diff options
Diffstat (limited to 'libs/ode-0.16.1')
648 files changed, 321052 insertions, 0 deletions
diff --git a/libs/ode-0.16.1/CHANGELOG.txt b/libs/ode-0.16.1/CHANGELOG.txt new file mode 100644 index 0000000..0f0678d --- /dev/null +++ b/libs/ode-0.16.1/CHANGELOG.txt @@ -0,0 +1,1285 @@ +ODE CHANGELOG +------------- + +the rules for this file: + * entries are sorted newest-first. + * summarize sets of changes - dont reproduce every CVS log comment here. + * don't ever delete anything. + * keep the format consistent (79 char width, M/D/Y date format). + +------------------------------------------------------------------------------ +11/12/2018 Oleh Derevenko + * The commentary from 11/05/2018 was wrong. The constraints were not + reset to their natural order and remained randomized. + The other thing that was missing was full contraint reorder without + separation into independent and dependent ones. The algorithm doesn't + converge without it well. + +11/10/2018 Oleh Derevenko + * An incorrect optimization to Jacobian Copy building code from #1938 + that resulted in corrupt data in multi-threaded execution mode was + fixed. + +11/05/2018 Oleh Derevenko + * An unintended change from commit #1898 has been reverted. + The QuickStep used to solve with randomized constraint order + each 8th iteration. The other iterations, the constraints + were reset to their natural order, as generated, with the dependent + constraints gathered in reverse order at end (the reverse order is + somehow important). With the commit #1898 the constraints were + randomly reordered each 8th iteration but then remained + in that randomized order and only were re-randomized on subsequent + multiples of 8. + +10/09/2017 Markus Rickert + * CMake support for project file generation has been added. + +06/14/2017 Oleh Derevenko + * dxHashSpace::collide() has been changed to fault host program + if scene gets too large and causes integer overflow. + +06/06/2017 Oleh Derevenko + * Memory and pointer size integer type use has been changed so that + internal typedefs are used instead of "_t" suffixed types. + +05/09/2017 Oleh Derevenko + * Introduction of cooperative algorithms API. + L*D*LT cooperative factorization and linear equation system + cooperative solving have been implemented. + * AtomicReadReorderBarrier, AtomicStore, AtomicStorePointer functions + have been added and some atomic function implementations have been + improved in OU. + +02/20/2017 Oleh Derevenko + * Project generation options have been changed to have built-in + multithreaded threading implementation enabled by default. + +02/19/2017 Oleh Derevenko + * dWorldStep threaded implementation has been extended to the final + steps of constraint force applications and body position updates + after the LCP solving. Note that body callbacks (if set) may be + called from multiple threads if threaded execution is enabled. + * OU atomicord32 type has been fixed to be unsigned on all supported + platforms. + +01/09/2017 Oleh Derevenko + * dGeomTriMeshDataPreprocess2() public function has been added to + replace dGeomTriMeshDataPreprocess(). Face angles pre-computation + for triangle meshes has been implemented. + +11/13/2016 Oleh Derevenko + * dGeomTriMeshDataGetBuff and dGeomTriMeshDataSetBuff have been marked + deprecated and their functionality implemented via + dGeomTriMeshDataGet and dGeomTriMeshDataSet. Extra function variant + dGeomTriMeshDataGet2() has been added to allow returning data size. + +11/07/2016 Oleh Derevenko + * The implementation of OPCODE TriMesh data pre-processing + (dGeomTriMeshDataPreprocess()) has been optimized to only contain + a sort and a single pass over edges (used to be a sort and O(N^2)). + +10/29/2016 Oleh Derevenko + * dGeomTriMeshDataPreprocess() public function has been changed to + return a boolean status (it can fail in low memory conditions). + +07/10/2016 Oleh Derevenko + * The correct handling of dJOINT_REVERSE mode for AngularMotor Joint + implemented (issue #37). + +06/29/2016 Oleh Derevenko + * A bug fixed with HashSpace calling big boxes collision twice + (both straight and reverse geometries order) since revision #1831. + +06/03/2016 Oleh Derevenko + * dJointSetHinge2Axes public function has been added and + dJointSetHinge2Axis1/2 have been marked deprecated due to being + unsafe. + +05/13/2016 Oleh Derevenko + * ICE Container class allocation strategy fixed to avoid reserving + excess memory with large collections. + +05/10/2016 Oleh Derevenko + * dSafeNormalize3 and dSafeNormalize4 functions changed to leave the + parameter intact instead of replacing it with the X-axis unit in case + of fault. + +04/12/2016 Oleh Derevenko + * A function to create a self-threaded threading implementation object + has been moved back to public headers as there could be a use for it + while running several worlds in parallel threads. + +01/09/2016 Oleh Derevenko + * Hinge2 joint corected to avoid faulting asserts when the axes get + temporarily invalid during assignments (suggested by David Mansolino) + +01/03/2016 Oleh Derevenko + * An invalid memory access fixed in dxSAPSpace::BoxPruning() in case + if there were NaN values in AABBs to be sorted. + +12/25/2015 Oleh Derevenko + * Unexpected joint mode assignment (instead of comparison) fixed within + an dUASSERT in dJointSetTransmissionAxis2() of transmission joint + +11/28/2015 Oleh Derevenko + * Convex-Trimesh collider added (libccd+GIMPACT only)(by Piotr Piastucki) + * dCreateConvex() and dGeomSetConvex() public APIs changed to expect + their parameter arrays as const pointers + +11/01/2015 Oleh Derevenko + * OPCODE mesh colliders' input coordinates have been offset to + mesh-relative frames to decrease potential computational errors + (suggested by luckytrashsc2@g***l.com) + +08/05/2015 Oleh Derevenko + * Implemented change to return highest depth contacts subset for GIMPACT + in cases if contacts count exceeds requested maximum (as suggested in + the issue #36 by Piotr Piastucki) + +11/17/2014 Daniel K. O. + * Added support for using libccd from the system (if found via + pkg-config) + +11/10/2014 Oleh Derevenko + * Floating point division by zero in capsule-ray collision routine + in case if the ray axis was parallel the cylinder and the ray started + from within it fixed (issue #26) + +11/08/2014 Oleh Derevenko + * Threading support has been extended to complete implementation + of QuickStep + +10/29/2014 Daniel K. O. + * Added dJointSetDBallDistance + +10/19/2014 Oleh Derevenko + * Built-in threading implementation compilation fixed for OSX + (clock_gettime() is missing from the system - reported by Bram) + +08/10/2014 Oleh Derevenko + * Declarations of dWorld[Get/Set]AutoDisableLinearAverageThreshold and + dWorld[Get/Set]AutoDisableAngularAverageThreshold have been removed + from public headers (were orphaned since rev.1052) + +07/16/2014 Oleh Derevenko + * Two fixes by Francesco Cat applied (fixes for mistakes made during + code style improvements in the past) + +02/27/14 Daniel K. O. + * Added dODE_VERSION macro to public headers (issue #24). + +02/11/14 Daniel K. O. + * Added dJointGetHinge2Angle2 (issue #12). + +02/07/14 Daniel K. O. + * Added dWorldSetData/dWorldGetData (issue #21). + +01/31/14 Daniel K. O. + * Applied patch #185: Stable, implicit gyroscopic forces. + +01/27/14 Daniel K. O. + * Fixed cylinder AABB computation. + +01/25/14 Daniel K. O. + * Removed ALLOCA calls from dHashSpace; it should not depend + on stack size limits anymore. + +12/06/13 Daniel K. O. + * Applied patch #181: fix some bugs in AMotor joint. + * Applied patch #186: fix some bugs in PU joint. + * Applied patch #182: Transmission joint. + * Applied patch #184: implement rolling friction for contacts. + +08/08/13 Oleh Derevenko + * Joint feedback forces application fixed in QuickStep implementation + (was broken since revision #1919 in old repository (#1927 in new one)) + +08/04/13 Oleh Derevenko + * Bugfix #89 by Luc applied (dJointAddSliderForce() adds a zero force + when the parent body is NULL) + +05/18/13 Oleh Derevenko + * OU library has been included in ODE at revision #46 instead of + being used as an external link due to difficulties using external + references with new protocol used for storage at SF. + +03/03/13 Oleh Derevenko + * Fixed issue with "findex==-1" constraints being intermixed with + "findex!=-1" ones during constraints random reordering in QuickStep. + +02/03/13 Oleh Derevenko + * [u]int[8/16/32] renamed to contain "d" prefix so that global namespace + was not polluted with these names unconditionally. + If your project depended on these types other than just for passing + parameters to ODE calls, add similar typedefs for yourself in some + of your project's global headers. + +01/02/13 Oleh Derevenko + * Applied patch #183 by Joseph Cooper (complementary matrix + calculation fix). + +12/28/12 Oleh Derevenko + * A bug with heightfield data assigned to a wrong field in + dGeomHeightfieldSetHeightfieldData fixed (bug report #88 by Luc). + +12/18/12 Oleh Derevenko + * Fixed issue with some kinds of joints (Ball, DBall, DHinge, Fixed) + might overwrite world ERP value with their custom ERP during + getInfo2() call and that inappropriate value would then be passed + to subsequent joints in solver instead of world ERP. + +12/01/12 Oleh Derevenko + * Fixed issues reported in patches #151 and #22 (collisions with + SAPSpace and QuadTreeSpace might not work because geometries list + was misused in them). + * Applied patch #160 "IsPointInPolygon in convex.cpp returns wrong + results" (by Janis Rucis) + +11/25/12 Oleh Derevenko + * Configuration option --disable-threading-intf added + (--no-threading-intf for Windows/Premake). This allows disabling + threading interface support (external implementations may not be + assigned) but eliminates dependency on OU and use of atomics in + steppers. + +11/05/12 Oleh Derevenko + * Fixed zero comparisons in OPCODE to use relative error instead of + absolute epsilon value (found by Bill Sellers) + +06/08/12 Daniel K. O. + * Removed the need for defining dSINGLE/dDOUBLE; this is stored now in + the generated ode/precision.h header. + * Some code cleanup to get rid of GCC warnings. + +05/30/12 Daniel K. O. + * Made drawstuff draw shadows for lines. + * Fixed dhinge's last constraint to properly handle rotations. + +05/03/12 Daniel K. O. + * Added two new joints: Double Ball and Double Hinge. + +04/22/12 Daniel K. O. + * Fixed plane2d joint: uninitialized variables (reported by Dimitris + Papavasiliou) + +04/14/12 Oleh Derevenko + * Assertion checking macros moved into library private headers. + +04/13/12 Daniel K. O. + * Applied patch from bug #3431829 - better handling of capsule-box with + deep penetrations. + * Fixed zero-mu issues: now either mu or mu2 can be set to zero. + +03/17/12 Oleh Derevenko + * Threaded execution support interface added. Optional built-in threading + implementation added. + Internal threading implementation is excluded by default and to be used, + it must be enabled with configure/premake. + At present, if threading interface is assigned to a world, island + selection and stepping is performed in multiple threads (one thread per + island). + +03/12/12 Oleh Derevenko + * PURE_INLINE macro renamed to ODE_PURE_INLINE and definition of + dNextAfter()/dCopySign() corrected to avoid creating conflicts with + other libraries. + +02/03/12 Oleh Derevenko + * Assertion checking macros moved from common.h to error.h + +12/18/11 Oleh Derevenko + * dIVERIFY macro added (same as dIASSERT in debug mode but evaluates its + expression in release mode) to be used to assert variable value + which is not used further in text while avoiding compiler warning. + * dICHECK macro added (same as dIASSERT but evaluates its expression and + raises assertion fault regardless of compilation mode) to be used to + generate a fault in cases when error is very unlikely but must be + handled and handling is very troublesome (e.g. failure to lock a mutex + due to lack of resources). + +12/07/11 Oleh Derevenko + * Partially fixed size_t to integer conversion warnings + * Fixed type signedness and added casts to size_t wherever necessary + in Step/QuickStep + +11/04/11 Daniel K. O. + * Applied patch #3429454 - fix compilation on some platforms. + +10/28/11 Daniel K. O. + * Fixed a box-capsule bug: more reasonable normal for deep penetrations + (contributed by Georg Martius.) + +10/27/11 Daniel K. O. + * Disabled merging of contacts for trimesh-sphere by default. + * Added new demo: demo_tracks. + +10/17/11 Daniel K. O. + * Added python bindings, contributed by Gideon Klompje. + * Updated some build scripts. + * Changed spheres distribution in demo_space_stress. + +05/17/11 Oleh Derevenko + * A typo in step.cpp fixed (assignment operator in a conditional + instead of comparison) (reported by Bram Stolk) + +01/29/11 Oleh Derevenko + * Heightfield zone boundaries calculation code fixed to also consider + whole next cell after the AABB if the AABB ends exactly at the cell + boundary. + +01/23/11 Daniel K. O. + * Applied patch from Daniel Fiser, add libccd collider for + box-cylinder. + +01/20/11 Daniel K. O. + * Applied patch from Daniel Fiser, fix infinite loop in libccd caused + by numerical problems. + +01/06/11 Daniel K. O. + * Applied patch from Daniel Fiser, efficient libccd tests when using + CONTACTS_UNIMPORTANT. + +12/17/10 Daniel K. O. + * Applied patches from Daniel Fiser for new colliders based on libccd. + +11/08/10 Daniel K. O. + * Applied patches from Daniel Fiser to incorporate libccd for + Cylinder-Cylinder collision tests. + +08/21/10 Oleh Derevenko + * Fix applied to dxReallocateTemporayWorldProcessContext() to remove typo + which caused segmentation fault (by Kyle McKay). + dTestSolveLCP() fixed to avoid exceeding allocated memory pool + (by Kyle McKay). + +07/19/10 Oleh Derevenko + * Patch applied (#3030783) to fix drawstuff dimensions being ignored + in OSX GLUT port (by Danny Price). + + Daniel K. O. + * Applied patch #2991622: dGeomGetRelPointPos, dGeomGetPosRelPoint, + dGeomVectorToWorld, and dGeomVectorFromWorld. + +07/16/10 Daniel K. O. + * Fixed bug #2937076: don't try to build demos if drawstuff is disabled. + +05/02/10 Oleh Derevenko + * Missing extern "C" wrapper has been added to include/ode/export-dif.h + (reported by Danny Price). The change affects dWorldExportDIF() public + function. + +05/02/10 Oleh Derevenko + * Patch applied (#2995450) to generate up to four contacts for box- + plane collision test (by alexdu) and fix contact depths. + +05/02/10 Oleh Derevenko + * dGeomLowLevelControl function added with ability to change/query OPCODE + trimesh-sphere contact merging behavior at runtime. + +02/18/10 Daniel K. O. + * Fixed bug affecting disabled joints and dWorldStep. + +01/16/10 Oleh Derevenko + * Patch applied (#2931174) to make demos work for recent MacOS. + * Patch applied (#2931177) to fix the demos' framerate on X11. + +12/20/09 Oleh Derevenko + * QuadTreeSpace implementation corrected to avoid object-block relation + ambiguity due to numeric errors. + +12/04/09 Oleh Derevenko + * odecpp classes changed to be inheritable and easily expandable + +11/29/09 Oleh Derevenko + * Improvement for trimesh-plane collision (also used in trimesh-heightfield) + to exclude mesh vertices that have already generated contacts from further + examination and contact generation in other triangles (suggested by LR). + +10/25/09 Oleh Derevenko + * Macros changed to static inline functions in odemath.h and related files. + Some code duplication has been eliminated across the files. + + * Fixed handling of --disable-asserts and --enable-double-precision + (absence of --enable-double-precision) in configure script. The script + was not appending compiler defines correctly. + + * dWorldStep implementation changed to remove allocation on stack. + dUSE_MALLOC_FOR_ALLOCA define has been removed as well as corresponding + configuration parameter. Also dMemoryFlag public variable has been removed. + (look for presence of ODE_EXT_malloc_not_alloca configuration string if + your application is dependent on that variable). + +09/05/09 Oleh Derevenko + * dWorldStepFast1 API removed along with dWorld[Get/Set]AutoEnableDepthSF1 + +08/29/09 Oleh Derevenko + * Fixed uninitialized floating point array used in computations. + +08/12/09 Oleh Derevenko + * A typo fixed in dGeomCopyOffsetRotation() (final_posr was used instead + of offset_posr). Reported by Tilmann. + +08/11/09 Daniel K. O. + * Made sure neither dSINGLE or dDOUBLE is defined by default; the user + should always explicitly specify the precision. + +06/27/09 Oleh Derevenko + * New functions have been added: + - dWorldUseSharedWorkingMemory + - dWorldCleanupWorkingMemory + - dWorldSetStepMemoryReservationPolicy + - dWorldSetStepMemoryManager + +06/25/09 Remi Ricard (papaDoc) + * Add limit to the to the second axis of the universal joint + for the pu joint. + +06/14/09 Oleh Derevenko + * dWorldQuickStep re-implemented to avoid memory allocation on stack. + Also several optimizations have been made to decrease memory + requirements and optimize algorithm implementation of dWorldQuickStep. + dWorldStep still remains with old memory allocation however new APIs + mentioned below are fully functional for it. + Both dWorldStep and dWorldQuickStep have been changed to return boolean + success status. + + * dInitODE2() changed to automatically call + AllocateODEDataForThread(dAllocateFlagBasicData) after library + initialization as this is a required initialization minimum that + must always be performed anyway. + +06/05/09 Daniel K. O. + * Removed aliasing issues from OPCODE/Ice, plus some other warnings. + Now it builds on gcc 4.3.2 with '-Wall -Werror -O3". + +05/30/09 Oleh Derevenko + * A minor memory usage optimization for QuickStep. + +05/24/09 Daniel K. O. + * Made the new trimesh collider the default. + * Added a "-texturepath" option to drawstuff. + +05/18/09 Oleh Derevenko + * Heightfield rotation fixed to avoid NaNs while rotating infinite + MIN/MAX heights. + +05/03/09 Oleh Derevenko + * Incorrect parameter order fixed on contact merging in Sphere-Trimesh + collisions. The bug resulted in merged contact remaining with normal + of first contact found. Thanks to Dimitris Papavasiliou for reporting. + +04/23/09 Daniel K. O. + * Fixed bug #2685170: use the C99 __func__ instead of __FUNCTION__ when + a C99 implementation is available. + +04/07/09 Remi Ricard (papaDoc) + * Remove unused code in demo_joints.cpp, reported by Tilmann. + +04/07/09 Remi Ricard (papaDoc) + * Fix bug in collision categories in demo_jointPU, reported by Tilmann + +03/14/09 Oleh Derevenko + * A possibility to initialize/close ODE multiple times recursively has + been added. + Also, now a call to dSpaceSetManualCleanup() is required for each + space right after creation if ODE has been initialized in thread data + manual cleanup mode. + +03/07/09 Oleh Derevenko + * Thread local data has been cleaned up from OPCODE and OdeTls as it is + not used (OPC_SweepAndPrune.* and OPC_BoxPruning.* have been removed + - rebuilding project files is necessary). + +02/07/09 Daniel K. O. + * New house of cards demo, which stresses the friction handling stability. + +01/29/09 Remi Ricard (papaDoc) + * Fix bug: Fix problem when attaching no body to a joint. Before calling + setRelativeValues a check is made for bodies. + * Add unittest + +01/28/09 Daniel K. O. + * Applied patch #2538046: Heightfield AABB bounds patch. + +01/23/09 Remi Ricard (papaDoc) + * Add new function dJointSetUniversalAxis1Offset and dJointSetUniversalAxis2Offset + * Add unittest for those funcitons. + +01/23/09 Remi Ricard (papaDoc) + * Fix problem with dJointGetUniversalAngle2 when the joint is attached to + only a body 2. The sign was inverted. + * Add unit test to verify for this problem + +01/21/09 Remi Ricard (papaDoc) + * Fix bug reported by Tilman: dxJointPU::getInfo1 was setting twice the + limit of limot1 to zero and not limot2 + +01/17/09 Daniel K. O. + * Fixed a bug in dSpaceCollide2: if both geoms are not in spaces they would + not have valid AABBs. + +12/20/08 Daniel K. O. + * New functions: dJointEnable, dJointDisable, dJointIsEnabled + (patch #2454764). + +12/19/08 Daniel K. O. + * Removed inline asm statements that break builds on 64-bit VC++. + +12/09/08 Daniel K. O. + * Applied patch #2381592, which adds support for Kinematic Bodies. + +12/06/08 Oleh Derevenko + + * Applied a patch by Martijn Buijs to make GIMPACT trimesh-ray collisions to + be consistent with those in OPCODE. + * Swapped geometries returned in contacts for OPCODE Trimesh-Plane collisions + as they were returned in unnatural order being different from that in GIMPACT + * Applied a patch by Martijn Buijs to make side1, side2 fields of contact + structure be always initialized, either with -1 for non-trmesh geometries + or with triangle index for trimeshes. These fields were only assigned for + trimesh-trimesh collisions before. + * dGeomTriMeshSetTriMergeCallback/dGeomTriMeshGetTriMergeCallback API added + to set/get user defined callback procedure for trimeshes that would be + invoked when contacts are merged to let user code accumulate attributes of + original contact triangles and generate a fake index by which it would + later be able to determine those attributes. If the callback is not + assigned (the default) -1 is generated as triangle index for merged + contacts (there was an index of first of merged triangles before!!!). + The callback is currently used within OPCODE trimesh-sphere and OPCODE + new trimesh-trimesh collisions. + +11/20/08 Remi Ricard (papaDoc) + * Fix problem with dJointGetPUPosition and + dJointGetPUPositionRate when the joint is attached to only + a body 2. The sign was inverted. + * Fix bug: When a pu joint had only one body attached to position 2, + dJointAttach(jId, 0, bId). The body was not push in the right direction to + move back between the limits. + * Add unit test to check the above problem + * Add the function void dJointSetPUAnchorOffset + * Make the function void dJointSetPUAnchorDelta deprecated + +11/19/08 Remi Ricard (papaDoc) + * Fix bug: When a pr joint had only one body attached to position 2, + dJointAttach(jId, 0, bId). The body was not push in the right direction to + move back between the limits. + * Add unit test to check the above problem + +11/19/08 Remi Ricard (papaDoc) + * Fix problem with dJointGetPRPosition and + dJointGetPRPositionRate when the joint is attached to only + a body 2. The sign was inverted. + * Add unit test to check the above problem + * Increase the tolerance to remove failure in unit test + * Remove compilation warning in unit test with the use of REAL() + +11/18/08 Remi Ricard (papaDoc) + * Fix bug: When a piston joint had only one body attached to position 2, + dJointAttach(jId, 0, bId). The body was not push in the right direction to + move back between the limits. + * Add more functionality to demo_piston.cpp + * Run astyle on modified files. + +11/18/08 Remi Ricard (papaDoc) + * Fix bug: When a slider joint had only one body attached to position 2, + dJointAttach(jId, 0, bId). The body was not push in the right direction to + move back between the limits. + +10/29/08 Oleh Derevenko + + * Premake scripts changed to only include chosen collision library + sources in project on Windows. --all-collis-libs premake option + added to allow inclusion of all collision library sources into the + project + +10/15/08 Remi Ricard (papaDoc) + * Applying patch #2158425 64-bit GIMPACT provided by Mark + William. This patch enable GIMPACT to works on 64-bit machine. + +10/15/08 Remi Ricard (papaDoc) + * Add function dJointGetPRAngle and dJointGetPRAngleRate + +10/15/08 Remi Ricard (papaDoc) + * Enable the motor on the rotoide part of the PR joint + +10/15/08 Remi Ricard (papaDoc) + * Add unit test to check if using directly a joint + or using after setting with default values is the same. + * Add function setRelativeValues called in dJointAttach for + all joints. + +10/10/08 Remi Ricard (papaDoc) + * Fix bug in dJointGetPUAxis2. The axis was not multiplied with the + the rotation matrix of the good body. + * Fix bug if there is only one body on the PU joint the axis returned + was not the right one. + * Add unit test to verify previous bug. + +10/03/08 Rodrigo Hernandez (Kwizatz) + * Added Blender script to create ODE convex geoms under tools. + +10/01/08 Rodrigo Hernandez (Kwizatz) + * Convex-Convex collision detection code is finally stable. + +08/31/08 Daniel K. O. + * Applied patch 2080674: Improved dBodySetRotation; now exact rotation + matrices are preserved until the next simulation step. + +08/07/08 Daniel K. O. + * Fixed strict aliasing issue that was breaking the new trimesh collider. + +07/24/08 Daniel K. O. + * New functions: dBodyGetGyroscopicMode and dBodySetGyroscopicMode + (patch #2019242). + +07/15/08 Remi Ricard (papaDoc) + * Add a new define ODE_API_DEPRECATED to mark function as deprecated + when necessary. + +07/14/08 Remi Ricard (papaDoc) + * Finish adding patch 1336066: Joint feedback in quickstep by jsinecky + * demo_boxstack.cpp can now print joint feedback + +07/11/08 Daniel K. O. + * Bumped version for 0.10.1 + * Added proper usage of libtool's version info. + +07/10/08 Remi Ricard (papaDoc) + * Add new function dJointSetPistonAnchorOffset + * Add unittest for the piston joint + * Fix problem with dJointGetPistonPosition and + dJointGetPistonPositionRate when the joint is attached to only + a body 2. The sign was inverted. + +07/09/08 Remi Ricard (papaDoc) + * Optimize function Multiply1_12q1 in quickstep + Patch proposed by Riemer v.d. Zee and modified by Patrick Baggett + +07/08/08 Remi Ricard (papaDoc) + * Update the slider joint to have the same behavior as the other joint + when there is only a body2 attached to it. + * Update documentation for the slider joint. + * Remove warning by using REAL() + * Add new unittest for dJointGetSliderPositionRate + +07/08/08 Remi Ricard (papaDoc) + * Update unittest for the slider. + * Rename the new function dJointSetHingeAxisDelta to + dJointSetHingeAxisOffset. This remove will remove confusion with + the old function dJointSetHingeAnchorDelta + * Update documentation for the Hinge unittest + * Remove warning by using REAL() + +07/07/08 Daniel K. O. + * Max Correcting Vel doesn't affect bounciness, as before. + +07/03/08 Remi Ricard (papaDoc) + * Add new function dJointSetHingeAxisDelta + * Add unittest for this new function + +06/17/08 Remi Ricard (papaDoc) + + * Move the computation of the Relative Rotation for the slider joint + into a function. + * Add unittest for to check qrel + +06/17/08 Remi Ricard (papaDoc) + + * Remove unused variables. + * Remove a conversion warning between unsigned int and int + +06/17/08 Remi Ricard (papaDoc) + + * Move the function hingeComputeRelativeRotation as a member of + the hinge structure/class. + +06/17/08 Remi Ricard (papaDoc) + + * Move the computation of the Relative Rotation for the fixed joint + into a function. + +06/16/08 Remi Ricard (papaDoc) + + * Add testunit for the dxJointFixed + +06/04/08 Daniel K. O. + + * Moved joints to ode/src/joints, converted them to true virtual + methods. + +06/02/08 Daniel K. O. + + * Added an Auto<T> template to step.cpp to handle memory deallocation. + +05/09/08 Daniel K. O. + + * Applied patch #1335202: Contact Joint Motion (with some corrections), + and added demo_motion. + +05/01/08 Oleh Derevenko + + * Memory leak in GIMPACT fixed (reported by Derek) + +04/28/08 Oleh Derevenko + + * Added possibility to collide a space of lower sublevel as a geometry + against another space of a higher level with dSpaceCollide2. + dSpaceSetSublevel/dSpaceGetSublevel are used for sublevel assignment/ + retrieval. + +04/27/08 Oleh Derevenko + + * Fixed incorrect memory copying which could lead to memory corruption + in GIMPACT (luckily, in unused code) + * Fixed possible memory read beyond the end of allocated buffer along + with unnecessary extra memory copying in GIMPACT. + * Fixed buffer reserve being incorrectly reset to zero for bitsets + what resulted in unnecessary memory reallocations in GIMPACT. + * Implemented support for ability to run collision detection from + multiple threads for separate spaces. + +04/14/08 Oleh Derevenko + + * Fixed possible memory corruption in new trimesh-trimesh collider + in case if two degenerated triangles are checked against each other. + +04/12/08 Oleh Derevenko + + * Fixed sporadic assertion failure on vector normalization caused + by small triangles degenerating into segments during space + transformations. + +03/28/08 Remi + + * Fix a bug in dJointXXXGetInfo. The value in limot.limit was not + always updated. (Ex: If hi and lo limit were changed). + +03/27/08 Remi + + * Added a new Joint: Prismatic Universal (patch #1828454). + + Daniel K. O. + + * Fixed bug #1841309: collide2() method buggy. + +03/18/08 Rodrigo + + * New function: dVector4Copy. + +03/14/08 david + + * Added stub calls for trimesh functions. + * Applied patch #1914232: dGetConfiguration. + * Applied patch #1655333: Optimize the function dNormalize3. + * New function: dSetColliderOverride. + * New function: dCheckConfiguration. + + Daniel K. O. + + * Disabled building shared library by default with autotools. + +03/13/08 david + + * New function: dJointGetNumBodies (patch #1901550). + * New function: dSpaceGetClass (patch #1901637). + * Applied patch #1901649: Add missing function in the export + +03/12/08 Rodrigo + + * Fixed drawstuff build issues on OSX. + +01/12/08 Daniel K. O. + + * Fixed a typedef bug in configure.in. + * Added dCylinder to the C++ wrappers. + * Applied patch 1851394: support for GIMPACT with double precision, + dCollide fix. + * Moved bunny geometry to bunny_geom.h. + +12/11/07 Daniel K. O. + + * Added damping and MaxAngularVel() functions. + * Const-correctness: added const qualifier to some dWorldGet and dBodyGet + functions. + * Updated the odecpp.h header. + +12/07/07 Daniel K. O. + + * Removed most of the compiler warnings from Drawstuff, ODE and + OPCODE + * Upgraded automake requirement to 1.10, and change some Makefile.am + +12/06/07 Rodrigo + + * Modified autotools to use libtool for + library generation and administration + * Removed release and debug flags for configure.in + CPPFLAGS, CFLAGS, CXXFLAGS should be set by the + user to their liking, respecting autotools policies. + +11/30/07 Daniel K. O. + * Applied patch 1813079 (moved callback) + * Replaced moveAndRotateBody by dxStepBody in stepfast.cpp + +11/10/07 david + + * Added 'Sweep and Prune' collision space. + * New Piston joint type with demo, by Remi Ricard + * Added build option to use 16-bit indices for OPCODE trimesh + +11/03/06 david + + * Integrated Christoph Beyer's average based sampling system for body + disabling. + +10/26/06 Francisco Leon + + * Totally refactored trimesh collision system. + Using GIMPACT instead of OPCODE. Now works correctly, and faster. + Visit http://gimpact.sourceforge.net. + + * Finally, test_moving_trimesh.exe works nicely. + + * Fixed autodisable system. Now is possible to set bigger sleeping + threshold values and objects won't be sleeping on the air. They will + rest on the floor properly. + + * dInitODE function added. + + * Is Obligatory to call dInitODE() at the beginning for initialize ODE, + and calling dCloseODE() when the program ends. + +09/20/06 bram + + * Fixed two bugs in cyl/plane collision test. + +09/13/06 Remi + + * New Rotoide - Prismatic joint type + * dJointGetUniversalAngles for efficient angle retrieval. + +08/09/06 david + + * Integrated plane2d joint type which constrains bodies to z == 0. + +07/06/06 david + + * Added heightfield primitive collision code. Simple test available in + ode/test/test_heightfield + +04/03/06 rodrigo + + * Added Convex primitive collision code, + currently only convex-sphere and convex-plane work + +04/01/06 bram + + * Added program to test trimesh vs sphere: ode/test/test_basket + +03/20/06 jason379 + + * Added new autogenerated Visual Studio projects, with Premake scripts + +03/17/06 bram + + * Added plane/cyl intersection test + * Renamed CCylinder to Capsule + +02/04/06 gcarlton + + * Added support for geom offsets. + +10/26/05 rodrigo + + * Removed LIBTOOL from autotools since it was not really required. + * Added a target to build ODE as a shared library, this shared + library gets build alongside the static one, no flags required. + +10/24/05 tfautre + + (Backported patches from STABLE branch, applied by Adam) + + * dRandInt changed for a non-double all-int version. + * mics minor fixes and improvements. + +04/05/05 tfautre + + * Fixed segmentation fault with OPCODE on 64 bits systems. + +03/31/05 tfautre + + * Fixed timer.cpp compiler error on x86-64 using GCC. + +03/29/05 colin + + * Added trimesh preprocessing to mark unneeded edges and verts. Also + added support for preprocessed info to the ccylinder-trimesh + collider. + +12/07/04 adam + + * Important AMotors bugfix + +09/22/04 jeff + + * Assorted small bugfixes and tweaks for + trimesh_{box,ccylinder,trimesh} collisions + +09/21/04 jeff + + * added functions to joint.cpp to allow joint attachment to moving + geoms. + + * added malloc-based memory allocation in step.cpp & lcp.cpp (turned + on with a #define switch in common.h) + +05/29/04 russ + + * added joint feedback to the QuickStep solver + +05/18/04 russ + + * added warm starting to the QuickStep solver + +05/18/04 russ + + * added the QuickStep solver + + * added contact parameter functions. + +05/05/04 adam + + * use dRandInt instead of rand() in stepfast. + +04/21/04 russ + + * added auto-disable support from Aras Pranckevicius (with + modifications by russ). this useful feature can speed up + simulation significantly in some cases. + + * various internal tidyups. + +04/20/04 russ + + * changed the meaning of the 'index' argument to dJointGetBody(): + it was the only remaining API function that does not respect + dJOINT_REVERSE (spotted by Matthew D. Hancher). + + * updated the C++ headers: fixed two minor bugs and added + support for dQuadTreeSpace, dRay, and the dGeom::getSpace() method + (from Matthew D. Hancher). + +04/18/04 russ + + * changed the way that the dInfinity constant is implemented: now it + is #defined to be one of: FLT_MAX, DBL_MAX, HUGE_VAL, HUGE_VALF, or + a large numeric constant. previously it was a variable that was + exported from the library. this simplifies the configuration and + build process quite a bit, especially in the case of DLLs. + + * removed the old, deprecated collision system (geom.cpp,space.cpp, + geom.h,space.h,odecpp_old_collision.h). the ODE_OLD_COLLISION + configuration setting no longer has any meaning. + + * removed support for dGeomGroups, which have been deprecated for + a while and are equivalent to 'spaces' anyway. + +04/13/04 russ + + * bug fix in dMassSetCappedCylinder(), from Matthew D. Hancher. + +04/08/04 russ + + * added trimesh-CCylinder capability, from Vadim Macagon + <vadim_mcagon@hotmail.com>. + +04/04/04 adam + + * yet another rewrite of triangle-box collision code, this + time based on code donated by Croteam, ported by asko@jetti.org + and tweaked by Erwin. + +04/04/04 adam + + * merged trimesh-trimesh collision code by + Jeffrey Smith <jeffreys@Softimage.com>. + + * changed it to not break the trimesh interface, fix + some GCC compilation problems, bring it up to date with + ODE changes from 2003-11-15 -> 2004-04-04. + + * add ability to drop meshes on meshes in test_moving_trimesh, + not as good as it could be but it's illustrative. + +01/16/04 adam + + * implement a bunch of ultra-simple TriMesh functions that were + in the headers but not in the code -- patch by + Vadim Macagon <vadim_mcagon@hotmail.com> + + * disable temporal coherence on trimeshes by default, since + it has scaleability issues that don't make it a general clear win. + +12/01/03 adam + + * implement dxHashSpace::collide2(), not particularly efficiently. + +11/14/03 adam + + * applied several Trimesh fixes and improvements from + Aras Pranckevicius <nearaz@interamotion.com> + +10/22/03 adam + + * apply Nguyen Binh's work for removing many dSetZero() calls + and some other extraneous initializations. + +07/29/03 martin + + * added dJointAdd*Torque/Force(). + +07/10/03 russ + + * added the StepFast code, by David Whittaker. + +07/02/03 martin + + * added dMassSet*Total(). + +07/01/03 martin + + * added joint limits and motors to universal joints. + + * reversed the polarity of the dJOINT_REVERSE flag. + +06/30/03 russ + + * added the TriMesh geom class and the quad tree space to the ODE + core. both of these were developed by Erwin de Vries. added OPCODE + to the ODE distribution, this is required by TriMesh. + +06/23/03 martin + + * added dGeomSetQuaternion() and dGeomGetQuaternion() + + * added dJointGet*Anchor2() + +05/07/03 russ + + * added dGeomGetSpace(). + +02/05/03 russ + + * added dMassSetCylinder(). + +12/07/02 russ + + * added dAreConnectedExcluding(). + +11/30/02 russ + + * added the ray geom class. + + * added the dGeomXXXPointDepth() functions. + + * added a collision test infrastructure, and some more tests. + +11/24/02 russ + + * added support for multiple box-box contacts. + +11/10/02 russ + + * added new collision system. select between the old/new system by + setting the ODE_OLD_COLLISION variable in config/user-settings. + +10/28/02 russ + + * fixed two problems in the LCP code to improve the reliability of + the dContactApprox1 contact mode. + + * added a FAQ question about rolling bodies getting stuck when they + hit multiple geoms. + +09/08/02 russ + + * added dClosestLineSegmentPoints(). + * implemented dCollideCB(). + +08/28/02 russ + + * added dJointSetFeedback() and dJointGetFeedback(). + +08/05/02 russ + + * added dGeomTransformSetInfo() and dGeomTransformGetInfo(). + +07/13/02 russ + + * added dBodySetForce(), dBodySetTorque(), dWorldImpulseToForce(), + dBodyGetPosRelPoint(), dBodyGetPosRelPoint(), dBodyVectorToWorld(), + dBodyVectorFromWorld(). + + * added dBodyGetPointVel() (thanks to Colin Reed). + + * added a new C++ interface (from Martin C. Martin, with modifications + by russ). the old C++ interface is now in odecpp_old.h. + +06/25/02 russ + + * added an additional BSD-style licensing option for ODE. + +06/23/02 russ + + * added dCloseODE(), contributed by Nate Waddoups and David McClurg. + +05/16/02 russ + + * added dSpaceQuery(), contributed by Nate Waddoups. + +04/07/02 russ + + * added a section to the documentation for universal joints. + this includes a picture of the joint. + +04/05/02 russ + + * added a universal joint class (generously contributed by + Martin C. Martin). it doesn't (yet) have a motor or joint limits, + but it does come with tests. + +03/11/02 russ + + * makefile changes to accomodate OSs with command line length + limitations (thanks to Norman Lin). + +01/06/02 russ + + * added the dBodySetGravityMode() and dBodyGetGravityMode() + functions, which change the dxBodyNoGravity body flag. + + * added support for building a DLL with MSVC - there is now a + msvc-dll target. thanks to Norman Lin for doing this. + +12/28/01 russ + + * added the dParamCFM joint parameter. + +12/24/01 russ + + * reworked the build system to make it more cross-platform. + there is now a single top-level makefile and a configurator.c + program. see the INSTALL file for details. + +12/04/01 russ + + * the "angular motor" joint has been completed, and a new section + has been added to the documentation. + +11/26/01 russ + + * added a new joint type: "angular motor". using this joint is a good + way to get ball-joint motors and limits. this is work in progress - + it has not been fully implemented or tested yet. + +11/22/01 russ + + * replaced the mmap()-based joint group stack (stack.cpp) with a + malloc()-based arena stack (obstack.cpp). this will be more + portable and should not impact performance. + +11/12/01 russ + + * changed the meaning of the 'flags' parameter to dCollide() and + related functions: now the size of the contact buffer is kept in + the lower 16 bits. this change will be backward compatible. + + * added dBodyGetFiniteRotationMode() and dBodyGetFiniteRotationAxis(). + + * added dBodyAddForceAtRelPos() function. + +11/11/01 russ + + * added the ability to manually enable and disable bodies. + see dBodyEnable(), dBodyDisable(), dBodyIsEnabled(). + + * fixed a potential bug: when a world is destroyed that contains + joints in joint groups, those joints are marked as "deactivated" in + the joint group, so when the joint group is destroyed they can be + ignored. + + * the test_boxstack demo has new options to enable and disable bodies. + + * new configuration parameter in config.h: dEFFICIENT_SIZE. + +11/11/01 russ + + * started the change log for ODE. changes older than today were added + to this file by inspecting the CVS logs. + +11/05/01 russ + + * added REAL() constructions for floating point numbers, to prevent + many warnings when compiling under VC++. + +11/03/01 russ + + * added geometry transform class, documented composite objects. + + * added collision rule: no contacts if both geoms on the same body. + this is not the best rule, may have to remove this in the future. + + * new dMassAdd() function. + + * capped cylinder to capped cylinder collision function. + +10/31/01 russ + + * increase CFM in some demos to make them more robust. + +10/29/01 russ + + * added new accessor functions. + +10/19/01 russ + + * added the dJOINT_TWOBODIES flag to the joint, that says it can not + be attached to just one body. + +10/12/01 russ + + * fixed a collision bug in dCollide() that was causing memory + corruption when multiple contacts were being returned. + +10/11/01 russ + + * joints can now return m=0 to be "inactive". added a "null" joint + to test this. + +10/09/01 russ + + * in the LCP solver, try to fail gracefully when s <= 0. + + * dAABBTestFn() API change. + +10/08/01 russ + + * fixed a contact swapping bug in dCollide(). + +10/07/01 russ + + * added capped cylinder geometry object. + +09/30/01 russ + + * the test_buggy demo now uses geometry groups. + + * added a dAABBTestFn field in the geometry classes. + +09/29/01 russ + + * added geometry groups. + +09/20/01 russ + + * added finite rotation stuff. diff --git a/libs/ode-0.16.1/CMakeLists.txt b/libs/ode-0.16.1/CMakeLists.txt new file mode 100644 index 0000000..feb6a2a --- /dev/null +++ b/libs/ode-0.16.1/CMakeLists.txt @@ -0,0 +1,954 @@ +cmake_minimum_required(VERSION 2.8.11) + +project(ODE) + +include(CheckFunctionExists) +include(CheckIncludeFiles) +include(CMakeDependentOption) +include(GNUInstallDirs) + +set(VERSION_MAJOR 0) +set(VERSION_MINOR 16) +set(VERSION_PATCH 1) +set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) + +option(BUILD_SHARED_LIBS "Build shared libraries." OFF) +option(ODE_16BIT_INDICES "Use 16-bit indices for trimeshes (default is 32-bit)." OFF) +option(ODE_NO_BUILTIN_THREADING_IMPL "Disable built-in multithreaded threading implementation." OFF) +option(ODE_NO_THREADING_INTF "Disable threading interface support (external implementations cannot be assigned." OFF) +option(ODE_OLD_TRIMESH "Use old OPCODE trimesh-trimesh collider." OFF) +option(ODE_WITH_DEMOS "Builds the demo applications and DrawStuff library." OFF) +option(ODE_WITH_GIMPACT "Use GIMPACT for trimesh collisions (experimental)." OFF) +option(ODE_WITH_LIBCCD "Use libccd for handling some collision tests absent in ODE." OFF) +option(ODE_WITH_OPCODE "Use old OPCODE trimesh-trimesh collider." ON) +option(ODE_WITH_OU "Use TLS for global caches (allows threaded collision checks for separated spaces)." OFF) +option(ODE_WITH_TESTS "Builds the unit test application." OFF) + +cmake_dependent_option(ODE_WITH_LIBCCD_BOX_CYL "Use libccd for box-cylinder." ON "ODE_WITH_LIBCCD" OFF) +cmake_dependent_option(ODE_WITH_LIBCCD_CAP_CYL "Use libccd for capsule-cylinder." ON "ODE_WITH_LIBCCD" OFF) +cmake_dependent_option(ODE_WITH_LIBCCD_CYL_CYL "Use libccd for cylinder-cylinder." ON "ODE_WITH_LIBCCD" OFF) +cmake_dependent_option(ODE_WITH_LIBCCD_CONVEX_BOX "Use libccd for convex-box." ON "ODE_WITH_LIBCCD" OFF) +cmake_dependent_option(ODE_WITH_LIBCCD_CONVEX_CAP "Use libccd for convex-capsule." ON "ODE_WITH_LIBCCD" OFF) +cmake_dependent_option(ODE_WITH_LIBCCD_CONVEX_CONVEX "Use libccd for convex-convex." ON "ODE_WITH_LIBCCD" OFF) +cmake_dependent_option(ODE_WITH_LIBCCD_CONVEX_CYL "Use libccd for convex-cylinder." ON "ODE_WITH_LIBCCD" OFF) +cmake_dependent_option(ODE_WITH_LIBCCD_CONVEX_SPHERE "Use libccd for convex-sphere." ON "ODE_WITH_LIBCCD" OFF) +cmake_dependent_option(ODE_WITH_LIBCCD_SYSTEM "Use system libccd." OFF "ODE_WITH_LIBCCD" OFF) + +if(CMAKE_SIZEOF_VOID_P EQUAL 4) + option(ODE_DOUBLE_PRECISION "Use double-precision math." OFF) +else() + option(ODE_DOUBLE_PRECISION "Use double-precision math." ON) +endif() + +find_package(OpenGL) +find_package(Threads) + +set(CMAKE_REQUIRED_INCLUDES ${OPENGL_INCLUDE_DIR}) +set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_THREAD_LIBS_INIT} ${OPENGL_LIBRARIES}) + +if(APPLE AND OPENGL_FOUND) + set(HAVE_APPLE_OPENGL_FRAMEWORK ON) +endif() +check_include_files(alloca.h HAVE_ALLOCA_H) +check_function_exists(gettimeofday HAVE_GETTIMEOFDAY) +check_include_files(inttypes.h HAVE_INTTYPES_H) +check_function_exists(isnan HAVE_ISNAN) +check_function_exists(isnanf HAVE_ISNANF) +check_include_files(malloc.h HAVE_MALLOC_H) +check_function_exists(pthread_attr_setstacklazy HAVE_PTHREAD_ATTR_SETSTACKLAZY) +check_function_exists(pthread_condattr_setclock HAVE_PTHREAD_CONDATTR_SETCLOCK) +check_include_files(stdint.h HAVE_STDINT_H) +check_include_files(sys/time.h HAVE_SYS_TIME_H) +check_include_files(sys/types.h HAVE_SYS_TYPES_H) +check_include_files(unistd.h HAVE_UNISTD_H) +check_function_exists(_isnan HAVE__ISNAN) +check_function_exists(_isnanf HAVE__ISNANF) +check_function_exists(__isnan HAVE___ISNAN) +check_function_exists(__isnanf HAVE___ISNANF) +if(APPLE) + set(MAC_OS_X_VERSION 1000) + check_function_exists(OSAtomicAdd32Barrier MAC_OS_X_VERSION_1040) + if(MAC_OS_X_VERSION_1040) + set(MAC_OS_X_VERSION 1040) + endif() + check_function_exists(OSAtomicAnd32OrigBarrier MAC_OS_X_VERSION_1050) + if(MAC_OS_X_VERSION_1050) + set(MAC_OS_X_VERSION 1050) + endif() +endif() +if(CMAKE_SYSTEM_PROCESSOR MATCHES "i686.*|x86.*|x86_64.*|amd64.*|AMD64.*") + set(PENTIUM ON) +endif() +if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64.*|amd64.*|AMD64.*") + set(X86_64_SYSTEM ON) +endif() +if(ODE_WITH_OU) + set(_OU_FEATURE_SET _OU_FEATURE_SET_TLS) +elseif(NOT ODE_NO_THREADING_INTF) + set(_OU_FEATURE_SET _OU_FEATURE_SET_ATOMICS) +else() + set(_OU_FEATURE_SET _OU_FEATURE_SET_BASICS) +endif() +set(_OU_NAMESPACE odeou) +if(WIN32 OR CYGWIN) + set(_OU_TARGET_OS _OU_TARGET_OS_WINDOWS) +elseif(APPLE) + set(_OU_TARGET_OS _OU_TARGET_OS_MAC) +elseif(QNXNTO) + set(_OU_TARGET_OS _OU_TARGET_OS_QNX) +elseif(CMAKE_SYSTEM MATCHES "SunOS-4") + set(_OU_TARGET_OS _OU_TARGET_OS_SUNOS) +else() + set(_OU_TARGET_OS _OU_TARGET_OS_GENUNIX) +endif() + +configure_file(config.h.cmake.in ode/src/config.h) + +if(ODE_DOUBLE_PRECISION) + set(CCD_PRECISION CCD_DOUBLE) + set(ODE_PRECISION dDOUBLE) +else() + set(CCD_PRECISION CCD_SINGLE) + set(ODE_PRECISION dSINGLE) +endif() + +configure_file(libccd/src/ccd/precision.h.in include/ccd/precision.h) +configure_file(include/ode/precision.h.in include/ode/precision.h) + +set(ODE_VERSION ${VERSION}) + +configure_file(include/ode/version.h.in include/ode/version.h) + +set( + HDRS + include/ode/collision.h + include/ode/collision_space.h + include/ode/collision_trimesh.h + include/ode/common.h + include/ode/compatibility.h + include/ode/contact.h + include/ode/cooperative.h + include/ode/error.h + include/ode/export-dif.h + include/ode/mass.h + include/ode/matrix.h + include/ode/matrix_coop.h + include/ode/memory.h + include/ode/misc.h + include/ode/objects.h + include/ode/ode.h + include/ode/odeconfig.h + include/ode/odecpp.h + include/ode/odecpp_collision.h + include/ode/odeinit.h + include/ode/odemath.h + include/ode/odemath_legacy.h + include/ode/rotation.h + include/ode/threading.h + include/ode/threading_impl.h + include/ode/timer.h + ${CMAKE_CURRENT_BINARY_DIR}/include/ode/precision.h + ${CMAKE_CURRENT_BINARY_DIR}/include/ode/version.h +) + +set( + SRCS + ode/src/array.cpp + ode/src/array.h + ode/src/box.cpp + ode/src/capsule.cpp + ode/src/collision_cylinder_box.cpp + ode/src/collision_cylinder_plane.cpp + ode/src/collision_cylinder_sphere.cpp + ode/src/collision_kernel.cpp + ode/src/collision_kernel.h + ode/src/collision_quadtreespace.cpp + ode/src/collision_sapspace.cpp + ode/src/collision_space.cpp + ode/src/collision_space_internal.h + ode/src/collision_std.h + ode/src/collision_transform.cpp + ode/src/collision_transform.h + ode/src/collision_trimesh_colliders.h + ode/src/collision_trimesh_disabled.cpp + ode/src/collision_trimesh_gimpact.h + ode/src/collision_trimesh_internal.h + ode/src/collision_trimesh_opcode.h + ode/src/collision_util.cpp + ode/src/collision_util.h + ode/src/common.h + ode/src/convex.cpp + ode/src/coop_matrix_types.h + ode/src/cylinder.cpp + ode/src/default_threading.cpp + ode/src/default_threading.h + ode/src/error.cpp + ode/src/error.h + ode/src/export-dif.cpp + ode/src/fastdot.cpp + ode/src/fastdot_impl.h + ode/src/fastldltfactor.cpp + ode/src/fastldltfactor_impl.h + ode/src/fastldltsolve.cpp + ode/src/fastldltsolve_impl.h + ode/src/fastlsolve.cpp + ode/src/fastlsolve_impl.h + ode/src/fastltsolve.cpp + ode/src/fastltsolve_impl.h + ode/src/fastvecscale.cpp + ode/src/fastvecscale_impl.h + ode/src/heightfield.cpp + ode/src/heightfield.h + ode/src/lcp.cpp + ode/src/lcp.h + ode/src/mass.cpp + ode/src/mat.cpp + ode/src/mat.h + ode/src/matrix.cpp + ode/src/matrix.h + ode/src/memory.cpp + ode/src/misc.cpp + ode/src/nextafterf.c + ode/src/objects.cpp + ode/src/objects.h + ode/src/obstack.cpp + ode/src/obstack.h + ode/src/ode.cpp + ode/src/odeinit.cpp + ode/src/odemath.cpp + ode/src/odemath.h + ode/src/odeou.h + ode/src/odetls.h + ode/src/plane.cpp + ode/src/quickstep.cpp + ode/src/quickstep.h + ode/src/ray.cpp + ode/src/resource_control.cpp + ode/src/resource_control.h + ode/src/rotation.cpp + ode/src/simple_cooperative.cpp + ode/src/simple_cooperative.h + ode/src/sphere.cpp + ode/src/step.cpp + ode/src/step.h + ode/src/threaded_solver_ldlt.h + ode/src/threading_atomics_provs.h + ode/src/threading_base.cpp + ode/src/threading_base.h + ode/src/threading_fake_sync.h + ode/src/threading_impl.cpp + ode/src/threading_impl.h + ode/src/threading_impl_posix.h + ode/src/threading_impl_templates.h + ode/src/threading_impl_win.h + ode/src/threading_pool_posix.cpp + ode/src/threading_pool_win.cpp + ode/src/threadingutils.h + ode/src/timer.cpp + ode/src/typedefs.h + ode/src/util.cpp + ode/src/util.h + ode/src/joints/amotor.cpp + ode/src/joints/amotor.h + ode/src/joints/ball.cpp + ode/src/joints/ball.h + ode/src/joints/contact.cpp + ode/src/joints/contact.h + ode/src/joints/dball.cpp + ode/src/joints/dball.h + ode/src/joints/dhinge.cpp + ode/src/joints/dhinge.h + ode/src/joints/fixed.cpp + ode/src/joints/fixed.h + ode/src/joints/hinge.cpp + ode/src/joints/hinge.h + ode/src/joints/hinge2.cpp + ode/src/joints/hinge2.h + ode/src/joints/joint.cpp + ode/src/joints/joint.h + ode/src/joints/joint_internal.h + ode/src/joints/joints.h + ode/src/joints/lmotor.cpp + ode/src/joints/lmotor.h + ode/src/joints/null.cpp + ode/src/joints/null.h + ode/src/joints/piston.cpp + ode/src/joints/piston.h + ode/src/joints/plane2d.cpp + ode/src/joints/plane2d.h + ode/src/joints/pr.cpp + ode/src/joints/pr.h + ode/src/joints/pu.cpp + ode/src/joints/pu.h + ode/src/joints/slider.cpp + ode/src/joints/slider.h + ode/src/joints/transmission.cpp + ode/src/joints/transmission.h + ode/src/joints/universal.cpp + ode/src/joints/universal.h +) + +if(ODE_WITH_GIMPACT AND NOT ODE_NO_TRIMESH) + list( + APPEND SRCS + GIMPACT/src/gim_boxpruning.cpp + GIMPACT/src/gim_contact.cpp + GIMPACT/src/gim_math.cpp + GIMPACT/src/gim_memory.cpp + GIMPACT/src/gim_tri_tri_overlap.cpp + GIMPACT/src/gim_trimesh.cpp + GIMPACT/src/gim_trimesh_capsule_collision.cpp + GIMPACT/src/gim_trimesh_ray_collision.cpp + GIMPACT/src/gim_trimesh_sphere_collision.cpp + GIMPACT/src/gim_trimesh_trimesh_collision.cpp + GIMPACT/src/gimpact.cpp + ode/src/collision_convex_trimesh.cpp + ode/src/collision_cylinder_trimesh.cpp + ode/src/collision_trimesh_box.cpp + ode/src/collision_trimesh_ccylinder.cpp + ode/src/collision_trimesh_gimpact.cpp + ode/src/collision_trimesh_internal.cpp + ode/src/collision_trimesh_internal_impl.h + ode/src/collision_trimesh_internal.h + ode/src/collision_trimesh_plane.cpp + ode/src/collision_trimesh_ray.cpp + ode/src/collision_trimesh_sphere.cpp + ode/src/collision_trimesh_trimesh.cpp + ode/src/gimpact_contact_export_helper.cpp + ode/src/gimpact_contact_export_helper.h + ode/src/gimpact_gim_contact_accessor.h + ode/src/gimpact_plane_contact_accessor.h + ) +endif() + +if(ODE_WITH_LIBCCD) + if(NOT ODE_WITH_LIBCCD_SYSTEM) + list( + APPEND SRCS + libccd/src/alloc.c + libccd/src/ccd.c + libccd/src/mpr.c + libccd/src/polytope.c + libccd/src/support.c + libccd/src/vec3.c + libccd/src/ccd/alloc.h + libccd/src/ccd/ccd.h + libccd/src/ccd/compiler.h + libccd/src/ccd/dbg.h + libccd/src/ccd/list.h + libccd/src/ccd/quat.h + libccd/src/ccd/polytope.h + libccd/src/ccd/simplex.h + libccd/src/ccd/support.h + libccd/src/ccd/vec3.h + libccd/src/custom/ccdcustom/quat.h + libccd/src/custom/ccdcustom/vec3.h + ) + endif() + + list( + APPEND SRCS + ode/src/collision_libccd.cpp + ode/src/collision_libccd.h + ) +endif() + +if(ODE_WITH_OPCODE AND NOT ODE_NO_TRIMESH) + list( + APPEND SRCS + ode/src/collision_convex_trimesh.cpp + ode/src/collision_cylinder_trimesh.cpp + ode/src/collision_trimesh_box.cpp + ode/src/collision_trimesh_ccylinder.cpp + ode/src/collision_trimesh_internal.cpp + ode/src/collision_trimesh_internal_impl.h + ode/src/collision_trimesh_internal.h + ode/src/collision_trimesh_opcode.cpp + ode/src/collision_trimesh_plane.cpp + ode/src/collision_trimesh_ray.cpp + ode/src/collision_trimesh_sphere.cpp + ode/src/collision_trimesh_trimesh.cpp + ode/src/collision_trimesh_trimesh_old.cpp + OPCODE/OPC_AABBCollider.cpp + OPCODE/OPC_AABBCollider.h + OPCODE/OPC_AABBTree.cpp + OPCODE/OPC_AABBTree.h + OPCODE/OPC_BaseModel.cpp + OPCODE/OPC_BaseModel.h + OPCODE/OPC_BoxBoxOverlap.h + OPCODE/OPC_Collider.cpp + OPCODE/OPC_Collider.h + OPCODE/OPC_Common.cpp + OPCODE/OPC_Common.h + OPCODE/OPC_HybridModel.cpp + OPCODE/OPC_HybridModel.h + OPCODE/OPC_IceHook.h + OPCODE/OPC_LSSAABBOverlap.h + OPCODE/OPC_LSSCollider.cpp + OPCODE/OPC_LSSCollider.h + OPCODE/OPC_LSSTriOverlap.h + OPCODE/OPC_MeshInterface.cpp + OPCODE/OPC_MeshInterface.h + OPCODE/OPC_Model.cpp + OPCODE/OPC_Model.h + OPCODE/OPC_OBBCollider.cpp + OPCODE/OPC_OBBCollider.h + OPCODE/OPC_OptimizedTree.cpp + OPCODE/OPC_OptimizedTree.h + OPCODE/OPC_Picking.cpp + OPCODE/OPC_Picking.h + OPCODE/OPC_PlanesAABBOverlap.h + OPCODE/OPC_PlanesCollider.cpp + OPCODE/OPC_PlanesCollider.h + OPCODE/OPC_PlanesTriOverlap.h + OPCODE/OPC_RayAABBOverlap.h + OPCODE/OPC_RayCollider.cpp + OPCODE/OPC_RayCollider.h + OPCODE/OPC_RayTriOverlap.h + OPCODE/OPC_Settings.h + OPCODE/OPC_SphereAABBOverlap.h + OPCODE/OPC_SphereCollider.cpp + OPCODE/OPC_SphereCollider.h + OPCODE/OPC_SphereTriOverlap.h + OPCODE/OPC_TreeBuilders.cpp + OPCODE/OPC_TreeBuilders.h + OPCODE/OPC_TreeCollider.cpp + OPCODE/OPC_TreeCollider.h + OPCODE/OPC_TriBoxOverlap.h + OPCODE/OPC_TriTriOverlap.h + OPCODE/OPC_VolumeCollider.cpp + OPCODE/OPC_VolumeCollider.h + OPCODE/Opcode.cpp + OPCODE/Opcode.h + OPCODE/Stdafx.h + OPCODE/Ice/IceAABB.cpp + OPCODE/Ice/IceAABB.h + OPCODE/Ice/IceAxes.h + OPCODE/Ice/IceBoundingSphere.h + OPCODE/Ice/IceContainer.cpp + OPCODE/Ice/IceContainer.h + OPCODE/Ice/IceFPU.h + OPCODE/Ice/IceHPoint.cpp + OPCODE/Ice/IceHPoint.h + OPCODE/Ice/IceIndexedTriangle.cpp + OPCODE/Ice/IceIndexedTriangle.h + OPCODE/Ice/IceLSS.h + OPCODE/Ice/IceMatrix3x3.cpp + OPCODE/Ice/IceMatrix3x3.h + OPCODE/Ice/IceMatrix4x4.cpp + OPCODE/Ice/IceMatrix4x4.h + OPCODE/Ice/IceMemoryMacros.h + OPCODE/Ice/IceOBB.cpp + OPCODE/Ice/IceOBB.h + OPCODE/Ice/IcePairs.h + OPCODE/Ice/IcePlane.cpp + OPCODE/Ice/IcePlane.h + OPCODE/Ice/IcePoint.cpp + OPCODE/Ice/IcePoint.h + OPCODE/Ice/IcePreprocessor.h + OPCODE/Ice/IceRandom.cpp + OPCODE/Ice/IceRandom.h + OPCODE/Ice/IceRay.cpp + OPCODE/Ice/IceRay.h + OPCODE/Ice/IceRevisitedRadix.cpp + OPCODE/Ice/IceRevisitedRadix.h + OPCODE/Ice/IceSegment.cpp + OPCODE/Ice/IceSegment.h + OPCODE/Ice/IceTriangle.cpp + OPCODE/Ice/IceTriangle.h + OPCODE/Ice/IceTriList.h + OPCODE/Ice/IceTypes.h + OPCODE/Ice/IceUtils.cpp + OPCODE/Ice/IceUtils.h + ) +endif() + +list( + APPEND SRCS + ode/src/odeou.cpp + ode/src/odeou.h + ode/src/odetls.cpp + ode/src/odetls.h + ou/src/ou/atomic.cpp + ou/src/ou/customization.cpp + ou/src/ou/malloc.cpp + ou/src/ou/threadlocalstorage.cpp +) + +add_library(ODE ${SRCS}) + +set_target_properties( + ODE + PROPERTIES + OUTPUT_NAME ode + POSITION_INDEPENDENT_CODE ON + VERSION ${VERSION} +) + +if(WIN32) + if(BUILD_SHARED_LIBS) + set_target_properties(ODE PROPERTIES DEBUG_POSTFIX d) + else() + set_target_properties( + ODE + PROPERTIES + DEBUG_POSTFIX sd + MINSIZEREL_POSTFIX s + RELEASE_POSTFIX s + RELWITHDEBINFO_POSTFIX s + ) + endif() + + if(ODE_DOUBLE_PRECISION) + set_target_properties(ODE PROPERTIES OUTPUT_NAME ode_double) + else() + set_target_properties(ODE PROPERTIES OUTPUT_NAME ode_single) + endif() +endif() + +target_compile_definitions( + ODE + PRIVATE + -D_OU_NAMESPACE=${_OU_NAMESPACE} + -D_OU_FEATURE_SET=${_OU_FEATURE_SET} + -D_OU_TARGET_OS=${_OU_TARGET_OS} + $<$<NOT:$<CONFIG:Debug>>:dNODEBUG> + -DdOU_ENABLED +) + +if(APPLE) + target_compile_definitions(ODE PRIVATE -DMAC_OS_X_VERSION=${MAC_OS_X_VERSION}) +endif() + +if(WIN32) + target_compile_definitions(ODE PRIVATE -D_CRT_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS -D_USE_MATH_DEFINES) +endif() + +if(BUILD_SHARED_LIBS) + target_compile_definitions(ODE PRIVATE -DODE_DLL) +else() + target_compile_definitions(ODE PRIVATE -DODE_LIB) +endif() + +if(ODE_DOUBLE_PRECISION) + target_compile_definitions(ODE PUBLIC -DdIDEDOUBLE PRIVATE -DCCD_IDEDOUBLE) +else() + target_compile_definitions(ODE PUBLIC -DdIDESINGLE PRIVATE -DCCD_IDESINGLE) +endif() + +target_include_directories( + ODE + PUBLIC + $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include> + $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/ode/src> + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/ode/src> + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/ode/src/joints> + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/ou/include> + $<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}> +) + +if(ODE_16BIT_INDICES) + target_compile_definitions(ODE PRIVATE -DdTRIMESH_16BIT_INDICES) +endif() + +if(NOT ODE_NO_BUILTIN_THREADING_IMPL) + target_compile_definitions(ODE PRIVATE -DdBUILTIN_THREADING_IMPL_ENABLED) +endif() + +if(ODE_NO_THREADING_INTF) + target_compile_definitions(ODE PRIVATE -DdTHREADING_INTF_DISABLED) +endif() + +if(ODE_WITH_GIMPACT AND NOT ODE_NO_TRIMESH) + target_compile_definitions(ODE PRIVATE -DdTRIMESH_ENABLED -DdTRIMESH_GIMPACT) + target_include_directories(ODE PRIVATE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/GIMPACT/include>) +endif() + +if(ODE_WITH_LIBCCD) + if(ODE_WITH_LIBCCD_SYSTEM) + find_package(ccd) + target_compile_definitions(ode PRIVATE -DdLIBCCD_ENABLED -DdLIBCCD_SYSTEM) + target_link_libraries(ODE ccd::ccd) + else() + target_compile_definitions(ODE PRIVATE -DdLIBCCD_ENABLED -DdLIBCCD_INTERNAL) + target_include_directories( + ODE + PRIVATE + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/libccd/src> + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/libccd/src/custom> + ) + endif() + + if(ODE_WITH_LIBCCD_BOX_CYL) + target_compile_definitions(ODE PRIVATE -DdLIBCCD_BOX_CYL) + endif() + + if(ODE_WITH_LIBCCD_CAP_CYL) + target_compile_definitions(ODE PRIVATE -DdLIBCCD_CAP_CYL) + endif() + + if(ODE_WITH_LIBCCD_CYL_CYL) + target_compile_definitions(ODE PRIVATE -DdLIBCCD_CYL_CYL) + endif() + + if(ODE_WITH_LIBCCD_CONVEX_BOX) + target_compile_definitions(ODE PRIVATE -DdLIBCCD_CONVEX_BOX) + endif() + + if(ODE_WITH_LIBCCD_CONVEX_CAP) + target_compile_definitions(ODE PRIVATE -DdLIBCCD_CONVEX_CAP) + endif() + + if(ODE_WITH_LIBCCD_CONVEX_CONVEX) + target_compile_definitions(ODE PRIVATE -DdLIBCCD_CONVEX_CONVEX) + endif() + + if(ODE_WITH_LIBCCD_CONVEX_CYL) + target_compile_definitions(ODE PRIVATE -DdLIBCCD_CONVEX_CYL) + endif() + + if(ODE_WITH_LIBCCD_CONVEX_SPHERE) + target_compile_definitions(ODE PRIVATE -DdLIBCCD_CONVEX_SPHERE) + endif() +endif() + +if(ODE_WITH_OPCODE AND NOT ODE_NO_TRIMESH) + target_compile_definitions(ODE PRIVATE -DdTRIMESH_ENABLED -DdTRIMESH_OPCODE) + + if(ODE_OLD_TRIMESH) + target_compile_definitions(ODE PRIVATE -DdTRIMESH_OPCODE_USE_OLD_TRIMESH_TRIMESH_COLLIDER) + endif() + + target_include_directories( + ODE + PRIVATE + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/OPCODE> + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/OPCODE/Ice> + ) +endif() + +if(ODE_WITH_OU) + target_compile_definitions(ODE PRIVATE -DdATOMICS_ENABLED -DdTLS_ENABLED) +elseif(NOT ODE_NO_THREADING_INTF) + target_compile_definitions(ODE PRIVATE -DdATOMICS_ENABLED) +endif() + +if(ODE_WITH_OU OR NOT ODE_NO_THREADING_INTF) + target_link_libraries(ODE ${CMAKE_THREAD_LIBS_INIT}) +endif() + +install( + TARGETS ODE + EXPORT ODE + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT development + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT runtime NAMELINK_SKIP + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime +) + +if(BUILD_SHARED_LIBS) + install( + TARGETS ODE + EXPORT ODE + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT development NAMELINK_ONLY + ) +endif() + +if(MSVC AND BUILD_SHARED_LIBS AND NOT CMAKE_VERSION VERSION_LESS 3.1) + install(FILES $<TARGET_PDB_FILE:ODE> DESTINATION ${CMAKE_INSTALL_BINDIR} CONFIGURATIONS Debug RelWithDebInfo COMPONENT debug) +endif() + +install(FILES ${HDRS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ode COMPONENT development) + +set(prefix ${CMAKE_INSTALL_PREFIX}) +set(exec_prefix "\${prefix}") +set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}") +set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") +configure_file(ode.pc.in ode.pc @ONLY) +configure_file(ode-config.in ode-config @ONLY) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/ode.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT development) +install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/ode-config DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT development) + +if(ODE_WITH_DEMOS) + set( + DRAWSTUFF_SRCS + include/drawstuff/drawstuff.h + include/drawstuff/version.h + drawstuff/src/drawstuff.cpp + drawstuff/src/internal.h + ) + + if(WIN32) + list( + APPEND DRAWSTUFF_SRCS + drawstuff/src/resource.h + drawstuff/src/resources.rc + drawstuff/src/windows.cpp + ) + elseif(APPLE) + list(APPEND DRAWSTUFF_SRCS drawstuff/src/osx.cpp) + else() + list(APPEND DRAWSTUFF_SRCS drawstuff/src/x11.cpp) + endif() + + add_library(drawstuff ${DRAWSTUFF_SRCS}) + target_compile_definitions(drawstuff PUBLIC -DDRAWSTUFF_TEXTURE_PATH="${CMAKE_CURRENT_SOURCE_DIR}/drawstuff/textures") + + if(BUILD_SHARED_LIBS) + target_compile_definitions(drawstuff PRIVATE -DDS_DLL -DUSRDLL) + else() + target_compile_definitions(drawstuff PRIVATE -DDS_LIB) + endif() + + target_include_directories(drawstuff PUBLIC ${OPENGL_INCLUDE_DIR}) + target_link_libraries(drawstuff ODE ${OPENGL_LIBRARIES}) + + if(WIN32) + target_link_libraries(drawstuff winmm) + elseif(APPLE) + find_package(GLUT) + target_include_directories(drawstuff PUBLIC ${GLUT_INCLUDE_DIR}) + target_link_libraries(drawstuff ${GLUT_LIBRARIES}) + else() + find_package(X11) + target_include_directories(drawstuff PUBLIC ${X11_INCLUDE_DIR}) + target_link_libraries(drawstuff ${X11_LIBRARIES}) + endif() + + set( + DEMO_SRCS + ode/demo/demo_boxstack.cpp + ode/demo/demo_buggy.cpp + ode/demo/demo_cards.cpp + ode/demo/demo_chain1.c + ode/demo/demo_chain2.cpp + ode/demo/demo_collision.cpp + ode/demo/demo_convex.cpp + ode/demo/demo_crash.cpp + ode/demo/demo_cylvssphere.cpp + ode/demo/demo_dball.cpp + ode/demo/demo_dhinge.cpp + ode/demo/demo_feedback.cpp + ode/demo/demo_friction.cpp + ode/demo/demo_gyro2.cpp + ode/demo/demo_gyroscopic.cpp + ode/demo/demo_heightfield.cpp + ode/demo/demo_hinge.cpp + ode/demo/demo_I.cpp + ode/demo/demo_jointPR.cpp + ode/demo/demo_jointPU.cpp + ode/demo/demo_joints.cpp + ode/demo/demo_kinematic.cpp + ode/demo/demo_motion.cpp + ode/demo/demo_motor.cpp + ode/demo/demo_ode.cpp + ode/demo/demo_piston.cpp + ode/demo/demo_plane2d.cpp + ode/demo/demo_rfriction.cpp + ode/demo/demo_slider.cpp + ode/demo/demo_space.cpp + ode/demo/demo_space_stress.cpp + ode/demo/demo_step.cpp + ode/demo/demo_transmission.cpp + ) + + if(NOT ODE_NO_TRIMESH) + list( + APPEND DEMO_SRCS + ode/demo/demo_basket.cpp + ode/demo/demo_cyl.cpp + ode/demo/demo_moving_convex.cpp + ode/demo/demo_moving_trimesh.cpp + ode/demo/demo_tracks.cpp + ode/demo/demo_trimesh.cpp + ) + endif() + + foreach(DEMO_SRC ${DEMO_SRCS}) + get_filename_component(DEMO ${DEMO_SRC} NAME_WE) + add_executable(${DEMO} ${DEMO_SRC}) + target_link_libraries(${DEMO} drawstuff) + + if(NOT WIN32 AND ${DEMO} MATCHES "demo_chain1") + target_link_libraries(${DEMO} m) + endif() + endforeach() +endif() + +if(ODE_WITH_TESTS) + set( + TEST_SRCS + tests/collision.cpp + tests/friction.cpp + tests/joint.cpp + tests/main.cpp + tests/odemath.cpp + tests/joints/amotor.cpp + tests/joints/ball.cpp + tests/joints/dball.cpp + tests/joints/fixed.cpp + tests/joints/hinge.cpp + tests/joints/hinge2.cpp + tests/joints/piston.cpp + tests/joints/pr.cpp + tests/joints/pu.cpp + tests/joints/slider.cpp + tests/joints/universal.cpp + tests/UnitTest++/src/AssertException.cpp + tests/UnitTest++/src/AssertException.h + tests/UnitTest++/src/CheckMacros.h + tests/UnitTest++/src/Checks.cpp + tests/UnitTest++/src/Checks.h + tests/UnitTest++/src/Config.h + tests/UnitTest++/src/DeferredTestReporter.cpp + tests/UnitTest++/src/DeferredTestReporter.h + tests/UnitTest++/src/DeferredTestResult.cpp + tests/UnitTest++/src/DeferredTestResult.h + tests/UnitTest++/src/MemoryOutStream.cpp + tests/UnitTest++/src/MemoryOutStream.h + tests/UnitTest++/src/ReportAssert.cpp + tests/UnitTest++/src/ReportAssert.h + tests/UnitTest++/src/Test.cpp + tests/UnitTest++/src/TestDetails.cpp + tests/UnitTest++/src/TestDetails.h + tests/UnitTest++/src/Test.h + tests/UnitTest++/src/TestList.cpp + tests/UnitTest++/src/TestList.h + tests/UnitTest++/src/TestMacros.h + tests/UnitTest++/src/TestReporter.cpp + tests/UnitTest++/src/TestReporter.h + tests/UnitTest++/src/TestReporterStdout.cpp + tests/UnitTest++/src/TestReporterStdout.h + tests/UnitTest++/src/TestResults.cpp + tests/UnitTest++/src/TestResults.h + tests/UnitTest++/src/TestRunner.cpp + tests/UnitTest++/src/TestRunner.h + tests/UnitTest++/src/TestSuite.h + tests/UnitTest++/src/TimeConstraint.cpp + tests/UnitTest++/src/TimeConstraint.h + tests/UnitTest++/src/TimeHelpers.h + tests/UnitTest++/src/UnitTest++.h + tests/UnitTest++/src/XmlTestReporter.cpp + tests/UnitTest++/src/XmlTestReporter.h + ) + + if(WIN32) + list( + APPEND TEST_SRCS + tests/UnitTest++/src/Win32/TimeHelpers.cpp + tests/UnitTest++/src/Win32/TimeHelpers.h + ) + else() + list( + APPEND TEST_SRCS + tests/UnitTest++/src/Posix/SignalTranslator.cpp + tests/UnitTest++/src/Posix/SignalTranslator.h + tests/UnitTest++/src/Posix/TimeHelpers.cpp + tests/UnitTest++/src/Posix/TimeHelpers.h + ) + endif() + + add_executable(tests ${TEST_SRCS}) + target_include_directories(tests PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/tests/UnitTest++/src) + target_link_libraries(tests ODE) + + enable_testing() + add_test(tests ${CMAKE_CURRENT_BINARY_DIR}/tests) +endif() + +include(CMakePackageConfigHelpers) + +configure_package_config_file( + ${CMAKE_CURRENT_SOURCE_DIR}/ode-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/ode-config.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ode +) +install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/ode-config.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ode-${VERSION} + COMPONENT development +) +write_basic_package_version_file( + ${CMAKE_CURRENT_BINARY_DIR}/ode-config-version.cmake + VERSION ${VERSION} + COMPATIBILITY ExactVersion +) +install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/ode-config-version.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ode-${VERSION} + COMPONENT development +) +install( + EXPORT ODE + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ode-${VERSION} + NAMESPACE ODE:: + FILE ode-export.cmake + COMPONENT development +) + +configure_file(cmake/cmake_uninstall.cmake.in cmake_uninstall.cmake @ONLY) +add_custom_target(uninstall ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) + +set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "ODE is a free, industrial quality library for simulating articulated rigid body dynamics - for example ground vehicles, legged creatures, and moving objects in VR environments. It is fast, flexible, robust and platform independent, with advanced joints, contact with friction, and built-in collision detection.") + +set(CPACK_COMPONENT_DEVELOPMENT_DEPENDS runtime) +set(CPACK_COMPONENT_DEVELOPMENT_DESCRIPTION "Open Dynamics Engine - development files\n${CPACK_DEBIAN_PACKAGE_DESCRIPTION}") +set(CPACK_COMPONENT_RUNTIME_DESCRIPTION "Open Dynamics Engine - runtime library\n${CPACK_DEBIAN_PACKAGE_DESCRIPTION}") +set(CPACK_DEB_COMPONENT_INSTALL ON) +set(CPACK_DEBIAN_DEVELOPMENT_FILE_NAME "DEB-DEFAULT") +set(CPACK_DEBIAN_DEVELOPMENT_PACKAGE_SECTION "libdevel") +set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "http://www.ode.org/") +set(CPACK_DEBIAN_PACKAGE_NAME "libode") +set(CPACK_DEBIAN_PACKAGE_SECTION "devel") +set(CPACK_DEBIAN_RUNTIME_FILE_NAME "DEB-DEFAULT") +set(CPACK_DEBIAN_RUNTIME_PACKAGE_SECTION "libs") +set(CPACK_DEBIAN_RUNTIME_PACKAGE_SHLIBDEPS ON) +set(CPACK_NSIS_PACKAGE_NAME "ODE ${VERSION}") +set(CPACK_NSIS_URL_INFO_ABOUT "http://www.ode.org/") +set(CPACK_PACKAGE_CONTACT "ode@ode.org") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "High performance library for simulating rigid body dynamics") +set(CPACK_PACKAGE_DISPLAY_NAME "ODE ${VERSION}") +set(CPACK_PACKAGE_INSTALL_DIRECTORY "ode-${VERSION}") +set(CPACK_PACKAGE_NAME "ode") +set(CPACK_PACKAGE_VENDOR "") +set(CPACK_PACKAGE_VERSION ${VERSION}) +set(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR}) +set(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR}) +set(CPACK_PACKAGE_VERSION_PATCH ${VERSION_PATCH}) +set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/COPYING) +set(CPACK_RPM_COMPONENT_INSTALL ON) +set(CPACK_RPM_DEVELOPMENT_FILE_NAME "RPM-DEFAULT") +set(CPACK_RPM_development_PACKAGE_DESCRIPTION "The ode-devel package contains libraries and header files for developing applications that use ode or ode-double.") +set(CPACK_RPM_development_PACKAGE_NAME "ode-devel") +set(CPACK_RPM_development_PACKAGE_SUMMARY "Development files for ODE") +set(CPACK_RPM_PACKAGE_DESCRIPTION "ODE is an open source, high performance library for simulating rigid body dynamics. It is fully featured, stable, mature and platform independent with an easy to use C/C++ API. It has advanced joint types and integrated collision detection with friction. ODE is useful for simulating vehicles, objects in virtual reality environments and virtual creatures. It is currently used in many computer games, 3D authoring tools and simulation tools.") +set(CPACK_RPM_PACKAGE_GROUP "Development/Libraries") +set(CPACK_RPM_PACKAGE_LICENSE "BSD or LGPLv2+") +set(CPACK_RPM_PACKAGE_NAME "ode") +set(CPACK_RPM_PACKAGE_SUMMARY "High performance library for simulating rigid body dynamics") +set(CPACK_RPM_PACKAGE_URL "http://www.ode.org/") +set(CPACK_RPM_RUNTIME_FILE_NAME "RPM-DEFAULT") + +if(ODE_DOUBLE_PRECISION) + set(CPACK_DEBIAN_DEVELOPMENT_PACKAGE_CONFLICTS "libode-sp-dev") + set(CPACK_DEBIAN_DEVELOPMENT_PACKAGE_DEPENDS "libode6") + set(CPACK_DEBIAN_DEVELOPMENT_PACKAGE_NAME "libode-dev") + set(CPACK_DEBIAN_RUNTIME_PACKAGE_CONFLICTS "libode6sp") + set(CPACK_DEBIAN_RUNTIME_PACKAGE_NAME "libode6") + set(CPACK_RPM_development_PACKAGE_REQUIRES "ode-double") + set(CPACK_RPM_runtime_PACKAGE_CONFLICTS "ode") + set(CPACK_RPM_runtime_PACKAGE_DESCRIPTION "The ode-double package contains a version of the ODE library for simulating rigid body dynamics compiled with double precision.") + set(CPACK_RPM_runtime_PACKAGE_NAME "ode-double") + set(CPACK_RPM_runtime_PACKAGE_SUMMARY "ODE physics library compiled with double precision") +else() + set(CPACK_DEBIAN_DEVELOPMENT_PACKAGE_CONFLICTS "libode-dev") + set(CPACK_DEBIAN_DEVELOPMENT_PACKAGE_DEPENDS "libode6sp") + set(CPACK_DEBIAN_DEVELOPMENT_PACKAGE_NAME "libode-sp-dev") + set(CPACK_DEBIAN_RUNTIME_PACKAGE_CONFLICTS "libode6") + set(CPACK_DEBIAN_RUNTIME_PACKAGE_NAME "libode6sp") + set(CPACK_RPM_development_PACKAGE_REQUIRES "ode") + set(CPACK_RPM_runtime_PACKAGE_CONFLICTS "ode-double") + set(CPACK_RPM_runtime_PACKAGE_NAME "ode") +endif() + +include(CPack) diff --git a/libs/ode-0.16.1/COPYING b/libs/ode-0.16.1/COPYING new file mode 100644 index 0000000..b21a778 --- /dev/null +++ b/libs/ode-0.16.1/COPYING @@ -0,0 +1,32 @@ +ODE is dual-licensed under either: + + * GNU Lesser General Public License v 2.1 or later. + see LICENSE.TXT + + * Modified 3-clause BSD license. + see LICENSE-BSD.TXT + + +Third-party libraries bundled with ODE: + + * GIMPACT: dual-licensed under either: + - GNU Lesser General Public License v 2.1 or later. + see GIMPACT-LICENSE-LGPL.TXT + - Modified 3-clause BSD license. + see GIMPACT/GIMPACT-LICENSE-BSD.TXT + + * libccd: Modified 3-clause BSD License + see libccd/BSD-LICENSE + + * OU/ODER: triple-licensed under either: + - GNU Lesser General Public License v 3 or later. + see ou/LICENSE.TXT + see ou/LICENSE-LESSER.TXT + - Modified 3-clause BSD license. + see ou/LICENSE-BSD.TXT + - ZLIB license. + see ou/LICENSE-ZLIB.TXT + + * OPCODE: under the same terms as ODE + see OPCODE/COPYING + diff --git a/libs/ode-0.16.1/CSR.txt b/libs/ode-0.16.1/CSR.txt new file mode 100644 index 0000000..7d4ca2e --- /dev/null +++ b/libs/ode-0.16.1/CSR.txt @@ -0,0 +1,422 @@ +CODING STYLE REQUIREMENTS
+
+Copyright (c) 2011-2017 Oleh Derevenko
+This article is provided to you under the terms of Artistic License 2.0
+(http://www.opensource.org/licenses/artistic-license-2.0).
+
+(I) General Coding Requirements
+=============================================================================
+
+1. Not more than one complex construction per function
+----------------------------------------------------------------------------
+
+A function must not contain more than one* operator from the following set:
+for, while, do..while, switch and constructions try..catch, try..finally.
+Moreover, those operators/constructions must not appear inside of a
+conditional operator.
+
+* Loop inclusion is allowed if multi-dimensional array must be iterated and
+all the elements are uniform and need to be processed linearly.
+try..finally construction inclusion is allowed for several resource
+allocations that need to be performed together.
+
+
+2. Absence of jumps
+----------------------------------------------------------------------------
+
+goto and continue operators must not be used.
+
+
+3. Single exit point at the end of function
+----------------------------------------------------------------------------
+
+A function must not have other exit points except for the end of its
+definition. If a function returns a value, return operator must be the last
+syntactical construction in the function.
+
+
+4. Zero value means failure
+----------------------------------------------------------------------------
+
+Function results must be chosen the way that binary zero value had a meaning
+of failure. Similarly, types must be designed so that binary zero element
+had the meaning of an invalid value (if invalid element concept is applicable
+for the type).
+
+
+5. Variables and parameters are initialized with zeroes
+----------------------------------------------------------------------------
+
+Variables and class fields must be initialized with values of binary zero
+presentation. Public enumerated types must be designed to have zero element
+and that element is to be the default element. Function default parameters
+must be chosen in the form to have binary zero value.
+
+
+6. Variables are not reused
+----------------------------------------------------------------------------
+
+Variables must not be reused for other purposes after they have already been
+used for something. The only value that might be stored in a variable is that
+described with its name.
+
+
+7. Parameters passed by value are treated as constants
+----------------------------------------------------------------------------
+
+Parameters that are passed by value must not be modified*. All of them must
+be treated as if they have been implicitly declared with const modifier.
+
+* An exception could be the case when a value loses its meaning (e.g. a
+pointer to an object being deleted).
+
+
+8. Result assignment is performed at the end of function
+----------------------------------------------------------------------------
+
+Every function returning a result must have a variable to contain the result
+of that function. It is to be declared (initialized if necessary) at the
+beginning of the function* and the only access to it after that should be its
+final value assignment. The assignment should be the last meaningful operator
+in an execution branch**. Several assignments, one per each execution branch,
+are allowed.
+
+* It is allowed to declare result variable with assignment immediately before
+return operator.
+** It is allowed to include technical constructions like logging or
+performance measuring after result variable assignment.
+
+
+9. Parameters by reference are not used in expressions
+----------------------------------------------------------------------------
+
+Parameters of simple types passed by reference must be copied into local
+variables at function entry and then be assigned their final values at
+function exit.
+Output parameters can be initialized at function entry and must be assigned
+their final values immediately before the function result variable assignment.
+
+
+(II) Class Design Requirements
+=============================================================================
+
+1. Classes work with their fields on their own
+----------------------------------------------------------------------------
+
+A function or method must not call several methods of other class, some of
+them being used to return and the others being used to assign the class fields.
+Such a code must be implemented as a method of that other class.
+
+
+2. No direct access to the fields
+----------------------------------------------------------------------------
+
+All the work with class fields (including fields of own class) must be
+performed with aid of dedicated methods (accessors) that return and assign
+field values. Exceptions can be made for constructors/destructors and methods
+dedicated for field initialization/finalization.
+
+
+3. Private fields only
+----------------------------------------------------------------------------
+
+All class fields must be private.
+
+
+4. No code in constructors and destructors
+----------------------------------------------------------------------------
+
+Class constructors must not have raw code other than doing trivial field
+initialization. If creation of contained objects is necessary or other
+operations need to be done they are to be performed via calls to the class
+methods rather than placed directly in constructor. Initial zero-assignment
+to a field is always required even if that field is later to be
+unconditionally assigned in methods called from the constructor.
+Similarly, a destructor must free contained objects with calls to the class
+methods rather than containing that code inline.
+
+
+5. No code in callbacks
+----------------------------------------------------------------------------
+
+Event handlers, callback interface methods and static callback methods must
+not have meaningful code within them. Their implementation should validate
+input arguments, convert them to proper internal types if necessary, and call
+one or more other methods of the class. These methods must not be declated in
+public section.
+
+
+6. No public virtual methods
+----------------------------------------------------------------------------
+
+Methods declared as virtual must not be public. The public calls to such
+methods must be wrapped with ordinary class methods.
+
+
+7. No logical level violations
+----------------------------------------------------------------------------
+
+Methods of lower logical levels must not call any methods of higher logical
+levels of the class. In particular, methods declared as protected and private
+must not call methods declared in public sections of own or ancestor classes.
+Methods declared as public may only call protected and private methods.
+Similarly classes of lower logical levels must not call public methods of
+classes at higher logical levels. Such calls are only possible via dedicated
+callback methods or callback interfaces.
+
+
+(III) Canonical Function Structures
+=============================================================================
+
+0. Preamble
+----------------------------------------------------------------------------
+
+Following are general function structures encouraged to be used for coding
+all the program logic. Any algorithm with branching can be implemented
+with these types of functions.
+
+Using these function structures helps to make code clear and error-proof.
+
+
+1. A Boolean Function
+----------------------------------------------------------------------------
+
+The Boolean Function can be used to implement algorithms with conditional
+branching.
+
+bool PerformSomeAction(...)
+{
+ bool bResult = false;
+
+ // Some linear code
+
+ if (...)
+ {
+ // Some linear code
+
+ if (...) // Optionally...
+ {
+ bResult = true;
+ }
+ }
+ // Optionally...
+ else if (...)
+ {
+ // Some linear code
+
+ bResult = true;
+ }
+
+ return bResult;
+}
+
+The idea is to have result variable initialized with false at entry and then
+have an arbitrary structure of conditional operators with some branches
+changing result variable to true on exit.
+
+
+2. A Validation Function
+----------------------------------------------------------------------------
+
+The Validation Function is an alternative to Boolean Function to implement
+conditional logic. It's mostly convenient for implementing multi-step
+algorithms that may fail (like validations or initializations of multiple
+items of non-uniform nature).
+
+bool PerformSomeValidation(...)
+{
+ bool bResult = false;
+
+ do
+ {
+ // Some linear code
+
+ // Optionally...
+ if ( !(...) )
+ {
+ // Some error handling // Optionally...
+ break;
+ }
+
+ // Optionally...
+ if (...)
+ {
+ // Some linear code
+
+ if ( !(...) )
+ {
+ // Some error handling // Optionally...
+ break;
+ }
+
+ // Some linear code
+ }
+
+ bResult = true;
+ }
+ while (false);
+
+ return bResult;
+}
+
+If function execution has side effects which need to be rolled back in case
+of failures on subsequent steps the function structure can be altered to the
+following form.
+
+bool PerformSomeInitialization(...)
+{
+ bool bResult = false;
+
+ bool bFirstSideEffectApplied = false, bSecondSideEffectApplied = false, ...;
+
+ do
+ {
+ // Some linear code
+
+ if ( !ExecuteFirstSideEffectApplication(...) )
+ {
+ // Some error handling // Optionally...
+ break;
+ }
+
+ bFirstSideEffectApplied = true
+
+ // Some linear code
+
+ if ( !ExecuteSecondSideEffectApplication(...) )
+ {
+ // Some error handling // Optionally...
+ break;
+ }
+
+ bSecondSideEffectApplied = true
+
+ ...
+
+ // Some linear code
+
+ if ( !ExecuteLastSideEffectApplication(...) )
+ {
+ // Some error handling // Optionally...
+ break;
+ }
+
+ bResult = true;
+ }
+ while (false);
+
+ if (!bResult)
+ {
+ if (bFirstSideEffectApplied)
+ {
+ if (bSecondSideEffectApplied)
+ {
+ if (...)
+ {
+ ...
+ }
+
+ ExecuteSecondSideEffectRollback(...);
+ }
+
+ ExecuteFirstSideEffectRollback(...);
+ }
+ }
+
+ return bResult;
+}
+
+
+3. A Loop Validation Function
+----------------------------------------------------------------------------
+
+The Loop Validation Function can be used for processing sequences of items
+while the processing of each or some individual items can fail.
+
+bool PerformLoopValidation(...)
+{
+ bool bAnyFailure = false;
+
+ for (...) // Or any other loop control operator
+ {
+ // Some linear code
+
+ if ( !(...) )
+ {
+ // Some error handling // Optional
+ bAnyFailure = true;
+ break;
+ }
+
+ // Some linear code
+ }
+
+ bool bResult = !bAnyFailure;
+ return bResult;
+}
+
+In case if a loop processing function may apply side effects on each step
+which need to be reverted in case of a failure on subsequent steps the
+functions need to be organized in the following four-function two-level
+structure.
+
+bool PerformLoopInitialization(...)
+{
+ bool bResult = false;
+
+ size_t nFailureItem;
+
+ if (DoPerformLoopInitialization(..., nFailureItem))
+ {
+ bResult = true;
+ }
+ else
+ {
+ DoPerformLoopFinalization(..., nFailureItem);
+ }
+
+ return bResult;
+}
+
+void PerformLoopFinalization(...)
+{
+ DoPerformLoopFinalization(..., npos); // Here "npos" stands for the invalid item index
+}
+
+bool DoPerformLoopInitialization(..., size_t &nOutFailureItem)
+{
+ bool bAnyFailure = false;
+ size_t nOutFailureItem = npos;
+
+ for (...) // Or any other loop control operator
+ {
+ // Some linear code
+
+ if ( !(...) )
+ {
+ // Some error handling // Optional
+ nOutFailureItem = ...;
+ bAnyFailure = true;
+ break;
+ }
+
+ // Some linear code
+ }
+
+ bool bResult = !bAnyFailure;
+ return bResult;
+}
+
+void DoPerformLoopFinalization(..., size_t nExternalFinalizationEndItem/*=npos*/)
+{
+ size_t nFinalizationEndItem = nExternalFinalizationEndItem == npos
+ ? ... /* total item count */
+ : nExternalFinalizationEndItem;
+
+ for (... /* loop until nFinalizationEndItem */) // Or any other loop control operator
+ {
+ // Some linear code
+ RevertLoopItemSideEffects(...);
+ }
+}
+
diff --git a/libs/ode-0.16.1/GIMPACT/GIMPACT-LICENSE-BSD.TXT b/libs/ode-0.16.1/GIMPACT/GIMPACT-LICENSE-BSD.TXT new file mode 100644 index 0000000..95545aa --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/GIMPACT-LICENSE-BSD.TXT @@ -0,0 +1,29 @@ +GIMPACT : Geometric tools for VR.
+
+Copyright (c) 2006 , Francisco León.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of
+ conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice, this list
+ of conditions and the following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+ * Neither the name of the GIMPACT nor the names of its contributors may be used
+ to endorse or promote products derived from this software without specific prior
+ written permission.
+
+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 OWNER 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.
\ No newline at end of file diff --git a/libs/ode-0.16.1/GIMPACT/GIMPACT-LICENSE-LGPL.TXT b/libs/ode-0.16.1/GIMPACT/GIMPACT-LICENSE-LGPL.TXT new file mode 100644 index 0000000..60b8156 --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/GIMPACT-LICENSE-LGPL.TXT @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/libs/ode-0.16.1/GIMPACT/Makefile.am b/libs/ode-0.16.1/GIMPACT/Makefile.am new file mode 100644 index 0000000..7a4f8e5 --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/Makefile.am @@ -0,0 +1,4 @@ +EXTRA_DIST = GIMPACT-LICENSE-BSD.TXT GIMPACT-LICENSE-LGPL.TXT + +SUBDIRS = include src + diff --git a/libs/ode-0.16.1/GIMPACT/Makefile.in b/libs/ode-0.16.1/GIMPACT/Makefile.in new file mode 100644 index 0000000..e8aa375 --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/Makefile.in @@ -0,0 +1,641 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = GIMPACT +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ode/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_CFLAGS = @CCD_CFLAGS@ +CCD_LIBS = @CCD_LIBS@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSTDCXX = @LIBSTDCXX@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ODE_PRECISION = @ODE_PRECISION@ +ODE_VERSION = @ODE_VERSION@ +ODE_VERSION_INFO = @ODE_VERSION_INFO@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = GIMPACT-LICENSE-BSD.TXT GIMPACT-LICENSE-LGPL.TXT +SUBDIRS = include src +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign GIMPACT/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign GIMPACT/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/GIMPACT/include/GIMPACT/Makefile.am b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/Makefile.am new file mode 100644 index 0000000..347ae72 --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/Makefile.am @@ -0,0 +1,6 @@ +noinst_HEADERS = \ + gim_boxpruning.h gim_contact.h gim_geometry.h \ + gim_math.h gim_memory.h gimpact.h \ + gim_radixsort.h gim_tri_capsule_collision.h gim_tri_collision.h \ + gim_trimesh.h gim_tri_sphere_collision.h + diff --git a/libs/ode-0.16.1/GIMPACT/include/GIMPACT/Makefile.in b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/Makefile.in new file mode 100644 index 0000000..78758f7 --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/Makefile.in @@ -0,0 +1,533 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = GIMPACT/include/GIMPACT +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ode/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +HEADERS = $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_CFLAGS = @CCD_CFLAGS@ +CCD_LIBS = @CCD_LIBS@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSTDCXX = @LIBSTDCXX@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ODE_PRECISION = @ODE_PRECISION@ +ODE_VERSION = @ODE_VERSION@ +ODE_VERSION_INFO = @ODE_VERSION_INFO@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_HEADERS = \ + gim_boxpruning.h gim_contact.h gim_geometry.h \ + gim_math.h gim_memory.h gimpact.h \ + gim_radixsort.h gim_tri_capsule_collision.h gim_tri_collision.h \ + gim_trimesh.h gim_tri_sphere_collision.h + +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign GIMPACT/include/GIMPACT/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign GIMPACT/include/GIMPACT/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(HEADERS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool cscopelist-am ctags ctags-am distclean \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_boxpruning.h b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_boxpruning.h new file mode 100644 index 0000000..cfa6c79 --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_boxpruning.h @@ -0,0 +1,323 @@ +#ifndef GIM_BOXPRUNING_H_INCLUDED
+#define GIM_BOXPRUNING_H_INCLUDED
+
+/*! \file gim_boxpruning.h
+\author Francisco León
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include "GIMPACT/gim_radixsort.h"
+#include "GIMPACT/gim_geometry.h"
+
+/*! \defgroup BOX_PRUNNING
+
+\brief
+Tools for find overlapping objects on a scenary. These functions sort boxes for faster collisioin queries, using radix sort or quick sort as convenience. See \ref SORTING .
+<ul>
+<li> For using these collision routines, you must create a \ref GIM_AABB_SET by using this function : \ref gim_aabbset_alloc.
+<li> The GIM_AABB_SET objects must be updated on their boxes on each query, and they must be update by calling \ref gim_aabbset_update
+<li> Before calling collision functions, you must create a pair set with \ref GIM_CREATE_PAIR_SET
+<li> For finding collision pairs on a scene (common space for objects), call \ref gim_aabbset_self_intersections
+<li> For finding collision pairs between two box sets , call \ref gim_aabbset_box_collision
+<li> After using collision routines, you must destroy the pairset with \ref GIM_DESTROY_PAIR_SET
+<li> When the box set is no longer used, you must destroy it by calling \ref gim_aabbset_destroy
+</ul>
+*/
+//! @{
+//! Overlapping pair
+struct GIM_PAIR
+{
+ GUINT32 m_index1;
+ GUINT32 m_index2;
+};
+//typedef struct _GIM_PAIR GIM_PAIR;
+
+//! Box container
+struct GIM_AABB_SET
+{
+ GUINT32 m_count;
+ aabb3f m_global_bound;//!< Global calculated bound of all boxes
+ aabb3f * m_boxes;
+ GUINT32 * m_maxcoords;//!<Upper corners of the boxes, in integer representation
+ GIM_RSORT_TOKEN * m_sorted_mincoords;//!< sorted min coords (lower corners), with their coord value as the m_key and m_value as the box index
+ char m_shared;//!< if m_shared == 0 then the memory is allocated and the set must be destroyed, else the pointers are shared and the set should't be destroyed
+};
+//typedef struct _GIM_AABB_SET GIM_AABB_SET;
+
+//! Function for creating an overlapping pair set
+#define GIM_CREATE_PAIR_SET(dynarray) GIM_DYNARRAY_CREATE(GIM_PAIR,dynarray,G_ARRAY_GROW_SIZE)
+//! Function for destroying an overlapping pair set
+#define GIM_DESTROY_PAIR_SET(dynarray) GIM_DYNARRAY_DESTROY(dynarray)
+
+//! Allocate memory for all aabb set.
+void gim_aabbset_alloc(GIM_AABB_SET * aabbset, GUINT32 count);
+
+//! Destroys the aabb set.
+void gim_aabbset_destroy(GIM_AABB_SET * aabbset);
+
+//! Calcs the global bound only
+/*!
+\pre aabbset must be allocated. And the boxes must be already set.
+*/
+void gim_aabbset_calc_global_bound(GIM_AABB_SET * aabbset);
+
+//! Sorts the boxes for box prunning.
+/*!
+1) find the integer representation of the aabb coords
+2) Sorts the min coords
+3) Calcs the global bound
+\pre aabbset must be allocated. And the boxes must be already set.
+\param aabbset
+\param calc_global_bound If 1 , calcs the global bound
+\post If aabbset->m_sorted_mincoords == 0, then it allocs the sorted coordinates
+*/
+void gim_aabbset_sort(GIM_AABB_SET * aabbset, char calc_global_bound);
+
+//! log(N) Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
+/*!
+\pre aabbset must be allocated and sorted, the boxes must be already set.
+\param aabbset Must be sorted. Global bound isn't required
+\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
+*/
+void gim_aabbset_self_intersections_sorted(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs);
+
+//! NxN Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
+/*!
+\pre aabbset must be allocated, the boxes must be already set.
+\param aabbset Global bound isn't required. Doen't need to be sorted.
+\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
+*/
+void gim_aabbset_self_intersections_brute_force(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs);
+
+//! log(N) Bipartite box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
+/*!
+\pre aabbset1 and aabbset2 must be allocated and sorted, the boxes must be already set.
+\param aabbset1 Must be sorted, Global bound is required.
+\param aabbset2 Must be sorted, Global bound is required.
+\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
+*/
+void gim_aabbset_bipartite_intersections_sorted(GIM_AABB_SET * aabbset1, GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs);
+
+//! NxM Bipartite box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
+/*!
+\pre aabbset1 and aabbset2 must be allocated and sorted, the boxes must be already set.
+\param aabbset1 Must be sorted, Global bound is required.
+\param aabbset2 Must be sorted, Global bound is required.
+\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
+*/
+void gim_aabbset_bipartite_intersections_brute_force(GIM_AABB_SET * aabbset1,GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs);
+
+
+/*
+ Brute-Force Vs Sorted pruning
+Different approaches must be applied when colliding sets with different number of
+elements. When sets have less of 100 boxes, is often better to apply force brute
+approach instead of sorted methods, because at lowlevel bruteforce routines gives
+better perormance and consumes less resources, due of their simplicity.
+But when sets are larger, the complexiity of bruteforce increases exponencially.
+In the case of large sets, sorted approach is applied. So GIMPACT has the following
+strategies:
+
+On Sorting sets:
+!) When sets have more of 140 boxes, the boxes are sorted by its coded min coord
+and the global box is calculated. But when sets are smaller (less of 140 boxes),
+Is convenient to apply brute force approach.
+
+*******************************************************************************/
+
+//! Constant for apply approaches between brute force and sorted pruning on bipartite queries
+#define GIM_MIN_SORTED_BIPARTITE_PRUNING_BOXES 600
+//! Constant for apply approaches between brute force and sorted pruning for box collision
+#define GIM_MIN_SORTED_PRUNING_BOXES 140
+
+
+//Use these functions for general initialization
+
+//! Initalizes the set. Sort Boxes if needed.
+/*!
+\pre aabbset must be allocated. And the boxes must be already set.
+\post If the set has less of GIM_MIN_SORTED_BIPARTITE_PRUNING_BOXES boxes, only calcs the global box,
+ else it Sorts the entire set( Only applicable for large sets)
+*/
+void gim_aabbset_update(GIM_AABB_SET * aabbset);
+
+///Use these functions for general collision
+
+//! Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
+/*!
+This function sorts the set and then it calls to gim_aabbset_self_intersections_brute_force or gim_aabbset_self_intersections_sorted. This is an example of how to use this function:
+\code
+//Create contact list
+GDYNAMIC_ARRAY collision_pairs;
+GIM_CREATE_PAIR_SET(collision_pairs);
+//Do collision
+gim_aabbset_self_intersections(&aabbset,&collision_pairs);
+if(collision_pairs.m_size==0)
+{
+ GIM_DYNARRAY_DESTROY(collision_pairs);//
+ return; //no collisioin
+}
+
+//pair pointer
+GIM_PAIR *pairs = GIM_DYNARRAY_POINTER(GIM_PAIR,collision_pairs);
+GUINT i, ti1,ti2;
+for (i=0;i<collision_pairs.m_size; i++)
+{
+ ti1 = pairs[i].m_index1;
+ ti2 = pairs[i].m_index2;
+ //Do something with the pairs
+ ....
+ ....
+ ...
+
+}
+//Terminate
+GIM_DYNARRAY_DESTROY(dummycontacts);
+GIM_DYNARRAY_DESTROY(collision_pairs);
+\endcode
+\param aabbset Set of boxes. Sorting isn't required.
+\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
+\pre aabbset must be allocated and initialized.
+\post If aabbset->m_count >= GIM_MIN_SORTED_PRUNING_BOXES, then it calls to gim_aabbset_sort and then to gim_aabbset_self_intersections_sorted. Global box won't be calculated.
+*/
+void gim_aabbset_self_intersections(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs);
+
+//! Collides two sets. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
+/*!
+\pre aabbset1 and aabbset2 must be allocated and updated. See gim_aabbset_update.
+\param aabbset1 Must be updated.
+\param aabbset2 Must be updated.
+\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
+*/
+void gim_aabbset_bipartite_intersections(GIM_AABB_SET * aabbset1, GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs);
+
+///Function for create Box collision result set
+
+#define GIM_CREATE_BOXQUERY_LIST(dynarray) GIM_DYNARRAY_CREATE(GUINT32,dynarray,G_ARRAY_GROW_SIZE)
+
+//! Finds intersections between a box and a set. Return the colliding boxes of the set
+/*!
+\pre aabbset must be allocated and initialized.
+\param test_aabb Box for collision query
+\param aabbset Set of boxes .Global bound is required.
+\param collided Array of GUINT elements, indices of boxes. Must be initialized before (Reserve size ~ 100)
+*/
+void gim_aabbset_box_collision(aabb3f *test_aabb, GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collided);
+
+//! Finds intersections between a box and a set. Return the colliding boxes of the set
+/*!
+\pre aabbset must be allocated and initialized.
+\param vorigin Origin point of ray.
+\param vdir Direction vector of ray.
+\param tmax Max distance param for ray.
+\param aabbset Set of boxes .Global bound is required.
+\param collided Array of GUINT elements, indices of boxes. Must be initialized before (Reserve size ~ 100)
+*/
+void gim_aabbset_ray_collision(vec3f vorigin,vec3f vdir, GREAL tmax, GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collided);
+
+
+/*
+For sorting, each box corner must be discretized to a 32 bit integer.
+For this, we take the x and z coordinates from the box corner (a vector vec3f)
+Then convert the (x,z) pair to an integer. For convenience, we choose an error
+constant for converting the coordinates (0.05).
+*******************************************************************************/
+
+/**
+ For fitting the coordinate to an integer, we need to constraint the range of its values. So each coord component (x, z) must lie between 0 and 65536.
+ 20 give us a 0.05 floating point error
+*/
+#define ERROR_AABB 20.0f
+
+/**
+An error of 0.05 allows to make coordinates up to 1638.0f and no less of -1638.0f.
+So the maximum size of a room should be about 3276x3276 . Its dimensions must lie between [-1638,1638.0f]
+*/
+#define MAX_AABB_SIZE 1638.0f
+
+//! Converts a vector coordinate to an integer for box sorting
+/*!
+\param vx X component
+\param vz Z component
+\param uint_key a GUINT
+*/
+#define GIM_CONVERT_VEC3F_GUINT_XZ(vx,vz,uint_key)\
+{\
+ GUINT32 _z = ((GUINT32)(vz*ERROR_AABB))+32768;\
+ uint_key = ((GUINT32)(vx*ERROR_AABB))+32768;\
+ uint_key = (uint_key<<16) + _z;\
+}\
+
+//! Converts a vector coordinate to an integer for box sorting,rounding to the upper int
+/*!
+\param vx X component
+\param vz Z component
+\param uint_key a GUINT
+*/
+#define GIM_CONVERT_VEC3F_GUINT_XZ_UPPER(vx,vz,uint_key)\
+{\
+ GUINT32 _z = ((GUINT32)ceilf(vz*ERROR_AABB))+32768;\
+ uint_key = ((GUINT32)ceilf(vx*ERROR_AABB))+32768;\
+ uint_key = (uint_key<<16) + _z;\
+}\
+
+
+//! Converts a vector coordinate to an integer for box sorting. Secure clamped
+/*!
+\param vx X component
+\param vz Z component
+\param uint_key a GUINT
+*/
+#define GIM_CONVERT_VEC3F_GUINT_XZ_CLAMPED(vx,vz,uint_key)\
+{\
+ GREAL _cx = CLAMP(vx,-MAX_AABB_SIZE,MAX_AABB_SIZE);\
+ GREAL _cz = CLAMP(vz,-MAX_AABB_SIZE,MAX_AABB_SIZE);\
+ GUINT32 _z = ((GUINT32)(_cz*ERROR_AABB))+32768;\
+ uint_key = ((GUINT32)(_cx*ERROR_AABB))+32768;\
+ uint_key = (uint_key<<16) + _z;\
+}\
+
+//! Converts a vector coordinate to an integer for box sorting. Secure clamped, rounded
+/*!
+\param vx X component
+\param vz Z component
+\param uint_key a GUINT
+*/
+#define GIM_CONVERT_VEC3F_GUINT_XZ_UPPER_CLAMPED(vx,vz,uint_key)\
+{\
+ GREAL _cx = CLAMP(vx,-MAX_AABB_SIZE,MAX_AABB_SIZE);\
+ GREAL _cz = CLAMP(vz,-MAX_AABB_SIZE,MAX_AABB_SIZE);\
+ GUINT32 _z = ((GUINT32)ceilf(_cz*ERROR_AABB))+32768;\
+ uint_key = ((GUINT32)ceilf(_cx*ERROR_AABB))+32768;\
+ uint_key = (uint_key<<16) + _z;\
+}\
+
+//! @}
+
+#endif // GIM_BOXPRUNING_H_INCLUDED
diff --git a/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_contact.h b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_contact.h new file mode 100644 index 0000000..e7f5b5e --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_contact.h @@ -0,0 +1,115 @@ +#ifndef GIM_CONTACT_H_INCLUDED
+#define GIM_CONTACT_H_INCLUDED
+
+/*! \file gim_contact.h
+\author Francisco León
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include "GIMPACT/gim_geometry.h"
+#include "GIMPACT/gim_radixsort.h"
+
+/*! \defgroup CONTACTS
+\brief
+Functions for managing and sorting contacts resulting from a collision query.
+<ul>
+<li> Contact lists must be create by calling \ref GIM_CREATE_CONTACT_LIST
+<li> After querys, contact lists must be destroy by calling \ref GIM_DYNARRAY_DESTROY
+<li> Contacts can be merge for avoid duplicate results by calling \ref gim_merge_contacts
+</ul>
+
+*/
+//! @{
+/// Structure for collision results
+struct GIM_CONTACT
+{
+ vec3f m_point;
+ vec3f m_normal;
+ GREAL m_depth;//Positive value indicates interpenetration
+ void * m_handle1;
+ void * m_handle2;
+ GUINT32 m_feature1;//Face number
+ GUINT32 m_feature2;//Face number
+};
+//typedef struct _GIM_CONTACT GIM_CONTACT;
+
+#define CONTACT_DIFF_EPSILON 0.00001f
+
+#define GIM_CALC_KEY_CONTACT(pos,hash)\
+{\
+ GINT32 _coords[] = {(GINT32)(pos[0]*1000.0f+1.0f),(GINT32)(pos[1]*1333.0f),(GINT32)(pos[2]*2133.0f+3.0f)};\
+ GUINT32 _hash=0;\
+ GUINT32 *_uitmp = (GUINT32 *)(&_coords[0]);\
+ _hash = *_uitmp;\
+ _uitmp++;\
+ _hash += (*_uitmp)<<4;\
+ _uitmp++;\
+ _hash += (*_uitmp)<<8;\
+ hash = _hash;\
+}\
+
+///Creates a contact list for queries
+#define GIM_CREATE_CONTACT_LIST(contact_array) GIM_DYNARRAY_CREATE(GIM_CONTACT,contact_array,100)
+
+#define GIM_PUSH_CONTACT(contact_array, point, normal, deep,handle1, handle2, feat1, feat2)\
+{\
+ GIM_DYNARRAY_PUSH_EMPTY(GIM_CONTACT,contact_array);\
+ GIM_CONTACT * _last = GIM_DYNARRAY_POINTER_LAST(GIM_CONTACT,contact_array);\
+ VEC_COPY(_last->m_point,point);\
+ VEC_COPY(_last->m_normal,normal);\
+ _last->m_depth = deep;\
+ _last->m_handle1 = handle1;\
+ _last->m_handle2 = handle2;\
+ _last->m_feature1 = feat1;\
+ _last->m_feature2 = feat2;\
+}\
+
+///Receive pointer to contacts
+#define GIM_COPY_CONTACTS(dest_contact, source_contact)\
+{\
+ VEC_COPY(dest_contact->m_point,source_contact->m_point);\
+ VEC_COPY(dest_contact->m_normal,source_contact->m_normal);\
+ dest_contact->m_depth = source_contact->m_depth;\
+ dest_contact->m_handle1 = source_contact->m_handle1;\
+ dest_contact->m_handle2 = source_contact->m_handle2;\
+ dest_contact->m_feature1 = source_contact->m_feature1;\
+ dest_contact->m_feature2 = source_contact->m_feature2;\
+}\
+
+//! Merges duplicate contacts with minimum depth criterion
+void gim_merge_contacts(GDYNAMIC_ARRAY * source_contacts,
+ GDYNAMIC_ARRAY * dest_contacts);
+
+
+//! Merges to an unique contact
+void gim_merge_contacts_unique(GDYNAMIC_ARRAY * source_contacts,
+ GDYNAMIC_ARRAY * dest_contacts);
+
+//! @}
+#endif // GIM_CONTACT_H_INCLUDED
diff --git a/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_geometry.h b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_geometry.h new file mode 100644 index 0000000..f2b5ccb --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_geometry.h @@ -0,0 +1,1885 @@ +#ifndef GIM_VECTOR_H_INCLUDED
+#define GIM_VECTOR_H_INCLUDED
+
+/*! \file gim_geometry.h
+\author Francisco León
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include "GIMPACT/gim_math.h"
+
+/*! \defgroup GEOMETRIC_TYPES
+\brief
+Basic types and constants for geometry
+*/
+//! @{
+
+//! Integer vector 2D
+typedef GINT32 vec2i[2];
+//! Integer vector 3D
+typedef GINT32 vec3i[3];
+//! Integer vector 4D
+typedef GINT32 vec4i[4];
+
+//! Float vector 2D
+typedef GREAL vec2f[2];
+//! Float vector 3D
+typedef GREAL vec3f[3];
+//! Float vector 4D
+typedef GREAL vec4f[4];
+
+//! Matrix 2D, row ordered
+typedef GREAL mat2f[2][2];
+//! Matrix 3D, row ordered
+typedef GREAL mat3f[3][3];
+//! Matrix 4D, row ordered
+typedef GREAL mat4f[4][4];
+
+//! Quaternion
+typedef GREAL quatf[4];
+
+//! Axis aligned box
+struct aabb3f{
+ aabb3f() {}
+
+ template<typename tboundfloat>
+ aabb3f(const tboundfloat &_minX, const tboundfloat &_maxX, const tboundfloat &_minY, const tboundfloat &_maxY, const tboundfloat &_minZ, const tboundfloat &_maxZ):
+ minX((GREAL)_minX),
+ maxX((GREAL)_maxX),
+ minY((GREAL)_minY),
+ maxY((GREAL)_maxY),
+ minZ((GREAL)_minZ),
+ maxZ((GREAL)_maxZ)
+ {
+ }
+
+ GREAL minX;
+ GREAL maxX;
+ GREAL minY;
+ GREAL maxY;
+ GREAL minZ;
+ GREAL maxZ;
+};
+//typedef struct _aabb3f aabb3f;
+//! @}
+
+
+/*! \defgroup VECTOR_OPERATIONS
+Operations for vectors : vec2f,vec3f and vec4f
+*/
+//! @{
+
+//! Zero out a 2D vector
+#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; \
+}\
+
+
+/// Zero out a 4D vector
+#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]; \
+}\
+
+
+/// Copy 3D vector
+#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]; \
+}\
+
+
+/// Vector difference
+#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]; \
+}\
+
+
+/// 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]; \
+}\
+
+
+/// Vector sum
+#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]; \
+}\
+
+
+/// 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]; \
+}\
+
+
+/// scalar times vector
+#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]; \
+}\
+
+
+/// 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]; \
+}\
+
+
+/// accumulate scaled vector
+#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]; \
+}\
+
+
+/// 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]; \
+}\
+
+
+/// Vector dot product
+#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])
+
+/// 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])
+
+/// vector impact parameter (squared)
+#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); \
+}\
+
+/// Vector length
+#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);\
+}\
+
+
+/// Vector length
+#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);\
+}\
+
+
+/// Vector inv length
+#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);\
+}\
+
+
+
+/// distance between two points
+#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);\
+}\
+
+
+/// Vector length
+#define VEC_NORMALIZE(a) { \
+ GREAL len;\
+ VEC_INV_LENGTH(a,len); \
+ if(len<G_REAL_INFINITY)\
+ {\
+ a[0] *= len; \
+ a[1] *= len; \
+ a[2] *= len; \
+ } \
+}\
+
+/// Set Vector size
+#define VEC_RENORMALIZE(a,newlen) { \
+ GREAL len;\
+ VEC_INV_LENGTH(a,len); \
+ if(len<G_REAL_INFINITY)\
+ {\
+ len *= newlen;\
+ a[0] *= len; \
+ a[1] *= len; \
+ a[2] *= len; \
+ } \
+}\
+
+/// Vector cross
+#define VEC_CROSS(c,a,b) \
+{ \
+ c[0] = (a)[1] * (b)[2] - (a)[2] * (b)[1]; \
+ c[1] = (a)[2] * (b)[0] - (a)[0] * (b)[2]; \
+ c[2] = (a)[0] * (b)[1] - (a)[1] * (b)[0]; \
+}\
+
+
+/*! Vector perp -- assumes that n is of unit length
+ * accepts vector v, subtracts out any component parallel to n */
+#define VEC_PERPENDICULAR(vp,v,n) \
+{ \
+ GREAL dot = VEC_DOT(v, n); \
+ vp[0] = (v)[0] - dot*(n)[0]; \
+ vp[1] = (v)[1] - dot*(n)[1]; \
+ vp[2] = (v)[2] - dot*(n)[2]; \
+}\
+
+
+/*! Vector parallel -- assumes that n is of unit length */
+#define VEC_PARALLEL(vp,v,n) \
+{ \
+ GREAL dot = VEC_DOT(v, n); \
+ vp[0] = (dot) * (n)[0]; \
+ vp[1] = (dot) * (n)[1]; \
+ vp[2] = (dot) * (n)[2]; \
+}\
+
+/*! Same as Vector parallel -- n can have any length
+ * accepts vector v, subtracts out any component perpendicular to n */
+#define VEC_PROJECT(vp,v,n) \
+{ \
+ GREAL scalar = VEC_DOT(v, n); \
+ scalar/= VEC_DOT(n, n); \
+ vp[0] = (scalar) * (n)[0]; \
+ vp[1] = (scalar) * (n)[1]; \
+ vp[2] = (scalar) * (n)[2]; \
+}\
+
+
+/*! accepts vector v*/
+#define VEC_UNPROJECT(vp,v,n) \
+{ \
+ GREAL scalar = VEC_DOT(v, n); \
+ scalar = VEC_DOT(n, n)/scalar; \
+ vp[0] = (scalar) * (n)[0]; \
+ vp[1] = (scalar) * (n)[1]; \
+ vp[2] = (scalar) * (n)[2]; \
+}\
+
+
+/*! Vector reflection -- assumes n is of unit length
+ Takes vector v, reflects it against reflector n, and returns vr */
+#define VEC_REFLECT(vr,v,n) \
+{ \
+ GREAL dot = VEC_DOT(v, n); \
+ vr[0] = (v)[0] - 2.0 * (dot) * (n)[0]; \
+ vr[1] = (v)[1] - 2.0 * (dot) * (n)[1]; \
+ vr[2] = (v)[2] - 2.0 * (dot) * (n)[2]; \
+}\
+
+
+/*! Vector blending
+Takes two vectors a, b, blends them together with two scalars */
+#define VEC_BLEND_AB(vr,sa,a,sb,b) \
+{ \
+ vr[0] = (sa) * (a)[0] + (sb) * (b)[0]; \
+ vr[1] = (sa) * (a)[1] + (sb) * (b)[1]; \
+ vr[2] = (sa) * (a)[2] + (sb) * (b)[2]; \
+}\
+
+/*! Vector blending
+Takes two vectors a, b, blends them together with s <=1 */
+#define VEC_BLEND(vr,a,b,s) VEC_BLEND_AB(vr,1-s,a,sb,s)
+
+#define VEC_SET3(a,b,op,c) a[0]=b[0] op c[0]; a[1]=b[1] op c[1]; a[2]=b[2] op c[2];
+//! @}
+
+
+/*! \defgroup MATRIX_OPERATIONS
+Operations for matrices : mat2f, mat3f and mat4f
+*/
+//! @{
+
+/// 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; \
+}\
+
+/*! 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; \
+}\
+
+/*! 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; \
+}\
+
+/*! 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; \
+}\
+
+/*! 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; \
+}\
+
+/*! 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; \
+}\
+
+/*! 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]; \
+ \
+}\
+
+
+/*! 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]; \
+}\
+
+
+/*! 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]; \
+}\
+
+
+/*! 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]; \
+}\
+
+
+/*! 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]; \
+}\
+
+
+/*! 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]; \
+}\
+
+
+/*! 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]; \
+}\
+
+
+/*! 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]; \
+}\
+
+
+/*! 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]; \
+}\
+
+
+/*! 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]; \
+}\
+
+
+/*! 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]; \
+}\
+
+
+/*! 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]; \
+}\
+
+
+/*! 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]; \
+}\
+
+/*! 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]; \
+ \
+}\
+
+/*! 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]; \
+}\
+
+
+/*! 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];\
+}\
+
+
+/*! 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]; \
+}\
+
+
+/*! 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]; \
+}\
+
+
+/*! 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]; \
+}\
+
+/*! matrix times vector
+v is a vec3f
+and m is a mat4f<br>
+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]; \
+}\
+
+/*! 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]; \
+}\
+
+
+/*! 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]; \
+}\
+
+
+/** inverse transpose of matrix times vector
+ *
+ * This macro computes inverse transpose of matrix m,
+ * and multiplies vector v into it, to yeild vector p
+ *
+ * DANGER !!! Do Not use this on normal vectors!!!
+ * 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; \
+ } \
+}\
+
+
+/** transform normal vector by inverse transpose of matrix
+ * and then renormalize the vector
+ *
+ * This macro computes inverse transpose of matrix m,
+ * and multiplies vector v into it, to yeild vector p
+ * Vector p is then normalized.
+ */
+#define NORM_XFORM_2X2(p,m,v) \
+{ \
+ double 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]; \
+}\
+
+
+/** 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]; \
+}\
+
+
+/** 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]; \
+}\
+
+
+/** 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]; \
+}\
+
+
+/** 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]; \
+}\
+
+
+/** 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]; \
+}\
+
+
+/** 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]; \
+}\
+
+
+/** 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]); \
+}\
+
+
+/** i,j,th cofactor of a 4x4 matrix
+ *
+ */
+#define COFACTOR_4X4_IJ(fac,m,i,j) \
+{ \
+ int __ii[4], __jj[4], __k; \
+ \
+ for (__k=0; __k<i; __k++) __ii[__k] = __k; \
+ for (__k=i; __k<3; __k++) __ii[__k] = __k+1; \
+ for (__k=0; __k<j; __k++) __jj[__k] = __k; \
+ for (__k=j; __k<3; __k++) __jj[__k] = __k+1; \
+ \
+ (fac) = m[__ii[0]][__jj[0]] * (m[__ii[1]][__jj[1]]*m[__ii[2]][__jj[2]] \
+ - m[__ii[1]][__jj[2]]*m[__ii[2]][__jj[1]]); \
+ (fac) -= m[__ii[0]][__jj[1]] * (m[__ii[1]][__jj[0]]*m[__ii[2]][__jj[2]] \
+ - m[__ii[1]][__jj[2]]*m[__ii[2]][__jj[0]]);\
+ (fac) += m[__ii[0]][__jj[2]] * (m[__ii[1]][__jj[0]]*m[__ii[2]][__jj[1]] \
+ - m[__ii[1]][__jj[1]]*m[__ii[2]][__jj[0]]);\
+ \
+ __k = i+j; \
+ if ( __k != (__k/2)*2) { \
+ (fac) = -(fac); \
+ } \
+}\
+
+
+/** determinant of matrix
+ *
+ * Computes determinant of matrix m, returning d
+ */
+#define DETERMINANT_4X4(d,m) \
+{ \
+ double cofac; \
+ COFACTOR_4X4_IJ (cofac, m, 0, 0); \
+ d = m[0][0] * cofac; \
+ COFACTOR_4X4_IJ (cofac, m, 0, 1); \
+ d += m[0][1] * cofac; \
+ COFACTOR_4X4_IJ (cofac, m, 0, 2); \
+ d += m[0][2] * cofac; \
+ COFACTOR_4X4_IJ (cofac, m, 0, 3); \
+ d += m[0][3] * cofac; \
+}\
+
+
+/** cofactor of matrix
+ *
+ * Computes cofactor of matrix m, returning a
+ */
+#define COFACTOR_2X2(a,m) \
+{ \
+ a[0][0] = (m)[1][1]; \
+ a[0][1] = - (m)[1][0]; \
+ a[1][0] = - (m)[0][1]; \
+ a[1][1] = (m)[0][0]; \
+}\
+
+
+/** cofactor of matrix
+ *
+ * Computes cofactor of matrix m, returning a
+ */
+#define COFACTOR_3X3(a,m) \
+{ \
+ a[0][0] = m[1][1]*m[2][2] - m[1][2]*m[2][1]; \
+ a[0][1] = - (m[1][0]*m[2][2] - m[2][0]*m[1][2]); \
+ a[0][2] = m[1][0]*m[2][1] - m[1][1]*m[2][0]; \
+ a[1][0] = - (m[0][1]*m[2][2] - m[0][2]*m[2][1]); \
+ a[1][1] = m[0][0]*m[2][2] - m[0][2]*m[2][0]; \
+ a[1][2] = - (m[0][0]*m[2][1] - m[0][1]*m[2][0]); \
+ a[2][0] = m[0][1]*m[1][2] - m[0][2]*m[1][1]; \
+ a[2][1] = - (m[0][0]*m[1][2] - m[0][2]*m[1][0]); \
+ a[2][2] = m[0][0]*m[1][1] - m[0][1]*m[1][0]); \
+}\
+
+
+/** cofactor of matrix
+ *
+ * Computes cofactor of matrix m, returning a
+ */
+#define COFACTOR_4X4(a,m) \
+{ \
+ int i,j; \
+ \
+ for (i=0; i<4; i++) { \
+ for (j=0; j<4; j++) { \
+ COFACTOR_4X4_IJ (a[i][j], m, i, j); \
+ } \
+ } \
+}\
+
+
+/** adjoint of matrix
+ *
+ * Computes adjoint of matrix m, returning a
+ * (Note that adjoint is just the transpose of the cofactor matrix)
+ */
+#define ADJOINT_2X2(a,m) \
+{ \
+ a[0][0] = (m)[1][1]; \
+ a[1][0] = - (m)[1][0]; \
+ a[0][1] = - (m)[0][1]; \
+ a[1][1] = (m)[0][0]; \
+}\
+
+
+/** adjoint of matrix
+ *
+ * Computes adjoint of matrix m, returning a
+ * (Note that adjoint is just the transpose of the cofactor matrix)
+ */
+#define ADJOINT_3X3(a,m) \
+{ \
+ a[0][0] = m[1][1]*m[2][2] - m[1][2]*m[2][1]; \
+ a[1][0] = - (m[1][0]*m[2][2] - m[2][0]*m[1][2]); \
+ a[2][0] = m[1][0]*m[2][1] - m[1][1]*m[2][0]; \
+ a[0][1] = - (m[0][1]*m[2][2] - m[0][2]*m[2][1]); \
+ a[1][1] = m[0][0]*m[2][2] - m[0][2]*m[2][0]; \
+ a[2][1] = - (m[0][0]*m[2][1] - m[0][1]*m[2][0]); \
+ a[0][2] = m[0][1]*m[1][2] - m[0][2]*m[1][1]; \
+ a[1][2] = - (m[0][0]*m[1][2] - m[0][2]*m[1][0]); \
+ a[2][2] = m[0][0]*m[1][1] - m[0][1]*m[1][0]); \
+}\
+
+
+/** adjoint of matrix
+ *
+ * Computes adjoint of matrix m, returning a
+ * (Note that adjoint is just the transpose of the cofactor matrix)
+ */
+#define ADJOINT_4X4(a,m) \
+{ \
+ char _i_,_j_; \
+ \
+ for (_i_=0; _i_<4; _i_++) { \
+ for (_j_=0; _j_<4; _j_++) { \
+ COFACTOR_4X4_IJ (a[_j_][_i_], m, _i_, _j_); \
+ } \
+ } \
+}\
+
+
+/** compute adjoint of matrix and scale
+ *
+ * Computes adjoint of matrix m, scales it by s, returning a
+ */
+#define SCALE_ADJOINT_2X2(a,s,m) \
+{ \
+ a[0][0] = (s) * m[1][1]; \
+ a[1][0] = - (s) * m[1][0]; \
+ a[0][1] = - (s) * m[0][1]; \
+ a[1][1] = (s) * m[0][0]; \
+}\
+
+
+/** compute adjoint of matrix and scale
+ *
+ * Computes adjoint of matrix m, scales it by s, returning a
+ */
+#define SCALE_ADJOINT_3X3(a,s,m) \
+{ \
+ a[0][0] = (s) * (m[1][1] * m[2][2] - m[1][2] * m[2][1]); \
+ a[1][0] = (s) * (m[1][2] * m[2][0] - m[1][0] * m[2][2]); \
+ a[2][0] = (s) * (m[1][0] * m[2][1] - m[1][1] * m[2][0]); \
+ \
+ a[0][1] = (s) * (m[0][2] * m[2][1] - m[0][1] * m[2][2]); \
+ a[1][1] = (s) * (m[0][0] * m[2][2] - m[0][2] * m[2][0]); \
+ a[2][1] = (s) * (m[0][1] * m[2][0] - m[0][0] * m[2][1]); \
+ \
+ a[0][2] = (s) * (m[0][1] * m[1][2] - m[0][2] * m[1][1]); \
+ a[1][2] = (s) * (m[0][2] * m[1][0] - m[0][0] * m[1][2]); \
+ a[2][2] = (s) * (m[0][0] * m[1][1] - m[0][1] * m[1][0]); \
+}\
+
+
+/** compute adjoint of matrix and scale
+ *
+ * Computes adjoint of matrix m, scales it by s, returning a
+ */
+#define SCALE_ADJOINT_4X4(a,s,m) \
+{ \
+ char _i_,_j_; \
+ for (_i_=0; _i_<4; _i_++) { \
+ for (_j_=0; _j_<4; _j_++) { \
+ COFACTOR_4X4_IJ (a[_j_][_i_], m, _i_, _j_); \
+ a[_j_][_i_] *= s; \
+ } \
+ } \
+}\
+
+/** inverse of matrix
+ *
+ * Compute inverse of matrix a, returning determinant m and
+ * inverse b
+ */
+#define INVERT_2X2(b,det,a) \
+{ \
+ GREAL _tmp_; \
+ DETERMINANT_2X2 (det, a); \
+ _tmp_ = 1.0 / (det); \
+ SCALE_ADJOINT_2X2 (b, _tmp_, a); \
+}\
+
+
+/** inverse of matrix
+ *
+ * Compute inverse of matrix a, returning determinant m and
+ * inverse b
+ */
+#define INVERT_3X3(b,det,a) \
+{ \
+ GREAL _tmp_; \
+ DETERMINANT_3X3 (det, a); \
+ _tmp_ = 1.0 / (det); \
+ SCALE_ADJOINT_3X3 (b, _tmp_, a); \
+}\
+
+
+/** inverse of matrix
+ *
+ * Compute inverse of matrix a, returning determinant m and
+ * inverse b
+ */
+#define INVERT_4X4(b,det,a) \
+{ \
+ GREAL _tmp_; \
+ DETERMINANT_4X4 (det, a); \
+ _tmp_ = 1.0 / (det); \
+ SCALE_ADJOINT_4X4 (b, _tmp_, a); \
+}\
+
+//! @}
+
+/*! \defgroup BOUND_AABB_OPERATIONS
+*/
+//! @{
+
+//!Initializes an AABB
+#define INVALIDATE_AABB(aabb) {\
+ (aabb).minX = G_REAL_INFINITY;\
+ (aabb).maxX = -G_REAL_INFINITY;\
+ (aabb).minY = G_REAL_INFINITY;\
+ (aabb).maxY = -G_REAL_INFINITY;\
+ (aabb).minZ = G_REAL_INFINITY;\
+ (aabb).maxZ = -G_REAL_INFINITY;\
+}\
+
+#define AABB_GET_MIN(aabb,vmin) {\
+ vmin[0] = (aabb).minX;\
+ vmin[1] = (aabb).minY;\
+ vmin[2] = (aabb).minZ;\
+}\
+
+#define AABB_GET_MAX(aabb,vmax) {\
+ vmax[0] = (aabb).maxX;\
+ vmax[1] = (aabb).maxY;\
+ vmax[2] = (aabb).maxZ;\
+}\
+
+//!Copy boxes
+#define AABB_COPY(dest_aabb,src_aabb)\
+{\
+ (dest_aabb).minX = (src_aabb).minX;\
+ (dest_aabb).maxX = (src_aabb).maxX;\
+ (dest_aabb).minY = (src_aabb).minY;\
+ (dest_aabb).maxY = (src_aabb).maxY;\
+ (dest_aabb).minZ = (src_aabb).minZ;\
+ (dest_aabb).maxZ = (src_aabb).maxZ;\
+}\
+
+//! Computes an Axis aligned box from a triangle
+#define COMPUTEAABB_FOR_TRIANGLE(aabb,V1,V2,V3) {\
+ (aabb).minX = MIN3(V1[0],V2[0],V3[0]);\
+ (aabb).maxX = MAX3(V1[0],V2[0],V3[0]);\
+ (aabb).minY = MIN3(V1[1],V2[1],V3[1]);\
+ (aabb).maxY = MAX3(V1[1],V2[1],V3[1]);\
+ (aabb).minZ = MIN3(V1[2],V2[2],V3[2]);\
+ (aabb).maxZ = MAX3(V1[2],V2[2],V3[2]);\
+}\
+
+//! Merge two boxes to destaabb
+#define MERGEBOXES(destaabb,aabb) {\
+ (destaabb).minX = MIN((aabb).minX,(destaabb).minX);\
+ (destaabb).minY = MIN((aabb).minY,(destaabb).minY);\
+ (destaabb).minZ = MIN((aabb).minZ,(destaabb).minZ);\
+ (destaabb).maxX = MAX((aabb).maxX,(destaabb).maxX);\
+ (destaabb).maxY = MAX((aabb).maxY,(destaabb).maxY);\
+ (destaabb).maxZ = MAX((aabb).maxZ,(destaabb).maxZ);\
+}\
+
+//! Extends the box
+#define AABB_POINT_EXTEND(destaabb,p) {\
+ (destaabb).minX = MIN(p[0],(destaabb).minX);\
+ (destaabb).maxX = MAX(p[0],(destaabb).maxX);\
+ (destaabb).minY = MIN(p[1],(destaabb).minY);\
+ (destaabb).maxY = MAX(p[1],(destaabb).maxY);\
+ (destaabb).minZ = MIN(p[2],(destaabb).minZ);\
+ (destaabb).maxZ = MAX(p[2],(destaabb).maxZ);\
+}\
+
+//! Finds the intersection box of two boxes
+#define BOXINTERSECTION(aabb1, aabb2, iaabb) {\
+ (iaabb).minX = MAX((aabb1).minX,(aabb2).minX);\
+ (iaabb).minY = MAX((aabb1).minY,(aabb2).minY);\
+ (iaabb).minZ = MAX((aabb1).minZ,(aabb2).minZ);\
+ (iaabb).maxX = MIN((aabb1).maxX,(aabb2).maxX);\
+ (iaabb).maxY = MIN((aabb1).maxY,(aabb2).maxY);\
+ (iaabb).maxZ = MIN((aabb1).maxZ,(aabb2).maxZ);\
+}\
+
+//! Determines if two aligned boxes do intersect
+#define AABBCOLLISION(intersected,aabb1,aabb2) {\
+ intersected = 1;\
+ if ((aabb1).minX > (aabb2).maxX ||\
+ (aabb1).maxX < (aabb2).minX ||\
+ (aabb1).minY > (aabb2).maxY ||\
+ (aabb1).maxY < (aabb2).minY ||\
+ (aabb1).minZ > (aabb2).maxZ ||\
+ (aabb1).maxZ < (aabb2).minZ )\
+ {\
+ intersected = 0;\
+ }\
+}\
+
+#define AXIS_INTERSECT(min,max, a, d,tfirst, tlast,is_intersected) {\
+ if(IS_ZERO(d))\
+ {\
+ is_intersected = !(a < min || a > max);\
+ }\
+ else\
+ {\
+ GREAL a0, a1;\
+ a0 = (min - a) / (d);\
+ a1 = (max - a) / (d);\
+ if(a0 > a1) SWAP_NUMBERS(a0, a1);\
+ tfirst = MAX(a0, tfirst);\
+ tlast = MIN(a1, tlast);\
+ if (tlast < tfirst)\
+ {\
+ is_intersected = 0;\
+ }\
+ else\
+ {\
+ is_intersected = 1;\
+ }\
+ }\
+}\
+
+/*! \brief Finds the Ray intersection parameter.
+
+\param aabb Aligned box
+\param vorigin A vec3f with the origin of the ray
+\param vdir A vec3f with the direction of the ray
+\param tparam Output parameter
+\param tmax Max lenght of the ray
+\param is_intersected 1 if the ray collides the box, else false
+
+*/
+#define BOX_INTERSECTS_RAY(aabb, vorigin, vdir, tparam, tmax,is_intersected) { \
+ GREAL _tfirst = 0.0f, _tlast = tmax;\
+ AXIS_INTERSECT(aabb.minX,aabb.maxX,vorigin[0], vdir[0], _tfirst, _tlast,is_intersected);\
+ if(is_intersected)\
+ {\
+ AXIS_INTERSECT(aabb.minY,aabb.maxY,vorigin[1], vdir[1], _tfirst, _tlast,is_intersected);\
+ }\
+ if(is_intersected)\
+ {\
+ AXIS_INTERSECT(aabb.minZ,aabb.maxZ,vorigin[2], vdir[2], _tfirst, _tlast,is_intersected);\
+ }\
+ tparam = _tfirst;\
+}\
+
+#define AABB_PROJECTION_INTERVAL(aabb,direction, vmin, vmax)\
+{\
+ GREAL _center[] = {(aabb.minX + aabb.maxX)*0.5f, (aabb.minY + aabb.maxY)*0.5f, (aabb.minZ + aabb.maxZ)*0.5f};\
+ \
+ GREAL _extend[] = {aabb.maxX-_center[0],aabb.maxY-_center[1],aabb.maxZ-_center[2]};\
+ GREAL _fOrigin = VEC_DOT(direction,_center);\
+ GREAL _fMaximumExtent = _extend[0]*fabsf(direction[0]) + \
+ _extend[1]*fabsf(direction[1]) + \
+ _extend[2]*fabsf(direction[2]); \
+\
+ vmin = _fOrigin - _fMaximumExtent; \
+ vmax = _fOrigin + _fMaximumExtent; \
+}\
+
+/*!
+classify values:
+<ol>
+<li> 0 : In back of plane
+<li> 1 : Spanning
+<li> 2 : In front of
+</ol>
+*/
+#define PLANE_CLASSIFY_BOX(plane,aabb,classify)\
+{\
+ GREAL _fmin,_fmax; \
+ AABB_PROJECTION_INTERVAL(aabb,plane, _fmin, _fmax); \
+ if(plane[3] >= _fmax) \
+ { \
+ classify = 0;/*In back of*/ \
+ } \
+ else \
+ { \
+ if(plane[3]+0.000001f>=_fmin) \
+ { \
+ classify = 1;/*Spanning*/ \
+ } \
+ else \
+ { \
+ classify = 2;/*In front of*/ \
+ } \
+ } \
+}\
+//! @}
+
+/*! \defgroup GEOMETRIC_OPERATIONS
+*/
+//! @{
+
+
+#define PLANEDIREPSILON 0.0000001f
+#define PARALELENORMALS 0.000001f
+
+#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); \
+}\
+
+/// plane is a vec4f
+#define TRIANGLE_PLANE(v1,v2,v3,plane) {\
+ TRIANGLE_NORMAL(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 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 POINT_IN_HULL(point,planes,plane_count,outside)\
+{\
+ GREAL _dis;\
+ outside = 0;\
+ GUINT32 _i = 0;\
+ do\
+ {\
+ _dis = DISTANCE_PLANE_POINT(planes[_i],point);\
+ if(_dis>0.0f) outside = 1;\
+ _i++;\
+ }while(_i<plane_count&&outside==0);\
+}\
+
+
+#define PLANE_CLIP_SEGMENT(s1,s2,plane,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); \
+}\
+
+//! Confirms if the plane intersect the edge or nor
+/*!
+intersection type must have the following values
+<ul>
+<li> 0 : Segment in front of plane, s1 closest
+<li> 1 : Segment in front of plane, s2 closest
+<li> 2 : Segment in back of plane, s1 closest
+<li> 3 : Segment in back of plane, s2 closest
+<li> 4 : Segment collides plane, s1 in back
+<li> 5 : Segment collides plane, s2 in back
+</ul>
+*/
+#define PLANE_CLIP_SEGMENT2(s1,s2,plane,clipped,intersection_type) \
+{\
+ GREAL _dis1,_dis2;\
+ _dis1 = DISTANCE_PLANE_POINT(plane,s1);\
+ _dis2 = DISTANCE_PLANE_POINT(plane,s2);\
+ if(_dis1 >-G_EPSILON && _dis2 >-G_EPSILON)\
+ {\
+ if(_dis1<_dis2) intersection_type = 0;\
+ else intersection_type = 1;\
+ }\
+ else if(_dis1 <G_EPSILON && _dis2 <G_EPSILON)\
+ {\
+ if(_dis1>_dis2) intersection_type = 2;\
+ else intersection_type = 3; \
+ }\
+ else\
+ {\
+ if(_dis1<_dis2) intersection_type = 4;\
+ else intersection_type = 5;\
+ VEC_DIFF(clipped,s2,s1);\
+ _dis2 = VEC_DOT(clipped,plane);\
+ VEC_SCALE(clipped,-_dis1/_dis2,clipped);\
+ VEC_SUM(clipped,clipped,s1); \
+ }\
+}\
+
+//! Confirms if the plane intersect the edge or not
+/*!
+clipped1 and clipped2 are the vertices behind the plane.
+clipped1 is the closest
+
+intersection_type must have the following values
+<ul>
+<li> 0 : Segment in front of plane, s1 closest
+<li> 1 : Segment in front of plane, s2 closest
+<li> 2 : Segment in back of plane, s1 closest
+<li> 3 : Segment in back of plane, s2 closest
+<li> 4 : Segment collides plane, s1 in back
+<li> 5 : Segment collides plane, s2 in back
+</ul>
+*/
+#define PLANE_CLIP_SEGMENT_CLOSEST(s1,s2,plane,clipped1,clipped2,intersection_type)\
+{\
+ PLANE_CLIP_SEGMENT2(s1,s2,plane,clipped1,intersection_type);\
+ if(intersection_type == 0)\
+ {\
+ VEC_COPY(clipped1,s1);\
+ VEC_COPY(clipped2,s2);\
+ }\
+ else if(intersection_type == 1)\
+ {\
+ VEC_COPY(clipped1,s2);\
+ VEC_COPY(clipped2,s1);\
+ }\
+ else if(intersection_type == 2)\
+ {\
+ VEC_COPY(clipped1,s1);\
+ VEC_COPY(clipped2,s2);\
+ }\
+ else if(intersection_type == 3)\
+ {\
+ VEC_COPY(clipped1,s2);\
+ VEC_COPY(clipped2,s1);\
+ }\
+ else if(intersection_type == 4)\
+ { \
+ VEC_COPY(clipped2,s1);\
+ }\
+ else if(intersection_type == 5)\
+ { \
+ VEC_COPY(clipped2,s2);\
+ }\
+}\
+
+
+//! Finds the 2 smallest cartesian coordinates of a plane normal
+#define PLANE_MINOR_AXES(plane, i0, i1)\
+{\
+ GREAL A[] = {fabs(plane[0]),fabs(plane[1]),fabs(plane[2])};\
+ if(A[0]>A[1])\
+ {\
+ if(A[0]>A[2])\
+ {\
+ i0=1; /* A[0] is greatest */ \
+ i1=2;\
+ }\
+ else \
+ {\
+ i0=0; /* A[2] is greatest */ \
+ i1=1; \
+ }\
+ }\
+ else /* A[0]<=A[1] */ \
+ {\
+ if(A[2]>A[1]) \
+ { \
+ i0=0; /* A[2] is greatest */ \
+ i1=1; \
+ }\
+ else \
+ {\
+ i0=0; /* A[1] is greatest */ \
+ i1=2; \
+ }\
+ } \
+}\
+
+//! Ray plane collision
+#define RAY_PLANE_COLLISION(plane,vDir,vPoint,pout,tparam,does_intersect)\
+{\
+ GREAL _dis,_dotdir; \
+ _dotdir = VEC_DOT(plane,vDir);\
+ if(_dotdir<PLANEDIREPSILON)\
+ {\
+ does_intersect = 0;\
+ }\
+ else\
+ {\
+ _dis = DISTANCE_PLANE_POINT(plane,vPoint); \
+ tparam = -_dis/_dotdir;\
+ VEC_SCALE(pout,tparam,vDir);\
+ VEC_SUM(pout,vPoint,pout); \
+ does_intersect = 1;\
+ }\
+}\
+
+//! Bidireccional ray
+#define LINE_PLANE_COLLISION(plane,vDir,vPoint,pout,tparam, tmin, tmax)\
+{\
+ tparam = -DISTANCE_PLANE_POINT(plane,vPoint);\
+ tparam /= VEC_DOT(plane,vDir);\
+ tparam = CLAMP(tparam,tmin,tmax);\
+ VEC_SCALE(pout,tparam,vDir);\
+ VEC_SUM(pout,vPoint,pout); \
+}\
+
+/*! \brief Returns the Ray on which 2 planes intersect if they do.
+ Written by Rodrigo Hernandez on ODE convex collision
+
+ \param p1 Plane 1
+ \param p2 Plane 2
+ \param p Contains the origin of the ray upon returning if planes intersect
+ \param d Contains the direction of the ray upon returning if planes intersect
+ \param dointersect 1 if the planes intersect, 0 if paralell.
+
+*/
+#define INTERSECT_PLANES(p1,p2,p,d,dointersect) \
+{ \
+ VEC_CROSS(d,p1,p2); \
+ GREAL denom = VEC_DOT(d, d);\
+ if (IS_ZERO(denom)) \
+ { \
+ dointersect = 0; \
+ } \
+ else \
+ { \
+ 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; \
+ dointersect = 1; \
+ }\
+}\
+
+//***************** SEGMENT and LINE FUNCTIONS **********************************///
+
+/*! Finds the closest point(cp) to (v) on a segment (e1,e2)
+ */
+#define CLOSEST_POINT_ON_SEGMENT(cp,v,e1,e2) \
+{ \
+ 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)\
+ {\
+ VEC_COPY(cp,e1);\
+ }\
+ else if(_scalar >1.0f)\
+ {\
+ VEC_COPY(cp,e2);\
+ }\
+ else \
+ {\
+ 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
+\param point1 Point of line 1
+\param dir2 Direction of line 2
+\param point2 Point of line 2
+\param t1 Result Parameter for line 1
+\param t2 Result Parameter for line 2
+\param dointersect 0 if the lines won't intersect, else 1
+
+*/
+#define LINE_INTERSECTION_PARAMS(dir1,point1, dir2, point2,t1,t2,dointersect) {\
+ 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(IS_ZERO(det))\
+ {\
+ dointersect = 0;\
+ }\
+ else\
+ {\
+ t1 = (e1e2*p1p2e2 - e2e2*p1p2e1)/det;\
+ t2 = (e1e1*p1p2e2 - e1e2*p1p2e1)/det;\
+ dointersect = 1;\
+ }\
+}\
+
+//! Find closest points on segments
+#define SEGMENT_COLLISION(vA1,vA2,vB1,vB2,vPointA,vPointB)\
+{\
+ vec3f _AD,_BD,_N;\
+ vec4f _M;\
+ VEC_DIFF(_AD,vA2,vA1);\
+ VEC_DIFF(_BD,vB2,vB1);\
+ VEC_CROSS(_N,_AD,_BD);\
+ VEC_CROSS(_M,_N,_BD);\
+ _M[3] = VEC_DOT(_M,vB1);\
+ float _tp; \
+ LINE_PLANE_COLLISION(_M,_AD,vA1,vPointA,_tp,0.0f, 1.0f);\
+ /*Closest point on segment*/ \
+ VEC_DIFF(vPointB,vPointA,vB1);\
+ _tp = VEC_DOT(vPointB, _BD); \
+ _tp/= VEC_DOT(_BD, _BD); \
+ _tp = CLAMP(_tp,0.0f,1.0f); \
+ VEC_SCALE(vPointB,_tp,_BD);\
+ VEC_SUM(vPointB,vPointB,vB1);\
+}\
+
+//! @}
+
+///Additional Headers for Collision
+#include "GIMPACT/gim_tri_collision.h"
+#include "GIMPACT/gim_tri_sphere_collision.h"
+#include "GIMPACT/gim_tri_capsule_collision.h"
+
+#endif // GIM_VECTOR_H_INCLUDED
diff --git a/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_math.h b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_math.h new file mode 100644 index 0000000..97fdad2 --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_math.h @@ -0,0 +1,164 @@ +#ifndef GIM_MATH_H_INCLUDED
+#define GIM_MATH_H_INCLUDED
+
+/*! \file gim_math.h
+\author Francisco León
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "config.h"
+
+#include <math.h>
+#include <float.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#elif defined(_MSC_VER)
+typedef __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+#elif defined(__GNUC__)
+#include <inttypes.h>
+#else
+#error "GIMPACT: Must define int32_t and uint32_t"
+#endif
+
+
+/*! \defgroup BASIC_TYPES
+Basic types and constants
+Conventions:
+Types starting with G
+Constants starting with G_
+*/
+//! @{
+/*! Types */
+#define GREAL float
+#define GINT32 int32_t
+#define GUINT32 uint32_t
+
+#ifdef GPTR
+#undef GPTR
+#endif
+#define GPTR void*
+
+/*! Constants for integers*/
+#define GUINT32_BIT_COUNT 32
+#define GUINT32_EXPONENT 5
+
+#define G_FASTMATH 1
+#define G_PI 3.14159265358979f
+#define G_HALF_PI 1.5707963f
+//267948966
+#define G_TWO_PI 6.28318530f
+//71795864
+#define G_ROOT3 1.73205f
+#define G_ROOT2 1.41421f
+#define G_UINT_INFINITY 65534
+#define G_REAL_INFINITY FLT_MAX
+#define G_SIGN_BITMASK 0x80000000
+#define G_USE_EPSILON_TEST
+#define G_EPSILON 0.0000001f
+//! @}
+
+/*! \defgroup MATH_FUNCTIONS
+mathematical functions
+*/
+//! @{
+#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 IR(x) ((GUINT32&)(x))
+
+//! Signed integer representation of a floating-point value.
+#define SIR(x) ((GINT32&)(x))
+
+//! Absolute integer representation of a floating-point value
+#define AIR(x) (IR(x)&0x7fffffff)
+
+//! Floating-point representation of an integer value.
+#define FR(x) ((GREAL&)(x))
+
+#define MAX(a,b) ((a)<(b)?(b):(a))
+#define MIN(a,b) ((a)>(b)?(b):(a))
+
+#define MAX3(a,b,c) MAX(a,MAX(b,c))
+#define MIN3(a,b,c) MIN(a,MIN(b,c))
+
+#define IS_ZERO(value) ((value) < G_EPSILON && (value) > -G_EPSILON)
+
+#define IS_NEGATIVE(value) ((value) <= -G_EPSILON)
+
+#define IS_POSISITVE(value) ((value) >= G_EPSILON)
+
+///returns a clamped number
+#define CLAMP(number,minval,maxval) ((number)<(minval)?(minval):((number)>(maxval)?(maxval):(number)))
+
+///Swap numbers
+#define 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;\
+ GUINT32 _y = 0x5f3759df - ( IR(va) >> 1);\
+ (isva) = FR(_y);\
+ (isva) = (isva) * ( 1.5f - ( _x * (isva) * (isva) ) );\
+ }\
+}\
+
+#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
+GREAL gim_inv_sqrt(GREAL f);
+
+//! Computes sqrtf(x) faster.
+/*!
+\sa gim_inv_sqrt
+*/
+GREAL gim_sqrt(GREAL f);
+
+//!Initializes mathematical functions
+void gim_init_math();
+
+//! Generates an unit random
+GREAL gim_unit_random();
+//! @}
+
+#endif // GIM_MATH_H_INCLUDED
diff --git a/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_memory.h b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_memory.h new file mode 100644 index 0000000..d007bda --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_memory.h @@ -0,0 +1,1056 @@ +#ifndef GIM_MEMORY_H_INCLUDED
+#define GIM_MEMORY_H_INCLUDED
+/*! \file gim_memory.h
+\author Francisco León
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include "GIMPACT/gim_math.h"
+#include <memory.h>
+
+//#define PREFETCH 1
+//! \defgroup PREFETCH
+//! @{
+#ifdef PREFETCH
+#include <xmmintrin.h> // for prefetch
+#define pfval 64
+#define pfval2 128
+//! Prefetch 64
+#define pf(_x,_i) _mm_prefetch((void *)(_x + _i + pfval), 0)
+//! Prefetch 128
+#define pf2(_x,_i) _mm_prefetch((void *)(_x + _i + pfval2), 0)
+#else
+//! Prefetch 64
+#define pf(_x,_i)
+//! Prefetch 128
+#define pf2(_x,_i)
+#endif
+//! @}
+
+/*! \defgroup ARRAY_UTILITIES
+\brief
+Functions for manip packed arrays of numbers
+*/
+//! @{
+#define GIM_COPY_ARRAYS(dest_array, source_array, element_count)\
+{\
+ GUINT32 _i_;\
+ for (_i_ = 0; _i_ < (element_count); _i_++)\
+ {\
+ (dest_array)[_i_] = (source_array)[_i_];\
+ }\
+}\
+
+#define GIM_COPY_ARRAYS_1(dest_array, source_array, element_count, copy_macro)\
+{\
+ GUINT32 _i_;\
+ for (_i_=0; _i_ < (element_count); _i_++)\
+ {\
+ copy_macro((dest_array)[_i_], (source_array)[_i_]);\
+ }\
+}\
+
+
+#define GIM_ZERO_ARRAY(array, element_count)\
+{\
+ GUINT32 _i_;\
+ for (_i_=0; _i_ < (element_count); _i_++)\
+ {\
+ (array)[_i_] = 0;\
+ }\
+}\
+
+#define GIM_CONSTANT_ARRAY(array, element_count, constant)\
+{\
+ GUINT32 _i_;\
+ for (_i_ = 0; _i_ < (element_count); _i_++)\
+ {\
+ (array)[_i_] = (constant);\
+ }\
+}\
+//! @}
+
+/*! \defgroup MEMORY_FUNCTION_PROTOTYPES
+Function prototypes to allocate and free memory.
+*/
+//! @{
+typedef void * gim_alloc_function (size_t size);
+typedef void * gim_alloca_function (size_t size);//Allocs on the heap
+typedef void * gim_realloc_function (void *ptr, size_t oldsize, size_t newsize);
+typedef void gim_free_function (void *ptr, size_t size);
+//! @}
+
+/*! \defgroup MEMORY_FUNCTION_HANDLERS
+\brief
+Memory Function Handlers
+ set new memory management functions. if fn is 0, the default handlers are
+ used. */
+//! @{
+void gim_set_alloc_handler (gim_alloc_function *fn);
+// void gim_set_alloca_handler (gim_alloca_function *fn); -- a nonsense
+void gim_set_realloc_handler (gim_realloc_function *fn);
+void gim_set_free_handler (gim_free_function *fn);
+//! @}
+
+/*! \defgroup MEMORY_FUNCTION_GET_HANDLERS
+\brief
+get current memory management functions.
+*/
+//! @{
+gim_alloc_function *gim_get_alloc_handler (void);
+// gim_alloca_function *gim_get_alloca_handler(void); -- a nonsense
+gim_realloc_function *gim_get_realloc_handler (void);
+gim_free_function *gim_get_free_handler (void);
+//! @}
+
+/*! \defgroup MEMORY_FUNCTIONS
+Standar Memory functions
+*/
+//! @{
+void * gim_alloc(size_t size);
+// void * gim_alloca(size_t size); -- a nonsense
+void * gim_realloc(void *ptr, size_t oldsize, size_t newsize);
+void gim_free(void *ptr, size_t size);
+//! @}
+
+/*! \defgroup DYNAMIC_ARRAYS
+\brief
+Dynamic Arrays. Allocated from system memory.
+<ul>
+<li> For initializes a dynamic array, use GIM_DYNARRAY_CREATE or GIM_DYNARRAY_CREATE_SIZED.
+<li> When an array is no longer used, must be terminated with the macro GIM_DYNARRAY_DESTROY.
+</ul>
+*/
+//! @{
+#define G_ARRAY_GROW_SIZE 64
+#define G_ARRAY_BUFFERMANAGER_INIT_SIZE 2
+
+//! Dynamic array handle.
+struct GDYNAMIC_ARRAY
+{
+ char * m_pdata;
+ GUINT32 m_size;
+ GUINT32 m_reserve_size;
+};
+//typedef struct _GDYNAMIC_ARRAY GDYNAMIC_ARRAY;
+
+//! Creates a dynamic array zero sized
+#define GIM_DYNARRAY_CREATE(type, array_data, reserve_size) \
+{ \
+ (array_data).m_pdata = (char *)gim_alloc((reserve_size) * sizeof(type)); \
+ (array_data).m_size = 0; \
+ (array_data).m_reserve_size = (reserve_size); \
+} \
+
+//! Creates a dynamic array with n = size elements
+#define GIM_DYNARRAY_CREATE_SIZED(type, array_data, size) \
+{ \
+ (array_data).m_pdata = (char *)gim_alloc((size) * sizeof(type)); \
+ (array_data).m_size = (size); \
+ (array_data).m_reserve_size = (size); \
+} \
+
+//! Reserves memory for a dynamic array.
+#define GIM_DYNARRAY_RESERVE_SIZE(type, array_data, old_size, reserve_size) \
+{ \
+ if ((reserve_size) > (array_data).m_reserve_size) \
+ { \
+ (array_data).m_pdata = (char *) gim_realloc((array_data).m_pdata, (old_size) * sizeof(type), (reserve_size) * sizeof(type)); \
+ (array_data).m_reserve_size = (reserve_size); \
+ } \
+} \
+
+//! Set the size of the array
+#define GIM_DYNARRAY_SET_SIZE(type, array_data, size) \
+{ \
+ GIM_DYNARRAY_RESERVE_SIZE(type, array_data, (array_data).m_size, size); \
+ (array_data).m_size = size; \
+} \
+
+//! Gets a pointer from the beginning of the array
+#define GIM_DYNARRAY_POINTER(type, array_data) ((type *)((array_data).m_pdata))
+
+//! Gets a pointer from the last elemento of the array
+#define GIM_DYNARRAY_POINTER_LAST(type, array_data) (((type *)(array_data).m_pdata) + ((array_data).m_size - 1))
+
+//! Inserts an element at the last position
+#define GIM_DYNARRAY_PUSH_ITEM(type, array_data, item)\
+{ \
+ if ((array_data).m_reserve_size <= (array_data).m_size)\
+ {\
+ GIM_DYNARRAY_RESERVE_SIZE(type, array_data, (array_data).m_size, (array_data).m_size + G_ARRAY_GROW_SIZE); \
+ }\
+ type * _pt = GIM_DYNARRAY_POINTER(type, array_data); \
+ memcpy(&_pt[(array_data).m_size], &(item), sizeof(type)); \
+ (array_data).m_size++; \
+} \
+
+//! Inserts an element at the last position
+#define GIM_DYNARRAY_PUSH_EMPTY(type, array_data) \
+{ \
+ if ((array_data).m_reserve_size <= (array_data).m_size) \
+ { \
+ GIM_DYNARRAY_RESERVE_SIZE(type, array_data, (array_data).m_size, (array_data).m_size + G_ARRAY_GROW_SIZE); \
+ } \
+ (array_data).m_size++; \
+} \
+
+//! Inserts an element
+#define GIM_DYNARRAY_INSERT_ITEM(type, array_data, item, index) \
+{ \
+ if ((array_data).m_reserve_size <= (array_data).m_size) \
+ { \
+ GIM_DYNARRAY_RESERVE_SIZE(type, array_data, (array_data).m_size, (array_data).m_size + G_ARRAY_GROW_SIZE); \
+ } \
+ type * _pt = GIM_DYNARRAY_POINTER(type, array_data); \
+ if ((index) < (array_data).m_size - 1) \
+ { \
+ memmove(&_pt[(index) + 1], &_pt[(index)], ((array_data).m_size - (index)) * sizeof(type)); \
+ } \
+ memcpy(&_pt[(index)], &(item), sizeof(type)); \
+ array_data.m_size++; \
+} \
+
+//! Removes an element
+#define GIM_DYNARRAY_DELETE_ITEM(type, array_data, index) \
+{ \
+ if ((index) < (array_data).m_size - 1) \
+ { \
+ type * _pt = GIM_DYNARRAY_POINTER(type, array_data);\
+ memmove(&_pt[(index)], &_pt[(index) + 1], ((array_data).m_size - (index) - 1) * sizeof(type)); \
+ } \
+ (array_data).m_size--; \
+} \
+
+//! Removes an element at the last position
+#define GIM_DYNARRAY_POP_ITEM(array_data) \
+{ \
+ if ((array_data).m_size > 0) \
+ { \
+ (array_data).m_size--; \
+ } \
+}\
+
+//! Destroys the array
+void GIM_DYNARRAY_DESTROY(GDYNAMIC_ARRAY & array_data);
+//! @}
+
+/*! \defgroup BITSET
+\brief
+Bitsets , based on \ref DYNAMIC_ARRAYS .
+<ul>
+<li> For initializes a bitset array, use \ref GIM_BITSET_CREATE or \ref GIM_BITSET_CREATE_SIZED.
+<li> When the bitset is no longer used, must be terminated with the macro \ref GIM_DYNARRAY_DESTROY.
+<li> For putting a mark on the bitset, call \ref GIM_BITSET_SET
+<li> For clearing a mark on the bitset, call \ref GIM_BITSET_CLEAR
+<li> For retrieving a bit value from a bitset, call \ref GIM_BITSET_GET-
+</ul>
+*/
+//! @{
+
+//! Creates a bitset
+#define GIM_BITSET_CREATE(array_data) GIM_DYNARRAY_CREATE(GUINT32, array_data, G_ARRAY_GROW_SIZE)
+
+//! Creates a bitset, with their bits set to 0.
+#define GIM_BITSET_CREATE_SIZED(array_data, bits_count) \
+{ \
+ GUINT32 array_size = (bits_count) / GUINT32_BIT_COUNT + 1; \
+ GIM_DYNARRAY_CREATE(GUINT32, array_data, array_size); \
+ GUINT32 * _pt = GIM_DYNARRAY_POINTER(GUINT32, array_data); \
+ memset(_pt, 0, sizeof(GUINT32) * ((array_data).m_size)); \
+} \
+
+//! Gets the bitset bit count.
+#define GIM_BITSET_SIZE(array_data) ((array_data).m_size * GUINT32_BIT_COUNT)
+
+//! Resizes a bitset, with their bits set to 0.
+#define GIM_BITSET_RESIZE(array_data, new_bits_count) \
+{ \
+ GUINT32 _oldsize = (array_data).m_size; \
+ (array_data).m_size = (new_bits_count) / GUINT32_BIT_COUNT + 1; \
+ if (_oldsize < (array_data).m_size) \
+ { \
+ if ((array_data).m_size > (array_data).m_reserve_size) \
+ { \
+ GIM_DYNARRAY_RESERVE_SIZE(GUINT32, array_data, _oldsize, (array_data).m_size + G_ARRAY_GROW_SIZE); \
+ } \
+ GUINT32 * _pt = GIM_DYNARRAY_POINTER(GUINT32, array_data); \
+ memset(&_pt[_oldsize], 0, sizeof(GUINT32) * ((array_data).m_size - _oldsize)); \
+ } \
+} \
+
+//! Sets all bitset bit to 0.
+#define GIM_BITSET_CLEAR_ALL(array_data) \
+{ \
+ memset((array_data).m_pdata, 0, sizeof(GUINT32) * (array_data).m_size); \
+} \
+
+//! Sets all bitset bit to 1.
+#define GIM_BITSET_SET_ALL(array_data) \
+{ \
+ memset((array_data).m_pdata, 0xFF, sizeof(GUINT32) * (array_data).m_size); \
+} \
+
+///Sets the desired bit to 1
+#define GIM_BITSET_SET(array_data, bit_index) \
+{ \
+ if ((bit_index) >= GIM_BITSET_SIZE(array_data)) \
+ { \
+ GIM_BITSET_RESIZE(array_data, bit_index); \
+ } \
+ GUINT32 * _pt = GIM_DYNARRAY_POINTER(GUINT32, array_data); \
+ _pt[(bit_index) >> GUINT32_EXPONENT] |= (1 << ((bit_index) & (GUINT32_BIT_COUNT - 1))); \
+} \
+
+///Return 0 or 1
+#define GIM_BITSET_GET(array_data, bit_index, get_value) \
+{ \
+ if ((bit_index) >= GIM_BITSET_SIZE(array_data)) \
+ { \
+ (get_value) = 0; \
+ } \
+ else \
+ { \
+ GUINT32 * _pt = GIM_DYNARRAY_POINTER(GUINT32, array_data); \
+ (get_value) = _pt[(bit_index) >> GUINT32_EXPONENT] & (1 << ((bit_index) & (GUINT32_BIT_COUNT - 1))); \
+ } \
+} \
+
+///Sets the desired bit to 0
+#define GIM_BITSET_CLEAR(array_data, bit_index) \
+{ \
+ if ((bit_index) < GIM_BITSET_SIZE(array_data)) \
+ { \
+ GUINT32 * _pt = GIM_DYNARRAY_POINTER(GUINT32, array_data); \
+ _pt[(bit_index) >> GUINT32_EXPONENT] &= ~(1 << ((bit_index) & (GUINT32_BIT_COUNT - 1))); \
+ } \
+} \
+//! @}
+
+/*! \defgroup MEMORY_ACCESS_CONSTANTS
+\brief
+Memory Access constants.
+\sa BUFFERS
+*/
+//! @{
+#define G_MA_READ_ONLY 1
+#define G_MA_WRITE_ONLY 2
+#define G_MA_READ_WRITE 3
+//! @}
+
+/*! \defgroup MEMORY_USAGE_CONSTANTS
+\brief
+Memory usage constants.
+\sa BUFFERS
+*/
+//! @{
+/// Don't care how memory is used
+#define G_MU_EITHER 0
+/// specified once, doesn't allow read information
+#define G_MU_STATIC_WRITE 1
+/// specified once, allows to read information from a shadow buffer
+#define G_MU_STATIC_READ 2
+/// write directly on buffer, allows to read information from a shadow buffer
+#define G_MU_STATIC_READ_DYNAMIC_WRITE 3
+/// upload data to buffer from the shadow buffer, allows to read information from a shadow buffer
+#define G_MU_STATIC_READ_DYNAMIC_WRITE_COPY 4
+/// specified once, allows to read information directly from memory
+#define G_MU_STATIC_WRITE_DYNAMIC_READ 5
+/// write directly on buffer, allows to read information directly from memory
+#define G_MU_DYNAMIC_READ_WRITE 6
+//! @}
+
+/*! \defgroup BUFFER_ERRORS
+\brief
+Buffer operation errors
+\sa BUFFERS
+*/
+//! @{
+#define G_BUFFER_OP_SUCCESS 0
+#define G_BUFFER_OP_INVALID 1
+#define G_BUFFER_OP_STILLREFCOUNTED 2
+//! @}
+
+/*! \defgroup BUFFER_MANAGER_IDS
+\brief
+Buffer manager identifiers
+\sa BUFFERS, BUFFER_MANAGERS
+*/
+//! @{
+enum
+{
+ G_BUFFER_MANAGER_SYSTEM,
+ G_BUFFER_MANAGER_SHARED,
+
+ G_BUFFER_MANAGER__MAX
+};
+//! @}
+
+/*! \defgroup BUFFERS
+\brief
+Buffer operations and structs.
+<ul>
+<li> Before using buffers you must initializes GIMPACT buffer managers by calling \ref gimpact_init.
+<li> For initializes a buffer, use \ref gim_create_buffer, \ref gim_create_buffer_from_data , \ref gim_create_common_buffer, \ref gim_create_common_buffer_from_data or \ref gim_create_shared_buffer_from_data.
+<li> For accessing to the buffer memory, you must call \ref gim_lock_buffer, and then \ref gim_unlock_buffer for finish the access.
+<li> When a buffer is no longer needed, you must free it by calling \ref gim_buffer_free.
+<li> You must call \ref gimpact_terminate when finish your application.
+<li> For a safe manipulation of buffers, use \ref BUFFER_ARRAYS
+</ul>
+\sa BUFFER_MANAGERS, BUFFER_ARRAYS
+*/
+//! @{
+
+struct GBUFFER_MANAGER_DATA;
+
+//! Buffer handle.
+struct GBUFFER_ID
+{
+ GBUFFER_MANAGER_DATA * m_bm_data;
+ GUINT32 m_buffer_id;
+};
+//typedef struct _GBUFFER_ID GBUFFER_ID;
+
+//! Buffer internal data
+struct GBUFFER_DATA
+{
+ GPTR m_buffer_handle;//!< if 0, buffer doesn't exists
+ GUINT32 m_size;
+ GUINT32 m_usage;
+ GINT32 m_access;
+ GUINT32 m_lock_count;
+ char * m_mapped_pointer;
+ GBUFFER_ID m_shadow_buffer;
+ GUINT32 m_refcount;//! Reference counting for safe garbage collection
+};
+//typedef struct _GBUFFER_DATA GBUFFER_DATA;
+//! @}
+
+/*! \defgroup BUFFERS_MANAGER_PROTOTYPES
+\brief
+Function prototypes to allocate and free memory for buffers
+\sa BUFFER_MANAGERS, BUFFERS
+*/
+//! @{
+
+//! Returns a Buffer handle
+typedef GPTR gim_buffer_alloc_function(GUINT32 size,int usage);
+
+//! Returns a Buffer handle, and copies the pdata to the buffer
+typedef GPTR gim_buffer_alloc_data_function(const void * pdata,GUINT32 size,int usage);
+
+//! Changes the size of the buffer preserving the content, and returns the new buffer id
+typedef GPTR gim_buffer_realloc_function(GPTR buffer_handle,GUINT32 oldsize,int old_usage,GUINT32 newsize,int new_usage);
+
+//! It changes the m_buffer_handle member to 0/0
+typedef void gim_buffer_free_function(GPTR buffer_handle,GUINT32 size);
+
+//! It maps the m_mapped_pointer. Returns a pointer
+typedef char * gim_lock_buffer_function(GPTR buffer_handle,int access);
+
+//! It sets the m_mapped_pointer to 0
+typedef void gim_unlock_buffer_function(GPTR buffer_handle);
+
+typedef void gim_download_from_buffer_function(
+ GPTR source_buffer_handle,
+ GUINT32 source_pos,
+ void * destdata,
+ GUINT32 copysize);
+
+typedef void gim_upload_to_buffer_function(
+ GPTR dest_buffer_handle,
+ GUINT32 dest_pos,
+ void * sourcedata,
+ GUINT32 copysize);
+
+typedef void gim_copy_buffers_function(
+ GPTR source_buffer_handle,
+ GUINT32 source_pos,
+ GPTR dest_buffer_handle,
+ GUINT32 dest_pos,
+ GUINT32 copysize);
+//! @}
+
+
+/*! \defgroup BUFFER_MANAGERS
+\brief
+Buffer Manager operations
+*/
+//! @{
+//! Buffer manager prototype
+struct GBUFFER_MANAGER_PROTOTYPE
+{
+ gim_buffer_alloc_function * alloc_fn;
+ gim_buffer_alloc_data_function *alloc_data_fn;
+ gim_buffer_realloc_function * realloc_fn;
+ gim_buffer_free_function * free_fn;
+ gim_lock_buffer_function * lock_buffer_fn;
+ gim_unlock_buffer_function * unlock_buffer_fn;
+ gim_download_from_buffer_function * download_from_buffer_fn;
+ gim_upload_to_buffer_function * upload_to_buffer_fn;
+ gim_copy_buffers_function * copy_buffers_fn;
+};
+//typedef struct _GBUFFER_MANAGER_PROTOTYPE GBUFFER_MANAGER_PROTOTYPE;
+
+//! Buffer manager
+struct GBUFFER_MANAGER_DATA
+{
+ GDYNAMIC_ARRAY m_buffer_array;//!< Array of GBUFFER_DATA objects
+ GDYNAMIC_ARRAY m_free_positions;//!< Array of GUINT elements. Free positions
+ const GBUFFER_MANAGER_PROTOTYPE *m_prototype;//!< Prototype of functions
+ GUINT32 m_buffer_manager_id;//!< Buffer manager id
+};
+//typedef struct _GBUFFER_MANAGER_DATA GBUFFER_MANAGER_DATA;
+
+//! Checks if buffer manager is used
+int gim_is_buffer_manager_active(GBUFFER_MANAGER_DATA buffer_managers[],
+ GUINT32 buffer_manager_id);
+//! Adds a buffer Manager to the Memory Singleton
+void gim_create_buffer_manager(GBUFFER_MANAGER_DATA buffer_managers[],
+ GUINT32 buffer_manager_id);
+//! Destroys a buffer manager
+void gim_destroy_buffer_manager(GBUFFER_MANAGER_DATA buffer_managers[], GUINT32 buffer_manager_id);
+void gim_get_buffer_manager_data(GBUFFER_MANAGER_DATA buffer_managers[],
+ GUINT32 buffer_manager_id,GBUFFER_MANAGER_DATA ** pbm_data);
+void gim_init_buffer_managers(GBUFFER_MANAGER_DATA buffer_managers[]);
+void gim_terminate_buffer_managers(GBUFFER_MANAGER_DATA buffer_managers[]);
+
+//! @}
+
+
+/*! \addtogroup BUFFERS
+*/
+//! @{
+
+//!Creates a buffer on the buffer manager specified by buffer_manager_id
+/*!
+\param buffer_manager_id
+\param buffer_size
+\param usage An usage constant. Use G_MU_DYNAMIC_READ_WRITE as default.
+\param buffer_id a pointer for receive the new buffer id
+\return An error code. 0 if success.
+\post m_refcount = 0
+*/
+GUINT32 gim_create_buffer(
+ GBUFFER_MANAGER_DATA buffer_managers[],
+ GUINT32 buffer_manager_id,
+ GUINT32 buffer_size,
+ int usage,
+ GBUFFER_ID * buffer_id);
+
+//!Creates a buffer on the buffer manager specified by buffer_manager_id
+/*!
+\param buffer_manager_id
+\param pdata Data for allocating
+\param buffer_size Size of the data buffer
+\param usage An usage constant. Use G_MU_DYNAMIC_READ_WRITE as default.
+\param buffer_id a pointer for receive the new buffer id
+\return An error code. 0 if success.
+\post m_refcount = 0
+*/
+GUINT32 gim_create_buffer_from_data(
+ GBUFFER_MANAGER_DATA buffer_managers[],
+ GUINT32 buffer_manager_id,
+ const void * pdata,
+ GUINT32 buffer_size,
+ int usage,
+ GBUFFER_ID * buffer_id);
+
+//!Allocates on the G_BUFFER_MANAGER_SYSTEM
+GUINT32 gim_create_common_buffer(GBUFFER_MANAGER_DATA buffer_managers[],
+ GUINT32 buffer_size, GBUFFER_ID * buffer_id);
+//!Allocates on the G_BUFFER_MANAGER_SYSTEM, and copies the data
+GUINT32 gim_create_common_buffer_from_data(GBUFFER_MANAGER_DATA buffer_managers[],
+ const void * pdata, GUINT32 buffer_size, GBUFFER_ID * buffer_id);
+//!Creates a buffer with shared data
+GUINT32 gim_create_shared_buffer_from_data(GBUFFER_MANAGER_DATA buffer_managers[],
+ const void * pdata, GUINT32 buffer_size, GBUFFER_ID * buffer_id);
+
+
+//! Add reference counting to buffer.
+GINT32 gim_buffer_add_ref(GBUFFER_ID * buffer_id);
+
+//! Function for resize buffer, preserving the content
+/*!
+\param buffer_id
+\param newsize
+\return An error code. 0 if success.
+\post If m_refcount>0 then it decrements it.
+*/
+GINT32 gim_buffer_realloc(GBUFFER_ID * buffer_id,GUINT32 newsize);
+
+//! Eliminates the buffer.
+/*!
+If the buffer reference counting is <= 1 and is unlocked, then it eliminates the buffer.
+*/
+GINT32 gim_buffer_free(GBUFFER_ID * buffer_id);
+
+//! Locks the buffer for memory access.
+/*!
+\param buffer_id Id from buffer.
+\param access Must have the following values: G_MA_READ_ONLY,G_MA_WRITE_ONLY or G_MA_READ_WRITE.
+\param map_pointer Dest Pointer of the memory address from buffer.
+\post m_lock_count increases.
+*/
+GINT32 gim_lock_buffer(GBUFFER_ID * buffer_id,int access,char ** map_pointer);
+
+//! Unlocks the buffer for memory access.
+GINT32 gim_unlock_buffer(GBUFFER_ID * buffer_id);
+
+//! Gets the buffer size in bytes
+GINT32 gim_get_buffer_size(GBUFFER_ID * buffer_id,GUINT32 * buffer_size);
+
+//! Determines if the buffer is locked
+GINT32 gim_get_buffer_is_locked(GBUFFER_ID * buffer_id,GUINT32 * lock_count);
+
+//! Copies the content of the buffer to a dest pointer
+GINT32 gim_download_from_buffer(
+ GBUFFER_ID * buffer_id,
+ GUINT32 source_pos,
+ void * destdata,
+ GUINT32 copysize);
+
+//! Copies the content of a memory pointer to the buffer
+GINT32 gim_upload_to_buffer(
+ GBUFFER_ID * buffer_id,
+ GUINT32 dest_pos,
+ void * sourcedata,
+ GUINT32 copysize);
+
+//! Copies two buffers.
+GINT32 gim_copy_buffers(
+ GBUFFER_ID * source_buffer_id,
+ GUINT32 source_pos,
+ GBUFFER_ID * dest_buffer_id,
+ GUINT32 dest_pos,
+ GUINT32 copysize);
+//! @}
+
+
+/*! \defgroup BUFFER_ARRAYS
+
+\brief
+Buffered Arrays, for manip elements on a buffer and treat it as an array.
+<ul>
+<li> Before using buffer arrays you must initializes GIMPACT buffer managers by calling gimpact_init.
+<li> Before creating buffer arrays, you must create a buffer. see \ref BUFFERS.
+<li> Create a buffer narray by calling \ref GIM_BUFFER_ARRAY_INIT_TYPE, \ref GIM_BUFFER_ARRAY_INIT_TYPE_OFFSET or \ref GIM_BUFFER_ARRAY_INIT_OFFSET_STRIDE.
+<li> For accessing to the array elements, you must call \ref gim_buffer_array_lock, and then \ref gim_buffer_array_unlock for finish the access.
+<li> When a buffer array is no longer needed, you must free it by calling \ref GIM_BUFFER_ARRAY_DESTROY.
+</ul>
+The following example shows how Buffer arrays can be used:
+
+\code
+int main()
+{
+ //init gimpact
+ gimpact_init();
+
+ //Buffer handle to use
+ GBUFFER_ID bufferhandle;
+
+ //Create a memory buffer of 100 float numbers
+ gim_create_common_buffer(100*sizeof(float), &bufferhandle);
+
+ //Create a buffer array from the bufferhandle
+ GBUFFER_ARRAY buffer_float_array;
+ GIM_BUFFER_ARRAY_INIT_TYPE(float,buffer_float_array,bufferhandle,100);
+
+ ////Access to the buffer data, set all elements of the array
+
+ int i, count;
+ count = buffer_float_array.m_element_count;
+ //Locks the array
+ gim_buffer_array_lock(&buffer_float_array,G_MA_READ_WRITE);
+ float * pelements = GIM_BUFFER_ARRAY_POINTER(float, buffer_float_array, 0); // A pointer to the buffer memory
+
+ //fill the array with random numbers
+ for (i = 0;i < count;i++ )
+ {
+ pelements[i] = gim_unit_random();
+ }
+ //unlock buffer
+ gim_buffer_array_unlock(&buffer_float_array);
+
+ //Program code
+ ....
+ ....
+
+ //Destroy array
+ GIM_BUFFER_ARRAY_DESTROY(buffer_float_array);
+
+ //terminate gimpact
+ gimpact_terminate();
+}
+\endcode
+
+\sa BUFFERS
+*/
+//! @{
+
+//! Buffer managed array struct.
+struct GBUFFER_ARRAY
+{
+ GBUFFER_ID m_buffer_id;
+ char * m_buffer_data;
+ char m_byte_stride;
+ GUINT32 m_byte_offset;
+ GUINT32 m_element_count;
+};
+//typedef struct _GBUFFER_ARRAY GBUFFER_ARRAY;
+
+//! Sets offset for a buffered array.
+#define GIM_BUFFER_ARRAY_SET_OFFSET(_array_data,_offset) (_array_data).m_byte_offset = (_offset)*(_array_data).m_byte_stride;
+
+//! Sets offset for a buffered array.
+#define GIM_BUFFER_ARRAY_GET_OFFSET(_array_data,_offset) (_offset) = (_array_data).m_byte_offset/(_array_data).m_byte_stride;
+
+//!Return a pointer of the element at the _index
+#define GIM_BUFFER_ARRAY_POINTER(_type,_array_data,_index) (_type *)((_array_data).m_buffer_data + (_index)*(_array_data).m_byte_stride)
+
+//! Sets stride for a buffered array.
+#define GIM_BUFFER_ARRAY_SET_STRIDE(_type,_array_data) (_array_data).m_byte_stride = sizeof(_type);
+
+//! Is array stride equal to the size of the type ?
+#define GIM_BUFFER_ARRAY_IS_ALIGNED(_type,_array_data) ((_array_data).m_byte_stride == sizeof(_type))
+
+///Verify if two arrays have the same data
+#define GIM_BUFFER_ARRAY_ARE_SAME(_array_data1,_array_data2,aresame) \
+{ \
+ (aresame) = 1; \
+ if ((_array_data1).m_buffer_id.m_buffer_id != (_array_data2).m_buffer_id.m_buffer_id || (_array_data1).m_buffer_id.m_buffer_manager_id != (_array_data2).m_buffer_id.m_buffer_manager_id || (_array_data1).m_byte_offset != (_array_data2).m_byte_offset) \
+ { \
+ (aresame) = 0; \
+ } \
+} \
+
+//! Reserve size for a buffered array.
+/*!
+\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
+*/
+#define GIM_BUFFER_ARRAY_RESERVE_SIZE(type, array_data, reserve_size) \
+{ \
+ if ((reserve_size) > (array_data).m_element_count) \
+ { \
+ GUINT32 _buffer_size, _newarray_size; \
+ gim_get_buffer_size(&(array_data).m_buffer_id, _buffer_size); \
+ _newarray_size = (reserve_size) * (array_data).m_byte_stride; \
+ if(_newarray_size > _buffer_size) \
+ { \
+ _newarray_size += G_ARRAY_GROW_SIZE * (array_data).m_byte_stride; \
+ gim_buffer_realloc(&(array_data).m_buffer_id, _newarray_size); \
+ } \
+ } \
+} \
+
+//! Pushes an element at last position
+/*!
+\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
+*/
+#define GIM_BUFFER_ARRAY_PUSH_ITEM(type, array_data, item) \
+{ \
+ GIM_BUFFER_ARRAY_RESERVE_SIZE(type, array_data, (array_data).m_element_count + 1); \
+ gim_buffer_array_lock(&(array_data), G_MA_WRITE_ONLY); \
+ type * _pt = GIM_BUFFER_ARRAY_POINTER(type, array_data, (array_data).m_element_count); \
+ memcpy(_pt, &(item), sizeof(type)); \
+ gim_buffer_array_unlock(&(array_data)); \
+ (array_data)->m_element_count++; \
+} \
+
+//! Pushes a new element at last position
+/*!
+\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
+*/
+#define GIM_BUFFER_ARRAY_PUSH_EMPTY(type, array_data) \
+{\
+ GIM_BUFFER_ARRAY_RESERVE_SIZE(type, array_data, (array_data).m_element_count + 1); \
+ (array_data)->m_element_count++; \
+}\
+
+//! Inserts an element
+/*!
+\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
+*/
+#define GIM_BUFFER_ARRAY_INSERT_ITEM(type, array_data, item, index) \
+{ \
+ GIM_BUFFER_ARRAY_RESERVE_SIZE(type, array_data, (array_data).m_element_count + 1); \
+ gim_buffer_array_lock(&(array_data), G_MA_WRITE_ONLY); \
+ type * _pt = GIM_BUFFER_ARRAY_POINTER(type, array_data, 0); \
+ if ((index) < (array_data)->m_element_count - 1) \
+ { \
+ memmove(&_pt[(index) + 1], &_pt[(index)], ((array_data).m_element_count - (index)) * sizeof(type)); \
+ } \
+ memcpy(&_pt[(index)], &(item), sizeof(type)); \
+ gim_buffer_array_unlock(&(array_data)); \
+ (array_data).m_element_count++; \
+} \
+
+//! Deletes an element
+/*!
+\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
+*/
+#define GIM_BUFFER_ARRAY_DELETE_ITEM(type, array_data, index) \
+{ \
+ if ((index) < (array_data).m_element_count - 1) \
+ { \
+ gim_buffer_array_lock(&(array_data), G_MA_WRITE_ONLY); \
+ type * _pt = GIM_BUFFER_ARRAY_POINTER(type, array_data, 0); \
+ memmove(&_pt[(index)], &_pt[(index) + 1],((array_data).m_element_count - (index) - 1) * sizeof(type)); \
+ gim_buffer_array_unlock(&(array_data)); \
+ } \
+ (array_data).m_element_count--; \
+} \
+
+//! Deletes an element at last position
+/*!
+\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
+*/
+#define GIM_BUFFER_ARRAY_POP_ITEM(array_data) \
+{ \
+ if ((array_data).m_element_count > 0) \
+ { \
+ (array_data).m_element_count--; \
+ } \
+} \
+
+
+//! Initializes an GBUFFER_ARRAY object from a buffer ID
+/*!
+m_buffer_data will be 0, for acces to the elements, you'd need to call lock_array
+\param array_data Array structure to be filled
+\param buffer_id A GBUFFER_ID structure which this array_daya will refer to
+\param element_count Number of elements
+\param offset element offset, it isn't byte offset. 0 is recomended
+\param byte_stride size of each element. 0 is recomended.
+\post Adds reference to the buffer
+\sa gim_buffer_add_ref
+*/
+#define GIM_BUFFER_ARRAY_INIT_OFFSET_STRIDE(array_data, buffer_id, element_count, offset, byte_stride) \
+{ \
+ (array_data).m_buffer_id.m_buffer_id = (buffer_id).m_buffer_id; \
+ (array_data).m_buffer_id.m_buffer_manager_id = (buffer_id).m_buffer_manager_id; \
+ (array_data).m_buffer_data = 0; \
+ (array_data).m_element_count = (element_count); \
+ (array_data).m_byte_stride = (byte_stride); \
+ GIM_BUFFER_ARRAY_SET_OFFSET(array_data, offset); \
+ gim_buffer_add_ref(&(buffer_id)); \
+} \
+
+//! Initializes an GBUFFER_ARRAY object from a buffer ID and a Given type
+/*!
+m_buffer_data will be 0, for acces to the elements, you'd need to call lock_array
+\param type Type of the Array. It determines the stride.
+\param array_data Array structure to be filled
+\param buffer_id A GBUFFER_ID structure which this array_daya will refer to
+\param element_count Number of elements
+\param offset element offset, it isn't byte offset. 0 is recomended
+\post Adds reference to the buffer
+\sa gim_buffer_add_ref
+*/
+#define GIM_BUFFER_ARRAY_INIT_TYPE_OFFSET(type, array_data, buffer_id, element_count, offset) \
+{ \
+ (array_data).m_buffer_id.m_buffer_id = (buffer_id).m_buffer_id; \
+ (array_data).m_buffer_id.m_bm_data = (buffer_id).m_bm_data; \
+ (array_data).m_buffer_data = 0; \
+ (array_data).m_element_count = (element_count);\
+ GIM_BUFFER_ARRAY_SET_STRIDE(type, array_data); \
+ GIM_BUFFER_ARRAY_SET_OFFSET(array_data, offset); \
+ gim_buffer_add_ref(&(buffer_id)); \
+}\
+
+//! Initializes a buffer array giving a data type and a buffer id
+/*!
+m_buffer_data will be 0, for acces to the elements, you'd need to call lock_array.
+\param type Type of the Array. It determines the stride.
+\param array_data Array structure to be filled
+\param buffer_id A GBUFFER_ID structure which this array_daya will refer to
+\param element_count Number of elements
+\post Adds reference to the buffer
+\sa gim_buffer_add_ref
+*/
+#define GIM_BUFFER_ARRAY_INIT_TYPE(type, array_data, buffer_id, element_count) GIM_BUFFER_ARRAY_INIT_TYPE_OFFSET(type, array_data, buffer_id, element_count, 0)
+
+//! Gain access to the array buffer through the m_buffer_data element
+/*!
+m_buffer_data pointer will be located at the m_byte_offset position of the buffer m_buffer
+Then, You'd need to call unlock_array when finish to using the array access.
+
+\pre if m_buffer_data != 0, the function returns
+\param array_data Array structure to be locked
+\param access A constant for access to the buffer. can be G_MA_READ_ONLY,G_MA_WRITE_ONLY or G_MA_READ_WRITE
+\return an Buffer error code
+*/
+GINT32 gim_buffer_array_lock(GBUFFER_ARRAY * array_data, int access);
+
+//! close the access to the array buffer through the m_buffer_data element
+/*!
+\param array_data Array structure to be locked
+\return an Buffer error code
+*/
+GINT32 gim_buffer_array_unlock(GBUFFER_ARRAY * array_data);
+
+//! Copy an array by reference
+/*!
+\post A reference to the m_buffer_id is increased.
+*/
+void gim_buffer_array_copy_ref(GBUFFER_ARRAY * source_data,GBUFFER_ARRAY * dest_data);
+
+
+//! Copy an array by value
+/*!
+\post A new buffer is created
+*/
+void gim_buffer_array_copy_value(GBUFFER_ARRAY * source_data,
+ GBUFFER_MANAGER_DATA dest_buffer_managers[],GBUFFER_ARRAY * dest_data,
+ GUINT32 buffer_manager_id,int usage);
+
+//! Destroys an GBUFFER_ARRAY object
+/*!
+\post Attemps to destroy the buffer, decreases reference counting
+*/
+void GIM_BUFFER_ARRAY_DESTROY(GBUFFER_ARRAY & array_data);
+
+//! Copy the content of the array to a pointer
+/*!
+\pre dest_data must have the same size as the array_data
+\param type
+\param array_data A GBUFFERED_ARRAY structure
+\param dest_data A type pointer
+*/
+#define GIM_BUFFER_ARRAY_DOWNLOAD(type,array_data,dest_data) \
+{ \
+ if (GIM_BUFFER_ARRAY_IS_ALIGNED(type, array_data)) \
+ { \
+ gim_download_from_buffer(&(array_data).m_buffer_id, (array_data).m_byte_offset, (void *)(dest_data), (array_data).m_element_count * (array_data).m_byte_stride); \
+ } \
+ else \
+ { \
+ GUINT32 _k_, _ecount_= (array_data).m_element_count; \
+ type * _source_vert_; \
+ type * _dest_vert_ = (dest_data); \
+ gim_buffer_array_lock(&(array_data), G_MA_READ_ONLY); \
+ for (_k_ = 0; _k_ < _ecount_; _k_++) \
+ { \
+ _source_vert_ = GIM_BUFFER_ARRAY_POINTER(type, array_data, _k_); \
+ memcpy(_dest_vert_, _source_vert_, sizeof(type)); \
+ _dest_vert_++; \
+ } \
+ gim_buffer_array_unlock(&(array_data)); \
+ } \
+} \
+
+//! Upload the content of a a pointer to a buffered array
+/*!
+\pre source_data must have the same size as the array_data
+\param type
+\param array_data A GBUFFERED_ARRAY structure
+\param source_data A void pointer
+*/
+#define GIM_BUFFER_ARRAY_UPLOAD(type, array_data, source_data) \
+{ \
+ if (GIM_BUFFER_ARRAY_IS_ALIGNED(type, array_data)) \
+ { \
+ gim_upload_to_buffer(&(array_data).m_buffer_id, (array_data).m_byte_offset, (void *)(source_data), (array_data).m_element_count * (array_data).m_byte_stride); \
+ } \
+ else \
+ { \
+ GUINT32 _k_, _ecount_= (array_data).m_element_count; \
+ type * _source_vert_ = (source_data); \
+ type * _dest_vert_; \
+ gim_buffer_array_lock(&(array_data), G_MA_WRITE_ONLY); \
+ for (_k_ = 0; _k_ < _ecount_; _k_++) \
+ { \
+ _dest_vert_ = GIM_BUFFER_ARRAY_POINTER(type, array_data, _k_); \
+ memcpy(_dest_vert_, _source_vert_, sizeof(type)); \
+ _source_vert_++; \
+ } \
+ gim_buffer_array_unlock(&(array_data)); \
+ } \
+} \
+
+
+//!Kernel function prototype for process streams, given a buffered array as source and
+/*!
+\param 1 the uniform arguments
+\param 2 the source stream
+\param 3 the destination stream
+*/
+typedef void (* gim_kernel_func)(void *,GBUFFER_ARRAY *,GBUFFER_ARRAY *);
+
+//! Generic Stream Processingp loop
+/*!
+
+This macro executes a kernel macro or function for each element of the streams
+\pre _src_array->m_count <= _dst_array->m_count
+
+\param _uniform_data An argument to be passed to the Kernel function
+\param _src_array An GBUFFER_ARRAY structure passed as the source stream
+\param _dst_array An GBUFFER_ARRAY structure passed as the source stream
+\param _kernel Macro or function of the kernel
+\param _src_type Required. Type of all elements of the source stream
+\param _dst_type Required. Type of all elements of the dest stream
+*/
+#define GIM_PROCESS_BUFFER_ARRAY(_uniform_data, _src_array, _dst_array, _kernel, _src_type, _dst_type) \
+{ \
+\
+ gim_buffer_array_lock(&(_src_array), G_MA_READ_ONLY); \
+ gim_buffer_array_lock(&(_dst_array), G_MA_WRITE_ONLY); \
+\
+ GUINT32 _i_, _count_=(_src_array).m_element_count; \
+\
+ _src_type * _source_vert_; \
+ _dst_type * _dest_vert_; \
+ if (GIM_BUFFER_ARRAY_IS_ALIGNED(_src_type, _src_array) && GIM_BUFFER_ARRAY_IS_ALIGNED(_dst_type, _dst_array)) \
+ { \
+\
+ _source_vert_ = GIM_BUFFER_ARRAY_POINTER(_src_type, _src_array, 0); \
+ _dest_vert_ = GIM_BUFFER_ARRAY_POINTER(_dst_type, _dst_array, 0); \
+ for (_i_ = 0;_i_< _count_; _i_++) \
+ { \
+ _kernel(_uniform_data, *_source_vert_, *_dest_vert_); \
+ _source_vert_++; \
+ _dest_vert_++; \
+ } \
+ } \
+ else \
+ { \
+ for (_i_ = 0; _i_ < _count_; _i_++) \
+ { \
+ _source_vert_ = GIM_BUFFER_ARRAY_POINTER(_src_type, _src_array, _i_); \
+ _dest_vert_ = GIM_BUFFER_ARRAY_POINTER(_dst_type, _dst_array, _i_); \
+ _kernel(_uniform_data, *_source_vert_, *_dest_vert_); \
+ } \
+ } \
+ gim_buffer_array_unlock(&(_src_array)); \
+ gim_buffer_array_unlock(&(_dst_array)); \
+} \
+
+//! @}
+
+#endif // GIM_MEMORY_H_INCLUDED
diff --git a/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_radixsort.h b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_radixsort.h new file mode 100644 index 0000000..8572b92 --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_radixsort.h @@ -0,0 +1,258 @@ +#ifndef GIM_RADIXSORT_H_INCLUDED
+#define GIM_RADIXSORT_H_INCLUDED
+/*! \file gim_radixsort.h
+\author Francisco León.
+Based on the work of Michael Herf : "fast floating-point radix sort"
+Avaliable on http://www.stereopsis.com/radix.html
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "GIMPACT/gim_memory.h"
+
+/*! \defgroup SORTING
+\brief
+Macros for sorting.
+*/
+//! @{
+struct GIM_RSORT_TOKEN
+{
+ GUINT32 m_key;
+ GUINT32 m_value;
+};
+//typedef struct _GIM_RSORT_TOKEN GIM_RSORT_TOKEN;
+
+//comparator for sorting
+#define RSORT_TOKEN_COMPARATOR(x, y) ((int)((x.m_key) - (y.m_key)))
+
+// ---- 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 )
+
+
+//COMMON FUNCTIONS FOR ACCESSING THE KEY OF AN ELEMENT
+
+
+//For the type of your array, you need to declare a macro for obtaining the key, like these:
+#define SIMPLE_GET_FLOAT32KEY(e,key) {key =(GREAL)(e);}
+
+#define SIMPLE_GET_INTKEY(e,key) {key =(GINT32)(e);}
+
+#define SIMPLE_GET_UINTKEY(e,key) {key =(GUINT32)(e);}
+
+//For the type of your array, you need to declare a macro for copy elements, like this:
+
+#define SIMPLE_COPY_ELEMENTS(dest,src) {dest = src;}
+
+#define kHist 2048
+
+///Radix sort for unsigned integer keys
+
+#define GIM_RADIX_SORT_RTOKENS(array,sorted,element_count)\
+{\
+ GUINT32 i;\
+ GUINT32 b0[kHist * 3];\
+ GUINT32 *b1 = b0 + kHist;\
+ GUINT32 *b2 = b1 + kHist;\
+ for (i = 0; i < kHist * 3; i++)\
+ {\
+ b0[i] = 0;\
+ }\
+ GUINT32 fi;\
+ GUINT32 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)] ++;\
+ }\
+ {\
+ GUINT32 sum0 = 0, sum1 = 0, sum2 = 0;\
+ GUINT32 tsum;\
+ for (i = 0; i < kHist; i++)\
+ {\
+ tsum = b0[i] + sum0;\
+ b0[i] = sum0 - 1;\
+ sum0 = tsum;\
+ tsum = b1[i] + sum1;\
+ b1[i] = sum1 - 1;\
+ sum1 = tsum;\
+ tsum = b2[i] + sum2;\
+ b2[i] = sum2 - 1;\
+ sum2 = tsum;\
+ }\
+ }\
+ for (i = 0; i < element_count; i++)\
+ {\
+ fi = array[i].m_key;\
+ pos = D11_0(fi);\
+ pos = ++b0[pos];\
+ sorted[pos].m_key = array[i].m_key;\
+ sorted[pos].m_value = array[i].m_value;\
+ }\
+ for (i = 0; i < element_count; i++)\
+ {\
+ fi = sorted[i].m_key;\
+ pos = D11_1(fi);\
+ pos = ++b1[pos];\
+ array[pos].m_key = sorted[i].m_key;\
+ array[pos].m_value = sorted[i].m_value;\
+ }\
+ for (i = 0; i < element_count; i++)\
+ {\
+ fi = array[i].m_key;\
+ pos = D11_2(fi);\
+ pos = ++b2[pos];\
+ sorted[pos].m_key = array[i].m_key;\
+ sorted[pos].m_value = array[i].m_value;\
+ }\
+}\
+
+/// Get the sorted tokens from an array. For generic use. Tokens are GIM_RSORT_TOKEN
+#define GIM_RADIX_SORT_ARRAY_TOKENS(array, sorted_tokens, element_count, get_uintkey_macro)\
+{\
+ GIM_RSORT_TOKEN * _unsorted = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN )*element_count);\
+ GUINT32 _i;\
+ for (_i=0;_i<element_count;_i++)\
+ {\
+ get_uintkey_macro(array[_i],_unsorted[_i].m_key);\
+ _unsorted[_i].m_value = _i;\
+ }\
+ GIM_RADIX_SORT_RTOKENS(_unsorted,sorted_tokens,element_count);\
+ gim_free(_unsorted,sizeof(GIM_RSORT_TOKEN )*element_count);\
+}\
+
+/// Sorts array in place. For generic use
+#define GIM_RADIX_SORT(type,array,element_count,get_uintkey_macro,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);\
+ type * _original_array = (type *) gim_alloc(sizeof(type)*element_count); \
+ memcpy(_original_array,array,sizeof(type)*element_count);\
+ GUINT32 _i;\
+ for (_i=0;_i<element_count;_i++)\
+ {\
+ copy_elements_macro(array[_i],_original_array[_sorted[_i].m_value]);\
+ }\
+ gim_free(_original_array,sizeof(type)*element_count);\
+ gim_free(_sorted,sizeof(GIM_RSORT_TOKEN )*element_count);\
+}\
+
+/// Sorts array in place using quick sort
+#define GIM_QUICK_SORT_ARRAY(type, array, array_count, comp_macro, exchange_macro) \
+{\
+ GINT32 _i_, _j_, _p_, _stack_index_, _start_, _end_;\
+ GINT32 _start_stack_[64]; \
+ GINT32 _end_stack_[64];\
+ _start_stack_[0] = 0;\
+ _end_stack_[0] = (array_count);\
+ _stack_index_ = 1;\
+ while (_stack_index_ > 0)\
+ {\
+ _stack_index_ --;\
+ _start_ = _start_stack_[_stack_index_];\
+ _end_ = _end_stack_[_stack_index_];\
+ while (_end_ - _start_ > 2)\
+ {\
+ _p_ = _start_;\
+ _i_ = _start_ + 1;\
+ _j_ = _end_ - 1;\
+ while (_i_<_j_) \
+ {\
+ for(; _i_<=_j_ && comp_macro(((array)[_i_]),((array)[_p_]))<=0; _i_++) ;\
+ if (_i_ > _j_) \
+ {\
+ exchange_macro(type, array, _j_, _p_);\
+ _i_ = _j_;\
+ }\
+ else\
+ {\
+ for(; _i_<=_j_ && comp_macro(((array)[_j_]),((array)[_p_]))>=0; _j_--) ;\
+ if (_i_ > _j_) \
+ {\
+ exchange_macro(type, array, _j_, _p_);\
+ _i_ = _j_;\
+ }\
+ else if (_i_ < _j_)\
+ {\
+ exchange_macro(type, array, _i_, _j_);\
+ if (_i_+2 < _j_) {_i_++; _j_--;}\
+ else if (_i_+1 < _j_) _i_++;\
+ }\
+ }\
+ }\
+ if (_i_-_start_ > 1 && _end_-_j_ > 1) \
+ {\
+ if (_i_-_start_ < _end_-_j_-1) \
+ {\
+ _start_stack_[_stack_index_] = _j_+1;\
+ _end_stack_[_stack_index_] = _end_;\
+ _stack_index_ ++;\
+ _end_ = _i_;\
+ }\
+ else\
+ {\
+ _start_stack_[_stack_index_] = _start_;\
+ _end_stack_[_stack_index_] = _i_;\
+ _stack_index_ ++;\
+ _start_ = _j_+1;\
+ }\
+ }\
+ else\
+ {\
+ if (_i_-_start_ > 1)\
+ {\
+ _end_ = _i_;\
+ }\
+ else \
+ {\
+ _start_ = _j_+1;\
+ }\
+ }\
+ }\
+ if (_end_ - _start_ == 2) \
+ {\
+ if (comp_macro(((array)[_start_]),((array)[_end_-1])) > 0) \
+ {\
+ exchange_macro(type, array, _start_, _end_-1);\
+ }\
+ }\
+ }\
+}\
+
+#define GIM_DEF_EXCHANGE_MACRO(type, _array, _i, _j)\
+{\
+ type _e_tmp_ =(_array)[(_i)];\
+ (_array)[(_i)]=(_array)[(_j)];\
+ (_array)[(_j)]= _e_tmp_;\
+}\
+
+#define GIM_COMP_MACRO(x, y) ((GINT32)((x) - (y)))
+//! @}
+#endif // GIM_RADIXSORT_H_INCLUDED
diff --git a/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_tri_capsule_collision.h b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_tri_capsule_collision.h new file mode 100644 index 0000000..2b31604 --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_tri_capsule_collision.h @@ -0,0 +1,111 @@ +#ifndef GIM_TRI_CAPSULE_COLLISION_H_INCLUDED
+#define GIM_TRI_CAPSULE_COLLISION_H_INCLUDED
+
+/*! \file gim_tri_capsule_collision.h
+\author Francisco León
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "GIMPACT/gim_memory.h"
+
+/*! \addtogroup GEOMETRIC_OPERATIONS
+*/
+//! @{
+
+//! Capsule struct
+struct GIM_CAPSULE_DATA
+{
+ GREAL m_radius;
+ vec3f m_point1;
+ vec3f m_point2;
+};
+//typedef struct _GIM_CAPSULE_DATA GIM_CAPSULE_DATA;
+
+#define CALC_CAPSULE_AABB(capsule,aabb)\
+{\
+ if(capsule.m_point1[0]<capsule.m_point2[0])\
+ {\
+ aabb.minX = capsule.m_point1[0] - capsule.m_radius;\
+ aabb.maxX = capsule.m_point2[0] + capsule.m_radius;\
+ }\
+ else\
+ {\
+ aabb.minX = capsule.m_point2[0] - capsule.m_radius;\
+ aabb.maxX = capsule.m_point1[0] + capsule.m_radius;\
+ }\
+ if(capsule.m_point1[1]<capsule.m_point2[1])\
+ {\
+ aabb.minY = capsule.m_point1[1] - capsule.m_radius;\
+ aabb.maxY = capsule.m_point2[1] + capsule.m_radius;\
+ }\
+ else\
+ {\
+ aabb.minY = capsule.m_point2[1] - capsule.m_radius;\
+ aabb.maxY = capsule.m_point1[1] + capsule.m_radius;\
+ }\
+ if(capsule.m_point1[2]<capsule.m_point2[2])\
+ {\
+ aabb.minZ = capsule.m_point1[2] - capsule.m_radius;\
+ aabb.maxZ = capsule.m_point2[2] + capsule.m_radius;\
+ }\
+ else\
+ {\
+ aabb.minZ = capsule.m_point2[2] - capsule.m_radius;\
+ aabb.maxZ = capsule.m_point1[2] + capsule.m_radius;\
+ }\
+}\
+
+//! Utility function for find the closest point between a segment and a triangle
+/*!
+
+\param triangle
+\param s1
+\param s2
+\param contacts Contains the closest points on the segment (1,2), and the normal points to segment, and m_depth contains the distance
+
+\post The contacts array is not set to 0. It adds aditional contacts
+*/
+void gim_closest_point_triangle_segment(GIM_TRIANGLE_DATA * triangle, vec3f s1,vec3f s2, GDYNAMIC_ARRAY * contacts);
+
+
+
+
+
+//! Utility function for find the closest point between a capsule and a triangle
+/*!
+
+\param triangle
+\param capsule
+\param contacts Contains the closest points on the capsule, and the normal points to triangle
+\return 1 if the triangle collides the capsule
+\post The contacts array is not set to 0. It adds aditional contacts
+*/
+int gim_triangle_capsule_collision(GIM_TRIANGLE_DATA * triangle, GIM_CAPSULE_DATA * capsule, GDYNAMIC_ARRAY * contacts);
+//! @}
+
+#endif // GIM_TRI_CAPSULE_COLLISION_H_INCLUDED
diff --git a/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_tri_collision.h b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_tri_collision.h new file mode 100644 index 0000000..ae63252 --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_tri_collision.h @@ -0,0 +1,253 @@ +#ifndef GIM_TRI_COLLISION_H_INCLUDED
+#define GIM_TRI_COLLISION_H_INCLUDED
+
+/*! \file gim_tri_collision.h
+\author Francisco León Nájera
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+/*! \addtogroup GEOMETRIC_OPERATIONS
+*/
+//! @{
+
+
+#define MAX_TRI_CLIPPING 8
+
+//! Clips a polygon by a plane
+#define PLANE_CLIP_POLYGON(plane,polygon_points,polygon_point_count,clipped,clipped_count,max_clipped) \
+{ \
+ clipped_count = 0; \
+ GUINT32 _i, _vi, _prevclassif=32000, _classif; \
+ GREAL _d; \
+ for(_i=0;_i<=polygon_point_count;_i++) \
+ { \
+ _vi = _i%polygon_point_count; \
+ _d = DISTANCE_PLANE_POINT(plane,polygon_points[_vi]); \
+ _classif = _d>G_EPSILON ?1:0; \
+ if(_classif == 0) \
+ { \
+ if(_prevclassif==1) \
+ {\
+ if(clipped_count<max_clipped) \
+ {\
+ PLANE_CLIP_SEGMENT(polygon_points[_i-1],polygon_points[_vi],plane,clipped[clipped_count]); \
+ clipped_count++; \
+ } \
+ } \
+ if(clipped_count<max_clipped&&_i<polygon_point_count) \
+ { \
+ VEC_COPY(clipped[clipped_count],polygon_points[_vi]); \
+ clipped_count++; \
+ } \
+ } \
+ else \
+ { \
+ if(_prevclassif==0) \
+ { \
+ if(clipped_count<max_clipped) \
+ { \
+ PLANE_CLIP_SEGMENT(polygon_points[_i-1],polygon_points[_vi],plane,clipped[clipped_count]); \
+ clipped_count++; \
+ } \
+ } \
+ } \
+ _prevclassif = _classif; \
+ } \
+}\
+
+
+struct GIM_TRIPLANES_CACHE
+{
+ /*!
+ Planes are:
+ 0 : Face normal plane (0,3)
+ 1 : Edge 1 plane (4,7)
+ 2 : Edge 2 plane (8,11)
+ 3 : Edge 3 plane (12,15)
+ */
+ vec4f m_planes[4];
+};
+//typedef struct _GIM_TRIPLANES_CACHE GIM_TRIPLANES_CACHE;
+
+
+struct GIM_TRIANGLE_DATA
+{
+ vec3f m_vertices[3];
+ GIM_TRIPLANES_CACHE m_planes;
+};
+//typedef struct _GIM_TRIANGLE_DATA GIM_TRIANGLE_DATA;
+
+//! tri_data is a GIM_TRIANGLE_DATA
+#define GIM_CALC_TRIANGLE_DATA_PLANES(tri_data)\
+{\
+ TRIANGLE_PLANE((tri_data).m_vertices[0],(tri_data).m_vertices[1],(tri_data).m_vertices[2],(tri_data).m_planes.m_planes[0]);\
+ EDGE_PLANE((tri_data).m_vertices[0],(tri_data).m_vertices[1],((tri_data).m_planes.m_planes[0]),((tri_data).m_planes.m_planes[1]));\
+ EDGE_PLANE((tri_data).m_vertices[1],(tri_data).m_vertices[2],((tri_data).m_planes.m_planes[0]),((tri_data).m_planes.m_planes[2]));\
+ EDGE_PLANE((tri_data).m_vertices[2],(tri_data).m_vertices[0],((tri_data).m_planes.m_planes[0]), ((tri_data).m_planes.m_planes[3]));\
+}\
+
+//Structure for collision
+
+struct GIM_TRIANGLE_CONTACT_DATA
+{
+ GREAL m_penetration_depth;
+ GUINT32 m_point_count;
+ vec3f m_separating_normal;
+ vec3f m_points[MAX_TRI_CLIPPING];
+};
+//typedef struct _GIM_TRIANGLE_CONTACT_DATA GIM_TRIANGLE_CONTACT_DATA;
+
+struct GIM_TRIANGLE_RAY_CONTACT_DATA
+{
+ GREAL u;
+ GREAL v;
+ GREAL tparam;
+ GUINT32 m_face_id;
+ vec3f m_point;
+ vec3f m_normal;
+};
+//typedef struct _GIM_TRIANGLE_RAY_CONTACT_DATA GIM_TRIANGLE_RAY_CONTACT_DATA;
+
+//! Fast Triangle Triangle overlapping test
+int gim_triangle_triangle_overlap(
+ GIM_TRIANGLE_DATA *tri1,
+ GIM_TRIANGLE_DATA *tri2);
+
+
+//! Fast but inacurate conservative Triangle Triangle overlapping test
+int gim_triangle_triangle_overlap_fast(
+ GIM_TRIANGLE_DATA *tri1,
+ GIM_TRIANGLE_DATA *tri2);
+
+
+//! Finds the contact points from a collision of two triangles
+/*!
+Returns the contact points, the penetration depth and the separating normal of the collision
+between two triangles. The normal is pointing toward triangle 1 from triangle 2
+*/
+int gim_triangle_triangle_collision(
+ GIM_TRIANGLE_DATA *tri1,
+ GIM_TRIANGLE_DATA *tri2,
+ GIM_TRIANGLE_CONTACT_DATA * contact_data);
+
+//Ray triangle
+
+
+/*!
+ Solve the System for u,v parameters:
+
+ u*axe1[i1] + v*axe2[i1] = vecproj[i1]
+ u*axe1[i2] + v*axe2[i2] = vecproj[i2]
+
+ sustitute:
+ v = (vecproj[i2] - u*axe1[i2])/axe2[i2]
+
+ then the first equation in terms of 'u':
+
+ --> u*axe1[i1] + ((vecproj[i2] - u*axe1[i2])/axe2[i2])*axe2[i1] = vecproj[i1]
+
+ --> u*axe1[i1] + vecproj[i2]*axe2[i1]/axe2[i2] - u*axe1[i2]*axe2[i1]/axe2[i2] = vecproj[i1]
+
+ --> u*(axe1[i1] - axe1[i2]*axe2[i1]/axe2[i2]) = vecproj[i1] - vecproj[i2]*axe2[i1]/axe2[i2]
+
+ --> u*((axe1[i1]*axe2[i2] - axe1[i2]*axe2[i1])/axe2[i2]) = (vecproj[i1]*axe2[i2] - vecproj[i2]*axe2[i1])/axe2[i2]
+
+ --> u*(axe1[i1]*axe2[i2] - axe1[i2]*axe2[i1]) = vecproj[i1]*axe2[i2] - vecproj[i2]*axe2[i1]
+
+ --> u = (vecproj[i1]*axe2[i2] - vecproj[i2]*axe2[i1]) /(axe1[i1]*axe2[i2] - axe1[i2]*axe2[i1])
+
+if 0.0<= u+v <=1.0 then they are inside of triangle
+
+ */
+#define TRIANGLE_GET_UVPARAMETERS(point,vec1,vec2,vec3,tri_plane,u,v,outside)\
+{\
+ vec3f _axe1, _axe2, _vecproj;\
+ VEC_DIFF(_axe1,vec2,vec1);\
+ VEC_DIFF(_axe2,vec3,vec1);\
+ VEC_DIFF(_vecproj,point,vec1);\
+ GUINT32 _i1,_i2;\
+ PLANE_MINOR_AXES(tri_plane, _i1, _i2);\
+ if(fabsf(_axe2[_i2])<G_EPSILON)\
+ {\
+ u = (_vecproj[_i2]*_axe2[_i1] - _vecproj[_i1]*_axe2[_i2]) /(_axe1[_i2]*_axe2[_i1] - _axe1[_i1]*_axe2[_i2]);\
+ v = (_vecproj[_i1] - u*_axe1[_i1])/_axe2[_i1];\
+ }\
+ else\
+ {\
+ u = (_vecproj[_i1]*_axe2[_i2] - _vecproj[_i2]*_axe2[_i1]) /(_axe1[_i1]*_axe2[_i2] - _axe1[_i2]*_axe2[_i1]);\
+ v = (_vecproj[_i2] - u*_axe1[_i2])/_axe2[_i2];\
+ }\
+ if(u<-G_EPSILON)\
+ {\
+ outside = 1;\
+ }\
+ else if(v<-G_EPSILON)\
+ {\
+ outside = 1;\
+ }\
+ else\
+ {\
+ float sumuv;\
+ sumuv = u+v;\
+ if(sumuv<-G_EPSILON)\
+ {\
+ outside = 1;\
+ }\
+ else if(sumuv-1.0f>G_EPSILON)\
+ {\
+ outside = 1;\
+ }\
+ else\
+ {\
+ outside = 0;\
+ }\
+ }\
+}\
+
+//! Finds the collision of a ray and a triangle.
+#define RAY_TRIANGLE_INTERSECTION(vOrigin,vDir,vec1,vec2,vec3,tri_plane,pout,u,v,tparam,tmax,does_intersect)\
+{\
+ RAY_PLANE_COLLISION(tri_plane,vDir,vOrigin,pout,tparam,does_intersect);\
+ if(does_intersect != 0)\
+ {\
+ if(tparam<-G_EPSILON||tparam>tmax+G_EPSILON)\
+ {\
+ does_intersect = 0;\
+ }\
+ else\
+ {\
+ TRIANGLE_GET_UVPARAMETERS(pout,vec1,vec2,vec3,tri_plane,u,v,does_intersect);\
+ does_intersect = !does_intersect;\
+ }\
+ }\
+}\
+
+
+//! @}
+
+#endif // GIM_TRI_COLLISION_H_INCLUDED
diff --git a/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_tri_sphere_collision.h b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_tri_sphere_collision.h new file mode 100644 index 0000000..a2a81d6 --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_tri_sphere_collision.h @@ -0,0 +1,51 @@ +#ifndef GIM_TRI_SPHERE_COLLISION_H_INCLUDED
+#define GIM_TRI_SPHERE_COLLISION_H_INCLUDED
+
+/*! \file gim_tri_sphere_collision.h
+\author Francisco León
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+/*! \addtogroup GEOMETRIC_OPERATIONS
+*/
+//! @{
+
+//! Finds the contact points from a collision of a triangle and a sphere
+/*!
+\param tri
+\param center
+\param radius
+\param contact_data Contains the closest points on the Sphere, and the normal is pointing to triangle
+*/
+int gim_triangle_sphere_collision(
+ GIM_TRIANGLE_DATA *tri,
+ vec3f center, GREAL radius,
+ GIM_TRIANGLE_CONTACT_DATA * contact_data);
+
+//! @}
+#endif // GIM_TRI_SPHERE_COLLISION_H_INCLUDED
diff --git a/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_trimesh.h b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_trimesh.h new file mode 100644 index 0000000..2983fca --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gim_trimesh.h @@ -0,0 +1,544 @@ +#ifndef GIM_TRIMESH_H_INCLUDED
+#define GIM_TRIMESH_H_INCLUDED
+/*! \file gim_trimesh.h
+\author Francisco León
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "GIMPACT/gim_boxpruning.h"
+#include "GIMPACT/gim_contact.h"
+
+
+///MAsk defines
+#define GIM_TRIMESH_TRANSFORMED_REPLY 1
+#define GIM_TRIMESH_NEED_UPDATE 2
+
+/*! \addtogroup TRIMESH
+\brief
+A Trimesh is the basic geometric structure for representing solid objects.
+<p><strong>CREATING TRIMESHES</strong></p>
+<ul>
+<li> For creating trimeshes, you must initialize Buffer managers by calling \ref gimpact_init
+<li> Then you must define the vertex and index sources by creating them with \ref BUFFER_ARRAYS routines, and then call \ref gim_trimesh_create_from_arrays.
+<li> An alternative way for creaing trimesh objects is calling \ref gim_trimesh_create_from_data.
+<li> For access to the trimesh data (vertices, triangle indices), you must call \ref gim_trimesh_locks_work_data , and \ref gim_trimesh_unlocks_work_data for finish the access.
+<li> Each time when the trimesh data is modified, you must call \ref gim_trimesh_update after.
+<li> When a trimesh is no longer needed, you must call \ref gim_trimesh_destroy.
+</ul>
+
+<p>This is an example of how to create a deformable trimesh that shares vertices with the user application:</p>
+\code
+//Declaration of vertices
+vec3f trimeshvertices[200];
+//Declaration of indices
+GUINT trimeshindices[100];
+
+... Initializing vertices and triangle indices at beginning
+
+//Then create trimesh
+GIM_TRIMESH mytrimesh;
+
+//Calling trimesh create function
+
+gim_trimesh_create_from_data(
+&mytrimesh,
+trimeshvertices,200,
+0 ,//copy_vertices is 0
+trimeshindices,
+100,
+0, //copy_indices is 0
+0 //transformed_reply is 0
+);
+\endcode
+<p>Note that parameter transformed_reply is 0, that means that m_transformed_vertex_buffer is a reference to m_source_vertex on the trimesh, and transformations are not avaliable. Use that configuration if you have to simulate a deformable trimesh like cloth or elastic bodies.</p>
+<p>When the trimesh is no longer needed, destroy it safely with gim_trimesh_destroy()</p>
+<p><strong>UPDATING TRIMESHES</strong></p>
+<p>On simulation loops, is needed to update trimeshes every time for update vertices althought updating triangle boxes and planes cache. There is two ways for update trimeshes: </p>
+<ul>
+<li> Updating vertices directly. You need to access to the \ref GIM_TRIMESH.m_source_vertex_buffer member; a vertex buffer which has access to the source vertices.
+\code
+// Access to the source vertices
+gim_buffer_array_lock(&mytrimesh.m_source_vertex_buffer, G_MA_READ_WRITE);
+
+//Get a pointer to the vertex buffer
+vec3f * vertexpointer = GIM_BUFFER_ARRAY_POINTER(vec3f,mytrimesh.m_source_vertex_buffer,0);
+
+//Get the amount of vertices
+int veccount = mytrimesh.m_source_vertex_buffer.m_element_count;
+
+//Modify vertices
+for (int i=0;i<veccount ;i++ )
+{
+ .....
+ .....
+ processing vertices
+ .....
+ .....
+}
+
+// Don't forget to unlock the source vertex array
+gim_buffer_array_unlock(&mytrimesh.m_source_vertex_buffer);
+
+// Notify that the state of the trimesh is changed
+gim_trimesh_post_update(&mytrimesh.m_source_vertex_buffer);
+
+\endcode
+For making trimeshes that allow to update their vertices, use \ref gim_trimesh_create_from_data with parameter <strong>transformed_reply</strong> = 0.
+</ul>
+<ul>
+<li> Aplying a transformation. Simply use \ref gim_trimesh_set_tranform . Remember that with this method trimeshes must be created with \ref gim_trimesh_create_from_data with parameter <strong>transformed_reply</strong> = 1.
+</ul>
+<p> After updating vertices, you must call \ref gim_trimesh_update()</p>
+<p><strong>TRIMESHES COLLISION</strong></p>
+<p>Before collide trimeshes, you need to update them first.</p>
+<p>Then you must use \ref gim_trimesh_trimesh_collision().</p>
+
+*/
+//! @{
+
+//! Prototype for updating vertices
+typedef void * gim_update_trimesh_function(struct _GIM_TRIMESH *);
+
+//! Trimesh
+struct GIM_TRIMESH
+{
+ ///Original
+ //@{
+ GBUFFER_ARRAY m_source_vertex_buffer;//!< Buffer of vec3f coordinates
+
+ //! (GUINT) Indices of triangles,groups of three elements.
+ /*!
+ Array of GUINT. Triangle indices. Each triple contains indices of the vertices for each triangle.
+ \invariant must be aligned
+ */
+ GBUFFER_ARRAY m_tri_index_buffer;
+ //@}
+ ///Allocated
+ //@{
+ char m_mask;//!< Don't use directly
+
+ //! Allocated transformed vertices vec3f
+ /*!
+ Array of vec3f.If gim_trimesh_has_tranformed_reply(this) == 1 then it refers to the m_source_vertex_buffer
+ \invariant must be aligned
+ */
+ GBUFFER_ARRAY m_transformed_vertex_buffer;
+ //@}
+ ///Auxiliary data
+ //@{
+ GIM_AABB_SET m_aabbset;
+ GDYNAMIC_ARRAY m_planes_cache_buffer;//! Allocated GIM_TRIPLANES_CACHE
+ GDYNAMIC_ARRAY m_planes_cache_bitset;
+ gim_update_trimesh_function * m_update_callback;//! If null, then m_transform is applied.
+ mat4f m_transform;
+ //@}
+};
+//typedef struct _GIM_TRIMESH GIM_TRIMESH;
+
+/// Info about mesh
+//! Return the trimesh triangle count
+GUINT32 gim_trimesh_get_triangle_count(GIM_TRIMESH * trimesh);
+
+//! Returns 1 if the m_transformed_vertex_buffer is a reply of m_source_vertex_buffer
+char gim_trimesh_has_tranformed_reply(GIM_TRIMESH * trimesh);
+
+//! Returns 1 if the trimesh needs to update their aabbset and the planes cache.
+char gim_trimesh_needs_update(GIM_TRIMESH * trimesh);
+
+//! Change the state of the trimesh for force it to update
+/*!
+Call it after made changes to the trimesh.
+\post gim_trimesh_need_update(trimesh) will return 1
+\sa gim_trimesh_needs_update,gim_trimesh_has_tranformed_reply
+*/
+void gim_trimesh_post_update(GIM_TRIMESH * trimesh);
+
+//! Creates the aabb set and the triangles cache
+/*!
+
+\param trimesh
+\param vertex_array
+\param triindex_array
+\param transformed_reply If 1, then the m_transformed_vertices is a reply of the source vertices. Else it just be a reference to the original array.
+\post it copies the arrays by reference, and creates the auxiliary data (m_aabbset,m_planes_cache_buffer)
+*/
+void gim_trimesh_create_from_arrays(GBUFFER_MANAGER_DATA buffer_managers[],
+ GIM_TRIMESH * trimesh, GBUFFER_ARRAY * vertex_array, GBUFFER_ARRAY * triindex_array,char transformed_reply);
+
+
+
+//! Create a trimesh from vertex array and an index array
+/*!
+\param trimesh An uninitialized GIM_TRIMESH structure
+\param vertex_array A buffer to a vec3f array
+\param vertex_count
+\param triindex_array
+\param index_count
+\param copy_vertices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
+\param copy_indices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
+\param transformed_reply If 1, then the m_transformed_vertices is a reply of the source vertices. Else it just be a reference to the original array. Use 1 if you will apply transformations to the trimesh. See \ref gim_trimesh_set_tranform().
+*/
+void gim_trimesh_create_from_data(GBUFFER_MANAGER_DATA buffer_managers[],
+ GIM_TRIMESH * trimesh, vec3f * vertex_array, GUINT32 vertex_count,char copy_vertices,
+ GUINT32 * triindex_array, GUINT32 index_count,char copy_indices,char transformed_reply);
+
+//! Clears auxiliary data and releases buffer arrays
+void gim_trimesh_destroy(GIM_TRIMESH * trimesh);
+
+//! Copies two meshes
+/*!
+\param source_trimesh
+\param dest_trimesh
+\param copy_by_reference If 1, it attach a reference to the source vertices, else it copies the vertices
+\param transformed_reply If 1, transformed vertices are reply of source vertives. 1 Is recommended
+*/
+void gim_trimesh_copy(GIM_TRIMESH * source_trimesh,
+ GBUFFER_MANAGER_DATA dest_buffer_managers[], GIM_TRIMESH * dest_trimesh,
+ char copy_by_reference, char transformed_reply);
+
+
+//! Locks the trimesh for working with it
+/*!
+\post locks m_tri_index_buffer and m_transformed_vertex_buffer.
+\param trimesh
+*/
+void gim_trimesh_locks_work_data(GIM_TRIMESH * trimesh);
+
+
+//! unlocks the trimesh
+/*!
+\post unlocks m_tri_index_buffer and m_transformed_vertex_buffer.
+\param trimesh
+*/
+void gim_trimesh_unlocks_work_data(GIM_TRIMESH * trimesh);
+
+//! Updates m_transformed_vertex_buffer
+/*!
+\pre m_transformed_vertex_buffer must be unlocked
+*/
+void gim_trimesh_update_vertices(GIM_TRIMESH * trimesh);
+
+//! Updates m_aabbset and m_planes_cache_bitset
+/*!
+\pre gim_trimesh_locks_work_data must be called before
+*/
+void gim_trimesh_update_aabbset(GIM_TRIMESH * trimesh);
+
+//! Calls before perfom collisions. Updates the trimesh if needed
+/*!
+\post If gim_trimesh_needs_update returns 1, then it calls gim_trimesh_update_vertices and gim_trimesh_update_aabbset
+*/
+void gim_trimesh_update(GIM_TRIMESH * trimesh);
+
+//! Set the transform of a trimesh
+/*!
+\post This function calls to gim_trimesh_post_update
+*/
+void gim_trimesh_set_tranform(GIM_TRIMESH * trimesh, mat4f transform);
+
+//! Fetch triangle data
+/*!
+\pre gim_trimesh_locks_work_data must be called before
+*/
+void gim_trimesh_get_triangle_data(GIM_TRIMESH * trimesh, GUINT32 triangle_index, GIM_TRIANGLE_DATA * tri_data);
+
+//! Fetch triangle vertices
+/*!
+\pre gim_trimesh_locks_work_data must be called before
+*/
+void gim_trimesh_get_triangle_vertices(GIM_TRIMESH * trimesh, GUINT32 triangle_index, vec3f v1,vec3f v2,vec3f v3);
+
+//! Trimesh Trimesh Collisions
+/*!
+Before use this function you must update each trimesh:
+\code
+gim_trimesh_update(TriMesh1);
+gim_trimesh_update(TriMesh2);
+\endcode
+Then you must use the trimesh collision in this way:
+\code
+int collide_trimeshes(GIM_TRIMESH * TriMesh1, GIM_TRIMESH * TriMesh2)
+{
+ //Create contact list
+ GDYNAMIC_ARRAY trimeshcontacts;
+ GIM_CREATE_CONTACT_LIST(trimeshcontacts);
+
+ //Collide trimeshes
+ gim_trimesh_trimesh_collision(TriMesh1,TriMesh2,&trimeshcontacts);
+
+ if(trimeshcontacts.m_size == 0) //do nothing
+ {
+ GIM_DYNARRAY_DESTROY(trimeshcontacts);//clean contact array
+ return 0;
+ }
+
+ //Getting a pointer to the contact array
+ GIM_CONTACT * ptrimeshcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,trimeshcontacts);
+
+ int contactcount = trimeshcontacts.m_size;
+ int i;
+ //Process contacts
+ for (i=0;i<contactcount ;i++)
+ {
+ //Do something with the contact (ptrimeshcontacts)
+ ......
+ ......
+ // Like creating joints or anything else
+ ......
+ ......
+ ptrimeshcontacts++;
+ }
+ GIM_DYNARRAY_DESTROY(trimeshcontacts);
+ return contactcount;
+}
+\endcode
+In each contact
+<ul>
+<li> m_handle1 points to trimesh1.
+<li> m_handle2 points to trimesh2.
+<li> m_feature1 Is a triangle index of trimesh1.
+<li> m_feature2 Is a triangle index of trimesh2.
+</ul>
+
+\param trimesh1 Collider
+\param trimesh2 Collidee
+\param contacts A GIM_CONTACT array. Must be initialized
+*/
+void gim_trimesh_trimesh_collision(GIM_TRIMESH * trimesh1, GIM_TRIMESH * trimesh2, GDYNAMIC_ARRAY * contacts);
+
+
+//! Trimesh Sphere Collisions
+/*!
+Before use this function you must update the trimesh:
+\code
+gim_trimesh_update(trimesh);
+\endcode
+Then you must use this function in this way:
+\code
+int collide_trimesh_sphere(GIM_TRIMESH * trimesh, vec3f center,GREAL radius)
+{
+ //Create contact list
+ GDYNAMIC_ARRAY trimeshcontacts;
+ GIM_CREATE_CONTACT_LIST(trimeshcontacts);
+
+ //Collide trimeshes
+ gim_trimesh_sphere_collision(trimesh,center,radius,&trimeshcontacts);
+
+ if(trimeshcontacts.m_size == 0) //do nothing
+ {
+ GIM_DYNARRAY_DESTROY(trimeshcontacts);//clean contact array
+ return 0;
+ }
+
+ //Getting a pointer to the contact array
+ GIM_CONTACT * ptrimeshcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,trimeshcontacts);
+
+ int contactcount = trimeshcontacts.m_size;
+ int i;
+ //Process contacts
+ for (i=0;i<contactcount ;i++)
+ {
+ //Do something with the contact (ptrimeshcontacts)
+ ......
+ ......
+ // Like creating joints or anything else
+ ......
+ ......
+ ptrimeshcontacts++;
+ }
+ GIM_DYNARRAY_DESTROY(trimeshcontacts);
+ return contactcount;
+}
+\endcode
+
+In each contact
+<ul>
+<li> m_handle1 points to trimesh.
+<li> m_handle2 points to NULL.
+<li> m_feature1 Is a triangle index of trimesh.
+</ul>
+
+\param trimesh
+\param center
+\param radius
+\param contacts A GIM_CONTACT array. Must be initialized
+*/
+void gim_trimesh_sphere_collision(GIM_TRIMESH * trimesh,vec3f center,GREAL radius, GDYNAMIC_ARRAY * contacts);
+
+
+//! Trimesh Capsule collision
+/*!
+Find the closest primitive collided by the ray.
+
+Before use this function you must update the trimesh:
+\code
+gim_trimesh_update(trimesh);
+\endcode
+Then you must use this function in this way:
+\code
+int collide_trimesh_capsule(GIM_TRIMESH * trimesh, GIM_CAPSULE_DATA * capsule)
+{
+ //Create contact list
+ GDYNAMIC_ARRAY trimeshcontacts;
+ GIM_CREATE_CONTACT_LIST(trimeshcontacts);
+
+ //Collide trimeshes
+ gim_trimesh_capsule_collision(trimesh,capsule,&trimeshcontacts);
+
+ if(trimeshcontacts.m_size == 0) //do nothing
+ {
+ GIM_DYNARRAY_DESTROY(trimeshcontacts);//clean contact array
+ return 0;
+ }
+
+ //Getting a pointer to the contact array
+ GIM_CONTACT * ptrimeshcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,trimeshcontacts);
+
+ int contactcount = trimeshcontacts.m_size;
+ int i;
+ //Process contacts
+ for (i=0;i<contactcount ;i++)
+ {
+ //Do something with the contact (ptrimeshcontacts)
+ ......
+ ......
+ // Like creating joints or anything else
+ ......
+ ......
+ ptrimeshcontacts++;
+ }
+ GIM_DYNARRAY_DESTROY(trimeshcontacts);
+ return contactcount;
+}
+\endcode
+
+In each contact
+<ul>
+<li> m_handle1 points to trimesh.
+<li> m_handle2 points to NULL.
+<li> m_feature1 Is a triangle index of trimesh.
+</ul>
+
+\param trimesh
+\param capsule
+\param contacts A GIM_CONTACT array. Must be initialized
+*/
+void gim_trimesh_capsule_collision(GIM_TRIMESH * trimesh, GIM_CAPSULE_DATA * capsule, GDYNAMIC_ARRAY * contacts);
+
+
+///Function for create Trimesh Plane collision result
+#define GIM_CREATE_TRIMESHPLANE_CONTACTS(dynarray) GIM_DYNARRAY_CREATE(vec4f,dynarray,G_ARRAY_GROW_SIZE)
+
+//! Trimesh Plane Collisions
+/*!
+
+Before use this function you must update the trimesh:
+\code
+gim_trimesh_update(trimesh);
+\endcode
+Then you must use this function in this way:
+\code
+int collide_trimesh_plane(GIM_TRIMESH * trimesh, vec4f plane)
+{
+ //Create contact list
+ GDYNAMIC_ARRAY tri_plane_contacts;
+ GIM_CREATE_TRIMESHPLANE_CONTACTS(tri_plane_contacts);
+
+ //Collide trimeshes
+ gim_trimesh_plane_collision(trimesh,plane,&tri_plane_contacts);
+
+ if(tri_plane_contacts.m_size == 0) //do nothing
+ {
+ GIM_DYNARRAY_DESTROY(tri_plane_contacts);//clean contact array
+ return 0;
+ }
+
+ //Getting a pointer to the contact array
+ vec4f * planecontacts = GIM_DYNARRAY_POINTER(vec4f,tri_plane_contacts);
+
+ int contactcount = tri_plane_contacts.m_size;
+ int i;
+ //Process contacts
+ for (i=0;i<contactcount ;i++)
+ {
+ vec3f contactpoint;
+ GREAL contactdis;
+
+ VEC_COPY(contactpoint,planecontacts[i]); //Get contact point
+ contactdis = planecontacts[i][3]; // Get distance depth
+
+ //Do something with the contact
+ ......
+ ......
+ // Like creating joints or anything else
+ ......
+ ......
+ }
+ GIM_DYNARRAY_DESTROY(tri_plane_contacts);
+ return contactcount;
+}
+\endcode
+
+In each contact the 3 first coordinates refers to the contact point, the fourth refers to the distance depth and the normal is the normal of the plane.
+
+\param trimesh
+\param plane vec4f plane
+\param contacts A vec4f array. Must be initialized (~100). Each element have the coordinate point in the first 3 elements, and vec4f[3] has the penetration depth.
+*/
+void gim_trimesh_plane_collision(GIM_TRIMESH * trimesh,vec4f plane, GDYNAMIC_ARRAY * contacts);
+
+
+//! Trimesh Ray Collisions
+/*!
+\param trimesh
+\param origin
+\param dir
+\param tmax
+\param contact
+\return 1 if the ray collides, else 0
+*/
+int gim_trimesh_ray_collision(GIM_TRIMESH * trimesh,vec3f origin,vec3f dir, GREAL tmax, GIM_TRIANGLE_RAY_CONTACT_DATA * contact);
+
+
+//! Trimesh Ray Collisions closest
+/*!
+Find the closest primitive collided by the ray
+\param trimesh
+\param origin
+\param dir
+\param tmax
+\param contact
+\return 1 if the ray collides, else 0
+*/
+int gim_trimesh_ray_closest_collision(GIM_TRIMESH * trimesh,vec3f origin,vec3f dir, GREAL tmax, GIM_TRIANGLE_RAY_CONTACT_DATA * contact);
+
+//! @}
+
+
+
+#endif // GIM_TRIMESH_H_INCLUDED
diff --git a/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gimpact.h b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gimpact.h new file mode 100644 index 0000000..bcd22a1 --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/include/GIMPACT/gimpact.h @@ -0,0 +1,45 @@ +#ifndef GIMPACT_H_INCLUDED
+#define GIMPACT_H_INCLUDED
+
+/*! \file gimpact.h
+\author Francisco León
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include "GIMPACT/gim_trimesh.h"
+
+/*! \defgroup GIMPACT_INIT
+*/
+//! @{
+//! Call this for initialize GIMPACT system structures.
+void gimpact_init();
+//! Call this for clean GIMPACT system structures.
+void gimpact_terminate();
+//! @}
+#endif // GIMPACT_H_INCLUDED
diff --git a/libs/ode-0.16.1/GIMPACT/include/Makefile.am b/libs/ode-0.16.1/GIMPACT/include/Makefile.am new file mode 100644 index 0000000..e247258 --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/include/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = GIMPACT diff --git a/libs/ode-0.16.1/GIMPACT/include/Makefile.in b/libs/ode-0.16.1/GIMPACT/include/Makefile.in new file mode 100644 index 0000000..79b367d --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/include/Makefile.in @@ -0,0 +1,640 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = GIMPACT/include +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ode/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_CFLAGS = @CCD_CFLAGS@ +CCD_LIBS = @CCD_LIBS@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSTDCXX = @LIBSTDCXX@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ODE_PRECISION = @ODE_PRECISION@ +ODE_VERSION = @ODE_VERSION@ +ODE_VERSION_INFO = @ODE_VERSION_INFO@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = GIMPACT +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign GIMPACT/include/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign GIMPACT/include/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/GIMPACT/src/Makefile.am b/libs/ode-0.16.1/GIMPACT/src/Makefile.am new file mode 100644 index 0000000..2cd230b --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/src/Makefile.am @@ -0,0 +1,19 @@ +noinst_LTLIBRARIES = libGIMPACT.la +AM_CPPFLAGS = -fno-strict-aliasing \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/ode/src \ + -I$(top_srcdir)/GIMPACT/include + +libGIMPACT_la_SOURCES = gim_boxpruning.cpp \ + gim_contact.cpp \ + gim_math.cpp \ + gim_memory.cpp \ + gim_tri_tri_overlap.cpp \ + gim_trimesh.cpp \ + gim_trimesh_capsule_collision.cpp \ + gim_trimesh_ray_collision.cpp \ + gim_trimesh_sphere_collision.cpp \ + gim_trimesh_trimesh_collision.cpp \ + gimpact.cpp + diff --git a/libs/ode-0.16.1/GIMPACT/src/Makefile.in b/libs/ode-0.16.1/GIMPACT/src/Makefile.in new file mode 100644 index 0000000..70ab49e --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/src/Makefile.in @@ -0,0 +1,638 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = GIMPACT/src +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ode/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libGIMPACT_la_LIBADD = +am_libGIMPACT_la_OBJECTS = gim_boxpruning.lo gim_contact.lo \ + gim_math.lo gim_memory.lo gim_tri_tri_overlap.lo \ + gim_trimesh.lo gim_trimesh_capsule_collision.lo \ + gim_trimesh_ray_collision.lo gim_trimesh_sphere_collision.lo \ + gim_trimesh_trimesh_collision.lo gimpact.lo +libGIMPACT_la_OBJECTS = $(am_libGIMPACT_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +SOURCES = $(libGIMPACT_la_SOURCES) +DIST_SOURCES = $(libGIMPACT_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_CFLAGS = @CCD_CFLAGS@ +CCD_LIBS = @CCD_LIBS@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSTDCXX = @LIBSTDCXX@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ODE_PRECISION = @ODE_PRECISION@ +ODE_VERSION = @ODE_VERSION@ +ODE_VERSION_INFO = @ODE_VERSION_INFO@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LTLIBRARIES = libGIMPACT.la +AM_CPPFLAGS = -fno-strict-aliasing \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/ode/src \ + -I$(top_srcdir)/GIMPACT/include + +libGIMPACT_la_SOURCES = gim_boxpruning.cpp \ + gim_contact.cpp \ + gim_math.cpp \ + gim_memory.cpp \ + gim_tri_tri_overlap.cpp \ + gim_trimesh.cpp \ + gim_trimesh_capsule_collision.cpp \ + gim_trimesh_ray_collision.cpp \ + gim_trimesh_sphere_collision.cpp \ + gim_trimesh_trimesh_collision.cpp \ + gimpact.cpp + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign GIMPACT/src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign GIMPACT/src/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libGIMPACT.la: $(libGIMPACT_la_OBJECTS) $(libGIMPACT_la_DEPENDENCIES) $(EXTRA_libGIMPACT_la_DEPENDENCIES) + $(AM_V_CXXLD)$(CXXLINK) $(libGIMPACT_la_OBJECTS) $(libGIMPACT_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_boxpruning.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_contact.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_math.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_memory.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_tri_tri_overlap.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_trimesh.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_trimesh_capsule_collision.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_trimesh_ray_collision.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_trimesh_sphere_collision.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gim_trimesh_trimesh_collision.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpact.Plo@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/GIMPACT/src/gim_boxpruning.cpp b/libs/ode-0.16.1/GIMPACT/src/gim_boxpruning.cpp new file mode 100644 index 0000000..f2e77d7 --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/src/gim_boxpruning.cpp @@ -0,0 +1,519 @@ +
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include "GIMPACT/gim_boxpruning.h"
+
+
+
+//! Allocate memory for all aabb set.
+void gim_aabbset_alloc(GIM_AABB_SET * aabbset, GUINT32 count)
+{
+ aabbset->m_count = count;
+ aabbset->m_boxes = (aabb3f *)gim_alloc(sizeof(aabb3f)*count);
+
+ if(count<GIM_MIN_SORTED_BIPARTITE_PRUNING_BOXES)
+ {
+ aabbset->m_maxcoords = 0;
+ aabbset->m_sorted_mincoords = 0;
+ }
+ else
+ {
+ aabbset->m_maxcoords = (GUINT32 *)gim_alloc(sizeof(GUINT32)*aabbset->m_count );
+ aabbset->m_sorted_mincoords = (GIM_RSORT_TOKEN *)gim_alloc(sizeof(GIM_RSORT_TOKEN)*aabbset->m_count);
+ }
+ aabbset->m_shared = 0;
+ INVALIDATE_AABB(aabbset->m_global_bound);
+}
+
+//! Destroys the aabb set.
+void gim_aabbset_destroy(GIM_AABB_SET * aabbset)
+{
+ aabbset->m_count = 0;
+ if(aabbset->m_shared==0)
+ {
+ gim_free(aabbset->m_boxes,0);
+ gim_free(aabbset->m_maxcoords,0);
+ gim_free(aabbset->m_sorted_mincoords,0);
+ }
+ aabbset->m_boxes = 0;
+ aabbset->m_sorted_mincoords = 0;
+ aabbset->m_maxcoords = 0;
+}
+
+void gim_aabbset_calc_global_bound(GIM_AABB_SET * aabbset)
+{
+ aabb3f * paabb = aabbset->m_boxes;
+ aabb3f * globalbox = &aabbset->m_global_bound;
+ AABB_COPY((*globalbox),(*paabb));
+
+ GUINT32 count = aabbset->m_count-1;
+ paabb++;
+ while(count)
+ {
+ MERGEBOXES(*globalbox,*paabb)
+ paabb++;
+ count--;
+ }
+}
+
+
+//! Sorts the boxes for box prunning.
+/*!
+1) find the integer representation of the aabb coords
+2) Sorts the min coords
+3) Calcs the global bound
+\pre aabbset must be allocated. And the boxes must be already set.
+\param aabbset
+\param calc_global_bound If 1 , calcs the global bound
+\post If aabbset->m_sorted_mincoords == 0, then it allocs the sorted coordinates
+*/
+void gim_aabbset_sort(GIM_AABB_SET * aabbset, char calc_global_bound)
+{
+ if(aabbset->m_sorted_mincoords == 0)
+ {//allocate
+ aabbset->m_maxcoords = (GUINT32 *)gim_alloc(sizeof(GUINT32)*aabbset->m_count );
+ aabbset->m_sorted_mincoords = (GIM_RSORT_TOKEN *)gim_alloc(sizeof(GIM_RSORT_TOKEN)*aabbset->m_count);
+ }
+
+ GUINT32 i, count = aabbset->m_count;
+ aabb3f * paabb = aabbset->m_boxes;
+ GUINT32 * maxcoords = aabbset->m_maxcoords;
+ GIM_RSORT_TOKEN * sorted_tokens = aabbset->m_sorted_mincoords;
+
+ if(count<860)//Calibrated on a Pentium IV
+ {
+ //Sort by quick sort
+ //Calculate keys
+ for(i=0;i<count;i++)
+ {
+ GIM_CONVERT_VEC3F_GUINT_XZ_UPPER(paabb[i].maxX,paabb[i].maxZ,maxcoords[i]);
+ GIM_CONVERT_VEC3F_GUINT_XZ(paabb[i].minX,paabb[i].minZ,sorted_tokens[i].m_key);
+ sorted_tokens[i].m_value = i;
+ }
+ GIM_QUICK_SORT_ARRAY(GIM_RSORT_TOKEN , sorted_tokens, count, RSORT_TOKEN_COMPARATOR,GIM_DEF_EXCHANGE_MACRO);
+ }
+ else
+ {
+ //Sort by radix sort
+ GIM_RSORT_TOKEN * unsorted = (GIM_RSORT_TOKEN *)gim_alloc(sizeof(GIM_RSORT_TOKEN )*count);
+ //Calculate keys
+ for(i=0;i<count;i++)
+ {
+ GIM_CONVERT_VEC3F_GUINT_XZ_UPPER(paabb[i].maxX,paabb[i].maxZ,maxcoords[i]);
+ GIM_CONVERT_VEC3F_GUINT_XZ(paabb[i].minX,paabb[i].minZ,unsorted[i].m_key);
+ unsorted[i].m_value = i;
+ }
+ GIM_RADIX_SORT_RTOKENS(unsorted,sorted_tokens,count);
+ gim_free(unsorted,0);
+ }
+
+ if(calc_global_bound) gim_aabbset_calc_global_bound(aabbset);
+}
+
+//utility macros
+
+/*#define PUSH_PAIR(i,j,pairset)\
+{\
+ GIM_PAIR _pair={i,j};\
+ GIM_DYNARRAY_PUSH_ITEM(GIM_PAIR,pairset,_pair);\
+}*/
+
+#define PUSH_PAIR(i,j,pairset)\
+{\
+ GIM_DYNARRAY_PUSH_EMPTY(GIM_PAIR,pairset);\
+ GIM_PAIR * _pair = GIM_DYNARRAY_POINTER(GIM_PAIR,pairset) + (pairset).m_size - 1;\
+ _pair->m_index1 = i;\
+ _pair->m_index2 = j;\
+}
+
+#define PUSH_PAIR_INV(i,j,pairset)\
+{\
+ GIM_DYNARRAY_PUSH_EMPTY(GIM_PAIR,pairset);\
+ GIM_PAIR * _pair = GIM_DYNARRAY_POINTER(GIM_PAIR,pairset) + (pairset).m_size - 1;\
+ _pair->m_index1 = j;\
+ _pair->m_index2 = i;\
+}
+
+#define FIND_OVERLAPPING_FOWARD(\
+ curr_index,\
+ test_count,\
+ test_aabb,\
+ max_coord_uint,\
+ sorted_tokens,\
+ aabbarray,\
+ pairset,\
+ push_pair_macro)\
+{\
+ GUINT32 _i = test_count;\
+ char _intersected;\
+ GIM_RSORT_TOKEN * _psorted_tokens = sorted_tokens;\
+ while(_i>0 && max_coord_uint >= _psorted_tokens->m_key)\
+ {\
+ AABBCOLLISION(_intersected,test_aabb,aabbarray[_psorted_tokens->m_value]);\
+ if(_intersected)\
+ {\
+ push_pair_macro(curr_index, _psorted_tokens->m_value,pairset);\
+ }\
+ _psorted_tokens++;\
+ _i--;\
+ }\
+}
+
+//! log(N) Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
+/*!
+\pre aabbset must be allocated and sorted, the boxes must be already set.
+\param aabbset Must be sorted. Global bound isn't required
+\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
+*/
+void gim_aabbset_self_intersections_sorted(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs)
+{
+ collision_pairs->m_size = 0;
+ GUINT32 count = aabbset->m_count;
+ aabb3f * paabb = aabbset->m_boxes;
+ GUINT32 * maxcoords = aabbset->m_maxcoords;
+ GIM_RSORT_TOKEN * sorted_tokens = aabbset->m_sorted_mincoords;
+ aabb3f test_aabb;
+ while(count>1)
+ {
+ ///current cache variables
+ GUINT32 curr_index = sorted_tokens->m_value;
+ GUINT32 max_coord_uint = maxcoords[curr_index];
+ AABB_COPY(test_aabb,paabb[curr_index]);
+
+ ///next pairs
+ sorted_tokens++;
+ count--;
+ FIND_OVERLAPPING_FOWARD( curr_index, count, test_aabb, max_coord_uint, sorted_tokens , paabb, (*collision_pairs),PUSH_PAIR);
+ }
+}
+
+//! NxN Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
+/*!
+\pre aabbset must be allocated, the boxes must be already set.
+\param aabbset Global bound isn't required. Doen't need to be sorted.
+\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
+*/
+void gim_aabbset_self_intersections_brute_force(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs)
+{
+ collision_pairs->m_size = 0;
+ GUINT32 i,j;
+ GUINT32 count = aabbset->m_count;
+ aabb3f * paabb = aabbset->m_boxes;
+ char intersected;
+ for (i=0;i< count-1 ;i++ )
+ {
+ for (j=i+1;j<count ;j++ )
+ {
+ AABBCOLLISION(intersected,paabb[i],paabb[j]);
+ if(intersected)
+ {
+ PUSH_PAIR(i,j,(*collision_pairs));
+ }
+ }
+ }
+}
+
+//! log(N) Bipartite box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
+/*!
+\pre aabbset1 and aabbset2 must be allocated and sorted, the boxes must be already set.
+\param aabbset1 Must be sorted, Global bound is required.
+\param aabbset2 Must be sorted, Global bound is required.
+\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
+*/
+void gim_aabbset_bipartite_intersections_sorted(GIM_AABB_SET * aabbset1, GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs)
+{
+ char intersected;
+ collision_pairs->m_size = 0;
+
+ AABBCOLLISION(intersected,aabbset1->m_global_bound,aabbset2->m_global_bound);
+ if(intersected == 0) return;
+
+ GUINT32 count1 = aabbset1->m_count;
+ aabb3f * paabb1 = aabbset1->m_boxes;
+ GUINT32 * maxcoords1 = aabbset1->m_maxcoords;
+ GIM_RSORT_TOKEN * sorted_tokens1 = aabbset1->m_sorted_mincoords;
+
+ GUINT32 count2 = aabbset2->m_count;
+ aabb3f * paabb2 = aabbset2->m_boxes;
+ GUINT32 * maxcoords2 = aabbset2->m_maxcoords;
+ GIM_RSORT_TOKEN * sorted_tokens2 = aabbset2->m_sorted_mincoords;
+
+ GUINT32 curr_index;
+
+ GUINT32 max_coord_uint;
+ aabb3f test_aabb;
+
+ //Classify boxes
+ //Find Set intersection
+ aabb3f int_abbb;
+ BOXINTERSECTION(aabbset1->m_global_bound,aabbset2->m_global_bound, int_abbb);
+
+ //Clasify set 1
+ GIM_RSORT_TOKEN * classified_tokens1 = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN)*count1);
+ GUINT32 i,classified_count1 = 0,classified_count2 = 0;
+
+
+ for (i=0;i<count1;i++ )
+ {
+ curr_index = sorted_tokens1[i].m_value;
+ AABBCOLLISION(intersected,paabb1[curr_index],int_abbb);
+ if(intersected)
+ {
+ classified_tokens1[classified_count1] = sorted_tokens1[i];
+ classified_count1++;
+ }
+ }
+
+ if(classified_count1==0)
+ {
+ gim_free(classified_tokens1 ,0);
+ return; // no pairs
+ }
+
+ //Clasify set 2
+ GIM_RSORT_TOKEN * classified_tokens2 = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN)*count2);
+
+ for (i=0;i<count2;i++ )
+ {
+ curr_index = sorted_tokens2[i].m_value;
+ AABBCOLLISION(intersected,paabb2[curr_index],int_abbb);
+ if(intersected)
+ {
+ classified_tokens2[classified_count2] = sorted_tokens2[i];
+ classified_count2++;
+ }
+ }
+
+ if(classified_count2==0)
+ {
+ gim_free(classified_tokens1 ,0);
+ gim_free(classified_tokens2 ,0);
+ return; // no pairs
+ }
+
+ sorted_tokens1 = classified_tokens1;
+ sorted_tokens2 = classified_tokens2;
+
+ while(classified_count1>0&&classified_count2>0)
+ {
+ if(sorted_tokens1->m_key <= sorted_tokens2->m_key)
+ {
+ ///current cache variables
+ curr_index = sorted_tokens1->m_value;
+ max_coord_uint = maxcoords1[curr_index];
+ AABB_COPY(test_aabb,paabb1[curr_index]);
+ ///next pairs
+ sorted_tokens1++;
+ classified_count1--;
+ FIND_OVERLAPPING_FOWARD( curr_index, classified_count2, test_aabb, max_coord_uint, sorted_tokens2 , paabb2, (*collision_pairs), PUSH_PAIR);
+ }
+ else ///Switch test
+ {
+ ///current cache variables
+ curr_index = sorted_tokens2->m_value;
+ max_coord_uint = maxcoords2[curr_index];
+ AABB_COPY(test_aabb,paabb2[curr_index]);
+ ///next pairs
+ sorted_tokens2++;
+ classified_count2--;
+ FIND_OVERLAPPING_FOWARD( curr_index, classified_count1, test_aabb, max_coord_uint, sorted_tokens1 , paabb1, (*collision_pairs), PUSH_PAIR_INV );
+ }
+ }
+ gim_free(classified_tokens1 ,0);
+ gim_free(classified_tokens2 ,0);
+}
+
+//! NxM Bipartite box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
+/*!
+\pre aabbset1 and aabbset2 must be allocated and sorted, the boxes must be already set.
+\param aabbset1 Must be sorted, Global bound is required.
+\param aabbset2 Must be sorted, Global bound is required.
+\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
+*/
+void gim_aabbset_bipartite_intersections_brute_force(GIM_AABB_SET * aabbset1,GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs)
+{
+ char intersected;
+ collision_pairs->m_size = 0;
+ AABBCOLLISION(intersected,aabbset1->m_global_bound,aabbset2->m_global_bound);
+ if(intersected == 0) return;
+
+ aabb3f int_abbb;
+ //Find Set intersection
+ BOXINTERSECTION(aabbset1->m_global_bound,aabbset2->m_global_bound, int_abbb);
+ //Clasify set 1
+ GUINT32 i,j;
+ GUINT32 classified_count = 0;
+
+ GUINT32 count = aabbset1->m_count;
+ aabb3f * paabb1 = aabbset1->m_boxes;
+ aabb3f * paabb2 = aabbset2->m_boxes;
+
+ GUINT32 * classified = (GUINT32 *) gim_alloc(sizeof(GUINT32)*count);
+
+ for (i=0;i<count;i++ )
+ {
+ AABBCOLLISION(intersected,paabb1[i],int_abbb);
+ if(intersected)
+ {
+ classified[classified_count] = i;
+ classified_count++;
+ }
+ }
+
+ if(classified_count==0)
+ {
+ gim_free(classified,0);
+ return; // no pairs
+ }
+
+ //intesect set2
+ count = aabbset2->m_count;
+ for (i=0;i<count;i++)
+ {
+ AABBCOLLISION(intersected,paabb2[i],int_abbb);
+ if(intersected)
+ {
+ for (j=0;j<classified_count;j++)
+ {
+ AABBCOLLISION(intersected,paabb2[i],paabb1[classified[j]]);
+ if(intersected)
+ {
+ PUSH_PAIR(classified[j],i,(*collision_pairs));
+ }
+ }
+ }
+ }
+ gim_free(classified,0);
+}
+
+
+//! Initalizes the set. Sort Boxes if needed.
+/*!
+\pre aabbset must be allocated. And the boxes must be already set.
+\post If the set has less of GIM_MIN_SORTED_BIPARTITE_PRUNING_BOXES boxes, only calcs the global box,
+ else it Sorts the entire set( Only applicable for large sets)
+*/
+void gim_aabbset_update(GIM_AABB_SET * aabbset)
+{
+ if(aabbset->m_count < GIM_MIN_SORTED_BIPARTITE_PRUNING_BOXES)
+ {//Brute force approach
+ gim_aabbset_calc_global_bound(aabbset);
+ }
+ else
+ {//Sorted force approach
+ gim_aabbset_sort(aabbset,1);
+ }
+}
+
+//! Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set.
+/*!
+This function sorts the set and then it calls to gim_aabbset_self_intersections_brute_force or gim_aabbset_self_intersections_sorted.
+
+\param aabbset Set of boxes. Sorting isn't required.
+\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
+\pre aabbset must be allocated and initialized.
+\post If aabbset->m_count >= GIM_MIN_SORTED_PRUNING_BOXES, then it calls to gim_aabbset_sort and then to gim_aabbset_self_intersections_sorted.
+*/
+void gim_aabbset_self_intersections(GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collision_pairs)
+{
+ if(aabbset->m_count < GIM_MIN_SORTED_PRUNING_BOXES)
+ {//Brute force approach
+ gim_aabbset_self_intersections_brute_force(aabbset,collision_pairs);
+ }
+ else
+ {//Sorted force approach
+ gim_aabbset_sort(aabbset,0);
+ gim_aabbset_self_intersections_sorted(aabbset,collision_pairs);
+ }
+}
+
+//! Collides two sets. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set.
+/*!
+\pre aabbset1 and aabbset2 must be allocated and updated. See .
+\param aabbset1 Must be sorted, Global bound is required.
+\param aabbset2 Must be sorted, Global bound is required.
+\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100)
+*/
+void gim_aabbset_bipartite_intersections(GIM_AABB_SET * aabbset1, GIM_AABB_SET * aabbset2, GDYNAMIC_ARRAY * collision_pairs)
+{
+ if(aabbset1->m_sorted_mincoords == 0||aabbset2->m_sorted_mincoords == 0)
+ {//Brute force approach
+ gim_aabbset_bipartite_intersections_brute_force(aabbset1,aabbset2,collision_pairs);
+ }
+ else
+ {//Sorted force approach
+ gim_aabbset_bipartite_intersections_sorted(aabbset1,aabbset2,collision_pairs);
+ }
+}
+
+void gim_aabbset_box_collision(aabb3f *test_aabb, GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collided)
+{
+ collided->m_size = 0;
+ char intersected;
+ AABBCOLLISION(intersected,aabbset->m_global_bound,(*test_aabb));
+ if(intersected == 0) return;
+
+ GUINT32 i;
+ GUINT32 count = aabbset->m_count;
+ aabb3f * paabb = aabbset->m_boxes;
+ aabb3f _testaabb;
+ AABB_COPY(_testaabb,*test_aabb);
+
+ for (i=0;i< count;i++ )
+ {
+ AABBCOLLISION(intersected,paabb[i],_testaabb);
+ if(intersected)
+ {
+ GIM_DYNARRAY_PUSH_ITEM(GUINT32,(*collided),i);
+ }
+ }
+}
+
+void gim_aabbset_ray_collision(vec3f vorigin,vec3f vdir, GREAL tmax, GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collided)
+{
+ collided->m_size = 0;
+ char intersected;
+ GREAL tparam = 0;
+ BOX_INTERSECTS_RAY(aabbset->m_global_bound, vorigin, vdir, tparam, tmax,intersected);
+ if(intersected==0) return;
+
+ GUINT32 i;
+ GUINT32 count = aabbset->m_count;
+ aabb3f * paabb = aabbset->m_boxes;
+
+ for (i=0;i< count;i++ )
+ {
+ BOX_INTERSECTS_RAY(paabb[i], vorigin, vdir, tparam, tmax,intersected);
+ if(intersected)
+ {
+ GIM_DYNARRAY_PUSH_ITEM(GUINT32,(*collided),i);
+ }
+ }
+ (void)tparam;
+}
diff --git a/libs/ode-0.16.1/GIMPACT/src/gim_contact.cpp b/libs/ode-0.16.1/GIMPACT/src/gim_contact.cpp new file mode 100644 index 0000000..4b61298 --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/src/gim_contact.cpp @@ -0,0 +1,132 @@ +
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "GIMPACT/gim_contact.h"
+
+void gim_merge_contacts(GDYNAMIC_ARRAY * source_contacts,
+ GDYNAMIC_ARRAY * dest_contacts)
+{
+ dest_contacts->m_size = 0;
+
+ GUINT32 source_count = source_contacts->m_size;
+ GIM_CONTACT * psource_contacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,(*source_contacts));
+ //create keys
+ GIM_RSORT_TOKEN * keycontacts = (GIM_RSORT_TOKEN * )gim_alloc(sizeof(GIM_RSORT_TOKEN)*source_count);
+
+ GUINT32 i;
+ for(i=0;i<source_count;i++)
+ {
+ keycontacts[i].m_value = i;
+ GIM_CALC_KEY_CONTACT(psource_contacts[i].m_point,keycontacts[i].m_key);
+ }
+
+ //sort keys
+ GIM_QUICK_SORT_ARRAY(GIM_RSORT_TOKEN , keycontacts, source_count, RSORT_TOKEN_COMPARATOR,GIM_DEF_EXCHANGE_MACRO);
+
+ // Merge contacts
+ GIM_CONTACT * pcontact = 0;
+ GIM_CONTACT * scontact = 0;
+ GUINT32 key,last_key=0;
+
+ for(i=0;i<source_contacts->m_size;i++)
+ {
+ key = keycontacts[i].m_key;
+ scontact = &psource_contacts[keycontacts[i].m_value];
+
+ if(i>0 && last_key == key)
+ {
+ //merge contact
+ if(pcontact->m_depth > scontact->m_depth + CONTACT_DIFF_EPSILON)
+ {
+ GIM_COPY_CONTACTS(pcontact, scontact);
+ }
+ }
+ else
+ {//add new contact
+ GIM_DYNARRAY_PUSH_EMPTY(GIM_CONTACT,(*dest_contacts));
+ pcontact = GIM_DYNARRAY_POINTER_LAST(GIM_CONTACT,(*dest_contacts));
+ GIM_COPY_CONTACTS(pcontact, scontact);
+ }
+ last_key = key;
+ }
+ gim_free(keycontacts,0);
+}
+
+void gim_merge_contacts_unique(GDYNAMIC_ARRAY * source_contacts,
+ GDYNAMIC_ARRAY * dest_contacts)
+{
+ dest_contacts->m_size = 0;
+ //Traverse the source contacts
+ GUINT32 source_count = source_contacts->m_size;
+ if(source_count==0) return;
+
+ GIM_CONTACT * psource_contacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,(*source_contacts));
+
+ //add the unique contact
+ GIM_CONTACT * pcontact = 0;
+ GIM_DYNARRAY_PUSH_EMPTY(GIM_CONTACT,(*dest_contacts));
+ pcontact = GIM_DYNARRAY_POINTER_LAST(GIM_CONTACT,(*dest_contacts));
+ //set the first contact
+ GIM_COPY_CONTACTS(pcontact, psource_contacts);
+
+ if(source_count==1) return;
+ //scale the first contact
+ VEC_SCALE(pcontact->m_normal,pcontact->m_depth,pcontact->m_normal);
+
+ psource_contacts++;
+
+ //Average the contacts
+ GUINT32 i;
+ for(i=1;i<source_count;i++)
+ {
+ VEC_SUM(pcontact->m_point,pcontact->m_point,psource_contacts->m_point);
+ VEC_ACCUM(pcontact->m_normal,psource_contacts->m_depth,psource_contacts->m_normal);
+ psource_contacts++;
+ }
+
+ GREAL divide_average = 1.0f/((GREAL)source_count);
+
+ VEC_SCALE(pcontact->m_point,divide_average,pcontact->m_point);
+
+ pcontact->m_depth = VEC_DOT(pcontact->m_normal,pcontact->m_normal)*divide_average;
+ GIM_SQRT(pcontact->m_depth,pcontact->m_depth);
+
+ VEC_NORMALIZE(pcontact->m_normal);
+
+ /*GREAL normal_len;
+ VEC_INV_LENGTH(pcontact->m_normal,normal_len);
+ VEC_SCALE(pcontact->m_normal,normal_len,pcontact->m_normal);
+
+ //Deep = LEN(normal)/SQRT(source_count)
+ GIM_SQRT(divide_average,divide_average);
+ pcontact->m_depth = divide_average/normal_len;
+ */
+}
+
+
+
diff --git a/libs/ode-0.16.1/GIMPACT/src/gim_math.cpp b/libs/ode-0.16.1/GIMPACT/src/gim_math.cpp new file mode 100644 index 0000000..18efb2c --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/src/gim_math.cpp @@ -0,0 +1,60 @@ +/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include "GIMPACT/gim_math.h"
+#include "stdlib.h"
+#include "time.h"
+
+
+GREAL gim_inv_sqrt(GREAL f)
+{
+ GREAL r;
+ GIM_INV_SQRT(f,r);
+ return r;
+}
+
+GREAL gim_sqrt(GREAL f)
+{
+ GREAL r;
+ GIM_SQRT(f,r);
+ return r;
+}
+
+//!Initializes mathematical functions
+void gim_init_math()
+{
+ srand( static_cast< unsigned int >( time( 0 ) ) );
+}
+
+//! Generates an unit random
+GREAL gim_unit_random()
+{
+ GREAL rn = static_cast< GREAL >( rand() );
+ rn/=(GREAL)RAND_MAX;
+ return rn;
+}
diff --git a/libs/ode-0.16.1/GIMPACT/src/gim_memory.cpp b/libs/ode-0.16.1/GIMPACT/src/gim_memory.cpp new file mode 100644 index 0000000..cc5188d --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/src/gim_memory.cpp @@ -0,0 +1,878 @@ +
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include <assert.h>
+#include <stdlib.h>
+#include "GIMPACT/gim_memory.h"
+#include <ode/odeconfig.h>
+#include "config.h"
+//#include "malloc.h"
+//#include "mm_malloc.h"
+
+static gim_alloc_function *g_allocfn = 0;
+// static gim_alloca_function *g_allocafn = 0; -- a nonsense
+static gim_realloc_function *g_reallocfn = 0;
+static gim_free_function *g_freefn = 0;
+
+
+#define VALIDATE_BUFFER_MANAGER(buffer_managers,buffer_manager_id)\
+ if(buffer_manager_id>=G_BUFFER_MANAGER__MAX) return G_BUFFER_OP_INVALID;\
+ GBUFFER_MANAGER_DATA * bm_data;\
+ gim_get_buffer_manager_data(buffer_managers,buffer_manager_id,&bm_data);\
+ if(bm_data == 0) return G_BUFFER_OP_INVALID;\
+
+#define VALIDATE_BUFFER_ID_PT(buffer_id)\
+ GBUFFER_MANAGER_DATA * bm_data = buffer_id->m_bm_data;\
+ if(bm_data == 0) return G_BUFFER_OP_INVALID;\
+ if(buffer_id->m_buffer_id>=bm_data->m_buffer_array.m_size) return G_BUFFER_OP_INVALID;\
+ GBUFFER_DATA * pbuffer = GIM_DYNARRAY_POINTER(GBUFFER_DATA,bm_data->m_buffer_array);\
+ pbuffer += buffer_id->m_buffer_id;\
+ if(pbuffer->m_buffer_handle==0) return G_BUFFER_OP_INVALID;\
+
+
+void GIM_BUFFER_ARRAY_DESTROY(GBUFFER_ARRAY & array_data)
+{
+ gim_buffer_array_unlock(&array_data);
+ gim_buffer_free(&(array_data).m_buffer_id);
+}
+
+void GIM_DYNARRAY_DESTROY(GDYNAMIC_ARRAY & array_data)
+{
+ if(array_data.m_pdata != 0)
+ {
+ gim_free(array_data.m_pdata,0);
+ array_data.m_reserve_size = 0;
+ array_data.m_size = 0;
+ array_data.m_pdata = 0;
+ }
+}
+
+void gim_set_alloc_handler (gim_alloc_function *fn)
+{
+ g_allocfn = fn;
+}
+
+/* -- a nonsense
+void gim_set_alloca_handler (gim_alloca_function *fn)
+{
+ g_allocafn = fn;
+}
+*/
+
+void gim_set_realloc_handler (gim_realloc_function *fn)
+{
+ g_reallocfn = fn;
+}
+
+void gim_set_free_handler (gim_free_function *fn)
+{
+ g_freefn = fn;
+}
+
+gim_alloc_function *gim_get_alloc_handler()
+{
+ return g_allocfn;
+}
+
+/* -- a nonsense
+gim_alloca_function *gim_get_alloca_handler()
+{
+ return g_allocafn;
+}
+*/
+
+gim_realloc_function *gim_get_realloc_handler ()
+{
+ return g_reallocfn;
+}
+
+
+gim_free_function *gim_get_free_handler ()
+{
+ return g_freefn;
+}
+
+
+void * gim_alloc(size_t size)
+{
+ void * ptr;
+/*
+ if (g_allocfn)
+ {
+ ptr = g_allocfn(size);
+ }
+ else
+*/
+ {
+ ptr = malloc(size);//_mm_malloc(size,0);*/
+ }
+ assert(ptr);
+ return ptr;
+}
+
+/* -- a nonsense
+void * gim_alloca(size_t size)
+{
+ if (g_allocafn) return g_allocafn(size); else return alloca(size);
+}
+*/
+
+void * gim_realloc(void *ptr, size_t oldsize, size_t newsize)
+{
+ /*if (g_reallocfn) return g_reallocfn(ptr,oldsize,newsize);
+ else return realloc(ptr,newsize);*/
+ //return realloc(ptr,newsize);
+ void * newptr = gim_alloc(newsize);
+ size_t copysize = newsize> oldsize? oldsize: newsize;
+ memcpy(newptr,ptr,copysize);
+ gim_free(ptr,oldsize);
+ return newptr;
+}
+
+void gim_free(void *ptr, size_t size)
+{
+ if (!ptr) return;
+/* -- if custom allocation function is not used, custom free must not be used too
+ if (g_freefn)
+ {
+ g_freefn(ptr,size);
+ }
+ else
+*/
+ {
+ free(ptr);//_mm_free(ptr);
+ }
+}
+
+///******************************* BUFFER MANAGERS ******************************///
+
+//!** Basic buffer prototype functions
+
+static GPTR _system_buffer_alloc_function(GUINT32 size,int usage)
+{
+ void * newdata = gim_alloc(size);
+ memset(newdata,0,size);
+ return (GPTR)newdata;
+}
+
+static GPTR _system_buffer_alloc_data_function(const void * pdata,GUINT32 size,int usage)
+{
+ void * newdata = gim_alloc(size);
+ memcpy(newdata,pdata,size);
+ return (GPTR)(newdata);
+}
+
+static GPTR _system_buffer_realloc_function(GPTR buffer_handle,GUINT32 oldsize,int old_usage,GUINT32 newsize,int new_usage)
+{
+ void * newdata = gim_realloc(buffer_handle,oldsize,newsize);
+ return (GPTR)(newdata);
+}
+
+static void _system_buffer_free_function(GPTR buffer_handle,GUINT32 size)
+{
+ gim_free(buffer_handle,size);
+}
+
+static char * _system_lock_buffer_function(GPTR buffer_handle,int access)
+{
+ return (char * )(buffer_handle);
+}
+
+
+static void _system_unlock_buffer_function(GPTR buffer_handle)
+{
+}
+
+static void _system_download_from_buffer_function(
+ GPTR source_buffer_handle,
+ GUINT32 source_pos,
+ void * destdata,
+ GUINT32 copysize)
+{
+ char * pdata;
+ pdata = (char *)source_buffer_handle;
+ memcpy(destdata,pdata+source_pos,copysize);
+}
+
+static void _system_upload_to_buffer_function(
+ GPTR dest_buffer_handle,
+ GUINT32 dest_pos,
+ void * sourcedata,
+ GUINT32 copysize)
+{
+ char * pdata;
+ pdata = (char * )dest_buffer_handle;
+ memcpy(pdata+dest_pos,sourcedata,copysize);
+}
+
+static void _system_copy_buffers_function(
+ GPTR source_buffer_handle,
+ GUINT32 source_pos,
+ GPTR dest_buffer_handle,
+ GUINT32 dest_pos,
+ GUINT32 copysize)
+{
+ char * pdata1,*pdata2;
+ pdata1 = (char *)source_buffer_handle;
+ pdata2 = (char *)dest_buffer_handle;
+ memcpy(pdata2+dest_pos,pdata1+source_pos,copysize);
+}
+
+static GPTR _shared_buffer_alloc_function(GUINT32 size,int usage)
+{
+ return 0;
+}
+
+static GPTR _shared_buffer_alloc_data_function(const void * pdata,GUINT32 size,int usage)
+{
+ return (GPTR)pdata;
+}
+
+#if 0
+static GPTR _shared_buffer_realloc_function(GPTR buffer_handle,GUINT32 oldsize,int old_usage,GUINT32 newsize,int new_usage)
+{
+ return 0;
+}
+#endif
+
+static void _shared_buffer_free_function(GPTR buffer_handle,GUINT32 size)
+{
+}
+
+static inline int _is_buffer_manager_data_active(GBUFFER_MANAGER_DATA * bm_data)
+{
+ return bm_data->m_buffer_array.m_pdata != 0;
+}
+
+static inline void _init_buffer_manager_data(GBUFFER_MANAGER_DATA * bm_data)
+{
+ bm_data->m_buffer_array.m_pdata = 0;
+}
+
+static const GBUFFER_MANAGER_PROTOTYPE g_bm_prototypes[G_BUFFER_MANAGER__MAX] =
+{
+ {
+ &_system_buffer_alloc_function, // alloc_fn;
+ &_system_buffer_alloc_data_function, // alloc_data_fn;
+ &_system_buffer_realloc_function, // realloc_fn;
+ &_system_buffer_free_function, // free_fn;
+ &_system_lock_buffer_function, // lock_buffer_fn;
+ &_system_unlock_buffer_function, // unlock_buffer_fn;
+ &_system_download_from_buffer_function, // download_from_buffer_fn;
+ &_system_upload_to_buffer_function, // upload_to_buffer_fn;
+ &_system_copy_buffers_function, // copy_buffers_fn;
+ }, // G_BUFFER_MANAGER_SYSTEM
+
+ {
+ &_shared_buffer_alloc_function, // alloc_fn;
+ &_shared_buffer_alloc_data_function, // alloc_data_fn;
+ &_system_buffer_realloc_function, // realloc_fn;
+ &_shared_buffer_free_function, // free_fn;
+ &_system_lock_buffer_function, // lock_buffer_fn;
+ &_system_unlock_buffer_function, // unlock_buffer_fn;
+ &_system_download_from_buffer_function, // download_from_buffer_fn;
+ &_system_upload_to_buffer_function, // upload_to_buffer_fn;
+ &_system_copy_buffers_function, // copy_buffers_fn;
+ }, // G_BUFFER_MANAGER_SHARED
+};
+
+int gim_is_buffer_manager_active(GBUFFER_MANAGER_DATA buffer_managers[],
+ GUINT32 buffer_manager_id)
+{
+ GBUFFER_MANAGER_DATA * bm_data;
+ bm_data = &buffer_managers[buffer_manager_id];
+ return _is_buffer_manager_data_active(bm_data);
+}
+
+//!** Buffer manager operations
+void gim_create_buffer_manager(GBUFFER_MANAGER_DATA buffer_managers[],
+ GUINT32 buffer_manager_id)
+{
+ GBUFFER_MANAGER_DATA * bm_data;
+ bm_data = &buffer_managers[buffer_manager_id];
+
+ if (_is_buffer_manager_data_active(bm_data))
+ {
+ gim_destroy_buffer_manager(buffer_managers, buffer_manager_id);
+ }
+
+ //CREATE ARRAYS
+ GIM_DYNARRAY_CREATE(GBUFFER_DATA,bm_data->m_buffer_array,G_ARRAY_BUFFERMANAGER_INIT_SIZE);
+ GIM_DYNARRAY_CREATE(GUINT32,bm_data->m_free_positions,G_ARRAY_BUFFERMANAGER_INIT_SIZE);
+ bm_data->m_prototype = g_bm_prototypes + buffer_manager_id;
+ bm_data->m_buffer_manager_id = buffer_manager_id;
+}
+
+void gim_destroy_buffer_manager(GBUFFER_MANAGER_DATA buffer_managers[], GUINT32 buffer_manager_id)
+{
+ GBUFFER_MANAGER_DATA * bm_data;
+ gim_get_buffer_manager_data(buffer_managers,buffer_manager_id,&bm_data);
+ if(bm_data == 0) return;
+ //Destroy all buffers
+
+ GBUFFER_DATA * buffers = GIM_DYNARRAY_POINTER(GBUFFER_DATA,bm_data->m_buffer_array);
+ GUINT32 i, buffer_count = bm_data->m_buffer_array.m_size;
+ for (i=0;i<buffer_count ;i++ )
+ {
+ GBUFFER_DATA * current_buffer = buffers + i;
+ if(current_buffer->m_buffer_handle!=0) //Is active
+ {
+ // free handle
+ bm_data->m_prototype->free_fn(current_buffer->m_buffer_handle,current_buffer->m_size);
+ }
+ }
+
+ //destroy buffer array
+ GIM_DYNARRAY_DESTROY(bm_data->m_buffer_array);
+ //destroy free positions
+ GIM_DYNARRAY_DESTROY(bm_data->m_free_positions);
+}
+void gim_get_buffer_manager_data(GBUFFER_MANAGER_DATA buffer_managers[],
+ GUINT32 buffer_manager_id,GBUFFER_MANAGER_DATA ** pbm_data)
+{
+ GBUFFER_MANAGER_DATA * bm_data;
+ bm_data = &buffer_managers[buffer_manager_id];
+
+ if (_is_buffer_manager_data_active(bm_data))
+ {
+ *pbm_data = bm_data;
+ }
+ else
+ {
+ *pbm_data = 0;
+ }
+}
+
+void gim_init_buffer_managers(GBUFFER_MANAGER_DATA buffer_managers[])
+{
+ GUINT32 i;
+ for (i=0;i<G_BUFFER_MANAGER__MAX;i++)
+ {
+ _init_buffer_manager_data(buffer_managers + i);
+ }
+
+ // Add the two most important buffer managers
+
+ //add system buffer manager
+ gim_create_buffer_manager(buffer_managers,G_BUFFER_MANAGER_SYSTEM );
+
+ //add shared buffer manager
+ gim_create_buffer_manager(buffer_managers,G_BUFFER_MANAGER_SHARED);
+}
+
+void gim_terminate_buffer_managers(GBUFFER_MANAGER_DATA buffer_managers[])
+{
+ GUINT32 i;
+ for (i=0;i<G_BUFFER_MANAGER__MAX;i++)
+ {
+ gim_destroy_buffer_manager(buffer_managers,i);
+ }
+}
+
+//!** Buffer operations
+
+void GET_AVALIABLE_BUFFER_ID(GBUFFER_MANAGER_DATA * buffer_manager, GUINT32 & buffer_id)
+{
+ if(buffer_manager->m_free_positions.m_size>0)\
+ {
+ GUINT32 * _pointer = GIM_DYNARRAY_POINTER(GUINT32,buffer_manager->m_free_positions);
+ buffer_id = _pointer[buffer_manager->m_free_positions.m_size-1];
+ GIM_DYNARRAY_POP_ITEM(buffer_manager->m_free_positions);
+ }
+ else
+ {
+ buffer_id = buffer_manager->m_buffer_array.m_size;
+ GIM_DYNARRAY_PUSH_EMPTY(GBUFFER_DATA,buffer_manager->m_buffer_array);
+ }
+}
+
+GINT32 _validate_buffer_id(GBUFFER_ID * buffer_id,GBUFFER_DATA ** ppbuffer,GBUFFER_MANAGER_DATA ** pbm_data)
+{
+ VALIDATE_BUFFER_ID_PT(buffer_id)
+ *ppbuffer = pbuffer;
+ *pbm_data = bm_data;
+ return G_BUFFER_OP_SUCCESS;
+}
+
+GUINT32 gim_create_buffer(
+ GBUFFER_MANAGER_DATA buffer_managers[],
+ GUINT32 buffer_manager_id,
+ GUINT32 buffer_size,
+ int usage,
+ GBUFFER_ID * buffer_id)
+{
+ VALIDATE_BUFFER_MANAGER(buffer_managers,buffer_manager_id)
+
+ GPTR newbufferhandle = bm_data->m_prototype->alloc_fn(buffer_size,usage);
+ if(newbufferhandle==0) return G_BUFFER_OP_INVALID;
+
+ GET_AVALIABLE_BUFFER_ID(bm_data,buffer_id->m_buffer_id);
+ buffer_id->m_bm_data = bm_data;
+
+ GBUFFER_DATA * pbuffer = GIM_DYNARRAY_POINTER(GBUFFER_DATA,bm_data->m_buffer_array);
+ pbuffer += buffer_id->m_buffer_id ;
+ pbuffer->m_buffer_handle = newbufferhandle;
+ pbuffer->m_size = buffer_size;
+ pbuffer->m_usage = usage;
+ pbuffer->m_lock_count = 0;
+ pbuffer->m_refcount = 0;
+ pbuffer->m_mapped_pointer = 0;
+
+ //set shadow buffer if needed
+
+ if(usage == G_MU_STATIC_READ ||
+ usage == G_MU_STATIC_READ_DYNAMIC_WRITE||
+ usage == G_MU_STATIC_READ_DYNAMIC_WRITE_COPY)
+ {
+ gim_create_common_buffer(buffer_managers,buffer_size,&pbuffer->m_shadow_buffer);
+ }
+ else
+ {
+ pbuffer->m_shadow_buffer.m_bm_data = 0;
+ pbuffer->m_shadow_buffer.m_buffer_id = G_UINT_INFINITY;
+ }
+ return G_BUFFER_OP_SUCCESS;
+}
+
+
+GUINT32 gim_create_buffer_from_data(
+ GBUFFER_MANAGER_DATA buffer_managers[],
+ GUINT32 buffer_manager_id,
+ const void * pdata,
+ GUINT32 buffer_size,
+ int usage,
+ GBUFFER_ID * buffer_id)
+{
+ VALIDATE_BUFFER_MANAGER(buffer_managers,buffer_manager_id)
+
+ GPTR newbufferhandle = bm_data->m_prototype->alloc_data_fn(pdata,buffer_size,usage);
+ if(newbufferhandle==0) return G_BUFFER_OP_INVALID;
+
+ GET_AVALIABLE_BUFFER_ID(bm_data,buffer_id->m_buffer_id);
+ buffer_id->m_bm_data = bm_data;
+
+ GBUFFER_DATA * pbuffer = GIM_DYNARRAY_POINTER(GBUFFER_DATA,bm_data->m_buffer_array);
+ pbuffer += buffer_id->m_buffer_id ;
+ pbuffer->m_buffer_handle = newbufferhandle;
+ pbuffer->m_size = buffer_size;
+ pbuffer->m_usage = usage;
+ pbuffer->m_lock_count = 0;
+ pbuffer->m_mapped_pointer = 0;
+ pbuffer->m_refcount = 0;
+
+ //set shadow buffer if needed
+
+ if(usage == G_MU_STATIC_READ ||
+ usage == G_MU_STATIC_READ_DYNAMIC_WRITE||
+ usage == G_MU_STATIC_READ_DYNAMIC_WRITE_COPY)
+ {
+ gim_create_common_buffer_from_data(buffer_managers,pdata,buffer_size,&pbuffer->m_shadow_buffer);
+ }
+ else
+ {
+ pbuffer->m_shadow_buffer.m_bm_data = 0;
+ pbuffer->m_shadow_buffer.m_buffer_id = G_UINT_INFINITY;
+ }
+ return G_BUFFER_OP_SUCCESS;
+}
+
+GUINT32 gim_create_common_buffer(GBUFFER_MANAGER_DATA buffer_managers[],
+ GUINT32 buffer_size, GBUFFER_ID * buffer_id)
+{
+ return gim_create_buffer(buffer_managers,G_BUFFER_MANAGER_SYSTEM,buffer_size,G_MU_DYNAMIC_READ_WRITE,buffer_id);
+}
+
+GUINT32 gim_create_common_buffer_from_data(GBUFFER_MANAGER_DATA buffer_managers[],
+ const void * pdata, GUINT32 buffer_size, GBUFFER_ID * buffer_id)
+{
+ return gim_create_buffer_from_data(buffer_managers,G_BUFFER_MANAGER_SYSTEM,pdata,buffer_size,G_MU_DYNAMIC_READ_WRITE,buffer_id);
+}
+
+GUINT32 gim_create_shared_buffer_from_data(GBUFFER_MANAGER_DATA buffer_managers[],
+ const void * pdata, GUINT32 buffer_size, GBUFFER_ID * buffer_id)
+{
+ return gim_create_buffer_from_data(buffer_managers,G_BUFFER_MANAGER_SHARED,pdata,buffer_size,G_MU_DYNAMIC_READ_WRITE,buffer_id);
+}
+
+GINT32 gim_buffer_realloc(GBUFFER_ID * buffer_id,GUINT32 newsize)
+{
+ VALIDATE_BUFFER_ID_PT(buffer_id)
+ if(pbuffer->m_lock_count>0) return G_BUFFER_OP_INVALID;
+ GPTR newhandle = buffer_id->m_bm_data->m_prototype->realloc_fn(
+ pbuffer->m_buffer_handle,pbuffer->m_size,pbuffer->m_usage,newsize,pbuffer->m_usage);
+ if(newhandle==0) return G_BUFFER_OP_INVALID;
+ pbuffer->m_buffer_handle = newhandle;
+ //realloc shadow buffer if any
+ gim_buffer_realloc(&pbuffer->m_shadow_buffer,newsize);
+ return G_BUFFER_OP_SUCCESS;
+}
+
+GINT32 gim_buffer_add_ref(GBUFFER_ID * buffer_id)
+{
+ VALIDATE_BUFFER_ID_PT(buffer_id)
+ pbuffer->m_refcount++;
+ return G_BUFFER_OP_SUCCESS;
+}
+
+GINT32 gim_buffer_free(GBUFFER_ID * buffer_id)
+{
+ VALIDATE_BUFFER_ID_PT(buffer_id)
+ if(pbuffer->m_lock_count>0) return G_BUFFER_OP_INVALID;
+ if(pbuffer->m_refcount>0) pbuffer->m_refcount--;
+ if(pbuffer->m_refcount>0) return G_BUFFER_OP_STILLREFCOUNTED;
+
+ buffer_id->m_bm_data->m_prototype->free_fn(
+ pbuffer->m_buffer_handle,pbuffer->m_size);
+ //destroy shadow buffer if needed
+ gim_buffer_free(&pbuffer->m_shadow_buffer);
+ // Obtain a free slot index for a new buffer
+ GIM_DYNARRAY_PUSH_ITEM(GUINT32,bm_data->m_free_positions,buffer_id->m_buffer_id);
+ pbuffer->m_buffer_handle = 0;
+ pbuffer->m_size = 0;
+ pbuffer->m_shadow_buffer.m_bm_data = 0;
+ pbuffer->m_shadow_buffer.m_buffer_id = G_UINT_INFINITY;
+ return G_BUFFER_OP_SUCCESS;
+}
+
+GINT32 gim_lock_buffer(GBUFFER_ID * buffer_id,int access,char ** map_pointer)
+{
+ VALIDATE_BUFFER_ID_PT(buffer_id)
+ if(pbuffer->m_lock_count>0)
+ {
+ if(pbuffer->m_access!=access) return G_BUFFER_OP_INVALID;
+ pbuffer->m_lock_count++;
+ *map_pointer = pbuffer->m_mapped_pointer;
+ return G_BUFFER_OP_SUCCESS;
+ }
+
+ pbuffer->m_access = access;
+
+ GUINT32 result;
+ if(pbuffer->m_usage==G_MU_STATIC_WRITE)
+ {
+ *map_pointer = 0;///no access
+ return G_BUFFER_OP_INVALID;
+ }
+ else if(pbuffer->m_usage==G_MU_STATIC_READ)
+ {
+ if(pbuffer->m_access == G_MA_READ_ONLY)
+ {
+ result = gim_lock_buffer(&pbuffer->m_shadow_buffer,access,map_pointer);
+ if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
+ pbuffer->m_mapped_pointer = *map_pointer;
+ pbuffer->m_lock_count++;
+ }
+ else
+ {
+ *map_pointer = 0;
+ return G_BUFFER_OP_INVALID;
+ }
+ }
+ else if(pbuffer->m_usage==G_MU_STATIC_READ_DYNAMIC_WRITE)
+ {
+ if(pbuffer->m_access == G_MA_READ_ONLY)
+ {
+ result = gim_lock_buffer(&pbuffer->m_shadow_buffer,access,map_pointer);
+ if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
+ pbuffer->m_mapped_pointer = *map_pointer;
+ pbuffer->m_lock_count++;
+ }
+ else if(pbuffer->m_access == G_MA_WRITE_ONLY)
+ {
+ pbuffer->m_mapped_pointer = buffer_id->m_bm_data->m_prototype->lock_buffer_fn(
+ pbuffer->m_buffer_handle,access);
+ *map_pointer = pbuffer->m_mapped_pointer;
+ pbuffer->m_lock_count++;
+ }
+ else if(pbuffer->m_access == G_MA_READ_WRITE)
+ {
+ *map_pointer = 0;
+ return G_BUFFER_OP_INVALID;
+ }
+ }
+ else if(pbuffer->m_usage==G_MU_STATIC_READ_DYNAMIC_WRITE_COPY)
+ {
+ result = gim_lock_buffer(&pbuffer->m_shadow_buffer,access,map_pointer);
+ if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
+ pbuffer->m_mapped_pointer = *map_pointer;
+ pbuffer->m_lock_count++;
+ }
+ else if(pbuffer->m_usage==G_MU_STATIC_WRITE_DYNAMIC_READ)
+ {
+ if(pbuffer->m_access == G_MA_READ_ONLY)
+ {
+ pbuffer->m_mapped_pointer = buffer_id->m_bm_data->m_prototype->lock_buffer_fn(
+ pbuffer->m_buffer_handle,access);
+ *map_pointer = pbuffer->m_mapped_pointer;
+ pbuffer->m_lock_count++;
+ }
+ else
+ {
+ *map_pointer = 0;
+ return G_BUFFER_OP_INVALID;
+ }
+ }
+ else if(pbuffer->m_usage==G_MU_DYNAMIC_READ_WRITE)
+ {
+ pbuffer->m_mapped_pointer = buffer_id->m_bm_data->m_prototype->lock_buffer_fn(
+ pbuffer->m_buffer_handle,access);
+ *map_pointer = pbuffer->m_mapped_pointer;
+ pbuffer->m_lock_count++;
+ }
+ return G_BUFFER_OP_SUCCESS;
+}
+
+GINT32 gim_unlock_buffer(GBUFFER_ID * buffer_id)
+{
+ VALIDATE_BUFFER_ID_PT(buffer_id)
+ if(pbuffer->m_lock_count==0) return G_BUFFER_OP_INVALID;
+
+ if(pbuffer->m_lock_count>1)
+ {
+ pbuffer->m_lock_count--;
+ return G_BUFFER_OP_SUCCESS;
+ }
+
+
+ GUINT32 result;
+ if(pbuffer->m_usage==G_MU_STATIC_WRITE)
+ {
+ pbuffer->m_mapped_pointer = 0;
+ pbuffer->m_lock_count=0;
+ return G_BUFFER_OP_INVALID;
+ }
+ else if(pbuffer->m_usage==G_MU_STATIC_READ)
+ {
+ if(pbuffer->m_access == G_MA_READ_ONLY)
+ {
+ result = gim_unlock_buffer(&pbuffer->m_shadow_buffer);
+ if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
+ pbuffer->m_mapped_pointer = 0;
+ pbuffer->m_lock_count=0;
+ }
+ else
+ {
+ pbuffer->m_mapped_pointer = 0;
+ pbuffer->m_lock_count=0;
+ return G_BUFFER_OP_INVALID;
+ }
+ }
+ else if(pbuffer->m_usage==G_MU_STATIC_READ_DYNAMIC_WRITE)
+ {
+ if(pbuffer->m_access == G_MA_READ_ONLY)
+ {
+ result = gim_unlock_buffer(&pbuffer->m_shadow_buffer);
+ if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
+ pbuffer->m_mapped_pointer = 0;
+ pbuffer->m_lock_count=0;
+ }
+ else if(pbuffer->m_access == G_MA_WRITE_ONLY)
+ {
+ buffer_id->m_bm_data->m_prototype->unlock_buffer_fn(
+ pbuffer->m_buffer_handle);
+ pbuffer->m_mapped_pointer = 0;
+ pbuffer->m_lock_count=0;
+ }
+ else if(pbuffer->m_access == G_MA_READ_WRITE)
+ {
+ pbuffer->m_mapped_pointer = 0;
+ pbuffer->m_lock_count=0;
+ return G_BUFFER_OP_INVALID;
+ }
+ }
+ else if(pbuffer->m_usage==G_MU_STATIC_READ_DYNAMIC_WRITE_COPY)
+ {
+ result = gim_unlock_buffer(&pbuffer->m_shadow_buffer);
+ if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
+ pbuffer->m_mapped_pointer = 0;
+ pbuffer->m_lock_count=0;
+ if(pbuffer->m_access == G_MA_WRITE_ONLY||pbuffer->m_access == G_MA_READ_WRITE)
+ {
+ gim_copy_buffers(&pbuffer->m_shadow_buffer,0,buffer_id,0,pbuffer->m_size);
+ }
+ }
+ else if(pbuffer->m_usage==G_MU_STATIC_WRITE_DYNAMIC_READ)
+ {
+ if(pbuffer->m_access == G_MA_READ_ONLY)
+ {
+ buffer_id->m_bm_data->m_prototype->unlock_buffer_fn(
+ pbuffer->m_buffer_handle);
+ pbuffer->m_mapped_pointer = 0;
+ pbuffer->m_lock_count=0;
+ }
+ else
+ {
+ pbuffer->m_mapped_pointer = 0;
+ pbuffer->m_lock_count=0;
+ return G_BUFFER_OP_INVALID;
+ }
+ }
+ else if(pbuffer->m_usage==G_MU_DYNAMIC_READ_WRITE)
+ {
+ buffer_id->m_bm_data->m_prototype->unlock_buffer_fn(
+ pbuffer->m_buffer_handle);
+ pbuffer->m_mapped_pointer = 0;
+ pbuffer->m_lock_count=0;
+ }
+ return G_BUFFER_OP_SUCCESS;
+}
+
+GINT32 gim_get_buffer_size(GBUFFER_ID * buffer_id,GUINT32 * buffer_size)
+{
+ VALIDATE_BUFFER_ID_PT(buffer_id)
+ *buffer_size = pbuffer->m_size;
+ return G_BUFFER_OP_SUCCESS;
+}
+
+GINT32 gim_get_buffer_is_locked(GBUFFER_ID * buffer_id,GUINT32 * lock_count)
+{
+ VALIDATE_BUFFER_ID_PT(buffer_id)
+ *lock_count = pbuffer->m_lock_count;
+ return G_BUFFER_OP_SUCCESS;
+}
+
+
+GINT32 gim_download_from_buffer(
+ GBUFFER_ID * buffer_id,
+ GUINT32 source_pos,
+ void * destdata,
+ GUINT32 copysize)
+{
+ VALIDATE_BUFFER_ID_PT(buffer_id)
+ buffer_id->m_bm_data->m_prototype->download_from_buffer_fn(
+ pbuffer->m_buffer_handle,source_pos,destdata,copysize);
+ return G_BUFFER_OP_SUCCESS;
+}
+
+GINT32 gim_upload_to_buffer(
+ GBUFFER_ID * buffer_id,
+ GUINT32 dest_pos,
+ void * sourcedata,
+ GUINT32 copysize)
+{
+ VALIDATE_BUFFER_ID_PT(buffer_id)
+ buffer_id->m_bm_data->m_prototype->upload_to_buffer_fn(
+ pbuffer->m_buffer_handle,dest_pos,sourcedata,copysize);
+ return G_BUFFER_OP_SUCCESS;
+}
+
+GINT32 gim_copy_buffers(
+ GBUFFER_ID * source_buffer_id,
+ GUINT32 source_pos,
+ GBUFFER_ID * dest_buffer_id,
+ GUINT32 dest_pos,
+ GUINT32 copysize)
+{
+ GBUFFER_MANAGER_DATA * bm_data1,* bm_data2;
+ GBUFFER_DATA * pbuffer1, * pbuffer2;
+ void * tempdata;
+ if(_validate_buffer_id(source_buffer_id,&pbuffer1,&bm_data1)!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
+
+ if(_validate_buffer_id(dest_buffer_id,&pbuffer2,&bm_data2)!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
+
+ if((bm_data1->m_buffer_manager_id == bm_data2->m_buffer_manager_id)||
+ (bm_data1->m_buffer_manager_id == G_BUFFER_MANAGER_SYSTEM && bm_data2->m_buffer_manager_id == G_BUFFER_MANAGER_SHARED)||
+ (bm_data1->m_buffer_manager_id == G_BUFFER_MANAGER_SHARED && bm_data2->m_buffer_manager_id == G_BUFFER_MANAGER_SYSTEM)
+ )
+ {//smooth copy
+ bm_data1->m_prototype->copy_buffers_fn(
+ pbuffer1->m_buffer_handle,source_pos,pbuffer2->m_buffer_handle,dest_pos,copysize);
+ }
+ else if(bm_data1->m_buffer_manager_id == G_BUFFER_MANAGER_SYSTEM ||
+ bm_data1->m_buffer_manager_id == G_BUFFER_MANAGER_SHARED)
+ {
+ //hard copy
+ tempdata = (void *)pbuffer1->m_buffer_handle;
+ //upload data
+ bm_data2->m_prototype->upload_to_buffer_fn(
+ pbuffer2->m_buffer_handle,dest_pos,tempdata,copysize);
+ }
+ else
+ {
+ //very hard copy
+ void * tempdata = gim_alloc(copysize);
+ //download data
+ bm_data1->m_prototype->download_from_buffer_fn(
+ pbuffer1->m_buffer_handle,source_pos,tempdata,copysize);
+
+ //upload data
+ bm_data2->m_prototype->upload_to_buffer_fn(
+ pbuffer2->m_buffer_handle,dest_pos,tempdata,copysize);
+ //delete temp buffer
+ gim_free(tempdata,copysize);
+ }
+ return G_BUFFER_OP_SUCCESS;
+}
+
+GINT32 gim_buffer_array_lock(GBUFFER_ARRAY * array_data, int access)
+{
+ if(array_data->m_buffer_data != 0) return G_BUFFER_OP_SUCCESS;
+ GINT32 result = gim_lock_buffer(&array_data->m_buffer_id,access,&array_data->m_buffer_data);
+ if(result!= G_BUFFER_OP_SUCCESS) return result;
+ array_data->m_buffer_data += array_data->m_byte_offset;
+ return result;
+}
+
+GINT32 gim_buffer_array_unlock(GBUFFER_ARRAY * array_data)
+{
+ if(array_data->m_buffer_data == 0) return G_BUFFER_OP_SUCCESS;
+ GINT32 result = gim_unlock_buffer(&array_data->m_buffer_id);
+ if(result!= G_BUFFER_OP_SUCCESS) return result;
+ array_data->m_buffer_data = 0;
+ return result;
+}
+
+void gim_buffer_array_copy_ref(GBUFFER_ARRAY * source_data,GBUFFER_ARRAY * dest_data)
+{
+ dest_data->m_buffer_id.m_buffer_id = source_data->m_buffer_id.m_buffer_id;
+ dest_data->m_buffer_id.m_bm_data = source_data->m_buffer_id.m_bm_data;
+ dest_data->m_buffer_data = 0;
+ dest_data->m_byte_stride = source_data->m_byte_stride;
+ dest_data->m_byte_offset = source_data->m_byte_offset;
+ dest_data->m_element_count = source_data->m_element_count;
+ gim_buffer_add_ref(&dest_data->m_buffer_id);
+}
+
+void gim_buffer_array_copy_value(GBUFFER_ARRAY * source_data,
+ GBUFFER_MANAGER_DATA dest_buffer_managers[],GBUFFER_ARRAY * dest_data,
+ GUINT32 buffer_manager_id,int usage)
+{
+ //Create new buffer
+ GUINT32 buffsize = source_data->m_element_count*source_data->m_byte_stride;
+ gim_create_buffer(dest_buffer_managers,buffer_manager_id,buffsize,usage,&dest_data->m_buffer_id);
+
+ //copy ref data
+ dest_data->m_buffer_data = 0;
+ dest_data->m_byte_stride = source_data->m_byte_stride;
+ dest_data->m_byte_offset = 0;
+ dest_data->m_element_count = source_data->m_element_count;
+ gim_buffer_add_ref(&dest_data->m_buffer_id);
+ //copy buffers
+ gim_copy_buffers(&source_data->m_buffer_id,source_data->m_byte_offset,&dest_data->m_buffer_id,0,buffsize);
+}
diff --git a/libs/ode-0.16.1/GIMPACT/src/gim_tri_tri_overlap.cpp b/libs/ode-0.16.1/GIMPACT/src/gim_tri_tri_overlap.cpp new file mode 100644 index 0000000..5b4e08d --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/src/gim_tri_tri_overlap.cpp @@ -0,0 +1,251 @@ +
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "GIMPACT/gim_trimesh.h"
+
+
+#define FABS(x) (float(fabs(x))) /* implement as is fastest on your machine */
+
+/* some macros */
+
+#define CLASSIFY_TRIPOINTS_BY_FACE(v1,v2,v3,faceplane,out_of_face)\
+{ \
+ _distances[0] = DISTANCE_PLANE_POINT(faceplane,v1);\
+ _distances[1] = _distances[0] * DISTANCE_PLANE_POINT(faceplane,v2);\
+ _distances[2] = _distances[0] * DISTANCE_PLANE_POINT(faceplane,v3); \
+ if(_distances[1]>0.0f && _distances[2]>0.0f)\
+ {\
+ out_of_face = 1;\
+ }\
+ else\
+ {\
+ out_of_face = 0;\
+ }\
+}\
+
+/* sort so that a<=b */
+#define SORT(a,b) \
+ if(a>b) \
+ { \
+ float c; \
+ c=a; \
+ a=b; \
+ b=c; \
+ }
+
+
+/* this edge to edge test is based on Franlin Antonio's gem:
+ "Faster Line Segment Intersection", in Graphics Gems III,
+ pp. 199-202 */
+#define EDGE_EDGE_TEST(V0,U0,U1) \
+ Bx=U0[i0]-U1[i0]; \
+ By=U0[i1]-U1[i1]; \
+ Cx=V0[i0]-U0[i0]; \
+ Cy=V0[i1]-U0[i1]; \
+ f=Ay*Bx-Ax*By; \
+ d=By*Cx-Bx*Cy; \
+ if((f>0 && d>=0 && d<=f) || (f<0 && d<=0 && d>=f)) \
+ { \
+ e=Ax*Cy-Ay*Cx; \
+ if(f>0) \
+ { \
+ if(e>=0 && e<=f) return 1; \
+ } \
+ else \
+ { \
+ if(e<=0 && e>=f) return 1; \
+ } \
+ }
+
+#define EDGE_AGAINST_TRI_EDGES(V0,V1,U0,U1,U2) \
+{ \
+ float Ax,Ay,Bx,By,Cx,Cy,e,d,f; \
+ Ax=V1[i0]-V0[i0]; \
+ Ay=V1[i1]-V0[i1]; \
+ /* test edge U0,U1 against V0,V1 */ \
+ EDGE_EDGE_TEST(V0,U0,U1); \
+ /* test edge U1,U2 against V0,V1 */ \
+ EDGE_EDGE_TEST(V0,U1,U2); \
+ /* test edge U2,U1 against V0,V1 */ \
+ EDGE_EDGE_TEST(V0,U2,U0); \
+}
+
+#define POINT_IN_TRI(V0,U0,U1,U2) \
+{ \
+ float a,b,c,d0,d1,d2; \
+ /* is T1 completly inside T2? */ \
+ /* check if V0 is inside tri(U0,U1,U2) */ \
+ a=U1[i1]-U0[i1]; \
+ b=-(U1[i0]-U0[i0]); \
+ c=-a*U0[i0]-b*U0[i1]; \
+ d0=a*V0[i0]+b*V0[i1]+c; \
+ \
+ a=U2[i1]-U1[i1]; \
+ b=-(U2[i0]-U1[i0]); \
+ c=-a*U1[i0]-b*U1[i1]; \
+ d1=a*V0[i0]+b*V0[i1]+c; \
+ \
+ a=U0[i1]-U2[i1]; \
+ b=-(U0[i0]-U2[i0]); \
+ c=-a*U2[i0]-b*U2[i1]; \
+ d2=a*V0[i0]+b*V0[i1]+c; \
+ if(d0*d1>0.0) \
+ { \
+ if(d0*d2>0.0) return 1; \
+ } \
+}
+
+int coplanar_tri_tri(GIM_TRIANGLE_DATA *tri1,
+ GIM_TRIANGLE_DATA *tri2)
+{
+ short i0,i1;
+ /* first project onto an axis-aligned plane, that maximizes the area */
+ /* of the triangles, compute indices: i0,i1. */
+ PLANE_MINOR_AXES(tri1->m_planes.m_planes[0], i0, i1);
+
+ /* test all edges of triangle 1 against the edges of triangle 2 */
+ EDGE_AGAINST_TRI_EDGES(tri1->m_vertices[0],tri1->m_vertices[1],tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2]);
+ EDGE_AGAINST_TRI_EDGES(tri1->m_vertices[1],tri1->m_vertices[2],tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2]);
+ EDGE_AGAINST_TRI_EDGES(tri1->m_vertices[2],tri1->m_vertices[0],tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2]);
+
+ /* finally, test if tri1 is totally contained in tri2 or vice versa */
+ POINT_IN_HULL(tri1->m_vertices[0],(&tri2->m_planes.m_planes[1]),3,i0);
+ if(i0==0) return 1;
+
+ POINT_IN_HULL(tri2->m_vertices[0],(&tri1->m_planes.m_planes[1]),3,i0);
+ if(i0==0) return 1;
+
+ return 0;
+}
+
+
+
+#define NEWCOMPUTE_INTERVALS(VV0,VV1,VV2,D0,D1,D2,D0D1,D0D2,A,B,C,X0,X1) \
+{ \
+ 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 */ \
+ A=VV2; B=(VV0-VV2)*D2; C=(VV1-VV2)*D2; X0=D2-D0; X1=D2-D1; \
+ } \
+ else if(D0D2>0.0f)\
+ { \
+ /* here we know that d0d1<=0.0 */ \
+ A=VV1; B=(VV0-VV1)*D1; C=(VV2-VV1)*D1; X0=D1-D0; X1=D1-D2; \
+ } \
+ else if(D1*D2>0.0f || D0!=0.0f) \
+ { \
+ /* here we know that d0d1<=0.0 or that D0!=0.0 */ \
+ A=VV0; B=(VV1-VV0)*D0; C=(VV2-VV0)*D0; X0=D0-D1; X1=D0-D2; \
+ } \
+ else if(D1!=0.0f) \
+ { \
+ A=VV1; B=(VV0-VV1)*D1; C=(VV2-VV1)*D1; X0=D1-D0; X1=D1-D2; \
+ } \
+ else if(D2!=0.0f) \
+ { \
+ A=VV2; B=(VV0-VV2)*D2; C=(VV1-VV2)*D2; X0=D2-D0; X1=D2-D1; \
+ } \
+ else \
+ { \
+ /* triangles are coplanar */ \
+ return coplanar_tri_tri(tri1,tri2); \
+ } \
+}\
+
+
+
+int gim_triangle_triangle_overlap(
+ GIM_TRIANGLE_DATA *tri1,
+ GIM_TRIANGLE_DATA *tri2)
+{
+ vec3f _distances;
+ char out_of_face;
+ CLASSIFY_TRIPOINTS_BY_FACE(tri1->m_vertices[0],tri1->m_vertices[1],tri1->m_vertices[2],tri2->m_planes.m_planes[0],out_of_face);
+ if(out_of_face==1) return 0;
+
+ CLASSIFY_TRIPOINTS_BY_FACE(tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2],tri1->m_planes.m_planes[0],out_of_face);
+ if(out_of_face==1) return 0;
+
+
+ float du0=0,du1=0,du2=0,dv0=0,dv1=0,dv2=0;
+ float D[3];
+ float isect1[2], isect2[2];
+ float du0du1=0,du0du2=0,dv0dv1=0,dv0dv2=0;
+ short index;
+ float vp0,vp1,vp2;
+ float up0,up1,up2;
+ float bb,cc,max;
+
+ /* compute direction of intersection line */
+ VEC_CROSS(D,tri1->m_planes.m_planes[0],tri2->m_planes.m_planes[0]);
+
+ /* compute and index to the largest component of D */
+ max=(float)FABS(D[0]);
+ index=0;
+ bb=(float)FABS(D[1]);
+ cc=(float)FABS(D[2]);
+ if(bb>max) max=bb,index=1;
+ if(cc>max) max=cc,index=2;
+
+ /* this is the simplified projection onto L*/
+ vp0= tri1->m_vertices[0][index];
+ vp1= tri1->m_vertices[1][index];
+ vp2= tri1->m_vertices[2][index];
+
+ up0= tri2->m_vertices[0][index];
+ up1= tri2->m_vertices[1][index];
+ up2= tri2->m_vertices[2][index];
+
+ /* compute interval for triangle 1 */
+ float a,b,c,x0,x1;
+ NEWCOMPUTE_INTERVALS(vp0,vp1,vp2,dv0,dv1,dv2,dv0dv1,dv0dv2,a,b,c,x0,x1);
+
+ /* compute interval for triangle 2 */
+ float d,e,f,y0,y1;
+ NEWCOMPUTE_INTERVALS(up0,up1,up2,du0,du1,du2,du0du1,du0du2,d,e,f,y0,y1);
+
+ float xx,yy,xxyy,tmp;
+ xx=x0*x1;
+ yy=y0*y1;
+ xxyy=xx*yy;
+
+ tmp=a*xxyy;
+ isect1[0]=tmp+b*x1*yy;
+ isect1[1]=tmp+c*x0*yy;
+
+ tmp=d*xxyy;
+ isect2[0]=tmp+e*xx*y1;
+ isect2[1]=tmp+f*xx*y0;
+
+ SORT(isect1[0],isect1[1]);
+ SORT(isect2[0],isect2[1]);
+
+ if(isect1[1]<isect2[0] || isect2[1]<isect1[0]) return 0;
+ return 1;
+}
diff --git a/libs/ode-0.16.1/GIMPACT/src/gim_trimesh.cpp b/libs/ode-0.16.1/GIMPACT/src/gim_trimesh.cpp new file mode 100644 index 0000000..7be639b --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/src/gim_trimesh.cpp @@ -0,0 +1,391 @@ +
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include <assert.h>
+#include "GIMPACT/gim_trimesh.h"
+
+GUINT32 gim_trimesh_get_triangle_count(GIM_TRIMESH * trimesh)
+{
+ return trimesh->m_tri_index_buffer.m_element_count/3;
+}
+
+//! Creates the aabb set and the triangles cache
+/*!
+
+\param trimesh
+\param vertex_array
+\param triindex_array
+\param transformed_reply If 1, then the m_transformed_vertices is a reply of the source vertices. Else it just be a reference to the original array.
+\post it copies the arrays by reference, and creates the auxiliary data (m_aabbset,m_planes_cache_buffer)
+*/
+void gim_trimesh_create_from_arrays(GBUFFER_MANAGER_DATA buffer_managers[],
+ GIM_TRIMESH * trimesh, GBUFFER_ARRAY * vertex_array, GBUFFER_ARRAY * triindex_array,char transformed_reply)
+{
+ assert(trimesh);
+ assert(vertex_array);
+ assert(triindex_array);
+ gim_buffer_array_copy_ref(vertex_array,&trimesh->m_source_vertex_buffer);
+ gim_buffer_array_copy_ref(triindex_array,&trimesh->m_tri_index_buffer);
+
+ trimesh->m_mask = GIM_TRIMESH_NEED_UPDATE;//needs update
+ //Create the transformed vertices
+ if(transformed_reply==1)
+ {
+ trimesh->m_mask |= GIM_TRIMESH_TRANSFORMED_REPLY;
+ gim_buffer_array_copy_value(vertex_array,
+ buffer_managers,&trimesh->m_transformed_vertex_buffer,G_BUFFER_MANAGER_SYSTEM,G_MU_DYNAMIC_READ_WRITE);
+ }
+ else
+ {
+ gim_buffer_array_copy_ref(vertex_array,&trimesh->m_transformed_vertex_buffer);
+ }
+ //create the box set
+ GUINT32 facecount = gim_trimesh_get_triangle_count(trimesh);
+
+ gim_aabbset_alloc(&trimesh->m_aabbset,facecount);
+ //create the planes cache
+ GIM_DYNARRAY_CREATE_SIZED(GIM_TRIPLANES_CACHE,trimesh->m_planes_cache_buffer,facecount);
+ //Create the bitset
+ GIM_BITSET_CREATE_SIZED(trimesh->m_planes_cache_bitset,facecount);
+ //Callback is 0
+ trimesh->m_update_callback = 0;
+ //set to identity
+ IDENTIFY_MATRIX_4X4(trimesh->m_transform);
+}
+
+
+
+//! Create a trimesh from vertex array and an index array
+/*!
+
+\param trimesh An uninitialized GIM_TRIMESH structure
+\param vertex_array A buffer to a vec3f array
+\param vertex_count
+\param triindex_array
+\param index_count
+\param copy_vertices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
+\param copy_indices If 1, it copies the source vertices in another buffer. Else (0) it constructs a reference to the data.
+\param transformed_reply If , then the m_transformed_vertices is a reply of the source vertices. Else it just be a reference to the original array.
+*/
+void gim_trimesh_create_from_data(GBUFFER_MANAGER_DATA buffer_managers[],
+ GIM_TRIMESH * trimesh, vec3f * vertex_array, GUINT32 vertex_count,char copy_vertices,
+ GUINT32 * triindex_array, GUINT32 index_count,char copy_indices,char transformed_reply)
+{
+ GBUFFER_ARRAY buffer_vertex_array;
+ GBUFFER_ARRAY buffer_triindex_array;
+
+ //Create vertices
+ if(copy_vertices == 1)
+ {
+ gim_create_common_buffer_from_data(buffer_managers,
+ vertex_array, vertex_count*sizeof(vec3f), &buffer_vertex_array.m_buffer_id);
+ }
+ else//Create a shared buffer
+ {
+ gim_create_shared_buffer_from_data(buffer_managers,
+ vertex_array, vertex_count*sizeof(vec3f), &buffer_vertex_array.m_buffer_id);
+ }
+ GIM_BUFFER_ARRAY_INIT_TYPE(vec3f,buffer_vertex_array,buffer_vertex_array.m_buffer_id,vertex_count);
+
+
+ //Create vertices
+ if(copy_indices == 1)
+ {
+ gim_create_common_buffer_from_data(buffer_managers,
+ triindex_array, index_count*sizeof(GUINT32), &buffer_triindex_array.m_buffer_id);
+ }
+ else//Create a shared buffer
+ {
+ gim_create_shared_buffer_from_data(buffer_managers,
+ triindex_array, index_count*sizeof(GUINT32), &buffer_triindex_array.m_buffer_id);
+ }
+ GIM_BUFFER_ARRAY_INIT_TYPE(GUINT32,buffer_triindex_array,buffer_triindex_array.m_buffer_id,index_count);
+
+ gim_trimesh_create_from_arrays(buffer_managers, trimesh,
+ &buffer_vertex_array, &buffer_triindex_array,transformed_reply);
+
+ ///always call this after create a buffer_array
+ GIM_BUFFER_ARRAY_DESTROY(buffer_vertex_array);
+ GIM_BUFFER_ARRAY_DESTROY(buffer_triindex_array);
+}
+
+//! Clears auxiliary data and releases buffer arrays
+void gim_trimesh_destroy(GIM_TRIMESH * trimesh)
+{
+ gim_aabbset_destroy(&trimesh->m_aabbset);
+
+ GIM_DYNARRAY_DESTROY(trimesh->m_planes_cache_buffer);
+ GIM_DYNARRAY_DESTROY(trimesh->m_planes_cache_bitset);
+
+ GIM_BUFFER_ARRAY_DESTROY(trimesh->m_transformed_vertex_buffer);
+ GIM_BUFFER_ARRAY_DESTROY(trimesh->m_source_vertex_buffer);
+ GIM_BUFFER_ARRAY_DESTROY(trimesh->m_tri_index_buffer);
+}
+
+//! Copies two meshes
+/*!
+\pre dest_trimesh shouldn't be created
+\post dest_trimesh will be created
+\param source_trimesh
+\param dest_trimesh
+\param copy_by_reference If 1, it attach a reference to the source vertices, else it copies the vertices
+\param transformed_reply IF 1, then it forces the m_trasnformed_vertices to be a reply of the source vertices
+*/
+void gim_trimesh_copy(GIM_TRIMESH * source_trimesh,
+ GBUFFER_MANAGER_DATA dest_buffer_managers[], GIM_TRIMESH * dest_trimesh,
+ char copy_by_reference, char transformed_reply)
+{
+/* -- trimesh can not be copied by reference until GBUFFER_MANAGER_DATA is rewritten
+ to be thread safe and until it is moved back to global variables.
+ if(copy_by_reference==1)
+ {
+ gim_trimesh_create_from_arrays(dest_trimesh, &source_trimesh->m_source_vertex_buffer, &source_trimesh->m_tri_index_buffer,transformed_reply);
+ }
+ else
+*/
+ {
+ GBUFFER_ARRAY buffer_vertex_array;
+ GBUFFER_ARRAY buffer_triindex_array;
+
+ gim_buffer_array_copy_value(&source_trimesh->m_source_vertex_buffer,
+ dest_buffer_managers,&buffer_vertex_array,G_BUFFER_MANAGER_SYSTEM,G_MU_DYNAMIC_READ_WRITE);
+
+ gim_buffer_array_copy_value(&source_trimesh->m_tri_index_buffer,
+ dest_buffer_managers,&buffer_triindex_array,G_BUFFER_MANAGER_SYSTEM,G_MU_DYNAMIC_READ_WRITE);
+
+ gim_trimesh_create_from_arrays(dest_buffer_managers, dest_trimesh,
+ &buffer_vertex_array, &buffer_triindex_array,transformed_reply);
+
+ ///always call this after create a buffer_array
+ GIM_BUFFER_ARRAY_DESTROY(buffer_vertex_array);
+ GIM_BUFFER_ARRAY_DESTROY(buffer_triindex_array);
+ }
+}
+//! Locks the trimesh for working with it
+/*!
+\post locks m_tri_index_buffer and m_transformed_vertex_buffer.
+\param trimesh
+*/
+void gim_trimesh_locks_work_data(GIM_TRIMESH * trimesh)
+{
+ GINT32 res;
+ res=gim_buffer_array_lock(&trimesh->m_tri_index_buffer,G_MA_READ_ONLY);
+ assert(res==G_BUFFER_OP_SUCCESS);
+ res=gim_buffer_array_lock(&trimesh->m_transformed_vertex_buffer,G_MA_READ_ONLY);
+ assert(res==G_BUFFER_OP_SUCCESS);
+}
+
+//! unlocks the trimesh
+/*!
+\post unlocks m_tri_index_buffer and m_transformed_vertex_buffer.
+\param trimesh
+*/
+void gim_trimesh_unlocks_work_data(GIM_TRIMESH * trimesh)
+{
+ gim_buffer_array_unlock(&trimesh->m_tri_index_buffer);
+ gim_buffer_array_unlock(&trimesh->m_transformed_vertex_buffer);
+}
+
+
+//! Returns 1 if the m_transformed_vertex_buffer is a reply of m_source_vertex_buffer
+char gim_trimesh_has_tranformed_reply(GIM_TRIMESH * trimesh)
+{
+ if(trimesh->m_mask&GIM_TRIMESH_TRANSFORMED_REPLY) return 1;
+ return 0;
+}
+
+//! Returns 1 if the trimesh needs to update their aabbset and the planes cache.
+char gim_trimesh_needs_update(GIM_TRIMESH * trimesh)
+{
+ if(trimesh->m_mask&GIM_TRIMESH_NEED_UPDATE) return 1;
+ return 0;
+}
+
+//! Change the state of the trimesh for force it to update
+/*!
+Call it after made changes to the trimesh.
+\post gim_trimesh_need_update(trimesh) will return 1
+*/
+void gim_trimesh_post_update(GIM_TRIMESH * trimesh)
+{
+ trimesh->m_mask |= GIM_TRIMESH_NEED_UPDATE;
+}
+
+//kernel
+#define MULT_MAT_VEC4_KERNEL(_mat,_src,_dst) MAT_DOT_VEC_3X4((_dst),(_mat),(_src))
+
+//! Updates m_transformed_vertex_buffer
+/*!
+\pre m_transformed_vertex_buffer must be unlocked
+*/
+void gim_trimesh_update_vertices(GIM_TRIMESH * trimesh)
+{
+ if(gim_trimesh_has_tranformed_reply(trimesh) == 0) return; //Don't perform transformation
+
+ //Vertices
+ GBUFFER_ARRAY * psource_vertex_buffer = &trimesh->m_source_vertex_buffer;
+ GBUFFER_ARRAY * ptransformed_vertex_buffer = &trimesh->m_transformed_vertex_buffer;
+ //Temp transform
+ mat4f transform;
+ COPY_MATRIX_4X4(transform,trimesh->m_transform);
+
+ GIM_PROCESS_BUFFER_ARRAY(transform,(*psource_vertex_buffer),(*ptransformed_vertex_buffer),MULT_MAT_VEC4_KERNEL,vec3f,vec3f);
+}
+
+//! Updates m_aabbset and m_planes_cache_bitset
+/*!
+\pre gim_trimesh_locks_work_data must be called before
+*/
+void gim_trimesh_update_aabbset(GIM_TRIMESH * trimesh)
+{
+ vec3f * transformed_vertices = GIM_BUFFER_ARRAY_POINTER(vec3f,trimesh->m_transformed_vertex_buffer,0);
+ assert(transformed_vertices);
+
+ GUINT32 * triangle_indices = GIM_BUFFER_ARRAY_POINTER(GUINT32,trimesh->m_tri_index_buffer,0);
+ assert(triangle_indices);
+ // box set
+ aabb3f * paabb = trimesh->m_aabbset.m_boxes;
+ GUINT32 triangle_count = gim_trimesh_get_triangle_count(trimesh);
+ float * v1,*v2,*v3;
+ GUINT32 i;
+ for (i=0; i<triangle_count;i++)
+ {
+ v1 = &transformed_vertices[triangle_indices[0]][0];
+ v2 = &transformed_vertices[triangle_indices[1]][0];
+ v3 = &transformed_vertices[triangle_indices[2]][0];
+ COMPUTEAABB_FOR_TRIANGLE((*paabb),v1,v2,v3);
+ triangle_indices+=3;
+ paabb++;
+ }
+ //Clear planes cache
+ GIM_BITSET_CLEAR_ALL(trimesh->m_planes_cache_bitset);
+ //Sorts set
+ gim_aabbset_update(&trimesh->m_aabbset);
+}
+
+//! Updates the trimesh if needed
+/*!
+\post If gim_trimesh_needs_update returns 1, then it calls gim_trimesh_update_vertices and gim_trimesh_update_aabbset
+*/
+void gim_trimesh_update(GIM_TRIMESH * trimesh)
+{
+ if(gim_trimesh_needs_update(trimesh)==0) return;
+ gim_trimesh_update_vertices(trimesh);
+ gim_trimesh_locks_work_data(trimesh);
+ gim_trimesh_update_aabbset(trimesh);
+ gim_trimesh_unlocks_work_data(trimesh);
+
+ //Clear update flag
+ trimesh->m_mask &= ~GIM_TRIMESH_NEED_UPDATE;
+}
+
+void gim_trimesh_set_tranform(GIM_TRIMESH * trimesh, mat4f transform)
+{
+ GREAL diff = 0.0f;
+ float * originaltrans = &trimesh->m_transform[0][0];
+ float * newtrans = &transform[0][0];
+ GUINT32 i;
+ for (i=0;i<16;i++)
+ {
+ diff += fabs(originaltrans[i]-newtrans[i]);
+ }
+
+// if(IS_ZERO(diff)) return ;///don't need to update
+ if(diff< 0.00001f) return ;///don't need to update
+
+ COPY_MATRIX_4X4(trimesh->m_transform,transform);
+
+ gim_trimesh_post_update(trimesh);
+}
+
+void gim_trimesh_get_triangle_data(GIM_TRIMESH * trimesh, GUINT32 triangle_index, GIM_TRIANGLE_DATA * tri_data)
+{
+ vec3f * transformed_vertices = GIM_BUFFER_ARRAY_POINTER(vec3f,trimesh->m_transformed_vertex_buffer,0);
+
+ GUINT32 * triangle_indices = GIM_BUFFER_ARRAY_POINTER(GUINT32,trimesh->m_tri_index_buffer,triangle_index*3);
+
+
+ //Copy the vertices
+ VEC_COPY(tri_data->m_vertices[0],transformed_vertices[triangle_indices[0]]);
+ VEC_COPY(tri_data->m_vertices[1],transformed_vertices[triangle_indices[1]]);
+ VEC_COPY(tri_data->m_vertices[2],transformed_vertices[triangle_indices[2]]);
+
+ //Get the planes
+ GIM_TRIPLANES_CACHE * planes = GIM_DYNARRAY_POINTER(GIM_TRIPLANES_CACHE,trimesh->m_planes_cache_buffer);
+ planes += triangle_index;
+
+ //verify planes cache
+ GUINT32 bit_eval;
+ GIM_BITSET_GET(trimesh->m_planes_cache_bitset,triangle_index,bit_eval);
+ if(bit_eval == 0)// Needs to calc the planes
+ {
+ //Calc the face plane
+ TRIANGLE_PLANE(tri_data->m_vertices[0],tri_data->m_vertices[1],tri_data->m_vertices[2],planes->m_planes[0]);
+ //Calc the edge 1
+ EDGE_PLANE(tri_data->m_vertices[0],tri_data->m_vertices[1],(planes->m_planes[0]),(planes->m_planes[1]));
+
+ //Calc the edge 2
+ EDGE_PLANE(tri_data->m_vertices[1],tri_data->m_vertices[2],(planes->m_planes[0]),(planes->m_planes[2]));
+
+ //Calc the edge 3
+ EDGE_PLANE(tri_data->m_vertices[2],tri_data->m_vertices[0],(planes->m_planes[0]), (planes->m_planes[3]));
+
+ //mark
+ GIM_BITSET_SET(trimesh->m_planes_cache_bitset,triangle_index);
+ }
+
+
+ VEC_COPY_4((tri_data->m_planes.m_planes[0]),(planes->m_planes[0]));//face plane
+ VEC_COPY_4((tri_data->m_planes.m_planes[1]),(planes->m_planes[1]));//edge1
+ VEC_COPY_4((tri_data->m_planes.m_planes[2]),(planes->m_planes[2]));//edge2
+ VEC_COPY_4((tri_data->m_planes.m_planes[3]),(planes->m_planes[3]));//edge3
+}
+
+void gim_trimesh_get_triangle_vertices(GIM_TRIMESH * trimesh, GUINT32 triangle_index, vec3f v1, vec3f v2, vec3f v3)
+{
+ vec3f * transformed_vertices = GIM_BUFFER_ARRAY_POINTER(vec3f,trimesh->m_transformed_vertex_buffer,0);
+
+ GUINT32 * triangle_indices = GIM_BUFFER_ARRAY_POINTER(GUINT32,trimesh->m_tri_index_buffer,triangle_index*3);
+
+ //Copy the vertices
+ if (v1 != NULL)
+ {
+ VEC_COPY(v1,transformed_vertices[triangle_indices[0]]);
+ }
+
+ if (v2 != NULL)
+ {
+ VEC_COPY(v2,transformed_vertices[triangle_indices[1]]);
+ }
+
+ if (v3 != NULL)
+ {
+ VEC_COPY(v3,transformed_vertices[triangle_indices[2]]);
+ }
+}
diff --git a/libs/ode-0.16.1/GIMPACT/src/gim_trimesh_capsule_collision.cpp b/libs/ode-0.16.1/GIMPACT/src/gim_trimesh_capsule_collision.cpp new file mode 100644 index 0000000..bc48aa5 --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/src/gim_trimesh_capsule_collision.cpp @@ -0,0 +1,285 @@ + +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + + This library 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 files + GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + +#include "GIMPACT/gim_trimesh.h" + +//! Utility function for find the closest point between a segment and a triangle +/*! + +\param triangle +\param s1 +\param s2 +\param contacts Contains the closest points on the segment (1,2), and the normal points to segment, and m_depth contains the distance + +\post The contacts array is not set to 0. It adds aditional contacts +*/ +void gim_closest_point_triangle_segment(GIM_TRIANGLE_DATA * triangle, vec3f s1,vec3f s2, GDYNAMIC_ARRAY * contacts) +{ + vec3f segment_points[4] = {{0}}; + vec3f closest_points[2] = {{0}}; + GUINT32 intersection_type, out_edge= 10; + GREAL dis, dis_temp,perpend; + vec4f sdiff; + + dis = DISTANCE_PLANE_POINT(triangle->m_planes.m_planes[0],s1); + dis_temp = DISTANCE_PLANE_POINT(triangle->m_planes.m_planes[0],s2); + + if(dis<=0.0f && dis_temp<=0.0f) return; + + VEC_DIFF(sdiff,s2,s1); + perpend = VEC_DOT(sdiff,triangle->m_planes.m_planes[0]); + + if(!IS_ZERO(perpend)) // Not perpendicular + { + if(dis<dis_temp) + { + VEC_COPY(closest_points[0],s1); + } + else + { + dis = dis_temp; + VEC_COPY(closest_points[0],s2); + } + + //Testing segment vertices over triangle + if(dis>=0.0f && dis_temp>=0.0f) + { + POINT_IN_HULL(closest_points[0],(&triangle->m_planes.m_planes[1]),3,out_edge); + + if(out_edge==0)//Point over face + { + GIM_PUSH_CONTACT((*contacts),closest_points[0] ,triangle->m_planes.m_planes[0] ,dis,0, 0, 0,0); + return; + } + } + else + { + + PLANE_CLIP_SEGMENT(s1,s2,triangle->m_planes.m_planes[0],closest_points[1]); + + POINT_IN_HULL(closest_points[1],(&triangle->m_planes.m_planes[1]),3,out_edge); + + if(out_edge==0)//Point over face + { + GIM_PUSH_CONTACT((*contacts),closest_points[0] ,triangle->m_planes.m_planes[0] ,dis,0, 0, 0,0); + return; + } + } + + } + else // Perpendicular Face + { + //out_edge=10 + //Clip segment by triangle + // Edge1 + PLANE_CLIP_SEGMENT_CLOSEST(s1,s2,triangle->m_planes.m_planes[1],segment_points[0],segment_points[1],intersection_type); + if(intersection_type==0||intersection_type==1) + { + out_edge = 0; + VEC_COPY(closest_points[0],segment_points[0]); + } + else + { + //Edge2 + PLANE_CLIP_SEGMENT_CLOSEST(segment_points[0],segment_points[1],triangle->m_planes.m_planes[2],segment_points[2],segment_points[3],intersection_type); + if(intersection_type==0||intersection_type==1) + { + out_edge = 1; + VEC_COPY(closest_points[0],segment_points[3]); + } + else + { + //Edge3 + PLANE_CLIP_SEGMENT_CLOSEST(segment_points[2],segment_points[3],triangle->m_planes.m_planes[3],closest_points[0],closest_points[1],intersection_type); + if(intersection_type==0||intersection_type==1) + { + out_edge = 2; + } + } + } + //POST closest_points[0] and closest_points[1] are inside the triangle, if out_edge>2 + if(out_edge>2) // Over triangle + { + dis = DISTANCE_PLANE_POINT(triangle->m_planes.m_planes[0],closest_points[0]); + GIM_PUSH_CONTACT((*contacts),closest_points[0] ,triangle->m_planes.m_planes[0] ,dis,0, 0, 0,0); + GIM_PUSH_CONTACT((*contacts),closest_points[1] ,triangle->m_planes.m_planes[0] ,dis,0, 0, 0,0); + return; + } + } + + //Find closest edges + out_edge = 10; + dis = G_REAL_INFINITY; + GUINT32 i; + for(i=0;i<3;i++) + { + SEGMENT_COLLISION(s1,s2,triangle->m_vertices[i],triangle->m_vertices[(i+1)%3],segment_points[0],segment_points[1]); + VEC_DIFF(sdiff,segment_points[0],segment_points[1]); + dis_temp = VEC_DOT(sdiff,sdiff); + if(dis_temp< dis) + { + dis = dis_temp; + out_edge = i; + VEC_COPY(closest_points[0],segment_points[0]); + VEC_COPY(closest_points[1],sdiff);//normal + } + } + if(out_edge>2) return ;// ???? ASSERT this please + + if(IS_ZERO(dis)) + { + //Set face plane + GIM_PUSH_CONTACT((*contacts),closest_points[0] ,triangle->m_planes.m_planes[0] ,0.0f,0, 0, 0,0); + + } + else + { + GIM_SQRT(dis,dis); + VEC_SCALE(closest_points[1],(1.0f/dis),closest_points[1]);//normal + GIM_PUSH_CONTACT((*contacts),closest_points[0] ,closest_points[1],dis,0, 0, 0,0); + } +} + + +//! Utility function for find the closest point between a capsule and a triangle +/*! + +\param triangle +\param capsule +\param contacts Contains the closest points on the capsule, and the normal points to triangle + +\post The contacts array is not set to 0. It adds aditional contacts +*/ +int gim_triangle_capsule_collision(GIM_TRIANGLE_DATA * triangle, GIM_CAPSULE_DATA * capsule, GDYNAMIC_ARRAY * contacts) +{ + GUINT32 old_contact_size = contacts->m_size; + gim_closest_point_triangle_segment(triangle,capsule->m_point1,capsule->m_point2,contacts); + + if (contacts->m_size == old_contact_size) + { + return 0; + } + + GIM_CONTACT * pcontact = GIM_DYNARRAY_POINTER(GIM_CONTACT ,(*contacts)); + pcontact+= old_contact_size; + + if(pcontact->m_depth > capsule->m_radius) + { + contacts->m_size = old_contact_size; + return 0; + } + + vec3f vec; + while(old_contact_size<contacts->m_size) + { + //Scale the normal for pointing to triangle + VEC_SCALE(pcontact->m_normal,-1.0f,pcontact->m_normal); + //Fix the contact point + VEC_SCALE(vec,capsule->m_radius,pcontact->m_normal); + VEC_SUM(pcontact->m_point,vec,pcontact->m_point); + //Fix the depth + pcontact->m_depth = capsule->m_radius - pcontact->m_depth; + + pcontact++; + old_contact_size++; + } + + return 1; +} + + +//! Trimesh Capsule collision +/*! +Find the closest primitive collided by the ray +\param trimesh +\param capsule +\param contact +\param contacts A GIM_CONTACT array. Must be initialized +*/ +void gim_trimesh_capsule_collision(GIM_TRIMESH * trimesh, GIM_CAPSULE_DATA * capsule, GDYNAMIC_ARRAY * contacts) +{ + contacts->m_size = 0; + + aabb3f test_aabb; + CALC_CAPSULE_AABB((*capsule),test_aabb); + + GDYNAMIC_ARRAY collision_result; + GIM_CREATE_BOXQUERY_LIST(collision_result); + + gim_aabbset_box_collision(&test_aabb, &trimesh->m_aabbset , &collision_result); + + if(collision_result.m_size==0) + { + GIM_DYNARRAY_DESTROY(collision_result); + } + + //collide triangles + //Locks trimesh + gim_trimesh_locks_work_data(trimesh); + //dummy contacts + GDYNAMIC_ARRAY dummycontacts; + GIM_CREATE_CONTACT_LIST(dummycontacts); + + int cresult; + unsigned int i; + GUINT32 * boxesresult = GIM_DYNARRAY_POINTER(GUINT32,collision_result); + GIM_TRIANGLE_DATA tri_data; + GUINT32 old_contact_size; + GIM_CONTACT * pcontact; + + for(i=0;i<collision_result.m_size;i++) + { + old_contact_size = dummycontacts.m_size; + gim_trimesh_get_triangle_data(trimesh,boxesresult[i],&tri_data); + cresult = gim_triangle_capsule_collision(&tri_data, capsule, &dummycontacts); + if(cresult!=0) + { + pcontact = GIM_DYNARRAY_POINTER(GIM_CONTACT ,dummycontacts); + pcontact+= old_contact_size; + while(old_contact_size<dummycontacts.m_size) + { + pcontact->m_handle1 = trimesh; + pcontact->m_handle2 = capsule; + pcontact->m_feature1 = boxesresult[i]; + pcontact->m_feature2 = 0; + pcontact++; + old_contact_size++; + } + } + } + ///unlocks + gim_trimesh_unlocks_work_data(trimesh); + ///Destroy box result + GIM_DYNARRAY_DESTROY(collision_result); + + //merge contacts + gim_merge_contacts(&dummycontacts,contacts); + + //Destroy dummy + GIM_DYNARRAY_DESTROY(dummycontacts); +} diff --git a/libs/ode-0.16.1/GIMPACT/src/gim_trimesh_ray_collision.cpp b/libs/ode-0.16.1/GIMPACT/src/gim_trimesh_ray_collision.cpp new file mode 100644 index 0000000..e83993e --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/src/gim_trimesh_ray_collision.cpp @@ -0,0 +1,149 @@ +
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "GIMPACT/gim_trimesh.h"
+
+
+//! Trimesh Ray Collisions
+/*!
+
+\param trimesh
+\param contact
+\return 1 if the ray collides, else 0
+*/
+int gim_trimesh_ray_collision(GIM_TRIMESH * trimesh,vec3f origin,vec3f dir, GREAL tmax, GIM_TRIANGLE_RAY_CONTACT_DATA * contact)
+{
+ GDYNAMIC_ARRAY collision_result;
+ GIM_CREATE_BOXQUERY_LIST(collision_result);
+
+ gim_aabbset_ray_collision(origin,dir,tmax,&trimesh->m_aabbset,&collision_result);
+
+ if(collision_result.m_size==0)
+ {
+ GIM_DYNARRAY_DESTROY(collision_result);
+ return 0;
+ }
+
+ //collide triangles
+
+ GUINT32 * boxesresult = GIM_DYNARRAY_POINTER(GUINT32,collision_result);
+ GIM_TRIANGLE_DATA tridata;
+ vec3f pout;
+ GREAL tparam,u,v;
+ char does_intersect;
+
+ gim_trimesh_locks_work_data(trimesh);
+
+ for(unsigned int i=0;i<collision_result.m_size;i++)
+ {
+ gim_trimesh_get_triangle_data(trimesh,boxesresult[i],&tridata);
+
+ // flip plane for correct result in ODE
+ // for more info: martijn@bytehazard.com
+ vec4f flippedPlane;
+ VEC_SCALE_4(flippedPlane, -1.0f, tridata.m_planes.m_planes[0]);
+
+ RAY_TRIANGLE_INTERSECTION(origin,dir,tridata.m_vertices[0],tridata.m_vertices[1],tridata.m_vertices[2],flippedPlane,pout,u,v,tparam,tmax,does_intersect);
+ if(does_intersect)
+ {
+ contact->tparam = tparam;
+ contact->u = u;
+ contact->v = v;
+ contact->m_face_id = boxesresult[i];
+ VEC_COPY(contact->m_point,pout);
+ VEC_COPY(contact->m_normal,flippedPlane);
+
+ gim_trimesh_unlocks_work_data(trimesh);
+ GIM_DYNARRAY_DESTROY(collision_result);
+ return 1;
+ }
+ }
+
+ gim_trimesh_unlocks_work_data(trimesh);
+ GIM_DYNARRAY_DESTROY(collision_result);
+ return 0;//no collisiion
+}
+
+
+//! Trimesh Ray Collisions closest
+/*!
+Find the closest primitive collided by the ray
+\param trimesh
+\param contact
+\return 1 if the ray collides, else 0
+*/
+int gim_trimesh_ray_closest_collision(GIM_TRIMESH * trimesh,vec3f origin,vec3f dir, GREAL tmax, GIM_TRIANGLE_RAY_CONTACT_DATA * contact)
+{
+ GDYNAMIC_ARRAY collision_result;
+ GIM_CREATE_BOXQUERY_LIST(collision_result);
+
+ gim_aabbset_ray_collision(origin,dir,tmax,&trimesh->m_aabbset,&collision_result);
+
+ if(collision_result.m_size==0)
+ {
+ GIM_DYNARRAY_DESTROY(collision_result);
+ return 0;
+ }
+
+ //collide triangles
+
+ GUINT32 * boxesresult = GIM_DYNARRAY_POINTER(GUINT32,collision_result);
+ GIM_TRIANGLE_DATA tridata;
+ vec3f pout;
+ GREAL tparam,u,v;
+ char does_intersect;
+ contact->tparam = tmax + 0.1f;
+
+ gim_trimesh_locks_work_data(trimesh);
+
+ for(unsigned int i=0;i<collision_result.m_size;i++)
+ {
+ gim_trimesh_get_triangle_data(trimesh,boxesresult[i],&tridata);
+
+ // flip plane for correct result in ODE
+ // for more info: martijn@bytehazard.com
+ vec4f flippedPlane;
+ VEC_SCALE_4(flippedPlane, -1.0f, tridata.m_planes.m_planes[0]);
+
+ RAY_TRIANGLE_INTERSECTION(origin,dir,tridata.m_vertices[0],tridata.m_vertices[1],tridata.m_vertices[2],flippedPlane,pout,u,v,tparam,tmax,does_intersect);
+ if(does_intersect && (tparam < contact->tparam))
+ {
+ contact->tparam = tparam;
+ contact->u = u;
+ contact->v = v;
+ contact->m_face_id = boxesresult[i];
+ VEC_COPY(contact->m_point,pout);
+ VEC_COPY(contact->m_normal,flippedPlane);
+ }
+ }
+
+ gim_trimesh_unlocks_work_data(trimesh);
+ GIM_DYNARRAY_DESTROY(collision_result);
+ if(contact->tparam > tmax) return 0;
+ return 1;
+}
diff --git a/libs/ode-0.16.1/GIMPACT/src/gim_trimesh_sphere_collision.cpp b/libs/ode-0.16.1/GIMPACT/src/gim_trimesh_sphere_collision.cpp new file mode 100644 index 0000000..0d61715 --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/src/gim_trimesh_sphere_collision.cpp @@ -0,0 +1,196 @@ +
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "GIMPACT/gim_trimesh.h"
+
+int gim_triangle_sphere_collision(
+ GIM_TRIANGLE_DATA *tri,
+ vec3f center, GREAL radius,
+ GIM_TRIANGLE_CONTACT_DATA * contact_data)
+{
+ contact_data->m_point_count = 0;
+
+ //Find Face plane distance
+ GREAL dis = DISTANCE_PLANE_POINT(tri->m_planes.m_planes[0],center);
+ if(dis>radius) return 0; //out
+ if(dis<-radius) return 0;//Out of triangle
+ contact_data->m_penetration_depth = dis;
+
+ //Find the most edge
+ GUINT32 most_edge = 4;//no edge
+ GREAL max_dis = 0.0f;
+ dis = DISTANCE_PLANE_POINT(tri->m_planes.m_planes[1],center);
+ if(dis>radius) return 0;//Out of triangle
+ if(dis>0.0f)
+ {
+ max_dis = dis;
+ most_edge = 0;
+ }
+
+ dis = DISTANCE_PLANE_POINT(tri->m_planes.m_planes[2],center);
+ if(dis>radius) return 0;//Out of triangle
+ if(dis>max_dis)// && dis>0.0f)
+ {
+ max_dis = dis;
+ most_edge = 1;
+ }
+
+ dis = DISTANCE_PLANE_POINT(tri->m_planes.m_planes[3],center);
+ if(dis>radius) return 0;//Out of triangle
+ if(dis>max_dis)// && dis>0.0f)
+ {
+ max_dis = dis;
+ most_edge = 2;
+ }
+
+ if(most_edge == 4) //Box is into triangle
+ {
+ //contact_data->m_penetration_depth = dis is set above
+ //Find Face plane point
+ VEC_COPY(contact_data->m_separating_normal,tri->m_planes.m_planes[0]);
+ //Find point projection on plane
+ if(contact_data->m_penetration_depth>=0.0f)
+ {
+ VEC_SCALE(contact_data->m_points[0],-radius,contact_data->m_separating_normal);
+ }
+ else
+ {
+ VEC_SCALE(contact_data->m_points[0],radius,contact_data->m_separating_normal);
+ }
+ contact_data->m_penetration_depth = radius - contact_data->m_penetration_depth;
+
+ VEC_SUM(contact_data->m_points[0],contact_data->m_points[0],center);
+ //Scale normal for pointing to triangle
+ VEC_SCALE(contact_data->m_separating_normal,-1.0f,contact_data->m_separating_normal);
+ contact_data->m_point_count = 1;
+ return 1;
+ }
+ //find the edge
+ vec3f e1,e2;
+ VEC_COPY(e1,tri->m_vertices[most_edge]);
+ VEC_COPY(e2,tri->m_vertices[(most_edge+1)%3]);
+
+ CLOSEST_POINT_ON_SEGMENT(contact_data->m_points[0],center,e1,e2);
+ //find distance
+ VEC_DIFF(e1,center,contact_data->m_points[0]);
+ VEC_LENGTH(e1,dis);
+ if(dis>radius) return 0;
+
+ contact_data->m_penetration_depth = radius - dis;
+
+ if(IS_ZERO(dis))
+ {
+ VEC_COPY(contact_data->m_separating_normal,tri->m_planes.m_planes[most_edge+1]);
+ VEC_SCALE(contact_data->m_points[0],-radius,contact_data->m_separating_normal);
+ VEC_SUM(contact_data->m_points[0],contact_data->m_points[0],center);
+ }
+ else
+ {
+ VEC_SCALE(contact_data->m_separating_normal,1.0f/dis,e1);
+ VEC_SCALE(contact_data->m_points[0],-radius,contact_data->m_separating_normal);
+ VEC_SUM(contact_data->m_points[0],contact_data->m_points[0],center);
+ }
+
+ //Scale normal for pointing to triangle
+ VEC_SCALE(contact_data->m_separating_normal,-1.0f,contact_data->m_separating_normal);
+
+ contact_data->m_point_count = 1;
+ return 1;
+
+}
+
+//! Trimesh Sphere Collisions
+/*!
+In each contact
+<ul>
+<li> m_handle1 points to trimesh.
+<li> m_handle2 points to NULL.
+<li> m_feature1 Is a triangle index of trimesh.
+</ul>
+
+\param trimesh
+\param center
+\param radius
+\param contacts A GIM_CONTACT array. Must be initialized
+*/
+void gim_trimesh_sphere_collision(GIM_TRIMESH * trimesh,vec3f center,GREAL radius, GDYNAMIC_ARRAY * contacts)
+{
+ contacts->m_size = 0;
+
+ aabb3f test_aabb;
+ test_aabb.minX = center[0]-radius;
+ test_aabb.maxX = center[0]+radius;
+ test_aabb.minY = center[1]-radius;
+ test_aabb.maxY = center[1]+radius;
+ test_aabb.minZ = center[2]-radius;
+ test_aabb.maxZ = center[2]+radius;
+
+ GDYNAMIC_ARRAY collision_result;
+ GIM_CREATE_BOXQUERY_LIST(collision_result);
+
+ gim_aabbset_box_collision(&test_aabb, &trimesh->m_aabbset , &collision_result);
+
+ if(collision_result.m_size==0)
+ {
+ GIM_DYNARRAY_DESTROY(collision_result);
+ }
+
+ //collide triangles
+ //Locks trimesh
+ gim_trimesh_locks_work_data(trimesh);
+ //dummy contacts
+ GDYNAMIC_ARRAY dummycontacts;
+ GIM_CREATE_CONTACT_LIST(dummycontacts);
+
+ int cresult;
+ unsigned int i;
+ GUINT32 * boxesresult = GIM_DYNARRAY_POINTER(GUINT32,collision_result);
+ GIM_TRIANGLE_CONTACT_DATA tri_contact_data;
+ GIM_TRIANGLE_DATA tri_data;
+
+ for(i=0;i<collision_result.m_size;i++)
+ {
+ gim_trimesh_get_triangle_data(trimesh,boxesresult[i],&tri_data);
+ cresult = gim_triangle_sphere_collision(&tri_data,center,radius,&tri_contact_data);
+ if(cresult!=0)
+ {
+ GIM_PUSH_CONTACT(dummycontacts, tri_contact_data.m_points[0],tri_contact_data.m_separating_normal ,tri_contact_data.m_penetration_depth,trimesh, 0, boxesresult[i],0);
+ }
+ }
+ ///unlocks
+ gim_trimesh_unlocks_work_data(trimesh);
+ ///Destroy box result
+ GIM_DYNARRAY_DESTROY(collision_result);
+
+ //merge contacts
+ gim_merge_contacts(&dummycontacts,contacts);
+
+ //Destroy dummy
+ GIM_DYNARRAY_DESTROY(dummycontacts);
+}
+
diff --git a/libs/ode-0.16.1/GIMPACT/src/gim_trimesh_trimesh_collision.cpp b/libs/ode-0.16.1/GIMPACT/src/gim_trimesh_trimesh_collision.cpp new file mode 100644 index 0000000..e5e3c06 --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/src/gim_trimesh_trimesh_collision.cpp @@ -0,0 +1,348 @@ +
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "GIMPACT/gim_trimesh.h"
+
+#define CLASSIFY_TRI_BY_FACE(v1,v2,v3,faceplane,out_of_face)\
+{ \
+ _distances[0] = DISTANCE_PLANE_POINT(faceplane,v1);\
+ _distances[1] = _distances[0] * DISTANCE_PLANE_POINT(faceplane,v2);\
+ _distances[2] = _distances[0] * DISTANCE_PLANE_POINT(faceplane,v3); \
+ if(_distances[1]>0.0f && _distances[2]>0.0f)\
+ {\
+ out_of_face = 1;\
+ }\
+ else\
+ {\
+ out_of_face = 0;\
+ }\
+}\
+
+
+//! Receives the 3 edge planes
+#define MOST_DEEP_POINTS(plane,points,point_count,deep_points,deep_points_count,maxdeep)\
+{\
+ maxdeep=-1000.0f;\
+ GUINT32 _k;\
+ GREAL _dist;\
+ deep_points_count = 0;\
+ for(_k=0;_k<point_count;_k++)\
+ {\
+ _dist = -DISTANCE_PLANE_POINT(plane,points[_k]);\
+ if(_dist>maxdeep)\
+ {\
+ maxdeep = _dist;\
+ _max_candidates[0] = _k;\
+ deep_points_count=1;\
+ }\
+ else if((_dist+G_EPSILON)>=maxdeep)\
+ {\
+ _max_candidates[deep_points_count] = _k;\
+ deep_points_count++;\
+ }\
+ }\
+ if(maxdeep<0.0f)\
+ {\
+ deep_points_count = 0;\
+ }\
+ else\
+ {\
+ for(_k=0;_k<deep_points_count;_k++)\
+ {\
+ VEC_COPY(deep_points[_k],points[_max_candidates[_k]]);\
+ }\
+ }\
+}\
+
+//! Receives the 3 edge planes
+#define CLIP_TRI_POINTS_BY_TRI_EDGE_PLANES(tri_points,tri_edge_planes, clipped_points, clipped_point_count)\
+{\
+ clipped_point_count = 0; \
+ _temp_clip_count = 0;\
+ PLANE_CLIP_POLYGON(tri_edge_planes[0],tri_points,3,_temp_clip,_temp_clip_count,MAX_TRI_CLIPPING);\
+ if(_temp_clip_count>0)\
+ {\
+ _temp_clip_count2 = 0;\
+ PLANE_CLIP_POLYGON(tri_edge_planes[1],_temp_clip,_temp_clip_count,_temp_clip2,_temp_clip_count2,MAX_TRI_CLIPPING);\
+ if(_temp_clip_count2>0)\
+ {\
+ PLANE_CLIP_POLYGON(tri_edge_planes[2],_temp_clip2,_temp_clip_count2,clipped_points,clipped_point_count,MAX_TRI_CLIPPING);\
+ }\
+ }\
+}\
+
+
+
+int _gim_triangle_triangle_collision(
+ GIM_TRIANGLE_DATA *tri1,
+ GIM_TRIANGLE_DATA *tri2,
+ GIM_TRIANGLE_CONTACT_DATA * contact_data)
+{
+ //Cache variables for triangle intersection
+ GUINT32 _max_candidates[MAX_TRI_CLIPPING];
+ vec3f _temp_clip[MAX_TRI_CLIPPING];
+ GUINT32 _temp_clip_count = 0;
+ vec3f _temp_clip2[MAX_TRI_CLIPPING];
+ GUINT32 _temp_clip_count2 = 0;
+ vec3f clipped_points2[MAX_TRI_CLIPPING];
+ vec3f deep_points2[MAX_TRI_CLIPPING];
+ vec3f clipped_points1[MAX_TRI_CLIPPING];
+ vec3f deep_points1[MAX_TRI_CLIPPING];
+
+
+
+ //State variabnles
+ GUINT32 mostdir=0;
+ GUINT32 clipped2_count=0;
+
+ //Clip tri2 by tri1 edges
+
+ CLIP_TRI_POINTS_BY_TRI_EDGE_PLANES(tri2->m_vertices,(&tri1->m_planes.m_planes[1]), clipped_points2, clipped2_count);
+
+ if(clipped2_count == 0 )
+ {
+ return 0;//Reject
+ }
+
+ //find most deep interval face1
+ GUINT32 deep2_count=0;
+
+ GREAL maxdeep;
+
+ MOST_DEEP_POINTS((tri1->m_planes.m_planes[0]), clipped_points2, clipped2_count, deep_points2, deep2_count, maxdeep);
+ if(deep2_count==0)
+ {
+// *perror = 0.0f;
+ return 0;//Reject
+ }
+
+ //Normal pointing to triangle1
+ VEC_SCALE(contact_data->m_separating_normal,-1.0f,(tri1->m_planes.m_planes[0]));
+
+
+ //Clip tri1 by tri2 edges
+
+ GUINT32 clipped1_count=0;
+
+ CLIP_TRI_POINTS_BY_TRI_EDGE_PLANES(tri1->m_vertices,(&tri2->m_planes.m_planes[1]), clipped_points1, clipped1_count);
+
+ if(clipped2_count == 0 )
+ {
+// *perror = 0.0f;
+ return 0;//Reject
+ }
+
+
+ //find interval face2
+ GUINT32 deep1_count=0;
+
+ GREAL dist;
+
+ MOST_DEEP_POINTS((tri2->m_planes.m_planes[0]), clipped_points1, clipped1_count, deep_points1, deep1_count, dist);
+
+ if(deep1_count==0)
+ {
+// *perror = 0.0f;
+ return 0;
+ }
+
+ if(dist<maxdeep)
+ {
+ maxdeep = dist;
+ mostdir = 1;
+ VEC_COPY(contact_data->m_separating_normal,(tri2->m_planes.m_planes[0]));
+ }
+ //set deep
+ contact_data->m_penetration_depth = maxdeep;
+
+ ////check most dir for contacts
+ if(mostdir==0)
+ {
+ contact_data->m_point_count = deep2_count;
+ for(mostdir=0;mostdir<deep2_count;mostdir++)
+ {
+ VEC_COPY(contact_data->m_points[mostdir] ,deep_points2[mostdir]);
+ }
+ }
+ else
+ {
+ contact_data->m_point_count = deep1_count;
+ for(mostdir=0;mostdir<deep1_count;mostdir++)
+ {
+ VEC_COPY(contact_data->m_points[mostdir] ,deep_points1[mostdir]);
+ }
+ }
+ return 1;
+}
+
+
+
+//! Finds the contact points from a collision of two triangles
+/*!
+Returns the contact points, the penetration depth and the separating normal of the collision
+between two triangles. The normal is pointing toward triangle 1 from triangle 2
+*/
+int gim_triangle_triangle_collision(
+ GIM_TRIANGLE_DATA *tri1,
+ GIM_TRIANGLE_DATA *tri2,
+ GIM_TRIANGLE_CONTACT_DATA * contact_data)
+{
+ vec3f _distances;
+ char out_of_face=0;
+
+ CLASSIFY_TRI_BY_FACE(tri1->m_vertices[0],tri1->m_vertices[1],tri1->m_vertices[2],tri2->m_planes.m_planes[0],out_of_face);
+ if(out_of_face==1) return 0;
+
+ CLASSIFY_TRI_BY_FACE(tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2],tri1->m_planes.m_planes[0],out_of_face);
+ if(out_of_face==1) return 0;
+
+ return _gim_triangle_triangle_collision(tri1,tri2,contact_data);
+}
+
+//! Trimesh Trimesh Collisions
+/*!
+
+In each contact
+<ul>
+<li> m_handle1 points to trimesh1.
+<li> m_handle2 points to trimesh2.
+<li> m_feature1 Is a triangle index of trimesh1.
+<li> m_feature2 Is a triangle index of trimesh2.
+</ul>
+
+\param trimesh1 Collider
+\param trimesh2 Collidee
+\param contacts A GIM_CONTACT array. Must be initialized
+*/
+void gim_trimesh_trimesh_collision(GIM_TRIMESH * trimesh1, GIM_TRIMESH * trimesh2, GDYNAMIC_ARRAY * contacts)
+{
+ contacts->m_size = 0;
+ GDYNAMIC_ARRAY collision_pairs;
+ GIM_CREATE_PAIR_SET(collision_pairs)
+
+ gim_aabbset_bipartite_intersections(&trimesh1->m_aabbset,&trimesh2->m_aabbset,&collision_pairs);
+
+ if(collision_pairs.m_size==0)
+ {
+ GIM_DYNARRAY_DESTROY(collision_pairs);
+ return; //no collisioin
+ }
+
+ //Locks meshes
+ gim_trimesh_locks_work_data(trimesh1);
+ gim_trimesh_locks_work_data(trimesh2);
+
+
+ //pair pointer
+ GIM_PAIR *pairs = GIM_DYNARRAY_POINTER(GIM_PAIR,collision_pairs);
+ //dummy contacts
+ GDYNAMIC_ARRAY dummycontacts;
+ GIM_CREATE_CONTACT_LIST(dummycontacts);
+
+ //Auxiliary triangle data
+ GIM_TRIANGLE_CONTACT_DATA tri_contact_data;
+ GIM_TRIANGLE_DATA tri1data,tri2data;
+
+
+ GUINT32 i, ti1,ti2,ci;
+ int colresult;
+ for (i=0;i<collision_pairs.m_size; i++)
+ {
+ ti1 = pairs[i].m_index1;
+ ti2 = pairs[i].m_index2;
+ //Get triangles data
+ gim_trimesh_get_triangle_data(trimesh1,ti1,&tri1data);
+ gim_trimesh_get_triangle_data(trimesh2,ti2,&tri2data);
+
+ //collide triangles
+ colresult = gim_triangle_triangle_collision(&tri1data,&tri2data,&tri_contact_data);
+ if(colresult == 1)
+ {
+ //Add contacts
+ for (ci=0;ci<tri_contact_data.m_point_count ;ci++ )
+ {
+ GIM_PUSH_CONTACT(dummycontacts, tri_contact_data.m_points[ci],tri_contact_data.m_separating_normal ,tri_contact_data.m_penetration_depth,trimesh1, trimesh2, ti1, ti2);
+ }
+ }
+ }
+
+ if(dummycontacts.m_size == 0) //reject
+ {
+ GIM_DYNARRAY_DESTROY(dummycontacts);
+ GIM_DYNARRAY_DESTROY(collision_pairs);
+ return;
+ }
+ //merge contacts
+ gim_merge_contacts(&dummycontacts,contacts);
+
+ //Terminate
+ GIM_DYNARRAY_DESTROY(dummycontacts);
+ GIM_DYNARRAY_DESTROY(collision_pairs);
+
+ //Unlocks meshes
+ gim_trimesh_unlocks_work_data(trimesh1);
+ gim_trimesh_unlocks_work_data(trimesh2);
+}
+
+
+//! Trimesh Plane Collisions
+/*!
+
+\param trimesh
+\param plane vec4f plane
+\param contacts A vec4f array. Must be initialized (~100). Each element have the coordinate point in the first 3 elements, and vec4f[3] has the penetration depth.
+*/
+void gim_trimesh_plane_collision(GIM_TRIMESH * trimesh,vec4f plane, GDYNAMIC_ARRAY * contacts)
+{
+ contacts->m_size = 0;
+ char classify;
+ PLANE_CLASSIFY_BOX(plane,trimesh->m_aabbset.m_global_bound,classify);
+ if(classify>1) return; // in front of plane
+
+ //Locks mesh
+ gim_trimesh_locks_work_data(trimesh);
+ //Get vertices
+ GUINT32 i, vertcount = trimesh->m_transformed_vertex_buffer.m_element_count;
+ vec3f * vertices = GIM_BUFFER_ARRAY_POINTER(vec3f,trimesh->m_transformed_vertex_buffer,0);
+
+ GREAL dist;
+ vec4f * result_contact;
+
+ for (i=0;i<vertcount;i++)
+ {
+ dist = DISTANCE_PLANE_POINT(plane,vertices[i]);
+ if(dist<=0.0f)
+ {
+ GIM_DYNARRAY_PUSH_EMPTY(vec4f,(*contacts));
+ result_contact = GIM_DYNARRAY_POINTER_LAST(vec4f,(*contacts));
+ VEC_COPY((*result_contact),vertices[i]);
+ (*result_contact)[3] = -dist;
+ }
+ }
+ gim_trimesh_unlocks_work_data(trimesh);
+}
diff --git a/libs/ode-0.16.1/GIMPACT/src/gimpact.cpp b/libs/ode-0.16.1/GIMPACT/src/gimpact.cpp new file mode 100644 index 0000000..b7fdf42 --- /dev/null +++ b/libs/ode-0.16.1/GIMPACT/src/gimpact.cpp @@ -0,0 +1,40 @@ +
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 2.1 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file GIMPACT-LICENSE-LGPL.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file GIMPACT-LICENSE-BSD.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "GIMPACT/gimpact.h"
+
+
+
+void gimpact_init()
+{
+ gim_init_math();
+}
+
+void gimpact_terminate()
+{
+}
diff --git a/libs/ode-0.16.1/INSTALL.txt b/libs/ode-0.16.1/INSTALL.txt new file mode 100644 index 0000000..567e061 --- /dev/null +++ b/libs/ode-0.16.1/INSTALL.txt @@ -0,0 +1,173 @@ +ODE has two new build systems, one for *nix systems and another for +just about everything else. + +1. Building with Visual Studio +2. Building with Autotools (Linux, OS X, MSYS, etc.) +3. Building with Code::Blocks +4. Building with Something Else +5. Building with CMake + + + + +1. BUILDING WITH VISUAL STUDIO (2002 and up) +============================================ + + If you downloaded this source code from Subversion you must first use + the Premake build system to generate project files. + + Open a command prompt and enter into the build directory. Then run the + premake4.exe program with the appropriate options to generate the + project files. For example, to generate a project for VS2008: + + > premake4.exe --with-tests --with-demos vs2008 + + To see a complete list of options use: + + > premake4.exe --help + + Note that Visual Studio 6 is not supported and users are advised to upgrade + to at least Visual Studio 2005 Express (it's free!) + + Using CMake is another option for generating project files for Visual Studio. + See section 5 below for more details on this. + + + + +2. BUILDING WITH AUTOTOOLS (Linux, OS X, MSYS, etc.) +==================================================== + +2.1 FROM SUBVERSION REPOSITORY +------------------------------ + + If you downloaded the source code from Subversion you must bootstrap the + process by running the command: + + $ ./bootstrap + + For this command to work you need a set of tools typically available + on BSD and Linux distributions with development packages installed. OS X + users may need to manually install libtool, autoconf, automake, + pkg-config, and maybe some more. + + If you downloaded a source code package from SourceForge this has + already been done for you. You may see some "underquoted definition" + warnings depending on your platform, these are (for now) harmless + warnings regarding scripts from other m4 installed packages. + +2.2 FROM A RELEASED TARBALL +--------------------------- + + First extract the archive (e.g. tar xvfz <filename.tar.gz>) and enter + the created directory (ode-x.y). + + Run the configure script to autodetect your build environment: + + $ ./configure + + By default this will build ODE as a static library with single-precision + math, trimesh support with OPCODE, and debug symbols enabled. You can + modify these defaults by passing additional parameters to + configure. For a full list of available options, type: + + $ ./configure --help + + Some of the more popular options are + + --enable-double-precision enable double-precision math + --with-trimesh=none disables the trimesh support + --with-trimesh=opcode use OPCODE for trimesh code + --with-trimesh=gimpact use GIMPACT for trimesh code + + --enabled-shared builds a shared library + + To pass specific flags for an optimized build, you must do so + in the CFLAGS and CXXFLAGS enviroment variables, or as arguments + to ./configure. For example if you are building for an athlon xp processor + and you want the compiler to use SSE instructions you can run configure as + follows: + + $ ./configure CFLAGS="-msse -march=atlon-xp" CXXFLAGS="-msse -march=atlon-xp" + + Note that you must set both CFLAGS and CXXFLAGS as ODE contains a mixture of + C and C++ files. + + Once configure has run successfully, build and install ODE: + + $ make + $ make install + + The latter command will also create a pkg-config script that provides + compilation and linking flags for programs. The old stand-alone + "ode-config" script is also installed for compatibility. + + + + +3. BUILDING WITH Code::Blocks +============================= + + Because Code::Blocks supports so many different platforms, we do not + provide workspaces. Instead, use Premake to create a workspace tailored + for your platform and project. Like so: + + $ cd build + $ premake4 --with-tests --with-demos codeblocks + + To see a complete list of options: + + $ cd build + $ premake4 --help + + Using CMake is another option for generating project files for Code::Blocks. + See section 5 below for more details on this. + + + + +4. BUILDING WITH SOMETHING ELSE +=============================== + + ODE uses the Premake tool to provide support for several different toolsets. + Premake adds support for new toolsets on a regular basis, so yours might be + supported. Check the Premake website at http://premake.sourceforge.net/, + and then follow the directions for Code::Blocks above, substituting your + toolset target in place of `codeblocks`. + + Using CMake is another option for generating project files for other + toolsets. See section 5 below for more details on this. + + + + +5. BUILDING WITH CMAKE +====================== + + ODE includes support for CMake to generate project files for various platforms + and IDEs including Unix Makefiles, Ninja, Code::Blocks, Visual Studio. A full + overview of all supported generators can be found at the latest version of the + manual at https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html + + CMake supports and encourages out-of-source builds. In order to generate build + files for your platform, create a build directory at your preferred location + and then call CMake with the path to ODE's source directory as argument, e.g., + one level above the source directory: + + $ cd .. + $ mkdir ode-build + $ cmake ../ode-src + + The existing build directory in the source directory can also be used as a + location for the project files. A different generator than the default one + for the system can be specified as well: + + $ cd build + $ cmake -G"Visual Studio 15 2017 Win64" .. + + QtCreator, CLion, and Visual Studio 2017 also offer the option to open the + source directory with the CMakeLists.txt file directly in the IDE. + + + + diff --git a/libs/ode-0.16.1/LICENSE-BSD.TXT b/libs/ode-0.16.1/LICENSE-BSD.TXT new file mode 100644 index 0000000..112f6a2 --- /dev/null +++ b/libs/ode-0.16.1/LICENSE-BSD.TXT @@ -0,0 +1,34 @@ + +This is the BSD-style license for the Open Dynamics Engine +---------------------------------------------------------- + +Open Dynamics Engine +Copyright (c) 2001-2007, Russell L. Smith. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +Neither the names of ODE's copyright owner nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +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 +OWNER 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. diff --git a/libs/ode-0.16.1/LICENSE.TXT b/libs/ode-0.16.1/LICENSE.TXT new file mode 100644 index 0000000..cfe59bc --- /dev/null +++ b/libs/ode-0.16.1/LICENSE.TXT @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/libs/ode-0.16.1/Makefile.am b/libs/ode-0.16.1/Makefile.am new file mode 100644 index 0000000..c786f5c --- /dev/null +++ b/libs/ode-0.16.1/Makefile.am @@ -0,0 +1,48 @@ +AUTOMAKE_OPTIONS = foreign +ACLOCAL_AMFLAGS = -I m4 --install + +if ENABLE_OU +OU_DIR = ou +endif + +if LIBCCD +if LIBCCD_INTERNAL +LIBCCD_DIR = libccd +endif +endif + +if ENABLE_DEMOS +DRAWSTUFF_DIR = drawstuff +endif + +if GIMPACT +GIMPACT_DIR = GIMPACT +endif + +if OPCODE +OPCODE_DIR = OPCODE +endif + +SUBDIRS = include \ + $(DRAWSTUFF_DIR) \ + $(GIMPACT_DIR) \ + $(OPCODE_DIR) \ + $(OU_DIR) \ + $(LIBCCD_DIR) \ + ode \ + tests + +bin_SCRIPTS = ode-config + +# Utility rule for making a release +release: dist-gzip dist-bzip2 + @echo Created release packages for ${PACKAGE}-${VERSION}. + +EXTRA_DIST = bootstrap build tools \ + CHANGELOG.txt COPYING INSTALL.txt CSR.txt README.md \ + LICENSE.TXT LICENSE-BSD.TXT \ + bindings \ + CMakeLists.txt ode-config.cmake.in config.h.cmake.in cmake + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = ode.pc diff --git a/libs/ode-0.16.1/Makefile.in b/libs/ode-0.16.1/Makefile.in new file mode 100644 index 0000000..2b8787e --- /dev/null +++ b/libs/ode-0.16.1/Makefile.in @@ -0,0 +1,941 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(am__DIST_COMMON) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ode/src/config.h +CONFIG_CLEAN_FILES = ode-config ode.pc +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgconfigdir)" +SCRIPTS = $(bin_SCRIPTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +DATA = $(pkgconfig_DATA) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + cscope distdir dist dist-all distcheck +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +CSCOPE = cscope +DIST_SUBDIRS = include drawstuff GIMPACT OPCODE ou libccd ode tests +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/ode-config.in \ + $(srcdir)/ode.pc.in COPYING compile config.guess config.sub \ + depcomp install-sh ltmain.sh missing +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +DIST_TARGETS = dist-gzip +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_CFLAGS = @CCD_CFLAGS@ +CCD_LIBS = @CCD_LIBS@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSTDCXX = @LIBSTDCXX@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ODE_PRECISION = @ODE_PRECISION@ +ODE_VERSION = @ODE_VERSION@ +ODE_VERSION_INFO = @ODE_VERSION_INFO@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = foreign +ACLOCAL_AMFLAGS = -I m4 --install +@ENABLE_OU_TRUE@OU_DIR = ou +@LIBCCD_INTERNAL_TRUE@@LIBCCD_TRUE@LIBCCD_DIR = libccd +@ENABLE_DEMOS_TRUE@DRAWSTUFF_DIR = drawstuff +@GIMPACT_TRUE@GIMPACT_DIR = GIMPACT +@OPCODE_TRUE@OPCODE_DIR = OPCODE +SUBDIRS = include \ + $(DRAWSTUFF_DIR) \ + $(GIMPACT_DIR) \ + $(OPCODE_DIR) \ + $(OU_DIR) \ + $(LIBCCD_DIR) \ + ode \ + tests + +bin_SCRIPTS = ode-config +EXTRA_DIST = bootstrap build tools \ + CHANGELOG.txt COPYING INSTALL.txt CSR.txt README.md \ + LICENSE.TXT LICENSE-BSD.TXT \ + bindings \ + CMakeLists.txt ode-config.cmake.in config.h.cmake.in cmake + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = ode.pc +all: all-recursive + +.SUFFIXES: +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): +ode-config: $(top_builddir)/config.status $(srcdir)/ode-config.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +ode.pc: $(top_builddir)/config.status $(srcdir)/ode.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +install-binSCRIPTS: $(bin_SCRIPTS) + @$(NORMAL_INSTALL) + @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n' \ + -e 'h;s|.*|.|' \ + -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) { files[d] = files[d] " " $$1; \ + if (++n[d] == $(am__install_max)) { \ + print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ + else { print "f", d "/" $$4, $$1 } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binSCRIPTS: + @$(NORMAL_UNINSTALL) + @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 's,.*/,,;$(transform)'`; \ + dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ + done + +uninstall-pkgconfigDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__post_remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + +dist-tarZ: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__post_remove_distdir) + +dist-shar: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__post_remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__post_remove_distdir) + +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build/sub \ + && ../../configure \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=../.. --prefix="$$dc_install_base" \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__post_remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile $(SCRIPTS) $(DATA) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgconfigdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-pkgconfigDATA + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-binSCRIPTS + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-binSCRIPTS uninstall-pkgconfigDATA + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--refresh check check-am clean clean-cscope clean-generic \ + clean-libtool cscope cscopelist-am ctags ctags-am dist \ + dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ + dist-xz dist-zip distcheck distclean distclean-generic \ + distclean-libtool distclean-tags distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-binSCRIPTS install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-pkgconfigDATA install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs installdirs-am \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-binSCRIPTS \ + uninstall-pkgconfigDATA + +.PRECIOUS: Makefile + + +# Utility rule for making a release +release: dist-gzip dist-bzip2 + @echo Created release packages for ${PACKAGE}-${VERSION}. + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/OPCODE/COPYING b/libs/ode-0.16.1/OPCODE/COPYING new file mode 100644 index 0000000..54a62aa --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/COPYING @@ -0,0 +1,30 @@ +The OPCODE library distributed as part of ODE is licensed under +the same terms as ODE (LGPLv2.1+ and BSD). + +Quoting a public e-mail from the author: + + Re: TriMesh support and OPCODE added to ODE core + Pierre Terdiman <p.terdiman <at> wanadoo.fr> + 2003-07-01 21:18:44 GMT + + > If he wants + > to explicitly make it clear that OpCode is good under ODE's + > license, that would be A-1 Super... + + "Opcode is good under ODE's license" + + I didn't put a license to prevent boring questions about licenses, but it + seems it's not enough - I still get as many questions, regarding missing + license. + + The only thing that would NOT be good would be renaming it "TopCode", + changing the author's name, selling it at a very expensive price, and still + managing to make money out of it :) + + ...I should add a license explicitely against this :) + + Pierre + +Source: + http://permalink.gmane.org/gmane.comp.lib.ode/3237 + diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceAABB.cpp b/libs/ode-0.16.1/OPCODE/Ice/IceAABB.cpp new file mode 100644 index 0000000..d96cd88 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceAABB.cpp @@ -0,0 +1,405 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains AABB-related code. + * \file IceAABB.cpp + * \author Pierre Terdiman + * \date January, 29, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * AABB class. + * \class AABB + * \author Pierre Terdiman + * \version 1.0 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace IceMaths; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the sum of two AABBs. + * \param aabb [in] the other AABB + * \return Self-Reference + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABB& AABB::Add(const AABB& aabb) +{ + // Compute new min & max values + Point Min; GetMin(Min); + Point Tmp; aabb.GetMin(Tmp); + Min.Min(Tmp); + + Point Max; GetMax(Max); + aabb.GetMax(Tmp); + Max.Max(Tmp); + + // Update this + SetMinMax(Min, Max); + return *this; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Makes a cube from the AABB. + * \param cube [out] the cube AABB + * \return cube edge length + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float AABB::MakeCube(AABB& cube) const +{ + Point Ext; GetExtents(Ext); + float Max = Ext.Max(); + + Point Cnt; GetCenter(Cnt); + cube.SetCenterExtents(Cnt, Point(Max, Max, Max)); + return Max; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Makes a sphere from the AABB. + * \param sphere [out] sphere containing the AABB + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABB::MakeSphere(Sphere& sphere) const +{ + GetExtents(sphere.mCenter); + sphere.mRadius = sphere.mCenter.Magnitude() * 1.00001f; // To make sure sphere::Contains(*this) succeeds + GetCenter(sphere.mCenter); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks a box is inside another box. + * \param box [in] the other AABB + * \return true if current box is inside input box + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABB::IsInside(const AABB& box) const +{ + if(box.GetMin(0)>GetMin(0)) return false; + if(box.GetMin(1)>GetMin(1)) return false; + if(box.GetMin(2)>GetMin(2)) return false; + if(box.GetMax(0)<GetMax(0)) return false; + if(box.GetMax(1)<GetMax(1)) return false; + if(box.GetMax(2)<GetMax(2)) return false; + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the AABB planes. + * \param planes [out] 6 planes surrounding the box + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABB::ComputePlanes(Plane* planes) const +{ + // Checkings + if(!planes) return false; + + Point Center, Extents; + GetCenter(Center); + GetExtents(Extents); + + // Writes normals + planes[0].n = Point(1.0f, 0.0f, 0.0f); + planes[1].n = Point(-1.0f, 0.0f, 0.0f); + planes[2].n = Point(0.0f, 1.0f, 0.0f); + planes[3].n = Point(0.0f, -1.0f, 0.0f); + planes[4].n = Point(0.0f, 0.0f, 1.0f); + planes[5].n = Point(0.0f, 0.0f, -1.0f); + + // Compute a point on each plane + Point p0 = Point(Center.x+Extents.x, Center.y, Center.z); + Point p1 = Point(Center.x-Extents.x, Center.y, Center.z); + Point p2 = Point(Center.x, Center.y+Extents.y, Center.z); + Point p3 = Point(Center.x, Center.y-Extents.y, Center.z); + Point p4 = Point(Center.x, Center.y, Center.z+Extents.z); + Point p5 = Point(Center.x, Center.y, Center.z-Extents.z); + + // Compute d + planes[0].d = -(planes[0].n|p0); + planes[1].d = -(planes[1].n|p1); + planes[2].d = -(planes[2].n|p2); + planes[3].d = -(planes[3].n|p3); + planes[4].d = -(planes[4].n|p4); + planes[5].d = -(planes[5].n|p5); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the aabb points. + * \param pts [out] 8 box points + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABB::ComputePoints(Point* pts) const +{ + // Checkings + if(!pts) return false; + + // Get box corners + Point min; GetMin(min); + Point max; GetMax(max); + + // 7+------+6 0 = --- + // /| /| 1 = +-- + // / | / | 2 = ++- + // / 4+---/--+5 3 = -+- + // 3+------+2 / y z 4 = --+ + // | / | / | / 5 = +-+ + // |/ |/ |/ 6 = +++ + // 0+------+1 *---x 7 = -++ + + // Generate 8 corners of the bbox + pts[0] = Point(min.x, min.y, min.z); + pts[1] = Point(max.x, min.y, min.z); + pts[2] = Point(max.x, max.y, min.z); + pts[3] = Point(min.x, max.y, min.z); + pts[4] = Point(min.x, min.y, max.z); + pts[5] = Point(max.x, min.y, max.z); + pts[6] = Point(max.x, max.y, max.z); + pts[7] = Point(min.x, max.y, max.z); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Gets vertex normals. + * \param pts [out] 8 box points + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +const Point* AABB::GetVertexNormals() const +{ + static const float VertexNormals[] = + { + -INVSQRT3, -INVSQRT3, -INVSQRT3, + INVSQRT3, -INVSQRT3, -INVSQRT3, + INVSQRT3, INVSQRT3, -INVSQRT3, + -INVSQRT3, INVSQRT3, -INVSQRT3, + -INVSQRT3, -INVSQRT3, INVSQRT3, + INVSQRT3, -INVSQRT3, INVSQRT3, + INVSQRT3, INVSQRT3, INVSQRT3, + -INVSQRT3, INVSQRT3, INVSQRT3 + }; + return (const Point*)VertexNormals; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Returns edges. + * \return 24 indices (12 edges) indexing the list returned by ComputePoints() + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +const udword* AABB::GetEdges() const +{ + static const udword Indices[] = { + 0, 1, 1, 2, 2, 3, 3, 0, + 7, 6, 6, 5, 5, 4, 4, 7, + 1, 5, 6, 2, + 3, 7, 4, 0 + }; + return Indices; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Returns edge normals. + * \return edge normals in local space + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +const Point* AABB::GetEdgeNormals() const +{ + static const float EdgeNormals[] = + { + 0, -INVSQRT2, -INVSQRT2, // 0-1 + INVSQRT2, 0, -INVSQRT2, // 1-2 + 0, INVSQRT2, -INVSQRT2, // 2-3 + -INVSQRT2, 0, -INVSQRT2, // 3-0 + + 0, INVSQRT2, INVSQRT2, // 7-6 + INVSQRT2, 0, INVSQRT2, // 6-5 + 0, -INVSQRT2, INVSQRT2, // 5-4 + -INVSQRT2, 0, INVSQRT2, // 4-7 + + INVSQRT2, -INVSQRT2, 0, // 1-5 + INVSQRT2, INVSQRT2, 0, // 6-2 + -INVSQRT2, INVSQRT2, 0, // 3-7 + -INVSQRT2, -INVSQRT2, 0 // 4-0 + }; + return (const Point*)EdgeNormals; +} + +// =========================================================================== +// (C) 1996-98 Vienna University of Technology +// =========================================================================== +// NAME: bboxarea +// TYPE: c++ code +// PROJECT: Bounding Box Area +// CONTENT: Computes area of 2D projection of 3D oriented bounding box +// VERSION: 1.0 +// =========================================================================== +// AUTHORS: ds Dieter Schmalstieg +// ep Erik Pojar +// =========================================================================== +// HISTORY: +// +// 19-sep-99 15:23:03 ds last modification +// 01-dec-98 15:23:03 ep created +// =========================================================================== + +//---------------------------------------------------------------------------- +// SAMPLE CODE STARTS HERE +//---------------------------------------------------------------------------- + +// NOTE: This sample program requires OPEN INVENTOR! + +//indexlist: this table stores the 64 possible cases of classification of +//the eyepoint with respect to the 6 defining planes of the bbox (2^6=64) +//only 26 (3^3-1, where 1 is "inside" cube) of these cases are valid. +//the first 6 numbers in each row are the indices of the bbox vertices that +//form the outline of which we want to compute the area (counterclockwise +//ordering), the 7th entry means the number of vertices in the outline. +//there are 6 cases with a single face and and a 4-vertex outline, and +//20 cases with 2 or 3 faces and a 6-vertex outline. a value of 0 indicates +//an invalid case. + + +// Original list was made of 7 items, I added an 8th element: +// - to padd on a cache line +// - to repeat the first entry to avoid modulos +// +// I also replaced original ints with sbytes. + +static const sbyte gIndexList[64][8] = +{ + {-1,-1,-1,-1,-1,-1,-1, 0}, // 0 inside + { 0, 4, 7, 3, 0,-1,-1, 4}, // 1 left + { 1, 2, 6, 5, 1,-1,-1, 4}, // 2 right + {-1,-1,-1,-1,-1,-1,-1, 0}, // 3 - + { 0, 1, 5, 4, 0,-1,-1, 4}, // 4 bottom + { 0, 1, 5, 4, 7, 3, 0, 6}, // 5 bottom, left + { 0, 1, 2, 6, 5, 4, 0, 6}, // 6 bottom, right + {-1,-1,-1,-1,-1,-1,-1, 0}, // 7 - + { 2, 3, 7, 6, 2,-1,-1, 4}, // 8 top + { 0, 4, 7, 6, 2, 3, 0, 6}, // 9 top, left + { 1, 2, 3, 7, 6, 5, 1, 6}, //10 top, right + {-1,-1,-1,-1,-1,-1,-1, 0}, //11 - + {-1,-1,-1,-1,-1,-1,-1, 0}, //12 - + {-1,-1,-1,-1,-1,-1,-1, 0}, //13 - + {-1,-1,-1,-1,-1,-1,-1, 0}, //14 - + {-1,-1,-1,-1,-1,-1,-1, 0}, //15 - + { 0, 3, 2, 1, 0,-1,-1, 4}, //16 front + { 0, 4, 7, 3, 2, 1, 0, 6}, //17 front, left + { 0, 3, 2, 6, 5, 1, 0, 6}, //18 front, right + {-1,-1,-1,-1,-1,-1,-1, 0}, //19 - + { 0, 3, 2, 1, 5, 4, 0, 6}, //20 front, bottom + { 1, 5, 4, 7, 3, 2, 1, 6}, //21 front, bottom, left + { 0, 3, 2, 6, 5, 4, 0, 6}, //22 front, bottom, right + {-1,-1,-1,-1,-1,-1,-1, 0}, //23 - + { 0, 3, 7, 6, 2, 1, 0, 6}, //24 front, top + { 0, 4, 7, 6, 2, 1, 0, 6}, //25 front, top, left + { 0, 3, 7, 6, 5, 1, 0, 6}, //26 front, top, right + {-1,-1,-1,-1,-1,-1,-1, 0}, //27 - + {-1,-1,-1,-1,-1,-1,-1, 0}, //28 - + {-1,-1,-1,-1,-1,-1,-1, 0}, //29 - + {-1,-1,-1,-1,-1,-1,-1, 0}, //30 - + {-1,-1,-1,-1,-1,-1,-1, 0}, //31 - + { 4, 5, 6, 7, 4,-1,-1, 4}, //32 back + { 0, 4, 5, 6, 7, 3, 0, 6}, //33 back, left + { 1, 2, 6, 7, 4, 5, 1, 6}, //34 back, right + {-1,-1,-1,-1,-1,-1,-1, 0}, //35 - + { 0, 1, 5, 6, 7, 4, 0, 6}, //36 back, bottom + { 0, 1, 5, 6, 7, 3, 0, 6}, //37 back, bottom, left + { 0, 1, 2, 6, 7, 4, 0, 6}, //38 back, bottom, right + {-1,-1,-1,-1,-1,-1,-1, 0}, //39 - + { 2, 3, 7, 4, 5, 6, 2, 6}, //40 back, top + { 0, 4, 5, 6, 2, 3, 0, 6}, //41 back, top, left + { 1, 2, 3, 7, 4, 5, 1, 6}, //42 back, top, right + {-1,-1,-1,-1,-1,-1,-1, 0}, //43 invalid + {-1,-1,-1,-1,-1,-1,-1, 0}, //44 invalid + {-1,-1,-1,-1,-1,-1,-1, 0}, //45 invalid + {-1,-1,-1,-1,-1,-1,-1, 0}, //46 invalid + {-1,-1,-1,-1,-1,-1,-1, 0}, //47 invalid + {-1,-1,-1,-1,-1,-1,-1, 0}, //48 invalid + {-1,-1,-1,-1,-1,-1,-1, 0}, //49 invalid + {-1,-1,-1,-1,-1,-1,-1, 0}, //50 invalid + {-1,-1,-1,-1,-1,-1,-1, 0}, //51 invalid + {-1,-1,-1,-1,-1,-1,-1, 0}, //52 invalid + {-1,-1,-1,-1,-1,-1,-1, 0}, //53 invalid + {-1,-1,-1,-1,-1,-1,-1, 0}, //54 invalid + {-1,-1,-1,-1,-1,-1,-1, 0}, //55 invalid + {-1,-1,-1,-1,-1,-1,-1, 0}, //56 invalid + {-1,-1,-1,-1,-1,-1,-1, 0}, //57 invalid + {-1,-1,-1,-1,-1,-1,-1, 0}, //58 invalid + {-1,-1,-1,-1,-1,-1,-1, 0}, //59 invalid + {-1,-1,-1,-1,-1,-1,-1, 0}, //60 invalid + {-1,-1,-1,-1,-1,-1,-1, 0}, //61 invalid + {-1,-1,-1,-1,-1,-1,-1, 0}, //62 invalid + {-1,-1,-1,-1,-1,-1,-1, 0} //63 invalid +}; + +const sbyte* AABB::ComputeOutline(const Point& local_eye, sdword& num) const +{ + // Get box corners + Point min; GetMin(min); + Point max; GetMax(max); + + // Compute 6-bit code to classify eye with respect to the 6 defining planes of the bbox + int pos = ((local_eye.x < min.x) ? 1 : 0) // 1 = left + + ((local_eye.x > max.x) ? 2 : 0) // 2 = right + + ((local_eye.y < min.y) ? 4 : 0) // 4 = bottom + + ((local_eye.y > max.y) ? 8 : 0) // 8 = top + + ((local_eye.z < min.z) ? 16 : 0) // 16 = front + + ((local_eye.z > max.z) ? 32 : 0); // 32 = back + + // Look up number of vertices in outline + num = (sdword)gIndexList[pos][7]; + // Zero indicates invalid case + if(!num) return null; + + return &gIndexList[pos][0]; +} + +// calculateBoxArea: computes the screen-projected 2D area of an oriented 3D bounding box + +//const Point& eye, //eye point (in bbox object coordinates) +//const AABB& box, //3d bbox +//const Matrix4x4& mat, //free transformation for bbox +//float width, float height, int& num) +float AABB::ComputeBoxArea(const Point& eye, const Matrix4x4& mat, float width, float height, sdword& num) const +{ + const sbyte* Outline = ComputeOutline(eye, num); + if(!Outline) return -1.0f; + + // Compute box vertices + Point vertexBox[8], dst[8]; + ComputePoints(vertexBox); + + // Transform all outline corners into 2D screen space + for(sdword i=0;i<num;i++) + { + HPoint Projected; + vertexBox[Outline[i]].ProjectToScreen(width, height, mat, Projected); + dst[i] = Projected; + } + + float Sum = (dst[num-1][0] - dst[0][0]) * (dst[num-1][1] + dst[0][1]); + + for(int i=0; i<num-1; i++) + Sum += (dst[i][0] - dst[i+1][0]) * (dst[i][1] + dst[i+1][1]); + + return Sum * 0.5f; //return computed value corrected by 0.5 +} diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceAABB.h b/libs/ode-0.16.1/OPCODE/Ice/IceAABB.h new file mode 100644 index 0000000..cc8cdf2 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceAABB.h @@ -0,0 +1,514 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains AABB-related code. (axis-aligned bounding box) + * \file IceAABB.h + * \author Pierre Terdiman + * \date January, 13, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEAABB_H__ +#define __ICEAABB_H__ + + // Forward declarations + class Sphere; + +//! Declarations of type-independent methods (most of them implemented in the .cpp) +#define AABB_COMMON_METHODS \ + AABB& Add(const AABB& aabb); \ + float MakeCube(AABB& cube) const; \ + void MakeSphere(Sphere& sphere) const; \ + const sbyte* ComputeOutline(const Point& local_eye, sdword& num) const; \ + float ComputeBoxArea(const Point& eye, const Matrix4x4& mat, float width, float height, sdword& num) const; \ + bool IsInside(const AABB& box) const; \ + bool ComputePlanes(Plane* planes) const; \ + bool ComputePoints(Point* pts) const; \ + const Point* GetVertexNormals() const; \ + const udword* GetEdges() const; \ + const Point* GetEdgeNormals() const; \ + inline_ BOOL ContainsPoint(const Point& p) const \ + { \ + if(p.x > GetMax(0) || p.x < GetMin(0)) return FALSE; \ + if(p.y > GetMax(1) || p.y < GetMin(1)) return FALSE; \ + if(p.z > GetMax(2) || p.z < GetMin(2)) return FALSE; \ + return TRUE; \ + } + + enum AABBType + { + AABB_RENDER = 0, //!< AABB used for rendering. Not visible == not rendered. + AABB_UPDATE = 1, //!< AABB used for dynamic updates. Not visible == not updated. + + AABB_FORCE_DWORD = 0x7fffffff, + }; + +#ifdef USE_MINMAX + + struct ICEMATHS_API ShadowAABB + { + Point mMin; + Point mMax; + }; + + class ICEMATHS_API AABB + { + public: + //! Constructor + inline_ AABB() {} + //! Destructor + inline_ ~AABB() {} + + //! Type-independent methods + AABB_COMMON_METHODS; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups an AABB from min & max vectors. + * \param min [in] the min point + * \param max [in] the max point + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void SetMinMax(const Point& min, const Point& max) { mMin = min; mMax = max; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups an AABB from center & extents vectors. + * \param c [in] the center point + * \param e [in] the extents vector + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void SetCenterExtents(const Point& c, const Point& e) { mMin = c - e; mMax = c + e; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups an empty AABB. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void SetEmpty() { Point p(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT); mMin = -p; mMax = p;} + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups a point AABB. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void SetPoint(const Point& pt) { mMin = mMax = pt; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the size of the AABB. The size is defined as the longest extent. + * \return the size of the AABB + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + float GetSize() const { Point e; GetExtents(e); return e.Max(); } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Extends the AABB. + * \param p [in] the next point + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void Extend(const Point& p) + { + if(p.x > mMax.x) mMax.x = p.x; + if(p.x < mMin.x) mMin.x = p.x; + + if(p.y > mMax.y) mMax.y = p.y; + if(p.y < mMin.y) mMin.y = p.y; + + if(p.z > mMax.z) mMax.z = p.z; + if(p.z < mMin.z) mMin.z = p.z; + } + // Data access + + //! Get min point of the box + inline_ void GetMin(Point& min) const { min = mMin; } + //! Get max point of the box + inline_ void GetMax(Point& max) const { max = mMax; } + + //! Get component of the box's min point along a given axis + inline_ float GetMin(udword axis) const { return mMin[axis]; } + //! Get component of the box's max point along a given axis + inline_ float GetMax(udword axis) const { return mMax[axis]; } + + //! Get box center + inline_ void GetCenter(Point& center) const { center = (mMax + mMin)*0.5f; } + //! Get box extents + inline_ void GetExtents(Point& extents) const { extents = (mMax - mMin)*0.5f; } + + //! Get component of the box's center along a given axis + inline_ float GetCenter(udword axis) const { return (mMax[axis] + mMin[axis])*0.5f; } + //! Get component of the box's extents along a given axis + inline_ float GetExtents(udword axis) const { return (mMax[axis] - mMin[axis])*0.5f; } + + //! Get box diagonal + inline_ void GetDiagonal(Point& diagonal) const { diagonal = mMax - mMin; } + inline_ float GetWidth() const { return mMax.x - mMin.x; } + inline_ float GetHeight() const { return mMax.y - mMin.y; } + inline_ float GetDepth() const { return mMax.z - mMin.z; } + + //! Volume + inline_ float GetVolume() const { return GetWidth() * GetHeight() * GetDepth(); } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes the intersection between two AABBs. + * \param a [in] the other AABB + * \return true on intersection + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL Intersect(const AABB& a) const + { + if(mMax.x < a.mMin.x + || a.mMax.x < mMin.x + || mMax.y < a.mMin.y + || a.mMax.y < mMin.y + || mMax.z < a.mMin.z + || a.mMax.z < mMin.z) return FALSE; + + return TRUE; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes the 1D-intersection between two AABBs, on a given axis. + * \param a [in] the other AABB + * \param axis [in] the axis (0, 1, 2) + * \return true on intersection + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL Intersect(const AABB& a, udword axis) const + { + if(mMax[axis] < a.mMin[axis] || a.mMax[axis] < mMin[axis]) return FALSE; + return TRUE; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Recomputes the AABB after an arbitrary transform by a 4x4 matrix. + * Original code by Charles Bloom on the GD-Algorithm list. (I slightly modified it) + * \param mtx [in] the transform matrix + * \param aabb [out] the transformed AABB [can be *this] + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void Rotate(const Matrix4x4& mtx, AABB& aabb) const + { + // The three edges transformed: you can efficiently transform an X-only vector + // by just getting the "X" column of the matrix + Point vx,vy,vz; + mtx.GetRow(0, vx); vx *= (mMax.x - mMin.x); + mtx.GetRow(1, vy); vy *= (mMax.y - mMin.y); + mtx.GetRow(2, vz); vz *= (mMax.z - mMin.z); + + // Transform the min point + aabb.mMin = aabb.mMax = mMin * mtx; + + // Take the transformed min & axes and find new extents + // Using CPU code in the right place is faster... + if(IS_NEGATIVE_FLOAT(vx.x)) aabb.mMin.x += vx.x; else aabb.mMax.x += vx.x; + if(IS_NEGATIVE_FLOAT(vx.y)) aabb.mMin.y += vx.y; else aabb.mMax.y += vx.y; + if(IS_NEGATIVE_FLOAT(vx.z)) aabb.mMin.z += vx.z; else aabb.mMax.z += vx.z; + if(IS_NEGATIVE_FLOAT(vy.x)) aabb.mMin.x += vy.x; else aabb.mMax.x += vy.x; + if(IS_NEGATIVE_FLOAT(vy.y)) aabb.mMin.y += vy.y; else aabb.mMax.y += vy.y; + if(IS_NEGATIVE_FLOAT(vy.z)) aabb.mMin.z += vy.z; else aabb.mMax.z += vy.z; + if(IS_NEGATIVE_FLOAT(vz.x)) aabb.mMin.x += vz.x; else aabb.mMax.x += vz.x; + if(IS_NEGATIVE_FLOAT(vz.y)) aabb.mMin.y += vz.y; else aabb.mMax.y += vz.y; + if(IS_NEGATIVE_FLOAT(vz.z)) aabb.mMin.z += vz.z; else aabb.mMax.z += vz.z; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks the AABB is valid. + * \return true if the box is valid + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL IsValid() const + { + // Consistency condition for (Min, Max) boxes: min < max + if(mMin.x > mMax.x) return FALSE; + if(mMin.y > mMax.y) return FALSE; + if(mMin.z > mMax.z) return FALSE; + return TRUE; + } + + //! Operator for AABB *= float. Scales the extents, keeps same center. + inline_ AABB& operator*=(float s) + { + Point Center; GetCenter(Center); + Point Extents; GetExtents(Extents); + SetCenterExtents(Center, Extents * s); + return *this; + } + + //! Operator for AABB /= float. Scales the extents, keeps same center. + inline_ AABB& operator/=(float s) + { + Point Center; GetCenter(Center); + Point Extents; GetExtents(Extents); + SetCenterExtents(Center, Extents / s); + return *this; + } + + //! Operator for AABB += Point. Translates the box. + inline_ AABB& operator+=(const Point& trans) + { + mMin+=trans; + mMax+=trans; + return *this; + } + private: + Point mMin; //!< Min point + Point mMax; //!< Max point + }; + +#else + + class ICEMATHS_API AABB + { + public: + //! Constructor + inline_ AABB() {} + //! Destructor + inline_ ~AABB() {} + + //! Type-independent methods + AABB_COMMON_METHODS; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups an AABB from min & max vectors. + * \param min [in] the min point + * \param max [in] the max point + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void SetMinMax(const Point& min, const Point& max) { mCenter = (max + min)*0.5f; mExtents = (max - min)*0.5f; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups an AABB from center & extents vectors. + * \param c [in] the center point + * \param e [in] the extents vector + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void SetCenterExtents(const Point& c, const Point& e) { mCenter = c; mExtents = e; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups an empty AABB. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void SetEmpty() { mCenter.Zero(); mExtents.Set(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT);} + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups a point AABB. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void SetPoint(const Point& pt) { mCenter = pt; mExtents.Zero(); } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the size of the AABB. The size is defined as the longest extent. + * \return the size of the AABB + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + float GetSize() const { return mExtents.Max(); } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Extends the AABB. + * \param p [in] the next point + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void Extend(const Point& p) + { + Point Max = mCenter + mExtents; + Point Min = mCenter - mExtents; + + if(p.x > Max.x) Max.x = p.x; + if(p.x < Min.x) Min.x = p.x; + + if(p.y > Max.y) Max.y = p.y; + if(p.y < Min.y) Min.y = p.y; + + if(p.z > Max.z) Max.z = p.z; + if(p.z < Min.z) Min.z = p.z; + + SetMinMax(Min, Max); + } + // Data access + + //! Get min point of the box + inline_ void GetMin(Point& min) const { min = mCenter - mExtents; } + //! Get max point of the box + inline_ void GetMax(Point& max) const { max = mCenter + mExtents; } + + //! Get component of the box's min point along a given axis + inline_ float GetMin(udword axis) const { return mCenter[axis] - mExtents[axis]; } + //! Get component of the box's max point along a given axis + inline_ float GetMax(udword axis) const { return mCenter[axis] + mExtents[axis]; } + + //! Get box center + inline_ void GetCenter(Point& center) const { center = mCenter; } + //! Get box extents + inline_ void GetExtents(Point& extents) const { extents = mExtents; } + + //! Get component of the box's center along a given axis + inline_ float GetCenter(udword axis) const { return mCenter[axis]; } + //! Get component of the box's extents along a given axis + inline_ float GetExtents(udword axis) const { return mExtents[axis]; } + + //! Get box diagonal + inline_ void GetDiagonal(Point& diagonal) const { diagonal = mExtents * 2.0f; } + inline_ float GetWidth() const { return mExtents.x * 2.0f; } + inline_ float GetHeight() const { return mExtents.y * 2.0f; } + inline_ float GetDepth() const { return mExtents.z * 2.0f; } + + //! Volume + inline_ float GetVolume() const { return mExtents.x * mExtents.y * mExtents.z * 8.0f; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes the intersection between two AABBs. + * \param a [in] the other AABB + * \return true on intersection + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL Intersect(const AABB& a) const + { + float tx = mCenter.x - a.mCenter.x; float ex = a.mExtents.x + mExtents.x; if(AIR(tx) > IR(ex)) return FALSE; + float ty = mCenter.y - a.mCenter.y; float ey = a.mExtents.y + mExtents.y; if(AIR(ty) > IR(ey)) return FALSE; + float tz = mCenter.z - a.mCenter.z; float ez = a.mExtents.z + mExtents.z; if(AIR(tz) > IR(ez)) return FALSE; + return TRUE; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * The standard intersection method from Gamasutra. Just here to check its speed against the one above. + * \param a [in] the other AABB + * \return true on intersection + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ bool GomezIntersect(const AABB& a) + { + Point T = mCenter - a.mCenter; // Vector from A to B + return ((fabsf(T.x) <= (a.mExtents.x + mExtents.x)) + && (fabsf(T.y) <= (a.mExtents.y + mExtents.y)) + && (fabsf(T.z) <= (a.mExtents.z + mExtents.z))); + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes the 1D-intersection between two AABBs, on a given axis. + * \param a [in] the other AABB + * \param axis [in] the axis (0, 1, 2) + * \return true on intersection + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL Intersect(const AABB& a, udword axis) const + { + float t = mCenter[axis] - a.mCenter[axis]; + float e = a.mExtents[axis] + mExtents[axis]; + if(AIR(t) > IR(e)) return FALSE; + return TRUE; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Recomputes the AABB after an arbitrary transform by a 4x4 matrix. + * \param mtx [in] the transform matrix + * \param aabb [out] the transformed AABB [can be *this] + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void Rotate(const Matrix4x4& mtx, AABB& aabb) const + { + // Compute new center + aabb.mCenter = mCenter * mtx; + + // Compute new extents. FPU code & CPU code have been interleaved for improved performance. + Point Ex(mtx.m[0][0] * mExtents.x, mtx.m[0][1] * mExtents.x, mtx.m[0][2] * mExtents.x); + //IR(Ex.x)&=0x7fffffff; IR(Ex.y)&=0x7fffffff; IR(Ex.z)&=0x7fffffff; + Ex.x = FR( AIR(Ex.x) ); + Ex.y = FR( AIR(Ex.y) ); + Ex.z = FR( AIR(Ex.z) ); + + Point Ey(mtx.m[1][0] * mExtents.y, mtx.m[1][1] * mExtents.y, mtx.m[1][2] * mExtents.y); + //IR(Ey.x)&=0x7fffffff; IR(Ey.y)&=0x7fffffff; IR(Ey.z)&=0x7fffffff; + Ey.x = FR( AIR(Ey.x) ); + Ey.y = FR( AIR(Ey.y) ); + Ey.z = FR( AIR(Ey.z) ); + + Point Ez(mtx.m[2][0] * mExtents.z, mtx.m[2][1] * mExtents.z, mtx.m[2][2] * mExtents.z); + //IR(Ez.x)&=0x7fffffff; IR(Ez.y)&=0x7fffffff; IR(Ez.z)&=0x7fffffff; + Ez.x = FR( AIR(Ez.x) ); + Ez.y = FR( AIR(Ez.y) ); + Ez.z = FR( AIR(Ez.z) ); + + aabb.mExtents.x = Ex.x + Ey.x + Ez.x; + aabb.mExtents.y = Ex.y + Ey.y + Ez.y; + aabb.mExtents.z = Ex.z + Ey.z + Ez.z; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks the AABB is valid. + * \return true if the box is valid + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL IsValid() const + { + // Consistency condition for (Center, Extents) boxes: Extents >= 0 + if(IS_NEGATIVE_FLOAT(mExtents.x)) return FALSE; + if(IS_NEGATIVE_FLOAT(mExtents.y)) return FALSE; + if(IS_NEGATIVE_FLOAT(mExtents.z)) return FALSE; + return TRUE; + } + + //! Operator for AABB *= float. Scales the extents, keeps same center. + inline_ AABB& operator*=(float s) { mExtents*=s; return *this; } + + //! Operator for AABB /= float. Scales the extents, keeps same center. + inline_ AABB& operator/=(float s) { mExtents/=s; return *this; } + + //! Operator for AABB += Point. Translates the box. + inline_ AABB& operator+=(const Point& trans) + { + mCenter+=trans; + return *this; + } + private: + Point mCenter; //!< AABB Center + Point mExtents; //!< x, y and z extents + }; + +#endif + + inline_ void ComputeMinMax(const Point& p, Point& min, Point& max) + { + if(p.x > max.x) max.x = p.x; + if(p.x < min.x) min.x = p.x; + + if(p.y > max.y) max.y = p.y; + if(p.y < min.y) min.y = p.y; + + if(p.z > max.z) max.z = p.z; + if(p.z < min.z) min.z = p.z; + } + + inline_ void ComputeAABB(AABB& aabb, const Point* list, udword nb_pts) + { + if(list) + { + Point Maxi(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT); + Point Mini(MAX_FLOAT, MAX_FLOAT, MAX_FLOAT); + while(nb_pts--) + { +// _prefetch(list+1); // off by one ? + ComputeMinMax(*list++, Mini, Maxi); + } + aabb.SetMinMax(Mini, Maxi); + } + } + +#endif // __ICEAABB_H__ diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceAxes.h b/libs/ode-0.16.1/OPCODE/Ice/IceAxes.h new file mode 100644 index 0000000..8af57e1 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceAxes.h @@ -0,0 +1,54 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains axes definition. + * \file IceAxes.h + * \author Pierre Terdiman + * \date January, 29, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEAXES_H__ +#define __ICEAXES_H__ + + enum PointComponent + { + X = 0, + Y = 1, + Z = 2, + W = 3, + + FORCE_DWORD = 0x7fffffff + }; + + enum AxisOrder + { + AXES_XYZ = (X)|(Y<<2)|(Z<<4), + AXES_XZY = (X)|(Z<<2)|(Y<<4), + AXES_YXZ = (Y)|(X<<2)|(Z<<4), + AXES_YZX = (Y)|(Z<<2)|(X<<4), + AXES_ZXY = (Z)|(X<<2)|(Y<<4), + AXES_ZYX = (Z)|(Y<<2)|(X<<4), + + AXES_FORCE_DWORD = 0x7fffffff + }; + + class ICEMATHS_API Axes + { + public: + + inline_ Axes(AxisOrder order) + { + mAxis0 = (order ) & 3; + mAxis1 = (order>>2) & 3; + mAxis2 = (order>>4) & 3; + } + inline_ ~Axes() {} + + udword mAxis0; + udword mAxis1; + udword mAxis2; + }; + +#endif // __ICEAXES_H__ diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceBoundingSphere.h b/libs/ode-0.16.1/OPCODE/Ice/IceBoundingSphere.h new file mode 100644 index 0000000..945d38c --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceBoundingSphere.h @@ -0,0 +1,142 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code to compute the minimal bounding sphere. + * \file IceBoundingSphere.h + * \author Pierre Terdiman + * \date January, 29, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEBOUNDINGSPHERE_H__ +#define __ICEBOUNDINGSPHERE_H__ + + enum BSphereMethod + { + BS_NONE, + BS_GEMS, + BS_MINIBALL, + + BS_FORCE_DWORD = 0x7fffffff + }; + + class ICEMATHS_API Sphere + { + public: + //! Constructor + inline_ Sphere() {} + //! Constructor + inline_ Sphere(const Point& center, float radius) : mCenter(center), mRadius(radius) {} + //! Constructor + Sphere(udword nb_verts, const Point* verts); + //! Copy constructor + inline_ Sphere(const Sphere& sphere) : mCenter(sphere.mCenter), mRadius(sphere.mRadius) {} + //! Destructor + inline_ ~Sphere() {} + + BSphereMethod Compute(udword nb_verts, const Point* verts); + bool FastCompute(udword nb_verts, const Point* verts); + + // Access methods + inline_ const Point& GetCenter() const { return mCenter; } + inline_ float GetRadius() const { return mRadius; } + + inline_ const Point& Center() const { return mCenter; } + inline_ float Radius() const { return mRadius; } + + inline_ Sphere& Set(const Point& center, float radius) { mCenter = center; mRadius = radius; return *this; } + inline_ Sphere& SetCenter(const Point& center) { mCenter = center; return *this; } + inline_ Sphere& SetRadius(float radius) { mRadius = radius; return *this; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Tests if a point is contained within the sphere. + * \param p [in] the point to test + * \return true if inside the sphere + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ bool Contains(const Point& p) const + { + return mCenter.SquareDistance(p) <= mRadius*mRadius; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Tests if a sphere is contained within the sphere. + * \param sphere [in] the sphere to test + * \return true if inside the sphere + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ bool Contains(const Sphere& sphere) const + { + // If our radius is the smallest, we can't possibly contain the other sphere + if(mRadius < sphere.mRadius) return false; + // So r is always positive or null now + float r = mRadius - sphere.mRadius; + return mCenter.SquareDistance(sphere.mCenter) <= r*r; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Tests if a box is contained within the sphere. + * \param aabb [in] the box to test + * \return true if inside the sphere + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL Contains(const AABB& aabb) const + { + // I assume if all 8 box vertices are inside the sphere, so does the whole box. + // Sounds ok but maybe there's a better way? + float R2 = mRadius * mRadius; +#ifdef USE_MIN_MAX + const Point& Max = ((ShadowAABB&)&aabb).mMax; + const Point& Min = ((ShadowAABB&)&aabb).mMin; +#else + Point Max; aabb.GetMax(Max); + Point Min; aabb.GetMin(Min); +#endif + Point p; + p.x=Max.x; p.y=Max.y; p.z=Max.z; if(mCenter.SquareDistance(p)>=R2) return FALSE; + p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE; + p.x=Max.x; p.y=Min.y; if(mCenter.SquareDistance(p)>=R2) return FALSE; + p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE; + p.x=Max.x; p.y=Max.y; p.z=Min.z; if(mCenter.SquareDistance(p)>=R2) return FALSE; + p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE; + p.x=Max.x; p.y=Min.y; if(mCenter.SquareDistance(p)>=R2) return FALSE; + p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE; + + return TRUE; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Tests if the sphere intersects another sphere + * \param sphere [in] the other sphere + * \return true if spheres overlap + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ bool Intersect(const Sphere& sphere) const + { + float r = mRadius + sphere.mRadius; + return mCenter.SquareDistance(sphere.mCenter) <= r*r; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks the sphere is valid. + * \return true if the box is valid + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL IsValid() const + { + // Consistency condition for spheres: Radius >= 0.0f + if(mRadius < 0.0f) return FALSE; + return TRUE; + } + public: + Point mCenter; //!< Sphere center + float mRadius; //!< Sphere radius + }; + +#endif // __ICEBOUNDINGSPHERE_H__ diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceContainer.cpp b/libs/ode-0.16.1/OPCODE/Ice/IceContainer.cpp new file mode 100644 index 0000000..3eeefe0 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceContainer.cpp @@ -0,0 +1,357 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a simple container class. + * \file IceContainer.cpp + * \author Pierre Terdiman + * \date February, 5, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a list of 32-bits values. + * Use this class when you need to store an unknown number of values. The list is automatically + * resized and can contains 32-bits entities (dwords or floats) + * + * \class Container + * \author Pierre Terdiman + * \version 1.0 + * \date 08.15.98 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace IceCore; + +#define MAX_RESERVE_GROWTH_SIZE 65536U + +// Static members +#ifdef CONTAINER_STATS +udword Container::mNbContainers = 0; +udword Container::mUsedRam = 0; +#endif + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. No entries allocated there. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Container::Container() : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null), mGrowthFactor(2) +{ +#ifdef CONTAINER_STATS + mNbContainers++; + mUsedRam+=sizeof(Container); +#endif +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. Also allocates a given number of entries. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Container::Container(udword size, float growth_factor) : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null), mGrowthFactor(growth_factor) +{ +#ifdef CONTAINER_STATS + mNbContainers++; + mUsedRam+=sizeof(Container); +#endif + SetSize(size); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Copy constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Container::Container(const Container& object) : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null), mGrowthFactor(2) +{ +#ifdef CONTAINER_STATS + mNbContainers++; + mUsedRam+=sizeof(Container); +#endif + *this = object; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. Frees everything and leaves. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Container::~Container() +{ + Empty(); +#ifdef CONTAINER_STATS + mNbContainers--; + mUsedRam-=GetUsedRam(); +#endif +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Clears the container. All stored values are deleted, and it frees used ram. + * \see Reset() + * \return Self-Reference + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Container& Container::Empty() +{ +#ifdef CONTAINER_STATS + mUsedRam-=mMaxNbEntries*sizeof(udword); +#endif + DELETEARRAY(mEntries); + mCurNbEntries = mMaxNbEntries = 0; + return *this; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Resizes the container. + * \param needed [in] assume the container can be added at least "needed" values + * \return true if success. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool Container::Resize(udword needed) +{ +#ifdef CONTAINER_STATS + // Subtract previous amount of bytes + mUsedRam-=mMaxNbEntries*sizeof(udword); +#endif + + if (MAX_UDWORD - mCurNbEntries < needed) + { + CHECKALLOC(null); + } + + // Get more entries + udword NewMaxNbEntries = mMaxNbEntries ? udword(mMaxNbEntries * mGrowthFactor) : 2; // Default nb Entries = 2 + + if (NewMaxNbEntries <= mMaxNbEntries) NewMaxNbEntries = MAX_UDWORD - mMaxNbEntries < MAX_RESERVE_GROWTH_SIZE ? MAX_UDWORD : mMaxNbEntries + MAX_RESERVE_GROWTH_SIZE; + else if (NewMaxNbEntries - mMaxNbEntries > MAX_RESERVE_GROWTH_SIZE) NewMaxNbEntries = mMaxNbEntries + MAX_RESERVE_GROWTH_SIZE; + + if (NewMaxNbEntries < mCurNbEntries + needed) NewMaxNbEntries = mCurNbEntries + needed; + + // Get some bytes for new entries + udword* NewEntries = new udword[NewMaxNbEntries]; + CHECKALLOC(NewEntries); + + // Copy old data if needed + if(mCurNbEntries) CopyMemory(NewEntries, mEntries, mCurNbEntries*sizeof(udword)); + + // Delete old data + DELETEARRAY(mEntries); + + // Assign new pointer + mEntries = NewEntries; + mMaxNbEntries = NewMaxNbEntries; + +#ifdef CONTAINER_STATS + // Add current amount of bytes + mUsedRam+=mMaxNbEntries*sizeof(udword); +#endif + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Sets the initial size of the container. If it already contains something, it's discarded. + * \param nb [in] Number of entries + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool Container::SetSize(udword nb) +{ + // Make sure it's empty + Empty(); + + // Checkings + if(!nb) return false; + + // Initialize for nb entries + mMaxNbEntries = nb; + + // Get some bytes for new entries + mEntries = new udword[mMaxNbEntries]; + CHECKALLOC(mEntries); + +#ifdef CONTAINER_STATS + // Add current amount of bytes + mUsedRam+=mMaxNbEntries*sizeof(udword); +#endif + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Refits the container and get rid of unused bytes. + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool Container::Refit() +{ +#ifdef CONTAINER_STATS + // Subtract previous amount of bytes + mUsedRam-=mMaxNbEntries*sizeof(udword); +#endif + + // Get just enough entries + mMaxNbEntries = mCurNbEntries; + if(!mMaxNbEntries) return false; + + // Get just enough bytes + udword* NewEntries = new udword[mMaxNbEntries]; + CHECKALLOC(NewEntries); + +#ifdef CONTAINER_STATS + // Add current amount of bytes + mUsedRam+=mMaxNbEntries*sizeof(udword); +#endif + + // Copy old data + CopyMemory(NewEntries, mEntries, mCurNbEntries*sizeof(udword)); + + // Delete old data + DELETEARRAY(mEntries); + + // Assign new pointer + mEntries = NewEntries; + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks whether the container already contains a given value. + * \param entry [in] the value to look for in the container + * \param location [out] a possible pointer to store the entry location + * \see Add(udword entry) + * \see Add(float entry) + * \see Empty() + * \return true if the value has been found in the container, else false. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool Container::Contains(udword entry, udword* location) const +{ + // Look for the entry + for(udword i=0;i<mCurNbEntries;i++) + { + if(mEntries[i]==entry) + { + if(location) *location = i; + return true; + } + } + return false; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Deletes an entry. If the container contains such an entry, it's removed. + * \param entry [in] the value to delete. + * \return true if the value has been found in the container, else false. + * \warning This method is arbitrary slow (O(n)) and should be used carefully. Insertion order is not preserved. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool Container::Delete(udword entry) +{ + // Look for the entry + for(udword i=0;i<mCurNbEntries;i++) + { + if(mEntries[i]==entry) + { + // Entry has been found at index i. The strategy is to copy the last current entry at index i, and decrement the current number of entries. + DeleteIndex(i); + return true; + } + } + return false; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Deletes an entry, preserving the insertion order. If the container contains such an entry, it's removed. + * \param entry [in] the value to delete. + * \return true if the value has been found in the container, else false. + * \warning This method is arbitrary slow (O(n)) and should be used carefully. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool Container::DeleteKeepingOrder(udword entry) +{ + // Look for the entry + for(udword i=0;i<mCurNbEntries;i++) + { + if(mEntries[i]==entry) + { + // Entry has been found at index i. + // Shift entries to preserve order. You really should use a linked list instead. + mCurNbEntries--; + for(udword j=i;j<mCurNbEntries;j++) + { + mEntries[j] = mEntries[j+1]; + } + return true; + } + } + return false; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Gets the next entry, starting from input one. + * \param entry [in/out] On input, the entry to look for. On output, the next entry + * \param find_mode [in] wrap/clamp + * \return Self-Reference + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Container& Container::FindNext(udword& entry, FindMode find_mode) +{ + udword Location; + if(Contains(entry, &Location)) + { + Location++; + if(Location==mCurNbEntries) Location = find_mode==FIND_WRAP ? 0 : mCurNbEntries-1; + entry = mEntries[Location]; + } + return *this; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Gets the previous entry, starting from input one. + * \param entry [in/out] On input, the entry to look for. On output, the previous entry + * \param find_mode [in] wrap/clamp + * \return Self-Reference + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Container& Container::FindPrev(udword& entry, FindMode find_mode) +{ + udword Location; + if(Contains(entry, &Location)) + { + Location--; + if(Location==0xffffffff) Location = find_mode==FIND_WRAP ? mCurNbEntries-1 : 0; + entry = mEntries[Location]; + } + return *this; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Gets the ram used by the container. + * \return the ram used in bytes. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +udword Container::GetUsedRam() const +{ + return sizeof(Container) + mMaxNbEntries * sizeof(udword); +} + +/*void Container::operator=(const Container& object) +{ + SetSize(object.GetNbEntries()); + CopyMemory(mEntries, object.GetEntries(), mMaxNbEntries*sizeof(udword)); + mCurNbEntries = mMaxNbEntries; +}*/ diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceContainer.h b/libs/ode-0.16.1/OPCODE/Ice/IceContainer.h new file mode 100644 index 0000000..2c3c597 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceContainer.h @@ -0,0 +1,243 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a simple container class. + * \file IceContainer.h + * \author Pierre Terdiman + * \date February, 5, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICECONTAINER_H__ +#define __ICECONTAINER_H__ + +// #define CONTAINER_STATS + + enum FindMode + { + FIND_CLAMP, + FIND_WRAP, + + FIND_FORCE_DWORD = 0x7fffffff + }; + + class ICECORE_API Container + { + public: + // Constructor / Destructor + Container(); + Container(const Container& object); + Container(udword size, float growth_factor); + ~Container(); + // Management + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * A O(1) method to add a value in the container. The container is automatically resized if needed. + * The method is inline, not the resize. The call overhead happens on resizes only, which is not a problem since the resizing operation + * costs a lot more than the call overhead... + * + * \param entry [in] a udword to store in the container + * \see Add(float entry) + * \see Empty() + * \see Contains(udword entry) + * \return Self-Reference + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ Container& Add(udword entry) + { + // Resize if needed + if (mCurNbEntries == mMaxNbEntries + && !Resize()) + { + IceAbort(); + } + + // Add new entry + mEntries[mCurNbEntries++] = entry; + return *this; + } + + inline_ Container& Add(const uword* entries, udword nb) + { + // Resize if needed + if (mCurNbEntries + nb > mMaxNbEntries + && !Resize(nb)) + { + IceAbort(); + } + + // Add new entry + CopyMemory(&mEntries[mCurNbEntries], entries, nb*sizeof(uword)); + mCurNbEntries+=nb; + return *this; + } + + inline_ Container& Add(const udword* entries, udword nb) + { + // Resize if needed + if (mCurNbEntries + nb > mMaxNbEntries + && !Resize(nb)) + { + IceAbort(); + } + + // Add new entry + CopyMemory(&mEntries[mCurNbEntries], entries, nb*sizeof(udword)); + mCurNbEntries+=nb; + return *this; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * A O(1) method to add a value in the container. The container is automatically resized if needed. + * The method is inline, not the resize. The call overhead happens on resizes only, which is not a problem since the resizing operation + * costs a lot more than the call overhead... + * + * \param entry [in] a float to store in the container + * \see Add(udword entry) + * \see Empty() + * \see Contains(udword entry) + * \return Self-Reference + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ Container& Add(float entry) + { + // Resize if needed + if (mCurNbEntries == mMaxNbEntries + && !Resize()) + { + IceAbort(); + } + + // Add new entry + mEntries[mCurNbEntries++] = IR(entry); + return *this; + } + + inline_ Container& Add(const float* entries, udword nb) + { + // Resize if needed + if (mCurNbEntries + nb > mMaxNbEntries + && !Resize(nb)) + { + IceAbort(); + } + + // Add new entry + CopyMemory(&mEntries[mCurNbEntries], entries, nb*sizeof(float)); + mCurNbEntries+=nb; + return *this; + } + + //! Add unique [slow] + inline_ Container& AddUnique(udword entry) + { + if(!Contains(entry)) Add(entry); + return *this; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Clears the container. All stored values are deleted, and it frees used ram. + * \see Reset() + * \return Self-Reference + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + Container& Empty(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Resets the container. Stored values are discarded but the buffer is kept so that further calls don't need resizing again. + * That's a kind of temporal coherence. + * \see Empty() + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void Reset() + { + // Avoid the write if possible + // ### CMOV + if(mCurNbEntries) mCurNbEntries = 0; + } + + // HANDLE WITH CARE + inline_ void ForceSize(udword size) + { + mCurNbEntries = size; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Sets the initial size of the container. If it already contains something, it's discarded. + * \param nb [in] Number of entries + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool SetSize(udword nb); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Refits the container and get rid of unused bytes. + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool Refit(); + + // Checks whether the container already contains a given value. + bool Contains(udword entry, udword* location=null) const; + // Deletes an entry - doesn't preserve insertion order. + bool Delete(udword entry); + // Deletes an entry - does preserve insertion order. + bool DeleteKeepingOrder(udword entry); + //! Deletes the very last entry. + inline_ void DeleteLastEntry() { if(mCurNbEntries) mCurNbEntries--; } + //! Deletes the entry whose index is given + inline_ void DeleteIndex(udword index) { ASSERT(index < mCurNbEntries); mEntries[index] = mEntries[--mCurNbEntries]; } + + // Helpers + Container& FindNext(udword& entry, FindMode find_mode=FIND_CLAMP); + Container& FindPrev(udword& entry, FindMode find_mode=FIND_CLAMP); + // Data access. + inline_ udword GetNbEntries() const { return mCurNbEntries; } //!< Returns the current number of entries. + inline_ udword GetEntry(udword i) const { return mEntries[i]; } //!< Returns ith entry + inline_ udword* GetEntries() const { return mEntries; } //!< Returns the list of entries. + + inline_ udword GetFirst() const { return mEntries[0]; } + inline_ udword GetLast() const { return mEntries[mCurNbEntries-1]; } + + // Growth control + inline_ udword GetGrowthFactor() const { return mGrowthFactor; } //!< Returns the growth factor + inline_ void SetGrowthFactor(udword growth) { mGrowthFactor = growth; } //!< Sets the growth factor + inline_ bool IsFull() const { return mCurNbEntries==mMaxNbEntries; } //!< Checks the container is full + inline_ BOOL IsNotEmpty() const { return mCurNbEntries; } //!< Checks the container is empty + + //! Read-access as an array + inline_ udword operator[](udword i) const { ASSERT(i>=0 && i<mCurNbEntries); return mEntries[i]; } + //! Write-access as an array + inline_ udword& operator[](udword i) { ASSERT(i>=0 && i<mCurNbEntries); return mEntries[i]; } + + // Stats + udword GetUsedRam() const; + + //! Operator for "Container A = Container B" + //void operator = (const Container& object); + +#ifdef CONTAINER_STATS + inline_ udword GetNbContainers() const { return mNbContainers; } + inline_ udword GetTotalBytes() const { return mUsedRam; } + private: + + static udword mNbContainers; //!< Number of containers around + static udword mUsedRam; //!< Amount of bytes used by containers in the system +#endif + private: + // Resizing + bool Resize(udword needed=1); + // Data + udword mMaxNbEntries; //!< Maximum possible number of entries + udword mCurNbEntries; //!< Current number of entries + udword* mEntries; //!< List of entries + udword mGrowthFactor; //!< Resize: new number of entries = old number * mGrowthFactor + }; + +#endif // __ICECONTAINER_H__ diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceFPU.h b/libs/ode-0.16.1/OPCODE/Ice/IceFPU.h new file mode 100644 index 0000000..e7ec3f5 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceFPU.h @@ -0,0 +1,282 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains FPU related code. + * \file IceFPU.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEFPU_H__ +#define __ICEFPU_H__ + + #define SIGN_BITMASK 0x80000000 + + namespace { + union float_udword { float f; udword u; }; + union float_sdword { float f; sdword s; }; + } + + + //! Integer representation of a floating-point value. + //#define IR(x) ((udword&)(x)) + static inline udword IR(float x) { float_udword fu; fu.f = x; return fu.u; } + + //! Signed integer representation of a floating-point value. + //#define SIR(x) ((sdword&)(x)) + static inline sdword SIR(float x) { float_sdword fs; fs.f = x; return fs.s; } + + //! Absolute integer representation of a floating-point value + #define AIR(x) (IR(x)&0x7fffffff) + + //! Floating-point representation of an integer value. + //#define FR(x) ((float&)(x)) + static inline float FR(unsigned x) { float_udword fu; fu.u = x; return fu.f; } + + //! Integer-based comparison of a floating point value. + //! Don't use it blindly, it can be faster or slower than the FPU comparison, depends on the context. + #define IS_NEGATIVE_FLOAT(x) (IR(x)&0x80000000) + + //! Fast fabs for floating-point values. It just clears the sign bit. + //! Don't use it blindy, it can be faster or slower than the FPU comparison, depends on the context. + inline_ float FastFabs(float x) + { + udword FloatBits = IR(x)&0x7fffffff; + return FR(FloatBits); + } + + //! Fast square root for floating-point values. + inline_ float FastSqrt(float square) + { + return sqrtf(square); + } + + //! Saturates positive to zero. + inline_ float fsat(float f) + { + udword y = IR(f) & ~(SIR(f) >>31); + return FR(y); + } + + //! Computes 1.0f / sqrtf(x). + inline_ float frsqrt(float f) + { + float x = f * 0.5f; + udword y = 0x5f3759df - (IR(f) >> 1); + // Iteration... + const float fy = FR(y); + const float result = fy * ( 1.5f - ( x * fy * fy ) ); + // Result + return result; + } + + //! Computes 1.0f / sqrtf(x). Comes from NVIDIA. + inline_ float InvSqrt(const float& x) + { + const udword tmp = (udword(IEEE_1_0 << 1) + IEEE_1_0 - IR(x)) >> 1; + const float y = FR(tmp); + return y * (1.47f - 0.47f * x * y * y); + } + + //! Computes 1.0f / sqrtf(x). Comes from Quake3. Looks like the first one I had above. + //! See http://www.magic-software.com/3DGEDInvSqrt.html + inline_ float RSqrt(float number) + { + int i; + float x2, y; + const float threehalfs = 1.5f; + + x2 = number * 0.5f; + y = number; + i = IR(y); + i = 0x5f3759df - (i >> 1); + y = FR(i); + y = y * (threehalfs - (x2 * y * y)); + + return y; + } + + //! TO BE DOCUMENTED + inline_ float fsqrt(float f) + { + udword y = ( ( SIR(f) - 0x3f800000 ) >> 1 ) + 0x3f800000; + // Iteration...? + // (float&)y = (3.0f - ((float&)y * (float&)y) / f) * (float&)y * 0.5f; + // Result + return FR(y); + } + + //! Returns the float ranged espilon value. + inline_ float fepsilon(float f) + { + udword b = IR(f) & 0xff800000; + udword a = b | 0x00000001; + // Result + return FR(a) - FR(b); + } + + //! Is the float valid ? + inline_ bool IsNAN(float value) { return (IR(value)&0x7f800000) == 0x7f800000; } + inline_ bool IsIndeterminate(float value) { return IR(value) == 0xffc00000; } + inline_ bool IsPlusInf(float value) { return IR(value) == 0x7f800000; } + inline_ bool IsMinusInf(float value) { return IR(value) == 0xff800000; } + + inline_ bool IsValidFloat(float value) + { + if(IsNAN(value)) return false; + if(IsIndeterminate(value)) return false; + if(IsPlusInf(value)) return false; + if(IsMinusInf(value)) return false; + return true; + } + + #define CHECK_VALID_FLOAT(x) ASSERT(IsValidFloat(x)); + +/* + //! FPU precision setting function. + inline_ void SetFPU() + { + // This function evaluates whether the floating-point + // control word is set to single precision/round to nearest/ + // exceptions disabled. If these conditions don't hold, the + // function changes the control word to set them and returns + // TRUE, putting the old control word value in the passback + // location pointed to by pwOldCW. + { + uword wTemp, wSave; + + __asm fstcw wSave + if (wSave & 0x300 || // Not single mode + 0x3f != (wSave & 0x3f) || // Exceptions enabled + wSave & 0xC00) // Not round to nearest mode + { + __asm + { + mov ax, wSave + and ax, not 300h ;; single mode + or ax, 3fh ;; disable all exceptions + and ax, not 0xC00 ;; round to nearest mode + mov wTemp, ax + fldcw wTemp + } + } + } + } +*/ + //! This function computes the slowest possible floating-point value (you can also directly use FLT_EPSILON) + inline_ float ComputeFloatEpsilon() + { + const float f = FR( IR(1.0f) ^ 1 ); + return f - 1.0f; // You can check it's the same as FLT_EPSILON + } + + inline_ bool IsFloatZero(float x, float epsilon=1e-6f) + { + return x*x < epsilon; + } + + #define FCOMI_ST0 _asm _emit 0xdb _asm _emit 0xf0 + #define FCOMIP_ST0 _asm _emit 0xdf _asm _emit 0xf0 + #define FCMOVB_ST0 _asm _emit 0xda _asm _emit 0xc0 + #define FCMOVNB_ST0 _asm _emit 0xdb _asm _emit 0xc0 + + #define FCOMI_ST1 _asm _emit 0xdb _asm _emit 0xf1 + #define FCOMIP_ST1 _asm _emit 0xdf _asm _emit 0xf1 + #define FCMOVB_ST1 _asm _emit 0xda _asm _emit 0xc1 + #define FCMOVNB_ST1 _asm _emit 0xdb _asm _emit 0xc1 + + #define FCOMI_ST2 _asm _emit 0xdb _asm _emit 0xf2 + #define FCOMIP_ST2 _asm _emit 0xdf _asm _emit 0xf2 + #define FCMOVB_ST2 _asm _emit 0xda _asm _emit 0xc2 + #define FCMOVNB_ST2 _asm _emit 0xdb _asm _emit 0xc2 + + #define FCOMI_ST3 _asm _emit 0xdb _asm _emit 0xf3 + #define FCOMIP_ST3 _asm _emit 0xdf _asm _emit 0xf3 + #define FCMOVB_ST3 _asm _emit 0xda _asm _emit 0xc3 + #define FCMOVNB_ST3 _asm _emit 0xdb _asm _emit 0xc3 + + #define FCOMI_ST4 _asm _emit 0xdb _asm _emit 0xf4 + #define FCOMIP_ST4 _asm _emit 0xdf _asm _emit 0xf4 + #define FCMOVB_ST4 _asm _emit 0xda _asm _emit 0xc4 + #define FCMOVNB_ST4 _asm _emit 0xdb _asm _emit 0xc4 + + #define FCOMI_ST5 _asm _emit 0xdb _asm _emit 0xf5 + #define FCOMIP_ST5 _asm _emit 0xdf _asm _emit 0xf5 + #define FCMOVB_ST5 _asm _emit 0xda _asm _emit 0xc5 + #define FCMOVNB_ST5 _asm _emit 0xdb _asm _emit 0xc5 + + #define FCOMI_ST6 _asm _emit 0xdb _asm _emit 0xf6 + #define FCOMIP_ST6 _asm _emit 0xdf _asm _emit 0xf6 + #define FCMOVB_ST6 _asm _emit 0xda _asm _emit 0xc6 + #define FCMOVNB_ST6 _asm _emit 0xdb _asm _emit 0xc6 + + #define FCOMI_ST7 _asm _emit 0xdb _asm _emit 0xf7 + #define FCOMIP_ST7 _asm _emit 0xdf _asm _emit 0xf7 + #define FCMOVB_ST7 _asm _emit 0xda _asm _emit 0xc7 + #define FCMOVNB_ST7 _asm _emit 0xdb _asm _emit 0xc7 + + //! A global function to find MAX(a,b) using FCOMI/FCMOV + inline_ float FCMax2(float a, float b) + { + return (a > b) ? a : b; + } + + //! A global function to find MIN(a,b) using FCOMI/FCMOV + inline_ float FCMin2(float a, float b) + { + return (a < b) ? a : b; + } + + //! A global function to find MAX(a,b,c) using FCOMI/FCMOV + inline_ float FCMax3(float a, float b, float c) + { + return (a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c); + } + + //! A global function to find MIN(a,b,c) using FCOMI/FCMOV + inline_ float FCMin3(float a, float b, float c) + { + return (a < b) ? ((a < c) ? a : c) : ((b < c) ? b : c); + } + + inline_ int ConvertToSortable(float f) + { + int Fi = SIR(f); + int Fmask = (Fi>>31); + Fi ^= Fmask; + Fmask &= ~(1<<31); + Fi -= Fmask; + return Fi; + } + + enum FPUMode + { + FPU_FLOOR = 0, + FPU_CEIL = 1, + FPU_BEST = 2, + + FPU_FORCE_DWORD = 0x7fffffff + }; + + FUNCTION ICECORE_API FPUMode GetFPUMode(); + FUNCTION ICECORE_API void SaveFPU(); + FUNCTION ICECORE_API void RestoreFPU(); + FUNCTION ICECORE_API void SetFPUFloorMode(); + FUNCTION ICECORE_API void SetFPUCeilMode(); + FUNCTION ICECORE_API void SetFPUBestMode(); + + FUNCTION ICECORE_API void SetFPUPrecision24(); + FUNCTION ICECORE_API void SetFPUPrecision53(); + FUNCTION ICECORE_API void SetFPUPrecision64(); + FUNCTION ICECORE_API void SetFPURoundingChop(); + FUNCTION ICECORE_API void SetFPURoundingUp(); + FUNCTION ICECORE_API void SetFPURoundingDown(); + FUNCTION ICECORE_API void SetFPURoundingNear(); + + FUNCTION ICECORE_API int intChop(const float& f); + FUNCTION ICECORE_API int intFloor(const float& f); + FUNCTION ICECORE_API int intCeil(const float& f); + +#endif // __ICEFPU_H__ diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceHPoint.cpp b/libs/ode-0.16.1/OPCODE/Ice/IceHPoint.cpp new file mode 100644 index 0000000..f806a0c --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceHPoint.cpp @@ -0,0 +1,70 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for homogeneous points. + * \file IceHPoint.cpp + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Homogeneous point. + * + * Use it: + * - for clipping in homogeneous space (standard way) + * - to differentiate between points (w=1) and vectors (w=0). + * - in some cases you can also use it instead of Point for padding reasons. + * + * \class HPoint + * \author Pierre Terdiman + * \version 1.0 + * \warning No cross-product in 4D. + * \warning HPoint *= Matrix3x3 doesn't exist, the matrix is first casted to a 4x4 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace IceMaths; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Point Mul = HPoint * Matrix3x3; +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Point HPoint::operator*(const Matrix3x3& mat) const +{ + return Point( + x * mat.m[0][0] + y * mat.m[1][0] + z * mat.m[2][0], + x * mat.m[0][1] + y * mat.m[1][1] + z * mat.m[2][1], + x * mat.m[0][2] + y * mat.m[1][2] + z * mat.m[2][2] ); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// HPoint Mul = HPoint * Matrix4x4; +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HPoint HPoint::operator*(const Matrix4x4& mat) const +{ + return HPoint( + x * mat.m[0][0] + y * mat.m[1][0] + z * mat.m[2][0] + w * mat.m[3][0], + x * mat.m[0][1] + y * mat.m[1][1] + z * mat.m[2][1] + w * mat.m[3][1], + x * mat.m[0][2] + y * mat.m[1][2] + z * mat.m[2][2] + w * mat.m[3][2], + x * mat.m[0][3] + y * mat.m[1][3] + z * mat.m[2][3] + w * mat.m[3][3]); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// HPoint *= Matrix4x4 +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HPoint& HPoint::operator*=(const Matrix4x4& mat) +{ + float xp = x * mat.m[0][0] + y * mat.m[1][0] + z * mat.m[2][0] + w * mat.m[3][0]; + float yp = x * mat.m[0][1] + y * mat.m[1][1] + z * mat.m[2][1] + w * mat.m[3][1]; + float zp = x * mat.m[0][2] + y * mat.m[1][2] + z * mat.m[2][2] + w * mat.m[3][2]; + float wp = x * mat.m[0][3] + y * mat.m[1][3] + z * mat.m[2][3] + w * mat.m[3][3]; + + x = xp; y = yp; z = zp; w = wp; + + return *this; +} + diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceHPoint.h b/libs/ode-0.16.1/OPCODE/Ice/IceHPoint.h new file mode 100644 index 0000000..a3770cd --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceHPoint.h @@ -0,0 +1,160 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for homogeneous points. + * \file IceHPoint.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEHPOINT_H__ +#define __ICEHPOINT_H__ + + class ICEMATHS_API HPoint : public Point + { + public: + + //! Empty constructor + inline_ HPoint() {} + //! Constructor from floats + inline_ HPoint(float xx, float yy, float zz, float ww=0.0f) : Point(xx, yy, zz), w(ww) {} + //! Constructor from array + inline_ HPoint(const float f[4]) : Point(f), w(f[3]) {} + //! Constructor from a Point + inline_ HPoint(const Point& p, float ww=0.0f) : Point(p), w(ww) {} + //! Destructor + inline_ ~HPoint() {} + + //! Clear the point + inline_ HPoint& Zero() { x = y = z = w = 0.0f; return *this; } + + //! Assignment from values + inline_ HPoint& Set(float xx, float yy, float zz, float ww ) { x = xx; y = yy; z = zz; w = ww; return *this; } + //! Assignment from array + inline_ HPoint& Set(const float f[4]) { x = f[X]; y = f[Y]; z = f[Z]; w = f[W]; return *this; } + //! Assignment from another h-point + inline_ HPoint& Set(const HPoint& src) { x = src.x; y = src.y; z = src.z; w = src.w; return *this; } + + //! Add a vector + inline_ HPoint& Add(float xx, float yy, float zz, float ww ) { x += xx; y += yy; z += zz; w += ww; return *this; } + //! Add a vector + inline_ HPoint& Add(const float f[4]) { x += f[X]; y += f[Y]; z += f[Z]; w += f[W]; return *this; } + + //! Subtract a vector + inline_ HPoint& Sub(float xx, float yy, float zz, float ww ) { x -= xx; y -= yy; z -= zz; w -= ww; return *this; } + //! Subtract a vector + inline_ HPoint& Sub(const float f[4]) { x -= f[X]; y -= f[Y]; z -= f[Z]; w -= f[W]; return *this; } + + //! Multiplies by a scalar + inline_ HPoint& Mul(float s) { x *= s; y *= s; z *= s; w *= s; return *this; } + + //! Returns MIN(x, y, z, w); + float Min() const { return MIN(x, MIN(y, MIN(z, w))); } + //! Returns MAX(x, y, z, w); + float Max() const { return MAX(x, MAX(y, MAX(z, w))); } + //! Sets each element to be componentwise minimum + HPoint& Min(const HPoint& p) { x = MIN(x, p.x); y = MIN(y, p.y); z = MIN(z, p.z); w = MIN(w, p.w); return *this; } + //! Sets each element to be componentwise maximum + HPoint& Max(const HPoint& p) { x = MAX(x, p.x); y = MAX(y, p.y); z = MAX(z, p.z); w = MAX(w, p.w); return *this; } + + //! Computes square magnitude + inline_ float SquareMagnitude() const { return x*x + y*y + z*z + w*w; } + //! Computes magnitude + inline_ float Magnitude() const { return sqrtf(x*x + y*y + z*z + w*w); } + + //! Normalize the vector + inline_ HPoint& Normalize() + { + float M = Magnitude(); + if(M) + { + M = 1.0f / M; + x *= M; + y *= M; + z *= M; + w *= M; + } + return *this; + } + + // Arithmetic operators + //! Operator for HPoint Negate = - HPoint; + inline_ HPoint operator-() const { return HPoint(-x, -y, -z, -w); } + + //! Operator for HPoint Plus = HPoint + HPoint; + inline_ HPoint operator+(const HPoint& p) const { return HPoint(x + p.x, y + p.y, z + p.z, w + p.w); } + //! Operator for HPoint Minus = HPoint - HPoint; + inline_ HPoint operator-(const HPoint& p) const { return HPoint(x - p.x, y - p.y, z - p.z, w - p.w); } + + //! Operator for HPoint Mul = HPoint * HPoint; + inline_ HPoint operator*(const HPoint& p) const { return HPoint(x * p.x, y * p.y, z * p.z, w * p.w); } + //! Operator for HPoint Scale = HPoint * float; + inline_ HPoint operator*(float s) const { return HPoint(x * s, y * s, z * s, w * s); } + //! Operator for HPoint Scale = float * HPoint; + inline_ friend HPoint operator*(float s, const HPoint& p) { return HPoint(s * p.x, s * p.y, s * p.z, s * p.w); } + + //! Operator for HPoint Div = HPoint / HPoint; + inline_ HPoint operator/(const HPoint& p) const { return HPoint(x / p.x, y / p.y, z / p.z, w / p.w); } + //! Operator for HPoint Scale = HPoint / float; + inline_ HPoint operator/(float s) const { s = 1.0f / s; return HPoint(x * s, y * s, z * s, w * s); } + //! Operator for HPoint Scale = float / HPoint; + inline_ friend HPoint operator/(float s, const HPoint& p) { return HPoint(s / p.x, s / p.y, s / p.z, s / p.w); } + + //! Operator for float DotProd = HPoint | HPoint; + inline_ float operator|(const HPoint& p) const { return x*p.x + y*p.y + z*p.z + w*p.w; } + // No cross-product in 4D + + //! Operator for HPoint += HPoint; + inline_ HPoint& operator+=(const HPoint& p) { x += p.x; y += p.y; z += p.z; w += p.w; return *this; } + //! Operator for HPoint += float; + inline_ HPoint& operator+=(float s) { x += s; y += s; z += s; w += s; return *this; } + + //! Operator for HPoint -= HPoint; + inline_ HPoint& operator-=(const HPoint& p) { x -= p.x; y -= p.y; z -= p.z; w -= p.w; return *this; } + //! Operator for HPoint -= float; + inline_ HPoint& operator-=(float s) { x -= s; y -= s; z -= s; w -= s; return *this; } + + //! Operator for HPoint *= HPoint; + inline_ HPoint& operator*=(const HPoint& p) { x *= p.x; y *= p.y; z *= p.z; w *= p.w; return *this; } + //! Operator for HPoint *= float; + inline_ HPoint& operator*=(float s) { x*=s; y*=s; z*=s; w*=s; return *this; } + + //! Operator for HPoint /= HPoint; + inline_ HPoint& operator/=(const HPoint& p) { x /= p.x; y /= p.y; z /= p.z; w /= p.w; return *this; } + //! Operator for HPoint /= float; + inline_ HPoint& operator/=(float s) { s = 1.0f / s; x*=s; y*=s; z*=s; w*=s; return *this; } + + // Arithmetic operators + + //! Operator for Point Mul = HPoint * Matrix3x3; + Point operator*(const Matrix3x3& mat) const; + //! Operator for HPoint Mul = HPoint * Matrix4x4; + HPoint operator*(const Matrix4x4& mat) const; + + // HPoint *= Matrix3x3 doesn't exist, the matrix is first casted to a 4x4 + //! Operator for HPoint *= Matrix4x4 + HPoint& operator*=(const Matrix4x4& mat); + + // Logical operators + + //! Operator for "if(HPoint==HPoint)" + inline_ bool operator==(const HPoint& p) const { return ( (x==p.x)&&(y==p.y)&&(z==p.z)&&(w==p.w)); } + //! Operator for "if(HPoint!=HPoint)" + inline_ bool operator!=(const HPoint& p) const { return ( (x!=p.x)||(y!=p.y)||(z!=p.z)||(w!=p.w)); } + + // Cast operators + + //! Cast a HPoint to a Point. w is discarded. +#ifdef _MSC_VER + inline_ operator Point() const { return Point(x, y, z); } + // gcc complains that conversion to a base class will never use a type conversion operator +#endif + + public: + float w; + }; + +#endif // __ICEHPOINT_H__ + diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceIndexedTriangle.cpp b/libs/ode-0.16.1/OPCODE/Ice/IceIndexedTriangle.cpp new file mode 100644 index 0000000..d317113 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceIndexedTriangle.cpp @@ -0,0 +1,548 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a handy indexed triangle class. + * \file IceIndexedTriangle.cpp + * \author Pierre Terdiman + * \date January, 17, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace IceMaths; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains an indexed triangle class. + * + * \class Triangle + * \author Pierre Terdiman + * \version 1.0 + * \date 08.15.98 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Flips the winding order. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void IndexedTriangle::Flip() +{ + Swap(mVRef[1], mVRef[2]); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle area. + * \param verts [in] the list of indexed vertices + * \return the area + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float IndexedTriangle::Area(const Point* verts) const +{ + if(!verts) return 0.0f; + const Point& p0 = verts[0]; + const Point& p1 = verts[1]; + const Point& p2 = verts[2]; + return ((p0-p1)^(p0-p2)).Magnitude() * 0.5f; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle perimeter. + * \param verts [in] the list of indexed vertices + * \return the perimeter + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float IndexedTriangle::Perimeter(const Point* verts) const +{ + if(!verts) return 0.0f; + const Point& p0 = verts[0]; + const Point& p1 = verts[1]; + const Point& p2 = verts[2]; + return p0.Distance(p1) + + p0.Distance(p2) + + p1.Distance(p2); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle compacity. + * \param verts [in] the list of indexed vertices + * \return the compacity + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float IndexedTriangle::Compacity(const Point* verts) const +{ + if(!verts) return 0.0f; + float P = Perimeter(verts); + if(P==0.0f) return 0.0f; + return (4.0f*PI*Area(verts)/(P*P)); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle normal. + * \param verts [in] the list of indexed vertices + * \param normal [out] the computed normal + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void IndexedTriangle::Normal(const Point* verts, Point& normal) const +{ + if(!verts) return; + + const Point& p0 = verts[mVRef[0]]; + const Point& p1 = verts[mVRef[1]]; + const Point& p2 = verts[mVRef[2]]; + normal = ((p2-p1)^(p0-p1)).Normalize(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle denormalized normal. + * \param verts [in] the list of indexed vertices + * \param normal [out] the computed normal + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void IndexedTriangle::DenormalizedNormal(const Point* verts, Point& normal) const +{ + if(!verts) return; + + const Point& p0 = verts[mVRef[0]]; + const Point& p1 = verts[mVRef[1]]; + const Point& p2 = verts[mVRef[2]]; + normal = ((p2-p1)^(p0-p1)); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle center. + * \param verts [in] the list of indexed vertices + * \param center [out] the computed center + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void IndexedTriangle::Center(const Point* verts, Point& center) const +{ + if(!verts) return; + + const Point& p0 = verts[mVRef[0]]; + const Point& p1 = verts[mVRef[1]]; + const Point& p2 = verts[mVRef[2]]; + center = (p0+p1+p2)*INV3; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the centered normal + * \param verts [in] the list of indexed vertices + * \param normal [out] the computed centered normal + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void IndexedTriangle::CenteredNormal(const Point* verts, Point& normal) const +{ + if(!verts) return; + + const Point& p0 = verts[mVRef[0]]; + const Point& p1 = verts[mVRef[1]]; + const Point& p2 = verts[mVRef[2]]; + Point Center = (p0+p1+p2)*INV3; + normal = Center + ((p2-p1)^(p0-p1)).Normalize(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes a random point within the triangle. + * \param verts [in] the list of indexed vertices + * \param normal [out] the computed centered normal + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void IndexedTriangle::RandomPoint(const Point* verts, Point& random) const +{ + if(!verts) return; + + // Random barycentric coords + float Alpha = UnitRandomFloat(); + float Beta = UnitRandomFloat(); + float Gamma = UnitRandomFloat(); + float OneOverTotal = 1.0f / (Alpha + Beta + Gamma); + Alpha *= OneOverTotal; + Beta *= OneOverTotal; + Gamma *= OneOverTotal; + + const Point& p0 = verts[mVRef[0]]; + const Point& p1 = verts[mVRef[1]]; + const Point& p2 = verts[mVRef[2]]; + random = Alpha*p0 + Beta*p1 + Gamma*p2; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes backface culling. + * \param verts [in] the list of indexed vertices + * \param source [in] source point (in local space) from which culling must be computed + * \return true if the triangle is visible from the source point + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool IndexedTriangle::IsVisible(const Point* verts, const Point& source) const +{ + // Checkings + if(!verts) return false; + + const Point& p0 = verts[mVRef[0]]; + const Point& p1 = verts[mVRef[1]]; + const Point& p2 = verts[mVRef[2]]; + + // Compute denormalized normal + Point Normal = (p2 - p1)^(p0 - p1); + + // Backface culling + return (Normal | source) >= 0.0f; + +// Same as: +// Plane PL(verts[mVRef[0]], verts[mVRef[1]], verts[mVRef[2]]); +// return PL.Distance(source) > PL.d; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes backface culling. + * \param verts [in] the list of indexed vertices + * \param source [in] source point (in local space) from which culling must be computed + * \return true if the triangle is visible from the source point + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool IndexedTriangle::BackfaceCulling(const Point* verts, const Point& source) const +{ + // Checkings + if(!verts) return false; + + const Point& p0 = verts[mVRef[0]]; + const Point& p1 = verts[mVRef[1]]; + const Point& p2 = verts[mVRef[2]]; + + // Compute base +// Point Base = (p0 + p1 + p2)*INV3; + + // Compute denormalized normal + Point Normal = (p2 - p1)^(p0 - p1); + + // Backface culling +// return (Normal | (source - Base)) >= 0.0f; + return (Normal | (source - p0)) >= 0.0f; + +// Same as: (but a bit faster) +// Plane PL(verts[mVRef[0]], verts[mVRef[1]], verts[mVRef[2]]); +// return PL.Distance(source)>0.0f; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the occlusion potential of the triangle. + * \param verts [in] the list of indexed vertices + * \param source [in] source point (in local space) from which occlusion potential must be computed + * \return the occlusion potential + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float IndexedTriangle::ComputeOcclusionPotential(const Point* verts, const Point& view) const +{ + if(!verts) return 0.0f; + // Occlusion potential: -(A * (N|V) / d^2) + // A = polygon area + // N = polygon normal + // V = view vector + // d = distance viewpoint-center of polygon + + float A = Area(verts); + Point N; Normal(verts, N); + Point C; Center(verts, C); + float d = view.Distance(C); + return -(A*(N|view))/(d*d); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Replaces a vertex reference with another one. + * \param oldref [in] the vertex reference to replace + * \param newref [in] the new vertex reference + * \return true if success, else false if the input vertex reference doesn't belong to the triangle + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool IndexedTriangle::ReplaceVertex(dTriIndex oldref, dTriIndex newref) +{ + if(mVRef[0]==oldref) { mVRef[0] = newref; return true; } + else if(mVRef[1]==oldref) { mVRef[1] = newref; return true; } + else if(mVRef[2]==oldref) { mVRef[2] = newref; return true; } + return false; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks whether the triangle is degenerate or not. A degenerate triangle has two common vertex references. This is a zero-area triangle. + * \return true if the triangle is degenerate + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool IndexedTriangle::IsDegenerate() const +{ + if(mVRef[0]==mVRef[1]) return true; + if(mVRef[1]==mVRef[2]) return true; + if(mVRef[2]==mVRef[0]) return true; + return false; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks whether the input vertex reference belongs to the triangle or not. + * \param ref [in] the vertex reference to look for + * \return true if the triangle contains the vertex reference + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool IndexedTriangle::HasVertex(dTriIndex ref) const +{ + if(mVRef[0]==ref) return true; + if(mVRef[1]==ref) return true; + if(mVRef[2]==ref) return true; + return false; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks whether the input vertex reference belongs to the triangle or not. + * \param ref [in] the vertex reference to look for + * \param index [out] the corresponding index in the triangle + * \return true if the triangle contains the vertex reference + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool IndexedTriangle::HasVertex(dTriIndex ref, dTriIndex* index) const +{ + if(mVRef[0]==ref) { *index = 0; return true; } + if(mVRef[1]==ref) { *index = 1; return true; } + if(mVRef[2]==ref) { *index = 2; return true; } + return false; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Finds an edge in a tri, given two vertex references. + * \param vref0 [in] the edge's first vertex reference + * \param vref1 [in] the edge's second vertex reference + * \return the edge number between 0 and 2, or 0xff if input refs are wrong. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +ubyte IndexedTriangle::FindEdge(dTriIndex vref0, dTriIndex vref1) const +{ + if(mVRef[0]==vref0 && mVRef[1]==vref1) return 0; + else if(mVRef[0]==vref1 && mVRef[1]==vref0) return 0; + else if(mVRef[0]==vref0 && mVRef[2]==vref1) return 1; + else if(mVRef[0]==vref1 && mVRef[2]==vref0) return 1; + else if(mVRef[1]==vref0 && mVRef[2]==vref1) return 2; + else if(mVRef[1]==vref1 && mVRef[2]==vref0) return 2; + return 0xff; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Gets the last reference given the first two. + * \param vref0 [in] the first vertex reference + * \param vref1 [in] the second vertex reference + * \return the last reference, or INVALID_ID if input refs are wrong. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +dTriIndex IndexedTriangle::OppositeVertex(dTriIndex vref0, dTriIndex vref1) const +{ + if(mVRef[0]==vref0 && mVRef[1]==vref1) return mVRef[2]; + else if(mVRef[0]==vref1 && mVRef[1]==vref0) return mVRef[2]; + else if(mVRef[0]==vref0 && mVRef[2]==vref1) return mVRef[1]; + else if(mVRef[0]==vref1 && mVRef[2]==vref0) return mVRef[1]; + else if(mVRef[1]==vref0 && mVRef[2]==vref1) return mVRef[0]; + else if(mVRef[1]==vref1 && mVRef[2]==vref0) return mVRef[0]; + return (dTriIndex)INVALID_ID; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Gets the three sorted vertex references according to an edge number. + * edgenb = 0 => edge 0-1, returns references 0, 1, 2 + * edgenb = 1 => edge 0-2, returns references 0, 2, 1 + * edgenb = 2 => edge 1-2, returns references 1, 2, 0 + * + * \param edgenb [in] the edge number, 0, 1 or 2 + * \param vref0 [out] the returned first vertex reference + * \param vref1 [out] the returned second vertex reference + * \param vref2 [out] the returned third vertex reference + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void IndexedTriangle::GetVRefs(ubyte edgenb, dTriIndex& vref0, dTriIndex& vref1, dTriIndex& vref2) const +{ + if(edgenb==0) + { + vref0 = mVRef[0]; + vref1 = mVRef[1]; + vref2 = mVRef[2]; + } + else if(edgenb==1) + { + vref0 = mVRef[0]; + vref1 = mVRef[2]; + vref2 = mVRef[1]; + } + else if(edgenb==2) + { + vref0 = mVRef[1]; + vref1 = mVRef[2]; + vref2 = mVRef[0]; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle's smallest edge length. + * \param verts [in] the list of indexed vertices + * \return the smallest edge length + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float IndexedTriangle::MinEdgeLength(const Point* verts) const +{ + if(!verts) return 0.0f; + + float Min = MAX_FLOAT; + float Length01 = verts[0].Distance(verts[1]); + float Length02 = verts[0].Distance(verts[2]); + float Length12 = verts[1].Distance(verts[2]); + if(Length01 < Min) Min = Length01; + if(Length02 < Min) Min = Length02; + if(Length12 < Min) Min = Length12; + return Min; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle's largest edge length. + * \param verts [in] the list of indexed vertices + * \return the largest edge length + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float IndexedTriangle::MaxEdgeLength(const Point* verts) const +{ + if(!verts) return 0.0f; + + float Max = MIN_FLOAT; + float Length01 = verts[0].Distance(verts[1]); + float Length02 = verts[0].Distance(verts[2]); + float Length12 = verts[1].Distance(verts[2]); + if(Length01 > Max) Max = Length01; + if(Length02 > Max) Max = Length02; + if(Length12 > Max) Max = Length12; + return Max; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes a point on the triangle according to the stabbing information. + * \param verts [in] the list of indexed vertices + * \param u,v [in] point's barycentric coordinates + * \param pt [out] point on triangle + * \param nearvtx [out] index of nearest vertex + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void IndexedTriangle::ComputePoint(const Point* verts, float u, float v, Point& pt, dTriIndex* nearvtx) const +{ + // Checkings + if(!verts) return; + + // Get face in local or global space + const Point& p0 = verts[mVRef[0]]; + const Point& p1 = verts[mVRef[1]]; + const Point& p2 = verts[mVRef[2]]; + + // Compute point coordinates + pt = (1.0f - u - v)*p0 + u*p1 + v*p2; + + // Compute nearest vertex if needed + if(nearvtx) + { + // Compute distance vector + Point d(p0.SquareDistance(pt), // Distance^2 from vertex 0 to point on the face + p1.SquareDistance(pt), // Distance^2 from vertex 1 to point on the face + p2.SquareDistance(pt)); // Distance^2 from vertex 2 to point on the face + + // Get smallest distance + *nearvtx = mVRef[d.SmallestAxis()]; + } +} + + //************************************** + // Angle between two vectors (in radians) + // we use this formula + // uv = |u||v| cos(u,v) + // u ^ v = w + // |w| = |u||v| |sin(u,v)| + //************************************** + float Angle(const Point& u, const Point& v) + { + float NormU = u.Magnitude(); // |u| + float NormV = v.Magnitude(); // |v| + float Product = NormU*NormV; // |u||v| + if(Product==0.0f) return 0.0f; + float OneOverProduct = 1.0f / Product; + + // Cosinus + float Cosinus = (u|v) * OneOverProduct; + + // Sinus + Point w = u^v; + float NormW = w.Magnitude(); + + float AbsSinus = NormW * OneOverProduct; + + // Remove degeneracy + if(AbsSinus > 1.0f) AbsSinus = 1.0f; + if(AbsSinus < -1.0f) AbsSinus = -1.0f; + + if(Cosinus>=0.0f) return asinf(AbsSinus); + else return (PI-asinf(AbsSinus)); + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the angle between two triangles. + * \param tri [in] the other triangle + * \param verts [in] the list of indexed vertices + * \return the angle in radians + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float IndexedTriangle::Angle(const IndexedTriangle& tri, const Point* verts) const +{ + // Checkings + if(!verts) return 0.0f; + + // Compute face normals + Point n0, n1; + Normal(verts, n0); + tri.Normal(verts, n1); + + // Compute angle + float dp = n0|n1; + if(dp>1.0f) return 0.0f; + if(dp<-1.0f) return PI; + return acosf(dp); + +// return ::Angle(n0,n1); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks a triangle is the same as another one. + * \param tri [in] the other triangle + * \return true if same triangle + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool IndexedTriangle::Equal(const IndexedTriangle& tri) const +{ + // Test all vertex references + return (HasVertex(tri.mVRef[0]) && + HasVertex(tri.mVRef[1]) && + HasVertex(tri.mVRef[2])); +} diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceIndexedTriangle.h b/libs/ode-0.16.1/OPCODE/Ice/IceIndexedTriangle.h new file mode 100644 index 0000000..d545e41 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceIndexedTriangle.h @@ -0,0 +1,76 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a handy indexed triangle class. + * \file IceIndexedTriangle.h + * \author Pierre Terdiman + * \date January, 17, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "ode/common.h" + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEINDEXEDTRIANGLE_H__ +#define __ICEINDEXEDTRIANGLE_H__ + + // Forward declarations +#ifdef _MSC_VER + enum CubeIndex; +#else + typedef int CubeIndex; +#endif + + // An indexed triangle class. + class ICEMATHS_API IndexedTriangle + { + public: + + //! Constructor + inline_ IndexedTriangle() {} + //! Constructor + inline_ IndexedTriangle(dTriIndex r0, dTriIndex r1, dTriIndex r2) { mVRef[0]=r0; mVRef[1]=r1; mVRef[2]=r2; } + //! Copy constructor + inline_ IndexedTriangle(const IndexedTriangle& triangle) + { + mVRef[0] = triangle.mVRef[0]; + mVRef[1] = triangle.mVRef[1]; + mVRef[2] = triangle.mVRef[2]; + } + //! Destructor + inline_ ~IndexedTriangle() {} + + //! Vertex-references + dTriIndex mVRef[3]; + + // Methods + void Flip(); + float Area(const Point* verts) const; + float Perimeter(const Point* verts) const; + float Compacity(const Point* verts) const; + void Normal(const Point* verts, Point& normal) const; + void DenormalizedNormal(const Point* verts, Point& normal) const; + void Center(const Point* verts, Point& center) const; + void CenteredNormal(const Point* verts, Point& normal) const; + void RandomPoint(const Point* verts, Point& random) const; + bool IsVisible(const Point* verts, const Point& source) const; + bool BackfaceCulling(const Point* verts, const Point& source) const; + float ComputeOcclusionPotential(const Point* verts, const Point& view) const; + bool ReplaceVertex(dTriIndex oldref, dTriIndex newref); + bool IsDegenerate() const; + bool HasVertex(dTriIndex ref) const; + bool HasVertex(dTriIndex ref, dTriIndex* index) const; + ubyte FindEdge(dTriIndex vref0, dTriIndex vref1) const; + dTriIndex OppositeVertex(dTriIndex vref0, dTriIndex vref1) const; + inline_ dTriIndex OppositeVertex(ubyte edgenb) const { return mVRef[2-edgenb]; } + void GetVRefs(ubyte edgenb, dTriIndex& vref0, dTriIndex& vref1, dTriIndex& vref2) const; + float MinEdgeLength(const Point* verts) const; + float MaxEdgeLength(const Point* verts) const; + void ComputePoint(const Point* verts, float u, float v, Point& pt, dTriIndex* nearvtx=null) const; + float Angle(const IndexedTriangle& tri, const Point* verts) const; + inline_ Plane PlaneEquation(const Point* verts) const { return Plane(verts[mVRef[0]], verts[mVRef[1]], verts[mVRef[2]]); } + bool Equal(const IndexedTriangle& tri) const; + CubeIndex ComputeCubeIndex(const Point* verts) const; + }; + +#endif // __ICEINDEXEDTRIANGLE_H__ diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceLSS.h b/libs/ode-0.16.1/OPCODE/Ice/IceLSS.h new file mode 100644 index 0000000..bd260c1 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceLSS.h @@ -0,0 +1,75 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for line-swept spheres. + * \file IceLSS.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICELSS_H__ +#define __ICELSS_H__ + + class ICEMATHS_API LSS : public Segment + { + public: + //! Constructor + inline_ LSS() {} + //! Constructor + inline_ LSS(const Segment& seg, float radius) : Segment(seg), mRadius(radius) {} + //! Destructor + inline_ ~LSS() {} + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes an OBB surrounding the LSS. + * \param box [out] the OBB + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void ComputeOBB(OBB& box); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Tests if a point is contained within the LSS. + * \param pt [in] the point to test + * \return true if inside the LSS + * \warning point and LSS must be in same space + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ bool Contains(const Point& pt) const { return SquareDistance(pt) <= mRadius*mRadius; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Tests if a sphere is contained within the LSS. + * \param sphere [in] the sphere to test + * \return true if inside the LSS + * \warning sphere and LSS must be in same space + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ bool Contains(const Sphere& sphere) + { + float d = mRadius - sphere.mRadius; + if(d>=0.0f) return SquareDistance(sphere.mCenter) <= d*d; + else return false; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Tests if an LSS is contained within the LSS. + * \param lss [in] the LSS to test + * \return true if inside the LSS + * \warning both LSS must be in same space + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ bool Contains(const LSS& lss) + { + // We check the LSS contains the two spheres at the start and end of the sweep + return Contains(Sphere(lss.mP0, lss.mRadius)) && Contains(Sphere(lss.mP0, lss.mRadius)); + } + + float mRadius; //!< Sphere radius + }; + +#endif // __ICELSS_H__ diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceMatrix3x3.cpp b/libs/ode-0.16.1/OPCODE/Ice/IceMatrix3x3.cpp new file mode 100644 index 0000000..af56d3e --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceMatrix3x3.cpp @@ -0,0 +1,48 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for 3x3 matrices. + * \file IceMatrix3x3.cpp + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * 3x3 matrix. + * DirectX-compliant, ie row-column order, ie m[Row][Col]. + * Same as: + * m11 m12 m13 first row. + * m21 m22 m23 second row. + * m31 m32 m33 third row. + * Stored in memory as m11 m12 m13 m21... + * + * Multiplication rules: + * + * [x'y'z'] = [xyz][M] + * + * x' = x*m11 + y*m21 + z*m31 + * y' = x*m12 + y*m22 + z*m32 + * z' = x*m13 + y*m23 + z*m33 + * + * \class Matrix3x3 + * \author Pierre Terdiman + * \version 1.0 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace IceMaths; + +// Cast operator +Matrix3x3::operator Matrix4x4() const +{ + return Matrix4x4( + m[0][0], m[0][1], m[0][2], 0.0f, + m[1][0], m[1][1], m[1][2], 0.0f, + m[2][0], m[2][1], m[2][2], 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f); +} diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceMatrix3x3.h b/libs/ode-0.16.1/OPCODE/Ice/IceMatrix3x3.h new file mode 100644 index 0000000..e3b950f --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceMatrix3x3.h @@ -0,0 +1,499 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for 3x3 matrices. + * \file IceMatrix3x3.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEMATRIX3X3_H__ +#define __ICEMATRIX3X3_H__ + + // Forward declarations + class Quat; + + #define MATRIX3X3_EPSILON (1.0e-7f) + + class ICEMATHS_API Matrix3x3 + { + public: + //! Empty constructor + inline_ Matrix3x3() {} + //! Constructor from 9 values + inline_ Matrix3x3(float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22) + { + m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; + m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; + m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; + } + //! Copy constructor + inline_ Matrix3x3(const Matrix3x3& mat) { CopyMemory(m, &mat.m, 9*sizeof(float)); } + //! Destructor + inline_ ~Matrix3x3() {} + + //! Assign values + template<typename trotationfloat> + inline_ void Set(trotationfloat m00, trotationfloat m01, trotationfloat m02, + trotationfloat m10, trotationfloat m11, trotationfloat m12, + trotationfloat m20, trotationfloat m21, trotationfloat m22) + { + m[0][0] = (float)m00; m[0][1] = (float)m01; m[0][2] = (float)m02; + m[1][0] = (float)m10; m[1][1] = (float)m11; m[1][2] = (float)m12; + m[2][0] = (float)m20; m[2][1] = (float)m21; m[2][2] = (float)m22; + } + + //! Sets the scale from a Point. The point is put on the diagonal. + inline_ void SetScale(const Point& p) { m[0][0] = p.x; m[1][1] = p.y; m[2][2] = p.z; } + + //! Sets the scale from floats. Values are put on the diagonal. + inline_ void SetScale(float sx, float sy, float sz) { m[0][0] = sx; m[1][1] = sy; m[2][2] = sz; } + + //! Scales from a Point. Each row is multiplied by a component. + inline_ void Scale(const Point& p) + { + m[0][0] *= p.x; m[0][1] *= p.x; m[0][2] *= p.x; + m[1][0] *= p.y; m[1][1] *= p.y; m[1][2] *= p.y; + m[2][0] *= p.z; m[2][1] *= p.z; m[2][2] *= p.z; + } + + //! Scales from floats. Each row is multiplied by a value. + inline_ void Scale(float sx, float sy, float sz) + { + m[0][0] *= sx; m[0][1] *= sx; m[0][2] *= sx; + m[1][0] *= sy; m[1][1] *= sy; m[1][2] *= sy; + m[2][0] *= sz; m[2][1] *= sz; m[2][2] *= sz; + } + + //! Copy from a Matrix3x3 + inline_ void Copy(const Matrix3x3& source) { CopyMemory(m, source.m, 9*sizeof(float)); } + + // Row-column access + //! Returns a row. + inline_ void GetRow(const udword r, Point& p) const { p.x = m[r][0]; p.y = m[r][1]; p.z = m[r][2]; } + //! Returns a row. + inline_ const Point& GetRow(const udword r) const { return *(const Point*)&m[r][0]; } + //! Returns a row. + inline_ Point& GetRow(const udword r) { return *(Point*)&m[r][0]; } + //! Sets a row. + inline_ void SetRow(const udword r, const Point& p) { m[r][0] = p.x; m[r][1] = p.y; m[r][2] = p.z; } + //! Returns a column. + inline_ void GetCol(const udword c, Point& p) const { p.x = m[0][c]; p.y = m[1][c]; p.z = m[2][c]; } + //! Sets a column. + inline_ void SetCol(const udword c, const Point& p) { m[0][c] = p.x; m[1][c] = p.y; m[2][c] = p.z; } + + //! Computes the trace. The trace is the sum of the 3 diagonal components. + inline_ float Trace() const { return m[0][0] + m[1][1] + m[2][2]; } + //! Clears the matrix. + inline_ void Zero() { ZeroMemory(&m, sizeof(m)); } + //! Sets the identity matrix. + inline_ void Identity() { Zero(); m[0][0] = m[1][1] = m[2][2] = 1.0f; } + //! Checks for identity + inline_ bool IsIdentity() const + { + if(IR(m[0][0])!=IEEE_1_0) return false; + if(IR(m[0][1])!=0) return false; + if(IR(m[0][2])!=0) return false; + + if(IR(m[1][0])!=0) return false; + if(IR(m[1][1])!=IEEE_1_0) return false; + if(IR(m[1][2])!=0) return false; + + if(IR(m[2][0])!=0) return false; + if(IR(m[2][1])!=0) return false; + if(IR(m[2][2])!=IEEE_1_0) return false; + + return true; + } + + //! Checks matrix validity + inline_ BOOL IsValid() const + { + for(udword j=0;j<3;j++) + { + for(udword i=0;i<3;i++) + { + if(!IsValidFloat(m[j][i])) return FALSE; + } + } + return TRUE; + } + + //! Makes a skew-symmetric matrix (a.k.a. Star(*) Matrix) + //! [ 0.0 -a.z a.y ] + //! [ a.z 0.0 -a.x ] + //! [ -a.y a.x 0.0 ] + //! This is also called a "cross matrix" since for any vectors A and B, + //! A^B = Skew(A) * B = - B * Skew(A); + inline_ void SkewSymmetric(const Point& a) + { + m[0][0] = 0.0f; + m[0][1] = -a.z; + m[0][2] = a.y; + + m[1][0] = a.z; + m[1][1] = 0.0f; + m[1][2] = -a.x; + + m[2][0] = -a.y; + m[2][1] = a.x; + m[2][2] = 0.0f; + } + + //! Negates the matrix + inline_ void Neg() + { + m[0][0] = -m[0][0]; m[0][1] = -m[0][1]; m[0][2] = -m[0][2]; + m[1][0] = -m[1][0]; m[1][1] = -m[1][1]; m[1][2] = -m[1][2]; + m[2][0] = -m[2][0]; m[2][1] = -m[2][1]; m[2][2] = -m[2][2]; + } + + //! Neg from another matrix + inline_ void Neg(const Matrix3x3& mat) + { + m[0][0] = -mat.m[0][0]; m[0][1] = -mat.m[0][1]; m[0][2] = -mat.m[0][2]; + m[1][0] = -mat.m[1][0]; m[1][1] = -mat.m[1][1]; m[1][2] = -mat.m[1][2]; + m[2][0] = -mat.m[2][0]; m[2][1] = -mat.m[2][1]; m[2][2] = -mat.m[2][2]; + } + + //! Add another matrix + inline_ void Add(const Matrix3x3& mat) + { + m[0][0] += mat.m[0][0]; m[0][1] += mat.m[0][1]; m[0][2] += mat.m[0][2]; + m[1][0] += mat.m[1][0]; m[1][1] += mat.m[1][1]; m[1][2] += mat.m[1][2]; + m[2][0] += mat.m[2][0]; m[2][1] += mat.m[2][1]; m[2][2] += mat.m[2][2]; + } + + //! Sub another matrix + inline_ void Sub(const Matrix3x3& mat) + { + m[0][0] -= mat.m[0][0]; m[0][1] -= mat.m[0][1]; m[0][2] -= mat.m[0][2]; + m[1][0] -= mat.m[1][0]; m[1][1] -= mat.m[1][1]; m[1][2] -= mat.m[1][2]; + m[2][0] -= mat.m[2][0]; m[2][1] -= mat.m[2][1]; m[2][2] -= mat.m[2][2]; + } + //! Mac + inline_ void Mac(const Matrix3x3& a, const Matrix3x3& b, float s) + { + m[0][0] = a.m[0][0] + b.m[0][0] * s; + m[0][1] = a.m[0][1] + b.m[0][1] * s; + m[0][2] = a.m[0][2] + b.m[0][2] * s; + + m[1][0] = a.m[1][0] + b.m[1][0] * s; + m[1][1] = a.m[1][1] + b.m[1][1] * s; + m[1][2] = a.m[1][2] + b.m[1][2] * s; + + m[2][0] = a.m[2][0] + b.m[2][0] * s; + m[2][1] = a.m[2][1] + b.m[2][1] * s; + m[2][2] = a.m[2][2] + b.m[2][2] * s; + } + //! Mac + inline_ void Mac(const Matrix3x3& a, float s) + { + m[0][0] += a.m[0][0] * s; m[0][1] += a.m[0][1] * s; m[0][2] += a.m[0][2] * s; + m[1][0] += a.m[1][0] * s; m[1][1] += a.m[1][1] * s; m[1][2] += a.m[1][2] * s; + m[2][0] += a.m[2][0] * s; m[2][1] += a.m[2][1] * s; m[2][2] += a.m[2][2] * s; + } + + //! this = A * s + inline_ void Mult(const Matrix3x3& a, float s) + { + m[0][0] = a.m[0][0] * s; m[0][1] = a.m[0][1] * s; m[0][2] = a.m[0][2] * s; + m[1][0] = a.m[1][0] * s; m[1][1] = a.m[1][1] * s; m[1][2] = a.m[1][2] * s; + m[2][0] = a.m[2][0] * s; m[2][1] = a.m[2][1] * s; m[2][2] = a.m[2][2] * s; + } + + inline_ void Add(const Matrix3x3& a, const Matrix3x3& b) + { + m[0][0] = a.m[0][0] + b.m[0][0]; m[0][1] = a.m[0][1] + b.m[0][1]; m[0][2] = a.m[0][2] + b.m[0][2]; + m[1][0] = a.m[1][0] + b.m[1][0]; m[1][1] = a.m[1][1] + b.m[1][1]; m[1][2] = a.m[1][2] + b.m[1][2]; + m[2][0] = a.m[2][0] + b.m[2][0]; m[2][1] = a.m[2][1] + b.m[2][1]; m[2][2] = a.m[2][2] + b.m[2][2]; + } + + inline_ void Sub(const Matrix3x3& a, const Matrix3x3& b) + { + m[0][0] = a.m[0][0] - b.m[0][0]; m[0][1] = a.m[0][1] - b.m[0][1]; m[0][2] = a.m[0][2] - b.m[0][2]; + m[1][0] = a.m[1][0] - b.m[1][0]; m[1][1] = a.m[1][1] - b.m[1][1]; m[1][2] = a.m[1][2] - b.m[1][2]; + m[2][0] = a.m[2][0] - b.m[2][0]; m[2][1] = a.m[2][1] - b.m[2][1]; m[2][2] = a.m[2][2] - b.m[2][2]; + } + + //! this = a * b + inline_ void Mult(const Matrix3x3& a, const Matrix3x3& b) + { + m[0][0] = a.m[0][0] * b.m[0][0] + a.m[0][1] * b.m[1][0] + a.m[0][2] * b.m[2][0]; + m[0][1] = a.m[0][0] * b.m[0][1] + a.m[0][1] * b.m[1][1] + a.m[0][2] * b.m[2][1]; + m[0][2] = a.m[0][0] * b.m[0][2] + a.m[0][1] * b.m[1][2] + a.m[0][2] * b.m[2][2]; + m[1][0] = a.m[1][0] * b.m[0][0] + a.m[1][1] * b.m[1][0] + a.m[1][2] * b.m[2][0]; + m[1][1] = a.m[1][0] * b.m[0][1] + a.m[1][1] * b.m[1][1] + a.m[1][2] * b.m[2][1]; + m[1][2] = a.m[1][0] * b.m[0][2] + a.m[1][1] * b.m[1][2] + a.m[1][2] * b.m[2][2]; + m[2][0] = a.m[2][0] * b.m[0][0] + a.m[2][1] * b.m[1][0] + a.m[2][2] * b.m[2][0]; + m[2][1] = a.m[2][0] * b.m[0][1] + a.m[2][1] * b.m[1][1] + a.m[2][2] * b.m[2][1]; + m[2][2] = a.m[2][0] * b.m[0][2] + a.m[2][1] * b.m[1][2] + a.m[2][2] * b.m[2][2]; + } + + //! this = transpose(a) * b + inline_ void MultAtB(const Matrix3x3& a, const Matrix3x3& b) + { + m[0][0] = a.m[0][0] * b.m[0][0] + a.m[1][0] * b.m[1][0] + a.m[2][0] * b.m[2][0]; + m[0][1] = a.m[0][0] * b.m[0][1] + a.m[1][0] * b.m[1][1] + a.m[2][0] * b.m[2][1]; + m[0][2] = a.m[0][0] * b.m[0][2] + a.m[1][0] * b.m[1][2] + a.m[2][0] * b.m[2][2]; + m[1][0] = a.m[0][1] * b.m[0][0] + a.m[1][1] * b.m[1][0] + a.m[2][1] * b.m[2][0]; + m[1][1] = a.m[0][1] * b.m[0][1] + a.m[1][1] * b.m[1][1] + a.m[2][1] * b.m[2][1]; + m[1][2] = a.m[0][1] * b.m[0][2] + a.m[1][1] * b.m[1][2] + a.m[2][1] * b.m[2][2]; + m[2][0] = a.m[0][2] * b.m[0][0] + a.m[1][2] * b.m[1][0] + a.m[2][2] * b.m[2][0]; + m[2][1] = a.m[0][2] * b.m[0][1] + a.m[1][2] * b.m[1][1] + a.m[2][2] * b.m[2][1]; + m[2][2] = a.m[0][2] * b.m[0][2] + a.m[1][2] * b.m[1][2] + a.m[2][2] * b.m[2][2]; + } + + //! this = a * transpose(b) + inline_ void MultABt(const Matrix3x3& a, const Matrix3x3& b) + { + m[0][0] = a.m[0][0] * b.m[0][0] + a.m[0][1] * b.m[0][1] + a.m[0][2] * b.m[0][2]; + m[0][1] = a.m[0][0] * b.m[1][0] + a.m[0][1] * b.m[1][1] + a.m[0][2] * b.m[1][2]; + m[0][2] = a.m[0][0] * b.m[2][0] + a.m[0][1] * b.m[2][1] + a.m[0][2] * b.m[2][2]; + m[1][0] = a.m[1][0] * b.m[0][0] + a.m[1][1] * b.m[0][1] + a.m[1][2] * b.m[0][2]; + m[1][1] = a.m[1][0] * b.m[1][0] + a.m[1][1] * b.m[1][1] + a.m[1][2] * b.m[1][2]; + m[1][2] = a.m[1][0] * b.m[2][0] + a.m[1][1] * b.m[2][1] + a.m[1][2] * b.m[2][2]; + m[2][0] = a.m[2][0] * b.m[0][0] + a.m[2][1] * b.m[0][1] + a.m[2][2] * b.m[0][2]; + m[2][1] = a.m[2][0] * b.m[1][0] + a.m[2][1] * b.m[1][1] + a.m[2][2] * b.m[1][2]; + m[2][2] = a.m[2][0] * b.m[2][0] + a.m[2][1] * b.m[2][1] + a.m[2][2] * b.m[2][2]; + } + + //! Makes a rotation matrix mapping vector "from" to vector "to". + Matrix3x3& FromTo(const Point& from, const Point& to); + + //! Set a rotation matrix around the X axis. + //! 1 0 0 + //! RX = 0 cx sx + //! 0 -sx cx + void RotX(float angle); + //! Set a rotation matrix around the Y axis. + //! cy 0 -sy + //! RY = 0 1 0 + //! sy 0 cy + void RotY(float angle); + //! Set a rotation matrix around the Z axis. + //! cz sz 0 + //! RZ = -sz cz 0 + //! 0 0 1 + void RotZ(float angle); + //! cy sx.sy -sy.cx + //! RY.RX 0 cx sx + //! sy -sx.cy cx.cy + void RotYX(float y, float x); + + //! Make a rotation matrix about an arbitrary axis + Matrix3x3& Rot(float angle, const Point& axis); + + //! Transpose the matrix. + void Transpose() + { + TSwap(m[1][0], m[0][1]); + TSwap(m[2][0], m[0][2]); + TSwap(m[2][1], m[1][2]); + } + + //! this = Transpose(a) + void Transpose(const Matrix3x3& a) + { + m[0][0] = a.m[0][0]; m[0][1] = a.m[1][0]; m[0][2] = a.m[2][0]; + m[1][0] = a.m[0][1]; m[1][1] = a.m[1][1]; m[1][2] = a.m[2][1]; + m[2][0] = a.m[0][2]; m[2][1] = a.m[1][2]; m[2][2] = a.m[2][2]; + } + + //! Compute the determinant of the matrix. We use the rule of Sarrus. + float Determinant() const + { + 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[2][0]*m[1][1]*m[0][2] + m[2][1]*m[1][2]*m[0][0] + m[2][2]*m[1][0]*m[0][1]); + } +/* + //! Compute a cofactor. Used for matrix inversion. + float CoFactor(ubyte row, ubyte column) const + { + static const sdword gIndex[3+2] = { 0, 1, 2, 0, 1 }; + return (m[gIndex[row+1]][gIndex[column+1]]*m[gIndex[row+2]][gIndex[column+2]] - m[gIndex[row+2]][gIndex[column+1]]*m[gIndex[row+1]][gIndex[column+2]]); + } +*/ + //! Invert the matrix. Determinant must be different from zero, else matrix can't be inverted. + Matrix3x3& Invert() + { + float Det = Determinant(); // Must be !=0 + float OneOverDet = 1.0f / Det; + + Matrix3x3 Temp; + Temp.m[0][0] = +(m[1][1] * m[2][2] - m[2][1] * m[1][2]) * OneOverDet; + Temp.m[1][0] = -(m[1][0] * m[2][2] - m[2][0] * m[1][2]) * OneOverDet; + Temp.m[2][0] = +(m[1][0] * m[2][1] - m[2][0] * m[1][1]) * OneOverDet; + Temp.m[0][1] = -(m[0][1] * m[2][2] - m[2][1] * m[0][2]) * OneOverDet; + Temp.m[1][1] = +(m[0][0] * m[2][2] - m[2][0] * m[0][2]) * OneOverDet; + Temp.m[2][1] = -(m[0][0] * m[2][1] - m[2][0] * m[0][1]) * OneOverDet; + Temp.m[0][2] = +(m[0][1] * m[1][2] - m[1][1] * m[0][2]) * OneOverDet; + Temp.m[1][2] = -(m[0][0] * m[1][2] - m[1][0] * m[0][2]) * OneOverDet; + Temp.m[2][2] = +(m[0][0] * m[1][1] - m[1][0] * m[0][1]) * OneOverDet; + + *this = Temp; + + return *this; + } + + Matrix3x3& Normalize(); + + //! this = exp(a) + Matrix3x3& Exp(const Matrix3x3& a); + +void FromQuat(const Quat &q); +void FromQuatL2(const Quat &q, float l2); + + // Arithmetic operators + //! Operator for Matrix3x3 Plus = Matrix3x3 + Matrix3x3; + inline_ Matrix3x3 operator+(const Matrix3x3& mat) const + { + return Matrix3x3( + m[0][0] + mat.m[0][0], m[0][1] + mat.m[0][1], m[0][2] + mat.m[0][2], + m[1][0] + mat.m[1][0], m[1][1] + mat.m[1][1], m[1][2] + mat.m[1][2], + m[2][0] + mat.m[2][0], m[2][1] + mat.m[2][1], m[2][2] + mat.m[2][2]); + } + + //! Operator for Matrix3x3 Minus = Matrix3x3 - Matrix3x3; + inline_ Matrix3x3 operator-(const Matrix3x3& mat) const + { + return Matrix3x3( + m[0][0] - mat.m[0][0], m[0][1] - mat.m[0][1], m[0][2] - mat.m[0][2], + m[1][0] - mat.m[1][0], m[1][1] - mat.m[1][1], m[1][2] - mat.m[1][2], + m[2][0] - mat.m[2][0], m[2][1] - mat.m[2][1], m[2][2] - mat.m[2][2]); + } + + //! Operator for Matrix3x3 Mul = Matrix3x3 * Matrix3x3; + inline_ Matrix3x3 operator*(const Matrix3x3& mat) const + { + return Matrix3x3( + m[0][0]*mat.m[0][0] + m[0][1]*mat.m[1][0] + m[0][2]*mat.m[2][0], + m[0][0]*mat.m[0][1] + m[0][1]*mat.m[1][1] + m[0][2]*mat.m[2][1], + m[0][0]*mat.m[0][2] + m[0][1]*mat.m[1][2] + m[0][2]*mat.m[2][2], + + m[1][0]*mat.m[0][0] + m[1][1]*mat.m[1][0] + m[1][2]*mat.m[2][0], + m[1][0]*mat.m[0][1] + m[1][1]*mat.m[1][1] + m[1][2]*mat.m[2][1], + m[1][0]*mat.m[0][2] + m[1][1]*mat.m[1][2] + m[1][2]*mat.m[2][2], + + m[2][0]*mat.m[0][0] + m[2][1]*mat.m[1][0] + m[2][2]*mat.m[2][0], + m[2][0]*mat.m[0][1] + m[2][1]*mat.m[1][1] + m[2][2]*mat.m[2][1], + m[2][0]*mat.m[0][2] + m[2][1]*mat.m[1][2] + m[2][2]*mat.m[2][2]); + } + + //! Operator for Point Mul = Matrix3x3 * Point; + inline_ Point operator*(const Point& v) const { return Point(GetRow(0)|v, GetRow(1)|v, GetRow(2)|v); } + + //! Operator for Matrix3x3 Mul = Matrix3x3 * float; + inline_ Matrix3x3 operator*(float s) const + { + return Matrix3x3( + m[0][0]*s, m[0][1]*s, m[0][2]*s, + m[1][0]*s, m[1][1]*s, m[1][2]*s, + m[2][0]*s, m[2][1]*s, m[2][2]*s); + } + + //! Operator for Matrix3x3 Mul = float * Matrix3x3; + inline_ friend Matrix3x3 operator*(float s, const Matrix3x3& mat) + { + return Matrix3x3( + s*mat.m[0][0], s*mat.m[0][1], s*mat.m[0][2], + s*mat.m[1][0], s*mat.m[1][1], s*mat.m[1][2], + s*mat.m[2][0], s*mat.m[2][1], s*mat.m[2][2]); + } + + //! Operator for Matrix3x3 Div = Matrix3x3 / float; + inline_ Matrix3x3 operator/(float s) const + { + if (s) s = 1.0f / s; + return Matrix3x3( + m[0][0]*s, m[0][1]*s, m[0][2]*s, + m[1][0]*s, m[1][1]*s, m[1][2]*s, + m[2][0]*s, m[2][1]*s, m[2][2]*s); + } + + //! Operator for Matrix3x3 Div = float / Matrix3x3; + inline_ friend Matrix3x3 operator/(float s, const Matrix3x3& mat) + { + return Matrix3x3( + s/mat.m[0][0], s/mat.m[0][1], s/mat.m[0][2], + s/mat.m[1][0], s/mat.m[1][1], s/mat.m[1][2], + s/mat.m[2][0], s/mat.m[2][1], s/mat.m[2][2]); + } + + //! Operator for Matrix3x3 += Matrix3x3 + inline_ Matrix3x3& operator+=(const Matrix3x3& mat) + { + m[0][0] += mat.m[0][0]; m[0][1] += mat.m[0][1]; m[0][2] += mat.m[0][2]; + m[1][0] += mat.m[1][0]; m[1][1] += mat.m[1][1]; m[1][2] += mat.m[1][2]; + m[2][0] += mat.m[2][0]; m[2][1] += mat.m[2][1]; m[2][2] += mat.m[2][2]; + return *this; + } + + //! Operator for Matrix3x3 -= Matrix3x3 + inline_ Matrix3x3& operator-=(const Matrix3x3& mat) + { + m[0][0] -= mat.m[0][0]; m[0][1] -= mat.m[0][1]; m[0][2] -= mat.m[0][2]; + m[1][0] -= mat.m[1][0]; m[1][1] -= mat.m[1][1]; m[1][2] -= mat.m[1][2]; + m[2][0] -= mat.m[2][0]; m[2][1] -= mat.m[2][1]; m[2][2] -= mat.m[2][2]; + return *this; + } + + //! Operator for Matrix3x3 *= Matrix3x3 + inline_ Matrix3x3& operator*=(const Matrix3x3& mat) + { + Point TempRow; + + GetRow(0, TempRow); + m[0][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0]; + m[0][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1]; + m[0][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2]; + + GetRow(1, TempRow); + m[1][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0]; + m[1][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1]; + m[1][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2]; + + GetRow(2, TempRow); + m[2][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0]; + m[2][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1]; + m[2][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2]; + return *this; + } + + //! Operator for Matrix3x3 *= float + inline_ Matrix3x3& operator*=(float s) + { + m[0][0] *= s; m[0][1] *= s; m[0][2] *= s; + m[1][0] *= s; m[1][1] *= s; m[1][2] *= s; + m[2][0] *= s; m[2][1] *= s; m[2][2] *= s; + return *this; + } + + //! Operator for Matrix3x3 /= float + inline_ Matrix3x3& operator/=(float s) + { + if (s) s = 1.0f / s; + m[0][0] *= s; m[0][1] *= s; m[0][2] *= s; + m[1][0] *= s; m[1][1] *= s; m[1][2] *= s; + m[2][0] *= s; m[2][1] *= s; m[2][2] *= s; + return *this; + } + + // Cast operators + //! Cast a Matrix3x3 to a Matrix4x4. + operator Matrix4x4() const; + //! Cast a Matrix3x3 to a Quat. + operator Quat() const; + + inline_ const Point& operator[](int row) const { return *(const Point*)&m[row][0]; } + inline_ Point& operator[](int row) { return *(Point*)&m[row][0]; } + + public: + + float m[3][3]; + }; + +#endif // __ICEMATRIX3X3_H__ + diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceMatrix4x4.cpp b/libs/ode-0.16.1/OPCODE/Ice/IceMatrix4x4.cpp new file mode 100644 index 0000000..0b258f0 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceMatrix4x4.cpp @@ -0,0 +1,135 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for 4x4 matrices. + * \file IceMatrix4x4.cpp + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * 4x4 matrix. + * DirectX-compliant, ie row-column order, ie m[Row][Col]. + * Same as: + * m11 m12 m13 m14 first row. + * m21 m22 m23 m24 second row. + * m31 m32 m33 m34 third row. + * m41 m42 m43 m44 fourth row. + * Translation is (m41, m42, m43), (m14, m24, m34, m44) = (0, 0, 0, 1). + * Stored in memory as m11 m12 m13 m14 m21... + * + * Multiplication rules: + * + * [x'y'z'1] = [xyz1][M] + * + * x' = x*m11 + y*m21 + z*m31 + m41 + * y' = x*m12 + y*m22 + z*m32 + m42 + * z' = x*m13 + y*m23 + z*m33 + m43 + * 1' = 0 + 0 + 0 + m44 + * + * \class Matrix4x4 + * \author Pierre Terdiman + * \version 1.0 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace IceMaths; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Inverts a PR matrix. (which only contains a rotation and a translation) + * This is faster and less subject to FPU errors than the generic inversion code. + * + * \relates Matrix4x4 + * \fn InvertPRMatrix(Matrix4x4& dest, const Matrix4x4& src) + * \param dest [out] destination matrix + * \param src [in] source matrix + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +ICEMATHS_API void IceMaths::InvertPRMatrix(Matrix4x4& dest, const Matrix4x4& src) +{ + dest.m[0][0] = src.m[0][0]; + dest.m[1][0] = src.m[0][1]; + dest.m[2][0] = src.m[0][2]; + dest.m[3][0] = -(src.m[3][0]*src.m[0][0] + src.m[3][1]*src.m[0][1] + src.m[3][2]*src.m[0][2]); + + dest.m[0][1] = src.m[1][0]; + dest.m[1][1] = src.m[1][1]; + dest.m[2][1] = src.m[1][2]; + dest.m[3][1] = -(src.m[3][0]*src.m[1][0] + src.m[3][1]*src.m[1][1] + src.m[3][2]*src.m[1][2]); + + dest.m[0][2] = src.m[2][0]; + dest.m[1][2] = src.m[2][1]; + dest.m[2][2] = src.m[2][2]; + dest.m[3][2] = -(src.m[3][0]*src.m[2][0] + src.m[3][1]*src.m[2][1] + src.m[3][2]*src.m[2][2]); + + dest.m[0][3] = 0.0f; + dest.m[1][3] = 0.0f; + dest.m[2][3] = 0.0f; + dest.m[3][3] = 1.0f; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Compute the cofactor of the Matrix at a specified location +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float Matrix4x4::CoFactor(udword row, udword col) const +{ + return (( m[(row+1)&3][(col+1)&3]*m[(row+2)&3][(col+2)&3]*m[(row+3)&3][(col+3)&3] + + m[(row+1)&3][(col+2)&3]*m[(row+2)&3][(col+3)&3]*m[(row+3)&3][(col+1)&3] + + m[(row+1)&3][(col+3)&3]*m[(row+2)&3][(col+1)&3]*m[(row+3)&3][(col+2)&3]) + - (m[(row+3)&3][(col+1)&3]*m[(row+2)&3][(col+2)&3]*m[(row+1)&3][(col+3)&3] + + m[(row+3)&3][(col+2)&3]*m[(row+2)&3][(col+3)&3]*m[(row+1)&3][(col+1)&3] + + m[(row+3)&3][(col+3)&3]*m[(row+2)&3][(col+1)&3]*m[(row+1)&3][(col+2)&3])) * ((row + col) & 1 ? -1.0f : +1.0f); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Compute the determinant of the Matrix +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float Matrix4x4::Determinant() const +{ + return m[0][0] * CoFactor(0, 0) + + m[0][1] * CoFactor(0, 1) + + m[0][2] * CoFactor(0, 2) + + m[0][3] * CoFactor(0, 3); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Compute the inverse of the matrix +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Matrix4x4& Matrix4x4::Invert() +{ + float Det = Determinant(); + Matrix4x4 Temp; + + if(fabsf(Det) < MATRIX4X4_EPSILON) + return *this; // The matrix is not invertible! Singular case! + + float IDet = 1.0f / Det; + + Temp.m[0][0] = CoFactor(0,0) * IDet; + Temp.m[1][0] = CoFactor(0,1) * IDet; + Temp.m[2][0] = CoFactor(0,2) * IDet; + Temp.m[3][0] = CoFactor(0,3) * IDet; + Temp.m[0][1] = CoFactor(1,0) * IDet; + Temp.m[1][1] = CoFactor(1,1) * IDet; + Temp.m[2][1] = CoFactor(1,2) * IDet; + Temp.m[3][1] = CoFactor(1,3) * IDet; + Temp.m[0][2] = CoFactor(2,0) * IDet; + Temp.m[1][2] = CoFactor(2,1) * IDet; + Temp.m[2][2] = CoFactor(2,2) * IDet; + Temp.m[3][2] = CoFactor(2,3) * IDet; + Temp.m[0][3] = CoFactor(3,0) * IDet; + Temp.m[1][3] = CoFactor(3,1) * IDet; + Temp.m[2][3] = CoFactor(3,2) * IDet; + Temp.m[3][3] = CoFactor(3,3) * IDet; + + *this = Temp; + + return *this; +} + diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceMatrix4x4.h b/libs/ode-0.16.1/OPCODE/Ice/IceMatrix4x4.h new file mode 100644 index 0000000..e2db104 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceMatrix4x4.h @@ -0,0 +1,457 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for 4x4 matrices. + * \file IceMatrix4x4.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEMATRIX4X4_H__ +#define __ICEMATRIX4X4_H__ + + // Forward declarations + class PRS; + class PR; + + #define MATRIX4X4_EPSILON (1.0e-7f) + + class ICEMATHS_API Matrix4x4 + { +// void LUBackwardSubstitution( sdword *indx, float* b ); +// void LUDecomposition( sdword* indx, float* d ); + + public: + //! Empty constructor. + inline_ Matrix4x4() {} + //! Constructor from 16 values + inline_ Matrix4x4( 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) + { + m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; m[0][3] = m03; + m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; m[1][3] = m13; + m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; m[2][3] = m23; + m[3][0] = m30; m[3][1] = m31; m[3][2] = m32; m[3][3] = m33; + } + //! Copy constructor + inline_ Matrix4x4(const Matrix4x4& mat) { CopyMemory(m, &mat.m, 16*sizeof(float)); } + //! Destructor. + inline_ ~Matrix4x4() {} + + //! Assign values (rotation only) + template<typename trotationfloat> + inline_ Matrix4x4& Set( trotationfloat m00, trotationfloat m01, trotationfloat m02, + trotationfloat m10, trotationfloat m11, trotationfloat m12, + trotationfloat m20, trotationfloat m21, trotationfloat m22) + { + m[0][0] = (float)m00; m[0][1] = (float)m01; m[0][2] = (float)m02; + m[1][0] = (float)m10; m[1][1] = (float)m11; m[1][2] = (float)m12; + m[2][0] = (float)m20; m[2][1] = (float)m21; m[2][2] = (float)m22; + return *this; + } + //! Assign values + template<typename trotationfloat, typename toffsetfloat, typename textrafloat> + inline_ Matrix4x4& Set( trotationfloat m00, trotationfloat m01, trotationfloat m02, textrafloat m03, + trotationfloat m10, trotationfloat m11, trotationfloat m12, textrafloat m13, + trotationfloat m20, trotationfloat m21, trotationfloat m22, textrafloat m23, + toffsetfloat m30, toffsetfloat m31, toffsetfloat m32, textrafloat m33) + { + m[0][0] = (float)m00; m[0][1] = (float)m01; m[0][2] = (float)m02; m[0][3] = (float)m03; + m[1][0] = (float)m10; m[1][1] = (float)m11; m[1][2] = (float)m12; m[1][3] = (float)m13; + m[2][0] = (float)m20; m[2][1] = (float)m21; m[2][2] = (float)m22; m[2][3] = (float)m23; + m[3][0] = (float)m30; m[3][1] = (float)m31; m[3][2] = (float)m32; m[3][3] = (float)m33; + return *this; + } + + //! Copy from a Matrix4x4 + inline_ void Copy(const Matrix4x4& source) { CopyMemory(m, source.m, 16*sizeof(float)); } + + // Row-column access + //! Returns a row. + inline_ void GetRow(const udword r, HPoint& p) const { p.x=m[r][0]; p.y=m[r][1]; p.z=m[r][2]; p.w=m[r][3]; } + //! Returns a row. + inline_ void GetRow(const udword r, Point& p) const { p.x=m[r][0]; p.y=m[r][1]; p.z=m[r][2]; } + //! Returns a row. + inline_ const HPoint& GetRow(const udword r) const { return *(const HPoint*)&m[r][0]; } + //! Returns a row. + inline_ HPoint& GetRow(const udword r) { return *(HPoint*)&m[r][0]; } + //! Sets a row. + inline_ void SetRow(const udword r, const HPoint& p) { m[r][0]=p.x; m[r][1]=p.y; m[r][2]=p.z; m[r][3]=p.w; } + //! Sets a row. + inline_ void SetRow(const udword r, const Point& p) { m[r][0]=p.x; m[r][1]=p.y; m[r][2]=p.z; m[r][3]= (r!=3) ? 0.0f : 1.0f; } + //! Returns a column. + inline_ void GetCol(const udword c, HPoint& p) const { p.x=m[0][c]; p.y=m[1][c]; p.z=m[2][c]; p.w=m[3][c]; } + //! Returns a column. + inline_ void GetCol(const udword c, Point& p) const { p.x=m[0][c]; p.y=m[1][c]; p.z=m[2][c]; } + //! Sets a column. + inline_ void SetCol(const udword c, const HPoint& p) { m[0][c]=p.x; m[1][c]=p.y; m[2][c]=p.z; m[3][c]=p.w; } + //! Sets a column. + inline_ void SetCol(const udword c, const Point& p) { m[0][c]=p.x; m[1][c]=p.y; m[2][c]=p.z; m[3][c]= (c!=3) ? 0.0f : 1.0f; } + + // Translation + //! Returns the translation part of the matrix. + inline_ const HPoint& GetTrans() const { return GetRow(3); } + //! Gets the translation part of the matrix + inline_ void GetTrans(Point& p) const { p.x=m[3][0]; p.y=m[3][1]; p.z=m[3][2]; } + //! Sets the translation part of the matrix, from a Point. + inline_ void SetTrans(const Point& p) { m[3][0]=p.x; m[3][1]=p.y; m[3][2]=p.z; } + //! Sets the translation part of the matrix, from a HPoint. + inline_ void SetTrans(const HPoint& p) { m[3][0]=p.x; m[3][1]=p.y; m[3][2]=p.z; m[3][3]=p.w; } + //! Sets the translation part of the matrix, from floats. + inline_ void SetTrans(float tx, float ty, float tz) { m[3][0]=tx; m[3][1]=ty; m[3][2]=tz; } + + // Scale + //! Sets the scale from a Point. The point is put on the diagonal. + inline_ void SetScale(const Point& p) { m[0][0]=p.x; m[1][1]=p.y; m[2][2]=p.z; } + //! Sets the scale from floats. Values are put on the diagonal. + inline_ void SetScale(float sx, float sy, float sz) { m[0][0]=sx; m[1][1]=sy; m[2][2]=sz; } + //! Scales from a Point. Each row is multiplied by a component. + void Scale(const Point& p) + { + m[0][0] *= p.x; m[1][0] *= p.y; m[2][0] *= p.z; + m[0][1] *= p.x; m[1][1] *= p.y; m[2][1] *= p.z; + m[0][2] *= p.x; m[1][2] *= p.y; m[2][2] *= p.z; + } + //! Scales from floats. Each row is multiplied by a value. + void Scale(float sx, float sy, float sz) + { + m[0][0] *= sx; m[1][0] *= sy; m[2][0] *= sz; + m[0][1] *= sx; m[1][1] *= sy; m[2][1] *= sz; + m[0][2] *= sx; m[1][2] *= sy; m[2][2] *= sz; + } +/* + //! Returns a row. + inline_ HPoint GetRow(const udword row) const { return mRow[row]; } + //! Sets a row. + inline_ Matrix4x4& SetRow(const udword row, const HPoint& p) { mRow[row] = p; return *this; } + //! Sets a row. + Matrix4x4& SetRow(const udword row, const Point& p) + { + m[row][0] = p.x; + m[row][1] = p.y; + m[row][2] = p.z; + m[row][3] = (row != 3) ? 0.0f : 1.0f; + return *this; + } + //! Returns a column. + HPoint GetCol(const udword col) const + { + HPoint Res; + Res.x = m[0][col]; + Res.y = m[1][col]; + Res.z = m[2][col]; + Res.w = m[3][col]; + return Res; + } + //! Sets a column. + Matrix4x4& SetCol(const udword col, const HPoint& p) + { + m[0][col] = p.x; + m[1][col] = p.y; + m[2][col] = p.z; + m[3][col] = p.w; + return *this; + } + //! Sets a column. + Matrix4x4& SetCol(const udword col, const Point& p) + { + m[0][col] = p.x; + m[1][col] = p.y; + m[2][col] = p.z; + m[3][col] = (col != 3) ? 0.0f : 1.0f; + return *this; + } +*/ + //! Computes the trace. The trace is the sum of the 4 diagonal components. + inline_ float Trace() const { return m[0][0] + m[1][1] + m[2][2] + m[3][3]; } + //! Computes the trace of the upper 3x3 matrix. + inline_ float Trace3x3() const { return m[0][0] + m[1][1] + m[2][2]; } + //! Clears the matrix. + inline_ void Zero() { ZeroMemory(&m, sizeof(m)); } + //! Sets the identity matrix. + inline_ void Identity() { Zero(); m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0f; } + //! Checks for identity + inline_ bool IsIdentity() const + { + if(IR(m[0][0])!=IEEE_1_0) return false; + if(IR(m[0][1])!=0) return false; + if(IR(m[0][2])!=0) return false; + if(IR(m[0][3])!=0) return false; + + if(IR(m[1][0])!=0) return false; + if(IR(m[1][1])!=IEEE_1_0) return false; + if(IR(m[1][2])!=0) return false; + if(IR(m[1][3])!=0) return false; + + if(IR(m[2][0])!=0) return false; + if(IR(m[2][1])!=0) return false; + if(IR(m[2][2])!=IEEE_1_0) return false; + if(IR(m[2][3])!=0) return false; + + if(IR(m[3][0])!=0) return false; + if(IR(m[3][1])!=0) return false; + if(IR(m[3][2])!=0) return false; + if(IR(m[3][3])!=IEEE_1_0) return false; + return true; + } + + //! Checks matrix validity + inline_ BOOL IsValid() const + { + for(udword j=0;j<4;j++) + { + for(udword i=0;i<4;i++) + { + if(!IsValidFloat(m[j][i])) return FALSE; + } + } + return TRUE; + } + + //! Sets a rotation matrix around the X axis. + void RotX(float angle) { float Cos = cosf(angle), Sin = sinf(angle); Identity(); m[1][1] = m[2][2] = Cos; m[2][1] = -Sin; m[1][2] = Sin; } + //! Sets a rotation matrix around the Y axis. + void RotY(float angle) { float Cos = cosf(angle), Sin = sinf(angle); Identity(); m[0][0] = m[2][2] = Cos; m[2][0] = Sin; m[0][2] = -Sin; } + //! Sets a rotation matrix around the Z axis. + void RotZ(float angle) { float Cos = cosf(angle), Sin = sinf(angle); Identity(); m[0][0] = m[1][1] = Cos; m[1][0] = -Sin; m[0][1] = Sin; } + + //! Makes a rotation matrix about an arbitrary axis + Matrix4x4& Rot(float angle, Point& p1, Point& p2); + + //! Transposes the matrix. + void Transpose() + { + TSwap(m[1][0], m[0][1]); + TSwap(m[2][0], m[0][2]); + TSwap(m[3][0], m[0][3]); + TSwap(m[1][2], m[2][1]); + TSwap(m[1][3], m[3][1]); + TSwap(m[2][3], m[3][2]); + } + + //! Computes a cofactor. Used for matrix inversion. + float CoFactor(udword row, udword col) const; + //! Computes the determinant of the matrix. + float Determinant() const; + //! Inverts the matrix. Determinant must be different from zero, else matrix can't be inverted. + Matrix4x4& Invert(); +// Matrix& ComputeAxisMatrix(Point& axis, float angle); + + // Cast operators + //! Casts a Matrix4x4 to a Matrix3x3. + inline_ operator Matrix3x3() const + { + return Matrix3x3( + m[0][0], m[0][1], m[0][2], + m[1][0], m[1][1], m[1][2], + m[2][0], m[2][1], m[2][2]); + } + //! Casts a Matrix4x4 to a Quat. + operator Quat() const; + //! Casts a Matrix4x4 to a PR. + operator PR() const; + + // Arithmetic operators + //! Operator for Matrix4x4 Plus = Matrix4x4 + Matrix4x4; + inline_ Matrix4x4 operator+(const Matrix4x4& mat) const + { + return Matrix4x4( + m[0][0]+mat.m[0][0], m[0][1]+mat.m[0][1], m[0][2]+mat.m[0][2], m[0][3]+mat.m[0][3], + m[1][0]+mat.m[1][0], m[1][1]+mat.m[1][1], m[1][2]+mat.m[1][2], m[1][3]+mat.m[1][3], + m[2][0]+mat.m[2][0], m[2][1]+mat.m[2][1], m[2][2]+mat.m[2][2], m[2][3]+mat.m[2][3], + m[3][0]+mat.m[3][0], m[3][1]+mat.m[3][1], m[3][2]+mat.m[3][2], m[3][3]+mat.m[3][3]); + } + + //! Operator for Matrix4x4 Minus = Matrix4x4 - Matrix4x4; + inline_ Matrix4x4 operator-(const Matrix4x4& mat) const + { + return Matrix4x4( + m[0][0]-mat.m[0][0], m[0][1]-mat.m[0][1], m[0][2]-mat.m[0][2], m[0][3]-mat.m[0][3], + m[1][0]-mat.m[1][0], m[1][1]-mat.m[1][1], m[1][2]-mat.m[1][2], m[1][3]-mat.m[1][3], + m[2][0]-mat.m[2][0], m[2][1]-mat.m[2][1], m[2][2]-mat.m[2][2], m[2][3]-mat.m[2][3], + m[3][0]-mat.m[3][0], m[3][1]-mat.m[3][1], m[3][2]-mat.m[3][2], m[3][3]-mat.m[3][3]); + } + + //! Operator for Matrix4x4 Mul = Matrix4x4 * Matrix4x4; + inline_ Matrix4x4 operator*(const Matrix4x4& mat) const + { + return Matrix4x4( + m[0][0]*mat.m[0][0] + m[0][1]*mat.m[1][0] + m[0][2]*mat.m[2][0] + m[0][3]*mat.m[3][0], + m[0][0]*mat.m[0][1] + m[0][1]*mat.m[1][1] + m[0][2]*mat.m[2][1] + m[0][3]*mat.m[3][1], + m[0][0]*mat.m[0][2] + m[0][1]*mat.m[1][2] + m[0][2]*mat.m[2][2] + m[0][3]*mat.m[3][2], + m[0][0]*mat.m[0][3] + m[0][1]*mat.m[1][3] + m[0][2]*mat.m[2][3] + m[0][3]*mat.m[3][3], + + m[1][0]*mat.m[0][0] + m[1][1]*mat.m[1][0] + m[1][2]*mat.m[2][0] + m[1][3]*mat.m[3][0], + m[1][0]*mat.m[0][1] + m[1][1]*mat.m[1][1] + m[1][2]*mat.m[2][1] + m[1][3]*mat.m[3][1], + m[1][0]*mat.m[0][2] + m[1][1]*mat.m[1][2] + m[1][2]*mat.m[2][2] + m[1][3]*mat.m[3][2], + m[1][0]*mat.m[0][3] + m[1][1]*mat.m[1][3] + m[1][2]*mat.m[2][3] + m[1][3]*mat.m[3][3], + + m[2][0]*mat.m[0][0] + m[2][1]*mat.m[1][0] + m[2][2]*mat.m[2][0] + m[2][3]*mat.m[3][0], + m[2][0]*mat.m[0][1] + m[2][1]*mat.m[1][1] + m[2][2]*mat.m[2][1] + m[2][3]*mat.m[3][1], + m[2][0]*mat.m[0][2] + m[2][1]*mat.m[1][2] + m[2][2]*mat.m[2][2] + m[2][3]*mat.m[3][2], + m[2][0]*mat.m[0][3] + m[2][1]*mat.m[1][3] + m[2][2]*mat.m[2][3] + m[2][3]*mat.m[3][3], + + m[3][0]*mat.m[0][0] + m[3][1]*mat.m[1][0] + m[3][2]*mat.m[2][0] + m[3][3]*mat.m[3][0], + m[3][0]*mat.m[0][1] + m[3][1]*mat.m[1][1] + m[3][2]*mat.m[2][1] + m[3][3]*mat.m[3][1], + m[3][0]*mat.m[0][2] + m[3][1]*mat.m[1][2] + m[3][2]*mat.m[2][2] + m[3][3]*mat.m[3][2], + m[3][0]*mat.m[0][3] + m[3][1]*mat.m[1][3] + m[3][2]*mat.m[2][3] + m[3][3]*mat.m[3][3]); + } + + //! Operator for HPoint Mul = Matrix4x4 * HPoint; + inline_ HPoint operator*(const HPoint& v) const { return HPoint(GetRow(0)|v, GetRow(1)|v, GetRow(2)|v, GetRow(3)|v); } + + //! Operator for Point Mul = Matrix4x4 * Point; + inline_ Point operator*(const Point& v) const + { + return Point( m[0][0]*v.x + m[0][1]*v.y + m[0][2]*v.z + m[0][3], + m[1][0]*v.x + m[1][1]*v.y + m[1][2]*v.z + m[1][3], + m[2][0]*v.x + m[2][1]*v.y + m[2][2]*v.z + m[2][3] ); + } + + //! Operator for Matrix4x4 Scale = Matrix4x4 * float; + inline_ Matrix4x4 operator*(float s) const + { + return Matrix4x4( + m[0][0]*s, m[0][1]*s, m[0][2]*s, m[0][3]*s, + m[1][0]*s, m[1][1]*s, m[1][2]*s, m[1][3]*s, + m[2][0]*s, m[2][1]*s, m[2][2]*s, m[2][3]*s, + m[3][0]*s, m[3][1]*s, m[3][2]*s, m[3][3]*s); + } + + //! Operator for Matrix4x4 Scale = float * Matrix4x4; + inline_ friend Matrix4x4 operator*(float s, const Matrix4x4& mat) + { + return Matrix4x4( + s*mat.m[0][0], s*mat.m[0][1], s*mat.m[0][2], s*mat.m[0][3], + s*mat.m[1][0], s*mat.m[1][1], s*mat.m[1][2], s*mat.m[1][3], + s*mat.m[2][0], s*mat.m[2][1], s*mat.m[2][2], s*mat.m[2][3], + s*mat.m[3][0], s*mat.m[3][1], s*mat.m[3][2], s*mat.m[3][3]); + } + + //! Operator for Matrix4x4 Div = Matrix4x4 / float; + inline_ Matrix4x4 operator/(float s) const + { + if(s) s = 1.0f / s; + + return Matrix4x4( + m[0][0]*s, m[0][1]*s, m[0][2]*s, m[0][3]*s, + m[1][0]*s, m[1][1]*s, m[1][2]*s, m[1][3]*s, + m[2][0]*s, m[2][1]*s, m[2][2]*s, m[2][3]*s, + m[3][0]*s, m[3][1]*s, m[3][2]*s, m[3][3]*s); + } + + //! Operator for Matrix4x4 Div = float / Matrix4x4; + inline_ friend Matrix4x4 operator/(float s, const Matrix4x4& mat) + { + return Matrix4x4( + s/mat.m[0][0], s/mat.m[0][1], s/mat.m[0][2], s/mat.m[0][3], + s/mat.m[1][0], s/mat.m[1][1], s/mat.m[1][2], s/mat.m[1][3], + s/mat.m[2][0], s/mat.m[2][1], s/mat.m[2][2], s/mat.m[2][3], + s/mat.m[3][0], s/mat.m[3][1], s/mat.m[3][2], s/mat.m[3][3]); + } + + //! Operator for Matrix4x4 += Matrix4x4; + inline_ Matrix4x4& operator+=(const Matrix4x4& mat) + { + m[0][0]+=mat.m[0][0]; m[0][1]+=mat.m[0][1]; m[0][2]+=mat.m[0][2]; m[0][3]+=mat.m[0][3]; + m[1][0]+=mat.m[1][0]; m[1][1]+=mat.m[1][1]; m[1][2]+=mat.m[1][2]; m[1][3]+=mat.m[1][3]; + m[2][0]+=mat.m[2][0]; m[2][1]+=mat.m[2][1]; m[2][2]+=mat.m[2][2]; m[2][3]+=mat.m[2][3]; + m[3][0]+=mat.m[3][0]; m[3][1]+=mat.m[3][1]; m[3][2]+=mat.m[3][2]; m[3][3]+=mat.m[3][3]; + return *this; + } + + //! Operator for Matrix4x4 -= Matrix4x4; + inline_ Matrix4x4& operator-=(const Matrix4x4& mat) + { + m[0][0]-=mat.m[0][0]; m[0][1]-=mat.m[0][1]; m[0][2]-=mat.m[0][2]; m[0][3]-=mat.m[0][3]; + m[1][0]-=mat.m[1][0]; m[1][1]-=mat.m[1][1]; m[1][2]-=mat.m[1][2]; m[1][3]-=mat.m[1][3]; + m[2][0]-=mat.m[2][0]; m[2][1]-=mat.m[2][1]; m[2][2]-=mat.m[2][2]; m[2][3]-=mat.m[2][3]; + m[3][0]-=mat.m[3][0]; m[3][1]-=mat.m[3][1]; m[3][2]-=mat.m[3][2]; m[3][3]-=mat.m[3][3]; + return *this; + } + + //! Operator for Matrix4x4 *= Matrix4x4; + Matrix4x4& operator*=(const Matrix4x4& mat) + { + HPoint TempRow; + + GetRow(0, TempRow); + m[0][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0]; + m[0][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1]; + m[0][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2]; + m[0][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3]; + + GetRow(1, TempRow); + m[1][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0]; + m[1][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1]; + m[1][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2]; + m[1][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3]; + + GetRow(2, TempRow); + m[2][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0]; + m[2][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1]; + m[2][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2]; + m[2][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3]; + + GetRow(3, TempRow); + m[3][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0] + TempRow.w*mat.m[3][0]; + m[3][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1] + TempRow.w*mat.m[3][1]; + m[3][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2] + TempRow.w*mat.m[3][2]; + m[3][3] = TempRow.x*mat.m[0][3] + TempRow.y*mat.m[1][3] + TempRow.z*mat.m[2][3] + TempRow.w*mat.m[3][3]; + + return *this; + } + + //! Operator for Matrix4x4 *= float; + inline_ Matrix4x4& operator*=(float s) + { + m[0][0]*=s; m[0][1]*=s; m[0][2]*=s; m[0][3]*=s; + m[1][0]*=s; m[1][1]*=s; m[1][2]*=s; m[1][3]*=s; + m[2][0]*=s; m[2][1]*=s; m[2][2]*=s; m[2][3]*=s; + m[3][0]*=s; m[3][1]*=s; m[3][2]*=s; m[3][3]*=s; + return *this; + } + + //! Operator for Matrix4x4 /= float; + inline_ Matrix4x4& operator/=(float s) + { + if(s) s = 1.0f / s; + m[0][0]*=s; m[0][1]*=s; m[0][2]*=s; m[0][3]*=s; + m[1][0]*=s; m[1][1]*=s; m[1][2]*=s; m[1][3]*=s; + m[2][0]*=s; m[2][1]*=s; m[2][2]*=s; m[2][3]*=s; + m[3][0]*=s; m[3][1]*=s; m[3][2]*=s; m[3][3]*=s; + return *this; + } + + inline_ const HPoint& operator[](int row) const { return *(const HPoint*)&m[row][0]; } + inline_ HPoint& operator[](int row) { return *(HPoint*)&m[row][0]; } + + public: + + float m[4][4]; + }; + + //! Quickly rotates & translates a vector, using the 4x3 part of a 4x4 matrix + inline_ void TransformPoint4x3(Point& dest, const Point& source, const Matrix4x4& rot) + { + dest.x = rot.m[3][0] + source.x * rot.m[0][0] + source.y * rot.m[1][0] + source.z * rot.m[2][0]; + dest.y = rot.m[3][1] + source.x * rot.m[0][1] + source.y * rot.m[1][1] + source.z * rot.m[2][1]; + dest.z = rot.m[3][2] + source.x * rot.m[0][2] + source.y * rot.m[1][2] + source.z * rot.m[2][2]; + } + + //! Quickly rotates a vector, using the 3x3 part of a 4x4 matrix + inline_ void TransformPoint3x3(Point& dest, const Point& source, const Matrix4x4& rot) + { + dest.x = source.x * rot.m[0][0] + source.y * rot.m[1][0] + source.z * rot.m[2][0]; + dest.y = source.x * rot.m[0][1] + source.y * rot.m[1][1] + source.z * rot.m[2][1]; + dest.z = source.x * rot.m[0][2] + source.y * rot.m[1][2] + source.z * rot.m[2][2]; + } + + ICEMATHS_API void InvertPRMatrix(Matrix4x4& dest, const Matrix4x4& src); + +#endif // __ICEMATRIX4X4_H__ + diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceMemoryMacros.h b/libs/ode-0.16.1/OPCODE/Ice/IceMemoryMacros.h new file mode 100644 index 0000000..ad25c44 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceMemoryMacros.h @@ -0,0 +1,86 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains all memory macros. + * \file IceMemoryMacros.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEMEMORYMACROS_H__ +#define __ICEMEMORYMACROS_H__ + +#undef ZeroMemory +#undef CopyMemory +#undef MoveMemory +#undef FillMemory + + //! Clears a buffer. + //! \param addr [in] buffer address + //! \param size [in] buffer length + //! \see FillMemory + //! \see StoreDwords + //! \see CopyMemory + //! \see MoveMemory + inline_ void ZeroMemory(void* addr, udword size) { memset(addr, 0, size); } + + //! Fills a buffer with a given byte. + //! \param addr [in] buffer address + //! \param size [in] buffer length + //! \param val [in] the byte value + //! \see StoreDwords + //! \see ZeroMemory + //! \see CopyMemory + //! \see MoveMemory + inline_ void FillMemory(void* dest, udword size, ubyte val) { memset(dest, val, size); } + + //! Fills a buffer with a given dword. + //! \param addr [in] buffer address + //! \param nb [in] number of dwords to write + //! \param value [in] the dword value + //! \see FillMemory + //! \see ZeroMemory + //! \see CopyMemory + //! \see MoveMemory + //! \warning writes nb*4 bytes ! + inline_ void StoreDwords(udword* dest, udword nb, udword value) + { + while(nb--) *dest++ = value; + } + + //! Copies a buffer. + //! \param addr [in] destination buffer address + //! \param addr [in] source buffer address + //! \param size [in] buffer length + //! \see ZeroMemory + //! \see FillMemory + //! \see StoreDwords + //! \see MoveMemory + inline_ void CopyMemory(void* dest, const void* src, udword size) { memcpy(dest, src, size); } + + //! Moves a buffer. + //! \param addr [in] destination buffer address + //! \param addr [in] source buffer address + //! \param size [in] buffer length + //! \see ZeroMemory + //! \see FillMemory + //! \see StoreDwords + //! \see CopyMemory + inline_ void MoveMemory(void* dest, const void* src, udword size) { memmove(dest, src, size); } + + #define SIZEOFOBJECT sizeof(*this) //!< Gives the size of current object. Avoid some mistakes (e.g. "sizeof(this)"). + //#define CLEAROBJECT { memset(this, 0, SIZEOFOBJECT); } //!< Clears current object. Laziness is my business. HANDLE WITH CARE. + #define DELETESINGLE(x) if (x) { delete x; x = null; } //!< Deletes an instance of a class. + #define DELETEARRAY(x) if (x) { delete []x; x = null; } //!< Deletes an array. + #define SAFE_RELEASE(x) if (x) { (x)->Release(); (x) = null; } //!< Safe D3D-style release + #define SAFE_DESTRUCT(x) if (x) { (x)->SelfDestruct(); (x) = null; } //!< Safe ICE-style release + +#ifdef __ICEERROR_H__ + #define CHECKALLOC(x) if(!x) return SetIceError("Out of memory.", EC_OUT_OF_MEMORY); //!< Standard alloc checking. HANDLE WITH CARE. +#else + #define CHECKALLOC(x) if(!x) return false; +#endif + +#endif // __ICEMEMORYMACROS_H__ diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceOBB.cpp b/libs/ode-0.16.1/OPCODE/Ice/IceOBB.cpp new file mode 100644 index 0000000..0ad1ce3 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceOBB.cpp @@ -0,0 +1,324 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains OBB-related code. + * \file IceOBB.cpp + * \author Pierre Terdiman + * \date January, 29, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * An Oriented Bounding Box (OBB). + * \class OBB + * \author Pierre Terdiman + * \version 1.0 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace IceMaths; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Tests if a point is contained within the OBB. + * \param p [in] the world point to test + * \return true if inside the OBB + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool OBB::ContainsPoint(const Point& p) const +{ + // Point in OBB test using lazy evaluation and early exits + + // Translate to box space + Point RelPoint = p - mCenter; + + // Point * mRot maps from box space to world space + // mRot * Point maps from world space to box space (what we need here) + + float f = mRot.m[0][0] * RelPoint.x + mRot.m[0][1] * RelPoint.y + mRot.m[0][2] * RelPoint.z; + if(f >= mExtents.x || f <= -mExtents.x) return false; + + f = mRot.m[1][0] * RelPoint.x + mRot.m[1][1] * RelPoint.y + mRot.m[1][2] * RelPoint.z; + if(f >= mExtents.y || f <= -mExtents.y) return false; + + f = mRot.m[2][0] * RelPoint.x + mRot.m[2][1] * RelPoint.y + mRot.m[2][2] * RelPoint.z; + if(f >= mExtents.z || f <= -mExtents.z) return false; + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Builds an OBB from an AABB and a world transform. + * \param aabb [in] the aabb + * \param mat [in] the world transform + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void OBB::Create(const AABB& aabb, const Matrix4x4& mat) +{ + // Note: must be coherent with Rotate() + + aabb.GetCenter(mCenter); + aabb.GetExtents(mExtents); + // Here we have the same as OBB::Rotate(mat) where the obb is (mCenter, mExtents, Identity). + + // So following what's done in Rotate: + // - x-form the center + mCenter *= mat; + // - combine rotation with identity, i.e. just use given matrix + mRot = mat; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the obb planes. + * \param planes [out] 6 box planes + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool OBB::ComputePlanes(Plane* planes) const +{ + // Checkings + if(!planes) return false; + + Point Axis0 = mRot[0]; + Point Axis1 = mRot[1]; + Point Axis2 = mRot[2]; + + // Writes normals + planes[0].n = Axis0; + planes[1].n = -Axis0; + planes[2].n = Axis1; + planes[3].n = -Axis1; + planes[4].n = Axis2; + planes[5].n = -Axis2; + + // Compute a point on each plane + Point p0 = mCenter + Axis0 * mExtents.x; + Point p1 = mCenter - Axis0 * mExtents.x; + Point p2 = mCenter + Axis1 * mExtents.y; + Point p3 = mCenter - Axis1 * mExtents.y; + Point p4 = mCenter + Axis2 * mExtents.z; + Point p5 = mCenter - Axis2 * mExtents.z; + + // Compute d + planes[0].d = -(planes[0].n|p0); + planes[1].d = -(planes[1].n|p1); + planes[2].d = -(planes[2].n|p2); + planes[3].d = -(planes[3].n|p3); + planes[4].d = -(planes[4].n|p4); + planes[5].d = -(planes[5].n|p5); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the obb points. + * \param pts [out] 8 box points + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool OBB::ComputePoints(Point* pts) const +{ + // Checkings + if(!pts) return false; + + Point Axis0 = mRot[0]; + Point Axis1 = mRot[1]; + Point Axis2 = mRot[2]; + + Axis0 *= mExtents.x; + Axis1 *= mExtents.y; + Axis2 *= mExtents.z; + + // 7+------+6 0 = --- + // /| /| 1 = +-- + // / | / | 2 = ++- + // / 4+---/--+5 3 = -+- + // 3+------+2 / y z 4 = --+ + // | / | / | / 5 = +-+ + // |/ |/ |/ 6 = +++ + // 0+------+1 *---x 7 = -++ + + pts[0] = mCenter - Axis0 - Axis1 - Axis2; + pts[1] = mCenter + Axis0 - Axis1 - Axis2; + pts[2] = mCenter + Axis0 + Axis1 - Axis2; + pts[3] = mCenter - Axis0 + Axis1 - Axis2; + pts[4] = mCenter - Axis0 - Axis1 + Axis2; + pts[5] = mCenter + Axis0 - Axis1 + Axis2; + pts[6] = mCenter + Axis0 + Axis1 + Axis2; + pts[7] = mCenter - Axis0 + Axis1 + Axis2; + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes vertex normals. + * \param pts [out] 8 box points + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool OBB::ComputeVertexNormals(Point* pts) const +{ + static const float VertexNormals[] = + { + -INVSQRT3, -INVSQRT3, -INVSQRT3, + INVSQRT3, -INVSQRT3, -INVSQRT3, + INVSQRT3, INVSQRT3, -INVSQRT3, + -INVSQRT3, INVSQRT3, -INVSQRT3, + -INVSQRT3, -INVSQRT3, INVSQRT3, + INVSQRT3, -INVSQRT3, INVSQRT3, + INVSQRT3, INVSQRT3, INVSQRT3, + -INVSQRT3, INVSQRT3, INVSQRT3 + }; + + if(!pts) return false; + + const Point* VN = (const Point*)VertexNormals; + for(udword i=0;i<8;i++) + { + pts[i] = VN[i] * mRot; + } + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Returns edges. + * \return 24 indices (12 edges) indexing the list returned by ComputePoints() + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +const udword* OBB::GetEdges() const +{ + static const udword Indices[] = { + 0, 1, 1, 2, 2, 3, 3, 0, + 7, 6, 6, 5, 5, 4, 4, 7, + 1, 5, 6, 2, + 3, 7, 4, 0 + }; + return Indices; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Returns local edge normals. + * \return edge normals in local space + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +const Point* OBB::GetLocalEdgeNormals() const +{ + static const float EdgeNormals[] = + { + 0, -INVSQRT2, -INVSQRT2, // 0-1 + INVSQRT2, 0, -INVSQRT2, // 1-2 + 0, INVSQRT2, -INVSQRT2, // 2-3 + -INVSQRT2, 0, -INVSQRT2, // 3-0 + + 0, INVSQRT2, INVSQRT2, // 7-6 + INVSQRT2, 0, INVSQRT2, // 6-5 + 0, -INVSQRT2, INVSQRT2, // 5-4 + -INVSQRT2, 0, INVSQRT2, // 4-7 + + INVSQRT2, -INVSQRT2, 0, // 1-5 + INVSQRT2, INVSQRT2, 0, // 6-2 + -INVSQRT2, INVSQRT2, 0, // 3-7 + -INVSQRT2, -INVSQRT2, 0 // 4-0 + }; + return (const Point*)EdgeNormals; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Returns world edge normal + * \param edge_index [in] 0 <= edge index < 12 + * \param world_normal [out] edge normal in world space + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void OBB::ComputeWorldEdgeNormal(udword edge_index, Point& world_normal) const +{ + ASSERT(edge_index<12); + world_normal = GetLocalEdgeNormals()[edge_index] * mRot; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes an LSS surrounding the OBB. + * \param lss [out] the LSS + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void OBB::ComputeLSS(LSS& lss) const +{ + Point Axis0 = mRot[0]; + Point Axis1 = mRot[1]; + Point Axis2 = mRot[2]; + + switch(mExtents.LargestAxis()) + { + case 0: + lss.mRadius = (mExtents.y + mExtents.z)*0.5f; + lss.mP0 = mCenter + Axis0 * (mExtents.x - lss.mRadius); + lss.mP1 = mCenter - Axis0 * (mExtents.x - lss.mRadius); + break; + case 1: + lss.mRadius = (mExtents.x + mExtents.z)*0.5f; + lss.mP0 = mCenter + Axis1 * (mExtents.y - lss.mRadius); + lss.mP1 = mCenter - Axis1 * (mExtents.y - lss.mRadius); + break; + case 2: + lss.mRadius = (mExtents.x + mExtents.y)*0.5f; + lss.mP0 = mCenter + Axis2 * (mExtents.z - lss.mRadius); + lss.mP1 = mCenter - Axis2 * (mExtents.z - lss.mRadius); + break; + default: {} + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks the OBB is inside another OBB. + * \param box [in] the other OBB + * \return TRUE if we're inside the other box + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +BOOL OBB::IsInside(const OBB& box) const +{ + // Make a 4x4 from the box & inverse it + Matrix4x4 M0Inv; + { + Matrix4x4 M0 = box.mRot; + M0.SetTrans(box.mCenter); + InvertPRMatrix(M0Inv, M0); + } + + // With our inversed 4x4, create box1 in space of box0 + OBB _1in0; + Rotate(M0Inv, _1in0); + + // This should cancel out box0's rotation, i.e. it's now an AABB. + // => Center(0,0,0), Rot(identity) + + // The two boxes are in the same space so now we can compare them. + + // Create the AABB of (box1 in space of box0) + const Matrix3x3& mtx = _1in0.mRot; + + float f = fabsf(mtx.m[0][0] * mExtents.x) + fabsf(mtx.m[1][0] * mExtents.y) + fabsf(mtx.m[2][0] * mExtents.z) - box.mExtents.x; + if(f > _1in0.mCenter.x) return FALSE; + if(-f < _1in0.mCenter.x) return FALSE; + + f = fabsf(mtx.m[0][1] * mExtents.x) + fabsf(mtx.m[1][1] * mExtents.y) + fabsf(mtx.m[2][1] * mExtents.z) - box.mExtents.y; + if(f > _1in0.mCenter.y) return FALSE; + if(-f < _1in0.mCenter.y) return FALSE; + + f = fabsf(mtx.m[0][2] * mExtents.x) + fabsf(mtx.m[1][2] * mExtents.y) + fabsf(mtx.m[2][2] * mExtents.z) - box.mExtents.z; + if(f > _1in0.mCenter.z) return FALSE; + if(-f < _1in0.mCenter.z) return FALSE; + + return TRUE; +} diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceOBB.h b/libs/ode-0.16.1/OPCODE/Ice/IceOBB.h new file mode 100644 index 0000000..d6cf43e --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceOBB.h @@ -0,0 +1,177 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains OBB-related code. (oriented bounding box) + * \file IceOBB.h + * \author Pierre Terdiman + * \date January, 13, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEOBB_H__ +#define __ICEOBB_H__ + + // Forward declarations + class LSS; + + class ICEMATHS_API OBB + { + public: + //! Constructor + inline_ OBB() {} + //! Constructor + inline_ OBB(const Point& center, const Point& extents, const Matrix3x3& rot) : mCenter(center), mExtents(extents), mRot(rot) {} + //! Destructor + inline_ ~OBB() {} + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups an empty OBB. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void SetEmpty() + { + mCenter.Zero(); + mExtents.Set(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT); + mRot.Identity(); + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Tests if a point is contained within the OBB. + * \param p [in] the world point to test + * \return true if inside the OBB + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool ContainsPoint(const Point& p) const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Builds an OBB from an AABB and a world transform. + * \param aabb [in] the aabb + * \param mat [in] the world transform + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void Create(const AABB& aabb, const Matrix4x4& mat); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Recomputes the OBB after an arbitrary transform by a 4x4 matrix. + * \param mtx [in] the transform matrix + * \param obb [out] the transformed OBB + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void Rotate(const Matrix4x4& mtx, OBB& obb) const + { + // The extents remain constant + obb.mExtents = mExtents; + // The center gets x-formed + obb.mCenter = mCenter * mtx; + // Combine rotations + obb.mRot = mRot * Matrix3x3(mtx); + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks the OBB is valid. + * \return true if the box is valid + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL IsValid() const + { + // Consistency condition for (Center, Extents) boxes: Extents >= 0.0f + if(mExtents.x < 0.0f) return FALSE; + if(mExtents.y < 0.0f) return FALSE; + if(mExtents.z < 0.0f) return FALSE; + return TRUE; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes the obb planes. + * \param planes [out] 6 box planes + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool ComputePlanes(Plane* planes) const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes the obb points. + * \param pts [out] 8 box points + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool ComputePoints(Point* pts) const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes vertex normals. + * \param pts [out] 8 box points + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool ComputeVertexNormals(Point* pts) const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Returns edges. + * \return 24 indices (12 edges) indexing the list returned by ComputePoints() + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + const udword* GetEdges() const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Returns local edge normals. + * \return edge normals in local space + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + const Point* GetLocalEdgeNormals() const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Returns world edge normal + * \param edge_index [in] 0 <= edge index < 12 + * \param world_normal [out] edge normal in world space + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void ComputeWorldEdgeNormal(udword edge_index, Point& world_normal) const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes an LSS surrounding the OBB. + * \param lss [out] the LSS + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void ComputeLSS(LSS& lss) const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks the OBB is inside another OBB. + * \param box [in] the other OBB + * \return TRUE if we're inside the other box + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + BOOL IsInside(const OBB& box) const; + + inline_ const Point& GetCenter() const { return mCenter; } + inline_ const Point& GetExtents() const { return mExtents; } + inline_ const Matrix3x3& GetRot() const { return mRot; } + + inline_ void GetRotatedExtents(Matrix3x3& extents) const + { + extents = mRot; + extents.Scale(mExtents); + } + + Point mCenter; //!< B for Box + Point mExtents; //!< B for Bounding + Matrix3x3 mRot; //!< O for Oriented + + // Orientation is stored in row-major format, + // i.e. rows = eigen vectors of the covariance matrix + }; + +#endif // __ICEOBB_H__ diff --git a/libs/ode-0.16.1/OPCODE/Ice/IcePairs.h b/libs/ode-0.16.1/OPCODE/Ice/IcePairs.h new file mode 100644 index 0000000..2c09b92 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IcePairs.h @@ -0,0 +1,45 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a simple pair class. + * \file IcePairs.h + * \author Pierre Terdiman + * \date January, 13, 2003 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEPAIRS_H__ +#define __ICEPAIRS_H__ + + //! A generic couple structure + struct ICECORE_API Pair + { + inline_ Pair() {} + inline_ Pair(udword i0, udword i1) : id0(i0), id1(i1) {} + + udword id0; //!< First index of the pair + udword id1; //!< Second index of the pair + }; + + class ICECORE_API Pairs : private Container + { + public: + // Constructor / Destructor + Pairs() {} + ~Pairs() {} + + inline_ udword GetNbPairs() const { return GetNbEntries()>>1; } + inline_ const Pair* GetPairs() const { return (const Pair*)GetEntries(); } + inline_ const Pair* GetPair(udword i) const { return (const Pair*)&GetEntries()[i+i]; } + + inline_ BOOL HasPairs() const { return IsNotEmpty(); } + + inline_ void ResetPairs() { Reset(); } + inline_ void DeleteLastPair() { DeleteLastEntry(); DeleteLastEntry(); } + + inline_ void AddPair(const Pair& p) { Add(p.id0).Add(p.id1); } + inline_ void AddPair(udword id0, udword id1) { Add(id0).Add(id1); } + }; + +#endif // __ICEPAIRS_H__ diff --git a/libs/ode-0.16.1/OPCODE/Ice/IcePlane.cpp b/libs/ode-0.16.1/OPCODE/Ice/IcePlane.cpp new file mode 100644 index 0000000..394b31b --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IcePlane.cpp @@ -0,0 +1,45 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for planes. + * \file IcePlane.cpp + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Plane class. + * \class Plane + * \author Pierre Terdiman + * \version 1.0 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace IceMaths; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the plane equation from 3 points. + * \param p0 [in] first point + * \param p1 [in] second point + * \param p2 [in] third point + * \return Self-reference + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Plane& Plane::Set(const Point& p0, const Point& p1, const Point& p2) +{ + Point Edge0 = p1 - p0; + Point Edge1 = p2 - p0; + + n = Edge0 ^ Edge1; + n.Normalize(); + + d = -(p0 | n); + + return *this; +} diff --git a/libs/ode-0.16.1/OPCODE/Ice/IcePlane.h b/libs/ode-0.16.1/OPCODE/Ice/IcePlane.h new file mode 100644 index 0000000..4d47081 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IcePlane.h @@ -0,0 +1,113 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for planes. + * \file IcePlane.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEPLANE_H__ +#define __ICEPLANE_H__ + + #define PLANE_EPSILON (1.0e-7f) + + class ICEMATHS_API Plane + { + public: + //! Constructor + inline_ Plane() { } + //! Constructor from a normal and a distance + inline_ Plane(float nx, float ny, float nz, float d) { Set(nx, ny, nz, d); } + //! Constructor from a point on the plane and a normal + inline_ Plane(const Point& p, const Point& n) { Set(p, n); } + //! Constructor from three points + inline_ Plane(const Point& p0, const Point& p1, const Point& p2) { Set(p0, p1, p2); } + //! Constructor from a normal and a distance + inline_ Plane(const Point& _n, float _d) { n = _n; d = _d; } + //! Copy constructor + inline_ Plane(const Plane& plane) : n(plane.n), d(plane.d) { } + //! Destructor + inline_ ~Plane() { } + + inline_ Plane& Zero() { n.Zero(); d = 0.0f; return *this; } + inline_ Plane& Set(float nx, float ny, float nz, float _d) { n.Set(nx, ny, nz); d = _d; return *this; } + inline_ Plane& Set(const Point& p, const Point& _n) { n = _n; d = - p | _n; return *this; } + Plane& Set(const Point& p0, const Point& p1, const Point& p2); + + inline_ float Distance(const Point& p) const { return (p | n) + d; } + inline_ bool Belongs(const Point& p) const { return fabsf(Distance(p)) < PLANE_EPSILON; } + + inline_ void Normalize() + { + float Denom = 1.0f / n.Magnitude(); + n.x *= Denom; + n.y *= Denom; + n.z *= Denom; + d *= Denom; + } + public: + // Members + Point n; //!< The normal to the plane + float d; //!< The distance from the origin + + // Cast operators + inline_ operator Point() const { return n; } + inline_ operator HPoint() const { return HPoint(n, d); } + + // Arithmetic operators + inline_ Plane operator*(const Matrix4x4& m) const + { + // Old code from Irion. Kept for reference. + Plane Ret(*this); + return Ret *= m; + } + + inline_ Plane& operator*=(const Matrix4x4& m) + { + // Old code from Irion. Kept for reference. + Point n2 = HPoint(n, 0.0f) * m; + d = -((Point) (HPoint( -d*n, 1.0f ) * m) | n2); + n = n2; + return *this; + } + }; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Transforms a plane by a 4x4 matrix. Same as Plane * Matrix4x4 operator, but faster. + * \param transformed [out] transformed plane + * \param plane [in] source plane + * \param transform [in] transform matrix + * \warning the plane normal must be unit-length + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void TransformPlane(Plane& transformed, const Plane& plane, const Matrix4x4& transform) + { + // Rotate the normal using the rotation part of the 4x4 matrix + transformed.n = plane.n * Matrix3x3(transform); + + // Compute new d + transformed.d = plane.d - (Point(transform.GetTrans())|transformed.n); + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Transforms a plane by a 4x4 matrix. Same as Plane * Matrix4x4 operator, but faster. + * \param plane [in/out] source plane (transformed on return) + * \param transform [in] transform matrix + * \warning the plane normal must be unit-length + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void TransformPlane(Plane& plane, const Matrix4x4& transform) + { + // Rotate the normal using the rotation part of the 4x4 matrix + plane.n *= Matrix3x3(transform); + + // Compute new d + plane.d -= Point(transform.GetTrans())|plane.n; + } + +#endif // __ICEPLANE_H__ diff --git a/libs/ode-0.16.1/OPCODE/Ice/IcePoint.cpp b/libs/ode-0.16.1/OPCODE/Ice/IcePoint.cpp new file mode 100644 index 0000000..428908a --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IcePoint.cpp @@ -0,0 +1,191 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for 3D vectors. + * \file IcePoint.cpp + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * 3D point. + * + * The name is "Point" instead of "Vector" since a vector is N-dimensional, whereas a point is an implicit "vector of dimension 3". + * So the choice was between "Point" and "Vector3", the first one looked better (IMHO). + * + * Some people, then, use a typedef to handle both points & vectors using the same class: typedef Point Vector3; + * This is bad since it opens the door to a lot of confusion while reading the code. I know it may sounds weird but check this out: + * + * \code + * Point P0,P1 = some 3D points; + * Point Delta = P1 - P0; + * \endcode + * + * This compiles fine, although you should have written: + * + * \code + * Point P0,P1 = some 3D points; + * Vector3 Delta = P1 - P0; + * \endcode + * + * Subtle things like this are not caught at compile-time, and when you find one in the code, you never know whether it's a mistake + * from the author or something you don't get. + * + * One way to handle it at compile-time would be to use different classes for Point & Vector3, only overloading operator "-" for vectors. + * But then, you get a lot of redundant code in thoses classes, and basically it's really a lot of useless work. + * + * Another way would be to use homogeneous points: w=1 for points, w=0 for vectors. That's why the HPoint class exists. Now, to store + * your model's vertices and in most cases, you really want to use Points to save ram. + * + * \class Point + * \author Pierre Terdiman + * \version 1.0 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace IceMaths; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Creates a positive unit random vector. + * \return Self-reference + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Point& Point::PositiveUnitRandomVector() +{ + x = UnitRandomFloat(); + y = UnitRandomFloat(); + z = UnitRandomFloat(); + Normalize(); + return *this; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Creates a unit random vector. + * \return Self-reference + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Point& Point::UnitRandomVector() +{ + x = UnitRandomFloat() - 0.5f; + y = UnitRandomFloat() - 0.5f; + z = UnitRandomFloat() - 0.5f; + Normalize(); + return *this; +} + +// Cast operator +// WARNING: not inlined +Point::operator HPoint() const { return HPoint(x, y, z, 0.0f); } + +Point& Point::Refract(const Point& eye, const Point& n, float refractindex, Point& refracted) +{ + // Point EyePt = eye position + // Point p = current vertex + // Point n = vertex normal + // Point rv = refracted vector + // Eye vector - doesn't need to be normalized + Point Env; + Env.x = eye.x - x; + Env.y = eye.y - y; + Env.z = eye.z - z; + + float NDotE = n|Env; + float NDotN = n|n; + NDotE /= refractindex; + + // Refracted vector + refracted = n*NDotE - Env*NDotN; + + return *this; +} + +Point& Point::ProjectToPlane(const Plane& p) +{ + *this-= (p.d + (*this|p.n))*p.n; + return *this; +} + +void Point::ProjectToScreen(float halfrenderwidth, float halfrenderheight, const Matrix4x4& mat, HPoint& projected) const +{ + projected = HPoint(x, y, z, 1.0f) * mat; + projected.w = 1.0f / projected.w; + + projected.x*=projected.w; + projected.y*=projected.w; + projected.z*=projected.w; + + projected.x *= halfrenderwidth; projected.x += halfrenderwidth; + projected.y *= -halfrenderheight; projected.y += halfrenderheight; +} + +void Point::SetNotUsed() +{ + // We use a particular integer pattern : 0xffffffff everywhere. This is a NAN. + x = y = z = FR(0xffffffff); +} + +BOOL Point::IsNotUsed() const +{ + if(IR(x)!=0xffffffff) return FALSE; + if(IR(y)!=0xffffffff) return FALSE; + if(IR(z)!=0xffffffff) return FALSE; + return TRUE; +} + +Point& Point::Mult(const Matrix3x3& mat, const Point& a) +{ + x = a.x * mat.m[0][0] + a.y * mat.m[0][1] + a.z * mat.m[0][2]; + y = a.x * mat.m[1][0] + a.y * mat.m[1][1] + a.z * mat.m[1][2]; + z = a.x * mat.m[2][0] + a.y * mat.m[2][1] + a.z * mat.m[2][2]; + return *this; +} + +Point& Point::Mult2(const Matrix3x3& mat1, const Point& a1, const Matrix3x3& mat2, const Point& a2) +{ + x = a1.x * mat1.m[0][0] + a1.y * mat1.m[0][1] + a1.z * mat1.m[0][2] + a2.x * mat2.m[0][0] + a2.y * mat2.m[0][1] + a2.z * mat2.m[0][2]; + y = a1.x * mat1.m[1][0] + a1.y * mat1.m[1][1] + a1.z * mat1.m[1][2] + a2.x * mat2.m[1][0] + a2.y * mat2.m[1][1] + a2.z * mat2.m[1][2]; + z = a1.x * mat1.m[2][0] + a1.y * mat1.m[2][1] + a1.z * mat1.m[2][2] + a2.x * mat2.m[2][0] + a2.y * mat2.m[2][1] + a2.z * mat2.m[2][2]; + return *this; +} + +Point& Point::Mac(const Matrix3x3& mat, const Point& a) +{ + x += a.x * mat.m[0][0] + a.y * mat.m[0][1] + a.z * mat.m[0][2]; + y += a.x * mat.m[1][0] + a.y * mat.m[1][1] + a.z * mat.m[1][2]; + z += a.x * mat.m[2][0] + a.y * mat.m[2][1] + a.z * mat.m[2][2]; + return *this; +} + +Point& Point::TransMult(const Matrix3x3& mat, const Point& a) +{ + x = a.x * mat.m[0][0] + a.y * mat.m[1][0] + a.z * mat.m[2][0]; + y = a.x * mat.m[0][1] + a.y * mat.m[1][1] + a.z * mat.m[2][1]; + z = a.x * mat.m[0][2] + a.y * mat.m[1][2] + a.z * mat.m[2][2]; + return *this; +} + +Point& Point::Transform(const Point& r, const Matrix3x3& rotpos, const Point& linpos) +{ + x = r.x * rotpos.m[0][0] + r.y * rotpos.m[0][1] + r.z * rotpos.m[0][2] + linpos.x; + y = r.x * rotpos.m[1][0] + r.y * rotpos.m[1][1] + r.z * rotpos.m[1][2] + linpos.y; + z = r.x * rotpos.m[2][0] + r.y * rotpos.m[2][1] + r.z * rotpos.m[2][2] + linpos.z; + return *this; +} + +Point& Point::InvTransform(const Point& r, const Matrix3x3& rotpos, const Point& linpos) +{ + float sx = r.x - linpos.x; + float sy = r.y - linpos.y; + float sz = r.z - linpos.z; + x = sx * rotpos.m[0][0] + sy * rotpos.m[1][0] + sz * rotpos.m[2][0]; + y = sx * rotpos.m[0][1] + sy * rotpos.m[1][1] + sz * rotpos.m[2][1]; + z = sx * rotpos.m[0][2] + sy * rotpos.m[1][2] + sz * rotpos.m[2][2]; + return *this; +} diff --git a/libs/ode-0.16.1/OPCODE/Ice/IcePoint.h b/libs/ode-0.16.1/OPCODE/Ice/IcePoint.h new file mode 100644 index 0000000..7c8a931 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IcePoint.h @@ -0,0 +1,530 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for 3D vectors. + * \file IcePoint.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEPOINT_H__ +#define __ICEPOINT_H__ + + // Forward declarations + class HPoint; + class Plane; + class Matrix3x3; + class Matrix4x4; + + #define CROSS2D(a, b) (a.x*b.y - b.x*a.y) + + const float EPSILON2 = 1.0e-20f; + + class ICEMATHS_API Point + { + public: + + //! Empty constructor + inline_ Point() {} + //! Constructor from a single float +// inline_ Point(float val) : x(val), y(val), z(val) {} +// Removed since it introduced the nasty "Point T = *Matrix4x4.GetTrans();" bug....... + //! Constructor from floats + template<typename toffsetfloat> + inline_ Point(toffsetfloat xx, toffsetfloat yy, toffsetfloat zz) : x((float)xx), y((float)yy), z((float)zz) {} + //! Constructor from array + inline_ Point(const float f[3]) : x(f[X]), y(f[Y]), z(f[Z]) {} + //! Copy constructor + inline_ Point(const Point& p) : x(p.x), y(p.y), z(p.z) {} + //! Destructor + inline_ ~Point() {} + + //! Clears the vector + inline_ Point& Zero() { x = y = z = 0.0f; return *this; } + + //! + infinity + inline_ Point& SetPlusInfinity() { x = y = z = MAX_FLOAT; return *this; } + //! - infinity + inline_ Point& SetMinusInfinity() { x = y = z = MIN_FLOAT; return *this; } + + //! Sets positive unit random vector + Point& PositiveUnitRandomVector(); + //! Sets unit random vector + Point& UnitRandomVector(); + + //! Assignment from values + template<typename toffsetfloat> + inline_ Point& Set(toffsetfloat xx, toffsetfloat yy, toffsetfloat zz) { x = (float)xx; y = (float)yy; z = (float)zz; return *this; } + //! Assignment from array + inline_ Point& Set(const float f[3]) { x = f[X]; y = f[Y]; z = f[Z]; return *this; } + //! Assignment from another point + inline_ Point& Set(const Point& src) { x = src.x; y = src.y; z = src.z; return *this; } + + //! Adds a vector + inline_ Point& Add(const Point& p) { x += p.x; y += p.y; z += p.z; return *this; } + //! Adds a vector + inline_ Point& Add(float xx, float yy, float zz) { x += xx; y += yy; z += zz; return *this; } + //! Adds a vector + inline_ Point& Add(const float f[3]) { x += f[X]; y += f[Y]; z += f[Z]; return *this; } + //! Adds vectors + inline_ Point& Add(const Point& p, const Point& q) { x = p.x+q.x; y = p.y+q.y; z = p.z+q.z; return *this; } + + //! Subtracts a vector + inline_ Point& Sub(const Point& p) { x -= p.x; y -= p.y; z -= p.z; return *this; } + //! Subtracts a vector + inline_ Point& Sub(float xx, float yy, float zz) { x -= xx; y -= yy; z -= zz; return *this; } + //! Subtracts a vector + inline_ Point& Sub(const float f[3]) { x -= f[X]; y -= f[Y]; z -= f[Z]; return *this; } + //! Subtracts vectors + inline_ Point& Sub(const Point& p, const Point& q) { x = p.x-q.x; y = p.y-q.y; z = p.z-q.z; return *this; } + + //! this = -this + inline_ Point& Neg() { x = -x; y = -y; z = -z; return *this; } + //! this = -a + inline_ Point& Neg(const Point& a) { x = -a.x; y = -a.y; z = -a.z; return *this; } + + //! Multiplies by a scalar + inline_ Point& Mult(float s) { x *= s; y *= s; z *= s; return *this; } + + //! this = a * scalar + inline_ Point& Mult(const Point& a, float scalar) + { + x = a.x * scalar; + y = a.y * scalar; + z = a.z * scalar; + return *this; + } + + //! this = a + b * scalar + inline_ Point& Mac(const Point& a, const Point& b, float scalar) + { + x = a.x + b.x * scalar; + y = a.y + b.y * scalar; + z = a.z + b.z * scalar; + return *this; + } + + //! this = this + a * scalar + inline_ Point& Mac(const Point& a, float scalar) + { + x += a.x * scalar; + y += a.y * scalar; + z += a.z * scalar; + return *this; + } + + //! this = a - b * scalar + inline_ Point& Msc(const Point& a, const Point& b, float scalar) + { + x = a.x - b.x * scalar; + y = a.y - b.y * scalar; + z = a.z - b.z * scalar; + return *this; + } + + //! this = this - a * scalar + inline_ Point& Msc(const Point& a, float scalar) + { + x -= a.x * scalar; + y -= a.y * scalar; + z -= a.z * scalar; + return *this; + } + + //! this = a + b * scalarb + c * scalarc + inline_ Point& Mac2(const Point& a, const Point& b, float scalarb, const Point& c, float scalarc) + { + x = a.x + b.x * scalarb + c.x * scalarc; + y = a.y + b.y * scalarb + c.y * scalarc; + z = a.z + b.z * scalarb + c.z * scalarc; + return *this; + } + + //! this = a - b * scalarb - c * scalarc + inline_ Point& Msc2(const Point& a, const Point& b, float scalarb, const Point& c, float scalarc) + { + x = a.x - b.x * scalarb - c.x * scalarc; + y = a.y - b.y * scalarb - c.y * scalarc; + z = a.z - b.z * scalarb - c.z * scalarc; + return *this; + } + + //! this = mat * a + inline_ Point& Mult(const Matrix3x3& mat, const Point& a); + + //! this = mat1 * a1 + mat2 * a2 + inline_ Point& Mult2(const Matrix3x3& mat1, const Point& a1, const Matrix3x3& mat2, const Point& a2); + + //! this = this + mat * a + inline_ Point& Mac(const Matrix3x3& mat, const Point& a); + + //! this = transpose(mat) * a + inline_ Point& TransMult(const Matrix3x3& mat, const Point& a); + + //! Linear interpolate between two vectors: this = a + t * (b - a) + inline_ Point& Lerp(const Point& a, const Point& b, float t) + { + x = a.x + t * (b.x - a.x); + y = a.y + t * (b.y - a.y); + z = a.z + t * (b.z - a.z); + return *this; + } + + //! Hermite interpolate between p1 and p2. p0 and p3 are used for finding gradient at p1 and p2. + //! this = p0 * (2t^2 - t^3 - t)/2 + //! + p1 * (3t^3 - 5t^2 + 2)/2 + //! + p2 * (4t^2 - 3t^3 + t)/2 + //! + p3 * (t^3 - t^2)/2 + inline_ Point& Herp(const Point& p0, const Point& p1, const Point& p2, const Point& p3, float t) + { + float t2 = t * t; + float t3 = t2 * t; + float kp0 = (2.0f * t2 - t3 - t) * 0.5f; + float kp1 = (3.0f * t3 - 5.0f * t2 + 2.0f) * 0.5f; + float kp2 = (4.0f * t2 - 3.0f * t3 + t) * 0.5f; + float kp3 = (t3 - t2) * 0.5f; + x = p0.x * kp0 + p1.x * kp1 + p2.x * kp2 + p3.x * kp3; + y = p0.y * kp0 + p1.y * kp1 + p2.y * kp2 + p3.y * kp3; + z = p0.z * kp0 + p1.z * kp1 + p2.z * kp2 + p3.z * kp3; + return *this; + } + + //! this = rotpos * r + linpos + inline_ Point& Transform(const Point& r, const Matrix3x3& rotpos, const Point& linpos); + + //! this = trans(rotpos) * (r - linpos) + inline_ Point& InvTransform(const Point& r, const Matrix3x3& rotpos, const Point& linpos); + + //! Returns MIN(x, y, z); + inline_ float Min() const { return MIN(x, MIN(y, z)); } + //! Returns MAX(x, y, z); + inline_ float Max() const { return MAX(x, MAX(y, z)); } + //! Sets each element to be componentwise minimum + inline_ Point& Min(const Point& p) { x = MIN(x, p.x); y = MIN(y, p.y); z = MIN(z, p.z); return *this; } + //! Sets each element to be componentwise maximum + inline_ Point& Max(const Point& p) { x = MAX(x, p.x); y = MAX(y, p.y); z = MAX(z, p.z); return *this; } + + //! Clamps each element + inline_ Point& Clamp(float min, float max) + { + if(x<min) x=min; if(x>max) x=max; + if(y<min) y=min; if(y>max) y=max; + if(z<min) z=min; if(z>max) z=max; + return *this; + } + + //! Computes square magnitude + inline_ float SquareMagnitude() const { return x*x + y*y + z*z; } + //! Computes magnitude + inline_ float Magnitude() const { return sqrtf(x*x + y*y + z*z); } + //! Computes volume + inline_ float Volume() const { return x * y * z; } + + //! Checks the point is near zero + inline_ bool ApproxZero() const { return SquareMagnitude() < EPSILON2; } + + //! Tests for exact zero vector + inline_ BOOL IsZero() const + { + if(IR(x) || IR(y) || IR(z)) return FALSE; + return TRUE; + } + + //! Checks point validity + inline_ BOOL IsValid() const + { + if(!IsValidFloat(x)) return FALSE; + if(!IsValidFloat(y)) return FALSE; + if(!IsValidFloat(z)) return FALSE; + return TRUE; + } + + //! Slighty moves the point + void Tweak(udword coord_mask, udword tweak_mask) + { + if(coord_mask&1) { udword Dummy = IR(x); Dummy^=tweak_mask; x = FR(Dummy); } + if(coord_mask&2) { udword Dummy = IR(y); Dummy^=tweak_mask; y = FR(Dummy); } + if(coord_mask&4) { udword Dummy = IR(z); Dummy^=tweak_mask; z = FR(Dummy); } + } + + #define TWEAKMASK 0x3fffff + #define TWEAKNOTMASK ~TWEAKMASK + //! Slighty moves the point out + inline_ void TweakBigger() + { + udword Dummy = (IR(x)&TWEAKNOTMASK); if(!IS_NEGATIVE_FLOAT(x)) Dummy+=TWEAKMASK+1; x = FR(Dummy); + Dummy = (IR(y)&TWEAKNOTMASK); if(!IS_NEGATIVE_FLOAT(y)) Dummy+=TWEAKMASK+1; y = FR(Dummy); + Dummy = (IR(z)&TWEAKNOTMASK); if(!IS_NEGATIVE_FLOAT(z)) Dummy+=TWEAKMASK+1; z = FR(Dummy); + } + + //! Slighty moves the point in + inline_ void TweakSmaller() + { + udword Dummy = (IR(x)&TWEAKNOTMASK); if(IS_NEGATIVE_FLOAT(x)) Dummy+=TWEAKMASK+1; x = FR(Dummy); + Dummy = (IR(y)&TWEAKNOTMASK); if(IS_NEGATIVE_FLOAT(y)) Dummy+=TWEAKMASK+1; y = FR(Dummy); + Dummy = (IR(z)&TWEAKNOTMASK); if(IS_NEGATIVE_FLOAT(z)) Dummy+=TWEAKMASK+1; z = FR(Dummy); + } + + //! Normalizes the vector + inline_ Point& Normalize() + { + float M = x*x + y*y + z*z; + if(M) + { + M = 1.0f / sqrtf(M); + x *= M; + y *= M; + z *= M; + } + return *this; + } + + //! Sets vector length + inline_ Point& SetLength(float length) + { + float NewLength = length / Magnitude(); + x *= NewLength; + y *= NewLength; + z *= NewLength; + return *this; + } + + //! Clamps vector length + inline_ Point& ClampLength(float limit_length) + { + if(limit_length>=0.0f) // Magnitude must be positive + { + float CurrentSquareLength = SquareMagnitude(); + + if(CurrentSquareLength > limit_length * limit_length) + { + float Coeff = limit_length / sqrtf(CurrentSquareLength); + x *= Coeff; + y *= Coeff; + z *= Coeff; + } + } + return *this; + } + + //! Computes distance to another point + inline_ float Distance(const Point& b) const + { + return sqrtf((x - b.x)*(x - b.x) + (y - b.y)*(y - b.y) + (z - b.z)*(z - b.z)); + } + + //! Computes square distance to another point + inline_ float SquareDistance(const Point& b) const + { + return ((x - b.x)*(x - b.x) + (y - b.y)*(y - b.y) + (z - b.z)*(z - b.z)); + } + + //! Dot product dp = this|a + inline_ float Dot(const Point& p) const { return p.x * x + p.y * y + p.z * z; } + + //! Cross product this = a x b + inline_ Point& Cross(const Point& a, const Point& b) + { + 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; + return *this; + } + + //! Vector code ( bitmask = sign(z) | sign(y) | sign(x) ) + inline_ udword VectorCode() const + { + return (IR(x)>>31) | ((IR(y)&SIGN_BITMASK)>>30) | ((IR(z)&SIGN_BITMASK)>>29); + } + + //! Returns largest axis + inline_ PointComponent LargestAxis() const + { + const float* Vals = &x; + PointComponent m = X; + if(Vals[Y] > Vals[m]) m = Y; + if(Vals[Z] > Vals[m]) m = Z; + return m; + } + + //! Returns closest axis + inline_ PointComponent ClosestAxis() const + { + const float* Vals = &x; + PointComponent m = X; + if(AIR(Vals[Y]) > AIR(Vals[m])) m = Y; + if(AIR(Vals[Z]) > AIR(Vals[m])) m = Z; + return m; + } + + //! Returns smallest axis + inline_ PointComponent SmallestAxis() const + { + const float* Vals = &x; + PointComponent m = X; + if(Vals[Y] < Vals[m]) m = Y; + if(Vals[Z] < Vals[m]) m = Z; + return m; + } + + //! Refracts the point + Point& Refract(const Point& eye, const Point& n, float refractindex, Point& refracted); + + //! Projects the point onto a plane + Point& ProjectToPlane(const Plane& p); + + //! Projects the point onto the screen + void ProjectToScreen(float halfrenderwidth, float halfrenderheight, const Matrix4x4& mat, HPoint& projected) const; + + //! Unfolds the point onto a plane according to edge(a,b) + Point& Unfold(Plane& p, Point& a, Point& b); + + //! Hash function from Ville Miettinen + inline_ udword GetHashValue() const + { + const udword* h = (const udword*)(this); + udword f = (h[0]+h[1]*11-(h[2]*17)) & 0x7fffffff; // avoid problems with +-0 + return (f>>22)^(f>>12)^(f); + } + + //! Stuff magic values in the point, marking it as explicitely not used. + void SetNotUsed(); + //! Checks the point is marked as not used + BOOL IsNotUsed() const; + + // Arithmetic operators + + //! Unary operator for Point Negate = - Point + inline_ Point operator-() const { return Point(-x, -y, -z); } + + //! Operator for Point Plus = Point + Point. + inline_ Point operator+(const Point& p) const { return Point(x + p.x, y + p.y, z + p.z); } + //! Operator for Point Minus = Point - Point. + inline_ Point operator-(const Point& p) const { return Point(x - p.x, y - p.y, z - p.z); } + + //! Operator for Point Mul = Point * Point. + inline_ Point operator*(const Point& p) const { return Point(x * p.x, y * p.y, z * p.z); } + //! Operator for Point Scale = Point * float. + inline_ Point operator*(float s) const { return Point(x * s, y * s, z * s ); } + //! Operator for Point Scale = float * Point. + inline_ friend Point operator*(float s, const Point& p) { return Point(s * p.x, s * p.y, s * p.z); } + + //! Operator for Point Div = Point / Point. + inline_ Point operator/(const Point& p) const { return Point(x / p.x, y / p.y, z / p.z); } + //! Operator for Point Scale = Point / float. + inline_ Point operator/(float s) const { s = 1.0f / s; return Point(x * s, y * s, z * s); } + //! Operator for Point Scale = float / Point. + inline_ friend Point operator/(float s, const Point& p) { return Point(s / p.x, s / p.y, s / p.z); } + + //! Operator for float DotProd = Point | Point. + inline_ float operator|(const Point& p) const { return x*p.x + y*p.y + z*p.z; } + //! Operator for Point VecProd = Point ^ Point. + inline_ Point operator^(const Point& p) const + { + return Point( + y * p.z - z * p.y, + z * p.x - x * p.z, + x * p.y - y * p.x ); + } + + //! Operator for Point += Point. + inline_ Point& operator+=(const Point& p) { x += p.x; y += p.y; z += p.z; return *this; } + //! Operator for Point += float. + inline_ Point& operator+=(float s) { x += s; y += s; z += s; return *this; } + + //! Operator for Point -= Point. + inline_ Point& operator-=(const Point& p) { x -= p.x; y -= p.y; z -= p.z; return *this; } + //! Operator for Point -= float. + inline_ Point& operator-=(float s) { x -= s; y -= s; z -= s; return *this; } + + //! Operator for Point *= Point. + inline_ Point& operator*=(const Point& p) { x *= p.x; y *= p.y; z *= p.z; return *this; } + //! Operator for Point *= float. + inline_ Point& operator*=(float s) { x *= s; y *= s; z *= s; return *this; } + + //! Operator for Point /= Point. + inline_ Point& operator/=(const Point& p) { x /= p.x; y /= p.y; z /= p.z; return *this; } + //! Operator for Point /= float. + inline_ Point& operator/=(float s) { s = 1.0f/s; x *= s; y *= s; z *= s; return *this; } + + // Logical operators + + //! Operator for "if(Point==Point)" + inline_ bool operator==(const Point& p) const { return ( (IR(x)==IR(p.x))&&(IR(y)==IR(p.y))&&(IR(z)==IR(p.z))); } + //! Operator for "if(Point!=Point)" + inline_ bool operator!=(const Point& p) const { return ( (IR(x)!=IR(p.x))||(IR(y)!=IR(p.y))||(IR(z)!=IR(p.z))); } + + // Arithmetic operators + + //! Operator for Point Mul = Point * Matrix3x3. + inline_ Point operator*(const Matrix3x3& mat) const + { + class ShadowMatrix3x3{ public: float m[3][3]; }; // To allow inlining + const ShadowMatrix3x3* Mat = (const ShadowMatrix3x3*)&mat; + + return Point( + x * Mat->m[0][0] + y * Mat->m[1][0] + z * Mat->m[2][0], + x * Mat->m[0][1] + y * Mat->m[1][1] + z * Mat->m[2][1], + x * Mat->m[0][2] + y * Mat->m[1][2] + z * Mat->m[2][2] ); + } + + //! Operator for Point Mul = Point * Matrix4x4. + inline_ Point operator*(const Matrix4x4& mat) const + { + class ShadowMatrix4x4{ public: float m[4][4]; }; // To allow inlining + const ShadowMatrix4x4* Mat = (const ShadowMatrix4x4*)&mat; + + return Point( + x * Mat->m[0][0] + y * Mat->m[1][0] + z * Mat->m[2][0] + Mat->m[3][0], + x * Mat->m[0][1] + y * Mat->m[1][1] + z * Mat->m[2][1] + Mat->m[3][1], + x * Mat->m[0][2] + y * Mat->m[1][2] + z * Mat->m[2][2] + Mat->m[3][2]); + } + + //! Operator for Point *= Matrix3x3. + inline_ Point& operator*=(const Matrix3x3& mat) + { + class ShadowMatrix3x3{ public: float m[3][3]; }; // To allow inlining + const ShadowMatrix3x3* Mat = (const ShadowMatrix3x3*)&mat; + + float xp = x * Mat->m[0][0] + y * Mat->m[1][0] + z * Mat->m[2][0]; + float yp = x * Mat->m[0][1] + y * Mat->m[1][1] + z * Mat->m[2][1]; + float zp = x * Mat->m[0][2] + y * Mat->m[1][2] + z * Mat->m[2][2]; + + x = xp; y = yp; z = zp; + + return *this; + } + + //! Operator for Point *= Matrix4x4. + inline_ Point& operator*=(const Matrix4x4& mat) + { + class ShadowMatrix4x4{ public: float m[4][4]; }; // To allow inlining + const ShadowMatrix4x4* Mat = (const ShadowMatrix4x4*)&mat; + + float xp = x * Mat->m[0][0] + y * Mat->m[1][0] + z * Mat->m[2][0] + Mat->m[3][0]; + float yp = x * Mat->m[0][1] + y * Mat->m[1][1] + z * Mat->m[2][1] + Mat->m[3][1]; + float zp = x * Mat->m[0][2] + y * Mat->m[1][2] + z * Mat->m[2][2] + Mat->m[3][2]; + + x = xp; y = yp; z = zp; + + return *this; + } + + // Cast operators + + //! Cast a Point to a HPoint. w is set to zero. + operator HPoint() const; + + inline_ operator const float*() const { return &x; } + inline_ operator float*() { return &x; } + + public: + float x, y, z; + }; + + FUNCTION ICEMATHS_API void Normalize1(Point& a); + FUNCTION ICEMATHS_API void Normalize2(Point& a); + +#endif //__ICEPOINT_H__ diff --git a/libs/ode-0.16.1/OPCODE/Ice/IcePreprocessor.h b/libs/ode-0.16.1/OPCODE/Ice/IcePreprocessor.h new file mode 100644 index 0000000..dbeca38 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IcePreprocessor.h @@ -0,0 +1,132 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains preprocessor stuff. This should be the first included header. + * \file IcePreprocessor.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEPREPROCESSOR_H__ +#define __ICEPREPROCESSOR_H__ + + // Check platform + #if defined( _WIN32 ) || defined( WIN32 ) + // #pragma message("Compiling on Windows...") + #define PLATFORM_WINDOWS + #else + // don't issue pragmas on unknown platforms + // #pragma message("Compiling on unknown platform...") + #endif + + // Check compiler + #if defined(_MSC_VER) + // #pragma message("Compiling with VC++...") + #define COMPILER_VISUAL_CPP + #else + // don't issue pragmas on unknown platforms + // #pragma message("Compiling with unknown compiler...") + #endif + + // Check compiler options. If this file is included in user-apps, this + // shouldn't be needed, so that they can use what they like best. + #ifndef ICE_DONT_CHECK_COMPILER_OPTIONS + #ifdef COMPILER_VISUAL_CPP + #if defined(_CHAR_UNSIGNED) + #endif + + #if defined(_CPPRTTI) + #error Please disable RTTI... + #endif + + #if defined(_CPPUNWIND) + #error Please disable exceptions... + #endif + + #if defined(_MT) + // Multithreading + #endif + #endif + #endif + + // Check debug mode + #ifdef DEBUG // May be defined instead of _DEBUG. Let's fix it. + #ifndef _DEBUG + #define _DEBUG + #endif + #endif + + #ifdef _DEBUG + // Here you may define items for debug builds + #endif + + #ifndef THIS_FILE + #define THIS_FILE __FILE__ + #endif + + #ifndef ICE_NO_DLL + #ifdef ICECORE_EXPORTS + #define ICECORE_API __declspec(dllexport) + #else + #define ICECORE_API __declspec(dllimport) + #endif + #else + #define ICECORE_API + #endif + + // Don't override new/delete +// #define DEFAULT_NEWDELETE + #define DONT_TRACK_MEMORY_LEAKS + + #define FUNCTION extern "C" + + // Cosmetic stuff [mainly useful with multiple inheritance] + #define override(base_class) virtual + + // Our own inline keyword, so that: + // - we can switch to __forceinline to check it's really better or not + // - we can remove __forceinline if the compiler doesn't support it +// #define inline_ __forceinline +// #define inline_ inline + + // Contributed by Bruce Mitchener + #if defined(COMPILER_VISUAL_CPP) + #define inline_ __forceinline +// #define inline_ inline + #elif defined(__GNUC__) && __GNUC__ < 3 + #define inline_ inline + #elif defined(__GNUC__) + #define inline_ inline __attribute__ ((always_inline)) + #else + #define inline_ inline + #endif + + // Down the hatch +#ifdef _MSC_VER + #pragma inline_depth( 255 ) +#endif + + #ifdef COMPILER_VISUAL_CPP + #pragma intrinsic(memcmp) + #pragma intrinsic(memcpy) + #pragma intrinsic(memset) + #pragma intrinsic(strcat) + #pragma intrinsic(strcmp) + #pragma intrinsic(strcpy) + #pragma intrinsic(strlen) + #pragma intrinsic(abs) + #pragma intrinsic(labs) + #endif + + // ANSI compliance + #ifdef _DEBUG + // Remove painful warning in debug + inline_ bool __False__(){ return false; } + #define for if(__False__()){} else for + #else + #define for if(0){} else for + #endif + +#endif // __ICEPREPROCESSOR_H__ diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceRandom.cpp b/libs/ode-0.16.1/OPCODE/Ice/IceRandom.cpp new file mode 100644 index 0000000..cc63a04 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceRandom.cpp @@ -0,0 +1,35 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for random generators. + * \file IceRandom.cpp + * \author Pierre Terdiman + * \date August, 9, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace IceCore; + +void IceCore:: SRand(udword seed) +{ + srand(seed); +} + +udword IceCore::Rand() +{ + return rand(); +} + + +static BasicRandom gRandomGenerator(42); + +udword IceCore::GetRandomIndex(udword max_index) +{ + // We don't use rand() since it's limited to RAND_MAX + udword Index = gRandomGenerator.Randomize(); + return Index % max_index; +} + diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceRandom.h b/libs/ode-0.16.1/OPCODE/Ice/IceRandom.h new file mode 100644 index 0000000..3170b33 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceRandom.h @@ -0,0 +1,42 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for random generators. + * \file IceRandom.h + * \author Pierre Terdiman + * \date August, 9, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICERANDOM_H__ +#define __ICERANDOM_H__ + + FUNCTION ICECORE_API void SRand(udword seed); + FUNCTION ICECORE_API udword Rand(); + + //! Returns a unit random floating-point value + inline_ float UnitRandomFloat() { return float(Rand()) * ONE_OVER_RAND_MAX; } + + //! Returns a random index so that 0<= index < max_index + ICECORE_API udword GetRandomIndex(udword max_index); + + class ICECORE_API BasicRandom + { + public: + + //! Constructor + inline_ BasicRandom(udword seed=0) : mRnd(seed) {} + //! Destructor + inline_ ~BasicRandom() {} + + inline_ void SetSeed(udword seed) { mRnd = seed; } + inline_ udword GetCurrentValue() const { return mRnd; } + inline_ udword Randomize() { mRnd = mRnd * 2147001325 + 715136305; return mRnd; } + + private: + udword mRnd; + }; + +#endif // __ICERANDOM_H__ + diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceRay.cpp b/libs/ode-0.16.1/OPCODE/Ice/IceRay.cpp new file mode 100644 index 0000000..6cf0330 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceRay.cpp @@ -0,0 +1,84 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for rays. + * \file IceRay.cpp + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Ray class. + * A ray is a half-line P(t) = mOrig + mDir * t, with 0 <= t <= +infinity + * \class Ray + * \author Pierre Terdiman + * \version 1.0 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/* + O = Origin = impact point + i = normalized vector along the x axis + j = normalized vector along the y axis = actually the normal vector in O + D = Direction vector, norm |D| = 1 + N = Projection of D on y axis, norm |N| = normal reaction + T = Projection of D on x axis, norm |T| = tangential reaction + R = Reflexion vector + + ^y + | + | + | + _ _ _| _ _ _ + * * *| + \ | / + \ |N / | + R\ | /D + \ | / | + \ | / + _________\|/______*_______>x + O T + + Let define theta = angle between D and N. Then cos(theta) = |N| / |D| = |N| since D is normalized. + + j|D = |j|*|D|*cos(theta) => |N| = j|D + + Then we simply have: + + D = N + T + + To compute tangential reaction : + + T = D - N + + To compute reflexion vector : + + R = N - T = N - (D-N) = 2*N - D +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace IceMaths; + +float Ray::SquareDistance(const Point& point, float* t) const +{ + Point Diff = point - mOrig; + float fT = Diff | mDir; + + if(fT<=0.0f) + { + fT = 0.0f; + } + else + { + fT /= mDir.SquareMagnitude(); + Diff -= fT*mDir; + } + + if(t) *t = fT; + + return Diff.SquareMagnitude(); +} diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceRay.h b/libs/ode-0.16.1/OPCODE/Ice/IceRay.h new file mode 100644 index 0000000..0268287 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceRay.h @@ -0,0 +1,98 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for rays. + * \file IceRay.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICERAY_H__ +#define __ICERAY_H__ + + class ICEMATHS_API Ray + { + public: + //! Constructor + inline_ Ray() {} + //! Constructor + inline_ Ray(const Point& orig, const Point& dir) : mOrig(orig), mDir(dir) {} + //! Copy constructor + inline_ Ray(const Ray& ray) : mOrig(ray.mOrig), mDir(ray.mDir) {} + //! Destructor + inline_ ~Ray() {} + + float SquareDistance(const Point& point, float* t=null) const; + inline_ float Distance(const Point& point, float* t=null) const { return sqrtf(SquareDistance(point, t)); } + + Point mOrig; //!< Ray origin + Point mDir; //!< Normalized direction + }; + + inline_ void ComputeReflexionVector(Point& reflected, const Point& incoming_dir, const Point& outward_normal) + { + reflected = incoming_dir - outward_normal * 2.0f * (incoming_dir|outward_normal); + } + + inline_ void ComputeReflexionVector(Point& reflected, const Point& source, const Point& impact, const Point& normal) + { + Point V = impact - source; + reflected = V - normal * 2.0f * (V|normal); + } + + inline_ void DecomposeVector(Point& normal_compo, Point& tangent_compo, const Point& outward_dir, const Point& outward_normal) + { + normal_compo = outward_normal * (outward_dir|outward_normal); + tangent_compo = outward_dir - normal_compo; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Transforms a direction vector from world space to local space + * \param local_dir [out] direction vector in local space + * \param world_dir [in] direction vector in world space + * \param world [in] world transform + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void ComputeLocalDirection(Point& local_dir, const Point& world_dir, const Matrix4x4& world) + { + // Get world direction back in local space +// Matrix3x3 InvWorld = world; +// local_dir = InvWorld * world_dir; + local_dir = Matrix3x3(world) * world_dir; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Transforms a position vector from world space to local space + * \param local_pt [out] position vector in local space + * \param world_pt [in] position vector in world space + * \param world [in] world transform + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void ComputeLocalPoint(Point& local_pt, const Point& world_pt, const Matrix4x4& world) + { + // Get world vertex back in local space + Matrix4x4 InvWorld = world; + InvWorld.Invert(); + local_pt = world_pt * InvWorld; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Transforms a ray from world space to local space + * \param local_ray [out] ray in local space + * \param world_ray [in] ray in world space + * \param world [in] world transform + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void ComputeLocalRay(Ray& local_ray, const Ray& world_ray, const Matrix4x4& world) + { + // Get world ray back in local space + ComputeLocalDirection(local_ray.mDir, world_ray.mDir, world); + ComputeLocalPoint(local_ray.mOrig, world_ray.mOrig, world); + } + +#endif // __ICERAY_H__ diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceRevisitedRadix.cpp b/libs/ode-0.16.1/OPCODE/Ice/IceRevisitedRadix.cpp new file mode 100644 index 0000000..99a586f --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceRevisitedRadix.cpp @@ -0,0 +1,520 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains source code from the article "Radix Sort Revisited". + * \file IceRevisitedRadix.cpp + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Revisited Radix Sort. + * This is my new radix routine: + * - it uses indices and doesn't recopy the values anymore, hence wasting less ram + * - it creates all the histograms in one run instead of four + * - it sorts words faster than dwords and bytes faster than words + * - it correctly sorts negative floating-point values by patching the offsets + * - it automatically takes advantage of temporal coherence + * - multiple keys support is a side effect of temporal coherence + * - it may be worth recoding in asm... (mainly to use FCOMI, FCMOV, etc) [it's probably memory-bound anyway] + * + * History: + * - 08.15.98: very first version + * - 04.04.00: recoded for the radix article + * - 12.xx.00: code lifting + * - 09.18.01: faster CHECK_PASS_VALIDITY thanks to Mark D. Shattuck (who provided other tips, not included here) + * - 10.11.01: added local ram support + * - 01.20.02: bugfix! In very particular cases the last pass was skipped in the float code-path, leading to incorrect sorting...... + * - 01.02.02: - "mIndices" renamed => "mRanks". That's a rank sorter after all. + * - ranks are not "reset" anymore, but implicit on first calls + * - 07.05.02: - offsets rewritten with one less indirection. + * - 11.03.02: - "bool" replaced with RadixHint enum + * + * \class RadixSort + * \author Pierre Terdiman + * \version 1.4 + * \date August, 15, 1998 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/* +To do: + - add an offset parameter between two input values (avoid some data recopy sometimes) + - unroll ? asm ? + - 11 bits trick & 3 passes as Michael did + - prefetch stuff the day I have a P3 + - make a version with 16-bits indices ? +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace IceCore; + +#define INVALIDATE_RANKS mCurrentSize|=0x80000000 +#define VALIDATE_RANKS mCurrentSize&=0x7fffffff +#define CURRENT_SIZE (mCurrentSize&0x7fffffff) +#define INVALID_RANKS (mCurrentSize&0x80000000) + +#define CHECK_RESIZE(n) \ + if(n!=mPreviousSize) \ + { \ + if(n>mCurrentSize) Resize(n); \ + else ResetRanks(); \ + mPreviousSize = n; \ + } + +#define CREATE_HISTOGRAMS(type, buffer) \ + /* Clear counters/histograms */ \ + ZeroMemory(mHistogram, 256*4*sizeof(udword)); \ + \ + /* Prepare to count */ \ + ubyte* p = (ubyte*)input; \ + ubyte* pe = &p[nb*4]; \ + udword* h0= &mHistogram[0]; /* Histogram for first pass (LSB) */ \ + udword* h1= &mHistogram[256]; /* Histogram for second pass */ \ + udword* h2= &mHistogram[512]; /* Histogram for third pass */ \ + udword* h3= &mHistogram[768]; /* Histogram for last pass (MSB) */ \ + \ + bool AlreadySorted = true; /* Optimism... */ \ + \ + if(INVALID_RANKS) \ + { \ + /* Prepare for temporal coherence */ \ + type* Running = (type*)buffer; \ + type PrevVal = *Running; \ + \ + while(p!=pe) \ + { \ + /* Read input buffer in previous sorted order */ \ + type Val = *Running++; \ + /* Check whether already sorted or not */ \ + if(Val<PrevVal) { AlreadySorted = false; break; } /* Early out */ \ + /* Update for next iteration */ \ + PrevVal = Val; \ + \ + /* Create histograms */ \ + h0[*p++]++; h1[*p++]++; h2[*p++]++; h3[*p++]++; \ + } \ + \ + /* If all input values are already sorted, we just have to return and leave the */ \ + /* previous list unchanged. That way the routine may take advantage of temporal */ \ + /* coherence, for example when used to sort transparent faces. */ \ + if(AlreadySorted) \ + { \ + mNbHits++; \ + for(udword i=0;i<nb;i++) mRanks[i] = i; \ + return *this; \ + } \ + } \ + else \ + { \ + /* Prepare for temporal coherence */ \ + udword* Indices = mRanks; \ + type PrevVal = (type)buffer[*Indices]; \ + \ + while(p!=pe) \ + { \ + /* Read input buffer in previous sorted order */ \ + type Val = (type)buffer[*Indices++]; \ + /* Check whether already sorted or not */ \ + if(Val<PrevVal) { AlreadySorted = false; break; } /* Early out */ \ + /* Update for next iteration */ \ + PrevVal = Val; \ + \ + /* Create histograms */ \ + h0[*p++]++; h1[*p++]++; h2[*p++]++; h3[*p++]++; \ + } \ + \ + /* If all input values are already sorted, we just have to return and leave the */ \ + /* previous list unchanged. That way the routine may take advantage of temporal */ \ + /* coherence, for example when used to sort transparent faces. */ \ + if(AlreadySorted) { mNbHits++; return *this; } \ + } \ + \ + /* Else there has been an early out and we must finish computing the histograms */ \ + while(p!=pe) \ + { \ + /* Create histograms without the previous overhead */ \ + h0[*p++]++; h1[*p++]++; h2[*p++]++; h3[*p++]++; \ + } + +#define CHECK_PASS_VALIDITY(pass) \ + /* Shortcut to current counters */ \ + udword* CurCount = &mHistogram[pass<<8]; \ + \ + /* Reset flag. The sorting pass is supposed to be performed. (default) */ \ + bool PerformPass = true; \ + \ + /* Check pass validity */ \ + \ + /* If all values have the same byte, sorting is useless. */ \ + /* It may happen when sorting bytes or words instead of dwords. */ \ + /* This routine actually sorts words faster than dwords, and bytes */ \ + /* faster than words. Standard running time (O(4*n))is reduced to O(2*n) */ \ + /* for words and O(n) for bytes. Running time for floats depends on actual values... */ \ + \ + /* Get first byte */ \ + ubyte UniqueVal = *(((ubyte*)input)+pass); \ + \ + /* Check that byte's counter */ \ + if(CurCount[UniqueVal]==nb) PerformPass=false; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +RadixSort::RadixSort() : mCurrentSize(0), mRanks(null), mRanks2(null), mTotalCalls(0), mNbHits(0) +{ +#ifndef RADIX_LOCAL_RAM + // Allocate input-independent ram + mHistogram = new udword[256*4]; + mOffset = new udword[256]; +#endif + // Initialize indices + INVALIDATE_RANKS; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +RadixSort::~RadixSort() +{ + // Release everything +#ifndef RADIX_LOCAL_RAM + DELETEARRAY(mOffset); + DELETEARRAY(mHistogram); +#endif + DELETEARRAY(mRanks2); + DELETEARRAY(mRanks); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Resizes the inner lists. + * \param nb [in] new size (number of dwords) + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool RadixSort::Resize(udword nb) +{ + // Free previously used ram + DELETEARRAY(mRanks2); + DELETEARRAY(mRanks); + + // Get some fresh one + mRanks = new udword[nb]; CHECKALLOC(mRanks); + mRanks2 = new udword[nb]; CHECKALLOC(mRanks2); + + return true; +} + +inline_ void RadixSort::CheckResize(udword nb) +{ + udword CurSize = CURRENT_SIZE; + if(nb!=CurSize) + { + if(nb>CurSize) Resize(nb); + mCurrentSize = nb; + INVALIDATE_RANKS; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Main sort routine. + * This one is for integer values. After the call, mRanks contains a list of indices in sorted order, i.e. in the order you may process your data. + * \param input [in] a list of integer values to sort + * \param nb [in] number of values to sort, must be < 2^31 + * \param hint [in] RADIX_SIGNED to handle negative values, RADIX_UNSIGNED if you know your input buffer only contains positive values + * \return Self-Reference + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +RadixSort& RadixSort::Sort(const udword* input, udword nb, RadixHint hint) +{ + // Checkings + if(!input || !nb || nb&0x80000000) return *this; + + // Stats + mTotalCalls++; + + // Resize lists if needed + CheckResize(nb); + +#ifdef RADIX_LOCAL_RAM + // Allocate histograms & offsets on the stack + udword mHistogram[256*4]; +// udword mOffset[256]; + udword* mLink[256]; +#endif + + // Create histograms (counters). Counters for all passes are created in one run. + // Pros: read input buffer once instead of four times + // Cons: mHistogram is 4Kb instead of 1Kb + // We must take care of signed/unsigned values for temporal coherence.... I just + // have 2 code paths even if just a single opcode changes. Self-modifying code, someone? + if(hint==RADIX_UNSIGNED) { CREATE_HISTOGRAMS(udword, input); } + else { CREATE_HISTOGRAMS(sdword, input); } + + // Compute #negative values involved if needed + udword NbNegativeValues = 0; + if(hint==RADIX_SIGNED) + { + // An efficient way to compute the number of negatives values we'll have to deal with is simply to sum the 128 + // last values of the last histogram. Last histogram because that's the one for the Most Significant Byte, + // responsible for the sign. 128 last values because the 128 first ones are related to positive numbers. + udword* h3= &mHistogram[768]; + for(udword i=128;i<256;i++) NbNegativeValues += h3[i]; // 768 for last histogram, 128 for negative part + } + + // Radix sort, j is the pass number (0=LSB, 3=MSB) + for(udword j=0;j<4;j++) + { + CHECK_PASS_VALIDITY(j); + + // Sometimes the fourth (negative) pass is skipped because all numbers are negative and the MSB is 0xFF (for example). This is + // not a problem, numbers are correctly sorted anyway. + if(PerformPass) + { + // Should we care about negative values? + if(j!=3 || hint==RADIX_UNSIGNED) + { + // Here we deal with positive values only + + // Create offsets +// mOffset[0] = 0; +// for(udword i=1;i<256;i++) mOffset[i] = mOffset[i-1] + CurCount[i-1]; + mLink[0] = mRanks2; + for(udword i=1;i<256;i++) mLink[i] = mLink[i-1] + CurCount[i-1]; + } + else + { + // This is a special case to correctly handle negative integers. They're sorted in the right order but at the wrong place. + + // Create biased offsets, in order for negative numbers to be sorted as well +// mOffset[0] = NbNegativeValues; // First positive number takes place after the negative ones + mLink[0] = &mRanks2[NbNegativeValues]; // First positive number takes place after the negative ones +// for(udword i=1;i<128;i++) mOffset[i] = mOffset[i-1] + CurCount[i-1]; // 1 to 128 for positive numbers + for(udword i=1;i<128;i++) mLink[i] = mLink[i-1] + CurCount[i-1]; // 1 to 128 for positive numbers + + // Fixing the wrong place for negative values +// mOffset[128] = 0; + mLink[128] = mRanks2; +// for(i=129;i<256;i++) mOffset[i] = mOffset[i-1] + CurCount[i-1]; + for(udword i=129;i<256;i++) mLink[i] = mLink[i-1] + CurCount[i-1]; + } + + // Perform Radix Sort + ubyte* InputBytes = (ubyte*)input; + InputBytes += j; + if(INVALID_RANKS) + { +// for(udword i=0;i<nb;i++) mRanks2[mOffset[InputBytes[i<<2]]++] = i; + for(udword i=0;i<nb;i++) *mLink[InputBytes[i<<2]]++ = i; + VALIDATE_RANKS; + } + else + { + udword* Indices = mRanks; + udword* IndicesEnd = &mRanks[nb]; + while(Indices!=IndicesEnd) + { + udword id = *Indices++; +// mRanks2[mOffset[InputBytes[id<<2]]++] = id; + *mLink[InputBytes[id<<2]]++ = id; + } + } + + // Swap pointers for next pass. Valid indices - the most recent ones - are in mRanks after the swap. + udword* Tmp = mRanks; mRanks = mRanks2; mRanks2 = Tmp; + } + } + return *this; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Main sort routine. + * This one is for floating-point values. After the call, mRanks contains a list of indices in sorted order, i.e. in the order you may process your data. + * \param input [in] a list of floating-point values to sort + * \param nb [in] number of values to sort, must be < 2^31 + * \return Self-Reference + * \warning only sorts IEEE floating-point values + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +RadixSort& RadixSort::Sort(const float* input2, udword nb) +{ + // Checkings + if(!input2 || !nb || nb&0x80000000) return *this; + + // Stats + mTotalCalls++; + + udword* input = (udword*)input2; + + // Resize lists if needed + CheckResize(nb); + +#ifdef RADIX_LOCAL_RAM + // Allocate histograms & offsets on the stack + udword mHistogram[256*4]; +// udword mOffset[256]; + udword* mLink[256]; +#endif + + // Create histograms (counters). Counters for all passes are created in one run. + // Pros: read input buffer once instead of four times + // Cons: mHistogram is 4Kb instead of 1Kb + // Floating-point values are always supposed to be signed values, so there's only one code path there. + // Please note the floating point comparison needed for temporal coherence! Although the resulting asm code + // is dreadful, this is surprisingly not such a performance hit - well, I suppose that's a big one on first + // generation Pentiums....We can't make comparison on integer representations because, as Chris said, it just + // wouldn't work with mixed positive/negative values.... + { CREATE_HISTOGRAMS(float, input2); } + + // Compute #negative values involved if needed + udword NbNegativeValues = 0; + // An efficient way to compute the number of negatives values we'll have to deal with is simply to sum the 128 + // last values of the last histogram. Last histogram because that's the one for the Most Significant Byte, + // responsible for the sign. 128 last values because the 128 first ones are related to positive numbers. + udword* h3= &mHistogram[768]; + for(udword i=128;i<256;i++) NbNegativeValues += h3[i]; // 768 for last histogram, 128 for negative part + + // Radix sort, j is the pass number (0=LSB, 3=MSB) + for(udword j=0;j<4;j++) + { + // Should we care about negative values? + if(j!=3) + { + // Here we deal with positive values only + CHECK_PASS_VALIDITY(j); + + if(PerformPass) + { + // Create offsets +// mOffset[0] = 0; + mLink[0] = mRanks2; +// for(udword i=1;i<256;i++) mOffset[i] = mOffset[i-1] + CurCount[i-1]; + for(udword i=1;i<256;i++) mLink[i] = mLink[i-1] + CurCount[i-1]; + + // Perform Radix Sort + ubyte* InputBytes = (ubyte*)input; + InputBytes += j; + if(INVALID_RANKS) + { +// for(i=0;i<nb;i++) mRanks2[mOffset[InputBytes[i<<2]]++] = i; + for(udword i=0;i<nb;i++) *mLink[InputBytes[i<<2]]++ = i; + VALIDATE_RANKS; + } + else + { + udword* Indices = mRanks; + udword* IndicesEnd = &mRanks[nb]; + while(Indices!=IndicesEnd) + { + udword id = *Indices++; +// mRanks2[mOffset[InputBytes[id<<2]]++] = id; + *mLink[InputBytes[id<<2]]++ = id; + } + } + + // Swap pointers for next pass. Valid indices - the most recent ones - are in mRanks after the swap. + udword* Tmp = mRanks; mRanks = mRanks2; mRanks2 = Tmp; + } + } + else + { + // This is a special case to correctly handle negative values + CHECK_PASS_VALIDITY(j); + + if(PerformPass) + { + // Create biased offsets, in order for negative numbers to be sorted as well +// mOffset[0] = NbNegativeValues; // First positive number takes place after the negative ones + mLink[0] = &mRanks2[NbNegativeValues]; // First positive number takes place after the negative ones +// for(udword i=1;i<128;i++) mOffset[i] = mOffset[i-1] + CurCount[i-1]; // 1 to 128 for positive numbers + for(udword i=1;i<128;i++) mLink[i] = mLink[i-1] + CurCount[i-1]; // 1 to 128 for positive numbers + + // We must reverse the sorting order for negative numbers! +// mOffset[255] = 0; + mLink[255] = mRanks2; +// for(i=0;i<127;i++) mOffset[254-i] = mOffset[255-i] + CurCount[255-i]; // Fixing the wrong order for negative values + for(udword i=0;i<127;i++) mLink[254-i] = mLink[255-i] + CurCount[255-i]; // Fixing the wrong order for negative values +// for(i=128;i<256;i++) mOffset[i] += CurCount[i]; // Fixing the wrong place for negative values + for(udword i=128;i<256;i++) mLink[i] += CurCount[i]; // Fixing the wrong place for negative values + + // Perform Radix Sort + if(INVALID_RANKS) + { + for(udword i=0;i<nb;i++) + { + udword Radix = input[i]>>24; // Radix byte, same as above. AND is useless here (udword). + // ### cmp to be killed. Not good. Later. +// if(Radix<128) mRanks2[mOffset[Radix]++] = i; // Number is positive, same as above +// else mRanks2[--mOffset[Radix]] = i; // Number is negative, flip the sorting order + if(Radix<128) *mLink[Radix]++ = i; // Number is positive, same as above + else *(--mLink[Radix]) = i; // Number is negative, flip the sorting order + } + VALIDATE_RANKS; + } + else + { + for(udword i=0;i<nb;i++) + { + udword Radix = input[mRanks[i]]>>24; // Radix byte, same as above. AND is useless here (udword). + // ### cmp to be killed. Not good. Later. +// if(Radix<128) mRanks2[mOffset[Radix]++] = mRanks[i]; // Number is positive, same as above +// else mRanks2[--mOffset[Radix]] = mRanks[i]; // Number is negative, flip the sorting order + if(Radix<128) *mLink[Radix]++ = mRanks[i]; // Number is positive, same as above + else *(--mLink[Radix]) = mRanks[i]; // Number is negative, flip the sorting order + } + } + // Swap pointers for next pass. Valid indices - the most recent ones - are in mRanks after the swap. + udword* Tmp = mRanks; mRanks = mRanks2; mRanks2 = Tmp; + } + else + { + // The pass is useless, yet we still have to reverse the order of current list if all values are negative. + if(UniqueVal>=128) + { + if(INVALID_RANKS) + { + // ###Possible? + for(udword i=0;i<nb;i++) mRanks2[i] = nb-i-1; + VALIDATE_RANKS; + } + else + { + for(udword i=0;i<nb;i++) mRanks2[i] = mRanks[nb-i-1]; + } + + // Swap pointers for next pass. Valid indices - the most recent ones - are in mRanks after the swap. + udword* Tmp = mRanks; mRanks = mRanks2; mRanks2 = Tmp; + } + } + } + } + return *this; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Gets the ram used. + * \return memory used in bytes + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +udword RadixSort::GetUsedRam() const +{ + udword UsedRam = sizeof(RadixSort); +#ifndef RADIX_LOCAL_RAM + UsedRam += 256*4*sizeof(udword); // Histograms + UsedRam += 256*sizeof(udword); // Offsets +#endif + UsedRam += 2*CURRENT_SIZE*sizeof(udword); // 2 lists of indices + return UsedRam; +} diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceRevisitedRadix.h b/libs/ode-0.16.1/OPCODE/Ice/IceRevisitedRadix.h new file mode 100644 index 0000000..3bdfc22 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceRevisitedRadix.h @@ -0,0 +1,65 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains source code from the article "Radix Sort Revisited". + * \file IceRevisitedRadix.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICERADIXSORT_H__ +#define __ICERADIXSORT_H__ + + //! Allocate histograms & offsets locally + #define RADIX_LOCAL_RAM + + enum RadixHint + { + RADIX_SIGNED, //!< Input values are signed + RADIX_UNSIGNED, //!< Input values are unsigned + + RADIX_FORCE_DWORD = 0x7fffffff + }; + + class ICECORE_API RadixSort + { + public: + // Constructor/Destructor + RadixSort(); + ~RadixSort(); + // Sorting methods + RadixSort& Sort(const udword* input, udword nb, RadixHint hint=RADIX_SIGNED); + RadixSort& Sort(const float* input, udword nb); + + //! Access to results. mRanks is a list of indices in sorted order, i.e. in the order you may further process your data + inline_ const udword* GetRanks() const { return mRanks; } + + //! mIndices2 gets trashed on calling the sort routine, but otherwise you can recycle it the way you want. + inline_ udword* GetRecyclable() const { return mRanks2; } + + // Stats + udword GetUsedRam() const; + //! Returns the total number of calls to the radix sorter. + inline_ udword GetNbTotalCalls() const { return mTotalCalls; } + //! Returns the number of eraly exits due to temporal coherence. + inline_ udword GetNbHits() const { return mNbHits; } + + private: +#ifndef RADIX_LOCAL_RAM + udword* mHistogram; //!< Counters for each byte + udword* mOffset; //!< Offsets (nearly a cumulative distribution function) +#endif + udword mCurrentSize; //!< Current size of the indices list + udword* mRanks; //!< Two lists, swapped each pass + udword* mRanks2; + // Stats + udword mTotalCalls; //!< Total number of calls to the sort routine + udword mNbHits; //!< Number of early exits due to coherence + // Internal methods + void CheckResize(udword nb); + bool Resize(udword nb); + }; + +#endif // __ICERADIXSORT_H__ diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceSegment.cpp b/libs/ode-0.16.1/OPCODE/Ice/IceSegment.cpp new file mode 100644 index 0000000..cd9ceb7 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceSegment.cpp @@ -0,0 +1,57 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for segments. + * \file IceSegment.cpp + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Segment class. + * A segment is defined by S(t) = mP0 * (1 - t) + mP1 * t, with 0 <= t <= 1 + * Alternatively, a segment is S(t) = Origin + t * Direction for 0 <= t <= 1. + * Direction is not necessarily unit length. The end points are Origin = mP0 and Origin + Direction = mP1. + * + * \class Segment + * \author Pierre Terdiman + * \version 1.0 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace IceMaths; + +float Segment::SquareDistance(const Point& point, float* t) const +{ + Point Diff = point - mP0; + Point Dir = mP1 - mP0; + float fT = Diff | Dir; + + if(fT<=0.0f) + { + fT = 0.0f; + } + else + { + float SqrLen= Dir.SquareMagnitude(); + if(fT>=SqrLen) + { + fT = 1.0f; + Diff -= Dir; + } + else + { + fT /= SqrLen; + Diff -= fT*Dir; + } + } + + if(t) *t = fT; + + return Diff.SquareMagnitude(); +} diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceSegment.h b/libs/ode-0.16.1/OPCODE/Ice/IceSegment.h new file mode 100644 index 0000000..8d66322 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceSegment.h @@ -0,0 +1,55 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for segments. + * \file IceSegment.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICESEGMENT_H__ +#define __ICESEGMENT_H__ + + class ICEMATHS_API Segment + { + public: + //! Constructor + inline_ Segment() {} + //! Constructor + inline_ Segment(const Point& p0, const Point& p1) : mP0(p0), mP1(p1) {} + //! Copy constructor + inline_ Segment(const Segment& seg) : mP0(seg.mP0), mP1(seg.mP1) {} + //! Destructor + inline_ ~Segment() {} + + inline_ const Point& GetOrigin() const { return mP0; } + inline_ Point ComputeDirection() const { return mP1 - mP0; } + inline_ void ComputeDirection(Point& dir) const { dir = mP1 - mP0; } + inline_ float ComputeLength() const { return mP1.Distance(mP0); } + inline_ float ComputeSquareLength() const { return mP1.SquareDistance(mP0); } + + inline_ void SetOriginDirection(const Point& origin, const Point& direction) + { + mP0 = mP1 = origin; + mP1 += direction; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes a point on the segment + * \param pt [out] point on segment + * \param t [in] point's parameter [t=0 => pt = mP0, t=1 => pt = mP1] + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void ComputePoint(Point& pt, float t) const { pt = mP0 + t * (mP1 - mP0); } + + float SquareDistance(const Point& point, float* t=null) const; + inline_ float Distance(const Point& point, float* t=null) const { return sqrtf(SquareDistance(point, t)); } + + Point mP0; //!< Start of segment + Point mP1; //!< End of segment + }; + +#endif // __ICESEGMENT_H__ diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceTriList.h b/libs/ode-0.16.1/OPCODE/Ice/IceTriList.h new file mode 100644 index 0000000..73f5257 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceTriList.h @@ -0,0 +1,61 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for a triangle container. + * \file IceTrilist.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICETRILIST_H__ +#define __ICETRILIST_H__ + + class ICEMATHS_API TriList : public Container + { + public: + // Constructor / Destructor + TriList() {} + ~TriList() {} + + inline_ udword GetNbTriangles() const { return GetNbEntries()/9; } + inline_ Triangle* GetTriangles() const { return (Triangle*)GetEntries(); } + + void AddTri(const Triangle& tri) + { + Add(tri.mVerts[0].x).Add(tri.mVerts[0].y).Add(tri.mVerts[0].z); + Add(tri.mVerts[1].x).Add(tri.mVerts[1].y).Add(tri.mVerts[1].z); + Add(tri.mVerts[2].x).Add(tri.mVerts[2].y).Add(tri.mVerts[2].z); + } + + void AddTri(const Point& p0, const Point& p1, const Point& p2) + { + Add(p0.x).Add(p0.y).Add(p0.z); + Add(p1.x).Add(p1.y).Add(p1.z); + Add(p2.x).Add(p2.y).Add(p2.z); + } + }; + + class ICEMATHS_API TriangleList : public Container + { + public: + // Constructor / Destructor + TriangleList() {} + ~TriangleList() {} + + inline_ udword GetNbTriangles() const { return GetNbEntries()/3; } + inline_ IndexedTriangle* GetTriangles() const { return (IndexedTriangle*)GetEntries();} + + void AddTriangle(const IndexedTriangle& tri) + { + Add((udword)tri.mVRef[0]).Add((udword)tri.mVRef[1]).Add((udword)tri.mVRef[2]); + } + + void AddTriangle(udword vref0, udword vref1, udword vref2) + { + Add(vref0).Add(vref1).Add(vref2); + } + }; + +#endif //__ICETRILIST_H__ diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceTriangle.cpp b/libs/ode-0.16.1/OPCODE/Ice/IceTriangle.cpp new file mode 100644 index 0000000..4268ff4 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceTriangle.cpp @@ -0,0 +1,286 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a handy triangle class. + * \file IceTriangle.cpp + * \author Pierre Terdiman + * \date January, 17, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace IceMaths; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a triangle class. + * + * \class Tri + * \author Pierre Terdiman + * \version 1.0 + * \date 08.15.98 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +static sdword VPlaneSideEps(const Point& v, const Plane& plane, float epsilon) +{ + // Compute distance from current vertex to the plane + float Dist = plane.Distance(v); + // Compute side: + // 1 = the vertex is on the positive side of the plane + // -1 = the vertex is on the negative side of the plane + // 0 = the vertex is on the plane (within epsilon) + return Dist > epsilon ? 1 : Dist < -epsilon ? -1 : 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Flips the winding order. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void Triangle::Flip() +{ + Point Tmp = mVerts[1]; + mVerts[1] = mVerts[2]; + mVerts[2] = Tmp; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle area. + * \return the area + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float Triangle::Area() const +{ + const Point& p0 = mVerts[0]; + const Point& p1 = mVerts[1]; + const Point& p2 = mVerts[2]; + return ((p0 - p1)^(p0 - p2)).Magnitude() * 0.5f; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle perimeter. + * \return the perimeter + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float Triangle::Perimeter() const +{ + const Point& p0 = mVerts[0]; + const Point& p1 = mVerts[1]; + const Point& p2 = mVerts[2]; + return p0.Distance(p1) + + p0.Distance(p2) + + p1.Distance(p2); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle compacity. + * \return the compacity + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float Triangle::Compacity() const +{ + float P = Perimeter(); + if(P==0.0f) return 0.0f; + return (4.0f*PI*Area()/(P*P)); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle normal. + * \param normal [out] the computed normal + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void Triangle::Normal(Point& normal) const +{ + const Point& p0 = mVerts[0]; + const Point& p1 = mVerts[1]; + const Point& p2 = mVerts[2]; + normal = ((p0 - p1)^(p0 - p2)).Normalize(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle denormalized normal. + * \param normal [out] the computed normal + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void Triangle::DenormalizedNormal(Point& normal) const +{ + const Point& p0 = mVerts[0]; + const Point& p1 = mVerts[1]; + const Point& p2 = mVerts[2]; + normal = ((p0 - p1)^(p0 - p2)); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle center. + * \param center [out] the computed center + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void Triangle::Center(Point& center) const +{ + const Point& p0 = mVerts[0]; + const Point& p1 = mVerts[1]; + const Point& p2 = mVerts[2]; + center = (p0 + p1 + p2)*INV3; +} + +PartVal Triangle::TestAgainstPlane(const Plane& plane, float epsilon) const +{ + bool Pos = false, Neg = false; + + // Loop through all vertices + for(udword i=0;i<3;i++) + { + // Compute side: + sdword Side = VPlaneSideEps(mVerts[i], plane, epsilon); + + if (Side < 0) Neg = true; + else if (Side > 0) Pos = true; + } + + if (!Pos && !Neg) return TRI_ON_PLANE; + else if (Pos && Neg) return TRI_INTERSECT; + else if (Pos && !Neg) return TRI_PLUS_SPACE; + else if (!Pos && Neg) return TRI_MINUS_SPACE; + + // What?! + return TRI_FORCEDWORD; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle moment. + * \param m [out] the moment + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* +void Triangle::ComputeMoment(Moment& m) +{ + // Compute the area of the triangle + m.mArea = Area(); + + // Compute the centroid + Center(m.mCentroid); + + // Second-order components. Handle zero-area faces. + Point& p = mVerts[0]; + Point& q = mVerts[1]; + Point& r = mVerts[2]; + if(m.mArea==0.0f) + { + // This triangle has zero area. The second order components would be eliminated with the usual formula, so, for the + // sake of robustness we use an alternative form. These are the centroid and second-order components of the triangle's vertices. + m.mCovariance.m[0][0] = (p.x*p.x + q.x*q.x + r.x*r.x); + m.mCovariance.m[0][1] = (p.x*p.y + q.x*q.y + r.x*r.y); + m.mCovariance.m[0][2] = (p.x*p.z + q.x*q.z + r.x*r.z); + m.mCovariance.m[1][1] = (p.y*p.y + q.y*q.y + r.y*r.y); + m.mCovariance.m[1][2] = (p.y*p.z + q.y*q.z + r.y*r.z); + m.mCovariance.m[2][2] = (p.z*p.z + q.z*q.z + r.z*r.z); + m.mCovariance.m[2][1] = m.mCovariance.m[1][2]; + m.mCovariance.m[1][0] = m.mCovariance.m[0][1]; + m.mCovariance.m[2][0] = m.mCovariance.m[0][2]; + } + else + { + const float OneOverTwelve = 1.0f / 12.0f; + m.mCovariance.m[0][0] = m.mArea * (9.0f * m.mCentroid.x*m.mCentroid.x + p.x*p.x + q.x*q.x + r.x*r.x) * OneOverTwelve; + m.mCovariance.m[0][1] = m.mArea * (9.0f * m.mCentroid.x*m.mCentroid.y + p.x*p.y + q.x*q.y + r.x*r.y) * OneOverTwelve; + m.mCovariance.m[1][1] = m.mArea * (9.0f * m.mCentroid.y*m.mCentroid.y + p.y*p.y + q.y*q.y + r.y*r.y) * OneOverTwelve; + m.mCovariance.m[0][2] = m.mArea * (9.0f * m.mCentroid.x*m.mCentroid.z + p.x*p.z + q.x*q.z + r.x*r.z) * OneOverTwelve; + m.mCovariance.m[1][2] = m.mArea * (9.0f * m.mCentroid.y*m.mCentroid.z + p.y*p.z + q.y*q.z + r.y*r.z) * OneOverTwelve; + m.mCovariance.m[2][2] = m.mArea * (9.0f * m.mCentroid.z*m.mCentroid.z + p.z*p.z + q.z*q.z + r.z*r.z) * OneOverTwelve; + m.mCovariance.m[2][1] = m.mCovariance.m[1][2]; + m.mCovariance.m[1][0] = m.mCovariance.m[0][1]; + m.mCovariance.m[2][0] = m.mCovariance.m[0][2]; + } +} +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle's smallest edge length. + * \return the smallest edge length + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float Triangle::MinEdgeLength() const +{ + float Min = MAX_FLOAT; + float Length01 = mVerts[0].Distance(mVerts[1]); + float Length02 = mVerts[0].Distance(mVerts[2]); + float Length12 = mVerts[1].Distance(mVerts[2]); + if(Length01 < Min) Min = Length01; + if(Length02 < Min) Min = Length02; + if(Length12 < Min) Min = Length12; + return Min; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle's largest edge length. + * \return the largest edge length + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float Triangle::MaxEdgeLength() const +{ + float Max = MIN_FLOAT; + float Length01 = mVerts[0].Distance(mVerts[1]); + float Length02 = mVerts[0].Distance(mVerts[2]); + float Length12 = mVerts[1].Distance(mVerts[2]); + if(Length01 > Max) Max = Length01; + if(Length02 > Max) Max = Length02; + if(Length12 > Max) Max = Length12; + return Max; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes a point on the triangle according to the stabbing information. + * \param u,v [in] point's barycentric coordinates + * \param pt [out] point on triangle + * \param nearvtx [out] index of nearest vertex + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void Triangle::ComputePoint(float u, float v, Point& pt, udword* nearvtx) const +{ + // Compute point coordinates + pt = (1.0f - u - v)*mVerts[0] + u*mVerts[1] + v*mVerts[2]; + + // Compute nearest vertex if needed + if(nearvtx) + { + // Compute distance vector + Point d(mVerts[0].SquareDistance(pt), // Distance^2 from vertex 0 to point on the face + mVerts[1].SquareDistance(pt), // Distance^2 from vertex 1 to point on the face + mVerts[2].SquareDistance(pt)); // Distance^2 from vertex 2 to point on the face + + // Get smallest distance + *nearvtx = d.SmallestAxis(); + } +} + +void Triangle::Inflate(float fat_coeff, bool constant_border) +{ + // Compute triangle center + Point TriangleCenter; + Center(TriangleCenter); + + // Don't normalize? + // Normalize => add a constant border, regardless of triangle size + // Don't => add more to big triangles + for(udword i=0;i<3;i++) + { + Point v = mVerts[i] - TriangleCenter; + + if(constant_border) v.Normalize(); + + mVerts[i] += v * fat_coeff; + } +} diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceTriangle.h b/libs/ode-0.16.1/OPCODE/Ice/IceTriangle.h new file mode 100644 index 0000000..a984db8 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceTriangle.h @@ -0,0 +1,68 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a handy triangle class. + * \file IceTriangle.h + * \author Pierre Terdiman + * \date January, 17, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICETRIANGLE_H__ +#define __ICETRIANGLE_H__ + + // Forward declarations + class Moment; + + // Partitioning values + enum PartVal + { + TRI_MINUS_SPACE = 0, //!< Triangle is in the negative space + TRI_PLUS_SPACE = 1, //!< Triangle is in the positive space + TRI_INTERSECT = 2, //!< Triangle intersects plane + TRI_ON_PLANE = 3, //!< Triangle and plane are coplanar + + TRI_FORCEDWORD = 0x7fffffff + }; + + // A triangle class. + class ICEMATHS_API Triangle + { + public: + //! Constructor + inline_ Triangle() {} + //! Constructor + inline_ Triangle(const Point& p0, const Point& p1, const Point& p2) { mVerts[0]=p0; mVerts[1]=p1; mVerts[2]=p2; } + //! Copy constructor + inline_ Triangle(const Triangle& triangle) + { + mVerts[0] = triangle.mVerts[0]; + mVerts[1] = triangle.mVerts[1]; + mVerts[2] = triangle.mVerts[2]; + } + //! Destructor + inline_ ~Triangle() {} + //! Vertices + Point mVerts[3]; + + // Methods + void Flip(); + float Area() const; + float Perimeter() const; + float Compacity() const; + void Normal(Point& normal) const; + void DenormalizedNormal(Point& normal) const; + void Center(Point& center) const; + inline_ Plane PlaneEquation() const { return Plane(mVerts[0], mVerts[1], mVerts[2]); } + + PartVal TestAgainstPlane(const Plane& plane, float epsilon) const; +// float Distance(Point& cp, Point& cq, Tri& tri); + void ComputeMoment(Moment& m); + float MinEdgeLength() const; + float MaxEdgeLength() const; + void ComputePoint(float u, float v, Point& pt, udword* nearvtx=null) const; + void Inflate(float fat_coeff, bool constant_border); + }; + +#endif // __ICETRIANGLE_H__ diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceTypes.h b/libs/ode-0.16.1/OPCODE/Ice/IceTypes.h new file mode 100644 index 0000000..c896623 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceTypes.h @@ -0,0 +1,161 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains custom types. + * \file IceTypes.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICETYPES_H__ +#define __ICETYPES_H__ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Things to help us compile on non-windows platforms + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + #define USE_HANDLE_MANAGER + + // Constants + #define PI 3.1415926535897932384626433832795028841971693993751f //!< PI + #define HALFPI 1.57079632679489661923f //!< 0.5 * PI + #define TWOPI 6.28318530717958647692f //!< 2.0 * PI + #define INVPI 0.31830988618379067154f //!< 1.0 / PI + + #define RADTODEG 57.2957795130823208768f //!< 180.0 / PI, convert radians to degrees + #define DEGTORAD 0.01745329251994329577f //!< PI / 180.0, convert degrees to radians + + #define EXP 2.71828182845904523536f //!< e + #define INVLOG2 3.32192809488736234787f //!< 1.0 / log10(2) + #define LN2 0.693147180559945f //!< ln(2) + #define INVLN2 1.44269504089f //!< 1.0f / ln(2) + + #define INV3 0.33333333333333333333f //!< 1/3 + #define INV6 0.16666666666666666666f //!< 1/6 + #define INV7 0.14285714285714285714f //!< 1/7 + #define INV9 0.11111111111111111111f //!< 1/9 + #define INV255 0.00392156862745098039f //!< 1/255 + + #define SQRT2 1.41421356237f //!< sqrt(2) + #define INVSQRT2 0.707106781188f //!< 1 / sqrt(2) + + #define SQRT3 1.73205080757f //!< sqrt(3) + #define INVSQRT3 0.577350269189f //!< 1 / sqrt(3) + + #define null 0 //!< our own NULL pointer + + // Custom types used in ICE + typedef signed char sbyte; //!< sizeof(sbyte) must be 1 + typedef unsigned char ubyte; //!< sizeof(ubyte) must be 1 + typedef signed short sword; //!< sizeof(sword) must be 2 + typedef unsigned short uword; //!< sizeof(uword) must be 2 + typedef signed int sdword; //!< sizeof(sdword) must be 4 + typedef unsigned int udword; //!< sizeof(udword) must be 4 + typedef signed __int64 sqword; //!< sizeof(sqword) must be 8 + typedef unsigned __int64 uqword; //!< sizeof(uqword) must be 8 + typedef float float32; //!< sizeof(float32) must be 4 + typedef double float64; //!< sizeof(float64) must be 4 + + ICE_COMPILE_TIME_ASSERT(sizeof(ubyte)==1); + ICE_COMPILE_TIME_ASSERT(sizeof(sbyte)==1); + ICE_COMPILE_TIME_ASSERT(sizeof(sword)==2); + ICE_COMPILE_TIME_ASSERT(sizeof(uword)==2); + ICE_COMPILE_TIME_ASSERT(sizeof(udword)==4); + ICE_COMPILE_TIME_ASSERT(sizeof(sdword)==4); + ICE_COMPILE_TIME_ASSERT(sizeof(uqword)==8); + ICE_COMPILE_TIME_ASSERT(sizeof(sqword)==8); + + //! TO BE DOCUMENTED + #define DECLARE_ICE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name + + typedef udword DynID; //!< Dynamic identifier +#ifdef USE_HANDLE_MANAGER + typedef udword KID; //!< Kernel ID +// DECLARE_ICE_HANDLE(KID); +#else + typedef uword KID; //!< Kernel ID +#endif + typedef udword RTYPE; //!< Relationship-type (!) between owners and references + #define INVALID_ID 0xffffffff //!< Invalid dword ID (counterpart of null pointers) +#ifdef USE_HANDLE_MANAGER + #define INVALID_KID 0xffffffff //!< Invalid Kernel ID +#else + #define INVALID_KID 0xffff //!< Invalid Kernel ID +#endif + #define INVALID_NUMBER 0xDEADBEEF //!< Standard junk value + + // Define BOOL if needed + #ifndef BOOL + typedef int BOOL; //!< Another boolean type. + #endif + + //! Union of a float and a sdword + typedef union { + float f; //!< The float + sdword d; //!< The integer + }scell; + + //! Union of a float and a udword + typedef union { + float f; //!< The float + udword d; //!< The integer + }ucell; + + // Type ranges + #define MAX_SBYTE 0x7f //!< max possible sbyte value + #define MIN_SBYTE 0x80 //!< min possible sbyte value + #define MAX_UBYTE 0xff //!< max possible ubyte value + #define MIN_UBYTE 0x00 //!< min possible ubyte value + #define MAX_SWORD 0x7fff //!< max possible sword value + #define MIN_SWORD 0x8000 //!< min possible sword value + #define MAX_UWORD 0xffff //!< max possible uword value + #define MIN_UWORD 0x0000 //!< min possible uword value + #define MAX_SDWORD 0x7fffffff //!< max possible sdword value + #define MIN_SDWORD 0x80000000 //!< min possible sdword value + #define MAX_UDWORD 0xffffffff //!< max possible udword value + #define MIN_UDWORD 0x00000000 //!< min possible udword value + #define MAX_FLOAT FLT_MAX //!< max possible float value + #define MIN_FLOAT (-FLT_MAX) //!< min possible loat value + #define IEEE_1_0 0x3f800000 //!< integer representation of 1.0 + #define IEEE_255_0 0x437f0000 //!< integer representation of 255.0 + #define IEEE_MAX_FLOAT 0x7f7fffff //!< integer representation of MAX_FLOAT + #define IEEE_MIN_FLOAT 0xff7fffff //!< integer representation of MIN_FLOAT + #define IEEE_UNDERFLOW_LIMIT 0x1a000000 + + #define ONE_OVER_RAND_MAX (1.0f / float(RAND_MAX)) //!< Inverse of the max possible value returned by rand() + + // typedef int (__stdcall* PROC)(); -- Oleh Derevenko: Conflicts with Windows headers in x64 mode //!< A standard procedure call. + typedef bool (*ENUMERATION)(udword value, udword param, udword context); //!< ICE standard enumeration call + typedef void** VTABLE; //!< A V-Table. + + #undef MIN + #undef MAX + #define MIN(a, b) ((a) < (b) ? (a) : (b)) //!< Returns the min value between a and b + #define MAX(a, b) ((a) > (b) ? (a) : (b)) //!< Returns the max value between a and b + #define MAXMAX(a,b,c) ((a) > (b) ? MAX (a,c) : MAX (b,c)) //!< Returns the max value between a, b and c + + template<class T> inline_ const T& TMin (const T& a, const T& b) { return b < a ? b : a; } + template<class T> inline_ const T& TMax (const T& a, const T& b) { return a < b ? b : a; } + template<class T> inline_ void TSetMin (T& a, const T& b) { if(a>b) a = b; } + template<class T> inline_ void TSetMax (T& a, const T& b) { if(a<b) a = b; } + + #define SQR(x) ((x)*(x)) //!< Returns x square + #define CUBE(x) ((x)*(x)*(x)) //!< Returns x cube + + #define AND & //!< ... + #define OR | //!< ... + #define XOR ^ //!< ... + + #define QUADRAT(x) ((x)*(x)) //!< Returns x square + +#ifdef _WIN32 +# define srand48(x) srand((unsigned int) (x)) +# define srandom(x) srand((unsigned int) (x)) +# define random() ((double) rand()) +# define drand48() ((double) (((double) rand()) / ((double) RAND_MAX))) +#endif + +#endif // __ICETYPES_H__ diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceUtils.cpp b/libs/ode-0.16.1/OPCODE/Ice/IceUtils.cpp new file mode 100644 index 0000000..29b6c57 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceUtils.cpp @@ -0,0 +1,39 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains misc. useful macros & defines. + * \file IceUtils.cpp + * \author Pierre Terdiman (collected from various sources) + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace IceCore; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Returns the alignment of the input address. + * \fn Alignment() + * \param address [in] address to check + * \return the best alignment (e.g. 1 for odd addresses, etc) + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +udword IceCore::Alignment(udword address) +{ + // Returns 0 for null addresses + if(!address) return 0; + + // Test all bits + udword Align = 1; + for(udword i=1;i<32;i++) + { + // Returns as soon as the alignment is broken + if(address&Align) return Align; + Align<<=1; + } + // Here all bits are null, except the highest one (else the address would be null) + return Align; +} diff --git a/libs/ode-0.16.1/OPCODE/Ice/IceUtils.h b/libs/ode-0.16.1/OPCODE/Ice/IceUtils.h new file mode 100644 index 0000000..5fafdcc --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/IceUtils.h @@ -0,0 +1,259 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains misc. useful macros & defines. + * \file IceUtils.h + * \author Pierre Terdiman (collected from various sources) + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEUTILS_H__ +#define __ICEUTILS_H__ + +// #define START_RUNONCE { static bool __RunOnce__ = false; if(!__RunOnce__){ -- not thread safe +// #define END_RUNONCE __RunOnce__ = true;}} -- not thread safe + + //! Reverse all the bits in a 32 bit word (from Steve Baker's Cute Code Collection) + //! (each line can be done in any order. + inline_ void ReverseBits(udword& n) + { + n = ((n >> 1) & 0x55555555) | ((n << 1) & 0xaaaaaaaa); + n = ((n >> 2) & 0x33333333) | ((n << 2) & 0xcccccccc); + n = ((n >> 4) & 0x0f0f0f0f) | ((n << 4) & 0xf0f0f0f0); + n = ((n >> 8) & 0x00ff00ff) | ((n << 8) & 0xff00ff00); + n = ((n >> 16) & 0x0000ffff) | ((n << 16) & 0xffff0000); + // Etc for larger intergers (64 bits in Java) + // NOTE: the >> operation must be unsigned! (>>> in java) + } + + //! Count the number of '1' bits in a 32 bit word (from Steve Baker's Cute Code Collection) + inline_ udword CountBits(udword n) + { + // This relies of the fact that the count of n bits can NOT overflow + // an n bit interger. EG: 1 bit count takes a 1 bit interger, 2 bit counts + // 2 bit interger, 3 bit count requires only a 2 bit interger. + // So we add all bit pairs, then each nible, then each byte etc... + n = (n & 0x55555555) + ((n & 0xaaaaaaaa) >> 1); + n = (n & 0x33333333) + ((n & 0xcccccccc) >> 2); + n = (n & 0x0f0f0f0f) + ((n & 0xf0f0f0f0) >> 4); + n = (n & 0x00ff00ff) + ((n & 0xff00ff00) >> 8); + n = (n & 0x0000ffff) + ((n & 0xffff0000) >> 16); + // Etc for larger intergers (64 bits in Java) + // NOTE: the >> operation must be unsigned! (>>> in java) + return n; + } + + //! Even faster? + inline_ udword CountBits2(udword bits) + { + bits = bits - ((bits >> 1) & 0x55555555); + bits = ((bits >> 2) & 0x33333333) + (bits & 0x33333333); + bits = ((bits >> 4) + bits) & 0x0F0F0F0F; + return (bits * 0x01010101) >> 24; + } + + //! Spread out bits. EG 00001111 -> 0101010101 + //! 00001010 -> 0100010000 + //! This is used to interleve to intergers to produce a `Morten Key' + //! used in Space Filling Curves (See DrDobbs Journal, July 1999) + //! Order is important. + inline_ void SpreadBits(udword& n) + { + n = ( n & 0x0000ffff) | (( n & 0xffff0000) << 16); + n = ( n & 0x000000ff) | (( n & 0x0000ff00) << 8); + n = ( n & 0x000f000f) | (( n & 0x00f000f0) << 4); + n = ( n & 0x03030303) | (( n & 0x0c0c0c0c) << 2); + n = ( n & 0x11111111) | (( n & 0x22222222) << 1); + } + + // Next Largest Power of 2 + // Given a binary integer value x, the next largest power of 2 can be computed by a SWAR algorithm + // that recursively "folds" the upper bits into the lower bits. This process yields a bit vector with + // the same most significant 1 as x, but all 1's below it. Adding 1 to that value yields the next + // largest power of 2. For a 32-bit value: + inline_ udword nlpo2(udword x) + { + x |= (x >> 1); + x |= (x >> 2); + x |= (x >> 4); + x |= (x >> 8); + x |= (x >> 16); + return x+1; + } + + //! Test to see if a number is an exact power of two (from Steve Baker's Cute Code Collection) + inline_ bool IsPowerOfTwo(udword n) { return ((n&(n-1))==0); } + + //! Zero the least significant '1' bit in a word. (from Steve Baker's Cute Code Collection) + inline_ void ZeroLeastSetBit(udword& n) { n&=(n-1); } + + //! Set the least significant N bits in a word. (from Steve Baker's Cute Code Collection) + inline_ void SetLeastNBits(udword& x, udword n) { x|=~(~0<<n); } + + //! Classic XOR swap (from Steve Baker's Cute Code Collection) + //! x ^= y; /* x' = (x^y) */ + //! y ^= x; /* y' = (y^(x^y)) = x */ + //! x ^= y; /* x' = (x^y)^x = y */ + inline_ void Swap(udword& x, udword& y) { x ^= y; y ^= x; x ^= y; } + inline_ void Swap(uword& x, uword& y) { x ^= y; y ^= x; x ^= y; } + + //! Little/Big endian (from Steve Baker's Cute Code Collection) + //! + //! Extra comments by Kenny Hoff: + //! Determines the byte-ordering of the current machine (little or big endian) + //! by setting an integer value to 1 (so least significant bit is now 1); take + //! the address of the int and cast to a byte pointer (treat integer as an + //! array of four bytes); check the value of the first byte (must be 0 or 1). + //! If the value is 1, then the first byte least significant byte and this + //! implies LITTLE endian. If the value is 0, the first byte is the most + //! significant byte, BIG endian. Examples: + //! integer 1 on BIG endian: 00000000 00000000 00000000 00000001 + //! integer 1 on LITTLE endian: 00000001 00000000 00000000 00000000 + //!--------------------------------------------------------------------------- + //! int IsLittleEndian() { int x=1; return ( ((char*)(&x))[0] ); } + inline_ char LittleEndian() { int i = 1; return *((char*)&i); } + + //!< Alternative abs function + inline_ udword abs_(sdword x) { sdword y= x >> 31; return (x^y)-y; } + + //!< Alternative min function + inline_ sdword min_(sdword a, sdword b) { sdword delta = b-a; return a + (delta&(delta>>31)); } + + // Determine if one of the bytes in a 4 byte word is zero + inline_ BOOL HasNullByte(udword x) { return ((x + 0xfefefeff) & (~x) & 0x80808080); } + + // To find the smallest 1 bit in a word EG: ~~~~~~10---0 => 0----010---0 + inline_ udword LowestOneBit(udword w) { return ((w) & (~(w)+1)); } +// inline_ udword LowestOneBit_(udword w) { return ((w) & (-(w))); } + + // Most Significant 1 Bit + // Given a binary integer value x, the most significant 1 bit (highest numbered element of a bit set) + // can be computed using a SWAR algorithm that recursively "folds" the upper bits into the lower bits. + // This process yields a bit vector with the same most significant 1 as x, but all 1's below it. + // Bitwise AND of the original value with the complement of the "folded" value shifted down by one + // yields the most significant bit. For a 32-bit value: + inline_ udword msb32(udword x) + { + x |= (x >> 1); + x |= (x >> 2); + x |= (x >> 4); + x |= (x >> 8); + x |= (x >> 16); + return (x & ~(x >> 1)); + } + + /* + "Just call it repeatedly with various input values and always with the same variable as "memory". + The sharpness determines the degree of filtering, where 0 completely filters out the input, and 1 + does no filtering at all. + + I seem to recall from college that this is called an IIR (Infinite Impulse Response) filter. As opposed + to the more typical FIR (Finite Impulse Response). + + Also, I'd say that you can make more intelligent and interesting filters than this, for example filters + that remove wrong responses from the mouse because it's being moved too fast. You'd want such a filter + to be applied before this one, of course." + + (JCAB on Flipcode) + */ + inline_ float FeedbackFilter(float val, float& memory, float sharpness) + { + ASSERT(sharpness>=0.0f && sharpness<=1.0f && "Invalid sharpness value in feedback filter"); + if(sharpness<0.0f) sharpness = 0.0f; + else if(sharpness>1.0f) sharpness = 1.0f; + return memory = val * sharpness + memory * (1.0f - sharpness); + } + + //! If you can guarantee that your input domain (i.e. value of x) is slightly + //! limited (abs(x) must be < ((1<<31u)-32767)), then you can use the + //! following code to clamp the resulting value into [-32768,+32767] range: + inline_ int ClampToInt16(int x) + { +// ASSERT(abs(x) < (int)((1<<31u)-32767)); + + int delta = 32767 - x; + x += (delta>>31) & delta; + delta = x + 32768; + x -= (delta>>31) & delta; + return x; + } + + // Generic functions + template<class Type> inline_ void TSwap(Type& a, Type& b) { const Type c = a; a = b; b = c; } + template<class Type> inline_ Type TClamp(const Type& x, const Type& lo, const Type& hi) { return ((x<lo) ? lo : (x>hi) ? hi : x); } + + template<class Type> inline_ void TSort(Type& a, Type& b) + { + if(a>b) TSwap(a, b); + } + + template<class Type> inline_ void TSort(Type& a, Type& b, Type& c) + { + if(a>b) TSwap(a, b); + if(b>c) TSwap(b, c); + if(a>b) TSwap(a, b); + if(b>c) TSwap(b, c); + } + + // Prevent nasty user-manipulations (strategy borrowed from Charles Bloom) +// #define PREVENT_COPY(curclass) void operator = (const curclass& object) { ASSERT(!"Bad use of operator ="); } + // ... actually this is better ! + #define PREVENT_COPY(cur_class) private: cur_class(const cur_class& object); cur_class& operator=(const cur_class& object); + + //! TO BE DOCUMENTED + #define OFFSET_OF(Class, Member) (size_t)&(((Class*)0)->Member) + //! TO BE DOCUMENTED +#ifndef ARRAYSIZE + #define ARRAYSIZE(p) (sizeof(p)/sizeof((p)[0])) +#endif // #ifndef ARRAYSIZE + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Returns the alignment of the input address. + * \fn Alignment() + * \param address [in] address to check + * \return the best alignment (e.g. 1 for odd addresses, etc) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + FUNCTION ICECORE_API udword Alignment(udword address); + + #define IS_ALIGNED_2(x) ((x&1)==0) + #define IS_ALIGNED_4(x) ((x&3)==0) + #define IS_ALIGNED_8(x) ((x&7)==0) + + inline_ void _prefetch(void const* ptr) { (void)*(char const volatile *)ptr; } + + // Compute implicit coords from an index: + // The idea is to get back 2D coords from a 1D index. + // For example: + // + // 0 1 2 ... nbu-1 + // nbu nbu+1 i ... + // + // We have i, we're looking for the equivalent (u=2, v=1) location. + // i = u + v*nbu + // <=> i/nbu = u/nbu + v + // Since 0 <= u < nbu, u/nbu = 0 (integer) + // Hence: v = i/nbu + // Then we simply put it back in the original equation to compute u = i - v*nbu + inline_ void Compute2DCoords(udword& u, udword& v, udword i, udword nbu) + { + v = i / nbu; + u = i - (v * nbu); + } + + // In 3D: i = u + v*nbu + w*nbu*nbv + // <=> i/(nbu*nbv) = u/(nbu*nbv) + v/nbv + w + // u/(nbu*nbv) is null since u/nbu was null already. + // v/nbv is null as well for the same reason. + // Hence w = i/(nbu*nbv) + // Then we're left with a 2D problem: i' = i - w*nbu*nbv = u + v*nbu + inline_ void Compute3DCoords(udword& u, udword& v, udword& w, udword i, udword nbu, udword nbu_nbv) + { + w = i / (nbu_nbv); + Compute2DCoords(u, v, i - (w * nbu_nbv), nbu); + } + +#endif // __ICEUTILS_H__ diff --git a/libs/ode-0.16.1/OPCODE/Ice/Makefile.am b/libs/ode-0.16.1/OPCODE/Ice/Makefile.am new file mode 100644 index 0000000..4f3256c --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/Makefile.am @@ -0,0 +1,20 @@ +AM_CPPFLAGS = -I$(top_srcdir)/OPCODE \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/include + +noinst_LTLIBRARIES = libIce.la +libIce_la_SOURCES = \ + IceAABB.cpp IceAABB.h IceAxes.h \ + IceBoundingSphere.h IceContainer.cpp IceContainer.h \ + IceFPU.h IceHPoint.cpp IceHPoint.h \ + IceIndexedTriangle.cpp IceIndexedTriangle.h IceLSS.h \ + IceMatrix3x3.cpp IceMatrix3x3.h IceMatrix4x4.cpp \ + IceMatrix4x4.h IceMemoryMacros.h IceOBB.cpp \ + IceOBB.h IcePairs.h IcePlane.cpp \ + IcePlane.h IcePoint.cpp IcePoint.h \ + IcePreprocessor.h IceRandom.cpp IceRandom.h \ + IceRay.cpp IceRay.h IceRevisitedRadix.cpp \ + IceRevisitedRadix.h IceSegment.cpp IceSegment.h \ + IceTriangle.cpp IceTriangle.h IceTriList.h \ + IceTypes.h IceUtils.cpp IceUtils.h + diff --git a/libs/ode-0.16.1/OPCODE/Ice/Makefile.in b/libs/ode-0.16.1/OPCODE/Ice/Makefile.in new file mode 100644 index 0000000..d5f05b7 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Ice/Makefile.in @@ -0,0 +1,660 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = OPCODE/Ice +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ode/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libIce_la_LIBADD = +am_libIce_la_OBJECTS = IceAABB.lo IceContainer.lo IceHPoint.lo \ + IceIndexedTriangle.lo IceMatrix3x3.lo IceMatrix4x4.lo \ + IceOBB.lo IcePlane.lo IcePoint.lo IceRandom.lo IceRay.lo \ + IceRevisitedRadix.lo IceSegment.lo IceTriangle.lo IceUtils.lo +libIce_la_OBJECTS = $(am_libIce_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libIce_la_SOURCES) +DIST_SOURCES = $(libIce_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_CFLAGS = @CCD_CFLAGS@ +CCD_LIBS = @CCD_LIBS@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSTDCXX = @LIBSTDCXX@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ODE_PRECISION = @ODE_PRECISION@ +ODE_VERSION = @ODE_VERSION@ +ODE_VERSION_INFO = @ODE_VERSION_INFO@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = -I$(top_srcdir)/OPCODE \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/include + +noinst_LTLIBRARIES = libIce.la +libIce_la_SOURCES = \ + IceAABB.cpp IceAABB.h IceAxes.h \ + IceBoundingSphere.h IceContainer.cpp IceContainer.h \ + IceFPU.h IceHPoint.cpp IceHPoint.h \ + IceIndexedTriangle.cpp IceIndexedTriangle.h IceLSS.h \ + IceMatrix3x3.cpp IceMatrix3x3.h IceMatrix4x4.cpp \ + IceMatrix4x4.h IceMemoryMacros.h IceOBB.cpp \ + IceOBB.h IcePairs.h IcePlane.cpp \ + IcePlane.h IcePoint.cpp IcePoint.h \ + IcePreprocessor.h IceRandom.cpp IceRandom.h \ + IceRay.cpp IceRay.h IceRevisitedRadix.cpp \ + IceRevisitedRadix.h IceSegment.cpp IceSegment.h \ + IceTriangle.cpp IceTriangle.h IceTriList.h \ + IceTypes.h IceUtils.cpp IceUtils.h + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign OPCODE/Ice/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign OPCODE/Ice/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libIce.la: $(libIce_la_OBJECTS) $(libIce_la_DEPENDENCIES) $(EXTRA_libIce_la_DEPENDENCIES) + $(AM_V_CXXLD)$(CXXLINK) $(libIce_la_OBJECTS) $(libIce_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IceAABB.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IceContainer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IceHPoint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IceIndexedTriangle.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IceMatrix3x3.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IceMatrix4x4.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IceOBB.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IcePlane.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IcePoint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IceRandom.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IceRay.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IceRevisitedRadix.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IceSegment.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IceTriangle.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IceUtils.Plo@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/OPCODE/Makefile.am b/libs/ode-0.16.1/OPCODE/Makefile.am new file mode 100644 index 0000000..1e82910 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Makefile.am @@ -0,0 +1,45 @@ +EXTRA_DIST = COPYING \ + ReadMe.txt \ + README-ODE.txt \ + TemporalCoherence.txt + +SUBDIRS = Ice + +noinst_LTLIBRARIES = libOPCODE.la +AM_CPPFLAGS= -I$(top_srcdir)/include \ + -I$(top_builddir)/include + +libOPCODE_la_SOURCES = OPC_AABBCollider.cpp OPC_AABBCollider.h \ + OPC_AABBTree.cpp OPC_AABBTree.h \ + OPC_BaseModel.cpp OPC_BaseModel.h \ + OPC_Collider.cpp OPC_Collider.h \ + OPC_Common.cpp OPC_Common.h \ + OPC_HybridModel.cpp OPC_HybridModel.h \ + OPC_LSSCollider.cpp OPC_LSSCollider.h \ + OPC_MeshInterface.cpp OPC_MeshInterface.h \ + OPC_Model.cpp OPC_Model.h \ + OPC_OBBCollider.cpp OPC_OBBCollider.h \ + Opcode.cpp Opcode.h \ + OPC_OptimizedTree.cpp OPC_OptimizedTree.h \ + OPC_Picking.cpp OPC_Picking.h \ + OPC_PlanesCollider.cpp OPC_PlanesCollider.h \ + OPC_RayCollider.cpp OPC_RayCollider.h \ + OPC_SphereCollider.cpp OPC_SphereCollider.h \ + OPC_TreeBuilders.cpp OPC_TreeBuilders.h \ + OPC_TreeCollider.cpp OPC_TreeCollider.h \ + OPC_VolumeCollider.cpp OPC_VolumeCollider.h \ + OPC_Settings.h \ + OPC_SphereAABBOverlap.h \ + OPC_BoxBoxOverlap.h \ + OPC_SphereTriOverlap.h \ + OPC_PlanesAABBOverlap.h \ + OPC_TriBoxOverlap.h \ + OPC_IceHook.h \ + OPC_PlanesTriOverlap.h \ + OPC_TriTriOverlap.h \ + OPC_LSSAABBOverlap.h \ + OPC_RayAABBOverlap.h \ + Stdafx.h \ + OPC_LSSTriOverlap.h \ + OPC_RayTriOverlap.h + diff --git a/libs/ode-0.16.1/OPCODE/Makefile.in b/libs/ode-0.16.1/OPCODE/Makefile.in new file mode 100644 index 0000000..bc96d41 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Makefile.in @@ -0,0 +1,807 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = OPCODE +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ode/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libOPCODE_la_LIBADD = +am_libOPCODE_la_OBJECTS = OPC_AABBCollider.lo OPC_AABBTree.lo \ + OPC_BaseModel.lo OPC_Collider.lo OPC_Common.lo \ + OPC_HybridModel.lo OPC_LSSCollider.lo OPC_MeshInterface.lo \ + OPC_Model.lo OPC_OBBCollider.lo Opcode.lo OPC_OptimizedTree.lo \ + OPC_Picking.lo OPC_PlanesCollider.lo OPC_RayCollider.lo \ + OPC_SphereCollider.lo OPC_TreeBuilders.lo OPC_TreeCollider.lo \ + OPC_VolumeCollider.lo +libOPCODE_la_OBJECTS = $(am_libOPCODE_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libOPCODE_la_SOURCES) +DIST_SOURCES = $(libOPCODE_la_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp COPYING +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_CFLAGS = @CCD_CFLAGS@ +CCD_LIBS = @CCD_LIBS@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSTDCXX = @LIBSTDCXX@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ODE_PRECISION = @ODE_PRECISION@ +ODE_VERSION = @ODE_VERSION@ +ODE_VERSION_INFO = @ODE_VERSION_INFO@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = COPYING \ + ReadMe.txt \ + README-ODE.txt \ + TemporalCoherence.txt + +SUBDIRS = Ice +noinst_LTLIBRARIES = libOPCODE.la +AM_CPPFLAGS = -I$(top_srcdir)/include \ + -I$(top_builddir)/include + +libOPCODE_la_SOURCES = OPC_AABBCollider.cpp OPC_AABBCollider.h \ + OPC_AABBTree.cpp OPC_AABBTree.h \ + OPC_BaseModel.cpp OPC_BaseModel.h \ + OPC_Collider.cpp OPC_Collider.h \ + OPC_Common.cpp OPC_Common.h \ + OPC_HybridModel.cpp OPC_HybridModel.h \ + OPC_LSSCollider.cpp OPC_LSSCollider.h \ + OPC_MeshInterface.cpp OPC_MeshInterface.h \ + OPC_Model.cpp OPC_Model.h \ + OPC_OBBCollider.cpp OPC_OBBCollider.h \ + Opcode.cpp Opcode.h \ + OPC_OptimizedTree.cpp OPC_OptimizedTree.h \ + OPC_Picking.cpp OPC_Picking.h \ + OPC_PlanesCollider.cpp OPC_PlanesCollider.h \ + OPC_RayCollider.cpp OPC_RayCollider.h \ + OPC_SphereCollider.cpp OPC_SphereCollider.h \ + OPC_TreeBuilders.cpp OPC_TreeBuilders.h \ + OPC_TreeCollider.cpp OPC_TreeCollider.h \ + OPC_VolumeCollider.cpp OPC_VolumeCollider.h \ + OPC_Settings.h \ + OPC_SphereAABBOverlap.h \ + OPC_BoxBoxOverlap.h \ + OPC_SphereTriOverlap.h \ + OPC_PlanesAABBOverlap.h \ + OPC_TriBoxOverlap.h \ + OPC_IceHook.h \ + OPC_PlanesTriOverlap.h \ + OPC_TriTriOverlap.h \ + OPC_LSSAABBOverlap.h \ + OPC_RayAABBOverlap.h \ + Stdafx.h \ + OPC_LSSTriOverlap.h \ + OPC_RayTriOverlap.h + +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign OPCODE/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign OPCODE/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libOPCODE.la: $(libOPCODE_la_OBJECTS) $(libOPCODE_la_DEPENDENCIES) $(EXTRA_libOPCODE_la_DEPENDENCIES) + $(AM_V_CXXLD)$(CXXLINK) $(libOPCODE_la_OBJECTS) $(libOPCODE_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OPC_AABBCollider.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OPC_AABBTree.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OPC_BaseModel.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OPC_Collider.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OPC_Common.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OPC_HybridModel.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OPC_LSSCollider.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OPC_MeshInterface.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OPC_Model.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OPC_OBBCollider.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OPC_OptimizedTree.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OPC_Picking.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OPC_PlanesCollider.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OPC_RayCollider.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OPC_SphereCollider.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OPC_TreeBuilders.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OPC_TreeCollider.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OPC_VolumeCollider.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Opcode.Plo@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(LTLIBRARIES) +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libtool \ + clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/OPCODE/OPC_AABBCollider.cpp b/libs/ode-0.16.1/OPCODE/OPC_AABBCollider.cpp new file mode 100644 index 0000000..a192311 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_AABBCollider.cpp @@ -0,0 +1,696 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for an AABB collider. + * \file OPC_AABBCollider.cpp + * \author Pierre Terdiman + * \date January, 1st, 2002 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains an AABB-vs-tree collider. + * + * \class AABBCollider + * \author Pierre Terdiman + * \version 1.3 + * \date January, 1st, 2002 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +#include "OPC_BoxBoxOverlap.h" +#include "OPC_TriBoxOverlap.h" + +#define SET_CONTACT(prim_index, flag) \ + /* Set contact status */ \ + mFlags |= flag; \ + mTouchedPrimitives->Add(udword(prim_index)); + +//! AABB-triangle test +#define AABB_PRIM(prim_index, flag) \ + /* Request vertices from the app */ \ + VertexPointers VP; ConversionArea VC; mIMesh->GetTriangle(VP, prim_index, VC); \ + mLeafVerts[0] = *VP.Vertex[0]; \ + mLeafVerts[1] = *VP.Vertex[1]; \ + mLeafVerts[2] = *VP.Vertex[2]; \ + /* Perform triangle-box overlap test */ \ + if(TriBoxOverlap()) \ + { \ + SET_CONTACT(prim_index, flag) \ + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBCollider::AABBCollider() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBCollider::~AABBCollider() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Generic collision query for generic OPCODE models. After the call, access the results: + * - with GetContactStatus() + * - with GetNbTouchedPrimitives() + * - with GetTouchedPrimitives() + * + * \param cache [in/out] a box cache + * \param box [in] collision AABB in world space + * \param model [in] Opcode model to collide with + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBCollider::Collide(AABBCache& cache, const CollisionAABB& box, const Model& model) +{ + // Checkings + if(!Setup(&model)) return false; + + // Init collision query + if(InitQuery(cache, box)) return true; + + if(!model.HasLeafNodes()) + { + if(model.IsQuantized()) + { + const AABBQuantizedNoLeafTree* Tree = static_cast<const AABBQuantizedNoLeafTree *>(model.GetTree()); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + else + { + const AABBNoLeafTree* Tree = static_cast<const AABBNoLeafTree *>(model.GetTree()); + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + } + else + { + if(model.IsQuantized()) + { + const AABBQuantizedTree* Tree = static_cast<const AABBQuantizedTree *>(model.GetTree()); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + else + { + const AABBCollisionTree* Tree = static_cast<const AABBCollisionTree *>(model.GetTree()); + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + } + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Initializes a collision query : + * - reset stats & contact status + * - check temporal coherence + * + * \param cache [in/out] a box cache + * \param box [in] AABB in world space + * \return TRUE if we can return immediately + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +BOOL AABBCollider::InitQuery(AABBCache& cache, const CollisionAABB& box) +{ + // 1) Call the base method + VolumeCollider::InitQuery(); + + // 2) Keep track of the query box + mBox = box; + + // 3) Setup destination pointer + mTouchedPrimitives = &cache.TouchedPrimitives; + + // 4) Special case: 1-triangle meshes [Opcode 1.3] + if(mCurrentModel && mCurrentModel->HasSingleNode()) + { + if(!SkipPrimitiveTests()) + { + // We simply perform the BV-Prim overlap test each time. We assume single triangle has index 0. + mTouchedPrimitives->Reset(); + + // Perform overlap test between the unique triangle and the box (and set contact status if needed) + AABB_PRIM(udword(0), OPC_CONTACT) + + // Return immediately regardless of status + return TRUE; + } + } + + // 5) Check temporal coherence : + if(TemporalCoherenceEnabled()) + { + // Here we use temporal coherence + // => check results from previous frame before performing the collision query + if(FirstContactEnabled()) + { + // We're only interested in the first contact found => test the unique previously touched face + if(mTouchedPrimitives->GetNbEntries()) + { + // Get index of previously touched face = the first entry in the array + udword PreviouslyTouchedFace = mTouchedPrimitives->GetEntry(0); + + // Then reset the array: + // - if the overlap test below is successful, the index we'll get added back anyway + // - if it isn't, then the array should be reset anyway for the normal query + mTouchedPrimitives->Reset(); + + // Perform overlap test between the cached triangle and the box (and set contact status if needed) + AABB_PRIM(PreviouslyTouchedFace, OPC_TEMPORAL_CONTACT) + + // Return immediately if possible + if(GetContactStatus()) return TRUE; + } + // else no face has been touched during previous query + // => we'll have to perform a normal query + } + else + { + // We're interested in all contacts =>test the new real box N(ew) against the previous fat box P(revious): + if(IsCacheValid(cache) && mBox.IsInside(cache.FatBox)) + { + // - if N is included in P, return previous list + // => we simply leave the list (mTouchedFaces) unchanged + + // Set contact status if needed + if(mTouchedPrimitives->GetNbEntries()) mFlags |= OPC_TEMPORAL_CONTACT; + + // In any case we don't need to do a query + return TRUE; + } + else + { + // - else do the query using a fat N + + // Reset cache since we'll about to perform a real query + mTouchedPrimitives->Reset(); + + // Make a fat box so that coherence will work for subsequent frames + mBox.mExtents *= cache.FatCoeff; + + // Update cache with query data (signature for cached faces) + cache.FatBox = mBox; + } + } + } + else + { + // Here we don't use temporal coherence => do a normal query + mTouchedPrimitives->Reset(); + } + + // 5) Precompute min & max bounds if needed + mMin = box.mCenter - box.mExtents; + mMax = box.mCenter + box.mExtents; + + return FALSE; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Collision query for vanilla AABB trees. + * \param cache [in/out] a box cache + * \param box [in] collision AABB in world space + * \param tree [in] AABB tree + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBCollider::Collide(AABBCache& cache, const CollisionAABB& box, const AABBTree* tree) +{ + // This is typically called for a scene tree, full of -AABBs-, not full of triangles. + // So we don't really have "primitives" to deal with. Hence it doesn't work with + // "FirstContact" + "TemporalCoherence". + ASSERT( !(FirstContactEnabled() && TemporalCoherenceEnabled()) ); + + // Checkings + if(!tree) return false; + + // Init collision query + if(InitQuery(cache, box)) return true; + + // Perform collision query + _Collide(tree); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks the AABB completely contains the box. In which case we can end the query sooner. + * \param bc [in] box center + * \param be [in] box extents + * \return true if the AABB contains the whole box + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL AABBCollider::AABBContainsBox(const Point& bc, const Point& be) +{ + if(mMin.x > bc.x - be.x) return FALSE; + if(mMin.y > bc.y - be.y) return FALSE; + if(mMin.z > bc.z - be.z) return FALSE; + + if(mMax.x < bc.x + be.x) return FALSE; + if(mMax.y < bc.y + be.y) return FALSE; + if(mMax.z < bc.z + be.z) return FALSE; + + return TRUE; +} + +#define TEST_BOX_IN_AABB(center, extents) \ + if(AABBContainsBox(center, extents)) \ + { \ + /* Set contact status */ \ + mFlags |= OPC_CONTACT; \ + _Dump(node); \ + return; \ + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for normal AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBCollider::_Collide(const AABBCollisionNode* node) +{ + // Perform AABB-AABB overlap test + if(!AABBAABBOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return; + + TEST_BOX_IN_AABB(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->IsLeaf()) + { + AABB_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _Collide(node->GetPos()); + + if(ContactFound()) return; + + _Collide(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for normal AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBCollider::_CollideNoPrimitiveTest(const AABBCollisionNode* node) +{ + // Perform AABB-AABB overlap test + if(!AABBAABBOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return; + + TEST_BOX_IN_AABB(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->IsLeaf()) + { + SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + _CollideNoPrimitiveTest(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBCollider::_Collide(const AABBQuantizedNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform AABB-AABB overlap test + if(!AABBAABBOverlap(Extents, Center)) return; + + TEST_BOX_IN_AABB(Center, Extents) + + if(node->IsLeaf()) + { + AABB_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _Collide(node->GetPos()); + + if(ContactFound()) return; + + _Collide(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBCollider::_CollideNoPrimitiveTest(const AABBQuantizedNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform AABB-AABB overlap test + if(!AABBAABBOverlap(Extents, Center)) return; + + TEST_BOX_IN_AABB(Center, Extents) + + if(node->IsLeaf()) + { + SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + _CollideNoPrimitiveTest(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBCollider::_Collide(const AABBNoLeafNode* node) +{ + // Perform AABB-AABB overlap test + if(!AABBAABBOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return; + + TEST_BOX_IN_AABB(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->HasPosLeaf()) { AABB_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } + else _Collide(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { AABB_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } + else _Collide(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for no-leaf AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBCollider::_CollideNoPrimitiveTest(const AABBNoLeafNode* node) +{ + // Perform AABB-AABB overlap test + if(!AABBAABBOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return; + + TEST_BOX_IN_AABB(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBCollider::_Collide(const AABBQuantizedNoLeafNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform AABB-AABB overlap test + if(!AABBAABBOverlap(Extents, Center)) return; + + TEST_BOX_IN_AABB(Center, Extents) + + if(node->HasPosLeaf()) { AABB_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } + else _Collide(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { AABB_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } + else _Collide(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized no-leaf AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBCollider::_CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform AABB-AABB overlap test + if(!AABBAABBOverlap(Extents, Center)) return; + + TEST_BOX_IN_AABB(Center, Extents) + + if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for vanilla AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBCollider::_Collide(const AABBTreeNode* node) +{ + // Perform AABB-AABB overlap test + Point Center, Extents; + node->GetAABB()->GetCenter(Center); + node->GetAABB()->GetExtents(Extents); + if(!AABBAABBOverlap(Center, Extents)) return; + + if(node->IsLeaf() || AABBContainsBox(Center, Extents)) + { + mFlags |= OPC_CONTACT; + mTouchedPrimitives->Add(node->GetPrimitives(), node->GetNbPrimitives()); + } + else + { + _Collide(node->GetPos()); + _Collide(node->GetNeg()); + } +} + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HybridAABBCollider::HybridAABBCollider() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HybridAABBCollider::~HybridAABBCollider() +{ +} + +bool HybridAABBCollider::Collide(AABBCache& cache, const CollisionAABB& box, const HybridModel& model) +{ + // We don't want primitive tests here! + mFlags |= OPC_NO_PRIMITIVE_TESTS; + + // Checkings + if(!Setup(&model)) return false; + + // Init collision query + if(InitQuery(cache, box)) return true; + + // Special case for 1-leaf trees + if(mCurrentModel && mCurrentModel->HasSingleNode()) + { + // Here we're supposed to perform a normal query, except our tree has a single node, i.e. just a few triangles + udword Nb = mIMesh->GetNbTriangles(); + + // Loop through all triangles + for(udword i=0;i<Nb;i++) + { + AABB_PRIM(i, OPC_CONTACT) + } + return true; + } + + // Override destination array since we're only going to get leaf boxes here + mTouchedBoxes.Reset(); + mTouchedPrimitives = &mTouchedBoxes; + + // Now, do the actual query against leaf boxes + if(!model.HasLeafNodes()) + { + if(model.IsQuantized()) + { + const AABBQuantizedNoLeafTree* Tree = static_cast<const AABBQuantizedNoLeafTree *>(model.GetTree()); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + else + { + const AABBNoLeafTree* Tree = static_cast<const AABBNoLeafTree *>(model.GetTree()); + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + } + else + { + if(model.IsQuantized()) + { + const AABBQuantizedTree* Tree = static_cast<const AABBQuantizedTree *>(model.GetTree()); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + else + { + const AABBCollisionTree* Tree = static_cast<const AABBCollisionTree *>(model.GetTree()); + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + } + + // We only have a list of boxes so far + if(GetContactStatus()) + { + // Reset contact status, since it currently only reflects collisions with leaf boxes + Collider::InitQuery(); + + // Change dest container so that we can use built-in overlap tests and get collided primitives + cache.TouchedPrimitives.Reset(); + mTouchedPrimitives = &cache.TouchedPrimitives; + + // Read touched leaf boxes + udword Nb = mTouchedBoxes.GetNbEntries(); + const udword* Touched = mTouchedBoxes.GetEntries(); + + const LeafTriangles* LT = model.GetLeafTriangles(); + const udword* Indices = model.GetIndices(); + + // Loop through touched leaves + while(Nb--) + { + const LeafTriangles& CurrentLeaf = LT[*Touched++]; + + // Each leaf box has a set of triangles + udword NbTris = CurrentLeaf.GetNbTriangles(); + if(Indices) + { + const udword* T = &Indices[CurrentLeaf.GetTriangleIndex()]; + + // Loop through triangles and test each of them + while(NbTris--) + { + udword TriangleIndex = *T++; + AABB_PRIM(TriangleIndex, OPC_CONTACT) + } + } + else + { + udword BaseIndex = CurrentLeaf.GetTriangleIndex(); + + // Loop through triangles and test each of them + while(NbTris--) + { + udword TriangleIndex = BaseIndex++; + AABB_PRIM(TriangleIndex, OPC_CONTACT) + } + } + } + } + + return true; +} diff --git a/libs/ode-0.16.1/OPCODE/OPC_AABBCollider.h b/libs/ode-0.16.1/OPCODE/OPC_AABBCollider.h new file mode 100644 index 0000000..315d2d3 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_AABBCollider.h @@ -0,0 +1,97 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for an AABB collider. + * \file OPC_AABBCollider.h + * \author Pierre Terdiman + * \date January, 1st, 2002 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_AABBCOLLIDER_H__ +#define __OPC_AABBCOLLIDER_H__ + + struct OPCODE_API AABBCache : VolumeCache + { + AABBCache() : FatCoeff(1.1f) + { + FatBox.mCenter.Zero(); + FatBox.mExtents.Zero(); + } + + // Cached faces signature + CollisionAABB FatBox; //!< Box used when performing the query resulting in cached faces + // User settings + float FatCoeff; //!< mRadius2 multiplier used to create a fat sphere + }; + + class OPCODE_API AABBCollider : public VolumeCollider + { + public: + // Constructor / Destructor + AABBCollider(); + virtual ~AABBCollider(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Generic collision query for generic OPCODE models. After the call, access the results: + * - with GetContactStatus() + * - with GetNbTouchedPrimitives() + * - with GetTouchedPrimitives() + * + * \param cache [in/out] a box cache + * \param box [in] collision AABB in world space + * \param model [in] Opcode model to collide with + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool Collide(AABBCache& cache, const CollisionAABB& box, const Model& model); + // + bool Collide(AABBCache& cache, const CollisionAABB& box, const AABBTree* tree); + protected: + CollisionAABB mBox; //!< Query box in (center, extents) form + Point mMin; //!< Query box min point + Point mMax; //!< Query box max point + // Leaf description + Point mLeafVerts[3]; //!< Triangle vertices + // Internal methods + void _Collide(const AABBCollisionNode* node); + void _Collide(const AABBNoLeafNode* node); + void _Collide(const AABBQuantizedNode* node); + void _Collide(const AABBQuantizedNoLeafNode* node); + void _Collide(const AABBTreeNode* node); + void _CollideNoPrimitiveTest(const AABBCollisionNode* node); + void _CollideNoPrimitiveTest(const AABBNoLeafNode* node); + void _CollideNoPrimitiveTest(const AABBQuantizedNode* node); + void _CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node); + // Overlap tests + inline_ BOOL AABBContainsBox(const Point& bc, const Point& be); + inline_ BOOL AABBAABBOverlap(const Point& b, const Point& Pb); + inline_ BOOL TriBoxOverlap(); + // Init methods + BOOL InitQuery(AABBCache& cache, const CollisionAABB& box); + }; + + class OPCODE_API HybridAABBCollider : public AABBCollider + { + public: + // Constructor / Destructor + HybridAABBCollider(); + virtual ~HybridAABBCollider(); + + bool Collide(AABBCache& cache, const CollisionAABB& box, const HybridModel& model); + protected: + Container mTouchedBoxes; + }; + +#endif // __OPC_AABBCOLLIDER_H__ diff --git a/libs/ode-0.16.1/OPCODE/OPC_AABBTree.cpp b/libs/ode-0.16.1/OPCODE/OPC_AABBTree.cpp new file mode 100644 index 0000000..48129a8 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_AABBTree.cpp @@ -0,0 +1,568 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for a versatile AABB tree. + * \file OPC_AABBTree.cpp + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a generic AABB tree node. + * + * \class AABBTreeNode + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a generic AABB tree. + * This is a vanilla AABB tree, without any particular optimization. It contains anonymous references to + * user-provided primitives, which can theoretically be anything - triangles, boxes, etc. Each primitive + * is surrounded by an AABB, regardless of the primitive's nature. When the primitive is a triangle, the + * resulting tree can be converted into an optimized tree. If the primitive is a box, the resulting tree + * can be used for culling - VFC or occlusion -, assuming you cull on a mesh-by-mesh basis (modern way). + * + * \class AABBTree + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBTreeNode::AABBTreeNode() : + mPos (null), +#ifndef OPC_NO_NEG_VANILLA_TREE + mNeg (null), +#endif + mNodePrimitives (null), + mNbPrimitives (0) +{ +#ifdef OPC_USE_TREE_COHERENCE + mBitmask = 0; +#endif +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBTreeNode::~AABBTreeNode() +{ + // Opcode 1.3: + const AABBTreeNode* Pos = GetPos(); +#ifndef OPC_NO_NEG_VANILLA_TREE + const AABBTreeNode* Neg = GetNeg(); + if(!(mPos&1)) DELETESINGLE(Pos); + if(!(mNeg&1)) DELETESINGLE(Neg); +#else + if(!(mPos&1)) DELETEARRAY(Pos); +#endif + mNodePrimitives = null; // This was just a shortcut to the global list => no release + mNbPrimitives = 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Splits the node along a given axis. + * The list of indices is reorganized according to the split values. + * \param axis [in] splitting axis index + * \param builder [in] the tree builder + * \return the number of primitives assigned to the first child + * \warning this method reorganizes the internal list of primitives + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +udword AABBTreeNode::Split(udword axis, AABBTreeBuilder* builder) +{ + // Get node split value + float SplitValue = builder->GetSplittingValue(mNodePrimitives, mNbPrimitives, mBV, axis); + + udword NbPos = 0; + // Loop through all node-related primitives. Their indices range from mNodePrimitives[0] to mNodePrimitives[mNbPrimitives-1]. + // Those indices map the global list in the tree builder. + for(udword i=0;i<mNbPrimitives;i++) + { + // Get index in global list + udword Index = mNodePrimitives[i]; + + // Test against the splitting value. The primitive value is tested against the enclosing-box center. + // [We only need an approximate partition of the enclosing box here.] + float PrimitiveValue = builder->GetSplittingValue(Index, axis); + + // Reorganize the list of indices in this order: positive - negative. + if(PrimitiveValue > SplitValue) + { + // Swap entries + udword Tmp = mNodePrimitives[i]; + mNodePrimitives[i] = mNodePrimitives[NbPos]; + mNodePrimitives[NbPos] = Tmp; + // Count primitives assigned to positive space + NbPos++; + } + } + return NbPos; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Subdivides the node. + * + * N + * / \ + * / \ + * N/2 N/2 + * / \ / \ + * N/4 N/4 N/4 N/4 + * (etc) + * + * A well-balanced tree should have a O(log n) depth. + * A degenerate tree would have a O(n) depth. + * Note a perfectly-balanced tree is not well-suited to collision detection anyway. + * + * \param builder [in] the tree builder + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBTreeNode::Subdivide(AABBTreeBuilder* builder) +{ + // Checkings + if(!builder) return false; + + // Stop subdividing if we reach a leaf node. This is always performed here, + // else we could end in trouble if user overrides this. + if(mNbPrimitives==1) return true; + + // Let the user validate the subdivision + if(!builder->ValidateSubdivision(mNodePrimitives, mNbPrimitives, mBV)) return true; + + bool ValidSplit = true; // Optimism... + udword NbPos; + if(builder->mSettings.mRules & SPLIT_LARGEST_AXIS) + { + // Find the largest axis to split along + Point Extents; mBV.GetExtents(Extents); // Box extents + udword Axis = Extents.LargestAxis(); // Index of largest axis + + // Split along the axis + NbPos = Split(Axis, builder); + + // Check split validity + if(!NbPos || NbPos==mNbPrimitives) ValidSplit = false; + } + else if(builder->mSettings.mRules & SPLIT_SPLATTER_POINTS) + { + // Compute the means + Point Means(0.0f, 0.0f, 0.0f); + for(udword i=0;i<mNbPrimitives;i++) + { + udword Index = mNodePrimitives[i]; + Means += builder->GetSplittingValues(Index); + } + Means/=float(mNbPrimitives); + + // Compute variances + Point Vars(0.0f, 0.0f, 0.0f); + for(udword i=0;i<mNbPrimitives;i++) + { + udword Index = mNodePrimitives[i]; + Point Center = builder->GetSplittingValues(Index); + Point Delta = Center - Means; + Vars += Delta * Delta; + } + Vars/=float(mNbPrimitives-1); + + // Choose axis with greatest variance + udword Axis = Vars.LargestAxis(); + + // Split along the axis + NbPos = Split(Axis, builder); + + // Check split validity + if(!NbPos || NbPos==mNbPrimitives) ValidSplit = false; + } + else if(builder->mSettings.mRules & SPLIT_BALANCED) + { + // Test 3 axis, take the best + float Results[3]; + NbPos = Split(0, builder); Results[0] = float(NbPos)/float(mNbPrimitives); + NbPos = Split(1, builder); Results[1] = float(NbPos)/float(mNbPrimitives); + NbPos = Split(2, builder); Results[2] = float(NbPos)/float(mNbPrimitives); + Results[0]-=0.5f; Results[0]*=Results[0]; + Results[1]-=0.5f; Results[1]*=Results[1]; + Results[2]-=0.5f; Results[2]*=Results[2]; + udword Min=0; + if(Results[1]<Results[Min]) Min = 1; + if(Results[2]<Results[Min]) Min = 2; + + // Split along the axis + NbPos = Split(Min, builder); + + // Check split validity + if(!NbPos || NbPos==mNbPrimitives) ValidSplit = false; + } + else if(builder->mSettings.mRules & SPLIT_BEST_AXIS) + { + // Test largest, then middle, then smallest axis... + + // Sort axis + Point Extents; mBV.GetExtents(Extents); // Box extents + udword SortedAxis[] = { 0, 1, 2 }; + float* Keys = (float*)&Extents.x; + for(udword j=0;j<3;j++) + { + for(udword i=0;i<2;i++) + { + if(Keys[SortedAxis[i]]<Keys[SortedAxis[i+1]]) + { + udword Tmp = SortedAxis[i]; + SortedAxis[i] = SortedAxis[i+1]; + SortedAxis[i+1] = Tmp; + } + } + } + + // Find the largest axis to split along + udword CurAxis = 0; + ValidSplit = false; + while(!ValidSplit && CurAxis!=3) + { + NbPos = Split(SortedAxis[CurAxis], builder); + // Check the subdivision has been successful + if(!NbPos || NbPos==mNbPrimitives) CurAxis++; + else ValidSplit = true; + } + } + else if(builder->mSettings.mRules & SPLIT_FIFTY) + { + // Don't even bother splitting (mainly a performance test) + NbPos = mNbPrimitives>>1; + } + else return false; // Unknown splitting rules + + // Check the subdivision has been successful + if(!ValidSplit) + { + // Here, all boxes lie in the same sub-space. Two strategies: + // - if the tree *must* be complete, make an arbitrary 50-50 split + // - else stop subdividing +// if(builder->mSettings.mRules&SPLIT_COMPLETE) + if(builder->mSettings.mLimit==1) + { + builder->IncreaseNbInvalidSplits(); + NbPos = mNbPrimitives>>1; + } + else return true; + } + + // Now create children and assign their pointers. + if(builder->mNodeBase) + { + // We use a pre-allocated linear pool for complete trees [Opcode 1.3] + AABBTreeNode* Pool = (AABBTreeNode*)builder->mNodeBase; + udword Count = builder->GetCount() - 1; // Count begins to 1... + // Set last bit to tell it shouldn't be freed ### pretty ugly, find a better way. Maybe one bit in mNbPrimitives + ASSERT(!(udword(&Pool[Count+0])&1)); + ASSERT(!(udword(&Pool[Count+1])&1)); + mPos = size_t(&Pool[Count+0])|1; +#ifndef OPC_NO_NEG_VANILLA_TREE + mNeg = size_t(&Pool[Count+1])|1; +#endif + } + else + { + // Non-complete trees and/or Opcode 1.2 allocate nodes on-the-fly +#ifndef OPC_NO_NEG_VANILLA_TREE + mPos = (size_t)new AABBTreeNode; CHECKALLOC(mPos); + mNeg = (size_t)new AABBTreeNode; CHECKALLOC(mNeg); +#else + AABBTreeNode* PosNeg = new AABBTreeNode[2]; + CHECKALLOC(PosNeg); + mPos = (size_t)PosNeg; +#endif + } + + // Update stats + builder->IncreaseCount(2); + + // Assign children + AABBTreeNode* Pos = const_cast<AABBTreeNode *>(GetPos()); + AABBTreeNode* Neg = const_cast<AABBTreeNode *>(GetNeg()); + Pos->mNodePrimitives = &mNodePrimitives[0]; + Pos->mNbPrimitives = NbPos; + Neg->mNodePrimitives = &mNodePrimitives[NbPos]; + Neg->mNbPrimitives = mNbPrimitives - NbPos; + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive hierarchy building in a top-down fashion. + * \param builder [in] the tree builder + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeNode::_BuildHierarchy(AABBTreeBuilder* builder) +{ + // 1) Compute the global box for current node. The box is stored in mBV. + builder->ComputeGlobalBox(mNodePrimitives, mNbPrimitives, mBV); + + // 2) Subdivide current node + Subdivide(builder); + + // 3) Recurse + AABBTreeNode* Pos = const_cast<AABBTreeNode *>(GetPos()); + AABBTreeNode* Neg = const_cast<AABBTreeNode *>(GetNeg()); + if(Pos) Pos->_BuildHierarchy(builder); + if(Neg) Neg->_BuildHierarchy(builder); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Refits the tree (top-down). + * \param builder [in] the tree builder + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeNode::_Refit(AABBTreeBuilder* builder) +{ + // 1) Recompute the new global box for current node + builder->ComputeGlobalBox(mNodePrimitives, mNbPrimitives, mBV); + + // 2) Recurse + AABBTreeNode* Pos = const_cast<AABBTreeNode *>(GetPos()); + AABBTreeNode* Neg = const_cast<AABBTreeNode *>(GetNeg()); + if(Pos) Pos->_Refit(builder); + if(Neg) Neg->_Refit(builder); +} + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBTree::AABBTree() : mIndices(null), mPool(null), mTotalNbNodes(0) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBTree::~AABBTree() +{ + Release(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Releases the tree. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTree::Release() +{ + DELETEARRAY(mPool); + DELETEARRAY(mIndices); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Builds a generic AABB tree from a tree builder. + * \param builder [in] the tree builder + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBTree::Build(AABBTreeBuilder* builder) +{ + // Checkings + if(!builder || !builder->mNbPrimitives) return false; + + // Release previous tree + Release(); + + // Init stats + builder->SetCount(1); + builder->SetNbInvalidSplits(0); + + // Initialize indices. This list will be modified during build. + mIndices = new dTriIndex[builder->mNbPrimitives]; + CHECKALLOC(mIndices); + // Identity permutation + for(udword i=0;i<builder->mNbPrimitives;i++) mIndices[i] = i; + + // Setup initial node. Here we have a complete permutation of the app's primitives. + mNodePrimitives = mIndices; + mNbPrimitives = builder->mNbPrimitives; + + // Use a linear array for complete trees (since we can predict the final number of nodes) [Opcode 1.3] +// if(builder->mRules&SPLIT_COMPLETE) + if(builder->mSettings.mLimit==1) + { + // Allocate a pool of nodes + mPool = new AABBTreeNode[builder->mNbPrimitives*2 - 1]; + + builder->mNodeBase = mPool; // ### ugly ! + } + + // Build the hierarchy + _BuildHierarchy(builder); + + // Get back total number of nodes + mTotalNbNodes = builder->GetCount(); + + // For complete trees, check the correct number of nodes has been created [Opcode 1.3] + if(mPool) ASSERT(mTotalNbNodes==builder->mNbPrimitives*2 - 1); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the depth of the tree. + * A well-balanced tree should have a log(n) depth. A degenerate tree O(n) depth. + * \return depth of the tree + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +udword AABBTree::ComputeDepth() const +{ + return Walk(null, null); // Use the walking code without callback +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Walks the tree, calling the user back for each node. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +udword AABBTree::Walk(WalkingCallback callback, void* user_data) const +{ + // Call it without callback to compute max depth + udword MaxDepth = 0; + udword CurrentDepth = 0; + + struct Local + { + static void _Walk(const AABBTreeNode* current_node, udword& max_depth, udword& current_depth, WalkingCallback callback, void* user_data) + { + // Checkings + if(!current_node) return; + // Entering a new node => increase depth + current_depth++; + // Keep track of max depth + if(current_depth>max_depth) max_depth = current_depth; + + // Callback + if(callback && !(callback)(current_node, current_depth, user_data)) return; + + // Recurse + if(current_node->GetPos()) { _Walk(current_node->GetPos(), max_depth, current_depth, callback, user_data); current_depth--; } + if(current_node->GetNeg()) { _Walk(current_node->GetNeg(), max_depth, current_depth, callback, user_data); current_depth--; } + } + }; + Local::_Walk(this, MaxDepth, CurrentDepth, callback, user_data); + return MaxDepth; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Refits the tree in a top-down way. + * \param builder [in] the tree builder + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBTree::Refit(AABBTreeBuilder* builder) +{ + if(!builder) return false; + _Refit(builder); + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Refits the tree in a bottom-up way. + * \param builder [in] the tree builder + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBTree::Refit2(AABBTreeBuilder* builder) +{ + // Checkings + if(!builder) return false; + + ASSERT(mPool); + + // Bottom-up update + Point Min,Max; + Point Min_,Max_; + udword Index = mTotalNbNodes; + while(Index--) + { + AABBTreeNode& Current = mPool[Index]; + + if(Current.IsLeaf()) + { + builder->ComputeGlobalBox(Current.GetPrimitives(), Current.GetNbPrimitives(), *const_cast<AABB*>(Current.GetAABB())); + } + else + { + Current.GetPos()->GetAABB()->GetMin(Min); + Current.GetPos()->GetAABB()->GetMax(Max); + + Current.GetNeg()->GetAABB()->GetMin(Min_); + Current.GetNeg()->GetAABB()->GetMax(Max_); + + Min.Min(Min_); + Max.Max(Max_); + + const_cast<AABB*>(Current.GetAABB())->SetMinMax(Min, Max); + } + } + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the number of bytes used by the tree. + * \return number of bytes used + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +udword AABBTree::GetUsedBytes() const +{ + udword TotalSize = mTotalNbNodes*GetNodeSize(); + if(mIndices) TotalSize+=mNbPrimitives*sizeof(udword); + return TotalSize; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks the tree is a complete tree or not. + * A complete tree is made of 2*N-1 nodes, where N is the number of primitives in the tree. + * \return true for complete trees + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBTree::IsComplete() const +{ + return (GetNbNodes()==GetNbPrimitives()*2-1); +} diff --git a/libs/ode-0.16.1/OPCODE/OPC_AABBTree.h b/libs/ode-0.16.1/OPCODE/OPC_AABBTree.h new file mode 100644 index 0000000..681be9d --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_AABBTree.h @@ -0,0 +1,137 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for a versatile AABB tree. + * \file OPC_AABBTree.h + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_AABBTREE_H__ +#define __OPC_AABBTREE_H__ + +#ifdef OPC_NO_NEG_VANILLA_TREE + //! TO BE DOCUMENTED + #define IMPLEMENT_TREE(base_class, volume) \ + public: \ + /* Constructor / Destructor */ \ + base_class(); \ + ~base_class(); \ + /* Data access */ \ + inline_ const volume* Get##volume() const { return &mBV; } \ + /* Clear the last bit */ \ + inline_ const base_class* GetPos() const { return (const base_class*)(mPos&~1); } \ + inline_ const base_class* GetNeg() const { const base_class* P = GetPos(); return P ? P+1 : null;} \ + \ + /* We don't need to test both nodes since we can't have one without the other */ \ + inline_ bool IsLeaf() const { return !GetPos(); } \ + \ + /* Stats */ \ + inline_ udword GetNodeSize() const { return SIZEOFOBJECT; } \ + protected: \ + /* Tree-independent data */ \ + /* Following data always belong to the BV-tree, regardless of what the tree actually contains.*/ \ + /* Whatever happens we need the two children and the enclosing volume.*/ \ + volume mBV; /* Global bounding-volume enclosing all the node-related primitives */ \ + size_t mPos; /* "Positive" & "Negative" children */ +#else + //! TO BE DOCUMENTED + #define IMPLEMENT_TREE(base_class, volume) \ + public: \ + /* Constructor / Destructor */ \ + base_class(); \ + ~base_class(); \ + /* Data access */ \ + inline_ const volume* Get##volume() const { return &mBV; } \ + /* Clear the last bit */ \ + inline_ const base_class* GetPos() const { return (const base_class*)(mPos&~1); } \ + inline_ const base_class* GetNeg() const { return (const base_class*)(mNeg&~1); } \ + \ +/* inline_ bool IsLeaf() const { return (!GetPos() && !GetNeg()); } */ \ + /* We don't need to test both nodes since we can't have one without the other */ \ + inline_ bool IsLeaf() const { return !GetPos(); } \ + \ + /* Stats */ \ + inline_ udword GetNodeSize() const { return SIZEOFOBJECT; } \ + protected: \ + /* Tree-independent data */ \ + /* Following data always belong to the BV-tree, regardless of what the tree actually contains.*/ \ + /* Whatever happens we need the two children and the enclosing volume.*/ \ + volume mBV; /* Global bounding-volume enclosing all the node-related primitives */ \ + size_t mPos; /* "Positive" child */ \ + size_t mNeg; /* "Negative" child */ +#endif + + typedef void (*CullingCallback) (udword nb_primitives, udword* node_primitives, BOOL need_clipping, void* user_data); + + class OPCODE_API AABBTreeNode + { + IMPLEMENT_TREE(AABBTreeNode, AABB) + public: + // Data access + inline_ const dTriIndex* GetPrimitives() const { return mNodePrimitives; } + inline_ udword GetNbPrimitives() const { return mNbPrimitives; } + + protected: + // Tree-dependent data + dTriIndex* mNodePrimitives; //!< Node-related primitives (shortcut to a position in mIndices below) + udword mNbPrimitives; //!< Number of primitives for this node + // Internal methods + udword Split(udword axis, AABBTreeBuilder* builder); + bool Subdivide(AABBTreeBuilder* builder); + void _BuildHierarchy(AABBTreeBuilder* builder); + void _Refit(AABBTreeBuilder* builder); + }; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * User-callback, called for each node by the walking code. + * \param current [in] current node + * \param depth [in] current node's depth + * \param user_data [in] user-defined data + * \return true to recurse through children, else false to bypass them + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + typedef bool (*WalkingCallback) (const AABBTreeNode* current, udword depth, void* user_data); + + class OPCODE_API AABBTree : public AABBTreeNode + { + public: + // Constructor / Destructor + AABBTree(); + ~AABBTree(); + // Build + bool Build(AABBTreeBuilder* builder); + void Release(); + + // Data access + inline_ const dTriIndex* GetIndices() const { return mIndices; } //!< Catch the indices + inline_ udword GetNbNodes() const { return mTotalNbNodes; } //!< Catch the number of nodes + + // Infos + bool IsComplete() const; + // Stats + udword ComputeDepth() const; + udword GetUsedBytes() const; + udword Walk(WalkingCallback callback, void* user_data) const; + + bool Refit(AABBTreeBuilder* builder); + bool Refit2(AABBTreeBuilder* builder); + private: + dTriIndex* mIndices; //!< Indices in the app list. Indices are reorganized during build (permutation). + AABBTreeNode* mPool; //!< Linear pool of nodes for complete trees. Null otherwise. [Opcode 1.3] + // Stats + udword mTotalNbNodes; //!< Number of nodes in the tree. + }; + +#endif // __OPC_AABBTREE_H__ diff --git a/libs/ode-0.16.1/OPCODE/OPC_BaseModel.cpp b/libs/ode-0.16.1/OPCODE/OPC_BaseModel.cpp new file mode 100644 index 0000000..987c4f9 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_BaseModel.cpp @@ -0,0 +1,119 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains base model interface. + * \file OPC_BaseModel.cpp + * \author Pierre Terdiman + * \date May, 18, 2003 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * The base class for collision models. + * + * \class BaseModel + * \author Pierre Terdiman + * \version 1.3 + * \date May, 18, 2003 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +BaseModel::BaseModel() : mIMesh(null), mModelCode(0), mSource(null), mTree(null) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +BaseModel::~BaseModel() +{ + ReleaseBase(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Releases everything. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void BaseModel::ReleaseBase() +{ + DELETESINGLE(mSource); + DELETESINGLE(mTree); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Creates an optimized tree according to user-settings, and setups mModelCode. + * \param no_leaf [in] true for "no leaf" tree + * \param quantized [in] true for quantized tree + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool BaseModel::CreateTree(bool no_leaf, bool quantized) +{ + DELETESINGLE(mTree); + + // Setup model code + if(no_leaf) mModelCode |= OPC_NO_LEAF; + else mModelCode &= ~OPC_NO_LEAF; + + if(quantized) mModelCode |= OPC_QUANTIZED; + else mModelCode &= ~OPC_QUANTIZED; + + // Create the correct class + if(mModelCode & OPC_NO_LEAF) + { + if(mModelCode & OPC_QUANTIZED) mTree = new AABBQuantizedNoLeafTree; + else mTree = new AABBNoLeafTree; + } + else + { + if(mModelCode & OPC_QUANTIZED) mTree = new AABBQuantizedTree; + else mTree = new AABBCollisionTree; + } + CHECKALLOC(mTree); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Refits the collision model. This can be used to handle dynamic meshes. Usage is: + * 1. modify your mesh vertices (keep the topology constant!) + * 2. refit the tree (call this method) + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool BaseModel::Refit() +{ + // Refit the optimized tree + return mTree->Refit(mIMesh); + +// Old code kept for reference : refit the source tree then rebuild ! +// if(!mSource) return false; +// // Ouch... +// mSource->Refit(&mTB); +// // Ouch... +// return mTree->Build(mSource); +} diff --git a/libs/ode-0.16.1/OPCODE/OPC_BaseModel.h b/libs/ode-0.16.1/OPCODE/OPC_BaseModel.h new file mode 100644 index 0000000..eef77a6 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_BaseModel.h @@ -0,0 +1,199 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains base model interface. + * \file OPC_BaseModel.h + * \author Pierre Terdiman + * \date May, 18, 2003 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_BASEMODEL_H__ +#define __OPC_BASEMODEL_H__ + + //! Model creation structure + struct OPCODE_API OPCODECREATE + { + //! Constructor + inline_ OPCODECREATE(): + mIMesh(null), + mSettings(SPLIT_SPLATTER_POINTS | SPLIT_GEOM_CENTER), + mNoLeaf(true), + mQuantized(true), +#ifdef __MESHMERIZER_H__ + mCollisionHull(false), +#endif // __MESHMERIZER_H__ + mKeepOriginal(false), + mCanRemap(false) + { + } + + inline_ OPCODECREATE(MeshInterface *IMesh, const BuildSettings &Settings, bool NoLeaf, bool Quantized): + mIMesh(IMesh), + mSettings(Settings), + mNoLeaf(NoLeaf), + mQuantized(Quantized), +#ifdef __MESHMERIZER_H__ + mCollisionHull(false), +#endif // __MESHMERIZER_H__ + mKeepOriginal(false), + mCanRemap(false) + { + } + + MeshInterface* mIMesh; //!< Mesh interface (access to triangles & vertices) (*) + BuildSettings mSettings; //!< Builder's settings + bool mNoLeaf; //!< true => discard leaf nodes (else use a normal tree) + bool mQuantized; //!< true => quantize the tree (else use a normal tree) +#ifdef __MESHMERIZER_H__ + bool mCollisionHull; //!< true => use convex hull + GJK +#endif // __MESHMERIZER_H__ + bool mKeepOriginal; //!< true => keep a copy of the original tree (debug purpose) + bool mCanRemap; //!< true => allows OPCODE to reorganize client arrays + + // (*) This pointer is saved internally and used by OPCODE until collision structures are released, + // so beware of the object's lifetime. + }; + + enum ModelFlag + { + OPC_QUANTIZED = (1<<0), //!< Compressed/uncompressed tree + OPC_NO_LEAF = (1<<1), //!< Leaf/NoLeaf tree + OPC_SINGLE_NODE = (1<<2) //!< Special case for 1-node models + }; + + class OPCODE_API BaseModel + { + public: + // Constructor/Destructor + BaseModel(); + virtual ~BaseModel(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Builds a collision model. + * \param create [in] model creation structure + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual bool Build(const OPCODECREATE& create) = 0; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the number of bytes used by the tree. + * \return amount of bytes used + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual udword GetUsedBytes() const = 0; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Refits the collision model. This can be used to handle dynamic meshes. Usage is: + * 1. modify your mesh vertices (keep the topology constant!) + * 2. refit the tree (call this method) + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual bool Refit(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the source tree. + * \return generic tree + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ const AABBTree* GetSourceTree() const { return mSource; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the tree. + * \return the collision tree + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ const AABBOptimizedTree* GetTree() const { return mTree; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the tree. + * \return the collision tree + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ AABBOptimizedTree* GetTree() { return mTree; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the number of nodes in the tree. + * Should be 2*N-1 for normal trees and N-1 for optimized ones. + * \return number of nodes + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbNodes() const { return mTree->GetNbNodes(); } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks whether the tree has leaf nodes or not. + * \return true if the tree has leaf nodes (normal tree), else false (optimized tree) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL HasLeafNodes() const { return !(mModelCode & OPC_NO_LEAF); } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks whether the tree is quantized or not. + * \return true if the tree is quantized + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL IsQuantized() const { return mModelCode & OPC_QUANTIZED; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks whether the model has a single node or not. This special case must be handled separately. + * \return true if the model has only 1 node + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL HasSingleNode() const { return mModelCode & OPC_SINGLE_NODE; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the model's code. + * \return model's code + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetModelCode() const { return mModelCode; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the mesh interface. + * \return mesh interface + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ const MeshInterface* GetMeshInterface() const { return mIMesh; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Sets the mesh interface. + * \param imesh [in] mesh interface + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetMeshInterface(const MeshInterface* imesh) { mIMesh = imesh; } + + protected: + const MeshInterface* mIMesh; //!< User-defined mesh interface + udword mModelCode; //!< Model code = combination of ModelFlag(s) + AABBTree* mSource; //!< Original source tree + AABBOptimizedTree* mTree; //!< Optimized tree owned by the model + // Internal methods + void ReleaseBase(); + bool CreateTree(bool no_leaf, bool quantized); + }; + +#endif //__OPC_BASEMODEL_H__ diff --git a/libs/ode-0.16.1/OPCODE/OPC_BoxBoxOverlap.h b/libs/ode-0.16.1/OPCODE/OPC_BoxBoxOverlap.h new file mode 100644 index 0000000..757a17d --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_BoxBoxOverlap.h @@ -0,0 +1,122 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * OBB-OBB overlap test using the separating axis theorem. + * - original code by Gomez / Gamasutra (similar to Gottschalk's one in RAPID) + * - optimized for AABB trees by computing the rotation matrix once (SOLID-fashion) + * - the fabs matrix is precomputed as well and epsilon-tweaked (RAPID-style, we found this almost mandatory) + * - Class III axes can be disabled... (SOLID & Intel fashion) + * - ...or enabled to perform some profiling + * - CPU comparisons used when appropriate + * - lazy evaluation sometimes saves some work in case of early exits (unlike SOLID) + * + * \param ea [in] extents from box A + * \param ca [in] center from box A + * \param eb [in] extents from box B + * \param cb [in] center from box B + * \return true if boxes overlap + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL AABBTreeCollider::BoxBoxOverlap(const Point& ea, const Point& ca, const Point& eb, const Point& cb) +{ + // Stats + mNbBVBVTests++; + + float t,t2; + + // Class I : A's basis vectors + float Tx = (mR1to0.m[0][0]*cb.x + mR1to0.m[1][0]*cb.y + mR1to0.m[2][0]*cb.z) + mT1to0.x - ca.x; + t = ea.x + eb.x*mAR.m[0][0] + eb.y*mAR.m[1][0] + eb.z*mAR.m[2][0]; + if(GREATER(Tx, t)) return FALSE; + + float Ty = (mR1to0.m[0][1]*cb.x + mR1to0.m[1][1]*cb.y + mR1to0.m[2][1]*cb.z) + mT1to0.y - ca.y; + t = ea.y + eb.x*mAR.m[0][1] + eb.y*mAR.m[1][1] + eb.z*mAR.m[2][1]; + if(GREATER(Ty, t)) return FALSE; + + float Tz = (mR1to0.m[0][2]*cb.x + mR1to0.m[1][2]*cb.y + mR1to0.m[2][2]*cb.z) + mT1to0.z - ca.z; + t = ea.z + eb.x*mAR.m[0][2] + eb.y*mAR.m[1][2] + eb.z*mAR.m[2][2]; + if(GREATER(Tz, t)) return FALSE; + + // Class II : B's basis vectors + t = Tx*mR1to0.m[0][0] + Ty*mR1to0.m[0][1] + Tz*mR1to0.m[0][2]; t2 = ea.x*mAR.m[0][0] + ea.y*mAR.m[0][1] + ea.z*mAR.m[0][2] + eb.x; + if(GREATER(t, t2)) return FALSE; + + t = Tx*mR1to0.m[1][0] + Ty*mR1to0.m[1][1] + Tz*mR1to0.m[1][2]; t2 = ea.x*mAR.m[1][0] + ea.y*mAR.m[1][1] + ea.z*mAR.m[1][2] + eb.y; + if(GREATER(t, t2)) return FALSE; + + t = Tx*mR1to0.m[2][0] + Ty*mR1to0.m[2][1] + Tz*mR1to0.m[2][2]; t2 = ea.x*mAR.m[2][0] + ea.y*mAR.m[2][1] + ea.z*mAR.m[2][2] + eb.z; + if(GREATER(t, t2)) return FALSE; + + // Class III : 9 cross products + // Cool trick: always perform the full test for first level, regardless of settings. + // That way pathological cases (such as the pencils scene) are quickly rejected anyway ! + if(mFullBoxBoxTest || mNbBVBVTests==1) + { + t = Tz*mR1to0.m[0][1] - Ty*mR1to0.m[0][2]; t2 = ea.y*mAR.m[0][2] + ea.z*mAR.m[0][1] + eb.y*mAR.m[2][0] + eb.z*mAR.m[1][0]; if(GREATER(t, t2)) return FALSE; // L = A0 x B0 + t = Tz*mR1to0.m[1][1] - Ty*mR1to0.m[1][2]; t2 = ea.y*mAR.m[1][2] + ea.z*mAR.m[1][1] + eb.x*mAR.m[2][0] + eb.z*mAR.m[0][0]; if(GREATER(t, t2)) return FALSE; // L = A0 x B1 + t = Tz*mR1to0.m[2][1] - Ty*mR1to0.m[2][2]; t2 = ea.y*mAR.m[2][2] + ea.z*mAR.m[2][1] + eb.x*mAR.m[1][0] + eb.y*mAR.m[0][0]; if(GREATER(t, t2)) return FALSE; // L = A0 x B2 + t = Tx*mR1to0.m[0][2] - Tz*mR1to0.m[0][0]; t2 = ea.x*mAR.m[0][2] + ea.z*mAR.m[0][0] + eb.y*mAR.m[2][1] + eb.z*mAR.m[1][1]; if(GREATER(t, t2)) return FALSE; // L = A1 x B0 + t = Tx*mR1to0.m[1][2] - Tz*mR1to0.m[1][0]; t2 = ea.x*mAR.m[1][2] + ea.z*mAR.m[1][0] + eb.x*mAR.m[2][1] + eb.z*mAR.m[0][1]; if(GREATER(t, t2)) return FALSE; // L = A1 x B1 + t = Tx*mR1to0.m[2][2] - Tz*mR1to0.m[2][0]; t2 = ea.x*mAR.m[2][2] + ea.z*mAR.m[2][0] + eb.x*mAR.m[1][1] + eb.y*mAR.m[0][1]; if(GREATER(t, t2)) return FALSE; // L = A1 x B2 + t = Ty*mR1to0.m[0][0] - Tx*mR1to0.m[0][1]; t2 = ea.x*mAR.m[0][1] + ea.y*mAR.m[0][0] + eb.y*mAR.m[2][2] + eb.z*mAR.m[1][2]; if(GREATER(t, t2)) return FALSE; // L = A2 x B0 + t = Ty*mR1to0.m[1][0] - Tx*mR1to0.m[1][1]; t2 = ea.x*mAR.m[1][1] + ea.y*mAR.m[1][0] + eb.x*mAR.m[2][2] + eb.z*mAR.m[0][2]; if(GREATER(t, t2)) return FALSE; // L = A2 x B1 + t = Ty*mR1to0.m[2][0] - Tx*mR1to0.m[2][1]; t2 = ea.x*mAR.m[2][1] + ea.y*mAR.m[2][0] + eb.x*mAR.m[1][2] + eb.y*mAR.m[0][2]; if(GREATER(t, t2)) return FALSE; // L = A2 x B2 + } + return TRUE; +} + +//! A dedicated version when one box is constant +inline_ BOOL OBBCollider::BoxBoxOverlap(const Point& extents, const Point& center) +{ + // Stats + mNbVolumeBVTests++; + + float t,t2; + + // Class I : A's basis vectors + float Tx = mTBoxToModel.x - center.x; t = extents.x + mBBx1; if(GREATER(Tx, t)) return FALSE; + float Ty = mTBoxToModel.y - center.y; t = extents.y + mBBy1; if(GREATER(Ty, t)) return FALSE; + float Tz = mTBoxToModel.z - center.z; t = extents.z + mBBz1; if(GREATER(Tz, t)) return FALSE; + + // Class II : B's basis vectors + t = Tx*mRBoxToModel.m[0][0] + Ty*mRBoxToModel.m[0][1] + Tz*mRBoxToModel.m[0][2]; + t2 = extents.x*mAR.m[0][0] + extents.y*mAR.m[0][1] + extents.z*mAR.m[0][2] + mBoxExtents.x; + if(GREATER(t, t2)) return FALSE; + + t = Tx*mRBoxToModel.m[1][0] + Ty*mRBoxToModel.m[1][1] + Tz*mRBoxToModel.m[1][2]; + t2 = extents.x*mAR.m[1][0] + extents.y*mAR.m[1][1] + extents.z*mAR.m[1][2] + mBoxExtents.y; + if(GREATER(t, t2)) return FALSE; + + t = Tx*mRBoxToModel.m[2][0] + Ty*mRBoxToModel.m[2][1] + Tz*mRBoxToModel.m[2][2]; + t2 = extents.x*mAR.m[2][0] + extents.y*mAR.m[2][1] + extents.z*mAR.m[2][2] + mBoxExtents.z; + if(GREATER(t, t2)) return FALSE; + + // Class III : 9 cross products + // Cool trick: always perform the full test for first level, regardless of settings. + // That way pathological cases (such as the pencils scene) are quickly rejected anyway ! + if(mFullBoxBoxTest || mNbVolumeBVTests==1) + { + t = Tz*mRBoxToModel.m[0][1] - Ty*mRBoxToModel.m[0][2]; t2 = extents.y*mAR.m[0][2] + extents.z*mAR.m[0][1] + mBB_1; if(GREATER(t, t2)) return FALSE; // L = A0 x B0 + t = Tz*mRBoxToModel.m[1][1] - Ty*mRBoxToModel.m[1][2]; t2 = extents.y*mAR.m[1][2] + extents.z*mAR.m[1][1] + mBB_2; if(GREATER(t, t2)) return FALSE; // L = A0 x B1 + t = Tz*mRBoxToModel.m[2][1] - Ty*mRBoxToModel.m[2][2]; t2 = extents.y*mAR.m[2][2] + extents.z*mAR.m[2][1] + mBB_3; if(GREATER(t, t2)) return FALSE; // L = A0 x B2 + t = Tx*mRBoxToModel.m[0][2] - Tz*mRBoxToModel.m[0][0]; t2 = extents.x*mAR.m[0][2] + extents.z*mAR.m[0][0] + mBB_4; if(GREATER(t, t2)) return FALSE; // L = A1 x B0 + t = Tx*mRBoxToModel.m[1][2] - Tz*mRBoxToModel.m[1][0]; t2 = extents.x*mAR.m[1][2] + extents.z*mAR.m[1][0] + mBB_5; if(GREATER(t, t2)) return FALSE; // L = A1 x B1 + t = Tx*mRBoxToModel.m[2][2] - Tz*mRBoxToModel.m[2][0]; t2 = extents.x*mAR.m[2][2] + extents.z*mAR.m[2][0] + mBB_6; if(GREATER(t, t2)) return FALSE; // L = A1 x B2 + t = Ty*mRBoxToModel.m[0][0] - Tx*mRBoxToModel.m[0][1]; t2 = extents.x*mAR.m[0][1] + extents.y*mAR.m[0][0] + mBB_7; if(GREATER(t, t2)) return FALSE; // L = A2 x B0 + t = Ty*mRBoxToModel.m[1][0] - Tx*mRBoxToModel.m[1][1]; t2 = extents.x*mAR.m[1][1] + extents.y*mAR.m[1][0] + mBB_8; if(GREATER(t, t2)) return FALSE; // L = A2 x B1 + t = Ty*mRBoxToModel.m[2][0] - Tx*mRBoxToModel.m[2][1]; t2 = extents.x*mAR.m[2][1] + extents.y*mAR.m[2][0] + mBB_9; if(GREATER(t, t2)) return FALSE; // L = A2 x B2 + } + return TRUE; +} + +//! A special version for 2 axis-aligned boxes +inline_ BOOL AABBCollider::AABBAABBOverlap(const Point& extents, const Point& center) +{ + // Stats + mNbVolumeBVTests++; + + float tx = mBox.mCenter.x - center.x; float ex = extents.x + mBox.mExtents.x; if(GREATER(tx, ex)) return FALSE; + float ty = mBox.mCenter.y - center.y; float ey = extents.y + mBox.mExtents.y; if(GREATER(ty, ey)) return FALSE; + float tz = mBox.mCenter.z - center.z; float ez = extents.z + mBox.mExtents.z; if(GREATER(tz, ez)) return FALSE; + + return TRUE; +} diff --git a/libs/ode-0.16.1/OPCODE/OPC_Collider.cpp b/libs/ode-0.16.1/OPCODE/OPC_Collider.cpp new file mode 100644 index 0000000..f41fc36 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_Collider.cpp @@ -0,0 +1,54 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains base collider class. + * \file OPC_Collider.cpp + * \author Pierre Terdiman + * \date June, 2, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains the abstract class for colliders. + * + * \class Collider + * \author Pierre Terdiman + * \version 1.3 + * \date June, 2, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Collider::Collider() : + mFlags (0), + mCurrentModel (null), + mIMesh (null) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Collider::~Collider() +{ +} diff --git a/libs/ode-0.16.1/OPCODE/OPC_Collider.h b/libs/ode-0.16.1/OPCODE/OPC_Collider.h new file mode 100644 index 0000000..d718e02 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_Collider.h @@ -0,0 +1,176 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains base collider class. + * \file OPC_Collider.h + * \author Pierre Terdiman + * \date June, 2, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_COLLIDER_H__ +#define __OPC_COLLIDER_H__ + + enum CollisionFlag + { + OPC_FIRST_CONTACT = (1<<0), //!< Report all contacts (false) or only first one (true) + OPC_TEMPORAL_COHERENCE = (1<<1), //!< Use temporal coherence or not + OPC_CONTACT = (1<<2), //!< Final contact status after a collision query + OPC_TEMPORAL_HIT = (1<<3), //!< There has been an early exit due to temporal coherence + OPC_NO_PRIMITIVE_TESTS = (1<<4), //!< Keep or discard primitive-bv tests in leaf nodes (volume-mesh queries) + + OPC_CONTACT_FOUND = OPC_FIRST_CONTACT | OPC_CONTACT, + OPC_TEMPORAL_CONTACT = OPC_TEMPORAL_HIT | OPC_CONTACT, + + OPC_FORCE_DWORD = 0x7fffffff + }; + + class OPCODE_API Collider + { + public: + // Constructor / Destructor + Collider(); + virtual ~Collider(); + + // Collision report + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the last collision status after a collision query. + * \return true if a collision occured + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL GetContactStatus() const { return mFlags & OPC_CONTACT; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the "first contact" mode. + * \return true if "first contact" mode is on + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL FirstContactEnabled() const { return mFlags & OPC_FIRST_CONTACT; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the temporal coherence mode. + * \return true if temporal coherence is on + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL TemporalCoherenceEnabled() const { return mFlags & OPC_TEMPORAL_COHERENCE; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks a first contact has already been found. + * \return true if a first contact has been found and we can stop a query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL ContactFound() const { return (mFlags&OPC_CONTACT_FOUND)==OPC_CONTACT_FOUND; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks there's been an early exit due to temporal coherence; + * \return true if a temporal hit has occured + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL TemporalHit() const { return mFlags & OPC_TEMPORAL_HIT; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks primitive tests are enabled; + * \return true if primitive tests must be skipped + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL SkipPrimitiveTests() const { return mFlags & OPC_NO_PRIMITIVE_TESTS; } + + // Settings + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Reports all contacts (false) or first contact only (true) + * \param flag [in] true for first contact, false for all contacts + * \see SetTemporalCoherence(bool flag) + * \see ValidateSettings() + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetFirstContact(bool flag) + { + if(flag) mFlags |= OPC_FIRST_CONTACT; + else mFlags &= ~OPC_FIRST_CONTACT; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Enable/disable temporal coherence. + * \param flag [in] true to enable temporal coherence, false to discard it + * \see SetFirstContact(bool flag) + * \see ValidateSettings() + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetTemporalCoherence(bool flag) + { + if(flag) mFlags |= OPC_TEMPORAL_COHERENCE; + else mFlags &= ~OPC_TEMPORAL_COHERENCE; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Enable/disable primitive tests. + * \param flag [in] true to enable primitive tests, false to discard them + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetPrimitiveTests(bool flag) + { + if(!flag) mFlags |= OPC_NO_PRIMITIVE_TESTS; + else mFlags &= ~OPC_NO_PRIMITIVE_TESTS; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Validates current settings. You should call this method after all the settings / callbacks have been defined for a collider. + * \return null if everything is ok, else a string describing the problem + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual const char* ValidateSettings() = 0; + + protected: + udword mFlags; //!< Bit flags + const BaseModel* mCurrentModel; //!< Current model for collision query (owner of touched faces) + // User mesh interface + const MeshInterface* mIMesh; //!< User-defined mesh interface + + // Internal methods + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups current collision model + * \param model [in] current collision model + * \return TRUE if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL Setup(const BaseModel* model) + { + // Keep track of current model + mCurrentModel = model; + if(!mCurrentModel) return FALSE; + + mIMesh = model->GetMeshInterface(); + return mIMesh!=null; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Initializes a query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual inline_ void InitQuery() { mFlags &= ~OPC_TEMPORAL_CONTACT; } + }; + +#endif // __OPC_COLLIDER_H__ diff --git a/libs/ode-0.16.1/OPCODE/OPC_Common.cpp b/libs/ode-0.16.1/OPCODE/OPC_Common.cpp new file mode 100644 index 0000000..5b9a9c8 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_Common.cpp @@ -0,0 +1,48 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains common classes & defs used in OPCODE. + * \file OPC_Common.cpp + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * An AABB dedicated to collision detection. + * We don't use the generic AABB class included in ICE, since it can be a Min/Max or a Center/Extents one (depends + * on compilation flags). Since the Center/Extents model is more efficient in collision detection, it was worth + * using an extra special class. + * + * \class CollisionAABB + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * A quantized AABB. + * Center/Extent model, using 16-bits integers. + * + * \class QuantizedAABB + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; diff --git a/libs/ode-0.16.1/OPCODE/OPC_Common.h b/libs/ode-0.16.1/OPCODE/OPC_Common.h new file mode 100644 index 0000000..f134990 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_Common.h @@ -0,0 +1,101 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains common classes & defs used in OPCODE. + * \file OPC_Common.h + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_COMMON_H__ +#define __OPC_COMMON_H__ + +// [GOTTFRIED]: Just a small change for readability. +#ifdef OPC_CPU_COMPARE + #define GREATER(x, y) AIR(x) > IR(y) +#else + #define GREATER(x, y) fabsf(x) > (y) +#endif + + class OPCODE_API CollisionAABB + { + public: + //! Constructor + inline_ CollisionAABB() {} + //! Constructor + inline_ CollisionAABB(const AABB& b) { b.GetCenter(mCenter); b.GetExtents(mExtents); } + //! Destructor + inline_ ~CollisionAABB() {} + + //! Get min point of the box + inline_ void GetMin(Point& min) const { min = mCenter - mExtents; } + //! Get max point of the box + inline_ void GetMax(Point& max) const { max = mCenter + mExtents; } + + //! Get component of the box's min point along a given axis + inline_ float GetMin(udword axis) const { return mCenter[axis] - mExtents[axis]; } + //! Get component of the box's max point along a given axis + inline_ float GetMax(udword axis) const { return mCenter[axis] + mExtents[axis]; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups an AABB from min & max vectors. + * \param min [in] the min point + * \param max [in] the max point + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetMinMax(const Point& min, const Point& max) { mCenter = (max + min)*0.5f; mExtents = (max - min)*0.5f; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks a box is inside another box. + * \param box [in] the other box + * \return true if current box is inside input box + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL IsInside(const CollisionAABB& box) const + { + if(box.GetMin(0)>GetMin(0)) return FALSE; + if(box.GetMin(1)>GetMin(1)) return FALSE; + if(box.GetMin(2)>GetMin(2)) return FALSE; + if(box.GetMax(0)<GetMax(0)) return FALSE; + if(box.GetMax(1)<GetMax(1)) return FALSE; + if(box.GetMax(2)<GetMax(2)) return FALSE; + return TRUE; + } + + Point mCenter; //!< Box center + Point mExtents; //!< Box extents + }; + + class OPCODE_API QuantizedAABB + { + public: + //! Constructor + inline_ QuantizedAABB() {} + //! Destructor + inline_ ~QuantizedAABB() {} + + sword mCenter[3]; //!< Quantized center + uword mExtents[3]; //!< Quantized extents + }; + + //! Quickly rotates & translates a vector + inline_ void TransformPoint(Point& dest, const Point& source, const Matrix3x3& rot, const Point& trans) + { + dest.x = trans.x + source.x * rot.m[0][0] + source.y * rot.m[1][0] + source.z * rot.m[2][0]; + dest.y = trans.y + source.x * rot.m[0][1] + source.y * rot.m[1][1] + source.z * rot.m[2][1]; + dest.z = trans.z + source.x * rot.m[0][2] + source.y * rot.m[1][2] + source.z * rot.m[2][2]; + } + +#endif //__OPC_COMMON_H__ diff --git a/libs/ode-0.16.1/OPCODE/OPC_HybridModel.cpp b/libs/ode-0.16.1/OPCODE/OPC_HybridModel.cpp new file mode 100644 index 0000000..509c1b6 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_HybridModel.cpp @@ -0,0 +1,467 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for hybrid models. + * \file OPC_HybridModel.cpp + * \author Pierre Terdiman + * \date May, 18, 2003 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * An hybrid collision model. + * + * The problem : + * + * Opcode really shines for mesh-mesh collision, especially when meshes are deeply overlapping + * (it typically outperforms RAPID in those cases). + * + * Unfortunately this is not the typical scenario in games. + * + * For close-proximity cases, especially for volume-mesh queries, it's relatively easy to run faster + * than Opcode, that suffers from a relatively high setup time. + * + * In particular, Opcode's "vanilla" trees in those cases -can- run faster. They can also use -less- + * memory than the optimized ones, when you let the system stop at ~10 triangles / leaf for example + * (i.e. when you don't use "complete" trees). However, those trees tend to fragment memory quite a + * lot, increasing cache misses : since they're not "complete", we can't predict the final number of + * nodes and we have to allocate nodes on-the-fly. For the same reasons we can't use Opcode's "optimized" + * trees here, since they rely on a known layout to perform the "optimization". + * + * Hybrid trees : + * + * Hybrid trees try to combine best of both worlds : + * + * - they use a maximum limit of 16 triangles/leaf. "16" is used so that we'll be able to save the + * number of triangles using 4 bits only. + * + * - they're still "complete" trees thanks to a two-passes building phase. First we create a "vanilla" + * AABB-tree with Opcode, limited to 16 triangles/leaf. Then we create a *second* vanilla tree, this + * time using the leaves of the first one. The trick is : this second tree is now "complete"... so we + * can further transform it into an Opcode's optimized tree. + * + * - then we run the collision queries on that standard Opcode tree. The only difference is that leaf + * nodes contain indices to leaf nodes of another tree. Also, we have to skip all primitive tests in + * Opcode optimized trees, since our leaves don't contain triangles anymore. + * + * - finally, for each collided leaf, we simply loop through 16 triangles max, and collide them with + * the bounding volume used in the query (we only support volume-vs-mesh queries here, not mesh-vs-mesh) + * + * All of that is wrapped in this "hybrid model" that contains the minimal data required for this to work. + * It's a mix between old "vanilla" trees, and old "optimized" trees. + * + * Extra advantages: + * + * - If we use them for dynamic models, we're left with a very small number of leaf nodes to refit. It + * might be a bit faster since we have less nodes to write back. + * + * - In rigid body simulation, using temporal coherence and sleeping objects greatly reduce the actual + * influence of one tree over another (i.e. the speed difference is often invisible). So memory is really + * the key element to consider, and in this regard hybrid trees are just better. + * + * Information to take home: + * - they use less ram + * - they're not slower (they're faster or slower depending on cases, overall there's no significant + * difference *as long as objects don't interpenetrate too much* - in which case Opcode's optimized trees + * are still notably faster) + * + * \class HybridModel + * \author Pierre Terdiman + * \version 1.3 + * \date May, 18, 2003 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HybridModel::HybridModel() : + mNbLeaves (0), + mTriangles (null), + mNbPrimitives (0), + mIndices (null) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HybridModel::~HybridModel() +{ + Release(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Releases everything. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void HybridModel::Release() +{ + ReleaseBase(); + DELETEARRAY(mIndices); + DELETEARRAY(mTriangles); + mNbLeaves = 0; + mNbPrimitives = 0; +} + + struct Internal + { + Internal() + { + mNbLeaves = 0; + mLeaves = null; + mTriangles = null; + mBase = null; + } + ~Internal() + { + DELETEARRAY(mLeaves); + } + + udword mNbLeaves; + AABB* mLeaves; + LeafTriangles* mTriangles; + const dTriIndex* mBase; + }; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Builds a collision model. + * \param create [in] model creation structure + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool HybridModel::Build(const OPCODECREATE& create) +{ + // 1) Checkings + if(!create.mIMesh || !create.mIMesh->IsValid()) return false; + + // Look for degenerate faces. + //udword NbDegenerate = create.mIMesh->CheckTopology(); + //if(NbDegenerate) Log("OPCODE WARNING: found %d degenerate faces in model! Collision might report wrong results!\n", NbDegenerate); + // We continue nonetheless.... + + Release(); // Make sure previous tree has been discarded + + // 1-1) Setup mesh interface automatically + SetMeshInterface(create.mIMesh); + + bool Status = false; + AABBTree* LeafTree = null; + Internal Data; + + // 2) Build a generic AABB Tree. + mSource = new AABBTree; + CHECKALLOC(mSource); + + // 2-1) Setup a builder. Our primitives here are triangles from input mesh, + // so we use an AABBTreeOfTrianglesBuilder..... + { + AABBTreeOfTrianglesBuilder TB; + TB.mIMesh = create.mIMesh; + TB.mNbPrimitives = create.mIMesh->GetNbTriangles(); + TB.mSettings = create.mSettings; + TB.mSettings.mLimit = 16; // ### Hardcoded, but maybe we could let the user choose 8 / 16 / 32 ... + if(!mSource->Build(&TB)) goto FreeAndExit; + } + + // 2-2) Here's the trick : create *another* AABB tree using the leaves of the first one (which are boxes, this time) + struct Local + { + // A callback to count leaf nodes + static bool CountLeaves(const AABBTreeNode* current, udword /*depth*/, void* user_data) + { + if(current->IsLeaf()) + { + Internal* Data = (Internal*)user_data; + Data->mNbLeaves++; + } + return true; + } + + // A callback to setup leaf nodes in our internal structures + static bool SetupLeafData(const AABBTreeNode* current, udword /*depth*/, void* user_data) + { + if(current->IsLeaf()) + { + Internal* Data = (Internal*)user_data; + + // Get current leaf's box + Data->mLeaves[Data->mNbLeaves] = *current->GetAABB(); + + // Setup leaf data + udword Index = udword((size_t(current->GetPrimitives()) - size_t(Data->mBase)) / sizeof(udword)); + Data->mTriangles[Data->mNbLeaves].SetData(current->GetNbPrimitives(), Index); + + Data->mNbLeaves++; + } + return true; + } + }; + + // Walk the tree & count number of leaves + Data.mNbLeaves = 0; + mSource->Walk(Local::CountLeaves, &Data); + mNbLeaves = Data.mNbLeaves; // Keep track of it + + // Special case for 1-leaf meshes + if(mNbLeaves==1) + { + mModelCode |= OPC_SINGLE_NODE; + Status = true; + goto FreeAndExit; + } + + // Allocate our structures + Data.mLeaves = new AABB[Data.mNbLeaves]; CHECKALLOC(Data.mLeaves); + mTriangles = new LeafTriangles[Data.mNbLeaves]; CHECKALLOC(mTriangles); + + // Walk the tree again & setup leaf data + Data.mTriangles = mTriangles; + Data.mBase = mSource->GetIndices(); + Data.mNbLeaves = 0; // Reset for incoming walk + mSource->Walk(Local::SetupLeafData, &Data); + + // Handle source indices + { + bool MustKeepIndices = true; + if(create.mCanRemap) + { + // We try to get rid of source indices (saving more ram!) by reorganizing triangle arrays... + // Remap can fail when we use callbacks => keep track of indices in that case (it still + // works, only using more memory) + if(create.mIMesh->RemapClient(mSource->GetNbPrimitives(), mSource->GetIndices())) + { + MustKeepIndices = false; + } + } + + if(MustKeepIndices) + { + // Keep track of source indices (from vanilla tree) + mNbPrimitives = mSource->GetNbPrimitives(); + mIndices = new udword[mNbPrimitives]; + CopyMemory(mIndices, mSource->GetIndices(), mNbPrimitives*sizeof(udword)); + } + } + + // Now, create our optimized tree using previous leaf nodes + LeafTree = new AABBTree; + CHECKALLOC(LeafTree); + { + AABBTreeOfAABBsBuilder TB; // Now using boxes ! + TB.mSettings = create.mSettings; + TB.mSettings.mLimit = 1; // We now want a complete tree so that we can "optimize" it + TB.mNbPrimitives = Data.mNbLeaves; + TB.mAABBArray = Data.mLeaves; + if(!LeafTree->Build(&TB)) goto FreeAndExit; + } + + // 3) Create an optimized tree according to user-settings + if(!CreateTree(create.mNoLeaf, create.mQuantized)) goto FreeAndExit; + + // 3-2) Create optimized tree + if(!mTree->Build(LeafTree)) goto FreeAndExit; + + // Finally ok... + Status = true; + +FreeAndExit: // Allow me this one... + DELETESINGLE(LeafTree); + + // 3-3) Delete generic tree if needed + if(!create.mKeepOriginal) DELETESINGLE(mSource); + + return Status; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Gets the number of bytes used by the tree. + * \return amount of bytes used + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +udword HybridModel::GetUsedBytes() const +{ + udword UsedBytes = 0; + if(mTree) UsedBytes += mTree->GetUsedBytes(); + if(mIndices) UsedBytes += mNbPrimitives * sizeof(udword); // mIndices + if(mTriangles) UsedBytes += mNbLeaves * sizeof(LeafTriangles); // mTriangles + return UsedBytes; +} + +inline_ void ComputeMinMax(Point& min, Point& max, const VertexPointers& vp) +{ + // Compute triangle's AABB = a leaf box +#ifdef OPC_USE_FCOMI // a 15% speedup on my machine, not much + min.x = FCMin3(vp.Vertex[0]->x, vp.Vertex[1]->x, vp.Vertex[2]->x); + max.x = FCMax3(vp.Vertex[0]->x, vp.Vertex[1]->x, vp.Vertex[2]->x); + + min.y = FCMin3(vp.Vertex[0]->y, vp.Vertex[1]->y, vp.Vertex[2]->y); + max.y = FCMax3(vp.Vertex[0]->y, vp.Vertex[1]->y, vp.Vertex[2]->y); + + min.z = FCMin3(vp.Vertex[0]->z, vp.Vertex[1]->z, vp.Vertex[2]->z); + max.z = FCMax3(vp.Vertex[0]->z, vp.Vertex[1]->z, vp.Vertex[2]->z); +#else + min = *vp.Vertex[0]; + max = *vp.Vertex[0]; + min.Min(*vp.Vertex[1]); + max.Max(*vp.Vertex[1]); + min.Min(*vp.Vertex[2]); + max.Max(*vp.Vertex[2]); +#endif +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Refits the collision model. This can be used to handle dynamic meshes. Usage is: + * 1. modify your mesh vertices (keep the topology constant!) + * 2. refit the tree (call this method) + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool HybridModel::Refit() +{ + if(!mIMesh) return false; + if(!mTree) return false; + + if(IsQuantized()) return false; + if(HasLeafNodes()) return false; + + const LeafTriangles* LT = GetLeafTriangles(); + const udword* Indices = GetIndices(); + + // Bottom-up update + VertexPointers VP; + ConversionArea VC; + Point Min,Max; + Point Min_,Max_; + udword Index = mTree->GetNbNodes(); + AABBNoLeafNode* Nodes = const_cast<AABBNoLeafNode *>(static_cast<const AABBNoLeafNode *>(static_cast<AABBNoLeafTree *>(mTree)->GetNodes())); + while(Index--) + { + AABBNoLeafNode& Current = Nodes[Index]; + + if(Current.HasPosLeaf()) + { + const LeafTriangles& CurrentLeaf = LT[Current.GetPosPrimitive()]; + + Min.SetPlusInfinity(); + Max.SetMinusInfinity(); + + Point TmpMin, TmpMax; + + // Each leaf box has a set of triangles + udword NbTris = CurrentLeaf.GetNbTriangles(); + if(Indices) + { + const udword* T = &Indices[CurrentLeaf.GetTriangleIndex()]; + + // Loop through triangles and test each of them + while(NbTris--) + { + mIMesh->GetTriangle(VP, *T++, VC); + ComputeMinMax(TmpMin, TmpMax, VP); + Min.Min(TmpMin); + Max.Max(TmpMax); + } + } + else + { + udword BaseIndex = CurrentLeaf.GetTriangleIndex(); + + // Loop through triangles and test each of them + while(NbTris--) + { + mIMesh->GetTriangle(VP, BaseIndex++, VC); + ComputeMinMax(TmpMin, TmpMax, VP); + Min.Min(TmpMin); + Max.Max(TmpMax); + } + } + } + else + { + const CollisionAABB& CurrentBox = Current.GetPos()->mAABB; + CurrentBox.GetMin(Min); + CurrentBox.GetMax(Max); + } + + if(Current.HasNegLeaf()) + { + const LeafTriangles& CurrentLeaf = LT[Current.GetNegPrimitive()]; + + Min_.SetPlusInfinity(); + Max_.SetMinusInfinity(); + + Point TmpMin, TmpMax; + + // Each leaf box has a set of triangles + udword NbTris = CurrentLeaf.GetNbTriangles(); + if(Indices) + { + const udword* T = &Indices[CurrentLeaf.GetTriangleIndex()]; + + // Loop through triangles and test each of them + while(NbTris--) + { + mIMesh->GetTriangle(VP, *T++, VC); + ComputeMinMax(TmpMin, TmpMax, VP); + Min_.Min(TmpMin); + Max_.Max(TmpMax); + } + } + else + { + udword BaseIndex = CurrentLeaf.GetTriangleIndex(); + + // Loop through triangles and test each of them + while(NbTris--) + { + mIMesh->GetTriangle(VP, BaseIndex++, VC); + ComputeMinMax(TmpMin, TmpMax, VP); + Min_.Min(TmpMin); + Max_.Max(TmpMax); + } + } + } + else + { + const CollisionAABB& CurrentBox = Current.GetNeg()->mAABB; + CurrentBox.GetMin(Min_); + CurrentBox.GetMax(Max_); + } +#ifdef OPC_USE_FCOMI + Min.x = FCMin2(Min.x, Min_.x); + Max.x = FCMax2(Max.x, Max_.x); + Min.y = FCMin2(Min.y, Min_.y); + Max.y = FCMax2(Max.y, Max_.y); + Min.z = FCMin2(Min.z, Min_.z); + Max.z = FCMax2(Max.z, Max_.z); +#else + Min.Min(Min_); + Max.Max(Max_); +#endif + Current.mAABB.SetMinMax(Min, Max); + } + return true; +} diff --git a/libs/ode-0.16.1/OPCODE/OPC_HybridModel.h b/libs/ode-0.16.1/OPCODE/OPC_HybridModel.h new file mode 100644 index 0000000..c7eb59d --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_HybridModel.h @@ -0,0 +1,106 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for hybrid models. + * \file OPC_HybridModel.h + * \author Pierre Terdiman + * \date May, 18, 2003 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_HYBRIDMODEL_H__ +#define __OPC_HYBRIDMODEL_H__ + + //! Leaf descriptor + struct LeafTriangles + { + udword Data; //!< Packed data + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets number of triangles in the leaf. + * \return number of triangles N, with 0 < N <= 16 + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbTriangles() const { return (Data & 15)+1; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets triangle index for this leaf. Indexed model's array of indices retrieved with HybridModel::GetIndices() + * \return triangle index + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetTriangleIndex() const { return Data>>4; } + inline_ void SetData(udword nb, udword index) { ASSERT(nb>0 && nb<=16); nb--; Data = (index<<4)|(nb&15); } + }; + + class OPCODE_API HybridModel : public BaseModel + { + public: + // Constructor/Destructor + HybridModel(); + virtual ~HybridModel(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Builds a collision model. + * \param create [in] model creation structure + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(BaseModel) bool Build(const OPCODECREATE& create); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the number of bytes used by the tree. + * \return amount of bytes used + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(BaseModel) udword GetUsedBytes() const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Refits the collision model. This can be used to handle dynamic meshes. Usage is: + * 1. modify your mesh vertices (keep the topology constant!) + * 2. refit the tree (call this method) + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(BaseModel) bool Refit(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets array of triangles. + * \return array of triangles + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ const LeafTriangles* GetLeafTriangles() const { return mTriangles; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets array of indices. + * \return array of indices + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ const udword* GetIndices() const { return mIndices; } + + private: + udword mNbLeaves; //!< Number of leaf nodes in the model + LeafTriangles* mTriangles; //!< Array of mNbLeaves leaf descriptors + udword mNbPrimitives; //!< Number of primitives in the model + udword* mIndices; //!< Array of primitive indices + + // Internal methods + void Release(); + }; + +#endif // __OPC_HYBRIDMODEL_H__ diff --git a/libs/ode-0.16.1/OPCODE/OPC_IceHook.h b/libs/ode-0.16.1/OPCODE/OPC_IceHook.h new file mode 100644 index 0000000..4fc6c8a --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_IceHook.h @@ -0,0 +1,80 @@ + +// Should be included by Opcode.h if needed + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_ICEHOOK_H__ +#define __OPC_ICEHOOK_H__ + + #define ICE_DONT_CHECK_COMPILER_OPTIONS + + // From Windows... + typedef int BOOL; + #ifndef FALSE + #define FALSE 0 + #endif + + #ifndef TRUE + #define TRUE 1 + #endif + + #include <stdio.h> + #include <stdlib.h> + #include <assert.h> + #include <string.h> + #include <float.h> + #include <math.h> + + #ifndef ASSERT + #define ASSERT(exp) {} + #endif + #define ICE_COMPILE_TIME_ASSERT(exp) extern char ICE_Dummy[ (exp) ? 1 : -1 ] + + #define Log {} + #define SetIceError(a,b) false + #define EC_OUTOFMEMORY "Out of memory" + + extern void OPCODE_NORETURN IceAbort(); + + #include "Ice/IcePreprocessor.h" + + #undef ICECORE_API + #define ICECORE_API OPCODE_API + + #include "Ice/IceTypes.h" + #include "Ice/IceFPU.h" + #include "Ice/IceMemoryMacros.h" + + namespace IceCore + { + #include "Ice/IceUtils.h" + #include "Ice/IceContainer.h" + #include "Ice/IcePairs.h" + #include "Ice/IceRevisitedRadix.h" + #include "Ice/IceRandom.h" + } + using namespace IceCore; + + #define ICEMATHS_API OPCODE_API + namespace IceMaths + { + #include "Ice/IceAxes.h" + #include "Ice/IcePoint.h" + #include "Ice/IceHPoint.h" + #include "Ice/IceMatrix3x3.h" + #include "Ice/IceMatrix4x4.h" + #include "Ice/IcePlane.h" + #include "Ice/IceRay.h" + #include "Ice/IceIndexedTriangle.h" + #include "Ice/IceTriangle.h" + #include "Ice/IceTriList.h" + #include "Ice/IceAABB.h" + #include "Ice/IceOBB.h" + #include "Ice/IceBoundingSphere.h" + #include "Ice/IceSegment.h" + #include "Ice/IceLSS.h" + } + using namespace IceMaths; + + +#endif // __OPC_ICEHOOK_H__ diff --git a/libs/ode-0.16.1/OPCODE/OPC_LSSAABBOverlap.h b/libs/ode-0.16.1/OPCODE/OPC_LSSAABBOverlap.h new file mode 100644 index 0000000..c6ba9d3 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_LSSAABBOverlap.h @@ -0,0 +1,525 @@ + +// Following code from Magic-Software (http://www.magic-software.com/) +// A bit modified for Opcode + +inline_ float OPC_PointAABBSqrDist(const Point& point, const Point& center, const Point& extents) +{ + // Compute coordinates of point in box coordinate system + Point Closest = point - center; + + float SqrDistance = 0.0f; + + if(Closest.x < -extents.x) + { + float Delta = Closest.x + extents.x; + SqrDistance += Delta*Delta; + } + else if(Closest.x > extents.x) + { + float Delta = Closest.x - extents.x; + SqrDistance += Delta*Delta; + } + + if(Closest.y < -extents.y) + { + float Delta = Closest.y + extents.y; + SqrDistance += Delta*Delta; + } + else if(Closest.y > extents.y) + { + float Delta = Closest.y - extents.y; + SqrDistance += Delta*Delta; + } + + if(Closest.z < -extents.z) + { + float Delta = Closest.z + extents.z; + SqrDistance += Delta*Delta; + } + else if(Closest.z > extents.z) + { + float Delta = Closest.z - extents.z; + SqrDistance += Delta*Delta; + } + return SqrDistance; +} + +static void Face(int i0, int i1, int i2, Point& rkPnt, const Point& rkDir, const Point& extents, const Point& rkPmE, float* pfLParam, float& rfSqrDistance) +{ + Point kPpE; + float fLSqr, fInv, fTmp, fParam, fT, fDelta; + + kPpE[i1] = rkPnt[i1] + extents[i1]; + kPpE[i2] = rkPnt[i2] + extents[i2]; + if(rkDir[i0]*kPpE[i1] >= rkDir[i1]*rkPmE[i0]) + { + if(rkDir[i0]*kPpE[i2] >= rkDir[i2]*rkPmE[i0]) + { + // v[i1] >= -e[i1], v[i2] >= -e[i2] (distance = 0) + if(pfLParam) + { + rkPnt[i0] = extents[i0]; + fInv = 1.0f/rkDir[i0]; + rkPnt[i1] -= rkDir[i1]*rkPmE[i0]*fInv; + rkPnt[i2] -= rkDir[i2]*rkPmE[i0]*fInv; + *pfLParam = -rkPmE[i0]*fInv; + } + } + else + { + // v[i1] >= -e[i1], v[i2] < -e[i2] + fLSqr = rkDir[i0]*rkDir[i0] + rkDir[i2]*rkDir[i2]; + fTmp = fLSqr*kPpE[i1] - rkDir[i1]*(rkDir[i0]*rkPmE[i0] + rkDir[i2]*kPpE[i2]); + if(fTmp <= 2.0f*fLSqr*extents[i1]) + { + fT = fTmp/fLSqr; + fLSqr += rkDir[i1]*rkDir[i1]; + fTmp = kPpE[i1] - fT; + fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*fTmp + rkDir[i2]*kPpE[i2]; + fParam = -fDelta/fLSqr; + rfSqrDistance += rkPmE[i0]*rkPmE[i0] + fTmp*fTmp + kPpE[i2]*kPpE[i2] + fDelta*fParam; + + if(pfLParam) + { + *pfLParam = fParam; + rkPnt[i0] = extents[i0]; + rkPnt[i1] = fT - extents[i1]; + rkPnt[i2] = -extents[i2]; + } + } + else + { + fLSqr += rkDir[i1]*rkDir[i1]; + fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*rkPmE[i1] + rkDir[i2]*kPpE[i2]; + fParam = -fDelta/fLSqr; + rfSqrDistance += rkPmE[i0]*rkPmE[i0] + rkPmE[i1]*rkPmE[i1] + kPpE[i2]*kPpE[i2] + fDelta*fParam; + + if(pfLParam) + { + *pfLParam = fParam; + rkPnt[i0] = extents[i0]; + rkPnt[i1] = extents[i1]; + rkPnt[i2] = -extents[i2]; + } + } + } + } + else + { + if ( rkDir[i0]*kPpE[i2] >= rkDir[i2]*rkPmE[i0] ) + { + // v[i1] < -e[i1], v[i2] >= -e[i2] + fLSqr = rkDir[i0]*rkDir[i0] + rkDir[i1]*rkDir[i1]; + fTmp = fLSqr*kPpE[i2] - rkDir[i2]*(rkDir[i0]*rkPmE[i0] + rkDir[i1]*kPpE[i1]); + if(fTmp <= 2.0f*fLSqr*extents[i2]) + { + fT = fTmp/fLSqr; + fLSqr += rkDir[i2]*rkDir[i2]; + fTmp = kPpE[i2] - fT; + fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*kPpE[i1] + rkDir[i2]*fTmp; + fParam = -fDelta/fLSqr; + rfSqrDistance += rkPmE[i0]*rkPmE[i0] + kPpE[i1]*kPpE[i1] + fTmp*fTmp + fDelta*fParam; + + if(pfLParam) + { + *pfLParam = fParam; + rkPnt[i0] = extents[i0]; + rkPnt[i1] = -extents[i1]; + rkPnt[i2] = fT - extents[i2]; + } + } + else + { + fLSqr += rkDir[i2]*rkDir[i2]; + fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*kPpE[i1] + rkDir[i2]*rkPmE[i2]; + fParam = -fDelta/fLSqr; + rfSqrDistance += rkPmE[i0]*rkPmE[i0] + kPpE[i1]*kPpE[i1] + rkPmE[i2]*rkPmE[i2] + fDelta*fParam; + + if(pfLParam) + { + *pfLParam = fParam; + rkPnt[i0] = extents[i0]; + rkPnt[i1] = -extents[i1]; + rkPnt[i2] = extents[i2]; + } + } + } + else + { + // v[i1] < -e[i1], v[i2] < -e[i2] + fLSqr = rkDir[i0]*rkDir[i0]+rkDir[i2]*rkDir[i2]; + fTmp = fLSqr*kPpE[i1] - rkDir[i1]*(rkDir[i0]*rkPmE[i0] + rkDir[i2]*kPpE[i2]); + if(fTmp >= 0.0f) + { + // v[i1]-edge is closest + if ( fTmp <= 2.0f*fLSqr*extents[i1] ) + { + fT = fTmp/fLSqr; + fLSqr += rkDir[i1]*rkDir[i1]; + fTmp = kPpE[i1] - fT; + fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*fTmp + rkDir[i2]*kPpE[i2]; + fParam = -fDelta/fLSqr; + rfSqrDistance += rkPmE[i0]*rkPmE[i0] + fTmp*fTmp + kPpE[i2]*kPpE[i2] + fDelta*fParam; + + if(pfLParam) + { + *pfLParam = fParam; + rkPnt[i0] = extents[i0]; + rkPnt[i1] = fT - extents[i1]; + rkPnt[i2] = -extents[i2]; + } + } + else + { + fLSqr += rkDir[i1]*rkDir[i1]; + fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*rkPmE[i1] + rkDir[i2]*kPpE[i2]; + fParam = -fDelta/fLSqr; + rfSqrDistance += rkPmE[i0]*rkPmE[i0] + rkPmE[i1]*rkPmE[i1] + kPpE[i2]*kPpE[i2] + fDelta*fParam; + + if(pfLParam) + { + *pfLParam = fParam; + rkPnt[i0] = extents[i0]; + rkPnt[i1] = extents[i1]; + rkPnt[i2] = -extents[i2]; + } + } + return; + } + + fLSqr = rkDir[i0]*rkDir[i0] + rkDir[i1]*rkDir[i1]; + fTmp = fLSqr*kPpE[i2] - rkDir[i2]*(rkDir[i0]*rkPmE[i0] + rkDir[i1]*kPpE[i1]); + if(fTmp >= 0.0f) + { + // v[i2]-edge is closest + if(fTmp <= 2.0f*fLSqr*extents[i2]) + { + fT = fTmp/fLSqr; + fLSqr += rkDir[i2]*rkDir[i2]; + fTmp = kPpE[i2] - fT; + fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*kPpE[i1] + rkDir[i2]*fTmp; + fParam = -fDelta/fLSqr; + rfSqrDistance += rkPmE[i0]*rkPmE[i0] + kPpE[i1]*kPpE[i1] + fTmp*fTmp + fDelta*fParam; + + if(pfLParam) + { + *pfLParam = fParam; + rkPnt[i0] = extents[i0]; + rkPnt[i1] = -extents[i1]; + rkPnt[i2] = fT - extents[i2]; + } + } + else + { + fLSqr += rkDir[i2]*rkDir[i2]; + fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*kPpE[i1] + rkDir[i2]*rkPmE[i2]; + fParam = -fDelta/fLSqr; + rfSqrDistance += rkPmE[i0]*rkPmE[i0] + kPpE[i1]*kPpE[i1] + rkPmE[i2]*rkPmE[i2] + fDelta*fParam; + + if(pfLParam) + { + *pfLParam = fParam; + rkPnt[i0] = extents[i0]; + rkPnt[i1] = -extents[i1]; + rkPnt[i2] = extents[i2]; + } + } + return; + } + + // (v[i1],v[i2])-corner is closest + fLSqr += rkDir[i2]*rkDir[i2]; + fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*kPpE[i1] + rkDir[i2]*kPpE[i2]; + fParam = -fDelta/fLSqr; + rfSqrDistance += rkPmE[i0]*rkPmE[i0] + kPpE[i1]*kPpE[i1] + kPpE[i2]*kPpE[i2] + fDelta*fParam; + + if(pfLParam) + { + *pfLParam = fParam; + rkPnt[i0] = extents[i0]; + rkPnt[i1] = -extents[i1]; + rkPnt[i2] = -extents[i2]; + } + } + } +} + +static void CaseNoZeros(Point& rkPnt, const Point& rkDir, const Point& extents, float* pfLParam, float& rfSqrDistance) +{ + Point kPmE(rkPnt.x - extents.x, rkPnt.y - extents.y, rkPnt.z - extents.z); + + float fProdDxPy, fProdDyPx, fProdDzPx, fProdDxPz, fProdDzPy, fProdDyPz; + + fProdDxPy = rkDir.x*kPmE.y; + fProdDyPx = rkDir.y*kPmE.x; + if(fProdDyPx >= fProdDxPy) + { + fProdDzPx = rkDir.z*kPmE.x; + fProdDxPz = rkDir.x*kPmE.z; + if(fProdDzPx >= fProdDxPz) + { + // line intersects x = e0 + Face(0, 1, 2, rkPnt, rkDir, extents, kPmE, pfLParam, rfSqrDistance); + } + else + { + // line intersects z = e2 + Face(2, 0, 1, rkPnt, rkDir, extents, kPmE, pfLParam, rfSqrDistance); + } + } + else + { + fProdDzPy = rkDir.z*kPmE.y; + fProdDyPz = rkDir.y*kPmE.z; + if(fProdDzPy >= fProdDyPz) + { + // line intersects y = e1 + Face(1, 2, 0, rkPnt, rkDir, extents, kPmE, pfLParam, rfSqrDistance); + } + else + { + // line intersects z = e2 + Face(2, 0, 1, rkPnt, rkDir, extents, kPmE, pfLParam, rfSqrDistance); + } + } +} + +static void Case0(int i0, int i1, int i2, Point& rkPnt, const Point& rkDir, const Point& extents, float* pfLParam, float& rfSqrDistance) +{ + float fPmE0 = rkPnt[i0] - extents[i0]; + float fPmE1 = rkPnt[i1] - extents[i1]; + float fProd0 = rkDir[i1]*fPmE0; + float fProd1 = rkDir[i0]*fPmE1; + float fDelta, fInvLSqr, fInv; + + if(fProd0 >= fProd1) + { + // line intersects P[i0] = e[i0] + rkPnt[i0] = extents[i0]; + + float fPpE1 = rkPnt[i1] + extents[i1]; + fDelta = fProd0 - rkDir[i0]*fPpE1; + if(fDelta >= 0.0f) + { + fInvLSqr = 1.0f/(rkDir[i0]*rkDir[i0] + rkDir[i1]*rkDir[i1]); + rfSqrDistance += fDelta*fDelta*fInvLSqr; + if(pfLParam) + { + rkPnt[i1] = -extents[i1]; + *pfLParam = -(rkDir[i0]*fPmE0+rkDir[i1]*fPpE1)*fInvLSqr; + } + } + else + { + if(pfLParam) + { + fInv = 1.0f/rkDir[i0]; + rkPnt[i1] -= fProd0*fInv; + *pfLParam = -fPmE0*fInv; + } + } + } + else + { + // line intersects P[i1] = e[i1] + rkPnt[i1] = extents[i1]; + + float fPpE0 = rkPnt[i0] + extents[i0]; + fDelta = fProd1 - rkDir[i1]*fPpE0; + if(fDelta >= 0.0f) + { + fInvLSqr = 1.0f/(rkDir[i0]*rkDir[i0] + rkDir[i1]*rkDir[i1]); + rfSqrDistance += fDelta*fDelta*fInvLSqr; + if(pfLParam) + { + rkPnt[i0] = -extents[i0]; + *pfLParam = -(rkDir[i0]*fPpE0+rkDir[i1]*fPmE1)*fInvLSqr; + } + } + else + { + if(pfLParam) + { + fInv = 1.0f/rkDir[i1]; + rkPnt[i0] -= fProd1*fInv; + *pfLParam = -fPmE1*fInv; + } + } + } + + if(rkPnt[i2] < -extents[i2]) + { + fDelta = rkPnt[i2] + extents[i2]; + rfSqrDistance += fDelta*fDelta; + rkPnt[i2] = -extents[i2]; + } + else if ( rkPnt[i2] > extents[i2] ) + { + fDelta = rkPnt[i2] - extents[i2]; + rfSqrDistance += fDelta*fDelta; + rkPnt[i2] = extents[i2]; + } +} + +static void Case00(int i0, int i1, int i2, Point& rkPnt, const Point& rkDir, const Point& extents, float* pfLParam, float& rfSqrDistance) +{ + float fDelta; + + if(pfLParam) + *pfLParam = (extents[i0] - rkPnt[i0])/rkDir[i0]; + + rkPnt[i0] = extents[i0]; + + if(rkPnt[i1] < -extents[i1]) + { + fDelta = rkPnt[i1] + extents[i1]; + rfSqrDistance += fDelta*fDelta; + rkPnt[i1] = -extents[i1]; + } + else if(rkPnt[i1] > extents[i1]) + { + fDelta = rkPnt[i1] - extents[i1]; + rfSqrDistance += fDelta*fDelta; + rkPnt[i1] = extents[i1]; + } + + if(rkPnt[i2] < -extents[i2]) + { + fDelta = rkPnt[i2] + extents[i2]; + rfSqrDistance += fDelta*fDelta; + rkPnt[i1] = -extents[i2]; + } + else if(rkPnt[i2] > extents[i2]) + { + fDelta = rkPnt[i2] - extents[i2]; + rfSqrDistance += fDelta*fDelta; + rkPnt[i2] = extents[i2]; + } +} + +static void Case000(Point& rkPnt, const Point& extents, float& rfSqrDistance) +{ + float fDelta; + + if(rkPnt.x < -extents.x) + { + fDelta = rkPnt.x + extents.x; + rfSqrDistance += fDelta*fDelta; + rkPnt.x = -extents.x; + } + else if(rkPnt.x > extents.x) + { + fDelta = rkPnt.x - extents.x; + rfSqrDistance += fDelta*fDelta; + rkPnt.x = extents.x; + } + + if(rkPnt.y < -extents.y) + { + fDelta = rkPnt.y + extents.y; + rfSqrDistance += fDelta*fDelta; + rkPnt.y = -extents.y; + } + else if(rkPnt.y > extents.y) + { + fDelta = rkPnt.y - extents.y; + rfSqrDistance += fDelta*fDelta; + rkPnt.y = extents.y; + } + + if(rkPnt.z < -extents.z) + { + fDelta = rkPnt.z + extents.z; + rfSqrDistance += fDelta*fDelta; + rkPnt.z = -extents.z; + } + else if(rkPnt.z > extents.z) + { + fDelta = rkPnt.z - extents.z; + rfSqrDistance += fDelta*fDelta; + rkPnt.z = extents.z; + } +} + +static float SqrDistance(const Ray& rkLine, const Point& center, const Point& extents, float* pfLParam) +{ + // compute coordinates of line in box coordinate system + Point kDiff = rkLine.mOrig - center; + Point kPnt = kDiff; + Point kDir = rkLine.mDir; + +#if 0 + // Apply reflections so that direction vector has nonnegative components. + bool bReflect[3]; + for(int i=0;i<3;i++) + { + if(kDir[i]<0.0f) + { + kPnt[i] = -kPnt[i]; + kDir[i] = -kDir[i]; + bReflect[i] = true; + } + else + { + bReflect[i] = false; + } + } +#endif + + float fSqrDistance = 0.0f; + + if(kDir.x>0.0f) + { + if(kDir.y>0.0f) + { + if(kDir.z>0.0f) CaseNoZeros(kPnt, kDir, extents, pfLParam, fSqrDistance); // (+,+,+) + else Case0(0, 1, 2, kPnt, kDir, extents, pfLParam, fSqrDistance); // (+,+,0) + } + else + { + if(kDir.z>0.0f) Case0(0, 2, 1, kPnt, kDir, extents, pfLParam, fSqrDistance); // (+,0,+) + else Case00(0, 1, 2, kPnt, kDir, extents, pfLParam, fSqrDistance); // (+,0,0) + } + } + else + { + if(kDir.y>0.0f) + { + if(kDir.z>0.0f) Case0(1, 2, 0, kPnt, kDir, extents, pfLParam, fSqrDistance); // (0,+,+) + else Case00(1, 0, 2, kPnt, kDir, extents, pfLParam, fSqrDistance); // (0,+,0) + } + else + { + if(kDir.z>0.0f) Case00(2, 0, 1, kPnt, kDir, extents, pfLParam, fSqrDistance); // (0,0,+) + else + { + Case000(kPnt, extents, fSqrDistance); // (0,0,0) + if(pfLParam) *pfLParam = 0.0f; + } + } + } + return fSqrDistance; +} + +inline_ float OPC_SegmentOBBSqrDist(const Segment& segment, const Point& c0, const Point& e0) +{ + float fLP; + float fSqrDistance = SqrDistance(Ray(segment.GetOrigin(), segment.ComputeDirection()), c0, e0, &fLP); + if(fLP>=0.0f) + { + if(fLP<=1.0f) return fSqrDistance; + else return OPC_PointAABBSqrDist(segment.mP1, c0, e0); + } + else return OPC_PointAABBSqrDist(segment.mP0, c0, e0); +} + +inline_ BOOL LSSCollider::LSSAABBOverlap(const Point& center, const Point& extents) +{ + // Stats + mNbVolumeBVTests++; + + float s2 = OPC_SegmentOBBSqrDist(mSeg, center, extents); + if(s2<mRadius2) return TRUE; + + return FALSE; +} diff --git a/libs/ode-0.16.1/OPCODE/OPC_LSSCollider.cpp b/libs/ode-0.16.1/OPCODE/OPC_LSSCollider.cpp new file mode 100644 index 0000000..fd47bcc --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_LSSCollider.cpp @@ -0,0 +1,725 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for an LSS collider. + * \file OPC_LSSCollider.cpp + * \author Pierre Terdiman + * \date December, 28, 2002 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a lss-vs-tree collider. + * + * \class LSSCollider + * \author Pierre Terdiman + * \version 1.3 + * \date December, 28, 2002 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +#include "OPC_LSSAABBOverlap.h" +#include "OPC_LSSTriOverlap.h" + +#define SET_CONTACT(prim_index, flag) \ + /* Set contact status */ \ + mFlags |= flag; \ + mTouchedPrimitives->Add(udword(prim_index)); + +//! LSS-triangle overlap test +#define LSS_PRIM(prim_index, flag) \ + /* Request vertices from the app */ \ + VertexPointers VP; ConversionArea VC; mIMesh->GetTriangle(VP, prim_index, VC); \ + \ + /* Perform LSS-tri overlap test */ \ + if(LSSTriOverlap(*VP.Vertex[0], *VP.Vertex[1], *VP.Vertex[2])) \ + { \ + SET_CONTACT(prim_index, flag) \ + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +LSSCollider::LSSCollider() +{ +// mCenter.Zero(); +// mRadius2 = 0.0f; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +LSSCollider::~LSSCollider() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Generic collision query for generic OPCODE models. After the call, access the results: + * - with GetContactStatus() + * - with GetNbTouchedPrimitives() + * - with GetTouchedPrimitives() + * + * \param cache [in/out] an lss cache + * \param lss [in] collision lss in local space + * \param model [in] Opcode model to collide with + * \param worldl [in] lss world matrix, or null + * \param worldm [in] model's world matrix, or null + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool LSSCollider::Collide(LSSCache& cache, const LSS& lss, const Model& model, const Matrix4x4* worldl, const Matrix4x4* worldm) +{ + // Checkings + if(!Setup(&model)) return false; + + // Init collision query + if(InitQuery(cache, lss, worldl, worldm)) return true; + + if(!model.HasLeafNodes()) + { + if(model.IsQuantized()) + { + const AABBQuantizedNoLeafTree* Tree = static_cast<const AABBQuantizedNoLeafTree *>(model.GetTree()); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + else + { + const AABBNoLeafTree* Tree = static_cast<const AABBNoLeafTree *>(model.GetTree()); + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + } + else + { + if(model.IsQuantized()) + { + const AABBQuantizedTree* Tree = static_cast<const AABBQuantizedTree *>(model.GetTree()); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + else + { + const AABBCollisionTree* Tree = static_cast<const AABBCollisionTree *>(model.GetTree()); + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + } + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Initializes a collision query : + * - reset stats & contact status + * - setup matrices + * - check temporal coherence + * + * \param cache [in/out] an lss cache + * \param lss [in] lss in local space + * \param worldl [in] lss world matrix, or null + * \param worldm [in] model's world matrix, or null + * \return TRUE if we can return immediately + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +BOOL LSSCollider::InitQuery(LSSCache& cache, const LSS& lss, const Matrix4x4* worldl, const Matrix4x4* worldm) +{ + // 1) Call the base method + VolumeCollider::InitQuery(); + + // 2) Compute LSS in model space: + // - Precompute R^2 + mRadius2 = lss.mRadius * lss.mRadius; + // - Compute segment + mSeg.mP0 = lss.mP0; + mSeg.mP1 = lss.mP1; + // -> to world space + if(worldl) + { + mSeg.mP0 *= *worldl; + mSeg.mP1 *= *worldl; + } + // -> to model space + if(worldm) + { + // Invert model matrix + Matrix4x4 InvWorldM; + InvertPRMatrix(InvWorldM, *worldm); + + mSeg.mP0 *= InvWorldM; + mSeg.mP1 *= InvWorldM; + } + + // 3) Setup destination pointer + mTouchedPrimitives = &cache.TouchedPrimitives; + + // 4) Special case: 1-triangle meshes [Opcode 1.3] + if(mCurrentModel && mCurrentModel->HasSingleNode()) + { + if(!SkipPrimitiveTests()) + { + // We simply perform the BV-Prim overlap test each time. We assume single triangle has index 0. + mTouchedPrimitives->Reset(); + + // Perform overlap test between the unique triangle and the LSS (and set contact status if needed) + LSS_PRIM(udword(0), OPC_CONTACT) + + // Return immediately regardless of status + return TRUE; + } + } + + // 5) Check temporal coherence : + if(TemporalCoherenceEnabled()) + { + // Here we use temporal coherence + // => check results from previous frame before performing the collision query + if(FirstContactEnabled()) + { + // We're only interested in the first contact found => test the unique previously touched face + if(mTouchedPrimitives->GetNbEntries()) + { + // Get index of previously touched face = the first entry in the array + udword PreviouslyTouchedFace = mTouchedPrimitives->GetEntry(0); + + // Then reset the array: + // - if the overlap test below is successful, the index we'll get added back anyway + // - if it isn't, then the array should be reset anyway for the normal query + mTouchedPrimitives->Reset(); + + // Perform overlap test between the cached triangle and the LSS (and set contact status if needed) + LSS_PRIM(PreviouslyTouchedFace, OPC_TEMPORAL_CONTACT) + + // Return immediately if possible + if(GetContactStatus()) return TRUE; + } + // else no face has been touched during previous query + // => we'll have to perform a normal query + } + else + { + // We're interested in all contacts =>test the new real LSS N(ew) against the previous fat LSS P(revious): + + // ### rewrite this + + LSS Test(mSeg, lss.mRadius); // in model space + LSS Previous(cache.Previous, sqrtf(cache.Previous.mRadius)); + +// if(cache.Previous.Contains(Test)) + if(IsCacheValid(cache) && Previous.Contains(Test)) + { + // - if N is included in P, return previous list + // => we simply leave the list (mTouchedFaces) unchanged + + // Set contact status if needed + if(mTouchedPrimitives->GetNbEntries()) mFlags |= OPC_TEMPORAL_CONTACT; + + // In any case we don't need to do a query + return TRUE; + } + else + { + // - else do the query using a fat N + + // Reset cache since we'll about to perform a real query + mTouchedPrimitives->Reset(); + + // Make a fat sphere so that coherence will work for subsequent frames + mRadius2 *= cache.FatCoeff; +// mRadius2 = (lss.mRadius * cache.FatCoeff)*(lss.mRadius * cache.FatCoeff); + + + // Update cache with query data (signature for cached faces) + cache.Previous.mP0 = mSeg.mP0; + cache.Previous.mP1 = mSeg.mP1; + cache.Previous.mRadius = mRadius2; + } + } + } + else + { + // Here we don't use temporal coherence => do a normal query + mTouchedPrimitives->Reset(); + } + + return FALSE; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Collision query for vanilla AABB trees. + * \param cache [in/out] an lss cache + * \param lss [in] collision lss in world space + * \param tree [in] AABB tree + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool LSSCollider::Collide(LSSCache& cache, const LSS& lss, const AABBTree* tree) +{ + // This is typically called for a scene tree, full of -AABBs-, not full of triangles. + // So we don't really have "primitives" to deal with. Hence it doesn't work with + // "FirstContact" + "TemporalCoherence". + ASSERT( !(FirstContactEnabled() && TemporalCoherenceEnabled()) ); + + // Checkings + if(!tree) return false; + + // Init collision query + if(InitQuery(cache, lss)) return true; + + // Perform collision query + _Collide(tree); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks the LSS completely contains the box. In which case we can end the query sooner. + * \param bc [in] box center + * \param be [in] box extents + * \return true if the LSS contains the whole box + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL LSSCollider::LSSContainsBox(const Point& bc, const Point& be) +{ + // Not implemented + return FALSE; +} + +#define TEST_BOX_IN_LSS(center, extents) \ + if(LSSContainsBox(center, extents)) \ + { \ + /* Set contact status */ \ + mFlags |= OPC_CONTACT; \ + _Dump(node); \ + return; \ + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for normal AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void LSSCollider::_Collide(const AABBCollisionNode* node) +{ + // Perform LSS-AABB overlap test + if(!LSSAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; + + TEST_BOX_IN_LSS(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->IsLeaf()) + { + LSS_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _Collide(node->GetPos()); + + if(ContactFound()) return; + + _Collide(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for normal AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void LSSCollider::_CollideNoPrimitiveTest(const AABBCollisionNode* node) +{ + // Perform LSS-AABB overlap test + if(!LSSAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; + + TEST_BOX_IN_LSS(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->IsLeaf()) + { + SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + _CollideNoPrimitiveTest(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void LSSCollider::_Collide(const AABBQuantizedNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform LSS-AABB overlap test + if(!LSSAABBOverlap(Center, Extents)) return; + + TEST_BOX_IN_LSS(Center, Extents) + + if(node->IsLeaf()) + { + LSS_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _Collide(node->GetPos()); + + if(ContactFound()) return; + + _Collide(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void LSSCollider::_CollideNoPrimitiveTest(const AABBQuantizedNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform LSS-AABB overlap test + if(!LSSAABBOverlap(Center, Extents)) return; + + TEST_BOX_IN_LSS(Center, Extents) + + if(node->IsLeaf()) + { + SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + _CollideNoPrimitiveTest(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void LSSCollider::_Collide(const AABBNoLeafNode* node) +{ + // Perform LSS-AABB overlap test + if(!LSSAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; + + TEST_BOX_IN_LSS(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->HasPosLeaf()) { LSS_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } + else _Collide(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { LSS_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } + else _Collide(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for no-leaf AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void LSSCollider::_CollideNoPrimitiveTest(const AABBNoLeafNode* node) +{ + // Perform LSS-AABB overlap test + if(!LSSAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; + + TEST_BOX_IN_LSS(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void LSSCollider::_Collide(const AABBQuantizedNoLeafNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform LSS-AABB overlap test + if(!LSSAABBOverlap(Center, Extents)) return; + + TEST_BOX_IN_LSS(Center, Extents) + + if(node->HasPosLeaf()) { LSS_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } + else _Collide(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { LSS_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } + else _Collide(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized no-leaf AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void LSSCollider::_CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform LSS-AABB overlap test + if(!LSSAABBOverlap(Center, Extents)) return; + + TEST_BOX_IN_LSS(Center, Extents) + + if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for vanilla AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void LSSCollider::_Collide(const AABBTreeNode* node) +{ + // Perform LSS-AABB overlap test + Point Center, Extents; + node->GetAABB()->GetCenter(Center); + node->GetAABB()->GetExtents(Extents); + if(!LSSAABBOverlap(Center, Extents)) return; + + if(node->IsLeaf() || LSSContainsBox(Center, Extents)) + { + mFlags |= OPC_CONTACT; + mTouchedPrimitives->Add(node->GetPrimitives(), node->GetNbPrimitives()); + } + else + { + _Collide(node->GetPos()); + _Collide(node->GetNeg()); + } +} + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HybridLSSCollider::HybridLSSCollider() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HybridLSSCollider::~HybridLSSCollider() +{ +} + +bool HybridLSSCollider::Collide(LSSCache& cache, const LSS& lss, const HybridModel& model, const Matrix4x4* worldl, const Matrix4x4* worldm) +{ + // We don't want primitive tests here! + mFlags |= OPC_NO_PRIMITIVE_TESTS; + + // Checkings + if(!Setup(&model)) return false; + + // Init collision query + if(InitQuery(cache, lss, worldl, worldm)) return true; + + // Special case for 1-leaf trees + if(mCurrentModel && mCurrentModel->HasSingleNode()) + { + // Here we're supposed to perform a normal query, except our tree has a single node, i.e. just a few triangles + udword Nb = mIMesh->GetNbTriangles(); + + // Loop through all triangles + for(udword i=0;i<Nb;i++) + { + LSS_PRIM(i, OPC_CONTACT) + } + return true; + } + + // Override destination array since we're only going to get leaf boxes here + mTouchedBoxes.Reset(); + mTouchedPrimitives = &mTouchedBoxes; + + // Now, do the actual query against leaf boxes + if(!model.HasLeafNodes()) + { + if(model.IsQuantized()) + { + const AABBQuantizedNoLeafTree* Tree = static_cast<const AABBQuantizedNoLeafTree *>(model.GetTree()); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + else + { + const AABBNoLeafTree* Tree = static_cast<const AABBNoLeafTree *>(model.GetTree()); + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + } + else + { + if(model.IsQuantized()) + { + const AABBQuantizedTree* Tree = static_cast<const AABBQuantizedTree *>(model.GetTree()); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + else + { + const AABBCollisionTree* Tree = static_cast<const AABBCollisionTree *>(model.GetTree()); + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + } + + // We only have a list of boxes so far + if(GetContactStatus()) + { + // Reset contact status, since it currently only reflects collisions with leaf boxes + Collider::InitQuery(); + + // Change dest container so that we can use built-in overlap tests and get collided primitives + cache.TouchedPrimitives.Reset(); + mTouchedPrimitives = &cache.TouchedPrimitives; + + // Read touched leaf boxes + udword Nb = mTouchedBoxes.GetNbEntries(); + const udword* Touched = mTouchedBoxes.GetEntries(); + + const LeafTriangles* LT = model.GetLeafTriangles(); + const udword* Indices = model.GetIndices(); + + // Loop through touched leaves + while(Nb--) + { + const LeafTriangles& CurrentLeaf = LT[*Touched++]; + + // Each leaf box has a set of triangles + udword NbTris = CurrentLeaf.GetNbTriangles(); + if(Indices) + { + const udword* T = &Indices[CurrentLeaf.GetTriangleIndex()]; + + // Loop through triangles and test each of them + while(NbTris--) + { + udword TriangleIndex = *T++; + LSS_PRIM(TriangleIndex, OPC_CONTACT) + } + } + else + { + udword BaseIndex = CurrentLeaf.GetTriangleIndex(); + + // Loop through triangles and test each of them + while(NbTris--) + { + udword TriangleIndex = BaseIndex++; + LSS_PRIM(TriangleIndex, OPC_CONTACT) + } + } + } + } + + return true; +} diff --git a/libs/ode-0.16.1/OPCODE/OPC_LSSCollider.h b/libs/ode-0.16.1/OPCODE/OPC_LSSCollider.h new file mode 100644 index 0000000..b4d0893 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_LSSCollider.h @@ -0,0 +1,99 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for an LSS collider. + * \file OPC_LSSCollider.h + * \author Pierre Terdiman + * \date December, 28, 2002 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_LSSCOLLIDER_H__ +#define __OPC_LSSCOLLIDER_H__ + + struct OPCODE_API LSSCache : VolumeCache + { + LSSCache() + { + Previous.mP0 = Point(0.0f, 0.0f, 0.0f); + Previous.mP1 = Point(0.0f, 0.0f, 0.0f); + Previous.mRadius = 0.0f; + FatCoeff = 1.1f; + } + + // Cached faces signature + LSS Previous; //!< LSS used when performing the query resulting in cached faces + // User settings + float FatCoeff; //!< mRadius2 multiplier used to create a fat LSS + }; + + class OPCODE_API LSSCollider : public VolumeCollider + { + public: + // Constructor / Destructor + LSSCollider(); + virtual ~LSSCollider(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Generic collision query for generic OPCODE models. After the call, access the results: + * - with GetContactStatus() + * - with GetNbTouchedPrimitives() + * - with GetTouchedPrimitives() + * + * \param cache [in/out] an lss cache + * \param lss [in] collision lss in local space + * \param model [in] Opcode model to collide with + * \param worldl [in] lss world matrix, or null + * \param worldm [in] model's world matrix, or null + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool Collide(LSSCache& cache, const LSS& lss, const Model& model, const Matrix4x4* worldl=null, const Matrix4x4* worldm=null); + // + bool Collide(LSSCache& cache, const LSS& lss, const AABBTree* tree); + protected: + // LSS in model space + Segment mSeg; //!< Segment + float mRadius2; //!< LSS radius squared + // Internal methods + void _Collide(const AABBCollisionNode* node); + void _Collide(const AABBNoLeafNode* node); + void _Collide(const AABBQuantizedNode* node); + void _Collide(const AABBQuantizedNoLeafNode* node); + void _Collide(const AABBTreeNode* node); + void _CollideNoPrimitiveTest(const AABBCollisionNode* node); + void _CollideNoPrimitiveTest(const AABBNoLeafNode* node); + void _CollideNoPrimitiveTest(const AABBQuantizedNode* node); + void _CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node); + // Overlap tests + inline_ BOOL LSSContainsBox(const Point& bc, const Point& be); + inline_ BOOL LSSAABBOverlap(const Point& center, const Point& extents); + inline_ BOOL LSSTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2); + // Init methods + BOOL InitQuery(LSSCache& cache, const LSS& lss, const Matrix4x4* worldl=null, const Matrix4x4* worldm=null); + }; + + class OPCODE_API HybridLSSCollider : public LSSCollider + { + public: + // Constructor / Destructor + HybridLSSCollider(); + virtual ~HybridLSSCollider(); + + bool Collide(LSSCache& cache, const LSS& lss, const HybridModel& model, const Matrix4x4* worldl=null, const Matrix4x4* worldm=null); + protected: + Container mTouchedBoxes; + }; + +#endif // __OPC_LSSCOLLIDER_H__ diff --git a/libs/ode-0.16.1/OPCODE/OPC_LSSTriOverlap.h b/libs/ode-0.16.1/OPCODE/OPC_LSSTriOverlap.h new file mode 100644 index 0000000..f1d17e4 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_LSSTriOverlap.h @@ -0,0 +1,679 @@ +// Following code from Magic-Software (http://www.magic-software.com/) +// A bit modified for Opcode + +static const float gs_fTolerance = 1e-05f; + +static float OPC_PointTriangleSqrDist(const Point& point, const Point& p0, const Point& p1, const Point& p2) +{ + // Hook + Point TriEdge0 = p1 - p0; + Point TriEdge1 = p2 - p0; + + Point kDiff = p0 - point; + float fA00 = TriEdge0.SquareMagnitude(); + float fA01 = TriEdge0 | TriEdge1; + float fA11 = TriEdge1.SquareMagnitude(); + float fB0 = kDiff | TriEdge0; + float fB1 = kDiff | TriEdge1; + float fC = kDiff.SquareMagnitude(); + float fDet = fabsf(fA00*fA11 - fA01*fA01); + float fS = fA01*fB1-fA11*fB0; + float fT = fA01*fB0-fA00*fB1; + float fSqrDist; + + if(fS + fT <= fDet) + { + if(fS < 0.0f) + { + if(fT < 0.0f) // region 4 + { + if(fB0 < 0.0f) + { + if(-fB0 >= fA00) fSqrDist = fA00+2.0f*fB0+fC; + else fSqrDist = fB0*(-fB0/fA00)+fC; + } + else + { + if(fB1 >= 0.0f) fSqrDist = fC; + else if(-fB1 >= fA11) fSqrDist = fA11+2.0f*fB1+fC; + else fSqrDist = fB1*(-fB1/fA11)+fC; + } + } + else // region 3 + { + if(fB1 >= 0.0f) fSqrDist = fC; + else if(-fB1 >= fA11) fSqrDist = fA11+2.0f*fB1+fC; + else fSqrDist = fB1*(-fB1/fA11)+fC; + } + } + else if(fT < 0.0f) // region 5 + { + if(fB0 >= 0.0f) fSqrDist = fC; + else if(-fB0 >= fA00) fSqrDist = fA00+2.0f*fB0+fC; + else fSqrDist = fB0*(-fB0/fA00)+fC; + } + else // region 0 + { + // minimum at interior point + if(fDet==0.0f) + { + fSqrDist = MAX_FLOAT; + } + else + { + float fInvDet = 1.0f/fDet; + fS *= fInvDet; + fT *= fInvDet; + fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) + fT*(fA01*fS+fA11*fT+2.0f*fB1)+fC; + } + } + } + else + { + float fTmp0, fTmp1, fNumer, fDenom; + + if(fS < 0.0f) // region 2 + { + fTmp0 = fA01 + fB0; + fTmp1 = fA11 + fB1; + if(fTmp1 > fTmp0) + { + fNumer = fTmp1 - fTmp0; + fDenom = fA00-2.0f*fA01+fA11; + if(fNumer >= fDenom) + { + fSqrDist = fA00+2.0f*fB0+fC; + } + else + { + fS = fNumer/fDenom; + fT = 1.0f - fS; + fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) + fT*(fA01*fS+fA11*fT+2.0f*fB1)+fC; + } + } + else + { + if(fTmp1 <= 0.0f) fSqrDist = fA11+2.0f*fB1+fC; + else if(fB1 >= 0.0f) fSqrDist = fC; + else fSqrDist = fB1*(-fB1/fA11)+fC; + } + } + else if(fT < 0.0f) // region 6 + { + fTmp0 = fA01 + fB1; + fTmp1 = fA00 + fB0; + if(fTmp1 > fTmp0) + { + fNumer = fTmp1 - fTmp0; + fDenom = fA00-2.0f*fA01+fA11; + if(fNumer >= fDenom) + { + fSqrDist = fA11+2.0f*fB1+fC; + } + else + { + fT = fNumer/fDenom; + fS = 1.0f - fT; + fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) + fT*(fA01*fS+fA11*fT+2.0f*fB1)+fC; + } + } + else + { + if(fTmp1 <= 0.0f) fSqrDist = fA00+2.0f*fB0+fC; + else if(fB0 >= 0.0f) fSqrDist = fC; + else fSqrDist = fB0*(-fB0/fA00)+fC; + } + } + else // region 1 + { + fNumer = fA11 + fB1 - fA01 - fB0; + if(fNumer <= 0.0f) + { + fSqrDist = fA11+2.0f*fB1+fC; + } + else + { + fDenom = fA00-2.0f*fA01+fA11; + if(fNumer >= fDenom) + { + fSqrDist = fA00+2.0f*fB0+fC; + } + else + { + fS = fNumer/fDenom; + fT = 1.0f - fS; + fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) + fT*(fA01*fS+fA11*fT+2.0f*fB1)+fC; + } + } + } + } + return fabsf(fSqrDist); +} + +static float OPC_SegmentSegmentSqrDist(const Segment& rkSeg0, const Segment& rkSeg1) +{ + // Hook + Point rkSeg0Direction = rkSeg0.ComputeDirection(); + Point rkSeg1Direction = rkSeg1.ComputeDirection(); + + Point kDiff = rkSeg0.mP0 - rkSeg1.mP0; + float fA00 = rkSeg0Direction.SquareMagnitude(); + float fA01 = -rkSeg0Direction.Dot(rkSeg1Direction); + float fA11 = rkSeg1Direction.SquareMagnitude(); + float fB0 = kDiff.Dot(rkSeg0Direction); + float fC = kDiff.SquareMagnitude(); + float fDet = fabsf(fA00*fA11-fA01*fA01); + + float fB1, fS, fT, fSqrDist, fTmp; + + if(fDet>=gs_fTolerance) + { + // line segments are not parallel + fB1 = -kDiff.Dot(rkSeg1Direction); + fS = fA01*fB1-fA11*fB0; + fT = fA01*fB0-fA00*fB1; + + if(fS >= 0.0f) + { + if(fS <= fDet) + { + if(fT >= 0.0f) + { + if(fT <= fDet) // region 0 (interior) + { + // minimum at two interior points of 3D lines + float fInvDet = 1.0f/fDet; + fS *= fInvDet; + fT *= fInvDet; + fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) + fT*(fA01*fS+fA11*fT+2.0f*fB1)+fC; + } + else // region 3 (side) + { + fTmp = fA01+fB0; + if(fTmp>=0.0f) fSqrDist = fA11+2.0f*fB1+fC; + else if(-fTmp>=fA00) fSqrDist = fA00+fA11+fC+2.0f*(fB1+fTmp); + else fSqrDist = fTmp*(-fTmp/fA00)+fA11+2.0f*fB1+fC; + } + } + else // region 7 (side) + { + if(fB0>=0.0f) fSqrDist = fC; + else if(-fB0>=fA00) fSqrDist = fA00+2.0f*fB0+fC; + else fSqrDist = fB0*(-fB0/fA00)+fC; + } + } + else + { + if ( fT >= 0.0 ) + { + if ( fT <= fDet ) // region 1 (side) + { + fTmp = fA01+fB1; + if(fTmp>=0.0f) fSqrDist = fA00+2.0f*fB0+fC; + else if(-fTmp>=fA11) fSqrDist = fA00+fA11+fC+2.0f*(fB0+fTmp); + else fSqrDist = fTmp*(-fTmp/fA11)+fA00+2.0f*fB0+fC; + } + else // region 2 (corner) + { + fTmp = fA01+fB0; + if ( -fTmp <= fA00 ) + { + if(fTmp>=0.0f) fSqrDist = fA11+2.0f*fB1+fC; + else fSqrDist = fTmp*(-fTmp/fA00)+fA11+2.0f*fB1+fC; + } + else + { + fTmp = fA01+fB1; + if(fTmp>=0.0f) fSqrDist = fA00+2.0f*fB0+fC; + else if(-fTmp>=fA11) fSqrDist = fA00+fA11+fC+2.0f*(fB0+fTmp); + else fSqrDist = fTmp*(-fTmp/fA11)+fA00+2.0f*fB0+fC; + } + } + } + else // region 8 (corner) + { + if ( -fB0 < fA00 ) + { + if(fB0>=0.0f) fSqrDist = fC; + else fSqrDist = fB0*(-fB0/fA00)+fC; + } + else + { + fTmp = fA01+fB1; + if(fTmp>=0.0f) fSqrDist = fA00+2.0f*fB0+fC; + else if(-fTmp>=fA11) fSqrDist = fA00+fA11+fC+2.0f*(fB0+fTmp); + else fSqrDist = fTmp*(-fTmp/fA11)+fA00+2.0f*fB0+fC; + } + } + } + } + else + { + if ( fT >= 0.0f ) + { + if ( fT <= fDet ) // region 5 (side) + { + if(fB1>=0.0f) fSqrDist = fC; + else if(-fB1>=fA11) fSqrDist = fA11+2.0f*fB1+fC; + else fSqrDist = fB1*(-fB1/fA11)+fC; + } + else // region 4 (corner) + { + fTmp = fA01+fB0; + if ( fTmp < 0.0f ) + { + if(-fTmp>=fA00) fSqrDist = fA00+fA11+fC+2.0f*(fB1+fTmp); + else fSqrDist = fTmp*(-fTmp/fA00)+fA11+2.0f*fB1+fC; + } + else + { + if(fB1>=0.0f) fSqrDist = fC; + else if(-fB1>=fA11) fSqrDist = fA11+2.0f*fB1+fC; + else fSqrDist = fB1*(-fB1/fA11)+fC; + } + } + } + else // region 6 (corner) + { + if ( fB0 < 0.0f ) + { + if(-fB0>=fA00) fSqrDist = fA00+2.0f*fB0+fC; + else fSqrDist = fB0*(-fB0/fA00)+fC; + } + else + { + if(fB1>=0.0f) fSqrDist = fC; + else if(-fB1>=fA11) fSqrDist = fA11+2.0f*fB1+fC; + else fSqrDist = fB1*(-fB1/fA11)+fC; + } + } + } + } + else + { + // line segments are parallel + if ( fA01 > 0.0f ) + { + // direction vectors form an obtuse angle + if ( fB0 >= 0.0f ) + { + fSqrDist = fC; + } + else if ( -fB0 <= fA00 ) + { + fSqrDist = fB0*(-fB0/fA00)+fC; + } + else + { + fB1 = -kDiff.Dot(rkSeg1Direction); + fTmp = fA00+fB0; + if ( -fTmp >= fA01 ) + { + fSqrDist = fA00+fA11+fC+2.0f*(fA01+fB0+fB1); + } + else + { + fT = -fTmp/fA01; + fSqrDist = fA00+2.0f*fB0+fC+fT*(fA11*fT+2.0f*(fA01+fB1)); + } + } + } + else + { + // direction vectors form an acute angle + if ( -fB0 >= fA00 ) + { + fSqrDist = fA00+2.0f*fB0+fC; + } + else if ( fB0 <= 0.0f ) + { + fSqrDist = fB0*(-fB0/fA00)+fC; + } + else + { + fB1 = -kDiff.Dot(rkSeg1Direction); + if ( fB0 >= -fA01 ) + { + fSqrDist = fA11+2.0f*fB1+fC; + } + else + { + fT = -fB0/fA01; + fSqrDist = fC+fT*(2.0f*fB1+fA11*fT); + } + } + } + } + return fabsf(fSqrDist); +} + +inline_ float OPC_SegmentRaySqrDist(const Segment& rkSeg0, const Ray& rkSeg1) +{ + return OPC_SegmentSegmentSqrDist(rkSeg0, Segment(rkSeg1.mOrig, rkSeg1.mOrig + rkSeg1.mDir)); +} + +static float OPC_SegmentTriangleSqrDist(const Segment& segment, const Point& p0, const Point& p1, const Point& p2) +{ + // Hook + const Point TriEdge0 = p1 - p0; + const Point TriEdge1 = p2 - p0; + + const Point& rkSegOrigin = segment.GetOrigin(); + Point rkSegDirection = segment.ComputeDirection(); + + Point kDiff = p0 - rkSegOrigin; + float fA00 = rkSegDirection.SquareMagnitude(); + float fA01 = -rkSegDirection.Dot(TriEdge0); + float fA02 = -rkSegDirection.Dot(TriEdge1); + float fA11 = TriEdge0.SquareMagnitude(); + float fA12 = TriEdge0.Dot(TriEdge1); + float fA22 = TriEdge1.Dot(TriEdge1); + float fB0 = -kDiff.Dot(rkSegDirection); + float fB1 = kDiff.Dot(TriEdge0); + float fB2 = kDiff.Dot(TriEdge1); + float fCof00 = fA11*fA22-fA12*fA12; + float fCof01 = fA02*fA12-fA01*fA22; + float fCof02 = fA01*fA12-fA02*fA11; + float fDet = fA00*fCof00+fA01*fCof01+fA02*fCof02; + + Ray kTriSeg; + Point kPt; + float fSqrDist, fSqrDist0; + + if(fabsf(fDet)>=gs_fTolerance) + { + float fCof11 = fA00*fA22-fA02*fA02; + float fCof12 = fA02*fA01-fA00*fA12; + float fCof22 = fA00*fA11-fA01*fA01; + float fInvDet = 1.0f/fDet; + float fRhs0 = -fB0*fInvDet; + float fRhs1 = -fB1*fInvDet; + float fRhs2 = -fB2*fInvDet; + + float fR = fCof00*fRhs0+fCof01*fRhs1+fCof02*fRhs2; + float fS = fCof01*fRhs0+fCof11*fRhs1+fCof12*fRhs2; + float fT = fCof02*fRhs0+fCof12*fRhs1+fCof22*fRhs2; + + if ( fR < 0.0f ) + { + if ( fS+fT <= 1.0f ) + { + if ( fS < 0.0f ) + { + if ( fT < 0.0f ) // region 4m + { + // min on face s=0 or t=0 or r=0 + kTriSeg.mOrig = p0; + kTriSeg.mDir = TriEdge1; + fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); + kTriSeg.mOrig = p0; + kTriSeg.mDir = TriEdge0; + fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg); + if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; + fSqrDist0 = OPC_PointTriangleSqrDist(rkSegOrigin, p0, p1, p2); + if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; + } + else // region 3m + { + // min on face s=0 or r=0 + kTriSeg.mOrig = p0; + kTriSeg.mDir = TriEdge1; + fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); + fSqrDist0 = OPC_PointTriangleSqrDist(rkSegOrigin, p0, p1, p2); + if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; + } + } + else if ( fT < 0.0f ) // region 5m + { + // min on face t=0 or r=0 + kTriSeg.mOrig = p0; + kTriSeg.mDir = TriEdge0; + fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); + fSqrDist0 = OPC_PointTriangleSqrDist(rkSegOrigin, p0, p1, p2); + if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; + } + else // region 0m + { + // min on face r=0 + fSqrDist = OPC_PointTriangleSqrDist(rkSegOrigin, p0, p1, p2); + } + } + else + { + if ( fS < 0.0f ) // region 2m + { + // min on face s=0 or s+t=1 or r=0 + kTriSeg.mOrig = p0; + kTriSeg.mDir = TriEdge1; + fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); + kTriSeg.mOrig = p1; + kTriSeg.mDir = TriEdge1-TriEdge0; + fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg); + if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; + fSqrDist0 = OPC_PointTriangleSqrDist(rkSegOrigin, p0, p1, p2); + if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; + } + else if ( fT < 0.0f ) // region 6m + { + // min on face t=0 or s+t=1 or r=0 + kTriSeg.mOrig = p0; + kTriSeg.mDir = TriEdge0; + fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); + kTriSeg.mOrig = p1; + kTriSeg.mDir = TriEdge1-TriEdge0; + fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg); + if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; + fSqrDist0 = OPC_PointTriangleSqrDist(rkSegOrigin, p0, p1, p2); + if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; + } + else // region 1m + { + // min on face s+t=1 or r=0 + kTriSeg.mOrig = p1; + kTriSeg.mDir = TriEdge1-TriEdge0; + fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); + fSqrDist0 = OPC_PointTriangleSqrDist(rkSegOrigin, p0, p1, p2); + if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; + } + } + } + else if ( fR <= 1.0f ) + { + if ( fS+fT <= 1.0f ) + { + if ( fS < 0.0f ) + { + if ( fT < 0.0f ) // region 4 + { + // min on face s=0 or t=0 + kTriSeg.mOrig = p0; + kTriSeg.mDir = TriEdge1; + fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); + kTriSeg.mOrig = p0; + kTriSeg.mDir = TriEdge0; + fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg); + if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; + } + else // region 3 + { + // min on face s=0 + kTriSeg.mOrig = p0; + kTriSeg.mDir = TriEdge1; + fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); + } + } + else if ( fT < 0.0f ) // region 5 + { + // min on face t=0 + kTriSeg.mOrig = p0; + kTriSeg.mDir = TriEdge0; + fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); + } + else // region 0 + { + // global minimum is interior, done + fSqrDist = fR*(fA00*fR+fA01*fS+fA02*fT+2.0f*fB0) + +fS*(fA01*fR+fA11*fS+fA12*fT+2.0f*fB1) + +fT*(fA02*fR+fA12*fS+fA22*fT+2.0f*fB2) + +kDiff.SquareMagnitude(); + } + } + else + { + if ( fS < 0.0f ) // region 2 + { + // min on face s=0 or s+t=1 + kTriSeg.mOrig = p0; + kTriSeg.mDir = TriEdge1; + fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); + kTriSeg.mOrig = p1; + kTriSeg.mDir = TriEdge1-TriEdge0; + fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg); + if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; + } + else if ( fT < 0.0f ) // region 6 + { + // min on face t=0 or s+t=1 + kTriSeg.mOrig = p0; + kTriSeg.mDir = TriEdge0; + fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); + kTriSeg.mOrig = p1; + kTriSeg.mDir = TriEdge1-TriEdge0; + fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg); + if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; + } + else // region 1 + { + // min on face s+t=1 + kTriSeg.mOrig = p1; + kTriSeg.mDir = TriEdge1-TriEdge0; + fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); + } + } + } + else // fR > 1 + { + if ( fS+fT <= 1.0f ) + { + if ( fS < 0.0f ) + { + if ( fT < 0.0f ) // region 4p + { + // min on face s=0 or t=0 or r=1 + kTriSeg.mOrig = p0; + kTriSeg.mDir = TriEdge1; + fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); + kTriSeg.mOrig = p0; + kTriSeg.mDir = TriEdge0; + fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg); + if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; + kPt = rkSegOrigin+rkSegDirection; + fSqrDist0 = OPC_PointTriangleSqrDist(kPt, p0, p1, p2); + if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; + } + else // region 3p + { + // min on face s=0 or r=1 + kTriSeg.mOrig = p0; + kTriSeg.mDir = TriEdge1; + fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); + kPt = rkSegOrigin+rkSegDirection; + fSqrDist0 = OPC_PointTriangleSqrDist(kPt, p0, p1, p2); + if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; + } + } + else if ( fT < 0.0f ) // region 5p + { + // min on face t=0 or r=1 + kTriSeg.mOrig = p0; + kTriSeg.mDir = TriEdge0; + fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); + kPt = rkSegOrigin+rkSegDirection; + fSqrDist0 = OPC_PointTriangleSqrDist(kPt, p0, p1, p2); + if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; + } + else // region 0p + { + // min face on r=1 + kPt = rkSegOrigin+rkSegDirection; + fSqrDist = OPC_PointTriangleSqrDist(kPt, p0, p1, p2); + } + } + else + { + if ( fS < 0.0f ) // region 2p + { + // min on face s=0 or s+t=1 or r=1 + kTriSeg.mOrig = p0; + kTriSeg.mDir = TriEdge1; + fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); + kTriSeg.mOrig = p1; + kTriSeg.mDir = TriEdge1-TriEdge0; + fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg); + if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; + kPt = rkSegOrigin+rkSegDirection; + fSqrDist0 = OPC_PointTriangleSqrDist(kPt, p0, p1, p2); + if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; + } + else if ( fT < 0.0f ) // region 6p + { + // min on face t=0 or s+t=1 or r=1 + kTriSeg.mOrig = p0; + kTriSeg.mDir = TriEdge0; + fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); + kTriSeg.mOrig = p1; + kTriSeg.mDir = TriEdge1-TriEdge0; + fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg); + if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; + kPt = rkSegOrigin+rkSegDirection; + fSqrDist0 = OPC_PointTriangleSqrDist(kPt, p0, p1, p2); + if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; + } + else // region 1p + { + // min on face s+t=1 or r=1 + kTriSeg.mOrig = p1; + kTriSeg.mDir = TriEdge1-TriEdge0; + fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); + kPt = rkSegOrigin+rkSegDirection; + fSqrDist0 = OPC_PointTriangleSqrDist(kPt, p0, p1, p2); + if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; + } + } + } + } + else + { + // segment and triangle are parallel + kTriSeg.mOrig = p0; + kTriSeg.mDir = TriEdge0; + fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); + + kTriSeg.mDir = TriEdge1; + fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg); + if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; + + kTriSeg.mOrig = p1; + kTriSeg.mDir = TriEdge1 - TriEdge0; + fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg); + if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; + + fSqrDist0 = OPC_PointTriangleSqrDist(rkSegOrigin, p0, p1, p2); + if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; + + kPt = rkSegOrigin+rkSegDirection; + fSqrDist0 = OPC_PointTriangleSqrDist(kPt, p0, p1, p2); + if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; + } + return fabsf(fSqrDist); +} + +inline_ BOOL LSSCollider::LSSTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2) +{ + // Stats + mNbVolumePrimTests++; + + float s2 = OPC_SegmentTriangleSqrDist(mSeg, vert0, vert1, vert2); + if(s2<mRadius2) return TRUE; + return FALSE; +} diff --git a/libs/ode-0.16.1/OPCODE/OPC_MeshInterface.cpp b/libs/ode-0.16.1/OPCODE/OPC_MeshInterface.cpp new file mode 100644 index 0000000..157464e --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_MeshInterface.cpp @@ -0,0 +1,393 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a mesh interface. + * \file OPC_MeshInterface.cpp + * \author Pierre Terdiman + * \date November, 27, 2002 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * This structure holds 3 vertex-pointers. It's mainly used by collision callbacks so that the app doesn't have + * to return 3 vertices to OPCODE (36 bytes) but only 3 pointers (12 bytes). It seems better but I never profiled + * the alternative. + * + * \class VertexPointers + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * This class is an interface between us and user-defined meshes. Meshes can be defined in a lot of ways, and here we + * try to support most of them. + * + * Basically you have two options: + * - callbacks, if OPC_USE_CALLBACKS is defined in OPC_Settings.h. + * - else pointers. + * + * If using pointers, you can also use strides or not. Strides are used when OPC_USE_STRIDE is defined. + * + * + * CALLBACKS: + * + * Using callbacks is the most generic way to feed OPCODE with your meshes. Indeed, you just have to give + * access to three vertices at the end of the day. It's up to you to fetch them from your database, using + * whatever method you want. Hence your meshes can lie in system memory or AGP, be indexed or not, use 16 + * or 32-bits indices, you can decompress them on-the-fly if needed, etc. On the other hand, a callback is + * called each time OPCODE needs access to a particular triangle, so there might be a slight overhead. + * + * To make things clear: geometry & topology are NOT stored in the collision system, + * in order to save some ram. So, when the system needs them to perform accurate intersection + * tests, you're requested to provide the triangle-vertices corresponding to a given face index. + * + * Ex: + * + * \code + * static void ColCallback(udword triangle_index, VertexPointers& triangle, udword user_data) + * { + * // Get back Mesh0 or Mesh1 (you also can use 2 different callbacks) + * Mesh* MyMesh = (Mesh*)user_data; + * // Get correct triangle in the app-controlled database + * const Triangle* Tri = MyMesh->GetTriangle(triangle_index); + * // Setup pointers to vertices for the collision system + * triangle.Vertex[0] = MyMesh->GetVertex(Tri->mVRef[0]); + * triangle.Vertex[1] = MyMesh->GetVertex(Tri->mVRef[1]); + * triangle.Vertex[2] = MyMesh->GetVertex(Tri->mVRef[2]); + * } + * + * // Setup callbacks + * MeshInterface0->SetCallback(ColCallback, udword(Mesh0)); + * MeshInterface1->SetCallback(ColCallback, udword(Mesh1)); + * \endcode + * + * Of course, you should make this callback as fast as possible. And you're also not supposed + * to modify the geometry *after* the collision trees have been built. The alternative was to + * store the geometry & topology in the collision system as well (as in RAPID) but we have found + * this approach to waste a lot of ram in many cases. + * + * + * POINTERS: + * + * If you're internally using the following canonical structures: + * - a vertex made of three 32-bits floating point values + * - a triangle made of three 32-bits integer vertex references + * ...then you may want to use pointers instead of callbacks. This is the same, except OPCODE will directly + * use provided pointers to access the topology and geometry, without using a callback. It might be faster, + * but probably not as safe. Pointers have been introduced in OPCODE 1.2. + * + * Ex: + * + * \code + * // Setup pointers + * MeshInterface0->SetPointers(Mesh0->GetFaces(), Mesh0->GetVerts()); + * MeshInterface1->SetPointers(Mesh1->GetFaces(), Mesh1->GetVerts()); + * \endcode + * + * + * STRIDES: + * + * If your vertices are D3D-like entities interleaving a position, a normal and/or texture coordinates + * (i.e. if your vertices are FVFs), you might want to use a vertex stride to skip extra data OPCODE + * doesn't need. Using a stride shouldn't be notably slower than not using it, but it might increase + * cache misses. Please also note that you *shouldn't* read from AGP or video-memory buffers ! + * + * + * In any case, compilation flags are here to select callbacks/pointers/strides at compile time, so + * choose what's best for your application. All of this has been wrapped into this MeshInterface. + * + * \class MeshInterface + * \author Pierre Terdiman + * \version 1.3 + * \date November, 27, 2002 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +MeshInterface::MeshInterface() : + mNbTris (0), + mNbVerts (0), +#ifdef OPC_USE_CALLBACKS + mUserData (null), + mObjCallback (null), + mExUserData (null), + mObjExCallback (null), +#else + #ifdef OPC_USE_STRIDE + mTriStride (sizeof(IndexedTriangle)), + mVertexStride (sizeof(Point)), + mFetchTriangle (&MeshInterface::FetchTriangleFromSingles), + mFetchExTriangle (&MeshInterface::FetchExTriangleFromSingles), + #endif + mTris (null), + mVerts (null) +#endif +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +MeshInterface::~MeshInterface() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks the mesh interface is valid, i.e. things have been setup correctly. + * \return true if valid + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool MeshInterface::IsValid() const +{ + if(!mNbTris || !mNbVerts) return false; +#ifdef OPC_USE_CALLBACKS + if(!mObjCallback) return false; +#else + if(!mTris || !mVerts) return false; +#endif + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks the mesh itself is valid. + * Currently we only look for degenerate faces. + * \return number of degenerate faces + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +udword MeshInterface::CheckTopology() const +{ + // Check topology. If the model contains degenerate faces, collision report can be wrong in some cases. + // e.g. it happens with the standard MAX teapot. So clean your meshes first... If you don't have a mesh cleaner + // you can try this: www.codercorner.com/Consolidation.zip + + udword NbDegenerate = 0; + + VertexPointers VP; + ConversionArea VC; + + // Using callbacks, we don't have access to vertex indices. Nevertheless we still can check for + // redundant vertex pointers, which cover all possibilities (callbacks/pointers/strides). + for(udword i=0;i<mNbTris;i++) + { + GetTriangle(VP, i, VC); + + if( (VP.Vertex[0]==VP.Vertex[1]) + || (VP.Vertex[1]==VP.Vertex[2]) + || (VP.Vertex[2]==VP.Vertex[0])) NbDegenerate++; + } + + return NbDegenerate; +} + +#ifdef OPC_USE_CALLBACKS +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Callback control: setups object callback. Must provide triangle-vertices for a given triangle index. + * \param callback [in] user-defined callback + * \param user_data [in] user-defined data + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool MeshInterface::SetCallback(RequestCallback callback, void* user_data) +{ + if(!callback) return SetIceError("MeshInterface::SetCallback: callback pointer is null"); + + mObjCallback = callback; + mUserData = user_data; + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** +* Callback control: setups object ex-callback. Must provide triangle-vertices and vertex indice for a given triangle index. +* \param callback [in] user-defined callback +* \param user_data [in] user-defined data +* \return true if success +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool MeshInterface::SetExCallback(RequestExCallback callback, void* user_data) +{ +// if(!callback) -- allow nulls + + mObjExCallback = callback; + mExUserData = user_data; + return true; +} +#else +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Pointers control: setups object pointers. Must provide access to faces and vertices for a given object. + * \param tris [in] pointer to triangles + * \param verts [in] pointer to vertices + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool MeshInterface::SetPointers(const IndexedTriangle* tris, const Point* verts) +{ + if(!tris || !verts) return SetIceError("MeshInterface::SetPointers: pointer is null", null); + + mTris = tris; + mVerts = verts; + return true; +} +#ifdef OPC_USE_STRIDE +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Strides control + * \param tri_stride [in] size of a triangle in bytes. The first sizeof(IndexedTriangle) bytes are used to get vertex indices. + * \param vertex_stride [in] size of a vertex in bytes. The first sizeof(Point) bytes are used to get vertex position. + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool MeshInterface::SetStrides(udword tri_stride, udword vertex_stride) +{ + if(tri_stride<sizeof(IndexedTriangle)) return SetIceError("MeshInterface::SetStrides: invalid triangle stride", null); + if(vertex_stride<sizeof(Point)) return SetIceError("MeshInterface::SetStrides: invalid vertex stride", null); + + mTriStride = tri_stride; + mVertexStride = vertex_stride; + return true; +} +#endif +#endif + +#ifndef OPC_USE_CALLBACKS +#ifdef OPC_USE_STRIDE +void MeshInterface::FetchTriangleFromSingles(VertexPointers& vp, udword index, ConversionArea vc) const +{ + const IndexedTriangle* T = (const IndexedTriangle*)(((ubyte*)mTris) + index * mTriStride); + + const Point* Verts = GetVerts(); + udword VertexStride = GetVertexStride(); + vp.Vertex[0] = (const Point*)(((ubyte*)Verts) + T->mVRef[0] * VertexStride); + vp.Vertex[1] = (const Point*)(((ubyte*)Verts) + T->mVRef[1] * VertexStride); + vp.Vertex[2] = (const Point*)(((ubyte*)Verts) + T->mVRef[2] * VertexStride); +} + +void MeshInterface::FetchTriangleFromDoubles(VertexPointers& vp, udword index, ConversionArea vc) const +{ + const IndexedTriangle* T = (const IndexedTriangle*)(((ubyte*)mTris) + index * mTriStride); + + const Point* Verts = GetVerts(); + udword VertexStride = GetVertexStride(); + + for (int i = 0; i < 3; i++){ + const double* v = (const double*)(((ubyte*)Verts) + T->mVRef[i] * VertexStride); + + vc[i].x = (float)v[0]; + vc[i].y = (float)v[1]; + vc[i].z = (float)v[2]; + vp.Vertex[i] = &vc[i]; + } +} + +void MeshInterface::FetchExTriangleFromSingles(VertexPointersEx& vpe, udword index, ConversionArea vc) const +{ + const IndexedTriangle* T = (const IndexedTriangle*)(((ubyte*)mTris) + index * mTriStride); + + const Point* Verts = GetVerts(); + udword VertexStride = GetVertexStride(); + + dTriIndex VertIndex0 = T->mVRef[0]; + vpe.Index[0] = VertIndex0; + vpe.vp.Vertex[0] = (const Point*)(((ubyte*)Verts) + VertIndex0 * VertexStride); + + dTriIndex VertIndex1 = T->mVRef[1]; + vpe.Index[1] = VertIndex1; + vpe.vp.Vertex[1] = (const Point*)(((ubyte*)Verts) + VertIndex1 * VertexStride); + + dTriIndex VertIndex2 = T->mVRef[2]; + vpe.Index[2] = VertIndex2; + vpe.vp.Vertex[2] = (const Point*)(((ubyte*)Verts) + VertIndex2 * VertexStride); +} + +void MeshInterface::FetchExTriangleFromDoubles(VertexPointersEx& vpe, udword index, ConversionArea vc) const +{ + const IndexedTriangle* T = (const IndexedTriangle*)(((ubyte*)mTris) + index * mTriStride); + + const Point* Verts = GetVerts(); + udword VertexStride = GetVertexStride(); + + for (int i = 0; i < 3; i++){ + dTriIndex VertIndex = T->mVRef[i]; + vpe.Index[i] = VertIndex; + + const double* v = (const double*)(((ubyte*)Verts) + VertIndex * VertexStride); + vc[i].x = (float)v[0]; + vc[i].y = (float)v[1]; + vc[i].z = (float)v[2]; + vpe.vp.Vertex[i] = &vc[i]; + } +} +#endif +#endif + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Remaps client's mesh according to a permutation. + * \param nb_indices [in] number of indices in the permutation (will be checked against number of triangles) + * \param permutation [in] list of triangle indices + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool MeshInterface::RemapClient(udword nb_indices, const dTriIndex* permutation) const +{ + // Checkings + if(!nb_indices || !permutation) return false; + if(nb_indices!=mNbTris) return false; + +#ifdef OPC_USE_CALLBACKS + // We can't really do that using callbacks + return false; +#else + IndexedTriangle* Tmp = new IndexedTriangle[mNbTris]; + CHECKALLOC(Tmp); + + #ifdef OPC_USE_STRIDE + udword Stride = mTriStride; + #else + udword Stride = sizeof(IndexedTriangle); + #endif + + for(udword i=0;i<mNbTris;i++) + { + const IndexedTriangle* T = (const IndexedTriangle*)(((ubyte*)mTris) + i * Stride); + Tmp[i] = *T; + } + + for(udword i=0;i<mNbTris;i++) + { + IndexedTriangle* T = (IndexedTriangle*)(((ubyte*)mTris) + i * Stride); + *T = Tmp[permutation[i]]; + } + + DELETEARRAY(Tmp); +#endif + return true; +} diff --git a/libs/ode-0.16.1/OPCODE/OPC_MeshInterface.h b/libs/ode-0.16.1/OPCODE/OPC_MeshInterface.h new file mode 100644 index 0000000..c404948 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_MeshInterface.h @@ -0,0 +1,280 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a mesh interface. + * \file OPC_MeshInterface.h + * \author Pierre Terdiman + * \date November, 27, 2002 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_MESHINTERFACE_H__ +#define __OPC_MESHINTERFACE_H__ + + struct VertexPointers + { + const Point* Vertex[3]; + + bool BackfaceCulling(const Point& source) + { + const Point& p0 = *Vertex[0]; + const Point& p1 = *Vertex[1]; + const Point& p2 = *Vertex[2]; + + // Compute normal direction + Point Normal = (p2 - p1)^(p0 - p1); + + // Backface culling + return (Normal | (source - p0)) >= 0.0f; + } + }; + + struct VertexPointersEx + { + VertexPointers vp; + dTriIndex Index[3]; + }; + + typedef Point ConversionArea[3]; + +#ifdef OPC_USE_CALLBACKS + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * User-callback, called by OPCODE to request vertices from the app. + * \param triangle_index [in] face index for which the system is requesting the vertices + * \param triangle [out] triangle's vertices (must be provided by the user) + * \param user_data [in] user-defined data from SetCallback() + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + typedef void (*RequestCallback) (udword triangle_index, VertexPointers& triangle, void* user_data); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * User-callback, called by OPCODE to request vertex indices from the app. + * \param triangle_index [in] face index for which the system is requesting the vertices + * \param triangle [out] triangle's vertices with indices (must be provided by the user) + * \param user_data [in] user-defined data from SetExCallback() + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + typedef void (*RequestExCallback) (udword triangle_index, VertexPointersEx& triangle, void* user_data); +#endif + + class OPCODE_API MeshInterface + { + public: + // Constructor / Destructor + MeshInterface(); + ~MeshInterface(); + // Common settings + inline_ udword GetNbTriangles() const { return mNbTris; } + inline_ udword GetNbVertices() const { return mNbVerts; } + inline_ void SetNbTriangles(udword nb) { mNbTris = nb; } + inline_ void SetNbVertices(udword nb) { mNbVerts = nb; } + +#ifdef OPC_USE_CALLBACKS + // Callback settings + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Callback control: setups object callback. Must provide triangle-vertices for a given triangle index. + * \param callback [in] user-defined callback + * \param user_data [in] user-defined data + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool SetCallback(RequestCallback callback, void* user_data); + inline_ void* GetUserData() const { return mUserData; } + inline_ RequestCallback GetCallback() const { return mObjCallback; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Callback control: setups object callback. Must provide triangle-vertices for a given triangle index. + * \param callback [in] user-defined callback + * \param user_data [in] user-defined data + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool SetExCallback(RequestExCallback callback, void* user_data); + inline_ void* GetExUserData() const { return mExUserData; } + inline_ RequestExCallback GetExCallback() const { return mObjExCallback; } +#else + // Pointers settings + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Pointers control: setups object pointers. Must provide access to faces and vertices for a given object. + * \param tris [in] pointer to triangles + * \param verts [in] pointer to vertices + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool SetPointers(const IndexedTriangle* tris, const Point* verts); + inline_ const IndexedTriangle* GetTris() const { return mTris; } + inline_ const Point* GetVerts() const { return mVerts; } + + #ifdef OPC_USE_STRIDE + // Strides settings + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Strides control + * \param tri_stride [in] size of a triangle in bytes. The first sizeof(IndexedTriangle) bytes are used to get vertex indices. + * \param vertex_stride [in] size of a vertex in bytes. The first sizeof(Point) bytes are used to get vertex position. + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool SetStrides(udword tri_stride=sizeof(IndexedTriangle), udword vertex_stride=sizeof(Point)); + inline_ udword GetTriStride() const { return mTriStride; } + inline_ udword GetVertexStride() const { return mVertexStride; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Single/Double control + * \param value [in] Indicates if mesh data is provided as array of \c single values. If \c false, data is expected to contain \c double elements. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetSingle(bool value) + { + mFetchTriangle = (value ? &MeshInterface::FetchTriangleFromSingles : &MeshInterface::FetchTriangleFromDoubles); + mFetchExTriangle = (value ? &MeshInterface::FetchExTriangleFromSingles : &MeshInterface::FetchExTriangleFromDoubles); + } + + #else + inline_ bool SetStrides(udword tri_stride=sizeof(IndexedTriangle), udword vertex_stride=sizeof(Point)) { return true; } + inline_ void SetSingle(bool value) {} + inline_ udword GetTriStride() const { return sizeof(IndexedTriangle); } + inline_ udword GetVertexStride() const { return sizeof(Point); } + #endif +#endif + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Fetches a triangle given a triangle index. + * \param vp [out] required triangle's vertex pointers + * \param index [in] triangle index + * \param vc [in,out] storage required for data conversion (pass local variable with same scope as \a vp, as \a vp may point to this memory on return) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void GetTriangle(VertexPointers& vp, udword index, ConversionArea vc) const + { +#ifdef OPC_USE_CALLBACKS + (mObjCallback)(index, vp, mUserData); +#else + #ifdef OPC_USE_STRIDE + // Since there was conditional statement "if (Single)" which was unpredictable for compiler + // and required both branches to be always generated what made inlining a questionable + // benefit, I consider it better to introduce a forced call + // but get rig of branching and dead code injection. + ((*this).*mFetchTriangle)(vp, index, vc); + #else + const Point* Verts = GetVerts(); + const IndexedTriangle* T = &mTris[index]; + vp.Vertex[0] = &Verts[T->mVRef[0]]; + vp.Vertex[1] = &Verts[T->mVRef[1]]; + vp.Vertex[2] = &Verts[T->mVRef[2]]; + #endif +#endif + } + + inline_ bool GetExTriangle(VertexPointersEx& vpe, udword index, ConversionArea vc) const + { +#ifdef OPC_USE_CALLBACKS + if (mObjExCallback) { (mObjExCallback)(index, vpe, mUserData); return true; } + else { (mObjCallback)(index, vpe.vp, mUserData); return false; } +#else + #ifdef OPC_USE_STRIDE + // Since there was conditional statement "if (Single)" which was unpredictable for compiler + // and required both branches to be always generated what made inlining a questionable + // benefit, I consider it better to introduce a forced call + // but get rig of branching and dead code injection. + ((*this).*mFetchExTriangle)(vpe, index, vc); + return true; + #else + const Point* Verts = GetVerts(); + const IndexedTriangle* T = &mTris[index]; + dTriIndex VertIndex0 = T->mVRef[0]; + vpe.Index[0] = VertIndex0; + vpe.vp.Vertex[0] = &Verts[VertIndex0]; + dTriIndex VertIndex1 = T->mVRef[1]; + vpe.Index[1] = VertIndex1; + vpe.vp.Vertex[1] = &Verts[VertIndex1]; + dTriIndex VertIndex2 = T->mVRef[2]; + vpe.Index[2] = VertIndex2; + vpe.vp.Vertex[2] = &Verts[VertIndex2]; + return true; + #endif +#endif + } + + private: +#ifndef OPC_USE_CALLBACKS + #ifdef OPC_USE_STRIDE + void FetchTriangleFromSingles(VertexPointers& vp, udword index, ConversionArea vc) const; + void FetchTriangleFromDoubles(VertexPointers& vp, udword index, ConversionArea vc) const; + void FetchExTriangleFromSingles(VertexPointersEx& vpe, udword index, ConversionArea vc) const; + void FetchExTriangleFromDoubles(VertexPointersEx& vpe, udword index, ConversionArea vc) const; + #endif +#endif + + public: + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Remaps client's mesh according to a permutation. + * \param nb_indices [in] number of indices in the permutation (will be checked against number of triangles) + * \param permutation [in] list of triangle indices + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool RemapClient(udword nb_indices, const dTriIndex* permutation) const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks the mesh interface is valid, i.e. things have been setup correctly. + * \return true if valid + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool IsValid() const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks the mesh itself is valid. + * Currently we only look for degenerate faces. + * \return number of degenerate faces + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + udword CheckTopology() const; + private: + + udword mNbTris; //!< Number of triangles in the input model + udword mNbVerts; //!< Number of vertices in the input model +#ifdef OPC_USE_CALLBACKS + // User callback + void* mUserData; //!< User-defined data sent to callback + RequestCallback mObjCallback; //!< Object callback + void* mExUserData; //!< User-defined data sent to ex-callback + RequestExCallback mObjExCallback; //!< Object ex-callback +#else + // User pointers + #ifdef OPC_USE_STRIDE + udword mTriStride; //!< Possible triangle stride in bytes [Opcode 1.3] + udword mVertexStride; //!< Possible vertex stride in bytes [Opcode 1.3] + typedef void (MeshInterface:: *TriangleFetchProc)(VertexPointers& vp, udword index, ConversionArea vc) const; + TriangleFetchProc mFetchTriangle; + typedef void (MeshInterface:: *ExTriangleFetchProc)(VertexPointersEx& vpe, udword index, ConversionArea vc) const; + ExTriangleFetchProc mFetchExTriangle; + #endif + const IndexedTriangle* mTris; //!< Array of indexed triangles + const Point* mVerts; //!< Array of vertices +#endif + }; + +#endif //__OPC_MESHINTERFACE_H__ diff --git a/libs/ode-0.16.1/OPCODE/OPC_Model.cpp b/libs/ode-0.16.1/OPCODE/OPC_Model.cpp new file mode 100644 index 0000000..418dd7e --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_Model.cpp @@ -0,0 +1,222 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for OPCODE models. + * \file OPC_Model.cpp + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * The main collision wrapper, for all trees. Supported trees are: + * - Normal trees (2*N-1 nodes, full size) + * - No-leaf trees (N-1 nodes, full size) + * - Quantized trees (2*N-1 nodes, half size) + * - Quantized no-leaf trees (N-1 nodes, half size) + * + * Usage: + * + * 1) Create a static mesh interface using callbacks or pointers. (see OPC_MeshInterface.cpp). + * Keep it around in your app, since a pointer to this interface is saved internally and + * used until you release the collision structures. + * + * 2) Build a Model using a creation structure: + * + * \code + * Model Sample; + * + * OPCODECREATE OPCC; + * OPCC.IMesh = ...; + * OPCC.Rules = ...; + * OPCC.NoLeaf = ...; + * OPCC.Quantized = ...; + * OPCC.KeepOriginal = ...; + * bool Status = Sample.Build(OPCC); + * \endcode + * + * 3) Create a tree collider and set it up: + * + * \code + * AABBTreeCollider TC; + * TC.SetFirstContact(...); + * TC.SetFullBoxBoxTest(...); + * TC.SetFullPrimBoxTest(...); + * TC.SetTemporalCoherence(...); + * \endcode + * + * 4) Perform a collision query + * + * \code + * // Setup cache + * static BVTCache ColCache; + * ColCache.Model0 = &Model0; + * ColCache.Model1 = &Model1; + * + * // Collision query + * bool IsOk = TC.Collide(ColCache, World0, World1); + * + * // Get collision status => if true, objects overlap + * BOOL Status = TC.GetContactStatus(); + * + * // Number of colliding pairs and list of pairs + * udword NbPairs = TC.GetNbPairs(); + * const Pair* p = TC.GetPairs() + * \endcode + * + * 5) Stats + * + * \code + * Model0.GetUsedBytes() = number of bytes used for this collision tree + * TC.GetNbBVBVTests() = number of BV-BV overlap tests performed during last query + * TC.GetNbPrimPrimTests() = number of Triangle-Triangle overlap tests performed during last query + * TC.GetNbBVPrimTests() = number of Triangle-BV overlap tests performed during last query + * \endcode + * + * \class Model + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Model::Model() +{ +#ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE ! + mHull = null; +#endif // __MESHMERIZER_H__ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Model::~Model() +{ + Release(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Releases the model. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void Model::Release() +{ + ReleaseBase(); +#ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE ! + DELETESINGLE(mHull); +#endif // __MESHMERIZER_H__ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Builds a collision model. + * \param create [in] model creation structure + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool Model::Build(const OPCODECREATE& create) +{ + // 1) Checkings + if(!create.mIMesh || !create.mIMesh->IsValid()) return false; + + // For this model, we only support complete trees + if(create.mSettings.mLimit!=1) return SetIceError("OPCODE WARNING: supports complete trees only! Use mLimit = 1.\n", null); + + // Look for degenerate faces. + //udword NbDegenerate = create.mIMesh->CheckTopology(); + //if(NbDegenerate) Log("OPCODE WARNING: found %d degenerate faces in model! Collision might report wrong results!\n", NbDegenerate); + // We continue nonetheless.... + + Release(); // Make sure previous tree has been discarded [Opcode 1.3, thanks Adam] + + // 1-1) Setup mesh interface automatically [Opcode 1.3] + SetMeshInterface(create.mIMesh); + + // Special case for 1-triangle meshes [Opcode 1.3] + udword NbTris = create.mIMesh->GetNbTriangles(); + if(NbTris==1) + { + // We don't need to actually create a tree here, since we'll only have a single triangle to deal with anyway. + // It's a waste to use a "model" for this but at least it will work. + mModelCode |= OPC_SINGLE_NODE; + return true; + } + + // 2) Build a generic AABB Tree. + mSource = new AABBTree; + CHECKALLOC(mSource); + + // 2-1) Setup a builder. Our primitives here are triangles from input mesh, + // so we use an AABBTreeOfTrianglesBuilder..... + { + AABBTreeOfTrianglesBuilder TB; + TB.mIMesh = create.mIMesh; + TB.mSettings = create.mSettings; + TB.mNbPrimitives = NbTris; + if(!mSource->Build(&TB)) return false; + } + + // 3) Create an optimized tree according to user-settings + if(!CreateTree(create.mNoLeaf, create.mQuantized)) return false; + + // 3-2) Create optimized tree + if(!mTree->Build(mSource)) return false; + + // 3-3) Delete generic tree if needed + if(!create.mKeepOriginal) DELETESINGLE(mSource); + +#ifdef __MESHMERIZER_H__ + // 4) Convex hull + if(create.mCollisionHull) + { + // Create hull + mHull = new CollisionHull; + CHECKALLOC(mHull); + + CONVEXHULLCREATE CHC; + // ### doesn't work with strides + CHC.NbVerts = create.mIMesh->GetNbVertices(); + CHC.Vertices = create.mIMesh->GetVerts(); + CHC.UnifyNormals = true; + CHC.ReduceVertices = true; + CHC.WordFaces = false; + mHull->Compute(CHC); + } +#endif // __MESHMERIZER_H__ + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Gets the number of bytes used by the tree. + * \return amount of bytes used + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +udword Model::GetUsedBytes() const +{ + if(!mTree) return 0; + return mTree->GetUsedBytes(); +} diff --git a/libs/ode-0.16.1/OPCODE/OPC_Model.h b/libs/ode-0.16.1/OPCODE/OPC_Model.h new file mode 100644 index 0000000..98dee56 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_Model.h @@ -0,0 +1,65 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for OPCODE models. + * \file OPC_Model.h + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_MODEL_H__ +#define __OPC_MODEL_H__ + + class OPCODE_API Model : public BaseModel + { + public: + // Constructor/Destructor + Model(); + virtual ~Model(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Builds a collision model. + * \param create [in] model creation structure + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(BaseModel) bool Build(const OPCODECREATE& create); + +#ifdef __MESHMERIZER_H__ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the collision hull. + * \return the collision hull if it exists + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ const CollisionHull* GetHull() const { return mHull; } +#endif // __MESHMERIZER_H__ + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the number of bytes used by the tree. + * \return amount of bytes used + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(BaseModel) udword GetUsedBytes() const; + + private: +#ifdef __MESHMERIZER_H__ + CollisionHull* mHull; //!< Possible convex hull +#endif // __MESHMERIZER_H__ + // Internal methods + void Release(); + }; + +#endif //__OPC_MODEL_H__ diff --git a/libs/ode-0.16.1/OPCODE/OPC_OBBCollider.cpp b/libs/ode-0.16.1/OPCODE/OPC_OBBCollider.cpp new file mode 100644 index 0000000..730c7cc --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_OBBCollider.cpp @@ -0,0 +1,767 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for an OBB collider. + * \file OPC_OBBCollider.cpp + * \author Pierre Terdiman + * \date January, 1st, 2002 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains an OBB-vs-tree collider. + * + * \class OBBCollider + * \author Pierre Terdiman + * \version 1.3 + * \date January, 1st, 2002 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +#include "OPC_BoxBoxOverlap.h" +#include "OPC_TriBoxOverlap.h" + +#define SET_CONTACT(prim_index, flag) \ + /* Set contact status */ \ + mFlags |= flag; \ + mTouchedPrimitives->Add(udword(prim_index)); + +//! OBB-triangle test +#define OBB_PRIM(prim_index, flag) \ + /* Request vertices from the app */ \ + VertexPointers VP; ConversionArea VC; mIMesh->GetTriangle(VP, prim_index, VC); \ + /* Transform them in a common space */ \ + TransformPoint(mLeafVerts[0], *VP.Vertex[0], mRModelToBox, mTModelToBox); \ + TransformPoint(mLeafVerts[1], *VP.Vertex[1], mRModelToBox, mTModelToBox); \ + TransformPoint(mLeafVerts[2], *VP.Vertex[2], mRModelToBox, mTModelToBox); \ + /* Perform triangle-box overlap test */ \ + if(TriBoxOverlap()) \ + { \ + SET_CONTACT(prim_index, flag) \ + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +OBBCollider::OBBCollider() : mFullBoxBoxTest(true) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +OBBCollider::~OBBCollider() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Validates current settings. You should call this method after all the settings and callbacks have been defined. + * \return null if everything is ok, else a string describing the problem + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +const char* OBBCollider::ValidateSettings() +{ + if(TemporalCoherenceEnabled() && !FirstContactEnabled()) return "Temporal coherence only works with ""First contact"" mode!"; + + return VolumeCollider::ValidateSettings(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Generic collision query for generic OPCODE models. After the call, access the results: + * - with GetContactStatus() + * - with GetNbTouchedPrimitives() + * - with GetTouchedPrimitives() + * + * \param cache [in/out] a box cache + * \param box [in] collision OBB in local space + * \param model [in] Opcode model to collide with + * \param worldb [in] OBB's world matrix, or null + * \param worldm [in] model's world matrix, or null + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool OBBCollider::Collide(OBBCache& cache, const OBB& box, const Model& model, const Matrix4x4* worldb, const Matrix4x4* worldm) +{ + // Checkings + if(!Setup(&model)) return false; + + // Init collision query + if(InitQuery(cache, box, worldb, worldm)) return true; + + if(!model.HasLeafNodes()) + { + if(model.IsQuantized()) + { + const AABBQuantizedNoLeafTree* Tree = static_cast<const AABBQuantizedNoLeafTree *>(model.GetTree()); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + else + { + const AABBNoLeafTree* Tree = static_cast<const AABBNoLeafTree *>(model.GetTree()); + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + } + else + { + if(model.IsQuantized()) + { + const AABBQuantizedTree* Tree = static_cast<const AABBQuantizedTree *>(model.GetTree()); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + else + { + const AABBCollisionTree* Tree = static_cast<const AABBCollisionTree *>(model.GetTree()); + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + } + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Initializes a collision query : + * - reset stats & contact status + * - setup matrices + * - check temporal coherence + * + * \param cache [in/out] a box cache + * \param box [in] obb in local space + * \param worldb [in] obb's world matrix, or null + * \param worldm [in] model's world matrix, or null + * \return TRUE if we can return immediately + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +BOOL OBBCollider::InitQuery(OBBCache& cache, const OBB& box, const Matrix4x4* worldb, const Matrix4x4* worldm) +{ + // 1) Call the base method + VolumeCollider::InitQuery(); + + // 2) Compute obb in world space + mBoxExtents = box.mExtents; + + Matrix4x4 WorldB; + + if(worldb) + { + WorldB = Matrix4x4( box.mRot * Matrix3x3(*worldb) ); + WorldB.SetTrans(box.mCenter * *worldb); + } + else + { + WorldB = box.mRot; + WorldB.SetTrans(box.mCenter); + } + + // Setup matrices + Matrix4x4 InvWorldB; + InvertPRMatrix(InvWorldB, WorldB); + + if(worldm) + { + Matrix4x4 InvWorldM; + InvertPRMatrix(InvWorldM, *worldm); + + Matrix4x4 WorldBtoM = WorldB * InvWorldM; + Matrix4x4 WorldMtoB = *worldm * InvWorldB; + + mRModelToBox = WorldMtoB; WorldMtoB.GetTrans(mTModelToBox); + mRBoxToModel = WorldBtoM; WorldBtoM.GetTrans(mTBoxToModel); + } + else + { + mRModelToBox = InvWorldB; InvWorldB.GetTrans(mTModelToBox); + mRBoxToModel = WorldB; WorldB.GetTrans(mTBoxToModel); + } + + // 3) Setup destination pointer + mTouchedPrimitives = &cache.TouchedPrimitives; + + // 4) Special case: 1-triangle meshes [Opcode 1.3] + if(mCurrentModel && mCurrentModel->HasSingleNode()) + { + if(!SkipPrimitiveTests()) + { + // We simply perform the BV-Prim overlap test each time. We assume single triangle has index 0. + mTouchedPrimitives->Reset(); + + // Perform overlap test between the unique triangle and the box (and set contact status if needed) + OBB_PRIM(udword(0), OPC_CONTACT) + + // Return immediately regardless of status + return TRUE; + } + } + + // 5) Check temporal coherence: + if(TemporalCoherenceEnabled()) + { + // Here we use temporal coherence + // => check results from previous frame before performing the collision query + if(FirstContactEnabled()) + { + // We're only interested in the first contact found => test the unique previously touched face + if(mTouchedPrimitives->GetNbEntries()) + { + // Get index of previously touched face = the first entry in the array + udword PreviouslyTouchedFace = mTouchedPrimitives->GetEntry(0); + + // Then reset the array: + // - if the overlap test below is successful, the index we'll get added back anyway + // - if it isn't, then the array should be reset anyway for the normal query + mTouchedPrimitives->Reset(); + + // Perform overlap test between the cached triangle and the box (and set contact status if needed) + OBB_PRIM(PreviouslyTouchedFace, OPC_TEMPORAL_CONTACT) + + // Return immediately if possible + if(GetContactStatus()) return TRUE; + } + // else no face has been touched during previous query + // => we'll have to perform a normal query + } + else + { + // ### rewrite this + OBB TestBox(mTBoxToModel, mBoxExtents, mRBoxToModel); + + // We're interested in all contacts =>test the new real box N(ew) against the previous fat box P(revious): + if(IsCacheValid(cache) && TestBox.IsInside(cache.FatBox)) + { + // - if N is included in P, return previous list + // => we simply leave the list (mTouchedFaces) unchanged + + // Set contact status if needed + if(mTouchedPrimitives->GetNbEntries()) mFlags |= OPC_TEMPORAL_CONTACT; + + // In any case we don't need to do a query + return TRUE; + } + else + { + // - else do the query using a fat N + + // Reset cache since we'll about to perform a real query + mTouchedPrimitives->Reset(); + + // Make a fat box so that coherence will work for subsequent frames + TestBox.mExtents *= cache.FatCoeff; + mBoxExtents *= cache.FatCoeff; + + // Update cache with query data (signature for cached faces) + cache.FatBox = TestBox; + } + } + } + else + { + // Here we don't use temporal coherence => do a normal query + mTouchedPrimitives->Reset(); + } + + // Now we can precompute box-box data + + // Precompute absolute box-to-model rotation matrix + for(udword i=0;i<3;i++) + { + for(udword j=0;j<3;j++) + { + // Epsilon value prevents floating-point inaccuracies (strategy borrowed from RAPID) + mAR.m[i][j] = 1e-6f + fabsf(mRBoxToModel.m[i][j]); + } + } + + // Precompute bounds for box-in-box test + mB0 = mBoxExtents - mTModelToBox; + mB1 = - mBoxExtents - mTModelToBox; + + // Precompute box-box data - Courtesy of Erwin de Vries + mBBx1 = mBoxExtents.x*mAR.m[0][0] + mBoxExtents.y*mAR.m[1][0] + mBoxExtents.z*mAR.m[2][0]; + mBBy1 = mBoxExtents.x*mAR.m[0][1] + mBoxExtents.y*mAR.m[1][1] + mBoxExtents.z*mAR.m[2][1]; + mBBz1 = mBoxExtents.x*mAR.m[0][2] + mBoxExtents.y*mAR.m[1][2] + mBoxExtents.z*mAR.m[2][2]; + + mBB_1 = mBoxExtents.y*mAR.m[2][0] + mBoxExtents.z*mAR.m[1][0]; + mBB_2 = mBoxExtents.x*mAR.m[2][0] + mBoxExtents.z*mAR.m[0][0]; + mBB_3 = mBoxExtents.x*mAR.m[1][0] + mBoxExtents.y*mAR.m[0][0]; + mBB_4 = mBoxExtents.y*mAR.m[2][1] + mBoxExtents.z*mAR.m[1][1]; + mBB_5 = mBoxExtents.x*mAR.m[2][1] + mBoxExtents.z*mAR.m[0][1]; + mBB_6 = mBoxExtents.x*mAR.m[1][1] + mBoxExtents.y*mAR.m[0][1]; + mBB_7 = mBoxExtents.y*mAR.m[2][2] + mBoxExtents.z*mAR.m[1][2]; + mBB_8 = mBoxExtents.x*mAR.m[2][2] + mBoxExtents.z*mAR.m[0][2]; + mBB_9 = mBoxExtents.x*mAR.m[1][2] + mBoxExtents.y*mAR.m[0][2]; + + return FALSE; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks the OBB completely contains the box. In which case we can end the query sooner. + * \param bc [in] box center + * \param be [in] box extents + * \return true if the OBB contains the whole box + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL OBBCollider::OBBContainsBox(const Point& bc, const Point& be) +{ + // I assume if all 8 box vertices are inside the OBB, so does the whole box. + // Sounds ok but maybe there's a better way? +/* +#define TEST_PT(a,b,c) \ + p.x=a; p.y=b; p.z=c; p+=bc; \ + f = p.x * mRModelToBox.m[0][0] + p.y * mRModelToBox.m[1][0] + p.z * mRModelToBox.m[2][0]; if(f>mB0.x || f<mB1.x) return FALSE;\ + f = p.x * mRModelToBox.m[0][1] + p.y * mRModelToBox.m[1][1] + p.z * mRModelToBox.m[2][1]; if(f>mB0.y || f<mB1.y) return FALSE;\ + f = p.x * mRModelToBox.m[0][2] + p.y * mRModelToBox.m[1][2] + p.z * mRModelToBox.m[2][2]; if(f>mB0.z || f<mB1.z) return FALSE; + + Point p; + float f; + + TEST_PT(be.x, be.y, be.z) + TEST_PT(-be.x, be.y, be.z) + TEST_PT(be.x, -be.y, be.z) + TEST_PT(-be.x, -be.y, be.z) + TEST_PT(be.x, be.y, -be.z) + TEST_PT(-be.x, be.y, -be.z) + TEST_PT(be.x, -be.y, -be.z) + TEST_PT(-be.x, -be.y, -be.z) + + return TRUE; +*/ + + // Yes there is: + // - compute model-box's AABB in OBB space + // - test AABB-in-AABB + float NCx = bc.x * mRModelToBox.m[0][0] + bc.y * mRModelToBox.m[1][0] + bc.z * mRModelToBox.m[2][0]; + float NEx = fabsf(mRModelToBox.m[0][0] * be.x) + fabsf(mRModelToBox.m[1][0] * be.y) + fabsf(mRModelToBox.m[2][0] * be.z); + + if(mB0.x < NCx+NEx) return FALSE; + if(mB1.x > NCx-NEx) return FALSE; + + float NCy = bc.x * mRModelToBox.m[0][1] + bc.y * mRModelToBox.m[1][1] + bc.z * mRModelToBox.m[2][1]; + float NEy = fabsf(mRModelToBox.m[0][1] * be.x) + fabsf(mRModelToBox.m[1][1] * be.y) + fabsf(mRModelToBox.m[2][1] * be.z); + + if(mB0.y < NCy+NEy) return FALSE; + if(mB1.y > NCy-NEy) return FALSE; + + float NCz = bc.x * mRModelToBox.m[0][2] + bc.y * mRModelToBox.m[1][2] + bc.z * mRModelToBox.m[2][2]; + float NEz = fabsf(mRModelToBox.m[0][2] * be.x) + fabsf(mRModelToBox.m[1][2] * be.y) + fabsf(mRModelToBox.m[2][2] * be.z); + + if(mB0.z < NCz+NEz) return FALSE; + if(mB1.z > NCz-NEz) return FALSE; + + return TRUE; +} + +#define TEST_BOX_IN_OBB(center, extents) \ + if(OBBContainsBox(center, extents)) \ + { \ + /* Set contact status */ \ + mFlags |= OPC_CONTACT; \ + _Dump(node); \ + return; \ + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for normal AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void OBBCollider::_Collide(const AABBCollisionNode* node) +{ + // Perform OBB-AABB overlap test + if(!BoxBoxOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return; + + TEST_BOX_IN_OBB(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->IsLeaf()) + { + OBB_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _Collide(node->GetPos()); + + if(ContactFound()) return; + + _Collide(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for normal AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void OBBCollider::_CollideNoPrimitiveTest(const AABBCollisionNode* node) +{ + // Perform OBB-AABB overlap test + if(!BoxBoxOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return; + + TEST_BOX_IN_OBB(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->IsLeaf()) + { + SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + _CollideNoPrimitiveTest(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void OBBCollider::_Collide(const AABBQuantizedNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform OBB-AABB overlap test + if(!BoxBoxOverlap(Extents, Center)) return; + + TEST_BOX_IN_OBB(Center, Extents) + + if(node->IsLeaf()) + { + OBB_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _Collide(node->GetPos()); + + if(ContactFound()) return; + + _Collide(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void OBBCollider::_CollideNoPrimitiveTest(const AABBQuantizedNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform OBB-AABB overlap test + if(!BoxBoxOverlap(Extents, Center)) return; + + TEST_BOX_IN_OBB(Center, Extents) + + if(node->IsLeaf()) + { + SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + _CollideNoPrimitiveTest(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void OBBCollider::_Collide(const AABBNoLeafNode* node) +{ + // Perform OBB-AABB overlap test + if(!BoxBoxOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return; + + TEST_BOX_IN_OBB(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->HasPosLeaf()) { OBB_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } + else _Collide(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { OBB_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } + else _Collide(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for no-leaf AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void OBBCollider::_CollideNoPrimitiveTest(const AABBNoLeafNode* node) +{ + // Perform OBB-AABB overlap test + if(!BoxBoxOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return; + + TEST_BOX_IN_OBB(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void OBBCollider::_Collide(const AABBQuantizedNoLeafNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform OBB-AABB overlap test + if(!BoxBoxOverlap(Extents, Center)) return; + + TEST_BOX_IN_OBB(Center, Extents) + + if(node->HasPosLeaf()) { OBB_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } + else _Collide(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { OBB_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } + else _Collide(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized no-leaf AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void OBBCollider::_CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform OBB-AABB overlap test + if(!BoxBoxOverlap(Extents, Center)) return; + + TEST_BOX_IN_OBB(Center, Extents) + + if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetNeg()); +} + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HybridOBBCollider::HybridOBBCollider() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HybridOBBCollider::~HybridOBBCollider() +{ +} + +bool HybridOBBCollider::Collide(OBBCache& cache, const OBB& box, const HybridModel& model, const Matrix4x4* worldb, const Matrix4x4* worldm) +{ + // We don't want primitive tests here! + mFlags |= OPC_NO_PRIMITIVE_TESTS; + + // Checkings + if(!Setup(&model)) return false; + + // Init collision query + if(InitQuery(cache, box, worldb, worldm)) return true; + + // Special case for 1-leaf trees + if(mCurrentModel && mCurrentModel->HasSingleNode()) + { + // Here we're supposed to perform a normal query, except our tree has a single node, i.e. just a few triangles + udword Nb = mIMesh->GetNbTriangles(); + + // Loop through all triangles + for(udword i=0;i<Nb;i++) + { + OBB_PRIM(i, OPC_CONTACT) + } + return true; + } + + // Override destination array since we're only going to get leaf boxes here + mTouchedBoxes.Reset(); + mTouchedPrimitives = &mTouchedBoxes; + + // Now, do the actual query against leaf boxes + if(!model.HasLeafNodes()) + { + if(model.IsQuantized()) + { + const AABBQuantizedNoLeafTree* Tree = static_cast<const AABBQuantizedNoLeafTree *>(model.GetTree()); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + else + { + const AABBNoLeafTree* Tree = static_cast<const AABBNoLeafTree *>(model.GetTree()); + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + } + else + { + if(model.IsQuantized()) + { + const AABBQuantizedTree* Tree = static_cast<const AABBQuantizedTree *>(model.GetTree()); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + else + { + const AABBCollisionTree* Tree = static_cast<const AABBCollisionTree *>(model.GetTree()); + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + } + + // We only have a list of boxes so far + if(GetContactStatus()) + { + // Reset contact status, since it currently only reflects collisions with leaf boxes + Collider::InitQuery(); + + // Change dest container so that we can use built-in overlap tests and get collided primitives + cache.TouchedPrimitives.Reset(); + mTouchedPrimitives = &cache.TouchedPrimitives; + + // Read touched leaf boxes + udword Nb = mTouchedBoxes.GetNbEntries(); + const udword* Touched = mTouchedBoxes.GetEntries(); + + const LeafTriangles* LT = model.GetLeafTriangles(); + const udword* Indices = model.GetIndices(); + + // Loop through touched leaves + while(Nb--) + { + const LeafTriangles& CurrentLeaf = LT[*Touched++]; + + // Each leaf box has a set of triangles + udword NbTris = CurrentLeaf.GetNbTriangles(); + if(Indices) + { + const udword* T = &Indices[CurrentLeaf.GetTriangleIndex()]; + + // Loop through triangles and test each of them + while(NbTris--) + { + udword TriangleIndex = *T++; + OBB_PRIM(TriangleIndex, OPC_CONTACT) + } + } + else + { + udword BaseIndex = CurrentLeaf.GetTriangleIndex(); + + // Loop through triangles and test each of them + while(NbTris--) + { + udword TriangleIndex = BaseIndex++; + OBB_PRIM(TriangleIndex, OPC_CONTACT) + } + } + } + } + + return true; +} diff --git a/libs/ode-0.16.1/OPCODE/OPC_OBBCollider.h b/libs/ode-0.16.1/OPCODE/OPC_OBBCollider.h new file mode 100644 index 0000000..a050118 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_OBBCollider.h @@ -0,0 +1,142 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for an OBB collider. + * \file OPC_OBBCollider.h + * \author Pierre Terdiman + * \date January, 1st, 2002 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_OBBCOLLIDER_H__ +#define __OPC_OBBCOLLIDER_H__ + + struct OPCODE_API OBBCache : VolumeCache + { + OBBCache() : FatCoeff(1.1f) + { + FatBox.mCenter.Zero(); + FatBox.mExtents.Zero(); + FatBox.mRot.Identity(); + } + + // Cached faces signature + OBB FatBox; //!< Box used when performing the query resulting in cached faces + // User settings + float FatCoeff; //!< extents multiplier used to create a fat box + }; + + class OPCODE_API OBBCollider : public VolumeCollider + { + public: + // Constructor / Destructor + OBBCollider(); + virtual ~OBBCollider(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Generic collision query for generic OPCODE models. After the call, access the results: + * - with GetContactStatus() + * - with GetNbTouchedPrimitives() + * - with GetTouchedPrimitives() + * + * \param cache [in/out] a box cache + * \param box [in] collision OBB in local space + * \param model [in] Opcode model to collide with + * \param worldb [in] OBB's world matrix, or null + * \param worldm [in] model's world matrix, or null + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool Collide(OBBCache& cache, const OBB& box, const Model& model, const Matrix4x4* worldb=null, const Matrix4x4* worldm=null); + + // Settings + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Settings: select between full box-box tests or "SAT-lite" tests (where Class III axes are discarded) + * \param flag [in] true for full tests, false for coarse tests + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetFullBoxBoxTest(bool flag) { mFullBoxBoxTest = flag; } + + // Settings + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Validates current settings. You should call this method after all the settings and callbacks have been defined for a collider. + * \return null if everything is ok, else a string describing the problem + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(Collider) const char* ValidateSettings(); + + protected: + // Precomputed data + Matrix3x3 mAR; //!< Absolute rotation matrix + Matrix3x3 mRModelToBox; //!< Rotation from model space to obb space + Matrix3x3 mRBoxToModel; //!< Rotation from obb space to model space + Point mTModelToBox; //!< Translation from model space to obb space + Point mTBoxToModel; //!< Translation from obb space to model space + + Point mBoxExtents; + Point mB0; //!< - mTModelToBox + mBoxExtents + Point mB1; //!< - mTModelToBox - mBoxExtents + + float mBBx1; + float mBBy1; + float mBBz1; + + float mBB_1; + float mBB_2; + float mBB_3; + float mBB_4; + float mBB_5; + float mBB_6; + float mBB_7; + float mBB_8; + float mBB_9; + + // Leaf description + Point mLeafVerts[3]; //!< Triangle vertices + // Settings + bool mFullBoxBoxTest; //!< Perform full BV-BV tests (true) or SAT-lite tests (false) + // Internal methods + void _Collide(const AABBCollisionNode* node); + void _Collide(const AABBNoLeafNode* node); + void _Collide(const AABBQuantizedNode* node); + void _Collide(const AABBQuantizedNoLeafNode* node); + void _CollideNoPrimitiveTest(const AABBCollisionNode* node); + void _CollideNoPrimitiveTest(const AABBNoLeafNode* node); + void _CollideNoPrimitiveTest(const AABBQuantizedNode* node); + void _CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node); + // Overlap tests + inline_ BOOL OBBContainsBox(const Point& bc, const Point& be); + inline_ BOOL BoxBoxOverlap(const Point& extents, const Point& center); + inline_ BOOL TriBoxOverlap(); + // Init methods + BOOL InitQuery(OBBCache& cache, const OBB& box, const Matrix4x4* worldb=null, const Matrix4x4* worldm=null); + }; + + class OPCODE_API HybridOBBCollider : public OBBCollider + { + public: + // Constructor / Destructor + HybridOBBCollider(); + virtual ~HybridOBBCollider(); + + bool Collide(OBBCache& cache, const OBB& box, const HybridModel& model, const Matrix4x4* worldb=null, const Matrix4x4* worldm=null); + protected: + Container mTouchedBoxes; + }; + +#endif // __OPC_OBBCOLLIDER_H__ diff --git a/libs/ode-0.16.1/OPCODE/OPC_OptimizedTree.cpp b/libs/ode-0.16.1/OPCODE/OPC_OptimizedTree.cpp new file mode 100644 index 0000000..057853e --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_OptimizedTree.cpp @@ -0,0 +1,795 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for optimized trees. Implements 4 trees: + * - normal + * - no leaf + * - quantized + * - no leaf / quantized + * + * \file OPC_OptimizedTree.cpp + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * A standard AABB tree. + * + * \class AABBCollisionTree + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * A no-leaf AABB tree. + * + * \class AABBNoLeafTree + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * A quantized AABB tree. + * + * \class AABBQuantizedTree + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * A quantized no-leaf AABB tree. + * + * \class AABBQuantizedNoLeafTree + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +//! Compilation flag: +//! - true to fix quantized boxes (i.e. make sure they enclose the original ones) +//! - false to see the effects of quantization errors (faster, but wrong results in some cases) +static const bool gFixQuantized = true; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Builds an implicit tree from a standard one. An implicit tree is a complete tree (2*N-1 nodes) whose negative + * box pointers and primitive pointers have been made implicit, hence packing 3 pointers in one. + * + * Layout for implicit trees: + * Node: + * - box + * - data (32-bits value) + * + * if data's LSB = 1 => remaining bits are a primitive pointer + * else remaining bits are a P-node pointer, and N = P + 1 + * + * \relates AABBCollisionNode + * \fn _BuildCollisionTree(AABBCollisionNode* linear, const udword box_id, udword& current_id, const AABBTreeNode* current_node) + * \param linear [in] base address of destination nodes + * \param box_id [in] index of destination node + * \param current_id [in] current running index + * \param current_node [in] current node from input tree + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +static void _BuildCollisionTree(AABBCollisionNode* linear, const udword box_id, udword& current_id, const AABBTreeNode* current_node) +{ + // Current node from input tree is "current_node". Must be flattened into "linear[boxid]". + + // Store the AABB + current_node->GetAABB()->GetCenter(linear[box_id].mAABB.mCenter); + current_node->GetAABB()->GetExtents(linear[box_id].mAABB.mExtents); + // Store remaining info + if(current_node->IsLeaf()) + { + // The input tree must be complete => i.e. one primitive/leaf + ASSERT(current_node->GetNbPrimitives()==1); + // Get the primitive index from the input tree + udword PrimitiveIndex = current_node->GetPrimitives()[0]; + // Setup box data as the primitive index, marked as leaf + linear[box_id].mData = (PrimitiveIndex<<1)|1; + } + else + { + // To make the negative one implicit, we must store P and N in successive order + udword PosID = current_id++; // Get a new id for positive child + udword NegID = current_id++; // Get a new id for negative child + // Setup box data as the forthcoming new P pointer + linear[box_id].mData = (size_t)&linear[PosID]; + // Make sure it's not marked as leaf + ASSERT(!(linear[box_id].mData&1)); + // Recurse with new IDs + _BuildCollisionTree(linear, PosID, current_id, current_node->GetPos()); + _BuildCollisionTree(linear, NegID, current_id, current_node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Builds a "no-leaf" tree from a standard one. This is a tree whose leaf nodes have been removed. + * + * Layout for no-leaf trees: + * + * Node: + * - box + * - P pointer => a node (LSB=0) or a primitive (LSB=1) + * - N pointer => a node (LSB=0) or a primitive (LSB=1) + * + * \relates AABBNoLeafNode + * \fn _BuildNoLeafTree(AABBNoLeafNode* linear, const udword box_id, udword& current_id, const AABBTreeNode* current_node) + * \param linear [in] base address of destination nodes + * \param box_id [in] index of destination node + * \param current_id [in] current running index + * \param current_node [in] current node from input tree + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +static void _BuildNoLeafTree(AABBNoLeafNode* linear, const udword box_id, udword& current_id, const AABBTreeNode* current_node) +{ + const AABBTreeNode* P = current_node->GetPos(); + const AABBTreeNode* N = current_node->GetNeg(); + // Leaf nodes here?! + ASSERT(P); + ASSERT(N); + // Internal node => keep the box + current_node->GetAABB()->GetCenter(linear[box_id].mAABB.mCenter); + current_node->GetAABB()->GetExtents(linear[box_id].mAABB.mExtents); + + if(P->IsLeaf()) + { + // The input tree must be complete => i.e. one primitive/leaf + ASSERT(P->GetNbPrimitives()==1); + // Get the primitive index from the input tree + udword PrimitiveIndex = P->GetPrimitives()[0]; + // Setup prev box data as the primitive index, marked as leaf + linear[box_id].mPosData = (PrimitiveIndex<<1)|1; + } + else + { + // Get a new id for positive child + udword PosID = current_id++; + // Setup box data + linear[box_id].mPosData = (size_t)&linear[PosID]; + // Make sure it's not marked as leaf + ASSERT(!(linear[box_id].mPosData&1)); + // Recurse + _BuildNoLeafTree(linear, PosID, current_id, P); + } + + if(N->IsLeaf()) + { + // The input tree must be complete => i.e. one primitive/leaf + ASSERT(N->GetNbPrimitives()==1); + // Get the primitive index from the input tree + udword PrimitiveIndex = N->GetPrimitives()[0]; + // Setup prev box data as the primitive index, marked as leaf + linear[box_id].mNegData = (PrimitiveIndex<<1)|1; + } + else + { + // Get a new id for negative child + udword NegID = current_id++; + // Setup box data + linear[box_id].mNegData = (size_t)&linear[NegID]; + // Make sure it's not marked as leaf + ASSERT(!(linear[box_id].mNegData&1)); + // Recurse + _BuildNoLeafTree(linear, NegID, current_id, N); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBCollisionTree::AABBCollisionTree() : mNodes(null) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBCollisionTree::~AABBCollisionTree() +{ + DELETEARRAY(mNodes); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Builds the collision tree from a generic AABB tree. + * \param tree [in] generic AABB tree + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBCollisionTree::Build(AABBTree* tree) +{ + // Checkings + if(!tree) return false; + // Check the input tree is complete + udword NbTriangles = tree->GetNbPrimitives(); + udword NbNodes = tree->GetNbNodes(); + if(NbNodes!=NbTriangles*2-1) return false; + + // Get nodes + if(mNbNodes!=NbNodes) // Same number of nodes => keep moving + { + mNbNodes = NbNodes; + DELETEARRAY(mNodes); + mNodes = new AABBCollisionNode[NbNodes]; + CHECKALLOC(mNodes); + } + + // Build the tree + udword CurID = 1; + _BuildCollisionTree(mNodes, 0, CurID, tree); + ASSERT(CurID==NbNodes); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Refits the collision tree after vertices have been modified. + * \param mesh_interface [in] mesh interface for current model + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBCollisionTree::Refit(const MeshInterface* /*mesh_interface*/) +{ + ASSERT(!"Not implemented since AABBCollisionTrees have twice as more nodes to refit as AABBNoLeafTrees!"); + return false; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Walks the tree and call the user back for each node. + * \param callback [in] walking callback + * \param user_data [in] callback's user data + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBCollisionTree::Walk(GenericWalkingCallback callback, void* user_data) const +{ + if(!callback) return false; + + struct Local + { + static void _Walk(const AABBCollisionNode* current_node, GenericWalkingCallback callback, void* user_data) + { + if(!current_node || !(callback)(current_node, user_data)) return; + + if(!current_node->IsLeaf()) + { + _Walk(current_node->GetPos(), callback, user_data); + _Walk(current_node->GetNeg(), callback, user_data); + } + } + }; + Local::_Walk(mNodes, callback, user_data); + return true; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBNoLeafTree::AABBNoLeafTree() : mNodes(null) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBNoLeafTree::~AABBNoLeafTree() +{ + DELETEARRAY(mNodes); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Builds the collision tree from a generic AABB tree. + * \param tree [in] generic AABB tree + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBNoLeafTree::Build(AABBTree* tree) +{ + // Checkings + if(!tree) return false; + // Check the input tree is complete + udword NbTriangles = tree->GetNbPrimitives(); + udword NbExistingNodes = tree->GetNbNodes(); + if(NbExistingNodes!=NbTriangles*2-1) return false; + + udword NbNodes = NbTriangles-1; + // Get nodes + if(mNbNodes!=NbNodes) // Same number of nodes => keep moving + { + mNbNodes = NbNodes; + DELETEARRAY(mNodes); + mNodes = new AABBNoLeafNode[NbNodes]; + CHECKALLOC(mNodes); + } + + // Build the tree + udword CurID = 1; + _BuildNoLeafTree(mNodes, 0, CurID, tree); + ASSERT(CurID==NbNodes); + + return true; +} + +inline_ void ComputeMinMax(Point& min, Point& max, const VertexPointers& vp) +{ + // Compute triangle's AABB = a leaf box +#ifdef OPC_USE_FCOMI // a 15% speedup on my machine, not much + min.x = FCMin3(vp.Vertex[0]->x, vp.Vertex[1]->x, vp.Vertex[2]->x); + max.x = FCMax3(vp.Vertex[0]->x, vp.Vertex[1]->x, vp.Vertex[2]->x); + + min.y = FCMin3(vp.Vertex[0]->y, vp.Vertex[1]->y, vp.Vertex[2]->y); + max.y = FCMax3(vp.Vertex[0]->y, vp.Vertex[1]->y, vp.Vertex[2]->y); + + min.z = FCMin3(vp.Vertex[0]->z, vp.Vertex[1]->z, vp.Vertex[2]->z); + max.z = FCMax3(vp.Vertex[0]->z, vp.Vertex[1]->z, vp.Vertex[2]->z); +#else + min = *vp.Vertex[0]; + max = *vp.Vertex[0]; + min.Min(*vp.Vertex[1]); + max.Max(*vp.Vertex[1]); + min.Min(*vp.Vertex[2]); + max.Max(*vp.Vertex[2]); +#endif +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Refits the collision tree after vertices have been modified. + * \param mesh_interface [in] mesh interface for current model + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBNoLeafTree::Refit(const MeshInterface* mesh_interface) +{ + // Checkings + if(!mesh_interface) return false; + + // Bottom-up update + VertexPointers VP; + ConversionArea VC; + Point Min,Max; + Point Min_,Max_; + udword Index = mNbNodes; + while(Index--) + { + AABBNoLeafNode& Current = mNodes[Index]; + + if(Current.HasPosLeaf()) + { + mesh_interface->GetTriangle(VP, Current.GetPosPrimitive(), VC); + ComputeMinMax(Min, Max, VP); + } + else + { + const CollisionAABB& CurrentBox = Current.GetPos()->mAABB; + CurrentBox.GetMin(Min); + CurrentBox.GetMax(Max); + } + + if(Current.HasNegLeaf()) + { + mesh_interface->GetTriangle(VP, Current.GetNegPrimitive(), VC); + ComputeMinMax(Min_, Max_, VP); + } + else + { + const CollisionAABB& CurrentBox = Current.GetNeg()->mAABB; + CurrentBox.GetMin(Min_); + CurrentBox.GetMax(Max_); + } +#ifdef OPC_USE_FCOMI + Min.x = FCMin2(Min.x, Min_.x); + Max.x = FCMax2(Max.x, Max_.x); + Min.y = FCMin2(Min.y, Min_.y); + Max.y = FCMax2(Max.y, Max_.y); + Min.z = FCMin2(Min.z, Min_.z); + Max.z = FCMax2(Max.z, Max_.z); +#else + Min.Min(Min_); + Max.Max(Max_); +#endif + Current.mAABB.SetMinMax(Min, Max); + } + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Walks the tree and call the user back for each node. + * \param callback [in] walking callback + * \param user_data [in] callback's user data + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBNoLeafTree::Walk(GenericWalkingCallback callback, void* user_data) const +{ + if(!callback) return false; + + struct Local + { + static void _Walk(const AABBNoLeafNode* current_node, GenericWalkingCallback callback, void* user_data) + { + if(!current_node || !(callback)(current_node, user_data)) return; + + if(!current_node->HasPosLeaf()) _Walk(current_node->GetPos(), callback, user_data); + if(!current_node->HasNegLeaf()) _Walk(current_node->GetNeg(), callback, user_data); + } + }; + Local::_Walk(mNodes, callback, user_data); + return true; +} + +// Quantization notes: +// - We could use the highest bits of mData to store some more quantized bits. Dequantization code +// would be slightly more complex, but number of overlap tests would be reduced (and anyhow those +// bits are currently wasted). Of course it's not possible if we move to 16 bits mData. +// - Something like "16 bits floats" could be tested, to bypass the int-to-float conversion. +// - A dedicated BV-BV test could be used, dequantizing while testing for overlap. (i.e. it's some +// lazy-dequantization which may save some work in case of early exits). At the very least some +// muls could be saved by precomputing several more matrices. But maybe not worth the pain. +// - Do we need to dequantize anyway? Not doing the extents-related muls only implies the box has +// been scaled, for example. +// - The deeper we move into the hierarchy, the smaller the extents should be. May not need a fixed +// number of quantization bits. Even better, could probably be best delta-encoded. + + +// Find max values. Some people asked why I wasn't simply using the first node. Well, I can't. +// I'm not looking for (min, max) values like in a standard AABB, I'm looking for the extremal +// centers/extents in order to quantize them. The first node would only give a single center and +// a single extents. While extents would be the biggest, the center wouldn't. +#define FIND_MAX_VALUES \ + /* Get max values */ \ + Point CMax(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT); \ + Point EMax(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT); \ + const udword NbNodes = mNbNodes; \ + for(udword i=0;i<NbNodes;i++) \ + { \ + float cx = fabsf(Nodes[i].mAABB.mCenter.x); if(cx>CMax.x) CMax.x = cx; \ + float cy = fabsf(Nodes[i].mAABB.mCenter.y); if(cy>CMax.y) CMax.y = cy; \ + float cz = fabsf(Nodes[i].mAABB.mCenter.z); if(cz>CMax.z) CMax.z = cz; \ + float ex = fabsf(Nodes[i].mAABB.mExtents.x); if(ex>EMax.x) EMax.x = ex; \ + float ey = fabsf(Nodes[i].mAABB.mExtents.y); if(ey>EMax.y) EMax.y = ey; \ + float ez = fabsf(Nodes[i].mAABB.mExtents.z); if(ez>EMax.z) EMax.z = ez; \ + } + +#define INIT_QUANTIZATION \ + udword nbc=15; /* Keep one bit for sign */ \ + udword nbe=15; /* Keep one bit for fix */ \ + if(!gFixQuantized) nbe++; \ + \ + /* Compute quantization coeffs */ \ + Point CQuantCoeff, EQuantCoeff; \ + CQuantCoeff.x = CMax.x!=0.0f ? float((1<<nbc)-1)/CMax.x : 0.0f; \ + CQuantCoeff.y = CMax.y!=0.0f ? float((1<<nbc)-1)/CMax.y : 0.0f; \ + CQuantCoeff.z = CMax.z!=0.0f ? float((1<<nbc)-1)/CMax.z : 0.0f; \ + EQuantCoeff.x = EMax.x!=0.0f ? float((1<<nbe)-1)/EMax.x : 0.0f; \ + EQuantCoeff.y = EMax.y!=0.0f ? float((1<<nbe)-1)/EMax.y : 0.0f; \ + EQuantCoeff.z = EMax.z!=0.0f ? float((1<<nbe)-1)/EMax.z : 0.0f; \ + /* Compute and save dequantization coeffs */ \ + mCenterCoeff.x = CQuantCoeff.x!=0.0f ? 1.0f / CQuantCoeff.x : 0.0f; \ + mCenterCoeff.y = CQuantCoeff.y!=0.0f ? 1.0f / CQuantCoeff.y : 0.0f; \ + mCenterCoeff.z = CQuantCoeff.z!=0.0f ? 1.0f / CQuantCoeff.z : 0.0f; \ + mExtentsCoeff.x = EQuantCoeff.x!=0.0f ? 1.0f / EQuantCoeff.x : 0.0f; \ + mExtentsCoeff.y = EQuantCoeff.y!=0.0f ? 1.0f / EQuantCoeff.y : 0.0f; \ + mExtentsCoeff.z = EQuantCoeff.z!=0.0f ? 1.0f / EQuantCoeff.z : 0.0f; \ + +#define PERFORM_QUANTIZATION \ + /* Quantize */ \ + mNodes[i].mAABB.mCenter[0] = sword(Nodes[i].mAABB.mCenter.x * CQuantCoeff.x); \ + mNodes[i].mAABB.mCenter[1] = sword(Nodes[i].mAABB.mCenter.y * CQuantCoeff.y); \ + mNodes[i].mAABB.mCenter[2] = sword(Nodes[i].mAABB.mCenter.z * CQuantCoeff.z); \ + mNodes[i].mAABB.mExtents[0] = uword(Nodes[i].mAABB.mExtents.x * EQuantCoeff.x); \ + mNodes[i].mAABB.mExtents[1] = uword(Nodes[i].mAABB.mExtents.y * EQuantCoeff.y); \ + mNodes[i].mAABB.mExtents[2] = uword(Nodes[i].mAABB.mExtents.z * EQuantCoeff.z); \ + /* Fix quantized boxes */ \ + if(gFixQuantized) \ + { \ + /* Make sure the quantized box is still valid */ \ + Point Max = Nodes[i].mAABB.mCenter + Nodes[i].mAABB.mExtents; \ + Point Min = Nodes[i].mAABB.mCenter - Nodes[i].mAABB.mExtents; \ + /* For each axis */ \ + for(udword j=0;j<3;j++) \ + { /* Dequantize the box center */ \ + float qc = float(mNodes[i].mAABB.mCenter[j]) * mCenterCoeff[j]; \ + bool FixMe=true; \ + do \ + { /* Dequantize the box extent */ \ + float qe = float(mNodes[i].mAABB.mExtents[j]) * mExtentsCoeff[j]; \ + /* Compare real & dequantized values */ \ + if(qc+qe<Max[j] || qc-qe>Min[j]) \ + { \ + mNodes[i].mAABB.mExtents[j]++; \ + /* Prevent wrapping */ \ + if(!mNodes[i].mAABB.mExtents[j]) \ + { \ + mNodes[i].mAABB.mExtents[j]=0xffff; \ + FixMe=false; \ + } \ + } \ + else FixMe=false; \ + }while(FixMe); \ + } \ + } + +#define REMAP_DATA(member, NodeType) \ + /* Fix data */ \ + Data = Nodes[i].member; \ + if(!(Data&1)) \ + { \ + /* Compute box number */ \ + size_t Nb = ((NodeType *)(Data) - (Nodes)); \ + Data = (size_t) &mNodes[Nb]; \ + } \ + /* ...remapped */ \ + mNodes[i].member = Data; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBQuantizedTree::AABBQuantizedTree() : mNodes(null) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBQuantizedTree::~AABBQuantizedTree() +{ + DELETEARRAY(mNodes); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Builds the collision tree from a generic AABB tree. + * \param tree [in] generic AABB tree + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBQuantizedTree::Build(AABBTree* tree) +{ + // Checkings + if(!tree) return false; + // Check the input tree is complete + udword NbTriangles = tree->GetNbPrimitives(); + udword NbNodes = tree->GetNbNodes(); + if(NbNodes!=NbTriangles*2-1) return false; + + // Get nodes + mNbNodes = NbNodes; + DELETEARRAY(mNodes); + AABBCollisionNode* Nodes = new AABBCollisionNode[NbNodes]; + CHECKALLOC(Nodes); + + // Build the tree + udword CurID = 1; + _BuildCollisionTree(Nodes, 0, CurID, tree); + + // Quantize + { + mNodes = new AABBQuantizedNode[NbNodes]; + + if (mNodes != null) + { + // Get max values + FIND_MAX_VALUES + + // Quantization + INIT_QUANTIZATION + + // Quantize + size_t Data; + for(udword i=0;i<NbNodes;i++) + { + PERFORM_QUANTIZATION + REMAP_DATA(mData, AABBCollisionNode) + } + } + + DELETEARRAY(Nodes); + CHECKALLOC(mNodes); + } + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Refits the collision tree after vertices have been modified. + * \param mesh_interface [in] mesh interface for current model + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBQuantizedTree::Refit(const MeshInterface* /*mesh_interface*/) +{ + ASSERT(!"Not implemented since requantizing is painful !"); + return false; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Walks the tree and call the user back for each node. + * \param callback [in] walking callback + * \param user_data [in] callback's user data + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBQuantizedTree::Walk(GenericWalkingCallback callback, void* user_data) const +{ + if(!callback) return false; + + struct Local + { + static void _Walk(const AABBQuantizedNode* current_node, GenericWalkingCallback callback, void* user_data) + { + if(!current_node || !(callback)(current_node, user_data)) return; + + if(!current_node->IsLeaf()) + { + _Walk(current_node->GetPos(), callback, user_data); + _Walk(current_node->GetNeg(), callback, user_data); + } + } + }; + Local::_Walk(mNodes, callback, user_data); + return true; +} + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBQuantizedNoLeafTree::AABBQuantizedNoLeafTree() : mNodes(null) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBQuantizedNoLeafTree::~AABBQuantizedNoLeafTree() +{ + DELETEARRAY(mNodes); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Builds the collision tree from a generic AABB tree. + * \param tree [in] generic AABB tree + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBQuantizedNoLeafTree::Build(AABBTree* tree) +{ + // Checkings + if(!tree) return false; + // Check the input tree is complete + udword NbTriangles = tree->GetNbPrimitives(); + udword NbExistingNodes = tree->GetNbNodes(); + if(NbExistingNodes!=NbTriangles*2-1) return false; + + // Get nodes + udword NbNodes = NbTriangles-1; + mNbNodes = NbNodes; + DELETEARRAY(mNodes); + AABBNoLeafNode* Nodes = new AABBNoLeafNode[NbNodes]; + CHECKALLOC(Nodes); + + // Build the tree + udword CurID = 1; + _BuildNoLeafTree(Nodes, 0, CurID, tree); + ASSERT(CurID==NbNodes); + + // Quantize + { + mNodes = new AABBQuantizedNoLeafNode[NbNodes]; + + if (mNodes != null) + { + // Get max values + FIND_MAX_VALUES + + // Quantization + INIT_QUANTIZATION + + // Quantize + size_t Data; + for(udword i=0;i<NbNodes;i++) + { + PERFORM_QUANTIZATION + REMAP_DATA(mPosData, AABBNoLeafNode) + REMAP_DATA(mNegData, AABBNoLeafNode) + } + } + + DELETEARRAY(Nodes); + CHECKALLOC(mNodes); + } + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Refits the collision tree after vertices have been modified. + * \param mesh_interface [in] mesh interface for current model + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBQuantizedNoLeafTree::Refit(const MeshInterface* /*mesh_interface*/) +{ + ASSERT(!"Not implemented since requantizing is painful !"); + return false; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Walks the tree and call the user back for each node. + * \param callback [in] walking callback + * \param user_data [in] callback's user data + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBQuantizedNoLeafTree::Walk(GenericWalkingCallback callback, void* user_data) const +{ + if(!callback) return false; + + struct Local + { + static void _Walk(const AABBQuantizedNoLeafNode* current_node, GenericWalkingCallback callback, void* user_data) + { + if(!current_node || !(callback)(current_node, user_data)) return; + + if(!current_node->HasPosLeaf()) _Walk(current_node->GetPos(), callback, user_data); + if(!current_node->HasNegLeaf()) _Walk(current_node->GetNeg(), callback, user_data); + } + }; + Local::_Walk(mNodes, callback, user_data); + return true; +} diff --git a/libs/ode-0.16.1/OPCODE/OPC_OptimizedTree.h b/libs/ode-0.16.1/OPCODE/OPC_OptimizedTree.h new file mode 100644 index 0000000..36aea07 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_OptimizedTree.h @@ -0,0 +1,206 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for optimized trees. + * \file OPC_OptimizedTree.h + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_OPTIMIZEDTREE_H__ +#define __OPC_OPTIMIZEDTREE_H__ + + //! Common interface for a node of an implicit tree + #define IMPLEMENT_IMPLICIT_NODE(base_class, volume) \ + public: \ + /* Constructor / Destructor */ \ + inline_ base_class() : mData(0) {} \ + inline_ ~base_class() {} \ + /* Leaf test */ \ + inline_ BOOL IsLeaf() const { return (mData&1)!=0; } \ + /* Data access */ \ + inline_ const base_class* GetPos() const { return (base_class*)mData; } \ + inline_ const base_class* GetNeg() const { return ((base_class*)mData)+1; } \ + inline_ size_t GetPrimitive() const { return (mData>>1); } \ + /* Stats */ \ + inline_ udword GetNodeSize() const { return SIZEOFOBJECT; } \ + \ + volume mAABB; \ + size_t mData; + + //! Common interface for a node of a no-leaf tree + #define IMPLEMENT_NOLEAF_NODE(base_class, volume) \ + public: \ + /* Constructor / Destructor */ \ + inline_ base_class() : mPosData(0), mNegData(0) {} \ + inline_ ~base_class() {} \ + /* Leaf tests */ \ + inline_ BOOL HasPosLeaf() const { return (mPosData&1)!=0; } \ + inline_ BOOL HasNegLeaf() const { return (mNegData&1)!=0; } \ + /* Data access */ \ + inline_ const base_class* GetPos() const { return (base_class*)mPosData; } \ + inline_ const base_class* GetNeg() const { return (base_class*)mNegData; } \ + inline_ size_t GetPosPrimitive() const { return (mPosData>>1); } \ + inline_ size_t GetNegPrimitive() const { return (mNegData>>1); } \ + /* Stats */ \ + inline_ udword GetNodeSize() const { return SIZEOFOBJECT; } \ + \ + volume mAABB; \ + size_t mPosData; \ + size_t mNegData; + + class OPCODE_API AABBCollisionNode + { + IMPLEMENT_IMPLICIT_NODE(AABBCollisionNode, CollisionAABB) + + inline_ float GetVolume() const { return mAABB.mExtents.x * mAABB.mExtents.y * mAABB.mExtents.z; } + inline_ float GetSize() const { return mAABB.mExtents.SquareMagnitude(); } + inline_ udword GetRadius() const + { + udword* Bits = (udword*)&mAABB.mExtents.x; + udword Max = Bits[0]; + if(Bits[1]>Max) Max = Bits[1]; + if(Bits[2]>Max) Max = Bits[2]; + return Max; + } + + // NB: using the square-magnitude or the true volume of the box, seems to yield better results + // (assuming UNC-like informed traversal methods). I borrowed this idea from PQP. The usual "size" + // otherwise, is the largest box extent. In SOLID that extent is computed on-the-fly each time it's + // needed (the best approach IMHO). In RAPID the rotation matrix is permuted so that Extent[0] is + // always the greatest, which saves looking for it at runtime. On the other hand, it yields matrices + // whose determinant is not 1, i.e. you can't encode them anymore as unit quaternions. Not a very + // good strategy. + }; + + class OPCODE_API AABBQuantizedNode + { + IMPLEMENT_IMPLICIT_NODE(AABBQuantizedNode, QuantizedAABB) + + inline_ uword GetSize() const + { + const uword* Bits = mAABB.mExtents; + uword Max = Bits[0]; + if(Bits[1]>Max) Max = Bits[1]; + if(Bits[2]>Max) Max = Bits[2]; + return Max; + } + // NB: for quantized nodes I don't feel like computing a square-magnitude with integers all + // over the place.......! + }; + + class OPCODE_API AABBNoLeafNode + { + IMPLEMENT_NOLEAF_NODE(AABBNoLeafNode, CollisionAABB) + }; + + class OPCODE_API AABBQuantizedNoLeafNode + { + IMPLEMENT_NOLEAF_NODE(AABBQuantizedNoLeafNode, QuantizedAABB) + }; + + //! Common interface for a collision tree + #define IMPLEMENT_COLLISION_TREE(base_class, node) \ + public: \ + /* Constructor / Destructor */ \ + base_class(); \ + virtual ~base_class(); \ + /* Builds from a standard tree */ \ + override(AABBOptimizedTree) bool Build(AABBTree* tree); \ + /* Refits the tree */ \ + override(AABBOptimizedTree) bool Refit(const MeshInterface* mesh_interface); \ + /* Walks the tree */ \ + override(AABBOptimizedTree) bool Walk(GenericWalkingCallback callback, void* user_data) const; \ + /* Data access */ \ + inline_ const node* GetNodes() const { return mNodes; } \ + /* Stats */ \ + override(AABBOptimizedTree) udword GetUsedBytes() const { return mNbNodes*sizeof(node); } \ + private: \ + node* mNodes; + + typedef bool (*GenericWalkingCallback) (const void* current, void* user_data); + + class OPCODE_API AABBOptimizedTree + { + public: + // Constructor / Destructor + AABBOptimizedTree() : + mNbNodes (0) + {} + virtual ~AABBOptimizedTree() {} + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Builds the collision tree from a generic AABB tree. + * \param tree [in] generic AABB tree + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual bool Build(AABBTree* tree) = 0; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Refits the collision tree after vertices have been modified. + * \param mesh_interface [in] mesh interface for current model + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual bool Refit(const MeshInterface* mesh_interface) = 0; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Walks the tree and call the user back for each node. + * \param callback [in] walking callback + * \param user_data [in] callback's user data + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual bool Walk(GenericWalkingCallback callback, void* user_data) const = 0; + + // Data access + virtual udword GetUsedBytes() const = 0; + inline_ udword GetNbNodes() const { return mNbNodes; } + + protected: + udword mNbNodes; + }; + + class OPCODE_API AABBCollisionTree : public AABBOptimizedTree + { + IMPLEMENT_COLLISION_TREE(AABBCollisionTree, AABBCollisionNode) + }; + + class OPCODE_API AABBNoLeafTree : public AABBOptimizedTree + { + IMPLEMENT_COLLISION_TREE(AABBNoLeafTree, AABBNoLeafNode) + }; + + class OPCODE_API AABBQuantizedTree : public AABBOptimizedTree + { + IMPLEMENT_COLLISION_TREE(AABBQuantizedTree, AABBQuantizedNode) + + public: + Point mCenterCoeff; + Point mExtentsCoeff; + }; + + class OPCODE_API AABBQuantizedNoLeafTree : public AABBOptimizedTree + { + IMPLEMENT_COLLISION_TREE(AABBQuantizedNoLeafTree, AABBQuantizedNoLeafNode) + + public: + Point mCenterCoeff; + Point mExtentsCoeff; + }; + +#endif // __OPC_OPTIMIZEDTREE_H__ diff --git a/libs/ode-0.16.1/OPCODE/OPC_Picking.cpp b/libs/ode-0.16.1/OPCODE/OPC_Picking.cpp new file mode 100644 index 0000000..0f4c6c3 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_Picking.cpp @@ -0,0 +1,183 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code to perform "picking". + * \file OPC_Picking.cpp + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +#ifdef OPC_RAYHIT_CALLBACK + +/* + Possible RayCollider usages: + - boolean query (shadow feeler) + - closest hit + - all hits + - number of intersection (boolean) + +*/ + +bool Opcode::SetupAllHits(RayCollider& collider, CollisionFaces& contacts) +{ + struct Local + { + static void AllContacts(const CollisionFace& hit, void* user_data) + { + CollisionFaces* CF = (CollisionFaces*)user_data; + CF->AddFace(hit); + } + }; + + collider.SetFirstContact(false); + collider.SetHitCallback(Local::AllContacts); + collider.SetUserData(&contacts); + return true; +} + +bool Opcode::SetupClosestHit(RayCollider& collider, CollisionFace& closest_contact) +{ + struct Local + { + static void ClosestContact(const CollisionFace& hit, void* user_data) + { + CollisionFace* CF = (CollisionFace*)user_data; + if(hit.mDistance<CF->mDistance) *CF = hit; + } + }; + + collider.SetFirstContact(false); + collider.SetHitCallback(Local::ClosestContact); + collider.SetUserData(&closest_contact); + closest_contact.mDistance = MAX_FLOAT; + return true; +} + +bool Opcode::SetupShadowFeeler(RayCollider& collider) +{ + collider.SetFirstContact(true); + collider.SetHitCallback(null); + return true; +} + +bool Opcode::SetupInOutTest(RayCollider& collider) +{ + collider.SetFirstContact(false); + collider.SetHitCallback(null); + // Results with collider.GetNbIntersections() + return true; +} + +bool Opcode::Picking( +CollisionFace& picked_face, +const Ray& world_ray, const Model& model, const Matrix4x4* world, +float min_dist, float max_dist, const Point& view_point, CullModeCallback callback, void* user_data) +{ + struct Local + { + struct CullData + { + CollisionFace* Closest; + float MinLimit; + CullModeCallback Callback; + void* UserData; + Point ViewPoint; + const MeshInterface* IMesh; + }; + + // Called for each stabbed face + static void RenderCullingCallback(const CollisionFace& hit, void* user_data) + { + CullData* Data = (CullData*)user_data; + + // Discard face if we already have a closer hit + if(hit.mDistance>=Data->Closest->mDistance) return; + + // Discard face if hit point is smaller than min limit. This mainly happens when the face is in front + // of the near clip plane (or straddles it). If we keep the face nonetheless, the user can select an + // object that he may not even be able to see, which is very annoying. + if(hit.mDistance<=Data->MinLimit) return; + + // This is the index of currently stabbed triangle. + udword StabbedFaceIndex = hit.mFaceID; + + // We may keep it or not, depending on backface culling + bool KeepIt = true; + + // Catch *render* cull mode for this face + CullMode CM = (Data->Callback)(StabbedFaceIndex, Data->UserData); + + if(CM!=CULLMODE_NONE) // Don't even compute culling for double-sided triangles + { + // Compute backface culling for current face + + VertexPointers VP; + ConversionArea VC; + Data->IMesh->GetTriangle(VP, StabbedFaceIndex, VC); + if(VP.BackfaceCulling(Data->ViewPoint)) + { + if(CM==CULLMODE_CW) KeepIt = false; + } + else + { + if(CM==CULLMODE_CCW) KeepIt = false; + } + } + + if(KeepIt) *Data->Closest = hit; + } + }; + + RayCollider RC; + RC.SetMaxDist(max_dist); + RC.SetTemporalCoherence(false); + RC.SetCulling(false); // We need all faces since some of them can be double-sided + RC.SetFirstContact(false); + RC.SetHitCallback(Local::RenderCullingCallback); + + picked_face.mFaceID = INVALID_ID; + picked_face.mDistance = MAX_FLOAT; + picked_face.mU = 0.0f; + picked_face.mV = 0.0f; + + Local::CullData Data; + Data.Closest = &picked_face; + Data.MinLimit = min_dist; + Data.Callback = callback; + Data.UserData = user_data; + Data.ViewPoint = view_point; + Data.IMesh = model.GetMeshInterface(); + + if(world) + { + // Get matrices + Matrix4x4 InvWorld; + InvertPRMatrix(InvWorld, *world); + + // Compute camera position in mesh space + Data.ViewPoint *= InvWorld; + } + + RC.SetUserData(&Data); + if(RC.Collide(world_ray, model, world)) + { + return picked_face.mFaceID!=INVALID_ID; + } + return false; +} + +#endif diff --git a/libs/ode-0.16.1/OPCODE/OPC_Picking.h b/libs/ode-0.16.1/OPCODE/OPC_Picking.h new file mode 100644 index 0000000..d22fa38 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_Picking.h @@ -0,0 +1,45 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code to perform "picking". + * \file OPC_Picking.h + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_PICKING_H__ +#define __OPC_PICKING_H__ + +#ifdef OPC_RAYHIT_CALLBACK + + enum CullMode + { + CULLMODE_NONE = 0, + CULLMODE_CW = 1, + CULLMODE_CCW = 2 + }; + + typedef CullMode (*CullModeCallback)(udword triangle_index, void* user_data); + + OPCODE_API bool SetupAllHits (RayCollider& collider, CollisionFaces& contacts); + OPCODE_API bool SetupClosestHit (RayCollider& collider, CollisionFace& closest_contact); + OPCODE_API bool SetupShadowFeeler (RayCollider& collider); + OPCODE_API bool SetupInOutTest (RayCollider& collider); + + OPCODE_API bool Picking( + CollisionFace& picked_face, + const Ray& world_ray, const Model& model, const Matrix4x4* world, + float min_dist, float max_dist, const Point& view_point, CullModeCallback callback, void* user_data); +#endif + +#endif //__OPC_PICKING_H__ diff --git a/libs/ode-0.16.1/OPCODE/OPC_PlanesAABBOverlap.h b/libs/ode-0.16.1/OPCODE/OPC_PlanesAABBOverlap.h new file mode 100644 index 0000000..5d7576e --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_PlanesAABBOverlap.h @@ -0,0 +1,50 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Planes-AABB overlap test. + * - original code by Ville Miettinen, from Umbra/dPVS (released on the GD-Algorithms mailing list) + * - almost used "as-is", I even left the comments (hence the frustum-related notes) + * + * \param center [in] box center + * \param extents [in] box extents + * \param out_clip_mask [out] bitmask for active planes + * \param in_clip_mask [in] bitmask for active planes + * \return TRUE if boxes overlap planes + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL PlanesCollider::PlanesAABBOverlap(const Point& center, const Point& extents, udword& out_clip_mask, udword in_clip_mask) +{ + // Stats + mNbVolumeBVTests++; + + const Plane* p = mPlanes; + + // Evaluate through all active frustum planes. We determine the relation + // between the AABB and a plane by using the concept of "near" and "far" + // vertices originally described by Zhang (and later by Möller). Our + // variant here uses 3 fabs ops, 6 muls, 7 adds and two floating point + // comparisons per plane. The routine early-exits if the AABB is found + // to be outside any of the planes. The loop also constructs a new output + // clip mask. Most FPUs have a native single-cycle fabsf() operation. + + udword Mask = 1; // current mask index (1,2,4,8,..) + udword TmpOutClipMask = 0; // initialize output clip mask into empty. + + while(Mask<=in_clip_mask) // keep looping while we have active planes left... + { + if(in_clip_mask & Mask) // if clip plane is active, process it.. + { + float NP = extents.x*fabsf(p->n.x) + extents.y*fabsf(p->n.y) + extents.z*fabsf(p->n.z); // ### fabsf could be precomputed + float MP = center.x*p->n.x + center.y*p->n.y + center.z*p->n.z + p->d; + + if(NP < MP) // near vertex behind the clip plane... + return FALSE; // .. so there is no intersection.. + if((-NP) < MP) // near and far vertices on different sides of plane.. + TmpOutClipMask |= Mask; // .. so update the clip mask... + } + Mask+=Mask; // mk = (1<<plane) + p++; // advance to next plane + } + + out_clip_mask = TmpOutClipMask; // copy output value (temp used to resolve aliasing!) + return TRUE; // indicate that AABB intersects frustum +} diff --git a/libs/ode-0.16.1/OPCODE/OPC_PlanesCollider.cpp b/libs/ode-0.16.1/OPCODE/OPC_PlanesCollider.cpp new file mode 100644 index 0000000..ac12042 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_PlanesCollider.cpp @@ -0,0 +1,653 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for a planes collider. + * \file OPC_PlanesCollider.cpp + * \author Pierre Terdiman + * \date January, 1st, 2002 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a Planes-vs-tree collider. + * + * \class PlanesCollider + * \author Pierre Terdiman + * \version 1.3 + * \date January, 1st, 2002 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +#include "OPC_PlanesAABBOverlap.h" +#include "OPC_PlanesTriOverlap.h" + +#define SET_CONTACT(prim_index, flag) \ + /* Set contact status */ \ + mFlags |= flag; \ + mTouchedPrimitives->Add(udword(prim_index)); + +//! Planes-triangle test +#define PLANES_PRIM(prim_index, flag) \ + /* Request vertices from the app */ \ + mIMesh->GetTriangle(mVP, prim_index, mVC); \ + /* Perform triangle-box overlap test */ \ + if(PlanesTriOverlap(clip_mask)) \ + { \ + SET_CONTACT(prim_index, flag) \ + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +PlanesCollider::PlanesCollider() : + mNbPlanes (0), + mPlanes (null) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +PlanesCollider::~PlanesCollider() +{ + DELETEARRAY(mPlanes); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Validates current settings. You should call this method after all the settings and callbacks have been defined. + * \return null if everything is ok, else a string describing the problem + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +const char* PlanesCollider::ValidateSettings() +{ + if(TemporalCoherenceEnabled() && !FirstContactEnabled()) return "Temporal coherence only works with ""First contact"" mode!"; + + return VolumeCollider::ValidateSettings(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Generic collision query for generic OPCODE models. After the call, access the results: + * - with GetContactStatus() + * - with GetNbTouchedPrimitives() + * - with GetTouchedPrimitives() + * + * \param cache [in/out] a planes cache + * \param planes [in] list of planes in world space + * \param nb_planes [in] number of planes + * \param model [in] Opcode model to collide with + * \param worldm [in] model's world matrix, or null + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool PlanesCollider::Collide(PlanesCache& cache, const Plane* planes, udword nb_planes, const Model& model, const Matrix4x4* worldm) +{ + // Checkings + if(!Setup(&model)) return false; + + // Init collision query + if(InitQuery(cache, planes, nb_planes, worldm)) return true; + + udword PlaneMask = (1<<nb_planes)-1; + + if(!model.HasLeafNodes()) + { + if(model.IsQuantized()) + { + const AABBQuantizedNoLeafTree* Tree = static_cast<const AABBQuantizedNoLeafTree *>(model.GetTree()); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes(), PlaneMask); + else _Collide(Tree->GetNodes(), PlaneMask); + } + else + { + const AABBNoLeafTree* Tree = static_cast<const AABBNoLeafTree *>(model.GetTree()); + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes(), PlaneMask); + else _Collide(Tree->GetNodes(), PlaneMask); + } + } + else + { + if(model.IsQuantized()) + { + const AABBQuantizedTree* Tree = static_cast<const AABBQuantizedTree *>(model.GetTree()); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes(), PlaneMask); + else _Collide(Tree->GetNodes(), PlaneMask); + } + else + { + const AABBCollisionTree* Tree = static_cast<const AABBCollisionTree *>(model.GetTree()); + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes(), PlaneMask); + else _Collide(Tree->GetNodes(), PlaneMask); + } + } + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Initializes a collision query : + * - reset stats & contact status + * - compute planes in model space + * - check temporal coherence + * + * \param cache [in/out] a planes cache + * \param planes [in] list of planes + * \param nb_planes [in] number of planes + * \param worldm [in] model's world matrix, or null + * \return TRUE if we can return immediately + * \warning SCALE NOT SUPPORTED. The matrix must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +BOOL PlanesCollider::InitQuery(PlanesCache& cache, const Plane* planes, udword nb_planes, const Matrix4x4* worldm) +{ + // 1) Call the base method + VolumeCollider::InitQuery(); + + // 2) Compute planes in model space + if(nb_planes>mNbPlanes) + { + DELETEARRAY(mPlanes); + mPlanes = new Plane[nb_planes]; + } + mNbPlanes = nb_planes; + + if(worldm) + { + Matrix4x4 InvWorldM; + InvertPRMatrix(InvWorldM, *worldm); + +// for(udword i=0;i<nb_planes;i++) mPlanes[i] = planes[i] * InvWorldM; + for(udword i=0;i<nb_planes;i++) TransformPlane(mPlanes[i], planes[i], InvWorldM); + } + else CopyMemory(mPlanes, planes, nb_planes*sizeof(Plane)); + + // 3) Setup destination pointer + mTouchedPrimitives = &cache.TouchedPrimitives; + + // 4) Special case: 1-triangle meshes [Opcode 1.3] + if(mCurrentModel && mCurrentModel->HasSingleNode()) + { + if(!SkipPrimitiveTests()) + { + // We simply perform the BV-Prim overlap test each time. We assume single triangle has index 0. + mTouchedPrimitives->Reset(); + + // Perform overlap test between the unique triangle and the planes (and set contact status if needed) + udword clip_mask = (1<<mNbPlanes)-1; + PLANES_PRIM(udword(0), OPC_CONTACT) + + // Return immediately regardless of status + return TRUE; + } + } + + // 4) Check temporal coherence: + if(TemporalCoherenceEnabled()) + { + // Here we use temporal coherence + // => check results from previous frame before performing the collision query + if(FirstContactEnabled()) + { + // We're only interested in the first contact found => test the unique previously touched face + if(mTouchedPrimitives->GetNbEntries()) + { + // Get index of previously touched face = the first entry in the array + udword PreviouslyTouchedFace = mTouchedPrimitives->GetEntry(0); + + // Then reset the array: + // - if the overlap test below is successful, the index we'll get added back anyway + // - if it isn't, then the array should be reset anyway for the normal query + mTouchedPrimitives->Reset(); + + // Perform overlap test between the cached triangle and the planes (and set contact status if needed) + udword clip_mask = (1<<mNbPlanes)-1; + PLANES_PRIM(PreviouslyTouchedFace, OPC_TEMPORAL_CONTACT) + + // Return immediately if possible + if(GetContactStatus()) return TRUE; + } + // else no face has been touched during previous query + // => we'll have to perform a normal query + } + else mTouchedPrimitives->Reset(); + } + else + { + // Here we don't use temporal coherence => do a normal query + mTouchedPrimitives->Reset(); + } + + return FALSE; +} + +#define TEST_CLIP_MASK \ + /* If the box is completely included, so are its children. We don't need to do extra tests, we */ \ + /* can immediately output a list of visible children. Those ones won't need to be clipped. */ \ + if(!OutClipMask) \ + { \ + /* Set contact status */ \ + mFlags |= OPC_CONTACT; \ + _Dump(node); \ + return; \ + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for normal AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void PlanesCollider::_Collide(const AABBCollisionNode* node, udword clip_mask) +{ + // Test the box against the planes. If the box is completely culled, so are its children, hence we exit. + udword OutClipMask; + if(!PlanesAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents, OutClipMask, clip_mask)) return; + + TEST_CLIP_MASK + + // Else the box straddles one or several planes, so we need to recurse down the tree. + if(node->IsLeaf()) + { + PLANES_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _Collide(node->GetPos(), OutClipMask); + + if(ContactFound()) return; + + _Collide(node->GetNeg(), OutClipMask); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for normal AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void PlanesCollider::_CollideNoPrimitiveTest(const AABBCollisionNode* node, udword clip_mask) +{ + // Test the box against the planes. If the box is completely culled, so are its children, hence we exit. + udword OutClipMask; + if(!PlanesAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents, OutClipMask, clip_mask)) return; + + TEST_CLIP_MASK + + // Else the box straddles one or several planes, so we need to recurse down the tree. + if(node->IsLeaf()) + { + SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _CollideNoPrimitiveTest(node->GetPos(), OutClipMask); + + if(ContactFound()) return; + + _CollideNoPrimitiveTest(node->GetNeg(), OutClipMask); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void PlanesCollider::_Collide(const AABBQuantizedNode* node, udword clip_mask) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Test the box against the planes. If the box is completely culled, so are its children, hence we exit. + udword OutClipMask; + if(!PlanesAABBOverlap(Center, Extents, OutClipMask, clip_mask)) return; + + TEST_CLIP_MASK + + // Else the box straddles one or several planes, so we need to recurse down the tree. + if(node->IsLeaf()) + { + PLANES_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _Collide(node->GetPos(), OutClipMask); + + if(ContactFound()) return; + + _Collide(node->GetNeg(), OutClipMask); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void PlanesCollider::_CollideNoPrimitiveTest(const AABBQuantizedNode* node, udword clip_mask) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Test the box against the planes. If the box is completely culled, so are its children, hence we exit. + udword OutClipMask; + if(!PlanesAABBOverlap(Center, Extents, OutClipMask, clip_mask)) return; + + TEST_CLIP_MASK + + // Else the box straddles one or several planes, so we need to recurse down the tree. + if(node->IsLeaf()) + { + SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _CollideNoPrimitiveTest(node->GetPos(), OutClipMask); + + if(ContactFound()) return; + + _CollideNoPrimitiveTest(node->GetNeg(), OutClipMask); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void PlanesCollider::_Collide(const AABBNoLeafNode* node, udword clip_mask) +{ + // Test the box against the planes. If the box is completely culled, so are its children, hence we exit. + udword OutClipMask; + if(!PlanesAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents, OutClipMask, clip_mask)) return; + + TEST_CLIP_MASK + + // Else the box straddles one or several planes, so we need to recurse down the tree. + if(node->HasPosLeaf()) { PLANES_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } + else _Collide(node->GetPos(), OutClipMask); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { PLANES_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } + else _Collide(node->GetNeg(), OutClipMask); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void PlanesCollider::_CollideNoPrimitiveTest(const AABBNoLeafNode* node, udword clip_mask) +{ + // Test the box against the planes. If the box is completely culled, so are its children, hence we exit. + udword OutClipMask; + if(!PlanesAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents, OutClipMask, clip_mask)) return; + + TEST_CLIP_MASK + + // Else the box straddles one or several planes, so we need to recurse down the tree. + if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetPos(), OutClipMask); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetNeg(), OutClipMask); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void PlanesCollider::_Collide(const AABBQuantizedNoLeafNode* node, udword clip_mask) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Test the box against the planes. If the box is completely culled, so are its children, hence we exit. + udword OutClipMask; + if(!PlanesAABBOverlap(Center, Extents, OutClipMask, clip_mask)) return; + + TEST_CLIP_MASK + + // Else the box straddles one or several planes, so we need to recurse down the tree. + if(node->HasPosLeaf()) { PLANES_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } + else _Collide(node->GetPos(), OutClipMask); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { PLANES_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } + else _Collide(node->GetNeg(), OutClipMask); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void PlanesCollider::_CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node, udword clip_mask) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Test the box against the planes. If the box is completely culled, so are its children, hence we exit. + udword OutClipMask; + if(!PlanesAABBOverlap(Center, Extents, OutClipMask, clip_mask)) return; + + TEST_CLIP_MASK + + // Else the box straddles one or several planes, so we need to recurse down the tree. + if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetPos(), OutClipMask); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetNeg(), OutClipMask); +} + + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HybridPlanesCollider::HybridPlanesCollider() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HybridPlanesCollider::~HybridPlanesCollider() +{ +} + +bool HybridPlanesCollider::Collide(PlanesCache& cache, const Plane* planes, udword nb_planes, const HybridModel& model, const Matrix4x4* worldm) +{ + // We don't want primitive tests here! + mFlags |= OPC_NO_PRIMITIVE_TESTS; + + // Checkings + if(!Setup(&model)) return false; + + // Init collision query + if(InitQuery(cache, planes, nb_planes, worldm)) return true; + + // Special case for 1-leaf trees + if(mCurrentModel && mCurrentModel->HasSingleNode()) + { + // Here we're supposed to perform a normal query, except our tree has a single node, i.e. just a few triangles + udword Nb = mIMesh->GetNbTriangles(); + + // Loop through all triangles + udword clip_mask = (1<<mNbPlanes)-1; + for(udword i=0;i<Nb;i++) + { + PLANES_PRIM(i, OPC_CONTACT) + } + return true; + } + + // Override destination array since we're only going to get leaf boxes here + mTouchedBoxes.Reset(); + mTouchedPrimitives = &mTouchedBoxes; + + udword PlaneMask = (1<<nb_planes)-1; + + // Now, do the actual query against leaf boxes + if(!model.HasLeafNodes()) + { + if(model.IsQuantized()) + { + const AABBQuantizedNoLeafTree* Tree = static_cast<const AABBQuantizedNoLeafTree *>(model.GetTree()); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes(), PlaneMask); + } + else + { + const AABBNoLeafTree* Tree = static_cast<const AABBNoLeafTree *>(model.GetTree()); + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes(), PlaneMask); + } + } + else + { + if(model.IsQuantized()) + { + const AABBQuantizedTree* Tree = static_cast<const AABBQuantizedTree *>(model.GetTree()); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes(), PlaneMask); + } + else + { + const AABBCollisionTree* Tree = static_cast<const AABBCollisionTree *>(model.GetTree()); + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes(), PlaneMask); + } + } + + // We only have a list of boxes so far + if(GetContactStatus()) + { + // Reset contact status, since it currently only reflects collisions with leaf boxes + Collider::InitQuery(); + + // Change dest container so that we can use built-in overlap tests and get collided primitives + cache.TouchedPrimitives.Reset(); + mTouchedPrimitives = &cache.TouchedPrimitives; + + // Read touched leaf boxes + udword Nb = mTouchedBoxes.GetNbEntries(); + const udword* Touched = mTouchedBoxes.GetEntries(); + + const LeafTriangles* LT = model.GetLeafTriangles(); + const udword* Indices = model.GetIndices(); + + // Loop through touched leaves + udword clip_mask = (1<<mNbPlanes)-1; + while(Nb--) + { + const LeafTriangles& CurrentLeaf = LT[*Touched++]; + + // Each leaf box has a set of triangles + udword NbTris = CurrentLeaf.GetNbTriangles(); + if(Indices) + { + const udword* T = &Indices[CurrentLeaf.GetTriangleIndex()]; + + // Loop through triangles and test each of them + while(NbTris--) + { + udword TriangleIndex = *T++; + PLANES_PRIM(TriangleIndex, OPC_CONTACT) + } + } + else + { + udword BaseIndex = CurrentLeaf.GetTriangleIndex(); + + // Loop through triangles and test each of them + while(NbTris--) + { + udword TriangleIndex = BaseIndex++; + PLANES_PRIM(TriangleIndex, OPC_CONTACT) + } + } + } + } + + return true; +} diff --git a/libs/ode-0.16.1/OPCODE/OPC_PlanesCollider.h b/libs/ode-0.16.1/OPCODE/OPC_PlanesCollider.h new file mode 100644 index 0000000..872f8c5 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_PlanesCollider.h @@ -0,0 +1,122 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for a planes collider. + * \file OPC_PlanesCollider.h + * \author Pierre Terdiman + * \date January, 1st, 2002 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_PLANESCOLLIDER_H__ +#define __OPC_PLANESCOLLIDER_H__ + + struct OPCODE_API PlanesCache : VolumeCache + { + PlanesCache() + { + } + }; + + class OPCODE_API PlanesCollider : public VolumeCollider + { + public: + // Constructor / Destructor + PlanesCollider(); + virtual ~PlanesCollider(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Generic collision query for generic OPCODE models. After the call, access the results: + * - with GetContactStatus() + * - with GetNbTouchedPrimitives() + * - with GetTouchedPrimitives() + * + * \param cache [in/out] a planes cache + * \param planes [in] list of planes in world space + * \param nb_planes [in] number of planes + * \param model [in] Opcode model to collide with + * \param worldm [in] model's world matrix, or null + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool Collide(PlanesCache& cache, const Plane* planes, udword nb_planes, const Model& model, const Matrix4x4* worldm=null); + + // Mutant box-with-planes collision queries + inline_ bool Collide(PlanesCache& cache, const OBB& box, const Model& model, const Matrix4x4* worldb=null, const Matrix4x4* worldm=null) + { + Plane PL[6]; + + if(worldb) + { + // Create a new OBB in world space + OBB WorldBox; + box.Rotate(*worldb, WorldBox); + // Compute planes from the sides of the box + WorldBox.ComputePlanes(PL); + } + else + { + // Compute planes from the sides of the box + box.ComputePlanes(PL); + } + + // Collide with box planes + return Collide(cache, PL, 6, model, worldm); + } + // Settings + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Validates current settings. You should call this method after all the settings and callbacks have been defined for a collider. + * \return null if everything is ok, else a string describing the problem + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(Collider) const char* ValidateSettings(); + + protected: + // Planes in model space + udword mNbPlanes; + Plane* mPlanes; + // Leaf description + VertexPointers mVP; + ConversionArea mVC; + // Internal methods + void _Collide(const AABBCollisionNode* node, udword clip_mask); + void _Collide(const AABBNoLeafNode* node, udword clip_mask); + void _Collide(const AABBQuantizedNode* node, udword clip_mask); + void _Collide(const AABBQuantizedNoLeafNode* node, udword clip_mask); + void _CollideNoPrimitiveTest(const AABBCollisionNode* node, udword clip_mask); + void _CollideNoPrimitiveTest(const AABBNoLeafNode* node, udword clip_mask); + void _CollideNoPrimitiveTest(const AABBQuantizedNode* node, udword clip_mask); + void _CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node, udword clip_mask); + // Overlap tests + inline_ BOOL PlanesAABBOverlap(const Point& center, const Point& extents, udword& out_clip_mask, udword in_clip_mask); + inline_ BOOL PlanesTriOverlap(udword in_clip_mask); + // Init methods + BOOL InitQuery(PlanesCache& cache, const Plane* planes, udword nb_planes, const Matrix4x4* worldm=null); + }; + + class OPCODE_API HybridPlanesCollider : public PlanesCollider + { + public: + // Constructor / Destructor + HybridPlanesCollider(); + virtual ~HybridPlanesCollider(); + + bool Collide(PlanesCache& cache, const Plane* planes, udword nb_planes, const HybridModel& model, const Matrix4x4* worldm=null); + protected: + Container mTouchedBoxes; + }; + +#endif // __OPC_PLANESCOLLIDER_H__ diff --git a/libs/ode-0.16.1/OPCODE/OPC_PlanesTriOverlap.h b/libs/ode-0.16.1/OPCODE/OPC_PlanesTriOverlap.h new file mode 100644 index 0000000..3f9b39f --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_PlanesTriOverlap.h @@ -0,0 +1,40 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Planes-triangle overlap test. + * \param in_clip_mask [in] bitmask for active planes + * \return TRUE if triangle overlap planes + * \warning THIS IS A CONSERVATIVE TEST !! Some triangles will be returned as intersecting, while they're not! + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL PlanesCollider::PlanesTriOverlap(udword in_clip_mask) +{ + // Stats + mNbVolumePrimTests++; + + const Plane* p = mPlanes; + udword Mask = 1; + + while(Mask<=in_clip_mask) + { + if(in_clip_mask & Mask) + { + float d0 = p->Distance(*mVP.Vertex[0]); + float d1 = p->Distance(*mVP.Vertex[1]); + float d2 = p->Distance(*mVP.Vertex[2]); + if(d0>0.0f && d1>0.0f && d2>0.0f) return FALSE; +// if(!(IR(d0)&SIGN_BITMASK) && !(IR(d1)&SIGN_BITMASK) && !(IR(d2)&SIGN_BITMASK)) return FALSE; + } + Mask+=Mask; + p++; + } +/* + for(udword i=0;i<6;i++) + { + float d0 = p[i].Distance(mLeafVerts[0]); + float d1 = p[i].Distance(mLeafVerts[1]); + float d2 = p[i].Distance(mLeafVerts[2]); + if(d0>0.0f && d1>0.0f && d2>0.0f) return false; + } +*/ + return TRUE; +} diff --git a/libs/ode-0.16.1/OPCODE/OPC_RayAABBOverlap.h b/libs/ode-0.16.1/OPCODE/OPC_RayAABBOverlap.h new file mode 100644 index 0000000..a8162bf --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_RayAABBOverlap.h @@ -0,0 +1,63 @@ +// Opcode 1.1: ray-AABB overlap tests based on Woo's code +// Opcode 1.2: ray-AABB overlap tests based on the separating axis theorem +// +// The point of intersection is not computed anymore. The distance to impact is not needed anymore +// since we now have two different queries for segments or rays. + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes a segment-AABB overlap test using the separating axis theorem. Segment is cached within the class. + * \param center [in] AABB center + * \param extents [in] AABB extents + * \return true on overlap + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL RayCollider::SegmentAABBOverlap(const Point& center, const Point& extents) +{ + // Stats + mNbRayBVTests++; + + float Dx = mData2.x - center.x; if(fabsf(Dx) > extents.x + mFDir.x) return FALSE; + float Dy = mData2.y - center.y; if(fabsf(Dy) > extents.y + mFDir.y) return FALSE; + float Dz = mData2.z - center.z; if(fabsf(Dz) > extents.z + mFDir.z) return FALSE; + + float f; + f = mData.y * Dz - mData.z * Dy; if(fabsf(f) > extents.y*mFDir.z + extents.z*mFDir.y) return FALSE; + f = mData.z * Dx - mData.x * Dz; if(fabsf(f) > extents.x*mFDir.z + extents.z*mFDir.x) return FALSE; + f = mData.x * Dy - mData.y * Dx; if(fabsf(f) > extents.x*mFDir.y + extents.y*mFDir.x) return FALSE; + + return TRUE; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes a ray-AABB overlap test using the separating axis theorem. Ray is cached within the class. + * \param center [in] AABB center + * \param extents [in] AABB extents + * \return true on overlap + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL RayCollider::RayAABBOverlap(const Point& center, const Point& extents) +{ + // Stats + mNbRayBVTests++; + +// float Dx = mOrigin.x - center.x; if(fabsf(Dx) > extents.x && Dx*mDir.x>=0.0f) return FALSE; +// float Dy = mOrigin.y - center.y; if(fabsf(Dy) > extents.y && Dy*mDir.y>=0.0f) return FALSE; +// float Dz = mOrigin.z - center.z; if(fabsf(Dz) > extents.z && Dz*mDir.z>=0.0f) return FALSE; + + float Dx = mOrigin.x - center.x; if(GREATER(Dx, extents.x) && Dx*mDir.x>=0.0f) return FALSE; + float Dy = mOrigin.y - center.y; if(GREATER(Dy, extents.y) && Dy*mDir.y>=0.0f) return FALSE; + float Dz = mOrigin.z - center.z; if(GREATER(Dz, extents.z) && Dz*mDir.z>=0.0f) return FALSE; + +// float Dx = mOrigin.x - center.x; if(GREATER(Dx, extents.x) && ((SIR(Dx)-1)^SIR(mDir.x))>=0.0f) return FALSE; +// float Dy = mOrigin.y - center.y; if(GREATER(Dy, extents.y) && ((SIR(Dy)-1)^SIR(mDir.y))>=0.0f) return FALSE; +// float Dz = mOrigin.z - center.z; if(GREATER(Dz, extents.z) && ((SIR(Dz)-1)^SIR(mDir.z))>=0.0f) return FALSE; + + float f; + f = mDir.y * Dz - mDir.z * Dy; if(fabsf(f) > extents.y*mFDir.z + extents.z*mFDir.y) return FALSE; + f = mDir.z * Dx - mDir.x * Dz; if(fabsf(f) > extents.x*mFDir.z + extents.z*mFDir.x) return FALSE; + f = mDir.x * Dy - mDir.y * Dx; if(fabsf(f) > extents.x*mFDir.y + extents.y*mFDir.x) return FALSE; + + return TRUE; +} diff --git a/libs/ode-0.16.1/OPCODE/OPC_RayCollider.cpp b/libs/ode-0.16.1/OPCODE/OPC_RayCollider.cpp new file mode 100644 index 0000000..6a81857 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_RayCollider.cpp @@ -0,0 +1,764 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for a ray collider. + * \file OPC_RayCollider.cpp + * \author Pierre Terdiman + * \date June, 2, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a ray-vs-tree collider. + * This class performs a stabbing query on an AABB tree, i.e. does a ray-mesh collision. + * + * HIGHER DISTANCE BOUND: + * + * If P0 and P1 are two 3D points, let's define: + * - d = distance between P0 and P1 + * - Origin = P0 + * - Direction = (P1 - P0) / d = normalized direction vector + * - A parameter t such as a point P on the line (P0,P1) is P = Origin + t * Direction + * - t = 0 --> P = P0 + * - t = d --> P = P1 + * + * Then we can define a general "ray" as: + * + * struct Ray + * { + * Point Origin; + * Point Direction; + * }; + * + * But it actually maps three different things: + * - a segment, when 0 <= t <= d + * - a half-line, when 0 <= t < +infinity, or -infinity < t <= d + * - a line, when -infinity < t < +infinity + * + * In Opcode, we support segment queries, which yield half-line queries by setting d = +infinity. + * We don't support line-queries. If you need them, shift the origin along the ray by an appropriate margin. + * + * In short, the lower bound is always 0, and you can setup the higher bound "d" with RayCollider::SetMaxDist(). + * + * Query |segment |half-line |line + * --------|-------------------|---------------|---------------- + * Usages |-shadow feelers |-raytracing |- + * |-sweep tests |-in/out tests | + * + * FIRST CONTACT: + * + * - You can setup "first contact" mode or "all contacts" mode with RayCollider::SetFirstContact(). + * - In "first contact" mode we return as soon as the ray hits one face. If can be useful e.g. for shadow feelers, where + * you want to know whether the path to the light is free or not (a boolean answer is enough). + * - In "all contacts" mode we return all faces hit by the ray. + * + * TEMPORAL COHERENCE: + * + * - You can enable or disable temporal coherence with RayCollider::SetTemporalCoherence(). + * - It currently only works in "first contact" mode. + * - If temporal coherence is enabled, the previously hit triangle is cached during the first query. Then, next queries + * start by colliding the ray against the cached triangle. If they still collide, we return immediately. + * + * CLOSEST HIT: + * + * - You can enable or disable "closest hit" with RayCollider::SetClosestHit(). + * - It currently only works in "all contacts" mode. + * - If closest hit is enabled, faces are sorted by distance on-the-fly and the closest one only is reported. + * + * BACKFACE CULLING: + * + * - You can enable or disable backface culling with RayCollider::SetCulling(). + * - If culling is enabled, ray will not hit back faces (only front faces). + * + * + * + * \class RayCollider + * \author Pierre Terdiman + * \version 1.3 + * \date June, 2, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * This class describes a face hit by a ray or segment. + * This is a particular class dedicated to stabbing queries. + * + * \class CollisionFace + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * This class is a dedicated collection of CollisionFace. + * + * \class CollisionFaces + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +#include "OPC_RayAABBOverlap.h" +#include "OPC_RayTriOverlap.h" + +#define SET_CONTACT(prim_index, flag) \ + mNbIntersections++; \ + /* Set contact status */ \ + mFlags |= flag; \ + /* In any case the contact has been found and recorded in mStabbedFace */ \ + mStabbedFace.mFaceID = prim_index; + +#ifdef OPC_RAYHIT_CALLBACK + + #define HANDLE_CONTACT(prim_index, flag) \ + SET_CONTACT(prim_index, flag) \ + \ + if(mHitCallback) (mHitCallback)(mStabbedFace, mUserData); + + #define UPDATE_CACHE \ + if(cache && GetContactStatus()) \ + { \ + *cache = mStabbedFace.mFaceID; \ + } +#else + + #define HANDLE_CONTACT(prim_index, flag) \ + SET_CONTACT(prim_index, flag) \ + \ + /* Now we can also record it in mStabbedFaces if available */ \ + if(mStabbedFaces) \ + { \ + /* If we want all faces or if that's the first one we hit */ \ + if(!mClosestHit || !mStabbedFaces->GetNbFaces()) \ + { \ + mStabbedFaces->AddFace(mStabbedFace); \ + } \ + else \ + { \ + /* We only keep closest hit */ \ + CollisionFace* Current = const_cast<CollisionFace*>(mStabbedFaces->GetFaces()); \ + if(Current && mStabbedFace.mDistance<Current->mDistance) \ + { \ + *Current = mStabbedFace; \ + } \ + } \ + } + + #define UPDATE_CACHE \ + if(cache && GetContactStatus() && mStabbedFaces) \ + { \ + const CollisionFace* Current = mStabbedFaces->GetFaces(); \ + if(Current) *cache = Current->mFaceID; \ + else *cache = INVALID_ID; \ + } +#endif + +#define SEGMENT_PRIM(prim_index, flag) \ + /* Request vertices from the app */ \ + VertexPointers VP; ConversionArea VC; mIMesh->GetTriangle(VP, prim_index, VC); \ + \ + /* Perform ray-tri overlap test and return */ \ + if(RayTriOverlap(*VP.Vertex[0], *VP.Vertex[1], *VP.Vertex[2])) \ + { \ + /* Intersection point is valid if dist < segment's length */ \ + /* We know dist>0 so we can use integers */ \ + if(IR(mStabbedFace.mDistance)<IR(mMaxDist)) \ + { \ + HANDLE_CONTACT(prim_index, flag) \ + } \ + } + +#define RAY_PRIM(prim_index, flag) \ + /* Request vertices from the app */ \ + VertexPointers VP; ConversionArea VC; mIMesh->GetTriangle(VP, prim_index, VC); \ + \ + /* Perform ray-tri overlap test and return */ \ + if(RayTriOverlap(*VP.Vertex[0], *VP.Vertex[1], *VP.Vertex[2])) \ + { \ + HANDLE_CONTACT(prim_index, flag) \ + } + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +RayCollider::RayCollider() : +#ifdef OPC_RAYHIT_CALLBACK + mHitCallback (null), + mUserData (0), +#else + mStabbedFaces (null), + mClosestHit (false), +#endif + mNbRayBVTests (0), + mNbRayPrimTests (0), + mNbIntersections (0), + mMaxDist (MAX_FLOAT), + mCulling (true) + +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +RayCollider::~RayCollider() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Validates current settings. You should call this method after all the settings and callbacks have been defined. + * \return null if everything is ok, else a string describing the problem + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +const char* RayCollider::ValidateSettings() +{ + if(mMaxDist<0.0f) return "Higher distance bound must be positive!"; + if(TemporalCoherenceEnabled() && !FirstContactEnabled()) return "Temporal coherence only works with ""First contact"" mode!"; +#ifndef OPC_RAYHIT_CALLBACK + if(mClosestHit && FirstContactEnabled()) return "Closest hit doesn't work with ""First contact"" mode!"; + if(TemporalCoherenceEnabled() && mClosestHit) return "Temporal coherence can't guarantee to report closest hit!"; +#endif + if(SkipPrimitiveTests()) return "SkipPrimitiveTests not possible for RayCollider ! (not implemented)"; + return null; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Generic stabbing query for generic OPCODE models. After the call, access the results: + * - with GetContactStatus() + * - in the user-provided destination array + * + * \param world_ray [in] stabbing ray in world space + * \param model [in] Opcode model to collide with + * \param world [in] model's world matrix, or null + * \param cache [in] a possibly cached face index, or null + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool RayCollider::Collide(const Ray& world_ray, const Model& model, const Matrix4x4* world, udword* cache) +{ + // Checkings + if(!Setup(&model)) return false; + + // Init collision query + if(InitQuery(world_ray, world, cache)) return true; + + if(!model.HasLeafNodes()) + { + if(model.IsQuantized()) + { + const AABBQuantizedNoLeafTree* Tree = static_cast<const AABBQuantizedNoLeafTree *>(model.GetTree()); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform stabbing query + if(IR(mMaxDist)!=IEEE_MAX_FLOAT) _SegmentStab(Tree->GetNodes()); + else _RayStab(Tree->GetNodes()); + } + else + { + const AABBNoLeafTree* Tree = static_cast<const AABBNoLeafTree *>(model.GetTree()); + + // Perform stabbing query + if(IR(mMaxDist)!=IEEE_MAX_FLOAT) _SegmentStab(Tree->GetNodes()); + else _RayStab(Tree->GetNodes()); + } + } + else + { + if(model.IsQuantized()) + { + const AABBQuantizedTree* Tree = static_cast<const AABBQuantizedTree *>(model.GetTree()); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform stabbing query + if(IR(mMaxDist)!=IEEE_MAX_FLOAT) _SegmentStab(Tree->GetNodes()); + else _RayStab(Tree->GetNodes()); + } + else + { + const AABBCollisionTree* Tree = static_cast<const AABBCollisionTree *>(model.GetTree()); + + // Perform stabbing query + if(IR(mMaxDist)!=IEEE_MAX_FLOAT) _SegmentStab(Tree->GetNodes()); + else _RayStab(Tree->GetNodes()); + } + } + + // Update cache if needed + UPDATE_CACHE; + return true; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Initializes a stabbing query : + * - reset stats & contact status + * - compute ray in local space + * - check temporal coherence + * + * \param world_ray [in] stabbing ray in world space + * \param world [in] object's world matrix, or null + * \param face_id [in] index of previously stabbed triangle + * \return TRUE if we can return immediately + * \warning SCALE NOT SUPPORTED. The matrix must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +BOOL RayCollider::InitQuery(const Ray& world_ray, const Matrix4x4* world, udword* face_id) +{ + // Reset stats & contact status + Collider::InitQuery(); + mNbRayBVTests = 0; + mNbRayPrimTests = 0; + mNbIntersections = 0; +#ifndef OPC_RAYHIT_CALLBACK + if(mStabbedFaces) mStabbedFaces->Reset(); +#endif + + // Compute ray in local space + // The (Origin/Dir) form is needed for the ray-triangle test anyway (even for segment tests) + if(world) + { + Matrix3x3 InvWorld = *world; + mDir = InvWorld * world_ray.mDir; + + Matrix4x4 World; + InvertPRMatrix(World, *world); + mOrigin = world_ray.mOrig * World; + } + else + { + mDir = world_ray.mDir; + mOrigin = world_ray.mOrig; + } + + // 4) Special case: 1-triangle meshes [Opcode 1.3] + if(mCurrentModel && mCurrentModel->HasSingleNode()) + { + // We simply perform the BV-Prim overlap test each time. We assume single triangle has index 0. + if(!SkipPrimitiveTests()) + { + // Perform overlap test between the unique triangle and the ray (and set contact status if needed) + SEGMENT_PRIM(udword(0), OPC_CONTACT) + + // Return immediately regardless of status + return TRUE; + } + } + + // Check temporal coherence : + + // Test previously colliding primitives first + if(TemporalCoherenceEnabled() && FirstContactEnabled() && face_id && *face_id!=INVALID_ID) + { +#ifdef OLD_CODE +#ifndef OPC_RAYHIT_CALLBACK + if(!mClosestHit) +#endif + { + // Request vertices from the app + VertexPointers VP; + ConversionArea VC; + mIMesh->GetTriangle(VP, *face_id, VC); + // Perform ray-cached tri overlap test + if(RayTriOverlap(*VP.Vertex[0], *VP.Vertex[1], *VP.Vertex[2])) + { + // Intersection point is valid if: + // - distance is positive (else it can just be a face behind the orig point) + // - distance is smaller than a given max distance (useful for shadow feelers) +// if(mStabbedFace.mDistance>0.0f && mStabbedFace.mDistance<mMaxDist) + if(IR(mStabbedFace.mDistance)<IR(mMaxDist)) // The other test is already performed in RayTriOverlap + { + // Set contact status + mFlags |= OPC_TEMPORAL_CONTACT; + + mStabbedFace.mFaceID = *face_id; + +#ifndef OPC_RAYHIT_CALLBACK + if(mStabbedFaces) mStabbedFaces->AddFace(mStabbedFace); +#endif + return TRUE; + } + } + } +#else + // New code + // We handle both Segment/ray queries with the same segment code, and a possible infinite limit + SEGMENT_PRIM(*face_id, OPC_TEMPORAL_CONTACT) + + // Return immediately if possible + if(GetContactStatus()) return TRUE; +#endif + } + + // Precompute data (moved after temporal coherence since only needed for ray-AABB) + if(IR(mMaxDist)!=IEEE_MAX_FLOAT) + { + // For Segment-AABB overlap + mData = 0.5f * mDir * mMaxDist; + mData2 = mOrigin + mData; + + // Precompute mFDir; + mFDir.x = fabsf(mData.x); + mFDir.y = fabsf(mData.y); + mFDir.z = fabsf(mData.z); + } + else + { + // For Ray-AABB overlap +// udword x = SIR(mDir.x)-1; +// udword y = SIR(mDir.y)-1; +// udword z = SIR(mDir.z)-1; +// mData.x = FR(x); +// mData.y = FR(y); +// mData.z = FR(z); + + // Precompute mFDir; + mFDir.x = fabsf(mDir.x); + mFDir.y = fabsf(mDir.y); + mFDir.z = fabsf(mDir.z); + } + + return FALSE; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Stabbing query for vanilla AABB trees. + * \param world_ray [in] stabbing ray in world space + * \param tree [in] AABB tree + * \param box_indices [out] indices of stabbed boxes + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool RayCollider::Collide(const Ray& world_ray, const AABBTree* tree, Container& box_indices) +{ + // ### bad design here + + // This is typically called for a scene tree, full of -AABBs-, not full of triangles. + // So we don't really have "primitives" to deal with. Hence it doesn't work with + // "FirstContact" + "TemporalCoherence". + ASSERT( !(FirstContactEnabled() && TemporalCoherenceEnabled()) ); + + // Checkings + if(!tree) return false; + + // Init collision query + // Basically this is only called to initialize precomputed data + if(InitQuery(world_ray)) return true; + + // Perform stabbing query + if(IR(mMaxDist)!=IEEE_MAX_FLOAT) _SegmentStab(tree, box_indices); + else _RayStab(tree, box_indices); + + return true; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive stabbing query for normal AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void RayCollider::_SegmentStab(const AABBCollisionNode* node) +{ + // Perform Segment-AABB overlap test + if(!SegmentAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; + + if(node->IsLeaf()) + { + SEGMENT_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _SegmentStab(node->GetPos()); + + if(ContactFound()) return; + + _SegmentStab(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive stabbing query for quantized AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void RayCollider::_SegmentStab(const AABBQuantizedNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform Segment-AABB overlap test + if(!SegmentAABBOverlap(Center, Extents)) return; + + if(node->IsLeaf()) + { + SEGMENT_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _SegmentStab(node->GetPos()); + + if(ContactFound()) return; + + _SegmentStab(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive stabbing query for no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void RayCollider::_SegmentStab(const AABBNoLeafNode* node) +{ + // Perform Segment-AABB overlap test + if(!SegmentAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; + + if(node->HasPosLeaf()) + { + SEGMENT_PRIM(node->GetPosPrimitive(), OPC_CONTACT) + } + else _SegmentStab(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) + { + SEGMENT_PRIM(node->GetNegPrimitive(), OPC_CONTACT) + } + else _SegmentStab(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive stabbing query for quantized no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void RayCollider::_SegmentStab(const AABBQuantizedNoLeafNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform Segment-AABB overlap test + if(!SegmentAABBOverlap(Center, Extents)) return; + + if(node->HasPosLeaf()) + { + SEGMENT_PRIM(node->GetPosPrimitive(), OPC_CONTACT) + } + else _SegmentStab(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) + { + SEGMENT_PRIM(node->GetNegPrimitive(), OPC_CONTACT) + } + else _SegmentStab(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive stabbing query for vanilla AABB trees. + * \param node [in] current collision node + * \param box_indices [out] indices of stabbed boxes + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void RayCollider::_SegmentStab(const AABBTreeNode* node, Container& box_indices) +{ + // Test the box against the segment + Point Center, Extents; + node->GetAABB()->GetCenter(Center); + node->GetAABB()->GetExtents(Extents); + if(!SegmentAABBOverlap(Center, Extents)) return; + + if(node->IsLeaf()) + { + box_indices.Add(node->GetPrimitives(), node->GetNbPrimitives()); + } + else + { + _SegmentStab(node->GetPos(), box_indices); + _SegmentStab(node->GetNeg(), box_indices); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive stabbing query for normal AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void RayCollider::_RayStab(const AABBCollisionNode* node) +{ + // Perform Ray-AABB overlap test + if(!RayAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; + + if(node->IsLeaf()) + { + RAY_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _RayStab(node->GetPos()); + + if(ContactFound()) return; + + _RayStab(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive stabbing query for quantized AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void RayCollider::_RayStab(const AABBQuantizedNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform Ray-AABB overlap test + if(!RayAABBOverlap(Center, Extents)) return; + + if(node->IsLeaf()) + { + RAY_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _RayStab(node->GetPos()); + + if(ContactFound()) return; + + _RayStab(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive stabbing query for no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void RayCollider::_RayStab(const AABBNoLeafNode* node) +{ + // Perform Ray-AABB overlap test + if(!RayAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; + + if(node->HasPosLeaf()) + { + RAY_PRIM(node->GetPosPrimitive(), OPC_CONTACT) + } + else _RayStab(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) + { + RAY_PRIM(node->GetNegPrimitive(), OPC_CONTACT) + } + else _RayStab(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive stabbing query for quantized no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void RayCollider::_RayStab(const AABBQuantizedNoLeafNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform Ray-AABB overlap test + if(!RayAABBOverlap(Center, Extents)) return; + + if(node->HasPosLeaf()) + { + RAY_PRIM(node->GetPosPrimitive(), OPC_CONTACT) + } + else _RayStab(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) + { + RAY_PRIM(node->GetNegPrimitive(), OPC_CONTACT) + } + else _RayStab(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive stabbing query for vanilla AABB trees. + * \param node [in] current collision node + * \param box_indices [out] indices of stabbed boxes + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void RayCollider::_RayStab(const AABBTreeNode* node, Container& box_indices) +{ + // Test the box against the ray + Point Center, Extents; + node->GetAABB()->GetCenter(Center); + node->GetAABB()->GetExtents(Extents); + if(!RayAABBOverlap(Center, Extents)) return; + + if(node->IsLeaf()) + { + mFlags |= OPC_CONTACT; + box_indices.Add(node->GetPrimitives(), node->GetNbPrimitives()); + } + else + { + _RayStab(node->GetPos(), box_indices); + _RayStab(node->GetNeg(), box_indices); + } +} diff --git a/libs/ode-0.16.1/OPCODE/OPC_RayCollider.h b/libs/ode-0.16.1/OPCODE/OPC_RayCollider.h new file mode 100644 index 0000000..4a8ab7e --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_RayCollider.h @@ -0,0 +1,224 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for a ray collider. + * \file OPC_RayCollider.h + * \author Pierre Terdiman + * \date June, 2, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_RAYCOLLIDER_H__ +#define __OPC_RAYCOLLIDER_H__ + + class OPCODE_API CollisionFace + { + public: + //! Constructor + inline_ CollisionFace() {} + //! Destructor + inline_ ~CollisionFace() {} + + udword mFaceID; //!< Index of touched face + float mDistance; //!< Distance from collider to hitpoint + float mU, mV; //!< Impact barycentric coordinates + }; + + class OPCODE_API CollisionFaces : public Container + { + public: + //! Constructor + CollisionFaces() {} + //! Destructor + ~CollisionFaces() {} + + inline_ udword GetNbFaces() const { return GetNbEntries()>>2; } + inline_ const CollisionFace* GetFaces() const { return (const CollisionFace*)GetEntries(); } + + inline_ void Reset() { Container::Reset(); } + + inline_ void AddFace(const CollisionFace& face) { Add(face.mFaceID).Add(face.mDistance).Add(face.mU).Add(face.mV); } + }; + +#ifdef OPC_RAYHIT_CALLBACK + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * User-callback, called by OPCODE to record a hit. + * \param hit [in] current hit + * \param user_data [in] user-defined data from SetCallback() + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + typedef void (*HitCallback) (const CollisionFace& hit, void* user_data); +#endif + + class OPCODE_API RayCollider : public Collider + { + public: + // Constructor / Destructor + RayCollider(); + virtual ~RayCollider(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Generic stabbing query for generic OPCODE models. After the call, access the results: + * - with GetContactStatus() + * - in the user-provided destination array + * + * \param world_ray [in] stabbing ray in world space + * \param model [in] Opcode model to collide with + * \param world [in] model's world matrix, or null + * \param cache [in] a possibly cached face index, or null + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool Collide(const Ray& world_ray, const Model& model, const Matrix4x4* world=null, udword* cache=null); + // + bool Collide(const Ray& world_ray, const AABBTree* tree, Container& box_indices); + // Settings + +#ifndef OPC_RAYHIT_CALLBACK + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Settings: enable or disable "closest hit" mode. + * \param flag [in] true to report closest hit only + * \see SetCulling(bool flag) + * \see SetMaxDist(float max_dist) + * \see SetDestination(StabbedFaces* sf) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetClosestHit(bool flag) { mClosestHit = flag; } +#endif + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Settings: enable or disable backface culling. + * \param flag [in] true to enable backface culling + * \see SetClosestHit(bool flag) + * \see SetMaxDist(float max_dist) + * \see SetDestination(StabbedFaces* sf) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetCulling(bool flag) { mCulling = flag; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Settings: sets the higher distance bound. + * \param max_dist [in] higher distance bound. Default = maximal value, for ray queries (else segment) + * \see SetClosestHit(bool flag) + * \see SetCulling(bool flag) + * \see SetDestination(StabbedFaces* sf) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetMaxDist(float max_dist=MAX_FLOAT) { mMaxDist = max_dist; } + +#ifdef OPC_RAYHIT_CALLBACK + inline_ void SetHitCallback(HitCallback cb) { mHitCallback = cb; } + inline_ void SetUserData(void* user_data) { mUserData = user_data; } +#else + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Settings: sets the destination array for stabbed faces. + * \param cf [in] destination array, filled during queries + * \see SetClosestHit(bool flag) + * \see SetCulling(bool flag) + * \see SetMaxDist(float max_dist) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetDestination(CollisionFaces* cf) { mStabbedFaces = cf; } +#endif + // Stats + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Stats: gets the number of Ray-BV overlap tests after a collision query. + * \see GetNbRayPrimTests() + * \see GetNbIntersections() + * \return the number of Ray-BV tests performed during last query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbRayBVTests() const { return mNbRayBVTests; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Stats: gets the number of Ray-Triangle overlap tests after a collision query. + * \see GetNbRayBVTests() + * \see GetNbIntersections() + * \return the number of Ray-Triangle tests performed during last query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbRayPrimTests() const { return mNbRayPrimTests; } + + // In-out test + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Stats: gets the number of intersection found after a collision query. Can be used for in/out tests. + * \see GetNbRayBVTests() + * \see GetNbRayPrimTests() + * \return the number of valid intersections during last query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbIntersections() const { return mNbIntersections; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Validates current settings. You should call this method after all the settings and callbacks have been defined for a collider. + * \return null if everything is ok, else a string describing the problem + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(Collider) const char* ValidateSettings(); + + protected: + // Ray in local space + Point mOrigin; //!< Ray origin + Point mDir; //!< Ray direction (normalized) + Point mFDir; //!< fabsf(mDir) + Point mData, mData2; + // Stabbed faces + CollisionFace mStabbedFace; //!< Current stabbed face +#ifdef OPC_RAYHIT_CALLBACK + HitCallback mHitCallback; //!< Callback used to record a hit + void* mUserData; //!< User-defined data +#else + CollisionFaces* mStabbedFaces; //!< List of stabbed faces + bool mClosestHit; //!< Report closest hit only +#endif + // Stats + udword mNbRayBVTests; //!< Number of Ray-BV tests + udword mNbRayPrimTests; //!< Number of Ray-Primitive tests + // In-out test + udword mNbIntersections; //!< Number of valid intersections + // Dequantization coeffs + Point mCenterCoeff; + Point mExtentsCoeff; + // Settings + float mMaxDist; //!< Valid segment on the ray + + bool mCulling; //!< Stab culled faces or not + // Internal methods + void _SegmentStab(const AABBCollisionNode* node); + void _SegmentStab(const AABBNoLeafNode* node); + void _SegmentStab(const AABBQuantizedNode* node); + void _SegmentStab(const AABBQuantizedNoLeafNode* node); + void _SegmentStab(const AABBTreeNode* node, Container& box_indices); + void _RayStab(const AABBCollisionNode* node); + void _RayStab(const AABBNoLeafNode* node); + void _RayStab(const AABBQuantizedNode* node); + void _RayStab(const AABBQuantizedNoLeafNode* node); + void _RayStab(const AABBTreeNode* node, Container& box_indices); + // Overlap tests + inline_ BOOL RayAABBOverlap(const Point& center, const Point& extents); + inline_ BOOL SegmentAABBOverlap(const Point& center, const Point& extents); + inline_ BOOL RayTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2); + // Init methods + BOOL InitQuery(const Ray& world_ray, const Matrix4x4* world=null, udword* face_id=null); + }; + +#endif // __OPC_RAYCOLLIDER_H__ diff --git a/libs/ode-0.16.1/OPCODE/OPC_RayTriOverlap.h b/libs/ode-0.16.1/OPCODE/OPC_RayTriOverlap.h new file mode 100644 index 0000000..04110a1 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_RayTriOverlap.h @@ -0,0 +1,89 @@ +#define LOCAL_EPSILON 0.000001f + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes a ray-triangle intersection test. + * Original code from Tomas Möller's "Fast Minimum Storage Ray-Triangle Intersection". + * It's been optimized a bit with integer code, and modified to return a non-intersection if distance from + * ray origin to triangle is negative. + * + * \param vert0 [in] triangle vertex + * \param vert1 [in] triangle vertex + * \param vert2 [in] triangle vertex + * \return true on overlap. mStabbedFace is filled with relevant info. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL RayCollider::RayTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2) +{ + // Stats + mNbRayPrimTests++; + + // Find vectors for two edges sharing vert0 + Point edge1 = vert1 - vert0; + Point edge2 = vert2 - vert0; + + // Begin calculating determinant - also used to calculate U parameter + Point pvec = mDir^edge2; + + // If determinant is near zero, ray lies in plane of triangle + float det = edge1|pvec; + + if(mCulling) + { + if(det <= LOCAL_EPSILON * FCMin2(edge1.SquareMagnitude(), edge2.SquareMagnitude())) return FALSE; + // From here, det is > 0. So we can use integer cmp. + + // Calculate distance from vert0 to ray origin + Point tvec = mOrigin - vert0; + + // Calculate U parameter and test bounds + mStabbedFace.mU = tvec|pvec; +// if(IR(u)&0x80000000 || u>det) return FALSE; + if(IS_NEGATIVE_FLOAT(mStabbedFace.mU) || IR(mStabbedFace.mU)>IR(det)) return FALSE; + + // Prepare to test V parameter + Point qvec = tvec^edge1; + + // Calculate V parameter and test bounds + mStabbedFace.mV = mDir|qvec; + if(IS_NEGATIVE_FLOAT(mStabbedFace.mV) || mStabbedFace.mU+mStabbedFace.mV>det) return FALSE; + + // Calculate t, scale parameters, ray intersects triangle + mStabbedFace.mDistance = edge2|qvec; + // Det > 0 so we can early exit here + // Intersection point is valid if distance is positive (else it can just be a face behind the orig point) + if(IS_NEGATIVE_FLOAT(mStabbedFace.mDistance)) return FALSE; + // Else go on + float OneOverDet = 1.0f / det; + mStabbedFace.mDistance *= OneOverDet; + mStabbedFace.mU *= OneOverDet; + mStabbedFace.mV *= OneOverDet; + } + else + { + // the non-culling branch + if(FastFabs(det) <= LOCAL_EPSILON * FCMin2(edge1.SquareMagnitude(), edge2.SquareMagnitude())) return FALSE; + float OneOverDet = 1.0f / det; + + // Calculate distance from vert0 to ray origin + Point tvec = mOrigin - vert0; + + // Calculate U parameter and test bounds + mStabbedFace.mU = (tvec|pvec) * OneOverDet; +// if(IR(u)&0x80000000 || u>1.0f) return FALSE; + if(IS_NEGATIVE_FLOAT(mStabbedFace.mU) || IR(mStabbedFace.mU)>IEEE_1_0) return FALSE; + + // prepare to test V parameter + Point qvec = tvec^edge1; + + // Calculate V parameter and test bounds + mStabbedFace.mV = (mDir|qvec) * OneOverDet; + if(IS_NEGATIVE_FLOAT(mStabbedFace.mV) || mStabbedFace.mU+mStabbedFace.mV>1.0f) return FALSE; + + // Calculate t, ray intersects triangle + mStabbedFace.mDistance = (edge2|qvec) * OneOverDet; + // Intersection point is valid if distance is positive (else it can just be a face behind the orig point) + if(IS_NEGATIVE_FLOAT(mStabbedFace.mDistance)) return FALSE; + } + return TRUE; +} diff --git a/libs/ode-0.16.1/OPCODE/OPC_Settings.h b/libs/ode-0.16.1/OPCODE/OPC_Settings.h new file mode 100644 index 0000000..7509888 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_Settings.h @@ -0,0 +1,49 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains compilation flags. + * \file OPC_Settings.h + * \author Pierre Terdiman + * \date May, 12, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_SETTINGS_H__ +#define __OPC_SETTINGS_H__ + + //! Use CPU comparisons (comment that line to use standard FPU compares) + //#define OPC_CPU_COMPARE + + //! Use FCOMI / FCMOV on Pentium-Pro based processors (comment that line to use plain C++) + #define OPC_USE_FCOMI + + //! Use epsilon value in tri-tri overlap test + #define OPC_TRITRI_EPSILON_TEST + + //! Use tree-coherence or not [not implemented yet] +// #define OPC_USE_TREE_COHERENCE + + //! Use callbacks or direct pointers. Using callbacks might be a bit slower (but probably not much) +// #define OPC_USE_CALLBACKS + + //! Support triangle and vertex strides or not. Using strides might be a bit slower (but probably not much) + #define OPC_USE_STRIDE + + //! Discard negative pointer in vanilla trees + #define OPC_NO_NEG_VANILLA_TREE + + //! Use a callback in the ray collider + //#define OPC_RAYHIT_CALLBACK + + // NB: no compilation flag to enable/disable stats since they're actually needed in the box/box overlap test + +#endif //__OPC_SETTINGS_H__ diff --git a/libs/ode-0.16.1/OPCODE/OPC_SphereAABBOverlap.h b/libs/ode-0.16.1/OPCODE/OPC_SphereAABBOverlap.h new file mode 100644 index 0000000..2278bc0 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_SphereAABBOverlap.h @@ -0,0 +1,128 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Sphere-AABB overlap test, based on Jim Arvo's code. + * \param center [in] box center + * \param extents [in] box extents + * \return TRUE on overlap + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL SphereCollider::SphereAABBOverlap(const Point& center, const Point& extents) +{ + // Stats + mNbVolumeBVTests++; + + float d = 0.0f; + + //find the square of the distance + //from the sphere to the box +#ifdef OLDIES + for(udword i=0;i<3;i++) + { + float tmp = mCenter[i] - center[i]; + float s = tmp + extents[i]; + + if(s<0.0f) d += s*s; + else + { + s = tmp - extents[i]; + if(s>0.0f) d += s*s; + } + } +#endif + +//#ifdef NEW_TEST + +// float tmp = mCenter.x - center.x; +// float s = tmp + extents.x; + + float tmp,s; + + tmp = mCenter.x - center.x; + s = tmp + extents.x; + + if(s<0.0f) + { + d += s*s; + if(d>mRadius2) return FALSE; + } + else + { + s = tmp - extents.x; + if(s>0.0f) + { + d += s*s; + if(d>mRadius2) return FALSE; + } + } + + tmp = mCenter.y - center.y; + s = tmp + extents.y; + + if(s<0.0f) + { + d += s*s; + if(d>mRadius2) return FALSE; + } + else + { + s = tmp - extents.y; + if(s>0.0f) + { + d += s*s; + if(d>mRadius2) return FALSE; + } + } + + tmp = mCenter.z - center.z; + s = tmp + extents.z; + + if(s<0.0f) + { + d += s*s; + if(d>mRadius2) return FALSE; + } + else + { + s = tmp - extents.z; + if(s>0.0f) + { + d += s*s; + if(d>mRadius2) return FALSE; + } + } +//#endif + +#ifdef OLDIES +// Point Min = center - extents; +// Point Max = center + extents; + + float d = 0.0f; + + //find the square of the distance + //from the sphere to the box + for(udword i=0;i<3;i++) + { +float Min = center[i] - extents[i]; + +// if(mCenter[i]<Min[i]) + if(mCenter[i]<Min) + { +// float s = mCenter[i] - Min[i]; + float s = mCenter[i] - Min; + d += s*s; + } + else + { +float Max = center[i] + extents[i]; + +// if(mCenter[i]>Max[i]) + if(mCenter[i]>Max) + { + float s = mCenter[i] - Max; + d += s*s; + } + } + } +#endif + return d <= mRadius2; +} diff --git a/libs/ode-0.16.1/OPCODE/OPC_SphereCollider.cpp b/libs/ode-0.16.1/OPCODE/OPC_SphereCollider.cpp new file mode 100644 index 0000000..e2406ec --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_SphereCollider.cpp @@ -0,0 +1,739 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for a sphere collider. + * \file OPC_SphereCollider.cpp + * \author Pierre Terdiman + * \date June, 2, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a sphere-vs-tree collider. + * This class performs a collision test between a sphere and an AABB tree. You can use this to do a standard player vs world collision, + * in a Nettle/Telemachos way. It doesn't suffer from all reported bugs in those two classic codes - the "new" one by Paul Nettle is a + * debuggued version I think. Collision response can be driven by reported collision data - it works extremely well for me. In sake of + * efficiency, all meshes (that is, all AABB trees) should of course also be kept in an extra hierarchical structure (octree, whatever). + * + * \class SphereCollider + * \author Pierre Terdiman + * \version 1.3 + * \date June, 2, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +#include "OPC_SphereAABBOverlap.h" +#include "OPC_SphereTriOverlap.h" + +#define SET_CONTACT(prim_index, flag) \ + /* Set contact status */ \ + mFlags |= flag; \ + mTouchedPrimitives->Add(udword(prim_index)); + +//! Sphere-triangle overlap test +#define SPHERE_PRIM(prim_index, flag) \ + /* Request vertices from the app */ \ + VertexPointers VP; ConversionArea VC; mIMesh->GetTriangle(VP, prim_index, VC); \ + \ + /* Perform sphere-tri overlap test */ \ + if(SphereTriOverlap(*VP.Vertex[0], *VP.Vertex[1], *VP.Vertex[2])) \ + { \ + SET_CONTACT(prim_index, flag) \ + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +SphereCollider::SphereCollider() +{ + mCenter.Zero(); + mRadius2 = 0.0f; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +SphereCollider::~SphereCollider() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Generic collision query for generic OPCODE models. After the call, access the results: + * - with GetContactStatus() + * - with GetNbTouchedPrimitives() + * - with GetTouchedPrimitives() + * + * \param cache [in/out] a sphere cache + * \param sphere [in] collision sphere in local space + * \param model [in] Opcode model to collide with + * \param worlds [in] sphere's world matrix, or null + * \param worldm [in] model's world matrix, or null + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool SphereCollider::Collide(SphereCache& cache, const Sphere& sphere, const Model& model, const Matrix4x4* worlds, const Matrix4x4* worldm) +{ + // Checkings + if(!Setup(&model)) return false; + + // Init collision query + if(InitQuery(cache, sphere, worlds, worldm)) return true; + + // Special case for 1-leaf trees + if(mCurrentModel && mCurrentModel->HasSingleNode()) + { + // Here we're supposed to perform a normal query, except our tree has a single node, i.e. just a few triangles + udword Nb = mIMesh->GetNbTriangles(); + // Loop through all triangles + for(udword i=0;i<Nb;i++) + { + SPHERE_PRIM(i, OPC_CONTACT) + } + return true; + } + + if(!model.HasLeafNodes()) + { + if(model.IsQuantized()) + { + const AABBQuantizedNoLeafTree* Tree = static_cast<const AABBQuantizedNoLeafTree *>(model.GetTree()); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + else + { + const AABBNoLeafTree* Tree = static_cast<const AABBNoLeafTree *>(model.GetTree()); + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + } + else + { + if(model.IsQuantized()) + { + const AABBQuantizedTree* Tree = static_cast<const AABBQuantizedTree *>(model.GetTree()); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + else + { + const AABBCollisionTree* Tree = static_cast<const AABBCollisionTree *>(model.GetTree()); + + // Perform collision query + if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); + else _Collide(Tree->GetNodes()); + } + } + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Initializes a collision query : + * - reset stats & contact status + * - setup matrices + * - check temporal coherence + * + * \param cache [in/out] a sphere cache + * \param sphere [in] sphere in local space + * \param worlds [in] sphere's world matrix, or null + * \param worldm [in] model's world matrix, or null + * \return TRUE if we can return immediately + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +BOOL SphereCollider::InitQuery(SphereCache& cache, const Sphere& sphere, const Matrix4x4* worlds, const Matrix4x4* worldm) +{ + // 1) Call the base method + VolumeCollider::InitQuery(); + + // 2) Compute sphere in model space: + // - Precompute R^2 + mRadius2 = sphere.mRadius * sphere.mRadius; + // - Compute center position + mCenter = sphere.mCenter; + // -> to world space + if(worlds) mCenter *= *worlds; + // -> to model space + if(worldm) + { + // Invert model matrix + Matrix4x4 InvWorldM; + InvertPRMatrix(InvWorldM, *worldm); + + mCenter *= InvWorldM; + } + + // 3) Setup destination pointer + mTouchedPrimitives = &cache.TouchedPrimitives; + + // 4) Special case: 1-triangle meshes [Opcode 1.3] + if(mCurrentModel && mCurrentModel->HasSingleNode()) + { + if(!SkipPrimitiveTests()) + { + // We simply perform the BV-Prim overlap test each time. We assume single triangle has index 0. + mTouchedPrimitives->Reset(); + + // Perform overlap test between the unique triangle and the sphere (and set contact status if needed) + SPHERE_PRIM(udword(0), OPC_CONTACT) + + // Return immediately regardless of status + return TRUE; + } + } + + // 5) Check temporal coherence : + if(TemporalCoherenceEnabled()) + { + // Here we use temporal coherence + // => check results from previous frame before performing the collision query + if(FirstContactEnabled()) + { + // We're only interested in the first contact found => test the unique previously touched face + if(mTouchedPrimitives->GetNbEntries()) + { + // Get index of previously touched face = the first entry in the array + udword PreviouslyTouchedFace = mTouchedPrimitives->GetEntry(0); + + // Then reset the array: + // - if the overlap test below is successful, the index we'll get added back anyway + // - if it isn't, then the array should be reset anyway for the normal query + mTouchedPrimitives->Reset(); + + // Perform overlap test between the cached triangle and the sphere (and set contact status if needed) + SPHERE_PRIM(PreviouslyTouchedFace, OPC_TEMPORAL_CONTACT) + + // Return immediately if possible + if(GetContactStatus()) return TRUE; + } + // else no face has been touched during previous query + // => we'll have to perform a normal query + } + else + { + // We're interested in all contacts =>test the new real sphere N(ew) against the previous fat sphere P(revious): + float r = sqrtf(cache.FatRadius2) - sphere.mRadius; + if(IsCacheValid(cache) && cache.Center.SquareDistance(mCenter) < r*r) + { + // - if N is included in P, return previous list + // => we simply leave the list (mTouchedFaces) unchanged + + // Set contact status if needed + if(mTouchedPrimitives->GetNbEntries()) mFlags |= OPC_TEMPORAL_CONTACT; + + // In any case we don't need to do a query + return TRUE; + } + else + { + // - else do the query using a fat N + + // Reset cache since we'll about to perform a real query + mTouchedPrimitives->Reset(); + + // Make a fat sphere so that coherence will work for subsequent frames + mRadius2 *= cache.FatCoeff; +// mRadius2 = (sphere.mRadius * cache.FatCoeff)*(sphere.mRadius * cache.FatCoeff); + + // Update cache with query data (signature for cached faces) + cache.Center = mCenter; + cache.FatRadius2 = mRadius2; + } + } + } + else + { + // Here we don't use temporal coherence => do a normal query + mTouchedPrimitives->Reset(); + } + + return FALSE; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Collision query for vanilla AABB trees. + * \param cache [in/out] a sphere cache + * \param sphere [in] collision sphere in world space + * \param tree [in] AABB tree + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool SphereCollider::Collide(SphereCache& cache, const Sphere& sphere, const AABBTree* tree) +{ + // This is typically called for a scene tree, full of -AABBs-, not full of triangles. + // So we don't really have "primitives" to deal with. Hence it doesn't work with + // "FirstContact" + "TemporalCoherence". + ASSERT( !(FirstContactEnabled() && TemporalCoherenceEnabled()) ); + + // Checkings + if(!tree) return false; + + // Init collision query + if(InitQuery(cache, sphere)) return true; + + // Perform collision query + _Collide(tree); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks the sphere completely contains the box. In which case we can end the query sooner. + * \param bc [in] box center + * \param be [in] box extents + * \return true if the sphere contains the whole box + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL SphereCollider::SphereContainsBox(const Point& bc, const Point& be) +{ + // I assume if all 8 box vertices are inside the sphere, so does the whole box. + // Sounds ok but maybe there's a better way? + Point p; + p.x=bc.x+be.x; p.y=bc.y+be.y; p.z=bc.z+be.z; if(mCenter.SquareDistance(p)>=mRadius2) return FALSE; + p.x=bc.x-be.x; if(mCenter.SquareDistance(p)>=mRadius2) return FALSE; + p.x=bc.x+be.x; p.y=bc.y-be.y; if(mCenter.SquareDistance(p)>=mRadius2) return FALSE; + p.x=bc.x-be.x; if(mCenter.SquareDistance(p)>=mRadius2) return FALSE; + p.x=bc.x+be.x; p.y=bc.y+be.y; p.z=bc.z-be.z; if(mCenter.SquareDistance(p)>=mRadius2) return FALSE; + p.x=bc.x-be.x; if(mCenter.SquareDistance(p)>=mRadius2) return FALSE; + p.x=bc.x+be.x; p.y=bc.y-be.y; if(mCenter.SquareDistance(p)>=mRadius2) return FALSE; + p.x=bc.x-be.x; if(mCenter.SquareDistance(p)>=mRadius2) return FALSE; + + return TRUE; +} + +#define TEST_BOX_IN_SPHERE(center, extents) \ + if(SphereContainsBox(center, extents)) \ + { \ + /* Set contact status */ \ + mFlags |= OPC_CONTACT; \ + _Dump(node); \ + return; \ + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for normal AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void SphereCollider::_Collide(const AABBCollisionNode* node) +{ + // Perform Sphere-AABB overlap test + if(!SphereAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; + + TEST_BOX_IN_SPHERE(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->IsLeaf()) + { + SPHERE_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _Collide(node->GetPos()); + + if(ContactFound()) return; + + _Collide(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for normal AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void SphereCollider::_CollideNoPrimitiveTest(const AABBCollisionNode* node) +{ + // Perform Sphere-AABB overlap test + if(!SphereAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; + + TEST_BOX_IN_SPHERE(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->IsLeaf()) + { + SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + _CollideNoPrimitiveTest(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void SphereCollider::_Collide(const AABBQuantizedNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform Sphere-AABB overlap test + if(!SphereAABBOverlap(Center, Extents)) return; + + TEST_BOX_IN_SPHERE(Center, Extents) + + if(node->IsLeaf()) + { + SPHERE_PRIM(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _Collide(node->GetPos()); + + if(ContactFound()) return; + + _Collide(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void SphereCollider::_CollideNoPrimitiveTest(const AABBQuantizedNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform Sphere-AABB overlap test + if(!SphereAABBOverlap(Center, Extents)) return; + + TEST_BOX_IN_SPHERE(Center, Extents) + + if(node->IsLeaf()) + { + SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) + } + else + { + _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + _CollideNoPrimitiveTest(node->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void SphereCollider::_Collide(const AABBNoLeafNode* node) +{ + // Perform Sphere-AABB overlap test + if(!SphereAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; + + TEST_BOX_IN_SPHERE(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->HasPosLeaf()) { SPHERE_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } + else _Collide(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { SPHERE_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } + else _Collide(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for no-leaf AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void SphereCollider::_CollideNoPrimitiveTest(const AABBNoLeafNode* node) +{ + // Perform Sphere-AABB overlap test + if(!SphereAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents)) return; + + TEST_BOX_IN_SPHERE(node->mAABB.mCenter, node->mAABB.mExtents) + + if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized no-leaf AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void SphereCollider::_Collide(const AABBQuantizedNoLeafNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform Sphere-AABB overlap test + if(!SphereAABBOverlap(Center, Extents)) return; + + TEST_BOX_IN_SPHERE(Center, Extents) + + if(node->HasPosLeaf()) { SPHERE_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } + else _Collide(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { SPHERE_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } + else _Collide(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized no-leaf AABB trees, without primitive tests. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void SphereCollider::_CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node) +{ + // Dequantize box + const QuantizedAABB& Box = node->mAABB; + const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); + const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); + + // Perform Sphere-AABB overlap test + if(!SphereAABBOverlap(Center, Extents)) return; + + TEST_BOX_IN_SPHERE(Center, Extents) + + if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetPos()); + + if(ContactFound()) return; + + if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } + else _CollideNoPrimitiveTest(node->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for vanilla AABB trees. + * \param node [in] current collision node + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void SphereCollider::_Collide(const AABBTreeNode* node) +{ + // Perform Sphere-AABB overlap test + Point Center, Extents; + node->GetAABB()->GetCenter(Center); + node->GetAABB()->GetExtents(Extents); + if(!SphereAABBOverlap(Center, Extents)) return; + + if(node->IsLeaf() || SphereContainsBox(Center, Extents)) + { + mFlags |= OPC_CONTACT; + mTouchedPrimitives->Add(node->GetPrimitives(), node->GetNbPrimitives()); + } + else + { + _Collide(node->GetPos()); + _Collide(node->GetNeg()); + } +} + + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HybridSphereCollider::HybridSphereCollider() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HybridSphereCollider::~HybridSphereCollider() +{ +} + +bool HybridSphereCollider::Collide(SphereCache& cache, const Sphere& sphere, const HybridModel& model, const Matrix4x4* worlds, const Matrix4x4* worldm) +{ + // We don't want primitive tests here! + mFlags |= OPC_NO_PRIMITIVE_TESTS; + + // Checkings + if(!Setup(&model)) return false; + + // Init collision query + if(InitQuery(cache, sphere, worlds, worldm)) return true; + + // Special case for 1-leaf trees + if(mCurrentModel && mCurrentModel->HasSingleNode()) + { + // Here we're supposed to perform a normal query, except our tree has a single node, i.e. just a few triangles + udword Nb = mIMesh->GetNbTriangles(); + + // Loop through all triangles + for(udword i=0;i<Nb;i++) + { + SPHERE_PRIM(i, OPC_CONTACT) + } + return true; + } + + // Override destination array since we're only going to get leaf boxes here + mTouchedBoxes.Reset(); + mTouchedPrimitives = &mTouchedBoxes; + + // Now, do the actual query against leaf boxes + if(!model.HasLeafNodes()) + { + if(model.IsQuantized()) + { + const AABBQuantizedNoLeafTree* Tree = static_cast<const AABBQuantizedNoLeafTree *>(model.GetTree()); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + else + { + const AABBNoLeafTree* Tree = static_cast<const AABBNoLeafTree *>(model.GetTree()); + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + } + else + { + if(model.IsQuantized()) + { + const AABBQuantizedTree* Tree = static_cast<const AABBQuantizedTree *>(model.GetTree()); + + // Setup dequantization coeffs + mCenterCoeff = Tree->mCenterCoeff; + mExtentsCoeff = Tree->mExtentsCoeff; + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + else + { + const AABBCollisionTree* Tree = static_cast<const AABBCollisionTree *>(model.GetTree()); + + // Perform collision query - we don't want primitive tests here! + _CollideNoPrimitiveTest(Tree->GetNodes()); + } + } + + // We only have a list of boxes so far + if(GetContactStatus()) + { + // Reset contact status, since it currently only reflects collisions with leaf boxes + Collider::InitQuery(); + + // Change dest container so that we can use built-in overlap tests and get collided primitives + cache.TouchedPrimitives.Reset(); + mTouchedPrimitives = &cache.TouchedPrimitives; + + // Read touched leaf boxes + udword Nb = mTouchedBoxes.GetNbEntries(); + const udword* Touched = mTouchedBoxes.GetEntries(); + + const LeafTriangles* LT = model.GetLeafTriangles(); + const udword* Indices = model.GetIndices(); + + // Loop through touched leaves + while(Nb--) + { + const LeafTriangles& CurrentLeaf = LT[*Touched++]; + + // Each leaf box has a set of triangles + udword NbTris = CurrentLeaf.GetNbTriangles(); + if(Indices) + { + const udword* T = &Indices[CurrentLeaf.GetTriangleIndex()]; + + // Loop through triangles and test each of them + while(NbTris--) + { + udword TriangleIndex = *T++; + SPHERE_PRIM(TriangleIndex, OPC_CONTACT) + } + } + else + { + udword BaseIndex = CurrentLeaf.GetTriangleIndex(); + + // Loop through triangles and test each of them + while(NbTris--) + { + udword TriangleIndex = BaseIndex++; + SPHERE_PRIM(TriangleIndex, OPC_CONTACT) + } + } + } + } + + return true; +} diff --git a/libs/ode-0.16.1/OPCODE/OPC_SphereCollider.h b/libs/ode-0.16.1/OPCODE/OPC_SphereCollider.h new file mode 100644 index 0000000..ac6495e --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_SphereCollider.h @@ -0,0 +1,96 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for a sphere collider. + * \file OPC_SphereCollider.h + * \author Pierre Terdiman + * \date June, 2, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_SPHERECOLLIDER_H__ +#define __OPC_SPHERECOLLIDER_H__ + + struct OPCODE_API SphereCache : VolumeCache + { + SphereCache() : Center(0.0f,0.0f,0.0f), FatRadius2(0.0f), FatCoeff(1.1f) {} + ~SphereCache() {} + + // Cached faces signature + Point Center; //!< Sphere used when performing the query resulting in cached faces + float FatRadius2; //!< Sphere used when performing the query resulting in cached faces + // User settings + float FatCoeff; //!< mRadius2 multiplier used to create a fat sphere + }; + + class OPCODE_API SphereCollider : public VolumeCollider + { + public: + // Constructor / Destructor + SphereCollider(); + virtual ~SphereCollider(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Generic collision query for generic OPCODE models. After the call, access the results: + * - with GetContactStatus() + * - with GetNbTouchedPrimitives() + * - with GetTouchedPrimitives() + * + * \param cache [in/out] a sphere cache + * \param sphere [in] collision sphere in local space + * \param model [in] Opcode model to collide with + * \param worlds [in] sphere's world matrix, or null + * \param worldm [in] model's world matrix, or null + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool Collide(SphereCache& cache, const Sphere& sphere, const Model& model, const Matrix4x4* worlds=null, const Matrix4x4* worldm=null); + + // + bool Collide(SphereCache& cache, const Sphere& sphere, const AABBTree* tree); + protected: + // Sphere in model space + Point mCenter; //!< Sphere center + float mRadius2; //!< Sphere radius squared + // Internal methods + void _Collide(const AABBCollisionNode* node); + void _Collide(const AABBNoLeafNode* node); + void _Collide(const AABBQuantizedNode* node); + void _Collide(const AABBQuantizedNoLeafNode* node); + void _Collide(const AABBTreeNode* node); + void _CollideNoPrimitiveTest(const AABBCollisionNode* node); + void _CollideNoPrimitiveTest(const AABBNoLeafNode* node); + void _CollideNoPrimitiveTest(const AABBQuantizedNode* node); + void _CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node); + // Overlap tests + inline_ BOOL SphereContainsBox(const Point& bc, const Point& be); + inline_ BOOL SphereAABBOverlap(const Point& center, const Point& extents); + BOOL SphereTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2); + // Init methods + BOOL InitQuery(SphereCache& cache, const Sphere& sphere, const Matrix4x4* worlds=null, const Matrix4x4* worldm=null); + }; + + class OPCODE_API HybridSphereCollider : public SphereCollider + { + public: + // Constructor / Destructor + HybridSphereCollider(); + virtual ~HybridSphereCollider(); + + bool Collide(SphereCache& cache, const Sphere& sphere, const HybridModel& model, const Matrix4x4* worlds=null, const Matrix4x4* worldm=null); + protected: + Container mTouchedBoxes; + }; + +#endif // __OPC_SPHERECOLLIDER_H__ diff --git a/libs/ode-0.16.1/OPCODE/OPC_SphereTriOverlap.h b/libs/ode-0.16.1/OPCODE/OPC_SphereTriOverlap.h new file mode 100644 index 0000000..77e59f3 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_SphereTriOverlap.h @@ -0,0 +1,187 @@ + +// This is collision detection. If you do another distance test for collision *response*, +// if might be useful to simply *skip* the test below completely, and report a collision. +// - if sphere-triangle overlap, result is ok +// - if they don't, we'll discard them during collision response with a similar test anyway +// Overall this approach should run faster. + +// Original code by David Eberly in Magic. +BOOL SphereCollider::SphereTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2) +{ + // Stats + mNbVolumePrimTests++; + + // Early exit if one of the vertices is inside the sphere + Point kDiff = vert2 - mCenter; + float fC = kDiff.SquareMagnitude(); + if(fC <= mRadius2) return TRUE; + + kDiff = vert1 - mCenter; + fC = kDiff.SquareMagnitude(); + if(fC <= mRadius2) return TRUE; + + kDiff = vert0 - mCenter; + fC = kDiff.SquareMagnitude(); + if(fC <= mRadius2) return TRUE; + + // Else do the full distance test + Point TriEdge0 = vert1 - vert0; + Point TriEdge1 = vert2 - vert0; + +//Point kDiff = vert0 - mCenter; + float fA00 = TriEdge0.SquareMagnitude(); + float fA01 = TriEdge0 | TriEdge1; + float fA11 = TriEdge1.SquareMagnitude(); + float fB0 = kDiff | TriEdge0; + float fB1 = kDiff | TriEdge1; +//float fC = kDiff.SquareMagnitude(); + float fDet = fabsf(fA00*fA11 - fA01*fA01); + float u = fA01*fB1-fA11*fB0; + float v = fA01*fB0-fA00*fB1; + float SqrDist; + + if(u + v <= fDet) + { + if(u < 0.0f) + { + if(v < 0.0f) // region 4 + { + if(fB0 < 0.0f) + { +// v = 0.0f; + if(-fB0>=fA00) { /*u = 1.0f;*/ SqrDist = fA00+2.0f*fB0+fC; } + else { u = -fB0/fA00; SqrDist = fB0*u+fC; } + } + else + { +// u = 0.0f; + if(fB1>=0.0f) { /*v = 0.0f;*/ SqrDist = fC; } + else if(-fB1>=fA11) { /*v = 1.0f;*/ SqrDist = fA11+2.0f*fB1+fC; } + else { v = -fB1/fA11; SqrDist = fB1*v+fC; } + } + } + else // region 3 + { +// u = 0.0f; + if(fB1>=0.0f) { /*v = 0.0f;*/ SqrDist = fC; } + else if(-fB1>=fA11) { /*v = 1.0f;*/ SqrDist = fA11+2.0f*fB1+fC; } + else { v = -fB1/fA11; SqrDist = fB1*v+fC; } + } + } + else if(v < 0.0f) // region 5 + { +// v = 0.0f; + if(fB0>=0.0f) { /*u = 0.0f;*/ SqrDist = fC; } + else if(-fB0>=fA00) { /*u = 1.0f;*/ SqrDist = fA00+2.0f*fB0+fC; } + else { u = -fB0/fA00; SqrDist = fB0*u+fC; } + } + else // region 0 + { + // minimum at interior point + if(fDet==0.0f) + { +// u = 0.0f; +// v = 0.0f; + SqrDist = MAX_FLOAT; + } + else + { + float fInvDet = 1.0f/fDet; + u *= fInvDet; + v *= fInvDet; + SqrDist = u*(fA00*u+fA01*v+2.0f*fB0) + v*(fA01*u+fA11*v+2.0f*fB1)+fC; + } + } + } + else + { + float fTmp0, fTmp1, fNumer, fDenom; + + if(u < 0.0f) // region 2 + { + fTmp0 = fA01 + fB0; + fTmp1 = fA11 + fB1; + if(fTmp1 > fTmp0) + { + fNumer = fTmp1 - fTmp0; + fDenom = fA00-2.0f*fA01+fA11; + if(fNumer >= fDenom) + { +// u = 1.0f; +// v = 0.0f; + SqrDist = fA00+2.0f*fB0+fC; + } + else + { + u = fNumer/fDenom; + v = 1.0f - u; + SqrDist = u*(fA00*u+fA01*v+2.0f*fB0) + v*(fA01*u+fA11*v+2.0f*fB1)+fC; + } + } + else + { +// u = 0.0f; + if(fTmp1 <= 0.0f) { /*v = 1.0f;*/ SqrDist = fA11+2.0f*fB1+fC; } + else if(fB1 >= 0.0f) { /*v = 0.0f;*/ SqrDist = fC; } + else { v = -fB1/fA11; SqrDist = fB1*v+fC; } + } + } + else if(v < 0.0f) // region 6 + { + fTmp0 = fA01 + fB1; + fTmp1 = fA00 + fB0; + if(fTmp1 > fTmp0) + { + fNumer = fTmp1 - fTmp0; + fDenom = fA00-2.0f*fA01+fA11; + if(fNumer >= fDenom) + { +// v = 1.0f; +// u = 0.0f; + SqrDist = fA11+2.0f*fB1+fC; + } + else + { + v = fNumer/fDenom; + u = 1.0f - v; + SqrDist = u*(fA00*u+fA01*v+2.0f*fB0) + v*(fA01*u+fA11*v+2.0f*fB1)+fC; + } + } + else + { +// v = 0.0f; + if(fTmp1 <= 0.0f) { /*u = 1.0f;*/ SqrDist = fA00+2.0f*fB0+fC; } + else if(fB0 >= 0.0f) { /*u = 0.0f;*/ SqrDist = fC; } + else { u = -fB0/fA00; SqrDist = fB0*u+fC; } + } + } + else // region 1 + { + fNumer = fA11 + fB1 - fA01 - fB0; + if(fNumer <= 0.0f) + { +// u = 0.0f; +// v = 1.0f; + SqrDist = fA11+2.0f*fB1+fC; + } + else + { + fDenom = fA00-2.0f*fA01+fA11; + if(fNumer >= fDenom) + { +// u = 1.0f; +// v = 0.0f; + SqrDist = fA00+2.0f*fB0+fC; + } + else + { + u = fNumer/fDenom; + v = 1.0f - u; + SqrDist = u*(fA00*u+fA01*v+2.0f*fB0) + v*(fA01*u+fA11*v+2.0f*fB1)+fC; + } + } + } + } + + return fabsf(SqrDist) < mRadius2; +} diff --git a/libs/ode-0.16.1/OPCODE/OPC_TreeBuilders.cpp b/libs/ode-0.16.1/OPCODE/OPC_TreeBuilders.cpp new file mode 100644 index 0000000..4a78914 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_TreeBuilders.cpp @@ -0,0 +1,306 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for tree builders. + * \file OPC_TreeBuilders.cpp + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * A builder for AABB-trees of vertices. + * + * \class AABBTreeOfVerticesBuilder + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * A builder for AABB-trees of AABBs. + * + * \class AABBTreeOfAABBsBuilder + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * A builder for AABB-trees of triangles. + * + * \class AABBTreeOfTrianglesBuilder + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the AABB of a set of primitives. + * \param primitives [in] list of indices of primitives + * \param nb_prims [in] number of indices + * \param global_box [out] global AABB enclosing the set of input primitives + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBTreeOfAABBsBuilder::ComputeGlobalBox(const dTriIndex* primitives, udword nb_prims, AABB& global_box) const +{ + // Checkings + if(!primitives || !nb_prims) return false; + + // Initialize global box + global_box = mAABBArray[primitives[0]]; + + // Loop through boxes + for(udword i=1;i<nb_prims;i++) + { + // Update global box + global_box.Add(mAABBArray[primitives[i]]); + } + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the splitting value along a given axis for a given primitive. + * \param index [in] index of the primitive to split + * \param axis [in] axis index (0,1,2) + * \return splitting value + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float AABBTreeOfAABBsBuilder::GetSplittingValue(udword index, udword axis) const +{ + // For an AABB, the splitting value is the middle of the given axis, + // i.e. the corresponding component of the center point + return mAABBArray[index].GetCenter(axis); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the splitting value along a given axis for a given primitive. + * \param index [in] index of the primitive to split + * \return splitting value + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Point AABBTreeOfAABBsBuilder::GetSplittingValues(udword index) const +{ + // For an AABB, the splitting value is the middle of the given axis, + // i.e. the corresponding component of the center point + Point p; + mAABBArray[index].GetCenter(p); + return p; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the AABB of a set of primitives. + * \param primitives [in] list of indices of primitives + * \param nb_prims [in] number of indices + * \param global_box [out] global AABB enclosing the set of input primitives + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBTreeOfTrianglesBuilder::ComputeGlobalBox(const dTriIndex* primitives, udword nb_prims, AABB& global_box) const +{ + // Checkings + if(!primitives || !nb_prims) return false; + + // Initialize global box + Point Min(MAX_FLOAT, MAX_FLOAT, MAX_FLOAT); + Point Max(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT); + + // Loop through triangles + VertexPointers VP; + ConversionArea VC; + while(nb_prims--) + { + // Get current triangle-vertices + mIMesh->GetTriangle(VP, *primitives++, VC); + // Update global box + Min.Min(*VP.Vertex[0]).Min(*VP.Vertex[1]).Min(*VP.Vertex[2]); + Max.Max(*VP.Vertex[0]).Max(*VP.Vertex[1]).Max(*VP.Vertex[2]); + } + global_box.SetMinMax(Min, Max); + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the splitting value along a given axis for a given primitive. + * \param index [in] index of the primitive to split + * \return splitting value + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Point AABBTreeOfTrianglesBuilder::GetSplittingValues(udword index) const +{ + VertexPointers VP; + ConversionArea VC; + mIMesh->GetTriangle(VP, index, VC); + + return ( *VP.Vertex[0] + *VP.Vertex[1] + *VP.Vertex[2] ) * INV3; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the splitting value along a given axis for a given primitive. + * \param index [in] index of the primitive to split + * \param axis [in] axis index (0,1,2) + * \return splitting value + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float AABBTreeOfTrianglesBuilder::GetSplittingValue(udword index, udword axis) const +{ +/* // Compute center of triangle + Point Center; + mTriList[index].Center(mVerts, Center); + // Return value + return Center[axis];*/ + + // Compute correct component from center of triangle +// return (mVerts[mTriList[index].mVRef[0]][axis] +// +mVerts[mTriList[index].mVRef[1]][axis] +// +mVerts[mTriList[index].mVRef[2]][axis])*INV3; + + VertexPointers VP; + ConversionArea VC; + mIMesh->GetTriangle(VP, index, VC); + + // Compute correct component from center of triangle + return ((*VP.Vertex[0])[axis] + +(*VP.Vertex[1])[axis] + +(*VP.Vertex[2])[axis])*INV3; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the splitting value along a given axis for a given node. + * \param primitives [in] list of indices of primitives + * \param nb_prims [in] number of indices + * \param global_box [in] global AABB enclosing the set of input primitives + * \param axis [in] axis index (0,1,2) + * \return splitting value + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float AABBTreeOfTrianglesBuilder::GetSplittingValue(const dTriIndex* primitives, udword nb_prims, const AABB& global_box, udword axis) const +{ + if(mSettings.mRules&SPLIT_GEOM_CENTER) + { + // Loop through triangles + float SplitValue = 0.0f; + VertexPointers VP; + ConversionArea VC; + for(udword i=0;i<nb_prims;i++) + { + // Get current triangle-vertices + mIMesh->GetTriangle(VP, primitives[i], VC); + // Update split value + SplitValue += (*VP.Vertex[0])[axis]; + SplitValue += (*VP.Vertex[1])[axis]; + SplitValue += (*VP.Vertex[2])[axis]; + } + return SplitValue / float(nb_prims*3); + } + else return AABBTreeBuilder::GetSplittingValue(primitives, nb_prims, global_box, axis); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the AABB of a set of primitives. + * \param primitives [in] list of indices of primitives + * \param nb_prims [in] number of indices + * \param global_box [out] global AABB enclosing the set of input primitives + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBTreeOfVerticesBuilder::ComputeGlobalBox(const dTriIndex* primitives, udword nb_prims, AABB& global_box) const +{ + // Checkings + if(!primitives || !nb_prims) return false; + + // Initialize global box + global_box.SetEmpty(); + + // Loop through vertices + for(udword i=0;i<nb_prims;i++) + { + // Update global box + global_box.Extend(mVertexArray[primitives[i]]); + } + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the splitting value along a given axis for a given primitive. + * \param index [in] index of the primitive to split + * \param axis [in] axis index (0,1,2) + * \return splitting value + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float AABBTreeOfVerticesBuilder::GetSplittingValue(udword index, udword axis) const +{ + // For a vertex, the splitting value is simply the vertex coordinate. + return mVertexArray[index][axis]; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the splitting value along a given axis for a given primitive. + * \param index [in] index of the primitive to split + * \param axis [in] axis index (0,1,2) + * \return splitting value + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Point AABBTreeOfVerticesBuilder::GetSplittingValues(udword index) const +{ + // For a vertex, the splitting value is simply the vertex coordinate. + return mVertexArray[index]; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the splitting value along a given axis for a given node. + * \param primitives [in] list of indices of primitives + * \param nb_prims [in] number of indices + * \param global_box [in] global AABB enclosing the set of input primitives + * \param axis [in] axis index (0,1,2) + * \return splitting value + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float AABBTreeOfVerticesBuilder::GetSplittingValue(const dTriIndex* primitives, udword nb_prims, const AABB& global_box, udword axis) const +{ + if(mSettings.mRules&SPLIT_GEOM_CENTER) + { + // Loop through vertices + float SplitValue = 0.0f; + for(udword i=0;i<nb_prims;i++) + { + // Update split value + SplitValue += mVertexArray[primitives[i]][axis]; + } + return SplitValue / float(nb_prims); + } + else return AABBTreeBuilder::GetSplittingValue(primitives, nb_prims, global_box, axis); +} diff --git a/libs/ode-0.16.1/OPCODE/OPC_TreeBuilders.h b/libs/ode-0.16.1/OPCODE/OPC_TreeBuilders.h new file mode 100644 index 0000000..66e9480 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_TreeBuilders.h @@ -0,0 +1,178 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for tree builders. + * \file OPC_TreeBuilders.h + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_TREEBUILDERS_H__ +#define __OPC_TREEBUILDERS_H__ + + //! Tree splitting rules + enum SplittingRules + { + // Primitive split + SPLIT_LARGEST_AXIS = (1<<0), //!< Split along the largest axis + SPLIT_SPLATTER_POINTS = (1<<1), //!< Splatter primitive centers (QuickCD-style) + SPLIT_BEST_AXIS = (1<<2), //!< Try largest axis, then second, then last + SPLIT_BALANCED = (1<<3), //!< Try to keep a well-balanced tree + SPLIT_FIFTY = (1<<4), //!< Arbitrary 50-50 split + // Node split + SPLIT_GEOM_CENTER = (1<<5), //!< Split at geometric center (else split in the middle) + // + SPLIT_FORCE_DWORD = 0x7fffffff + }; + + //! Simple wrapper around build-related settings [Opcode 1.3] + struct OPCODE_API BuildSettings + { + inline_ BuildSettings() : mLimit(1), mRules(SPLIT_FORCE_DWORD) {} + inline_ explicit BuildSettings(udword Rules) : mLimit(1), mRules(Rules) {} + + udword mLimit; //!< Limit number of primitives / node. If limit is 1, build a complete tree (2*N-1 nodes) + udword mRules; //!< Building/Splitting rules (a combination of SplittingRules flags) + }; + + class OPCODE_API AABBTreeBuilder + { + public: + //! Constructor + AABBTreeBuilder() : + mNbPrimitives(0), + mNodeBase(null), + mCount(0), + mNbInvalidSplits(0) {} + //! Destructor + virtual ~AABBTreeBuilder() {} + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes the AABB of a set of primitives. + * \param primitives [in] list of indices of primitives + * \param nb_prims [in] number of indices + * \param global_box [out] global AABB enclosing the set of input primitives + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual bool ComputeGlobalBox(const dTriIndex* primitives, udword nb_prims, AABB& global_box) const = 0; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes the splitting value along a given axis for a given primitive. + * \param index [in] index of the primitive to split + * \param axis [in] axis index (0,1,2) + * \return splitting value + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual float GetSplittingValue(udword index, udword axis) const = 0; + virtual Point GetSplittingValues(udword index) const = 0; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes the splitting value along a given axis for a given node. + * \param primitives [in] list of indices of primitives + * \param nb_prims [in] number of indices + * \param global_box [in] global AABB enclosing the set of input primitives + * \param axis [in] axis index (0,1,2) + * \return splitting value + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual float GetSplittingValue(const dTriIndex* /*primitives*/, udword /*nb_prims*/, const AABB& global_box, udword axis) const + { + // Default split value = middle of the axis (using only the box) + return global_box.GetCenter(axis); + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Validates node subdivision. This is called each time a node is considered for subdivision, during tree building. + * \param primitives [in] list of indices of primitives + * \param nb_prims [in] number of indices + * \param global_box [in] global AABB enclosing the set of input primitives + * \return TRUE if the node should be subdivised + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual BOOL ValidateSubdivision(const dTriIndex* /*primitives*/, udword nb_prims, const AABB& /*global_box*/) + { + // Check the user-defined limit + if(nb_prims<=mSettings.mLimit) return FALSE; + + return TRUE; + } + + BuildSettings mSettings; //!< Splitting rules & split limit [Opcode 1.3] + udword mNbPrimitives; //!< Total number of primitives. + void* mNodeBase; //!< Address of node pool [Opcode 1.3] + // Stats + inline_ void SetCount(udword nb) { mCount=nb; } + inline_ void IncreaseCount(udword nb) { mCount+=nb; } + inline_ udword GetCount() const { return mCount; } + inline_ void SetNbInvalidSplits(udword nb) { mNbInvalidSplits=nb; } + inline_ void IncreaseNbInvalidSplits() { mNbInvalidSplits++; } + inline_ udword GetNbInvalidSplits() const { return mNbInvalidSplits; } + + private: + udword mCount; //!< Stats: number of nodes created + udword mNbInvalidSplits; //!< Stats: number of invalid splits + }; + + class OPCODE_API AABBTreeOfVerticesBuilder : public AABBTreeBuilder + { + public: + //! Constructor + AABBTreeOfVerticesBuilder() : mVertexArray(null) {} + //! Destructor + virtual ~AABBTreeOfVerticesBuilder() {} + + override(AABBTreeBuilder) bool ComputeGlobalBox(const dTriIndex* primitives, udword nb_prims, AABB& global_box) const; + override(AABBTreeBuilder) float GetSplittingValue(udword index, udword axis) const; + override(AABBTreeBuilder) Point GetSplittingValues(udword index) const; + override(AABBTreeBuilder) float GetSplittingValue(const dTriIndex* primitives, udword nb_prims, const AABB& global_box, udword axis) const; + + const Point* mVertexArray; //!< Shortcut to an app-controlled array of vertices. + }; + + class OPCODE_API AABBTreeOfAABBsBuilder : public AABBTreeBuilder + { + public: + //! Constructor + AABBTreeOfAABBsBuilder() : mAABBArray(null) {} + //! Destructor + virtual ~AABBTreeOfAABBsBuilder() {} + + override(AABBTreeBuilder) bool ComputeGlobalBox(const dTriIndex* primitives, udword nb_prims, AABB& global_box) const; + override(AABBTreeBuilder) float GetSplittingValue(udword index, udword axis) const; + override(AABBTreeBuilder) Point GetSplittingValues(udword index) const; + + const AABB* mAABBArray; //!< Shortcut to an app-controlled array of AABBs. + }; + + class OPCODE_API AABBTreeOfTrianglesBuilder : public AABBTreeBuilder + { + public: + //! Constructor + AABBTreeOfTrianglesBuilder() : mIMesh(null) {} + //! Destructor + virtual ~AABBTreeOfTrianglesBuilder() {} + + override(AABBTreeBuilder) bool ComputeGlobalBox(const dTriIndex* primitives, udword nb_prims, AABB& global_box) const; + override(AABBTreeBuilder) float GetSplittingValue(udword index, udword axis) const; + override(AABBTreeBuilder) float GetSplittingValue(const dTriIndex* primitives, udword nb_prims, const AABB& global_box, udword axis) const; + override(AABBTreeBuilder) Point GetSplittingValues(udword index) const; + + const MeshInterface* mIMesh; //!< Shortcut to an app-controlled mesh interface + }; + +#endif // __OPC_TREEBUILDERS_H__ diff --git a/libs/ode-0.16.1/OPCODE/OPC_TreeCollider.cpp b/libs/ode-0.16.1/OPCODE/OPC_TreeCollider.cpp new file mode 100644 index 0000000..ff625f9 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_TreeCollider.cpp @@ -0,0 +1,947 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for a tree collider. + * \file OPC_TreeCollider.cpp + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains an AABB tree collider. + * This class performs a collision test between two AABB trees. + * + * \class AABBTreeCollider + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +#include "OPC_BoxBoxOverlap.h" +#include "OPC_TriBoxOverlap.h" +#include "OPC_TriTriOverlap.h" + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBTreeCollider::AABBTreeCollider() : + mIMesh0 (null), + mIMesh1 (null), + mNbBVBVTests (0), + mNbPrimPrimTests (0), + mNbBVPrimTests (0), + mFullBoxBoxTest (true), + mFullPrimBoxTest (true) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBTreeCollider::~AABBTreeCollider() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Validates current settings. You should call this method after all the settings and callbacks have been defined. + * \return null if everything is ok, else a string describing the problem + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +const char* AABBTreeCollider::ValidateSettings() +{ + if(TemporalCoherenceEnabled() && !FirstContactEnabled()) return "Temporal coherence only works with ""First contact"" mode!"; + return null; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Generic collision query for generic OPCODE models. After the call, access the results with: + * - GetContactStatus() + * - GetNbPairs() + * - GetPairs() + * + * \param cache [in] collision cache for model pointers and a colliding pair of primitives + * \param world0 [in] world matrix for first object + * \param world1 [in] world matrix for second object + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBTreeCollider::Collide(BVTCache& cache, const Matrix4x4* world0, const Matrix4x4* world1) +{ + // Checkings + if(!cache.Model0 || !cache.Model1) return false; + if(cache.Model0->HasLeafNodes()!=cache.Model1->HasLeafNodes()) return false; + if(cache.Model0->IsQuantized()!=cache.Model1->IsQuantized()) return false; + + /* + + Rules: + - perform hull test + - when hulls collide, disable hull test + - if meshes overlap, reset countdown + - if countdown reaches 0, enable hull test + + */ + +#ifdef __MESHMERIZER_H__ + // Handle hulls + if(cache.HullTest) + { + if(cache.Model0->GetHull() && cache.Model1->GetHull()) + { + struct Local + { + static Point* SVCallback(const Point& sv, udword& previndex, udword user_data) + { + CollisionHull* Hull = (CollisionHull*)user_data; + previndex = Hull->ComputeSupportingVertex(sv, previndex); + return (Point*)&Hull->GetVerts()[previndex]; + } + }; + + bool Collide; + + if(0) + { + static GJKEngine GJK; -- not thread safe, store in ThreadLocalData + static bool GJKInitDone=false; -- not thread safe, to be removed + if(!GJKInitDone) + { + GJK.Enable(GJK_BACKUP_PROCEDURE); + GJK.Enable(GJK_DEGENERATE); + GJK.Enable(GJK_HILLCLIMBING); + GJKInitDone = true; + } + GJK.SetCallbackObj0(Local::SVCallback); + GJK.SetCallbackObj1(Local::SVCallback); + GJK.SetUserData0(udword(cache.Model0->GetHull())); + GJK.SetUserData1(udword(cache.Model1->GetHull())); + Collide = GJK.Collide(*world0, *world1, &cache.SepVector); + } + else + { + static SVEngine SVE; -- not thread safe, store in ThreadLocalData + SVE.SetCallbackObj0(Local::SVCallback); + SVE.SetCallbackObj1(Local::SVCallback); + SVE.SetUserData0(udword(cache.Model0->GetHull())); + SVE.SetUserData1(udword(cache.Model1->GetHull())); + Collide = SVE.Collide(*world0, *world1, &cache.SepVector); + } + + if(!Collide) + { + // Reset stats & contact status + mFlags &= ~OPC_CONTACT; + mNbBVBVTests = 0; + mNbPrimPrimTests = 0; + mNbBVPrimTests = 0; + mPairs.Reset(); + return true; + } + } + } + + // Here, hulls collide + cache.HullTest = false; +#endif // __MESHMERIZER_H__ + + // Checkings + if(!Setup(cache.Model0->GetMeshInterface(), cache.Model1->GetMeshInterface())) return false; + + // Simple double-dispatch + bool Status; + if(!cache.Model0->HasLeafNodes()) + { + if(cache.Model0->IsQuantized()) + { + const AABBQuantizedNoLeafTree* T0 = static_cast<const AABBQuantizedNoLeafTree *>(cache.Model0->GetTree()); + const AABBQuantizedNoLeafTree* T1 = static_cast<const AABBQuantizedNoLeafTree *>(cache.Model1->GetTree()); + Status = Collide(T0, T1, world0, world1, &cache); + } + else + { + const AABBNoLeafTree* T0 = static_cast<const AABBNoLeafTree *>(cache.Model0->GetTree()); + const AABBNoLeafTree* T1 = static_cast<const AABBNoLeafTree *>(cache.Model1->GetTree()); + Status = Collide(T0, T1, world0, world1, &cache); + } + } + else + { + if(cache.Model0->IsQuantized()) + { + const AABBQuantizedTree* T0 = static_cast<const AABBQuantizedTree *>(cache.Model0->GetTree()); + const AABBQuantizedTree* T1 = static_cast<const AABBQuantizedTree *>(cache.Model1->GetTree()); + Status = Collide(T0, T1, world0, world1, &cache); + } + else + { + const AABBCollisionTree* T0 = static_cast<const AABBCollisionTree *>(cache.Model0->GetTree()); + const AABBCollisionTree* T1 = static_cast<const AABBCollisionTree *>(cache.Model1->GetTree()); + Status = Collide(T0, T1, world0, world1, &cache); + } + } + +#ifdef __MESHMERIZER_H__ + if(Status) + { + // Reset counter as long as overlap occurs + if(GetContactStatus()) cache.ResetCountDown(); + + // Enable hull test again when counter reaches zero + cache.CountDown--; + if(!cache.CountDown) + { + cache.ResetCountDown(); + cache.HullTest = true; + } + } +#endif + return Status; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Initializes a collision query : + * - reset stats & contact status + * - setup matrices + * + * \param world0 [in] world matrix for first object + * \param world1 [in] world matrix for second object + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeCollider::InitQuery(const Matrix4x4* world0, const Matrix4x4* world1) +{ + // Reset stats & contact status + Collider::InitQuery(); + mNbBVBVTests = 0; + mNbPrimPrimTests = 0; + mNbBVPrimTests = 0; + mPairs.Reset(); + + // Setup matrices + Matrix4x4 InvWorld0, InvWorld1; + if(world0) InvertPRMatrix(InvWorld0, *world0); + else InvWorld0.Identity(); + + if(world1) InvertPRMatrix(InvWorld1, *world1); + else InvWorld1.Identity(); + + Matrix4x4 World0to1 = world0 ? (*world0 * InvWorld1) : InvWorld1; + Matrix4x4 World1to0 = world1 ? (*world1 * InvWorld0) : InvWorld0; + + mR0to1 = World0to1; World0to1.GetTrans(mT0to1); + mR1to0 = World1to0; World1to0.GetTrans(mT1to0); + + // Precompute absolute 1-to-0 rotation matrix + for(udword i=0;i<3;i++) + { + for(udword j=0;j<3;j++) + { + // Epsilon value prevents floating-point inaccuracies (strategy borrowed from RAPID) + mAR.m[i][j] = 1e-6f + fabsf(mR1to0.m[i][j]); + } + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Takes advantage of temporal coherence. + * \param cache [in] cache for a pair of previously colliding primitives + * \return true if we can return immediately + * \warning only works for "First Contact" mode + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBTreeCollider::CheckTemporalCoherence(Pair* cache) +{ + // Checkings + if(!cache) return false; + + // Test previously colliding primitives first + if(TemporalCoherenceEnabled() && FirstContactEnabled()) + { + PrimTest(cache->id0, cache->id1); + if(GetContactStatus()) return true; + } + return false; +} + +#define UPDATE_CACHE \ + if(cache && GetContactStatus()) \ + { \ + cache->id0 = mPairs.GetEntry(0); \ + cache->id1 = mPairs.GetEntry(1); \ + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Collision query for normal AABB trees. + * \param tree0 [in] AABB tree from first object + * \param tree1 [in] AABB tree from second object + * \param world0 [in] world matrix for first object + * \param world1 [in] world matrix for second object + * \param cache [in/out] cache for a pair of previously colliding primitives + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBTreeCollider::Collide(const AABBCollisionTree* tree0, const AABBCollisionTree* tree1, const Matrix4x4* world0, const Matrix4x4* world1, Pair* cache) +{ + // Init collision query + InitQuery(world0, world1); + + // Check previous state + if(CheckTemporalCoherence(cache)) return true; + + // Perform collision query + _Collide(tree0->GetNodes(), tree1->GetNodes()); + + UPDATE_CACHE + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Collision query for no-leaf AABB trees. + * \param tree0 [in] AABB tree from first object + * \param tree1 [in] AABB tree from second object + * \param world0 [in] world matrix for first object + * \param world1 [in] world matrix for second object + * \param cache [in/out] cache for a pair of previously colliding primitives + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBTreeCollider::Collide(const AABBNoLeafTree* tree0, const AABBNoLeafTree* tree1, const Matrix4x4* world0, const Matrix4x4* world1, Pair* cache) +{ + // Init collision query + InitQuery(world0, world1); + + // Check previous state + if(CheckTemporalCoherence(cache)) return true; + + // Perform collision query + _Collide(tree0->GetNodes(), tree1->GetNodes()); + + UPDATE_CACHE + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Collision query for quantized AABB trees. + * \param tree0 [in] AABB tree from first object + * \param tree1 [in] AABB tree from second object + * \param world0 [in] world matrix for first object + * \param world1 [in] world matrix for second object + * \param cache [in/out] cache for a pair of previously colliding primitives + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBTreeCollider::Collide(const AABBQuantizedTree* tree0, const AABBQuantizedTree* tree1, const Matrix4x4* world0, const Matrix4x4* world1, Pair* cache) +{ + // Init collision query + InitQuery(world0, world1); + + // Check previous state + if(CheckTemporalCoherence(cache)) return true; + + // Setup dequantization coeffs + mCenterCoeff0 = tree0->mCenterCoeff; + mExtentsCoeff0 = tree0->mExtentsCoeff; + mCenterCoeff1 = tree1->mCenterCoeff; + mExtentsCoeff1 = tree1->mExtentsCoeff; + + // Dequantize box A + const AABBQuantizedNode* N0 = tree0->GetNodes(); + const Point a(float(N0->mAABB.mExtents[0]) * mExtentsCoeff0.x, float(N0->mAABB.mExtents[1]) * mExtentsCoeff0.y, float(N0->mAABB.mExtents[2]) * mExtentsCoeff0.z); + const Point Pa(float(N0->mAABB.mCenter[0]) * mCenterCoeff0.x, float(N0->mAABB.mCenter[1]) * mCenterCoeff0.y, float(N0->mAABB.mCenter[2]) * mCenterCoeff0.z); + // Dequantize box B + const AABBQuantizedNode* N1 = tree1->GetNodes(); + const Point b(float(N1->mAABB.mExtents[0]) * mExtentsCoeff1.x, float(N1->mAABB.mExtents[1]) * mExtentsCoeff1.y, float(N1->mAABB.mExtents[2]) * mExtentsCoeff1.z); + const Point Pb(float(N1->mAABB.mCenter[0]) * mCenterCoeff1.x, float(N1->mAABB.mCenter[1]) * mCenterCoeff1.y, float(N1->mAABB.mCenter[2]) * mCenterCoeff1.z); + + // Perform collision query + _Collide(N0, N1, a, Pa, b, Pb); + + UPDATE_CACHE + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Collision query for quantized no-leaf AABB trees. + * \param tree0 [in] AABB tree from first object + * \param tree1 [in] AABB tree from second object + * \param world0 [in] world matrix for first object + * \param world1 [in] world matrix for second object + * \param cache [in/out] cache for a pair of previously colliding primitives + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABBTreeCollider::Collide(const AABBQuantizedNoLeafTree* tree0, const AABBQuantizedNoLeafTree* tree1, const Matrix4x4* world0, const Matrix4x4* world1, Pair* cache) +{ + // Init collision query + InitQuery(world0, world1); + + // Check previous state + if(CheckTemporalCoherence(cache)) return true; + + // Setup dequantization coeffs + mCenterCoeff0 = tree0->mCenterCoeff; + mExtentsCoeff0 = tree0->mExtentsCoeff; + mCenterCoeff1 = tree1->mCenterCoeff; + mExtentsCoeff1 = tree1->mExtentsCoeff; + + // Perform collision query + _Collide(tree0->GetNodes(), tree1->GetNodes()); + + UPDATE_CACHE + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Standard trees +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// The normal AABB tree can use 2 different descent rules (with different performances) +//#define ORIGINAL_CODE //!< UNC-like descent rules +#define ALTERNATIVE_CODE //!< Alternative descent rules + +#ifdef ORIGINAL_CODE +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for normal AABB trees. + * \param b0 [in] collision node from first tree + * \param b1 [in] collision node from second tree + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeCollider::_Collide(const AABBCollisionNode* b0, const AABBCollisionNode* b1) +{ + // Perform BV-BV overlap test + if(!BoxBoxOverlap(b0->mAABB.mExtents, b0->mAABB.mCenter, b1->mAABB.mExtents, b1->mAABB.mCenter)) return; + + if(b0->IsLeaf() && b1->IsLeaf()) { PrimTest(b0->GetPrimitive(), b1->GetPrimitive()); return; } + + if(b1->IsLeaf() || (!b0->IsLeaf() && (b0->GetSize() > b1->GetSize()))) + { + _Collide(b0->GetNeg(), b1); + if(ContactFound()) return; + _Collide(b0->GetPos(), b1); + } + else + { + _Collide(b0, b1->GetNeg()); + if(ContactFound()) return; + _Collide(b0, b1->GetPos()); + } +} +#endif + +#ifdef ALTERNATIVE_CODE +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for normal AABB trees. + * \param b0 [in] collision node from first tree + * \param b1 [in] collision node from second tree + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeCollider::_Collide(const AABBCollisionNode* b0, const AABBCollisionNode* b1) +{ + // Perform BV-BV overlap test + if(!BoxBoxOverlap(b0->mAABB.mExtents, b0->mAABB.mCenter, b1->mAABB.mExtents, b1->mAABB.mCenter)) + { + return; + } + + if(b0->IsLeaf()) + { + if(b1->IsLeaf()) + { + PrimTest(b0->GetPrimitive(), b1->GetPrimitive()); + } + else + { + _Collide(b0, b1->GetNeg()); + if(ContactFound()) return; + _Collide(b0, b1->GetPos()); + } + } + else if(b1->IsLeaf()) + { + _Collide(b0->GetNeg(), b1); + if(ContactFound()) return; + _Collide(b0->GetPos(), b1); + } + else + { + _Collide(b0->GetNeg(), b1->GetNeg()); + if(ContactFound()) return; + _Collide(b0->GetNeg(), b1->GetPos()); + if(ContactFound()) return; + _Collide(b0->GetPos(), b1->GetNeg()); + if(ContactFound()) return; + _Collide(b0->GetPos(), b1->GetPos()); + } +} +#endif + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// No-leaf trees +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Leaf-leaf test for two primitive indices. + * \param id0 [in] index from first leaf-triangle + * \param id1 [in] index from second leaf-triangle + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeCollider::PrimTest(udword id0, udword id1) +{ + // Request vertices from the app + VertexPointers VP0; + VertexPointers VP1; + ConversionArea VC0; + ConversionArea VC1; + mIMesh0->GetTriangle(VP0, id0, VC0); + mIMesh1->GetTriangle(VP1, id1, VC1); + + // Transform from space 1 to space 0 + Point u0,u1,u2; + TransformPoint(u0, *VP1.Vertex[0], mR1to0, mT1to0); + TransformPoint(u1, *VP1.Vertex[1], mR1to0, mT1to0); + TransformPoint(u2, *VP1.Vertex[2], mR1to0, mT1to0); + + // Perform triangle-triangle overlap test + if(TriTriOverlap(*VP0.Vertex[0], *VP0.Vertex[1], *VP0.Vertex[2], u0, u1, u2)) + { + // Keep track of colliding pairs + mPairs.Add(id0).Add(id1); + // Set contact status + mFlags |= OPC_CONTACT; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Leaf-leaf test for a previously fetched triangle from tree A (in B's space) and a new leaf from B. + * \param id1 [in] leaf-triangle index from tree B + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ void AABBTreeCollider::PrimTestTriIndex(udword id1) +{ + // Request vertices from the app + VertexPointers VP; + ConversionArea VC; + mIMesh1->GetTriangle(VP, id1, VC); + + // Perform triangle-triangle overlap test + if(TriTriOverlap(mLeafVerts[0], mLeafVerts[1], mLeafVerts[2], *VP.Vertex[0], *VP.Vertex[1], *VP.Vertex[2])) + { + // Keep track of colliding pairs + mPairs.Add(mLeafIndex).Add(id1); + // Set contact status + mFlags |= OPC_CONTACT; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Leaf-leaf test for a previously fetched triangle from tree B (in A's space) and a new leaf from A. + * \param id0 [in] leaf-triangle index from tree A + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ void AABBTreeCollider::PrimTestIndexTri(udword id0) +{ + // Request vertices from the app + VertexPointers VP; + ConversionArea VC; + mIMesh0->GetTriangle(VP, id0, VC); + + // Perform triangle-triangle overlap test + if(TriTriOverlap(mLeafVerts[0], mLeafVerts[1], mLeafVerts[2], *VP.Vertex[0], *VP.Vertex[1], *VP.Vertex[2])) + { + // Keep track of colliding pairs + mPairs.Add(id0).Add(mLeafIndex); + // Set contact status + mFlags |= OPC_CONTACT; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision of a leaf node from A and a branch from B. + * \param b [in] collision node from second tree + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeCollider::_CollideTriBox(const AABBNoLeafNode* b) +{ + // Perform triangle-box overlap test + if(!TriBoxOverlap(b->mAABB.mCenter, b->mAABB.mExtents)) return; + + // Keep same triangle, deal with first child + if(b->HasPosLeaf()) PrimTestTriIndex(b->GetPosPrimitive()); + else _CollideTriBox(b->GetPos()); + + if(ContactFound()) return; + + // Keep same triangle, deal with second child + if(b->HasNegLeaf()) PrimTestTriIndex(b->GetNegPrimitive()); + else _CollideTriBox(b->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision of a leaf node from B and a branch from A. + * \param b [in] collision node from first tree + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeCollider::_CollideBoxTri(const AABBNoLeafNode* b) +{ + // Perform triangle-box overlap test + if(!TriBoxOverlap(b->mAABB.mCenter, b->mAABB.mExtents)) return; + + // Keep same triangle, deal with first child + if(b->HasPosLeaf()) PrimTestIndexTri(b->GetPosPrimitive()); + else _CollideBoxTri(b->GetPos()); + + if(ContactFound()) return; + + // Keep same triangle, deal with second child + if(b->HasNegLeaf()) PrimTestIndexTri(b->GetNegPrimitive()); + else _CollideBoxTri(b->GetNeg()); +} + +//! Request triangle vertices from the app and transform them +#define FETCH_LEAF(prim_index, imesh, rot, trans) \ + mLeafIndex = prim_index; \ + /* Request vertices from the app */ \ + VertexPointers VP; ConversionArea VC; imesh->GetTriangle(VP, prim_index, VC); \ + /* Transform them in a common space */ \ + TransformPoint(mLeafVerts[0], *VP.Vertex[0], rot, trans); \ + TransformPoint(mLeafVerts[1], *VP.Vertex[1], rot, trans); \ + TransformPoint(mLeafVerts[2], *VP.Vertex[2], rot, trans); + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for no-leaf AABB trees. + * \param a [in] collision node from first tree + * \param b [in] collision node from second tree + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeCollider::_Collide(const AABBNoLeafNode* a, const AABBNoLeafNode* b) +{ + // Perform BV-BV overlap test + if(!BoxBoxOverlap(a->mAABB.mExtents, a->mAABB.mCenter, b->mAABB.mExtents, b->mAABB.mCenter)) return; + + // Catch leaf status + BOOL BHasPosLeaf = b->HasPosLeaf(); + BOOL BHasNegLeaf = b->HasNegLeaf(); + + if(a->HasPosLeaf()) + { + FETCH_LEAF(a->GetPosPrimitive(), mIMesh0, mR0to1, mT0to1) + + if(BHasPosLeaf) PrimTestTriIndex(b->GetPosPrimitive()); + else _CollideTriBox(b->GetPos()); + + if(ContactFound()) return; + + if(BHasNegLeaf) PrimTestTriIndex(b->GetNegPrimitive()); + else _CollideTriBox(b->GetNeg()); + } + else + { + if(BHasPosLeaf) + { + FETCH_LEAF(b->GetPosPrimitive(), mIMesh1, mR1to0, mT1to0) + + _CollideBoxTri(a->GetPos()); + } + else _Collide(a->GetPos(), b->GetPos()); + + if(ContactFound()) return; + + if(BHasNegLeaf) + { + FETCH_LEAF(b->GetNegPrimitive(), mIMesh1, mR1to0, mT1to0) + + _CollideBoxTri(a->GetPos()); + } + else _Collide(a->GetPos(), b->GetNeg()); + } + + if(ContactFound()) return; + + if(a->HasNegLeaf()) + { + FETCH_LEAF(a->GetNegPrimitive(), mIMesh0, mR0to1, mT0to1) + + if(BHasPosLeaf) PrimTestTriIndex(b->GetPosPrimitive()); + else _CollideTriBox(b->GetPos()); + + if(ContactFound()) return; + + if(BHasNegLeaf) PrimTestTriIndex(b->GetNegPrimitive()); + else _CollideTriBox(b->GetNeg()); + } + else + { + if(BHasPosLeaf) + { + // ### That leaf has possibly already been fetched + FETCH_LEAF(b->GetPosPrimitive(), mIMesh1, mR1to0, mT1to0) + + _CollideBoxTri(a->GetNeg()); + } + else _Collide(a->GetNeg(), b->GetPos()); + + if(ContactFound()) return; + + if(BHasNegLeaf) + { + // ### That leaf has possibly already been fetched + FETCH_LEAF(b->GetNegPrimitive(), mIMesh1, mR1to0, mT1to0) + + _CollideBoxTri(a->GetNeg()); + } + else _Collide(a->GetNeg(), b->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Quantized trees +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized AABB trees. + * \param b0 [in] collision node from first tree + * \param b1 [in] collision node from second tree + * \param a [in] extent from box A + * \param Pa [in] center from box A + * \param b [in] extent from box B + * \param Pb [in] center from box B + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeCollider::_Collide(const AABBQuantizedNode* b0, const AABBQuantizedNode* b1, const Point& a, const Point& Pa, const Point& b, const Point& Pb) +{ + // Perform BV-BV overlap test + if(!BoxBoxOverlap(a, Pa, b, Pb)) return; + + if(b0->IsLeaf() && b1->IsLeaf()) { PrimTest(b0->GetPrimitive(), b1->GetPrimitive()); return; } + + if(b1->IsLeaf() || (!b0->IsLeaf() && (b0->GetSize() > b1->GetSize()))) + { + // Dequantize box + const QuantizedAABB* Box = &b0->GetNeg()->mAABB; + const Point negPa(float(Box->mCenter[0]) * mCenterCoeff0.x, float(Box->mCenter[1]) * mCenterCoeff0.y, float(Box->mCenter[2]) * mCenterCoeff0.z); + const Point nega(float(Box->mExtents[0]) * mExtentsCoeff0.x, float(Box->mExtents[1]) * mExtentsCoeff0.y, float(Box->mExtents[2]) * mExtentsCoeff0.z); + _Collide(b0->GetNeg(), b1, nega, negPa, b, Pb); + + if(ContactFound()) return; + + // Dequantize box + Box = &b0->GetPos()->mAABB; + const Point posPa(float(Box->mCenter[0]) * mCenterCoeff0.x, float(Box->mCenter[1]) * mCenterCoeff0.y, float(Box->mCenter[2]) * mCenterCoeff0.z); + const Point posa(float(Box->mExtents[0]) * mExtentsCoeff0.x, float(Box->mExtents[1]) * mExtentsCoeff0.y, float(Box->mExtents[2]) * mExtentsCoeff0.z); + _Collide(b0->GetPos(), b1, posa, posPa, b, Pb); + } + else + { + // Dequantize box + const QuantizedAABB* Box = &b1->GetNeg()->mAABB; + const Point negPb(float(Box->mCenter[0]) * mCenterCoeff1.x, float(Box->mCenter[1]) * mCenterCoeff1.y, float(Box->mCenter[2]) * mCenterCoeff1.z); + const Point negb(float(Box->mExtents[0]) * mExtentsCoeff1.x, float(Box->mExtents[1]) * mExtentsCoeff1.y, float(Box->mExtents[2]) * mExtentsCoeff1.z); + _Collide(b0, b1->GetNeg(), a, Pa, negb, negPb); + + if(ContactFound()) return; + + // Dequantize box + Box = &b1->GetPos()->mAABB; + const Point posPb(float(Box->mCenter[0]) * mCenterCoeff1.x, float(Box->mCenter[1]) * mCenterCoeff1.y, float(Box->mCenter[2]) * mCenterCoeff1.z); + const Point posb(float(Box->mExtents[0]) * mExtentsCoeff1.x, float(Box->mExtents[1]) * mExtentsCoeff1.y, float(Box->mExtents[2]) * mExtentsCoeff1.z); + _Collide(b0, b1->GetPos(), a, Pa, posb, posPb); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Quantized no-leaf trees +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision of a leaf node from A and a quantized branch from B. + * \param leaf [in] leaf triangle from first tree + * \param b [in] collision node from second tree + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeCollider::_CollideTriBox(const AABBQuantizedNoLeafNode* b) +{ + // Dequantize box + const QuantizedAABB* bb = &b->mAABB; + const Point Pb(float(bb->mCenter[0]) * mCenterCoeff1.x, float(bb->mCenter[1]) * mCenterCoeff1.y, float(bb->mCenter[2]) * mCenterCoeff1.z); + const Point eb(float(bb->mExtents[0]) * mExtentsCoeff1.x, float(bb->mExtents[1]) * mExtentsCoeff1.y, float(bb->mExtents[2]) * mExtentsCoeff1.z); + + // Perform triangle-box overlap test + if(!TriBoxOverlap(Pb, eb)) return; + + if(b->HasPosLeaf()) PrimTestTriIndex(b->GetPosPrimitive()); + else _CollideTriBox(b->GetPos()); + + if(ContactFound()) return; + + if(b->HasNegLeaf()) PrimTestTriIndex(b->GetNegPrimitive()); + else _CollideTriBox(b->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision of a leaf node from B and a quantized branch from A. + * \param b [in] collision node from first tree + * \param leaf [in] leaf triangle from second tree + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeCollider::_CollideBoxTri(const AABBQuantizedNoLeafNode* b) +{ + // Dequantize box + const QuantizedAABB* bb = &b->mAABB; + const Point Pa(float(bb->mCenter[0]) * mCenterCoeff0.x, float(bb->mCenter[1]) * mCenterCoeff0.y, float(bb->mCenter[2]) * mCenterCoeff0.z); + const Point ea(float(bb->mExtents[0]) * mExtentsCoeff0.x, float(bb->mExtents[1]) * mExtentsCoeff0.y, float(bb->mExtents[2]) * mExtentsCoeff0.z); + + // Perform triangle-box overlap test + if(!TriBoxOverlap(Pa, ea)) return; + + if(b->HasPosLeaf()) PrimTestIndexTri(b->GetPosPrimitive()); + else _CollideBoxTri(b->GetPos()); + + if(ContactFound()) return; + + if(b->HasNegLeaf()) PrimTestIndexTri(b->GetNegPrimitive()); + else _CollideBoxTri(b->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized no-leaf AABB trees. + * \param a [in] collision node from first tree + * \param b [in] collision node from second tree + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeCollider::_Collide(const AABBQuantizedNoLeafNode* a, const AABBQuantizedNoLeafNode* b) +{ + // Dequantize box A + const QuantizedAABB* ab = &a->mAABB; + const Point Pa(float(ab->mCenter[0]) * mCenterCoeff0.x, float(ab->mCenter[1]) * mCenterCoeff0.y, float(ab->mCenter[2]) * mCenterCoeff0.z); + const Point ea(float(ab->mExtents[0]) * mExtentsCoeff0.x, float(ab->mExtents[1]) * mExtentsCoeff0.y, float(ab->mExtents[2]) * mExtentsCoeff0.z); + // Dequantize box B + const QuantizedAABB* bb = &b->mAABB; + const Point Pb(float(bb->mCenter[0]) * mCenterCoeff1.x, float(bb->mCenter[1]) * mCenterCoeff1.y, float(bb->mCenter[2]) * mCenterCoeff1.z); + const Point eb(float(bb->mExtents[0]) * mExtentsCoeff1.x, float(bb->mExtents[1]) * mExtentsCoeff1.y, float(bb->mExtents[2]) * mExtentsCoeff1.z); + + // Perform BV-BV overlap test + if(!BoxBoxOverlap(ea, Pa, eb, Pb)) return; + + // Catch leaf status + BOOL BHasPosLeaf = b->HasPosLeaf(); + BOOL BHasNegLeaf = b->HasNegLeaf(); + + if(a->HasPosLeaf()) + { + FETCH_LEAF(a->GetPosPrimitive(), mIMesh0, mR0to1, mT0to1) + + if(BHasPosLeaf) PrimTestTriIndex(b->GetPosPrimitive()); + else _CollideTriBox(b->GetPos()); + + if(ContactFound()) return; + + if(BHasNegLeaf) PrimTestTriIndex(b->GetNegPrimitive()); + else _CollideTriBox(b->GetNeg()); + } + else + { + if(BHasPosLeaf) + { + FETCH_LEAF(b->GetPosPrimitive(), mIMesh1, mR1to0, mT1to0) + + _CollideBoxTri(a->GetPos()); + } + else _Collide(a->GetPos(), b->GetPos()); + + if(ContactFound()) return; + + if(BHasNegLeaf) + { + FETCH_LEAF(b->GetNegPrimitive(), mIMesh1, mR1to0, mT1to0) + + _CollideBoxTri(a->GetPos()); + } + else _Collide(a->GetPos(), b->GetNeg()); + } + + if(ContactFound()) return; + + if(a->HasNegLeaf()) + { + FETCH_LEAF(a->GetNegPrimitive(), mIMesh0, mR0to1, mT0to1) + + if(BHasPosLeaf) PrimTestTriIndex(b->GetPosPrimitive()); + else _CollideTriBox(b->GetPos()); + + if(ContactFound()) return; + + if(BHasNegLeaf) PrimTestTriIndex(b->GetNegPrimitive()); + else _CollideTriBox(b->GetNeg()); + } + else + { + if(BHasPosLeaf) + { + // ### That leaf has possibly already been fetched + FETCH_LEAF(b->GetPosPrimitive(), mIMesh1, mR1to0, mT1to0) + + _CollideBoxTri(a->GetNeg()); + } + else _Collide(a->GetNeg(), b->GetPos()); + + if(ContactFound()) return; + + if(BHasNegLeaf) + { + // ### That leaf has possibly already been fetched + FETCH_LEAF(b->GetNegPrimitive(), mIMesh1, mR1to0, mT1to0) + + _CollideBoxTri(a->GetNeg()); + } + else _Collide(a->GetNeg(), b->GetNeg()); + } +} diff --git a/libs/ode-0.16.1/OPCODE/OPC_TreeCollider.h b/libs/ode-0.16.1/OPCODE/OPC_TreeCollider.h new file mode 100644 index 0000000..1e943a4 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_TreeCollider.h @@ -0,0 +1,246 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for a tree collider. + * \file OPC_TreeCollider.h + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_TREECOLLIDER_H__ +#define __OPC_TREECOLLIDER_H__ + + //! This structure holds cached information used by the algorithm. + //! Two model pointers and two colliding primitives are cached. Model pointers are assigned + //! to their respective meshes, and the pair of colliding primitives is used for temporal + //! coherence. That is, in case temporal coherence is enabled, those two primitives are + //! tested for overlap before everything else. If they still collide, we're done before + //! even entering the recursive collision code. + struct OPCODE_API BVTCache : Pair + { + //! Constructor + inline_ BVTCache() + { + ResetCache(); + ResetCountDown(); + } + + void ResetCache() + { + Model0 = null; + Model1 = null; + id0 = 0; + id1 = 1; +#ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE ! + HullTest = true; + SepVector.pid = 0; + SepVector.qid = 0; + SepVector.SV = Point(1.0f, 0.0f, 0.0f); +#endif // __MESHMERIZER_H__ + } + +#ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE ! + inline_ void ResetCountDown() + { + CountDown = 50; + } +#else + void ResetCountDown(){}; +#endif // __MESHMERIZER_H__ + + const Model* Model0; //!< Model for first object + const Model* Model1; //!< Model for second object + +#ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE ! + SVCache SepVector; + udword CountDown; + bool HullTest; +#endif // __MESHMERIZER_H__ + }; + + class OPCODE_API AABBTreeCollider : public Collider + { + public: + // Constructor / Destructor + AABBTreeCollider(); + virtual ~AABBTreeCollider(); + // Generic collision query + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Generic collision query for generic OPCODE models. After the call, access the results with: + * - GetContactStatus() + * - GetNbPairs() + * - GetPairs() + * + * \param cache [in] collision cache for model pointers and a colliding pair of primitives + * \param world0 [in] world matrix for first object, or null + * \param world1 [in] world matrix for second object, or null + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool Collide(BVTCache& cache, const Matrix4x4* world0=null, const Matrix4x4* world1=null); + + // Collision queries + bool Collide(const AABBCollisionTree* tree0, const AABBCollisionTree* tree1, const Matrix4x4* world0=null, const Matrix4x4* world1=null, Pair* cache=null); + bool Collide(const AABBNoLeafTree* tree0, const AABBNoLeafTree* tree1, const Matrix4x4* world0=null, const Matrix4x4* world1=null, Pair* cache=null); + bool Collide(const AABBQuantizedTree* tree0, const AABBQuantizedTree* tree1, const Matrix4x4* world0=null, const Matrix4x4* world1=null, Pair* cache=null); + bool Collide(const AABBQuantizedNoLeafTree* tree0, const AABBQuantizedNoLeafTree* tree1, const Matrix4x4* world0=null, const Matrix4x4* world1=null, Pair* cache=null); + // Settings + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Settings: selects between full box-box tests or "SAT-lite" tests (where Class III axes are discarded) + * \param flag [in] true for full tests, false for coarse tests + * \see SetFullPrimBoxTest(bool flag) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetFullBoxBoxTest(bool flag) { mFullBoxBoxTest = flag; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Settings: selects between full triangle-box tests or "SAT-lite" tests (where Class III axes are discarded) + * \param flag [in] true for full tests, false for coarse tests + * \see SetFullBoxBoxTest(bool flag) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetFullPrimBoxTest(bool flag) { mFullPrimBoxTest = flag; } + + // Stats + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Stats: gets the number of BV-BV overlap tests after a collision query. + * \see GetNbPrimPrimTests() + * \see GetNbBVPrimTests() + * \return the number of BV-BV tests performed during last query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbBVBVTests() const { return mNbBVBVTests; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Stats: gets the number of Triangle-Triangle overlap tests after a collision query. + * \see GetNbBVBVTests() + * \see GetNbBVPrimTests() + * \return the number of Triangle-Triangle tests performed during last query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbPrimPrimTests() const { return mNbPrimPrimTests; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Stats: gets the number of BV-Triangle overlap tests after a collision query. + * \see GetNbBVBVTests() + * \see GetNbPrimPrimTests() + * \return the number of BV-Triangle tests performed during last query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbBVPrimTests() const { return mNbBVPrimTests; } + + // Data access + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the number of contacts after a collision query. + * \see GetContactStatus() + * \see GetPairs() + * \return the number of contacts / colliding pairs. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbPairs() const { return mPairs.GetNbEntries()>>1; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the pairs of colliding triangles after a collision query. + * \see GetContactStatus() + * \see GetNbPairs() + * \return the list of colliding pairs (triangle indices) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ const Pair* GetPairs() const { return (const Pair*)mPairs.GetEntries(); } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Validates current settings. You should call this method after all the settings and callbacks have been defined for a collider. + * \return null if everything is ok, else a string describing the problem + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(Collider) const char* ValidateSettings(); + + protected: + // Colliding pairs + Container mPairs; //!< Pairs of colliding primitives + // User mesh interfaces + const MeshInterface* mIMesh0; //!< User-defined mesh interface for object0 + const MeshInterface* mIMesh1; //!< User-defined mesh interface for object1 + // Stats + udword mNbBVBVTests; //!< Number of BV-BV tests + udword mNbPrimPrimTests; //!< Number of Primitive-Primitive tests + udword mNbBVPrimTests; //!< Number of BV-Primitive tests + // Precomputed data + Matrix3x3 mAR; //!< Absolute rotation matrix + Matrix3x3 mR0to1; //!< Rotation from object0 to object1 + Matrix3x3 mR1to0; //!< Rotation from object1 to object0 + Point mT0to1; //!< Translation from object0 to object1 + Point mT1to0; //!< Translation from object1 to object0 + // Dequantization coeffs + Point mCenterCoeff0; + Point mExtentsCoeff0; + Point mCenterCoeff1; + Point mExtentsCoeff1; + // Leaf description + Point mLeafVerts[3]; //!< Triangle vertices + udword mLeafIndex; //!< Triangle index + // Settings + bool mFullBoxBoxTest; //!< Perform full BV-BV tests (true) or SAT-lite tests (false) + bool mFullPrimBoxTest; //!< Perform full Primitive-BV tests (true) or SAT-lite tests (false) + // Internal methods + + // Standard AABB trees + void _Collide(const AABBCollisionNode* b0, const AABBCollisionNode* b1); + // Quantized AABB trees + void _Collide(const AABBQuantizedNode* b0, const AABBQuantizedNode* b1, const Point& a, const Point& Pa, const Point& b, const Point& Pb); + // No-leaf AABB trees + void _CollideTriBox(const AABBNoLeafNode* b); + void _CollideBoxTri(const AABBNoLeafNode* b); + void _Collide(const AABBNoLeafNode* a, const AABBNoLeafNode* b); + // Quantized no-leaf AABB trees + void _CollideTriBox(const AABBQuantizedNoLeafNode* b); + void _CollideBoxTri(const AABBQuantizedNoLeafNode* b); + void _Collide(const AABBQuantizedNoLeafNode* a, const AABBQuantizedNoLeafNode* b); + // Overlap tests + void PrimTest(udword id0, udword id1); + inline_ void PrimTestTriIndex(udword id1); + inline_ void PrimTestIndexTri(udword id0); + + inline_ BOOL BoxBoxOverlap(const Point& ea, const Point& ca, const Point& eb, const Point& cb); + inline_ BOOL TriBoxOverlap(const Point& center, const Point& extents); + inline_ BOOL TriTriOverlap(const Point& V0, const Point& V1, const Point& V2, const Point& U0, const Point& U1, const Point& U2); + // Init methods + void InitQuery(const Matrix4x4* world0=null, const Matrix4x4* world1=null); + bool CheckTemporalCoherence(Pair* cache); + + inline_ BOOL Setup(const MeshInterface* mi0, const MeshInterface* mi1) + { + mIMesh0 = mi0; + mIMesh1 = mi1; + + if(!mIMesh0 || !mIMesh1) return FALSE; + + return TRUE; + } + }; + +#endif // __OPC_TREECOLLIDER_H__ diff --git a/libs/ode-0.16.1/OPCODE/OPC_TriBoxOverlap.h b/libs/ode-0.16.1/OPCODE/OPC_TriBoxOverlap.h new file mode 100644 index 0000000..b3a9bde --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_TriBoxOverlap.h @@ -0,0 +1,339 @@ + +//! This macro quickly finds the min & max values among 3 variables +#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; + +//! TO BE DOCUMENTED +inline_ BOOL planeBoxOverlap(const Point& normal, const float d, const Point& maxbox) +{ + Point vmin, vmax; + for(udword q=0;q<=2;q++) + { + if(normal[q]>0.0f) { vmin[q]=-maxbox[q]; vmax[q]=maxbox[q]; } + else { vmin[q]=maxbox[q]; vmax[q]=-maxbox[q]; } + } + if((normal|vmin)+d>0.0f) return FALSE; + if((normal|vmax)+d>=0.0f) return TRUE; + + return FALSE; +} + +//! TO BE DOCUMENTED +#define AXISTEST_X01(a, b, fa, fb) \ + min = a*v0.y - b*v0.z; \ + max = a*v2.y - b*v2.z; \ + if(min>max) {const float tmp=max; max=min; min=tmp; } \ + rad = fa * extents.y + fb * extents.z; \ + if(min>rad || max<-rad) return FALSE; + +//! TO BE DOCUMENTED +#define AXISTEST_X2(a, b, fa, fb) \ + min = a*v0.y - b*v0.z; \ + max = a*v1.y - b*v1.z; \ + if(min>max) {const float tmp=max; max=min; min=tmp; } \ + rad = fa * extents.y + fb * extents.z; \ + if(min>rad || max<-rad) return FALSE; + +//! TO BE DOCUMENTED +#define AXISTEST_Y02(a, b, fa, fb) \ + min = b*v0.z - a*v0.x; \ + max = b*v2.z - a*v2.x; \ + if(min>max) {const float tmp=max; max=min; min=tmp; } \ + rad = fa * extents.x + fb * extents.z; \ + if(min>rad || max<-rad) return FALSE; + +//! TO BE DOCUMENTED +#define AXISTEST_Y1(a, b, fa, fb) \ + min = b*v0.z - a*v0.x; \ + max = b*v1.z - a*v1.x; \ + if(min>max) {const float tmp=max; max=min; min=tmp; } \ + rad = fa * extents.x + fb * extents.z; \ + if(min>rad || max<-rad) return FALSE; + +//! TO BE DOCUMENTED +#define AXISTEST_Z12(a, b, fa, fb) \ + min = a*v1.x - b*v1.y; \ + max = a*v2.x - b*v2.y; \ + if(min>max) {const float tmp=max; max=min; min=tmp; } \ + rad = fa * extents.x + fb * extents.y; \ + if(min>rad || max<-rad) return FALSE; + +//! TO BE DOCUMENTED +#define AXISTEST_Z0(a, b, fa, fb) \ + min = a*v0.x - b*v0.y; \ + max = a*v1.x - b*v1.y; \ + if(min>max) {const float tmp=max; max=min; min=tmp; } \ + rad = fa * extents.x + fb * extents.y; \ + if(min>rad || max<-rad) return FALSE; + +// compute triangle edges +// - edges lazy evaluated to take advantage of early exits +// - fabs precomputed (half less work, possible since extents are always >0) +// - customized macros to take advantage of the null component +// - axis vector discarded, possibly saves useless movs +#define IMPLEMENT_CLASS3_TESTS \ + float rad; \ + float min, max; \ + \ + const float fey0 = fabsf(e0.y); \ + const float fez0 = fabsf(e0.z); \ + AXISTEST_X01(e0.z, e0.y, fez0, fey0); \ + const float fex0 = fabsf(e0.x); \ + AXISTEST_Y02(e0.z, e0.x, fez0, fex0); \ + AXISTEST_Z12(e0.y, e0.x, fey0, fex0); \ + \ + const float fey1 = fabsf(e1.y); \ + const float fez1 = fabsf(e1.z); \ + AXISTEST_X01(e1.z, e1.y, fez1, fey1); \ + const float fex1 = fabsf(e1.x); \ + AXISTEST_Y02(e1.z, e1.x, fez1, fex1); \ + AXISTEST_Z0(e1.y, e1.x, fey1, fex1); \ + \ + const Point e2 = mLeafVerts[0] - mLeafVerts[2]; \ + const float fey2 = fabsf(e2.y); \ + const float fez2 = fabsf(e2.z); \ + AXISTEST_X2(e2.z, e2.y, fez2, fey2); \ + const float fex2 = fabsf(e2.x); \ + AXISTEST_Y1(e2.z, e2.x, fez2, fex2); \ + AXISTEST_Z12(e2.y, e2.x, fey2, fex2); + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Triangle-Box overlap test using the separating axis theorem. + * This is the code from Tomas Möller, a bit optimized: + * - with some more lazy evaluation (faster path on PC) + * - with a tiny bit of assembly + * - with "SAT-lite" applied if needed + * - and perhaps with some more minor modifs... + * + * \param center [in] box center + * \param extents [in] box extents + * \return true if triangle & box overlap + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL AABBTreeCollider::TriBoxOverlap(const Point& center, const Point& extents) +{ + // Stats + mNbBVPrimTests++; + + // 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 + + // move everything so that the boxcenter is in (0,0,0) + Point v0, v1, v2; + v0.x = mLeafVerts[0].x - center.x; + v1.x = mLeafVerts[1].x - center.x; + v2.x = mLeafVerts[2].x - center.x; + + // First, test overlap in the {x,y,z}-directions +#ifdef OPC_USE_FCOMI + // find min, max of the triangle in x-direction, and test for overlap in X + if(FCMin3(v0.x, v1.x, v2.x)>extents.x) return FALSE; + if(FCMax3(v0.x, v1.x, v2.x)<-extents.x) return FALSE; + + // same for Y + v0.y = mLeafVerts[0].y - center.y; + v1.y = mLeafVerts[1].y - center.y; + v2.y = mLeafVerts[2].y - center.y; + + if(FCMin3(v0.y, v1.y, v2.y)>extents.y) return FALSE; + if(FCMax3(v0.y, v1.y, v2.y)<-extents.y) return FALSE; + + // same for Z + v0.z = mLeafVerts[0].z - center.z; + v1.z = mLeafVerts[1].z - center.z; + v2.z = mLeafVerts[2].z - center.z; + + if(FCMin3(v0.z, v1.z, v2.z)>extents.z) return FALSE; + if(FCMax3(v0.z, v1.z, v2.z)<-extents.z) return FALSE; +#else + float min,max; + // Find min, max of the triangle in x-direction, and test for overlap in X + FINDMINMAX(v0.x, v1.x, v2.x, min, max); + if(min>extents.x || max<-extents.x) return FALSE; + + // Same for Y + v0.y = mLeafVerts[0].y - center.y; + v1.y = mLeafVerts[1].y - center.y; + v2.y = mLeafVerts[2].y - center.y; + + FINDMINMAX(v0.y, v1.y, v2.y, min, max); + if(min>extents.y || max<-extents.y) return FALSE; + + // Same for Z + v0.z = mLeafVerts[0].z - center.z; + v1.z = mLeafVerts[1].z - center.z; + v2.z = mLeafVerts[2].z - center.z; + + FINDMINMAX(v0.z, v1.z, v2.z, min, max); + if(min>extents.z || max<-extents.z) return FALSE; +#endif + // 2) Test if the box intersects the plane of the triangle + // compute plane equation of triangle: normal*x+d=0 + // ### could be precomputed since we use the same leaf triangle several times + const Point e0 = v1 - v0; + const Point e1 = v2 - v1; + const Point normal = e0 ^ e1; + const float d = -normal|v0; + if(!planeBoxOverlap(normal, d, extents)) return FALSE; + + // 3) "Class III" tests + if(mFullPrimBoxTest) + { + IMPLEMENT_CLASS3_TESTS + } + return TRUE; +} + +//! A dedicated version where the box is constant +inline_ BOOL OBBCollider::TriBoxOverlap() +{ + // Stats + mNbVolumePrimTests++; + + // Hook + const Point& extents = mBoxExtents; + const Point& v0 = mLeafVerts[0]; + const Point& v1 = mLeafVerts[1]; + const Point& v2 = mLeafVerts[2]; + + // 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 + + // Box center is already in (0,0,0) + + // First, test overlap in the {x,y,z}-directions +#ifdef OPC_USE_FCOMI + // find min, max of the triangle in x-direction, and test for overlap in X + if(FCMin3(v0.x, v1.x, v2.x)>mBoxExtents.x) return FALSE; + if(FCMax3(v0.x, v1.x, v2.x)<-mBoxExtents.x) return FALSE; + + if(FCMin3(v0.y, v1.y, v2.y)>mBoxExtents.y) return FALSE; + if(FCMax3(v0.y, v1.y, v2.y)<-mBoxExtents.y) return FALSE; + + if(FCMin3(v0.z, v1.z, v2.z)>mBoxExtents.z) return FALSE; + if(FCMax3(v0.z, v1.z, v2.z)<-mBoxExtents.z) return FALSE; +#else + float min,max; + // Find min, max of the triangle in x-direction, and test for overlap in X + FINDMINMAX(v0.x, v1.x, v2.x, min, max); + if(min>mBoxExtents.x || max<-mBoxExtents.x) return FALSE; + + FINDMINMAX(v0.y, v1.y, v2.y, min, max); + if(min>mBoxExtents.y || max<-mBoxExtents.y) return FALSE; + + FINDMINMAX(v0.z, v1.z, v2.z, min, max); + if(min>mBoxExtents.z || max<-mBoxExtents.z) return FALSE; +#endif + // 2) Test if the box intersects the plane of the triangle + // compute plane equation of triangle: normal*x+d=0 + // ### could be precomputed since we use the same leaf triangle several times + const Point e0 = v1 - v0; + const Point e1 = v2 - v1; + const Point normal = e0 ^ e1; + const float d = -normal|v0; + if(!planeBoxOverlap(normal, d, mBoxExtents)) return FALSE; + + // 3) "Class III" tests - here we always do full tests since the box is a primitive (not a BV) + { + IMPLEMENT_CLASS3_TESTS + } + return TRUE; +} + +//! ...and another one, jeez +inline_ BOOL AABBCollider::TriBoxOverlap() +{ + // Stats + mNbVolumePrimTests++; + + // Hook + const Point& center = mBox.mCenter; + const Point& extents = mBox.mExtents; + + // 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 + + // move everything so that the boxcenter is in (0,0,0) + Point v0, v1, v2; + v0.x = mLeafVerts[0].x - center.x; + v1.x = mLeafVerts[1].x - center.x; + v2.x = mLeafVerts[2].x - center.x; + + // First, test overlap in the {x,y,z}-directions +#ifdef OPC_USE_FCOMI + // find min, max of the triangle in x-direction, and test for overlap in X + if(FCMin3(v0.x, v1.x, v2.x)>extents.x) return FALSE; + if(FCMax3(v0.x, v1.x, v2.x)<-extents.x) return FALSE; + + // same for Y + v0.y = mLeafVerts[0].y - center.y; + v1.y = mLeafVerts[1].y - center.y; + v2.y = mLeafVerts[2].y - center.y; + + if(FCMin3(v0.y, v1.y, v2.y)>extents.y) return FALSE; + if(FCMax3(v0.y, v1.y, v2.y)<-extents.y) return FALSE; + + // same for Z + v0.z = mLeafVerts[0].z - center.z; + v1.z = mLeafVerts[1].z - center.z; + v2.z = mLeafVerts[2].z - center.z; + + if(FCMin3(v0.z, v1.z, v2.z)>extents.z) return FALSE; + if(FCMax3(v0.z, v1.z, v2.z)<-extents.z) return FALSE; +#else + float min,max; + // Find min, max of the triangle in x-direction, and test for overlap in X + FINDMINMAX(v0.x, v1.x, v2.x, min, max); + if(min>extents.x || max<-extents.x) return FALSE; + + // Same for Y + v0.y = mLeafVerts[0].y - center.y; + v1.y = mLeafVerts[1].y - center.y; + v2.y = mLeafVerts[2].y - center.y; + + FINDMINMAX(v0.y, v1.y, v2.y, min, max); + if(min>extents.y || max<-extents.y) return FALSE; + + // Same for Z + v0.z = mLeafVerts[0].z - center.z; + v1.z = mLeafVerts[1].z - center.z; + v2.z = mLeafVerts[2].z - center.z; + + FINDMINMAX(v0.z, v1.z, v2.z, min, max); + if(min>extents.z || max<-extents.z) return FALSE; +#endif + // 2) Test if the box intersects the plane of the triangle + // compute plane equation of triangle: normal*x+d=0 + // ### could be precomputed since we use the same leaf triangle several times + const Point e0 = v1 - v0; + const Point e1 = v2 - v1; + const Point normal = e0 ^ e1; + const float d = -normal|v0; + if(!planeBoxOverlap(normal, d, extents)) return FALSE; + + // 3) "Class III" tests - here we always do full tests since the box is a primitive (not a BV) + { + IMPLEMENT_CLASS3_TESTS + } + return TRUE; +} diff --git a/libs/ode-0.16.1/OPCODE/OPC_TriTriOverlap.h b/libs/ode-0.16.1/OPCODE/OPC_TriTriOverlap.h new file mode 100644 index 0000000..fd652c9 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_TriTriOverlap.h @@ -0,0 +1,299 @@ + +//! if OPC_TRITRI_EPSILON_TEST is true then we do a check (if |dv|<EPSILON then dv=0.0;) else no check is done (which is less robust, but faster) +#define LOCAL_EPSILON 0.000001f + +//! sort so that a<=b +#define SORT(a,b) \ + if(a>b) \ + { \ + const float c=a; \ + a=b; \ + b=c; \ + } + +//! Edge to edge test based on Franlin Antonio's gem: "Faster Line Segment Intersection", in Graphics Gems III, pp. 199-202 +#define EDGE_EDGE_TEST(V0, U0, U1) \ + Bx = U0[i0] - U1[i0]; \ + By = U0[i1] - U1[i1]; \ + Cx = V0[i0] - U0[i0]; \ + Cy = V0[i1] - U0[i1]; \ + f = Ay*Bx - Ax*By; \ + d = By*Cx - Bx*Cy; \ + if((f>0.0f && d>=0.0f && d<=f) || (f<0.0f && d<=0.0f && d>=f)) \ + { \ + const float e=Ax*Cy - Ay*Cx; \ + if(f>0.0f) \ + { \ + if(e>=0.0f && e<=f) return TRUE; \ + } \ + else \ + { \ + if(e<=0.0f && e>=f) return TRUE; \ + } \ + } + +//! TO BE DOCUMENTED +#define EDGE_AGAINST_TRI_EDGES(V0, V1, U0, U1, U2) \ +{ \ + float Bx,By,Cx,Cy,d,f; \ + const float Ax = V1[i0] - V0[i0]; \ + const float Ay = V1[i1] - V0[i1]; \ + /* test edge U0,U1 against V0,V1 */ \ + EDGE_EDGE_TEST(V0, U0, U1); \ + /* test edge U1,U2 against V0,V1 */ \ + EDGE_EDGE_TEST(V0, U1, U2); \ + /* test edge U2,U1 against V0,V1 */ \ + EDGE_EDGE_TEST(V0, U2, U0); \ +} + +//! TO BE DOCUMENTED +#define POINT_IN_TRI(V0, U0, U1, U2) \ +{ \ + /* is T1 completly inside T2? */ \ + /* check if V0 is inside tri(U0,U1,U2) */ \ + float a = U1[i1] - U0[i1]; \ + float b = -(U1[i0] - U0[i0]); \ + float c = -a*U0[i0] - b*U0[i1]; \ + float d0 = a*V0[i0] + b*V0[i1] + c; \ + \ + a = U2[i1] - U1[i1]; \ + b = -(U2[i0] - U1[i0]); \ + c = -a*U1[i0] - b*U1[i1]; \ + const float d1 = a*V0[i0] + b*V0[i1] + c; \ + \ + a = U0[i1] - U2[i1]; \ + b = -(U0[i0] - U2[i0]); \ + c = -a*U2[i0] - b*U2[i1]; \ + const float d2 = a*V0[i0] + b*V0[i1] + c; \ + if(d0*d1>0.0f) \ + { \ + if(d0*d2>0.0f) return TRUE; \ + } \ +} + +//! TO BE DOCUMENTED +BOOL CoplanarTriTri(const Point& n, const Point& v0, const Point& v1, const Point& v2, const Point& u0, const Point& u1, const Point& u2) +{ + float A[3]; + short i0,i1; + /* first project onto an axis-aligned plane, that maximizes the area */ + /* of the triangles, compute indices: i0,i1. */ + A[0] = fabsf(n[0]); + A[1] = fabsf(n[1]); + A[2] = fabsf(n[2]); + if(A[0]>A[1]) + { + if(A[0]>A[2]) + { + i0=1; /* A[0] is greatest */ + i1=2; + } + else + { + i0=0; /* A[2] is greatest */ + i1=1; + } + } + else /* A[0]<=A[1] */ + { + if(A[2]>A[1]) + { + i0=0; /* A[2] is greatest */ + i1=1; + } + else + { + i0=0; /* A[1] is greatest */ + i1=2; + } + } + + /* test all edges of triangle 1 against the edges of triangle 2 */ + EDGE_AGAINST_TRI_EDGES(v0, v1, u0, u1, u2); + EDGE_AGAINST_TRI_EDGES(v1, v2, u0, u1, u2); + EDGE_AGAINST_TRI_EDGES(v2, v0, u0, u1, u2); + + /* finally, test if tri1 is totally contained in tri2 or vice versa */ + POINT_IN_TRI(v0, u0, u1, u2); + POINT_IN_TRI(u0, v0, v1, v2); + + return FALSE; +} + +//! TO BE DOCUMENTED +#define NEWCOMPUTE_INTERVALS(VV0, VV1, VV2, D0, D1, D2, D0D1, D0D2, A, B, C, X0, X1) \ +{ \ + 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 */ \ + A=VV2; B=(VV0 - VV2)*D2; C=(VV1 - VV2)*D2; X0=D2 - D0; X1=D2 - D1; \ + } \ + else if(D0D2>0.0f) \ + { \ + /* here we know that d0d1<=0.0 */ \ + A=VV1; B=(VV0 - VV1)*D1; C=(VV2 - VV1)*D1; X0=D1 - D0; X1=D1 - D2; \ + } \ + else if(D1*D2>0.0f || D0!=0.0f) \ + { \ + /* here we know that d0d1<=0.0 or that D0!=0.0 */ \ + A=VV0; B=(VV1 - VV0)*D0; C=(VV2 - VV0)*D0; X0=D0 - D1; X1=D0 - D2; \ + } \ + else if(D1!=0.0f) \ + { \ + A=VV1; B=(VV0 - VV1)*D1; C=(VV2 - VV1)*D1; X0=D1 - D0; X1=D1 - D2; \ + } \ + else if(D2!=0.0f) \ + { \ + A=VV2; B=(VV0 - VV2)*D2; C=(VV1 - VV2)*D2; X0=D2 - D0; X1=D2 - D1; \ + } \ + else \ + { \ + /* triangles are coplanar */ \ + return CoplanarTriTri(N1, V0, V1, V2, U0, U1, U2); \ + } \ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Triangle/triangle intersection test routine, + * by Tomas Moller, 1997. + * See article "A Fast Triangle-Triangle Intersection Test", + * Journal of Graphics Tools, 2(2), 1997 + * + * Updated June 1999: removed the divisions -- a little faster now! + * Updated October 1999: added {} to CROSS and SUB macros + * + * int NoDivTriTriIsect(float V0[3],float V1[3],float V2[3], + * float U0[3],float U1[3],float U2[3]) + * + * \param V0 [in] triangle 0, vertex 0 + * \param V1 [in] triangle 0, vertex 1 + * \param V2 [in] triangle 0, vertex 2 + * \param U0 [in] triangle 1, vertex 0 + * \param U1 [in] triangle 1, vertex 1 + * \param U2 [in] triangle 1, vertex 2 + * \return true if triangles overlap + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL AABBTreeCollider::TriTriOverlap(const Point& V0, const Point& V1, const Point& V2, const Point& U0, const Point& U1, const Point& U2) +{ + // Stats + mNbPrimPrimTests++; + + // Compute plane equation of triangle(V0,V1,V2) + Point E1 = V1 - V0; + Point E2 = V2 - V0; + const Point N1 = E1 ^ E2; + const float d1 =-N1 | V0; + // Plane equation 1: N1.X+d1=0 + + // Put U0,U1,U2 into plane equation 1 to compute signed distances to the plane + float du0 = (N1|U0) + d1; + float du1 = (N1|U1) + d1; + float du2 = (N1|U2) + d1; + + // Coplanarity robustness check +#ifdef OPC_TRITRI_EPSILON_TEST + float absd1 = FastFabs(d1), sqmagN1 = N1.SquareMagnitude(); + if (absd1>=sqmagN1) + { + if(FastFabs(du0)<=LOCAL_EPSILON*absd1) du0 = 0.0f; + if(FastFabs(du1)<=LOCAL_EPSILON*absd1) du1 = 0.0f; + if(FastFabs(du2)<=LOCAL_EPSILON*absd1) du2 = 0.0f; + } + else + { + if(FastFabs(du0)<=LOCAL_EPSILON*FCMax2(absd1, FCMin2(sqmagN1, U0.SquareMagnitude()))) du0 = 0.0f; + if(FastFabs(du1)<=LOCAL_EPSILON*FCMax2(absd1, FCMin2(sqmagN1, U1.SquareMagnitude()))) du1 = 0.0f; + if(FastFabs(du2)<=LOCAL_EPSILON*FCMax2(absd1, FCMin2(sqmagN1, U2.SquareMagnitude()))) du2 = 0.0f; + } +#endif + const float du0du1 = du0 * du1; + const float du0du2 = du0 * du2; + + if(du0du1>0.0f && du0du2>0.0f) // same sign on all of them + not equal 0 ? + return FALSE; // no intersection occurs + + // Compute plane of triangle (U0,U1,U2) + E1 = U1 - U0; + E2 = U2 - U0; + const Point N2 = E1 ^ E2; + const float d2=-N2 | U0; + // plane equation 2: N2.X+d2=0 + + // put V0,V1,V2 into plane equation 2 + float dv0 = (N2|V0) + d2; + float dv1 = (N2|V1) + d2; + float dv2 = (N2|V2) + d2; + +#ifdef OPC_TRITRI_EPSILON_TEST + float absd2 = FastFabs(d2), sqmagN2 = N2.SquareMagnitude(); + if (absd2>=sqmagN2) + { + if(FastFabs(dv0)<=LOCAL_EPSILON*absd2) dv0 = 0.0f; + if(FastFabs(dv1)<=LOCAL_EPSILON*absd2) dv1 = 0.0f; + if(FastFabs(dv2)<=LOCAL_EPSILON*absd2) dv2 = 0.0f; + } + else + { + if(FastFabs(dv0)<=LOCAL_EPSILON*FCMax2(absd2, FCMin2(sqmagN2, V0.SquareMagnitude()))) dv0 = 0.0f; + if(FastFabs(dv1)<=LOCAL_EPSILON*FCMax2(absd2, FCMin2(sqmagN2, V1.SquareMagnitude()))) dv1 = 0.0f; + if(FastFabs(dv2)<=LOCAL_EPSILON*FCMax2(absd2, FCMin2(sqmagN2, V2.SquareMagnitude()))) dv2 = 0.0f; + } +#endif + + const float dv0dv1 = dv0 * dv1; + const float dv0dv2 = dv0 * dv2; + + if(dv0dv1>0.0f && dv0dv2>0.0f) // same sign on all of them + not equal 0 ? + return FALSE; // no intersection occurs + + // Compute direction of intersection line + const Point D = N1^N2; + + // Compute and index to the largest component of D + float max=fabsf(D[0]); + short index=0; + float bb=fabsf(D[1]); + float cc=fabsf(D[2]); + if(bb>max) max=bb,index=1; + if(cc>max) max=cc,index=2; + + // This is the simplified projection onto L + const float vp0 = V0[index]; + const float vp1 = V1[index]; + const float vp2 = V2[index]; + + const float up0 = U0[index]; + const float up1 = U1[index]; + const float up2 = U2[index]; + + // Compute interval for triangle 1 + float a,b,c,x0,x1; + NEWCOMPUTE_INTERVALS(vp0,vp1,vp2,dv0,dv1,dv2,dv0dv1,dv0dv2,a,b,c,x0,x1); + + // Compute interval for triangle 2 + float d,e,f,y0,y1; + NEWCOMPUTE_INTERVALS(up0,up1,up2,du0,du1,du2,du0du1,du0du2,d,e,f,y0,y1); + + const float xx=x0*x1; + const float yy=y0*y1; + const float xxyy=xx*yy; + + float isect1[2], isect2[2]; + + float tmp=a*xxyy; + isect1[0]=tmp+b*x1*yy; + isect1[1]=tmp+c*x0*yy; + + tmp=d*xxyy; + isect2[0]=tmp+e*xx*y1; + isect2[1]=tmp+f*xx*y0; + + SORT(isect1[0],isect1[1]); + SORT(isect2[0],isect2[1]); + + if(isect1[1]<isect2[0] || isect2[1]<isect1[0]) return FALSE; + return TRUE; +} diff --git a/libs/ode-0.16.1/OPCODE/OPC_VolumeCollider.cpp b/libs/ode-0.16.1/OPCODE/OPC_VolumeCollider.cpp new file mode 100644 index 0000000..f374209 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_VolumeCollider.cpp @@ -0,0 +1,103 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains base volume collider class. + * \file OPC_VolumeCollider.cpp + * \author Pierre Terdiman + * \date June, 2, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains the abstract class for volume colliders. + * + * \class VolumeCollider + * \author Pierre Terdiman + * \version 1.3 + * \date June, 2, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +VolumeCollider::VolumeCollider() : + mTouchedPrimitives (null), + mNbVolumeBVTests (0), + mNbVolumePrimTests (0) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +VolumeCollider::~VolumeCollider() +{ + mTouchedPrimitives = null; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Validates current settings. You should call this method after all the settings / callbacks have been defined for a collider. + * \return null if everything is ok, else a string describing the problem + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +const char* VolumeCollider::ValidateSettings() +{ + return null; +} + +// Pretty dumb way to dump - to do better - one day... + +#define IMPLEMENT_NOLEAFDUMP(type) \ +void VolumeCollider::_Dump(const type* node) \ +{ \ + if(node->HasPosLeaf()) mTouchedPrimitives->Add(udword(node->GetPosPrimitive())); \ + else _Dump(node->GetPos()); \ + \ + if(ContactFound()) return; \ + \ + if(node->HasNegLeaf()) mTouchedPrimitives->Add(udword(node->GetNegPrimitive())); \ + else _Dump(node->GetNeg()); \ +} + +#define IMPLEMENT_LEAFDUMP(type) \ +void VolumeCollider::_Dump(const type* node) \ +{ \ + if(node->IsLeaf()) \ + { \ + mTouchedPrimitives->Add(udword(node->GetPrimitive())); \ + } \ + else \ + { \ + _Dump(node->GetPos()); \ + \ + if(ContactFound()) return; \ + \ + _Dump(node->GetNeg()); \ + } \ +} + +IMPLEMENT_NOLEAFDUMP(AABBNoLeafNode) +IMPLEMENT_NOLEAFDUMP(AABBQuantizedNoLeafNode) + +IMPLEMENT_LEAFDUMP(AABBCollisionNode) +IMPLEMENT_LEAFDUMP(AABBQuantizedNode) diff --git a/libs/ode-0.16.1/OPCODE/OPC_VolumeCollider.h b/libs/ode-0.16.1/OPCODE/OPC_VolumeCollider.h new file mode 100644 index 0000000..c0b812e --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/OPC_VolumeCollider.h @@ -0,0 +1,138 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains base volume collider class. + * \file OPC_VolumeCollider.h + * \author Pierre Terdiman + * \date June, 2, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_VOLUMECOLLIDER_H__ +#define __OPC_VOLUMECOLLIDER_H__ + + struct OPCODE_API VolumeCache + { + VolumeCache() : Model(null) {} + ~VolumeCache() {} + + Container TouchedPrimitives; //!< Indices of touched primitives + const BaseModel* Model; //!< Owner + }; + + class OPCODE_API VolumeCollider : public Collider + { + public: + // Constructor / Destructor + VolumeCollider(); + virtual ~VolumeCollider() = 0; + + // Collision report + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the number of touched primitives after a collision query. + * \see GetContactStatus() + * \see GetTouchedPrimitives() + * \return the number of touched primitives + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbTouchedPrimitives() const { return mTouchedPrimitives ? mTouchedPrimitives->GetNbEntries() : 0; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the list of touched primitives after a collision query. + * \see GetContactStatus() + * \see GetNbTouchedPrimitives() + * \return the list of touched primitives (primitive indices) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ const udword* GetTouchedPrimitives() const { return mTouchedPrimitives ? mTouchedPrimitives->GetEntries() : null; } + + // Stats + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Stats: gets the number of Volume-BV overlap tests after a collision query. + * \see GetNbVolumePrimTests() + * \return the number of Volume-BV tests performed during last query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbVolumeBVTests() const { return mNbVolumeBVTests; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Stats: gets the number of Volume-Triangle overlap tests after a collision query. + * \see GetNbVolumeBVTests() + * \return the number of Volume-Triangle tests performed during last query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbVolumePrimTests() const { return mNbVolumePrimTests; } + + // Settings + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Validates current settings. You should call this method after all the settings / callbacks have been defined for a collider. + * \return null if everything is ok, else a string describing the problem + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(Collider) const char* ValidateSettings(); + + protected: + // Touched primitives + Container* mTouchedPrimitives; //!< List of touched primitives + + // Dequantization coeffs + Point mCenterCoeff; + Point mExtentsCoeff; + // Stats + udword mNbVolumeBVTests; //!< Number of Volume-BV tests + udword mNbVolumePrimTests; //!< Number of Volume-Primitive tests + // Internal methods + void _Dump(const AABBCollisionNode* node); + void _Dump(const AABBNoLeafNode* node); + void _Dump(const AABBQuantizedNode* node); + void _Dump(const AABBQuantizedNoLeafNode* node); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Initializes a query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(Collider) inline_ void InitQuery() + { + // Reset stats & contact status + mNbVolumeBVTests = 0; + mNbVolumePrimTests = 0; + Collider::InitQuery(); + } + + inline_ BOOL IsCacheValid(VolumeCache& cache) + { + // We're going to do a volume-vs-model query. + if(cache.Model!=mCurrentModel) + { + // Cached list was for another model so we can't keep it + // Keep track of new owner and reset cache + cache.Model = mCurrentModel; + return FALSE; + } + else + { + // Same models, no problem + return TRUE; + } + } + }; + +#endif // __OPC_VOLUMECOLLIDER_H__ diff --git a/libs/ode-0.16.1/OPCODE/Opcode.cpp b/libs/ode-0.16.1/OPCODE/Opcode.cpp new file mode 100644 index 0000000..444619a --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Opcode.cpp @@ -0,0 +1,82 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Main file for Opcode.dll. + * \file Opcode.cpp + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/* + Finding a good name is difficult! + Here's the draft for this lib.... Spooky, uh? + + VOID? Very Optimized Interference Detection + ZOID? Zappy's Optimized Interference Detection + CID? Custom/Clever Interference Detection + AID / ACID! Accurate Interference Detection + QUID? Quick Interference Detection + RIDE? Realtime Interference DEtection + WIDE? Wicked Interference DEtection (....) + GUID! + KID ! k-dop interference detection :) + OPCODE! OPtimized COllision DEtection +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + + +static OPCODE_AbortHandler g_fnAbortHandler = NULL; + + +bool Opcode::InitOpcode(OPCODE_AbortHandler fnAbortHandler/*=NULL*/) +{ + //Log("// Initializing OPCODE\n\n"); +// LogAPIInfo(); + + g_fnAbortHandler = fnAbortHandler; + return true; +} + +bool Opcode::CloseOpcode() +{ + //Log("// Closing OPCODE\n\n"); + + return true; +} + + +#ifdef ICE_MAIN + +void ModuleAttach(HINSTANCE hinstance) +{ +} + +void ModuleDetach() +{ +} + +#endif + +/*extern */ +void OPCODE_NORETURN IceAbort() +{ + if (g_fnAbortHandler != NULL) + { + g_fnAbortHandler(); + } + + abort(); +} diff --git a/libs/ode-0.16.1/OPCODE/Opcode.h b/libs/ode-0.16.1/OPCODE/Opcode.h new file mode 100644 index 0000000..4a98e36 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Opcode.h @@ -0,0 +1,126 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Main file for Opcode.dll. + * \file Opcode.h + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPCODE_H__ +#define __OPCODE_H__ + +// stddef.h and stdarg.h must be included before Opcode headers +// as they latermay not compile being not able to find types in std:: +#include <stddef.h> +#include <stdarg.h> + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Things to help us compile on non-windows platforms + +#if defined(__APPLE__) || defined(__MACOSX__) +#if __APPLE_CC__ < 1495 +#define sqrtf sqrt +#define sinf sin +#define cosf cos +#define acosf acos +#define asinf asin +#endif +#endif + +#ifndef _MSC_VER +#ifndef __int64 +#define __int64 long long int +#endif +#ifndef __stdcall /* this is defined in MinGW and CygWin, so avoid the warning */ +#define __stdcall /* */ +#endif +#endif + +#if defined(__GNUC__) +#define OPCODE_NORETURN __attribute__((noreturn)) +#elif defined(_MSC_VER) +#define OPCODE_NORETURN __declspec(noreturn) +#else // #if !defined(_MSC_VER) +#define OPCODE_NORETURN +#endif // #if !defined(__GNUC__) + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Compilation messages +#ifdef _MSC_VER + #if defined(OPCODE_EXPORTS) + // #pragma message("Compiling OPCODE") + #elif !defined(OPCODE_EXPORTS) + // #pragma message("Using OPCODE") + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Automatic linking + #ifndef BAN_OPCODE_AUTOLINK + #ifdef _DEBUG + //#pragma comment(lib, "Opcode_D.lib") + #else + //#pragma comment(lib, "Opcode.lib") + #endif + #endif + #endif +#endif + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Preprocessor +#ifndef ICE_NO_DLL + #ifdef OPCODE_EXPORTS + #define OPCODE_API// __declspec(dllexport) + #else + #define OPCODE_API// __declspec(dllimport) + #endif +#else + #define OPCODE_API +#endif + + #include "OPC_Settings.h" + #include "OPC_IceHook.h" + + namespace Opcode + { + // Bulk-of-the-work + #include "OPC_Common.h" + #include "OPC_MeshInterface.h" + // Builders + #include "OPC_TreeBuilders.h" + // Trees + #include "OPC_AABBTree.h" + #include "OPC_OptimizedTree.h" + // Models + #include "OPC_BaseModel.h" + #include "OPC_Model.h" + #include "OPC_HybridModel.h" + // Colliders + #include "OPC_Collider.h" + #include "OPC_VolumeCollider.h" + #include "OPC_TreeCollider.h" + #include "OPC_RayCollider.h" + #include "OPC_SphereCollider.h" + #include "OPC_OBBCollider.h" + #include "OPC_AABBCollider.h" + #include "OPC_LSSCollider.h" + #include "OPC_PlanesCollider.h" + // Usages + #include "OPC_Picking.h" + + + typedef void (*OPCODE_AbortHandler)(); + FUNCTION OPCODE_API bool InitOpcode(OPCODE_AbortHandler fnAbortHandler=NULL); + FUNCTION OPCODE_API bool CloseOpcode(); + } + +#endif // __OPCODE_H__ diff --git a/libs/ode-0.16.1/OPCODE/README-ODE.txt b/libs/ode-0.16.1/OPCODE/README-ODE.txt new file mode 100644 index 0000000..c5d5800 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/README-ODE.txt @@ -0,0 +1,13 @@ + +This is a copy of the OPCODE collision detection library by Pierre Terdiman. +See http://www.codercorner.com/Opcode.htm for more information, and read +the ReadMe.txt in this directory. + +If you want to use the TriList (triangle mesh) geometry class in ODE, the +OPCODE library must be compiled. If you are using the autotools support to +compile ODE, you just have to specify --with-trimesh=opcode when calling ./configure. + +This code was originally written for and compiled on windows, but it has been +ported so that it should compile under unix/gcc too. Your mileage may vary. + +Russ Smith, April 12 2005. diff --git a/libs/ode-0.16.1/OPCODE/ReadMe.txt b/libs/ode-0.16.1/OPCODE/ReadMe.txt new file mode 100644 index 0000000..8a39eff --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/ReadMe.txt @@ -0,0 +1,171 @@ + + OPCODE distribution 1.3 (june 2003) + ----------------------- + + New in Opcode 1.3: + - fixed the divide by 0 bug that was happening when all centers where located on a coordinate axis (thanks to Jorrit T) + - linearized "complete" vanilla AABB trees + - ANSI-compliant "for" loops (for the ones porting it to Linux...) + - callbacks & pointers moved to mesh interface + - support for triangle & vertex strides + - optimized the sphere-triangle overlap code a bit + - dynamic trees (refit) + - more builders + - ValidateSubdivision in builders + - LSS collider + - primitive-bv tests can now be skipped in most volume queries + - temporal coherence now also works for airborne objects + - temporal coherence completed for boxes / all contacts, LSS, etc + - ray-collider now uses a callback + - some common "usages" have been introduced (only picking for now) + - SPLIT_COMPLETE removed (now implicitely using mLimit = 1) + - hybrid collision models + - sweep-and-prune code added, moved from my old Z-Collide lib + - it now works with meshes made of only 1 triangle (except in mesh-mesh case!) + + Disclaimer: + + - I forced myself to actually *do* the release today no matter what. Else it would never have been done. That's + why the code may not be very polished. I also removed a *lot* of things (more usages, distance queries, etc...) + that weren't ready for prime-time (or that were linked to too many of my supporting libs) + + - Some comments may also be obsolete here and there. The old User Manual for Opcode 1.2 may not fit version 1.3 + either, since there's a new "mesh interface" to support strides, etc. + + - Everything in the "Ice" directory has been hacked out of my engine and edited until everything compiled. Don't + expect anything out there to be cute or something. In particular, some CPP files are not even included when not + needed, so you can expect some linker errors if you try messing around with them... + + Otherwise, it should be just like previous version, only better. In particular, hybrid models can be very + memory-friendly (sometimes using like 10 times less ram than the best trees from version 1.2). The possible + speed hit is often invisible (if it even exists), especially using temporal coherence in "all contacts" mode. + (Admittedly, this depends on your particular usage pattern / what you do on collided triangles). + + The sweep-and-prune code is similar to the "vanilla" version found in V-Collide (but that one's better IMHO...) + The simple "radix" version is often just as good, see for yourself. + + OPCODE distribution 1.2 (august 2002) + ----------------------- + + New in Opcode 1.2: + - new VolumeCollider base class + - simplified callback setup + - you can now use callbacks or pointers (setup at compile time) + - destination array not needed anymore in the RayCollider (faster in-out tests) + - renamed classes: AABBRayCollider => RayCollider, AABBSphereCollider => SphereCollider + - the sphere query now only returns a list of faces (extra info discarded). On the other hand it's a lot faster. + - OBB, AABB and planes queries. Original OBB and AABB queries contributed by Erwin de Vries. + - cosmetic changes in OPC_BoxBoxOverlap.h contributed by Gottfried Chen + - some inlining problems fixed + - faster ray-mesh tests using the separating axis theorem + - new split value in AABB tree construction (contributed by Igor Kravtchenko). Provides faster queries most of the time. + - improved temporal coherence for sphere & AABB queries (works in "All contacts" mode) + + Notes: + + - Everything in the "Ice code" directory (in VC++) is basically copy-pasted from my engine, with a lot + of code removed until there was no link error anymore. Don't expect those files to be cute or anything, + they've never been meant to be released and they're often updated/modified/messy. + - Some experimental features have been removed as well. Else I would never have released the 1.2... + - Not as polished/optimal as I would like it to be, but that's life. I promised myself to release it + before october 2002 (one YEAR later ?!).... That's the only reason why it's there. + - Some people reported ColDet was faster. Uh, come on. They were using Opcode in + "All contacts" mode whereas ColDet was doing "first contact"... + + OPCODE distribution 1.1 (october 2001) + ----------------------- + + New in Opcode 1.1: + - stabbing queries + - sphere queries + - abtract base class for colliders + - settings validation methods + - compilation flags now grouped in OPC_Settings.h + - smaller files, new VC++ virtual dirs (cleaner) + + Notes: + + - "override(baseclass)" is a personal cosmetic thing. It's the same as "virtual", but provides more info. + - I code in 1600*1200, so some lines may look a bit long.. + - This version is not as polished as the previous one due to lack of time. The stabbing & sphere queries + can still be optimized: for example by trying other atomic overlap tests. I'm using my first ray-AABB + code, but the newer one seems better. Tim Schröder's one is good as well. See: www.codercorner.com/RayAABB.cpp + - The trees can easily be compressed even more, I save this for later (lack of time, lack of time!) + - I removed various tests before releasing this one: + - a separation line, a.k.a. "front" in QuickCD, because gains were unclear + - distance queries in a PQP style, because it was way too slow + - support for deformable models, too slow as well + - You can easily use Opcode to do your player-vs-world collision detection, in a Nettle/Telemachos way. + If someone out there wants to donate some art / level for the cause, I'd be glad to release a demo. (current + demo uses copyrighted art I'm not allowed to spread) + - Sorry for the lack of real docs and/or solid examples. I just don't have enough time. + + OPCODE distribution 1.0 (march 2001) + ----------------------- + + - First release + + =============================================================================== + + WHAT ? + + OPCODE means OPtimized COllision DEtection. + So this is a collision detection package similar to RAPID. Here's a + quick list of features: + + - C++ interface, developed for Windows systems using VC++ 6.0 + - Works on arbitrary meshes (convex or non-convex), even polygon soups + - Current implementation uses AABB-trees + - Introduces Primitive-BV overlap tests during recursive collision queries (whereas + standard libraries only rely on Primitive-Primitive and BV-BV tests) + - Introduces no-leaf trees, i.e. collision trees whose leaf nodes have been removed + - Supports collision queries on quantized trees (decompressed on-the-fly) + - Supports "first contact" or "all contacts" modes (à la RAPID) + - Uses temporal coherence for "first contact" mode (~10 to 20 times faster, useful + in rigid body simulation during bisection) + - Memory footprint is 7.2 times smaller than RAPID's one, which is ideal for console + games with limited ram (actually, if you use the unmodified RAPID code using double + precision, it's more like 13 times smaller...) + - And yet it often runs faster than RAPID (according to RDTSC, sometimes more than 5 + times faster when objects are deeply overlapping) + - Performance is usually close to RAPID's one in close-proximity situations + - Stabbing, planes & volume queries (sphere, AABB, OBB, LSS) + - Sweep-and-prune + - Now works with deformable meshes + - Hybrid trees + + + What it can be used for: + - standard mesh-mesh collision detection (similar to RAPID, SOLID, QuickCD, PQP, ColDet...) + - N-body collisions (similar to V-Collide) + - camera-vs-world collisions (similar to Telemachos/Paul Nettle/Stan Melax articles) + - shadow feelers to speed up lightmap computations + - in-out tests to speed up voxelization processes + - picking + - rigid body simulation + - view frustum culling + - etc + + WHY ? + + - Because RAPID uses too many bytes. + - Because the idea was nice... + + WHEN ? + + It's been coded in march 2001 following a thread on the GD-Algorithms list. + + GDAlgorithms-list mailing list + GDAlgorithms-list@lists.sourceforge.net + http://lists.sourceforge.net/lists/listinfo/gdalgorithms-list + + WHO ? + + Pierre Terdiman + June, 1, 2003 + + p.terdiman@wanadoo.fr + p.terdiman@codercorner.com + + http://www.codercorner.com + http://www.codercorner.com/Opcode.htm diff --git a/libs/ode-0.16.1/OPCODE/Stdafx.h b/libs/ode-0.16.1/OPCODE/Stdafx.h new file mode 100644 index 0000000..0223a6c --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/Stdafx.h @@ -0,0 +1,24 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_STDAFX_H__EFB95044_1D31_11D5_8B0F_0050BAC83302__INCLUDED_) +#define AFX_STDAFX_H__EFB95044_1D31_11D5_8B0F_0050BAC83302__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +// Insert your headers here +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +#include "Opcode.h" + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__EFB95044_1D31_11D5_8B0F_0050BAC83302__INCLUDED_) diff --git a/libs/ode-0.16.1/OPCODE/TemporalCoherence.txt b/libs/ode-0.16.1/OPCODE/TemporalCoherence.txt new file mode 100644 index 0000000..fb85931 --- /dev/null +++ b/libs/ode-0.16.1/OPCODE/TemporalCoherence.txt @@ -0,0 +1,32 @@ + +> Hi John, +> +> I know I'll forget to tell you this if I don't write it right now.... +> +> >(2) How is the receiving geometry for the shadow decided? +> +> I wrote about an LSS-test but actually performing a new VFC test (from the +> light's view) is the same. In both cases, here's a trick to take advantage +> of temporal coherence : test the world against a slightly larger than +> necessary LSS or frustum. Keep the list of touched surfaces. Then next +> frame, if the new volume is still contained within the previous one used +for +> the query, you can reuse the same list immediately. Actually it's a bit +> similar to what you did in your sphere-tree, I think. Anyway, now the +O(log +> N) VFC is O(1) for some frames. It's not worth it for the "real" VFC, but +> when you have N virtual frustum to test to drop N shadows, that's another +> story. +> +> Two downsides: +> - You need more ram to keep track of one list of meshes / shadow, but +> usually it's not a lot. +> - By using a larger volume for the query you possibly touch more +> faces/surfaces, which will be rendered in the shadow pass. Usually it's +not +> a problem either since rendering is simply faster than geometric queries +> those days. But of course, "your mileage may vary". +> +> Happy new year ! +> +> Pierre diff --git a/libs/ode-0.16.1/README.md b/libs/ode-0.16.1/README.md new file mode 100644 index 0000000..b28a3b5 --- /dev/null +++ b/libs/ode-0.16.1/README.md @@ -0,0 +1,34 @@ +The Open Dynamics Engine (ODE) +============================== + +![ODE logo](http://bitbucket.org/odedevs/ode/raw/default/web/ODElogo.png) + +Copyright (C) 2001-2007 Russell L. Smith. + + +ODE is a free, industrial quality library for simulating articulated +rigid body dynamics - for example ground vehicles, legged creatures, +and moving objects in VR environments. It is fast, flexible, robust +and platform independent, with advanced joints, contact with friction, +and built-in collision detection. + +This library is free software; you can redistribute it and/or +modify it under the terms of EITHER: + + * The GNU Lesser General Public License version 2.1 or any later. + + * The BSD-style License. + +See the [COPYING](http://bitbucket.org/odedevs/ode/raw/default/COPYING) file for more details. + + * Installation instructions are in the [INSTALL.txt](http://bitbucket.org/odedevs/ode/raw/default/INSTALL.txt) file. + + * The ODE web pages are at [ode.org](http://www.ode.org/). + + * An online manual is at [the Wiki](http://ode-wiki.org/wiki/index.php?title=Manual). + + * API documentation is in the file ode/docs/index.html, or you + can view it on the web at [opende.sf.net/docs/index.html](http://opende.sf.net/docs/index.html). + + * Coding style requirements can be found in the [CSR.txt](http://bitbucket.org/odedevs/ode/raw/default/CSR.txt) file. + diff --git a/libs/ode-0.16.1/aclocal.m4 b/libs/ode-0.16.1/aclocal.m4 new file mode 100644 index 0000000..df157e5 --- /dev/null +++ b/libs/ode-0.16.1/aclocal.m4 @@ -0,0 +1,1158 @@ +# generated automatically by aclocal 1.15 -*- Autoconf -*- + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. + +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +# Copyright (C) 2002-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.15' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.15], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.15])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is '.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each '.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.65])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl +]) +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: <http://www.gnu.org/software/coreutils/>. + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi +dnl The trailing newline in this macro's definition is deliberate, for +dnl backward compatibility and to allow trailing 'dnl'-style comments +dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. +]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST([install_sh])]) + +# Copyright (C) 2003-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + AC_MSG_WARN(['missing' script is too old or missing]) +fi +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) + +# Copyright (C) 2009-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor 'install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in "make install-strip", and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +# +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' + +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar <conftest.tar]) + AM_RUN_LOG([cat conftest.dir/file]) + grep GrepMe conftest.dir/file >/dev/null 2>&1 && break + fi + done + rm -rf conftest.dir + + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([m4/libtool.m4]) +m4_include([m4/ltoptions.m4]) +m4_include([m4/ltsugar.m4]) +m4_include([m4/ltversion.m4]) +m4_include([m4/lt~obsolete.m4]) +m4_include([m4/pkg.m4]) diff --git a/libs/ode-0.16.1/bindings/python/INSTALL.txt b/libs/ode-0.16.1/bindings/python/INSTALL.txt new file mode 100644 index 0000000..a0ae378 --- /dev/null +++ b/libs/ode-0.16.1/bindings/python/INSTALL.txt @@ -0,0 +1,64 @@ +1. REQUIREMENTS:
+
+1. Python 2.4 or higher (http://www.python.org/)
+ - Tested with Python 2.7 (2.6 on earlier builds)
+2. Cython 0.14.1** or higher (http://cython.org/)
+ - Tested with Cython 0.15 (0.14.1 on earlier builds)
+3. ODE shared*** library (or static with -fPIC)
+ - See the notes on building ODE below.
+4. pkg-config (http://www.freedesktop.org/wiki/Software/pkg-config)
+ - Windows executable (and GLib dependency) can be downloaded from
+ http://www.gtk.org/download/win32.php
+ - If you used premake to configure ODE, you may need to create an ode.pc file
+ in your PKG_CONFIG_PATH manually. See <ODE_DIR>/ode.pc.in
+
+
+
+2. BUILDING ODE
+
+ On certain systems (*nix) there is a requirement that a shared library
+ (such as the python module) contains only position-independent code
+ (PIC). In those cases, ODE needs to be either compiled as a shared library
+ too (--enable-shared), or as a static library with PIC (-fPIC).
+
+ Once ODE is built and installed in your desired destination, proceed with
+ building the wrapper.
+
+
+
+3a. BUILDING WITH Visual Studio (Windows)
+
+ python setup.py build_ext
+
+
+3b. BUILDING WITH MINGW (Windows)
+
+ python setup.py build_ext -c mingw32
+
+
+3c. BUILDING WITH GCC/G++ (Linux, OS X, etc.)
+
+ python setup.py build_ext
+
+
+
+4. INSTALLATION
+
+4a. For system-wide installation (needs administrator privileges):
+
+ python setup.py install
+
+4b. For user installation:
+
+ python setup.py install --user
+
+
+
+5. DEMOS and DOCUMENTATION
+
+ Try running the tutorials in the 'demos' directory. The tutorials were taken
+ from the PyODE website (http://pyode.sourceforge.net/).
+
+ For usage documentation, please refer to the PyODE API documentation at
+ http://pyode.sourceforge.net/api-1.2.0/index.html.
+
diff --git a/libs/ode-0.16.1/bindings/python/TODO.txt b/libs/ode-0.16.1/bindings/python/TODO.txt new file mode 100644 index 0000000..356edc4 --- /dev/null +++ b/libs/ode-0.16.1/bindings/python/TODO.txt @@ -0,0 +1,15 @@ +CODE:
+* (setup.py) add package information (version, authors, etc.)
+* (setup.py) add 'install' action
+* (setup.py) add configurable ODE DLL (currently hard-coded to default single precision)
+* (ode.pxd) clean up, add more comments
+* (ode.pyx) refactor for a more Pythonic implementation (e.g. replace getters and setters with
+ properties)?
+* (?) Add option to build bindings in ODE's makefiles
+
+
+DOCS:
+
+* Update and include API docs from PyODE
+* Adapt and include PyODE tutorials/demos
+* Update license text in ode.pxd and ode.pyx
diff --git a/libs/ode-0.16.1/bindings/python/demos/tutorial1.py b/libs/ode-0.16.1/bindings/python/demos/tutorial1.py new file mode 100755 index 0000000..c4266d4 --- /dev/null +++ b/libs/ode-0.16.1/bindings/python/demos/tutorial1.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +# http://pyode.sourceforge.net/tutorials/tutorial1.html + +# pyODE example 1: Getting started + +# modified by Gideon Klompje (removed literals and using +# 'ode.Mass.setSphereTotal' instead of 'ode.Mass.setSphere') + +import ode + +# Simulation constants +GRAVITY = (0, -9.81, 0) + +SPHERE_RADIUS = 0.05 +SPHERE_MASS = 1.0 +SPHERE_START_POS = (0, 2, 0) +SPHERE_FORCE = (0, 200, 0) # Initial force to apply to the sphere + +TIME_STEP = 0.04 +TIME_STOP = 2.0 # When to stop the simulation + +# Create a world object +world = ode.World() +world.setGravity(GRAVITY) + +# Create a spherical body inside the world +body = ode.Body(world) +mass = ode.Mass() +mass.setSphereTotal(SPHERE_MASS, SPHERE_RADIUS) +body.setMass(mass) + +body.setPosition(SPHERE_START_POS) +body.addForce(SPHERE_FORCE) + +# Do the simulation... +if __name__ == "__main__": + total_time = 0.0 + while total_time < TIME_STOP: + # output the body's position and velocity + x, y, z = body.getPosition() + u, v, w = body.getLinearVel() + print "%1.2fsec: pos=(%6.3f, %6.3f, %6.3f) vel=(%6.3f, %6.3f, %6.3f)" % \ + (total_time, x, y, z, u, v, w) + + # advance the simulation + world.step(TIME_STEP) + total_time += TIME_STEP + diff --git a/libs/ode-0.16.1/bindings/python/demos/tutorial2.py b/libs/ode-0.16.1/bindings/python/demos/tutorial2.py new file mode 100755 index 0000000..1a4a228 --- /dev/null +++ b/libs/ode-0.16.1/bindings/python/demos/tutorial2.py @@ -0,0 +1,135 @@ +#!/usr/bin/env python + +# http://pyode.sourceforge.net/tutorials/tutorial2.html + +# pyODE example 2: Connecting bodies with joints + +# modified by Gideon Klompje (removed literals and using +# 'ode.Mass.setSphereTotal' instead of 'ode.Mass.setSphere') + + +import ode +import pygame + +from pygame.locals import QUIT, KEYDOWN + +# Constants +WINDOW_RESOLUTION = (640, 480) + +DRAW_SCALE = WINDOW_RESOLUTION[0] / 5 +"""Factor to multiply physical coordinates by to obtain screen size in pixels""" + +DRAW_OFFSET = (WINDOW_RESOLUTION[0] / 2, 50) +"""Screen coordinates (in pixels) that map to the physical origin (0, 0, 0)""" + +BACKGROUND_COLOR = (255, 255, 255) + +GRAVITY = (0, -9.81, 0) + +SPHERE1_POSITION = (1, 0, 0) +SPHERE1_MASS = 1 +SPHERE1_RADIUS = 0.15 +SPHERE1_COLOR = (55, 0, 200) + +SPHERE2_POSITION = (2, 0, 0) +SPHERE2_MASS = 1 +SPHERE2_RADIUS = 0.15 +SPHERE2_COLOR = (55, 0, 200) + +JOINT1_ANCHOR = (0, 0, 0) +JOINT1_COLOR = (200, 0, 55) +JOINT1_WIDTH = 2 +"""Width of the line (in pixels) representing the joint""" + +JOINT2_ANCHOR = SPHERE1_POSITION +JOINT2_COLOR = (200, 0, 55) +JOINT2_WIDTH = 2 +"""Width of the line (in pixels) representing the joint""" + +TIME_STEP = 0.04 + +# Utility functions +def coord(x, y, integer=False): + """ + Convert world coordinates to pixel coordinates. Setting 'integer' to + True will return integer coordinates. + """ + xs = (DRAW_OFFSET[0] + DRAW_SCALE*x) + ys = (DRAW_OFFSET[1] - DRAW_SCALE*y) + + if integer: + return int(round(xs)), int(round(ys)) + else: + return xs, ys + +# Initialize pygame +pygame.init() + +# Open a display +screen = pygame.display.set_mode(WINDOW_RESOLUTION) + +# Create a world object +world = ode.World() +world.setGravity(GRAVITY) + +# Create two bodies +body1 = ode.Body(world) +M = ode.Mass() +M.setSphereTotal(SPHERE1_MASS, SPHERE1_RADIUS) +body1.setMass(M) +body1.setPosition(SPHERE1_POSITION) + +body2 = ode.Body(world) +M = ode.Mass() +M.setSphereTotal(SPHERE2_MASS, SPHERE2_RADIUS) +body2.setMass(M) +body2.setPosition(SPHERE2_POSITION) + +# Connect body1 with the static environment +j1 = ode.BallJoint(world) +j1.attach(body1, ode.environment) +j1.setAnchor(JOINT1_ANCHOR) + +# Connect body2 with body1 +j2 = ode.BallJoint(world) +j2.attach(body1, body2) +j2.setAnchor(JOINT2_ANCHOR) + +# Simulation loop... +if __name__ == "__main__": + fps = 1.0 / TIME_STEP + clk = pygame.time.Clock() + + sph1_rad = int(DRAW_SCALE * SPHERE1_RADIUS) + sph2_rad = int(DRAW_SCALE * SPHERE2_RADIUS) + + loopFlag = True + while loopFlag: + for e in pygame.event.get(): + if e.type==QUIT: + loopFlag=False + if e.type==KEYDOWN: + loopFlag=False + + # Clear the screen + screen.fill(BACKGROUND_COLOR) + + # Draw the two bodies and the lines representing the joints + x1, y1, z1 = body1.getPosition() + x2, y2, z2 = body2.getPosition() + xj1, yj1, zj1 = j1.getAnchor() + xj2, yj2, zj2 = j2.getAnchor() + + pygame.draw.line(screen, JOINT1_COLOR, coord(xj1, yj1), coord(x1, y1), JOINT1_WIDTH) + pygame.draw.line(screen, JOINT2_COLOR, coord(xj2, yj2), coord(x2, y2), JOINT2_WIDTH) + pygame.draw.circle(screen, SPHERE1_COLOR, coord(x1, y1, integer=True), sph1_rad, 0) + pygame.draw.circle(screen, SPHERE2_COLOR, coord(x2, y2, integer=True), sph2_rad, 0) + + pygame.display.flip() + + # Next simulation step + world.step(TIME_STEP) + + # Try to keep the specified framerate + clk.tick(fps) + diff --git a/libs/ode-0.16.1/bindings/python/demos/tutorial3.py b/libs/ode-0.16.1/bindings/python/demos/tutorial3.py new file mode 100644 index 0000000..2644d62 --- /dev/null +++ b/libs/ode-0.16.1/bindings/python/demos/tutorial3.py @@ -0,0 +1,284 @@ +#!/usr/bin/env python + +# http://pyode.sourceforge.net/tutorials/tutorial3.html + +# pyODE example 3: Collision detection + +# Originally by Matthias Baas. +# Updated by Pierre Gay to work without pygame or cgkit. + +import sys, os, random, time +from math import * +from OpenGL.GL import * +from OpenGL.GLU import * +from OpenGL.GLUT import * + +import ode + +# geometric utility functions +def scalp (vec, scal): + vec[0] *= scal + vec[1] *= scal + vec[2] *= scal + +def length (vec): + return sqrt (vec[0]**2 + vec[1]**2 + vec[2]**2) + +# prepare_GL +def prepare_GL(): + """Prepare drawing. + """ + + # Viewport + glViewport(0,0,640,480) + + # Initialize + glClearColor(0.8,0.8,0.9,0) + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_DEPTH_TEST) + glDisable(GL_LIGHTING) + glEnable(GL_LIGHTING) + glEnable(GL_NORMALIZE) + glShadeModel(GL_FLAT) + + # Projection + glMatrixMode(GL_PROJECTION) + glLoadIdentity() + gluPerspective (45,1.3333,0.2,20) + + # Initialize ModelView matrix + glMatrixMode(GL_MODELVIEW) + glLoadIdentity() + + # Light source + glLightfv(GL_LIGHT0,GL_POSITION,[0,0,1,0]) + glLightfv(GL_LIGHT0,GL_DIFFUSE,[1,1,1,1]) + glLightfv(GL_LIGHT0,GL_SPECULAR,[1,1,1,1]) + glEnable(GL_LIGHT0) + + # View transformation + gluLookAt (2.4, 3.6, 4.8, 0.5, 0.5, 0, 0, 1, 0) + +# draw_body +def draw_body(body): + """Draw an ODE body. + """ + + x,y,z = body.getPosition() + R = body.getRotation() + rot = [R[0], R[3], R[6], 0., + R[1], R[4], R[7], 0., + R[2], R[5], R[8], 0., + x, y, z, 1.0] + glPushMatrix() + glMultMatrixd(rot) + if body.shape=="box": + sx,sy,sz = body.boxsize + glScalef(sx, sy, sz) + glutSolidCube(1) + glPopMatrix() + + +# create_box +def create_box(world, space, density, lx, ly, lz): + """Create a box body and its corresponding geom.""" + + # Create body + body = ode.Body(world) + M = ode.Mass() + M.setBox(density, lx, ly, lz) + body.setMass(M) + + # Set parameters for drawing the body + body.shape = "box" + body.boxsize = (lx, ly, lz) + + # Create a box geom for collision detection + geom = ode.GeomBox(space, lengths=body.boxsize) + geom.setBody(body) + + return body, geom + +# drop_object +def drop_object(): + """Drop an object into the scene.""" + + global bodies, geom, counter, objcount + + body, geom = create_box(world, space, 1000, 1.0,0.2,0.2) + body.setPosition( (random.gauss(0,0.1),3.0,random.gauss(0,0.1)) ) + theta = random.uniform(0,2*pi) + ct = cos (theta) + st = sin (theta) + body.setRotation([ct, 0., -st, 0., 1., 0., st, 0., ct]) + bodies.append(body) + geoms.append(geom) + counter=0 + objcount+=1 + +# explosion +def explosion(): + """Simulate an explosion. + + Every object is pushed away from the origin. + The force is dependent on the objects distance from the origin. + """ + global bodies + + for b in bodies: + l=b.getPosition () + d = length (l) + a = max(0, 40000*(1.0-0.2*d*d)) + l = [l[0] / 4, l[1], l[2] /4] + scalp (l, a / length (l)) + b.addForce(l) + +# pull +def pull(): + """Pull the objects back to the origin. + + Every object will be pulled back to the origin. + Every couple of frames there'll be a thrust upwards so that + the objects won't stick to the ground all the time. + """ + global bodies, counter + + for b in bodies: + l=list (b.getPosition ()) + scalp (l, -1000 / length (l)) + b.addForce(l) + if counter%60==0: + b.addForce((0,10000,0)) + +# Collision callback +def near_callback(args, geom1, geom2): + """Callback function for the collide() method. + + This function checks if the given geoms do collide and + creates contact joints if they do. + """ + + # Check if the objects do collide + contacts = ode.collide(geom1, geom2) + + # Create contact joints + world,contactgroup = args + for c in contacts: + c.setBounce(0.2) + c.setMu(5000) + j = ode.ContactJoint(world, contactgroup, c) + j.attach(geom1.getBody(), geom2.getBody()) + + + +###################################################################### + +# Initialize Glut +glutInit ([]) + +# Open a window +glutInitDisplayMode (GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE) + +x = 0 +y = 0 +width = 640 +height = 480 +glutInitWindowPosition (x, y); +glutInitWindowSize (width, height); +glutCreateWindow ("testode") + +# Create a world object +world = ode.World() +world.setGravity( (0,-9.81,0) ) +world.setERP(0.8) +world.setCFM(1E-5) + +# Create a space object +space = ode.Space() + +# Create a plane geom which prevent the objects from falling forever +floor = ode.GeomPlane(space, (0,1,0), 0) + +# A list with ODE bodies +bodies = [] + +# The geoms for each of the bodies +geoms = [] + +# A joint group for the contact joints that are generated whenever +# two bodies collide +contactgroup = ode.JointGroup() + +# Some variables used inside the simulation loop +fps = 50 +dt = 1.0/fps +running = True +state = 0 +counter = 0 +objcount = 0 +lasttime = time.time() + + +# keyboard callback +def _keyfunc (c, x, y): + sys.exit (0) + +glutKeyboardFunc (_keyfunc) + +# draw callback +def _drawfunc (): + # Draw the scene + prepare_GL() + for b in bodies: + draw_body(b) + + glutSwapBuffers () + +glutDisplayFunc (_drawfunc) + +# idle callback +def _idlefunc (): + global counter, state, lasttime + + t = dt - (time.time() - lasttime) + if (t > 0): + time.sleep(t) + + counter += 1 + + if state==0: + if counter==20: + drop_object() + if objcount==30: + state=1 + counter=0 + # State 1: Explosion and pulling back the objects + elif state==1: + if counter==100: + explosion() + if counter>300: + pull() + if counter==500: + counter=20 + + glutPostRedisplay () + + # Simulate + n = 4 + + for i in range(n): + # Detect collisions and create contact joints + space.collide((world,contactgroup), near_callback) + + # Simulation step + world.step(dt/n) + + # Remove all contact joints + contactgroup.empty() + + lasttime = time.time() + +glutIdleFunc (_idlefunc) + +glutMainLoop () + diff --git a/libs/ode-0.16.1/bindings/python/ode.pxd b/libs/ode-0.16.1/bindings/python/ode.pxd new file mode 100644 index 0000000..10295c0 --- /dev/null +++ b/libs/ode-0.16.1/bindings/python/ode.pxd @@ -0,0 +1,503 @@ +######################################################################
+# Python Open Dynamics Engine Wrapper
+# Copyright (C) 2004 PyODE developers (see file AUTHORS)
+# All rights reserved.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of EITHER:
+# (1) The GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2.1 of the License, or (at
+# your option) any later version. The text of the GNU Lesser
+# General Public License is included with this library in the
+# file LICENSE.
+# (2) The BSD-style license that is included with this library in
+# the file LICENSE-BSD.
+#
+# This library 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 files
+# LICENSE and LICENSE-BSD for more details.
+######################################################################
+
+cdef extern from "stdlib.h":
+
+ void* malloc(long)
+ void free(void*)
+
+cdef extern from "stdio.h":
+ int printf(char*)
+
+# Include the basic floating point type -> dReal (either float or double)
+#include "_precision.pyx"
+
+cdef extern from "ode/ode.h":
+
+ ctypedef double dReal
+
+ # Dummy structs
+ cdef struct dxWorld:
+ int _dummy
+ cdef struct dxSpace:
+ int _dummy
+ cdef struct dxBody:
+ int _dummy
+ cdef struct dxGeom:
+ int _dummy
+ cdef struct dxJoint:
+ int _dummy
+ cdef struct dxJointGroup:
+ int _dummy
+ cdef struct dxTriMeshData:
+ int _dummy
+ cdef struct dxHeightfieldData:
+ int _dummy
+
+ # Types
+ ctypedef dxWorld* dWorldID
+ ctypedef dxSpace* dSpaceID
+ ctypedef dxBody* dBodyID
+ ctypedef dxGeom* dGeomID
+ ctypedef dxJoint* dJointID
+ ctypedef dxJointGroup* dJointGroupID
+ ctypedef dxTriMeshData* dTriMeshDataID
+ ctypedef dxHeightfieldData* dHeightfieldDataID
+ ctypedef dReal dVector3[4]
+ ctypedef dReal dVector4[4]
+ ctypedef dReal dMatrix3[4*3]
+ ctypedef dReal dMatrix4[4*4]
+ ctypedef dReal dMatrix6[8*6]
+ ctypedef dReal dQuaternion[4]
+
+ cdef extern dReal dInfinity
+ cdef extern int dAMotorUser
+ cdef extern int dAMotorEuler
+
+ ctypedef struct dMass:
+ dReal mass
+ dVector4 c
+ dMatrix3 I
+
+ ctypedef struct dJointFeedback:
+ dVector3 f1
+ dVector3 t1
+ dVector3 f2
+ dVector3 t2
+
+ ctypedef void dNearCallback(void* data, dGeomID o1, dGeomID o2)
+ ctypedef dReal dHeightfieldGetHeight( void* p_user_data, int x, int z )
+
+ ctypedef struct dSurfaceParameters:
+ int mode
+ dReal mu
+
+ dReal mu2
+ dReal bounce
+ dReal bounce_vel
+ dReal soft_erp
+ dReal soft_cfm
+ dReal motion1,motion2
+ dReal slip1,slip2
+
+ ctypedef struct dContactGeom:
+ dVector3 pos
+ dVector3 normal
+ dReal depth
+ dGeomID g1,g2
+
+ ctypedef struct dContact:
+ dSurfaceParameters surface
+ dContactGeom geom
+ dVector3 fdir1
+
+
+ # World
+ dWorldID dWorldCreate()
+ void dWorldDestroy (dWorldID)
+
+ void dCloseODE()
+ void dInitODE()
+
+ void dWorldSetGravity (dWorldID, dReal x, dReal y, dReal z)
+ void dWorldGetGravity (dWorldID, dVector3 gravity)
+ void dWorldSetERP (dWorldID, dReal erp)
+ dReal dWorldGetERP (dWorldID)
+ void dWorldSetCFM (dWorldID, dReal cfm)
+ dReal dWorldGetCFM (dWorldID)
+ void dWorldStep (dWorldID, dReal stepsize)
+ void dWorldQuickStep (dWorldID, dReal stepsize)
+ void dWorldSetQuickStepNumIterations (dWorldID, int num)
+ int dWorldGetQuickStepNumIterations (dWorldID)
+ void dWorldSetContactMaxCorrectingVel (dWorldID, dReal vel)
+ dReal dWorldGetContactMaxCorrectingVel (dWorldID)
+ void dWorldSetContactSurfaceLayer (dWorldID, dReal depth)
+ dReal dWorldGetContactSurfaceLayer (dWorldID)
+ void dWorldSetAutoDisableFlag (dWorldID, int do_auto_disable)
+ int dWorldGetAutoDisableFlag (dWorldID)
+ void dWorldSetAutoDisableLinearThreshold (dWorldID, dReal linear_threshold)
+ dReal dWorldGetAutoDisableLinearThreshold (dWorldID)
+ void dWorldSetAutoDisableAngularThreshold (dWorldID, dReal angular_threshold)
+ dReal dWorldGetAutoDisableAngularThreshold (dWorldID)
+ void dWorldSetAutoDisableSteps (dWorldID, int steps)
+ int dWorldGetAutoDisableSteps (dWorldID)
+ void dWorldSetAutoDisableTime (dWorldID, dReal time)
+ dReal dWorldGetAutoDisableTime (dWorldID)
+ dReal dWorldGetLinearDamping (dWorldID)
+ void dWorldSetLinearDamping (dWorldID, dReal scale)
+ dReal dWorldGetAngularDamping (dWorldID)
+ void dWorldSetAngularDamping (dWorldID, dReal scale)
+ void dWorldImpulseToForce (dWorldID, dReal stepsize,
+ dReal ix, dReal iy, dReal iz, dVector3 force)
+
+ # Body
+ dBodyID dBodyCreate (dWorldID)
+ void dBodyDestroy (dBodyID)
+
+ void dBodySetData (dBodyID, void *data)
+ void *dBodyGetData (dBodyID)
+
+ void dBodySetPosition (dBodyID, dReal x, dReal y, dReal z)
+ void dBodySetRotation (dBodyID, dMatrix3 R)
+ void dBodySetQuaternion (dBodyID, dQuaternion q)
+ void dBodySetLinearVel (dBodyID, dReal x, dReal y, dReal z)
+ void dBodySetAngularVel (dBodyID, dReal x, dReal y, dReal z)
+ dReal * dBodyGetPosition (dBodyID)
+ dReal * dBodyGetRotation (dBodyID)
+ dReal * dBodyGetQuaternion (dBodyID)
+ dReal * dBodyGetLinearVel (dBodyID)
+ dReal * dBodyGetAngularVel (dBodyID)
+
+ void dBodySetMass (dBodyID, dMass *mass)
+ void dBodyGetMass (dBodyID, dMass *mass)
+
+ void dBodyAddForce (dBodyID, dReal fx, dReal fy, dReal fz)
+ void dBodyAddTorque (dBodyID, dReal fx, dReal fy, dReal fz)
+ void dBodyAddRelForce (dBodyID, dReal fx, dReal fy, dReal fz)
+ void dBodyAddRelTorque (dBodyID, dReal fx, dReal fy, dReal fz)
+ void dBodyAddForceAtPos (dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz)
+ void dBodyAddForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz)
+ void dBodyAddRelForceAtPos (dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz)
+ void dBodyAddRelForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz)
+
+ dReal * dBodyGetForce (dBodyID)
+ dReal * dBodyGetTorque (dBodyID)
+
+ void dBodySetForce(dBodyID, dReal x, dReal y, dReal z)
+ void dBodySetTorque(dBodyID, dReal x, dReal y, dReal z)
+
+ void dBodyGetRelPointPos (dBodyID, dReal px, dReal py, dReal pz, dVector3 result)
+ void dBodyGetRelPointVel (dBodyID, dReal px, dReal py, dReal pz, dVector3 result)
+ void dBodyGetPointVel (dBodyID, dReal px, dReal py, dReal pz,
+ dVector3 result)
+ void dBodyGetPosRelPoint (dBodyID, dReal px, dReal py, dReal pz,
+ dVector3 result)
+ void dBodyVectorToWorld (dBodyID, dReal px, dReal py, dReal pz,
+ dVector3 result)
+ void dBodyVectorFromWorld (dBodyID, dReal px, dReal py, dReal pz,
+ dVector3 result)
+
+ void dBodySetFiniteRotationMode (dBodyID, int mode)
+ void dBodySetFiniteRotationAxis (dBodyID, dReal x, dReal y, dReal z)
+
+ int dBodyGetFiniteRotationMode (dBodyID)
+ void dBodyGetFiniteRotationAxis (dBodyID, dVector3 result)
+
+ int dBodyGetNumJoints (dBodyID b)
+ dJointID dBodyGetJoint (dBodyID, int index)
+
+ void dBodyEnable (dBodyID)
+ void dBodyDisable (dBodyID)
+ int dBodyIsEnabled (dBodyID)
+
+ void dBodySetGravityMode (dBodyID b, int mode)
+ int dBodyGetGravityMode (dBodyID b)
+
+ void dBodySetDynamic (dBodyID)
+ void dBodySetKinematic (dBodyID)
+ int dBodyIsKinematic (dBodyID)
+
+ void dBodySetMaxAngularSpeed (dBodyID, dReal max_speed)
+
+ # Joints
+ dJointID dJointCreateBall (dWorldID, dJointGroupID)
+ dJointID dJointCreateHinge (dWorldID, dJointGroupID)
+ dJointID dJointCreateSlider (dWorldID, dJointGroupID)
+ dJointID dJointCreateContact (dWorldID, dJointGroupID, dContact *)
+ dJointID dJointCreateUniversal (dWorldID, dJointGroupID)
+ dJointID dJointCreatePR (dWorldID, dJointGroupID)
+ dJointID dJointCreateHinge2 (dWorldID, dJointGroupID)
+ dJointID dJointCreateFixed (dWorldID, dJointGroupID)
+ dJointID dJointCreateNull (dWorldID, dJointGroupID)
+ dJointID dJointCreateAMotor (dWorldID, dJointGroupID)
+ dJointID dJointCreateLMotor (dWorldID, dJointGroupID)
+ dJointID dJointCreatePlane2D (dWorldID, dJointGroupID)
+
+ void dJointDestroy (dJointID)
+
+ void dJointEnable (dJointID)
+ void dJointDisable (dJointID)
+ int dJointIsEnabled (dJointID)
+
+ dJointGroupID dJointGroupCreate (int max_size)
+ void dJointGroupDestroy (dJointGroupID)
+ void dJointGroupEmpty (dJointGroupID)
+
+ void dJointAttach (dJointID, dBodyID body1, dBodyID body2)
+ void dJointSetData (dJointID, void *data)
+ void *dJointGetData (dJointID)
+ int dJointGetType (dJointID)
+ dBodyID dJointGetBody (dJointID, int index)
+
+ void dJointSetBallAnchor (dJointID, dReal x, dReal y, dReal z)
+ void dJointSetHingeAnchor (dJointID, dReal x, dReal y, dReal z)
+ void dJointSetHingeAxis (dJointID, dReal x, dReal y, dReal z)
+ void dJointSetHingeParam (dJointID, int parameter, dReal value)
+ void dJointAddHingeTorque(dJointID joint, dReal torque)
+ void dJointSetSliderAxis (dJointID, dReal x, dReal y, dReal z)
+ void dJointSetSliderParam (dJointID, int parameter, dReal value)
+ void dJointAddSliderForce(dJointID joint, dReal force)
+ void dJointSetHinge2Anchor (dJointID, dReal x, dReal y, dReal z)
+ void dJointSetHinge2Axis1 (dJointID, dReal x, dReal y, dReal z)
+ void dJointSetHinge2Axis2 (dJointID, dReal x, dReal y, dReal z)
+ void dJointSetHinge2Param (dJointID, int parameter, dReal value)
+ void dJointAddHinge2Torques(dJointID joint, dReal torque1, dReal torque2)
+ void dJointSetUniversalAnchor (dJointID, dReal x, dReal y, dReal z)
+ void dJointSetUniversalAxis1 (dJointID, dReal x, dReal y, dReal z)
+ void dJointSetUniversalAxis2 (dJointID, dReal x, dReal y, dReal z)
+ void dJointSetUniversalParam (dJointID, int parameter, dReal value)
+ void dJointAddUniversalTorques(dJointID joint, dReal torque1, dReal torque2)
+ void dJointSetFixed (dJointID)
+ void dJointSetAMotorNumAxes (dJointID, int num)
+ void dJointSetAMotorAxis (dJointID, int anum, int rel, dReal x, dReal y, dReal z)
+ void dJointSetAMotorAngle (dJointID, int anum, dReal angle)
+ void dJointSetAMotorParam (dJointID, int parameter, dReal value)
+ void dJointSetAMotorMode (dJointID, int mode)
+ void dJointAddAMotorTorques (dJointID, dReal torque1, dReal torque2, dReal torque3)
+ void dJointSetLMotorAxis (dJointID, int anum, int rel, dReal x, dReal y, dReal z)
+ void dJointSetLMotorNumAxes (dJointID, int num)
+ void dJointSetLMotorParam (dJointID, int parameter, dReal value)
+
+ void dJointGetBallAnchor (dJointID, dVector3 result)
+ void dJointGetBallAnchor2 (dJointID, dVector3 result)
+ void dJointGetHingeAnchor (dJointID, dVector3 result)
+ void dJointGetHingeAnchor2 (dJointID, dVector3 result)
+ void dJointGetHingeAxis (dJointID, dVector3 result)
+ dReal dJointGetHingeParam (dJointID, int parameter)
+ dReal dJointGetHingeAngle (dJointID)
+ dReal dJointGetHingeAngleRate (dJointID)
+ dReal dJointGetSliderPosition (dJointID)
+ dReal dJointGetSliderPositionRate (dJointID)
+ void dJointGetSliderAxis (dJointID, dVector3 result)
+ dReal dJointGetSliderParam (dJointID, int parameter)
+ void dJointGetHinge2Anchor (dJointID, dVector3 result)
+ void dJointGetHinge2Anchor2 (dJointID, dVector3 result)
+ void dJointGetHinge2Axis1 (dJointID, dVector3 result)
+ void dJointGetHinge2Axis2 (dJointID, dVector3 result)
+ dReal dJointGetHinge2Param (dJointID, int parameter)
+ dReal dJointGetHinge2Angle1 (dJointID)
+ dReal dJointGetHinge2Angle1Rate (dJointID)
+ dReal dJointGetHinge2Angle2Rate (dJointID)
+ void dJointGetUniversalAnchor (dJointID, dVector3 result)
+ void dJointGetUniversalAnchor2 (dJointID, dVector3 result)
+ void dJointGetUniversalAxis1 (dJointID, dVector3 result)
+ void dJointGetUniversalAxis2 (dJointID, dVector3 result)
+ dReal dJointGetUniversalParam (dJointID, int parameter)
+ dReal dJointGetUniversalAngle1 (dJointID)
+ dReal dJointGetUniversalAngle2 (dJointID)
+ dReal dJointGetUniversalAngle1Rate (dJointID)
+ dReal dJointGetUniversalAngle2Rate (dJointID)
+ int dJointGetAMotorNumAxes (dJointID)
+ void dJointGetAMotorAxis (dJointID, int anum, dVector3 result)
+ int dJointGetAMotorAxisRel (dJointID, int anum)
+ dReal dJointGetAMotorAngle (dJointID, int anum)
+ dReal dJointGetAMotorAngleRate (dJointID, int anum)
+ dReal dJointGetAMotorParam (dJointID, int parameter)
+ int dJointGetAMotorMode (dJointID)
+ int dJointGetLMotorNumAxes (dJointID)
+ void dJointGetLMotorAxis (dJointID, int anum, dVector3 result)
+ dReal dJointGetLMotorParam (dJointID, int parameter)
+ void dJointSetPlane2DXParam (dJointID, int parameter, dReal value)
+ void dJointSetPlane2DYParam (dJointID, int parameter, dReal value)
+ void dJointSetPlane2DAngleParam (dJointID, int parameter, dReal value)
+ dReal dJointGetPRPosition (dJointID j)
+ void dJointSetPRAnchor (dJointID j, dReal x, dReal y, dReal z)
+ void dJointSetPRAxis1 (dJointID j, dReal x, dReal y, dReal z)
+ void dJointSetPRAxis2 (dJointID j, dReal x, dReal y, dReal z)
+ void dJointGetPRAnchor (dJointID j, dVector3 result)
+ void dJointGetPRAxis1 (dJointID j, dVector3 result)
+ void dJointGetPRAxis2 (dJointID j, dVector3 result)
+
+ void dJointSetFeedback (dJointID, dJointFeedback *)
+ dJointFeedback *dJointGetFeedback (dJointID)
+
+ int dAreConnected (dBodyID, dBodyID)
+
+ # Mass
+ void dMassSetZero (dMass *)
+ void dMassSetParameters (dMass *, dReal themass,
+ dReal cgx, dReal cgy, dReal cgz,
+ dReal I11, dReal I22, dReal I33,
+ dReal I12, dReal I13, dReal I23)
+ void dMassSetSphere (dMass *, dReal density, dReal radius)
+ void dMassSetSphereTotal (dMass *, dReal total_mass, dReal radius)
+ void dMassSetCapsule (dMass *, dReal density, int direction, dReal radius, dReal length)
+ void dMassSetCapsuleTotal (dMass *, dReal total_mass, int direction, dReal radius, dReal length)
+ void dMassSetCylinder (dMass *, dReal density, int direction,
+ dReal radius, dReal length)
+ void dMassSetCylinderTotal (dMass *, dReal total_mass, int direction,
+ dReal radius, dReal length)
+ void dMassSetBox (dMass *, dReal density,
+ dReal lx, dReal ly, dReal lz)
+ void dMassSetBoxTotal (dMass *, dReal total_mass,
+ dReal lx, dReal ly, dReal lz)
+ void dMassAdjust (dMass *, dReal newmass)
+ void dMassTranslate (dMass *, dReal x, dReal y, dReal z)
+ void dMassRotate (dMass *, dMatrix3 R)
+ void dMassAdd (dMass *a, dMass *b)
+
+ # Space
+# dSpaceID dSimpleSpaceCreate(int space)
+# dSpaceID dHashSpaceCreate(int space)
+ dSpaceID dSimpleSpaceCreate(dSpaceID space)
+ dSpaceID dHashSpaceCreate(dSpaceID space)
+ dSpaceID dQuadTreeSpaceCreate (dSpaceID space, dVector3 Center,
+ dVector3 Extents, int Depth)
+
+ void dSpaceDestroy (dSpaceID)
+ void dSpaceAdd (dSpaceID, dGeomID)
+ void dSpaceRemove (dSpaceID, dGeomID)
+ int dSpaceQuery (dSpaceID, dGeomID)
+ void dSpaceCollide (dSpaceID space, void *data, dNearCallback *callback)
+ void dSpaceCollide2 (dGeomID o1, dGeomID o2, void *data, dNearCallback *callback)
+
+ void dHashSpaceSetLevels (dSpaceID space, int minlevel, int maxlevel)
+ void dHashSpaceGetLevels (dSpaceID space, int *minlevel, int *maxlevel)
+
+ void dSpaceSetCleanup (dSpaceID space, int mode)
+ int dSpaceGetCleanup (dSpaceID space)
+
+ int dSpaceGetNumGeoms (dSpaceID)
+ dGeomID dSpaceGetGeom (dSpaceID, int i)
+
+ # Geom
+ dGeomID dCreateSphere (dSpaceID space, dReal radius)
+ dGeomID dCreateBox (dSpaceID space, dReal lx, dReal ly, dReal lz)
+ dGeomID dCreatePlane (dSpaceID space, dReal a, dReal b, dReal c, dReal d)
+ dGeomID dCreateCapsule (dSpaceID space, dReal radius, dReal length)
+ dGeomID dCreateCylinder (dSpaceID space, dReal radius, dReal length)
+ dGeomID dCreateGeomGroup (dSpaceID space)
+
+ void dGeomSphereSetRadius (dGeomID sphere, dReal radius)
+ void dGeomBoxSetLengths (dGeomID box, dReal lx, dReal ly, dReal lz)
+ void dGeomPlaneSetParams (dGeomID plane, dReal a, dReal b, dReal c, dReal d)
+ void dGeomCapsuleSetParams (dGeomID ccylinder, dReal radius, dReal length)
+ void dGeomCylinderSetParams (dGeomID ccylinder, dReal radius, dReal length)
+
+ dReal dGeomSphereGetRadius (dGeomID sphere)
+ void dGeomBoxGetLengths (dGeomID box, dVector3 result)
+ void dGeomPlaneGetParams (dGeomID plane, dVector4 result)
+ void dGeomCapsuleGetParams (dGeomID ccylinder, dReal *radius, dReal *length)
+ void dGeomCylinderGetParams (dGeomID ccylinder, dReal *radius, dReal *length)
+
+ dReal dGeomSpherePointDepth (dGeomID sphere, dReal x, dReal y, dReal z)
+ dReal dGeomBoxPointDepth (dGeomID box, dReal x, dReal y, dReal z)
+ dReal dGeomPlanePointDepth (dGeomID plane, dReal x, dReal y, dReal z)
+ dReal dGeomCapsulePointDepth (dGeomID ccylinder, dReal x, dReal y, dReal z)
+
+ dGeomID dCreateRay (dSpaceID space, dReal length)
+ void dGeomRaySetLength (dGeomID ray, dReal length)
+ dReal dGeomRayGetLength (dGeomID ray)
+ void dGeomRaySet (dGeomID ray, dReal px, dReal py, dReal pz,
+ dReal dx, dReal dy, dReal dz)
+ void dGeomRayGet (dGeomID ray, dVector3 start, dVector3 dir)
+
+ void dGeomSetData (dGeomID, void *)
+ void *dGeomGetData (dGeomID)
+ void dGeomSetBody (dGeomID, dBodyID)
+ dBodyID dGeomGetBody (dGeomID)
+ void dGeomSetPosition (dGeomID, dReal x, dReal y, dReal z)
+ void dGeomSetRotation (dGeomID, dMatrix3 R)
+ void dGeomSetQuaternion (dGeomID, dQuaternion)
+ dReal * dGeomGetPosition (dGeomID)
+ dReal * dGeomGetRotation (dGeomID)
+ void dGeomGetQuaternion (dGeomID, dQuaternion result)
+ void dGeomSetOffsetPosition (dGeomID, dReal x, dReal y, dReal z)
+ void dGeomSetOffsetRotation (dGeomID, dMatrix3 R)
+ void dGeomClearOffset (dGeomID)
+ dReal * dGeomGetOffsetPosition (dGeomID)
+ dReal * dGeomGetOffsetRotation (dGeomID)
+ void dGeomDestroy (dGeomID)
+ void dGeomGetAABB (dGeomID, dReal aabb[6])
+ dReal *dGeomGetSpaceAABB (dGeomID)
+ int dGeomIsSpace (dGeomID)
+ dSpaceID dGeomGetSpace (dGeomID)
+ int dGeomGetClass (dGeomID)
+
+ void dGeomSetCategoryBits(dGeomID, unsigned long bits)
+ void dGeomSetCollideBits(dGeomID, unsigned long bits)
+ unsigned long dGeomGetCategoryBits(dGeomID)
+ unsigned long dGeomGetCollideBits(dGeomID)
+
+ void dGeomEnable (dGeomID)
+ void dGeomDisable (dGeomID)
+ int dGeomIsEnabled (dGeomID)
+
+ void dGeomGroupAdd (dGeomID group, dGeomID x)
+ void dGeomGroupRemove (dGeomID group, dGeomID x)
+ int dGeomGroupGetNumGeoms (dGeomID group)
+ dGeomID dGeomGroupGetGeom (dGeomID group, int i)
+
+ dGeomID dCreateGeomTransform (dSpaceID space)
+ void dGeomTransformSetGeom (dGeomID g, dGeomID obj)
+ dGeomID dGeomTransformGetGeom (dGeomID g)
+ void dGeomTransformSetCleanup (dGeomID g, int mode)
+ int dGeomTransformGetCleanup (dGeomID g)
+ void dGeomTransformSetInfo (dGeomID g, int mode)
+ int dGeomTransformGetInfo (dGeomID g)
+
+ int dCollide (dGeomID o1, dGeomID o2, int flags, dContactGeom *contact, int skip)
+
+ # Trimesh
+ dTriMeshDataID dGeomTriMeshDataCreate()
+ void dGeomTriMeshDataDestroy(dTriMeshDataID g)
+ void dGeomTriMeshDataBuildSingle1 (dTriMeshDataID g, void* Vertices,
+ int VertexStride, int VertexCount,
+ void* Indices, int IndexCount,
+ int TriStride, void* Normals)
+
+ void dGeomTriMeshDataBuildSimple(dTriMeshDataID g,
+ dReal* Vertices, int VertexCount,
+ int* Indices, int IndexCount)
+
+ dGeomID dCreateTriMesh (dSpaceID space, dTriMeshDataID Data,
+ void* Callback,
+ void* ArrayCallback,
+ void* RayCallback)
+
+ void dGeomTriMeshSetData (dGeomID g, dTriMeshDataID Data)
+
+ void dGeomTriMeshClearTCCache (dGeomID g)
+
+ void dGeomTriMeshGetTriangle (dGeomID g, int Index, dVector3 *v0,
+ dVector3 *v1, dVector3 *v2)
+
+ int dGeomTriMeshGetTriangleCount (dGeomID g)
+
+ void dGeomTriMeshGetPoint (dGeomID g, int Index, dReal u, dReal v,
+ dVector3 Out)
+
+ void dGeomTriMeshEnableTC(dGeomID g, int geomClass, int enable)
+ int dGeomTriMeshIsTCEnabled(dGeomID g, int geomClass)
+
+ # Heightfield
+ dHeightfieldDataID dGeomHeightfieldDataCreate()
+ void dGeomHeightfieldDataDestroy(dHeightfieldDataID g)
+ void dGeomHeightfieldDataBuildCallback(dHeightfieldDataID d,
+ void* pUserData,
+ dHeightfieldGetHeight* pCallback,
+ dReal width, dReal depth,
+ int widthSamples, int depthSamples,
+ dReal scale, dReal offset,
+ dReal thickness, int bWrap)
+ dGeomID dCreateHeightfield (dSpaceID space, dHeightfieldDataID data,
+ int bPlaceable)
+
diff --git a/libs/ode-0.16.1/bindings/python/ode.pyx b/libs/ode-0.16.1/bindings/python/ode.pyx new file mode 100644 index 0000000..92068f2 --- /dev/null +++ b/libs/ode-0.16.1/bindings/python/ode.pyx @@ -0,0 +1,4506 @@ +######################################################################
+# Python Open Dynamics Engine Wrapper
+# Copyright (C) 2004 PyODE developers (see file AUTHORS)
+# All rights reserved.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of EITHER:
+# (1) The GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2.1 of the License, or (at
+# your option) any later version. The text of the GNU Lesser
+# General Public License is included with this library in the
+# file LICENSE.
+# (2) The BSD-style license that is included with this library in
+# the file LICENSE-BSD.
+#
+# This library 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 files
+# LICENSE and LICENSE-BSD for more details.
+######################################################################
+
+from ode cimport *
+
+
+paramLoStop = 0
+paramHiStop = 1
+paramVel = 2
+paramLoVel = 3
+paramHiVel = 4
+paramFMax = 5
+paramFudgeFactor = 6
+paramBounce = 7
+paramCFM = 8
+paramStopERP = 9
+paramStopCFM = 10
+paramSuspensionERP = 11
+paramSuspensionCFM = 12
+paramERP = 13
+
+ParamLoStop = 0
+ParamHiStop = 1
+ParamVel = 2
+ParamLoVel = 3
+ParamHiVel = 4
+ParamFMax = 5
+ParamFudgeFactor = 6
+ParamBounce = 7
+ParamCFM = 8
+ParamStopERP = 9
+ParamStopCFM = 10
+ParamSuspensionERP = 11
+ParamSuspensionCFM = 12
+ParamERP = 13
+
+ParamLoStop2 = 256 + 0
+ParamHiStop2 = 256 + 1
+ParamVel2 = 256 + 2
+ParamLoVel2 = 256 + 3
+ParamHiVel2 = 256 + 4
+ParamFMax2 = 256 + 5
+ParamFudgeFactor2 = 256 + 6
+ParamBounce2 = 256 + 7
+ParamCFM2 = 256 + 8
+ParamStopERP2 = 256 + 9
+ParamStopCFM2 = 256 + 10
+ParamSuspensionERP2 = 256 + 11
+ParamSuspensionCFM2 = 256 + 12
+ParamERP2 = 256 + 13
+
+ParamLoStop3 = 512 + 0
+ParamHiStop3 = 512 + 1
+ParamVel3 = 512 + 2
+ParamLoVel3 = 512 + 3
+ParamHiVel3 = 512 + 4
+ParamFMax3 = 512 + 5
+ParamFudgeFactor3 = 512 + 6
+ParamBounce3 = 512 + 7
+ParamCFM3 = 512 + 8
+ParamStopERP3 = 512 + 9
+ParamStopCFM3 = 512 + 10
+ParamSuspensionERP3 = 512 + 11
+ParamSuspensionCFM3 = 512 + 12
+ParamERP3 = 512 + 13
+
+ParamGroup = 256
+
+ContactMu2 = 0x001
+ContactAxisDep = 0x001
+ContactFDir1 = 0x002
+ContactBounce = 0x004
+ContactSoftERP = 0x008
+ContactSoftCFM = 0x010
+ContactMotion1 = 0x020
+ContactMotion2 = 0x040
+ContactMotionN = 0x080
+ContactSlip1 = 0x100
+ContactSlip2 = 0x200
+ContactRolling = 0x400
+
+ContactApprox0 = 0x0000
+ContactApprox1_1 = 0x1000
+ContactApprox1_2 = 0x2000
+ContactApprox1_N = 0x4000
+ContactApprox1 = 0x7000
+
+AMotorUser = dAMotorUser
+AMotorEuler = dAMotorEuler
+
+Infinity = dInfinity
+
+
+import weakref
+_geom_c2py_lut = weakref.WeakValueDictionary()
+
+
+cdef class Mass:
+ """Mass parameters of a rigid body.
+
+ This class stores mass parameters of a rigid body which can be
+ accessed through the following attributes:
+
+ - mass: The total mass of the body (float)
+ - c: The center of gravity position in body frame (3-tuple of floats)
+ - I: The 3x3 inertia tensor in body frame (3-tuple of 3-tuples)
+
+ This class wraps the dMass structure from the C API.
+
+ @ivar mass: The total mass of the body
+ @ivar c: The center of gravity position in body frame (cx, cy, cz)
+ @ivar I: The 3x3 inertia tensor in body frame ((I11, I12, I13), (I12, I22, I23), (I13, I23, I33))
+ @type mass: float
+ @type c: 3-tuple of floats
+ @type I: 3-tuple of 3-tuples of floats
+ """
+ cdef dMass _mass
+
+ def __cinit__(self):
+ dMassSetZero(&self._mass)
+
+ def setZero(self):
+ """setZero()
+
+ Set all the mass parameters to zero."""
+ dMassSetZero(&self._mass)
+
+ def setParameters(self, mass, cgx, cgy, cgz, I11, I22, I33, I12, I13, I23):
+ """setParameters(mass, cgx, cgy, cgz, I11, I22, I33, I12, I13, I23)
+
+ Set the mass parameters to the given values.
+
+ @param mass: Total mass of the body.
+ @param cgx: Center of gravity position in the body frame (x component).
+ @param cgy: Center of gravity position in the body frame (y component).
+ @param cgz: Center of gravity position in the body frame (z component).
+ @param I11: Inertia tensor
+ @param I22: Inertia tensor
+ @param I33: Inertia tensor
+ @param I12: Inertia tensor
+ @param I13: Inertia tensor
+ @param I23: Inertia tensor
+ @type mass: float
+ @type cgx: float
+ @type cgy: float
+ @type cgz: float
+ @type I11: float
+ @type I22: float
+ @type I33: float
+ @type I12: float
+ @type I13: float
+ @type I23: float
+ """
+ dMassSetParameters(&self._mass, mass, cgx, cgy, cgz,
+ I11, I22, I33, I12, I13, I23)
+
+ def setSphere(self, density, radius):
+ """setSphere(density, radius)
+
+ Set the mass parameters to represent a sphere of the given radius
+ and density, with the center of mass at (0,0,0) relative to the body.
+
+ @param density: The density of the sphere
+ @param radius: The radius of the sphere
+ @type density: float
+ @type radius: float
+ """
+ dMassSetSphere(&self._mass, density, radius)
+
+ def setSphereTotal(self, total_mass, radius):
+ """setSphereTotal(total_mass, radius)
+
+ Set the mass parameters to represent a sphere of the given radius
+ and mass, with the center of mass at (0,0,0) relative to the body.
+
+ @param total_mass: The total mass of the sphere
+ @param radius: The radius of the sphere
+ @type total_mass: float
+ @type radius: float
+ """
+ dMassSetSphereTotal(&self._mass, total_mass, radius)
+
+ def setCapsule(self, density, direction, radius, length):
+ """setCapsule(density, direction, radius, length)
+
+ Set the mass parameters to represent a capsule of the given parameters
+ and density, with the center of mass at (0,0,0) relative to the body.
+ The radius of the cylinder (and the spherical cap) is radius. The length
+ of the cylinder (not counting the spherical cap) is length. The
+ cylinder's long axis is oriented along the body's x, y or z axis
+ according to the value of direction (1=x, 2=y, 3=z). The first function
+ accepts the density of the object, the second accepts its total mass.
+
+ @param density: The density of the capsule
+ @param direction: The direction of the capsule's cylinder (1=x axis, 2=y axis, 3=z axis)
+ @param radius: The radius of the capsule's cylinder
+ @param length: The length of the capsule's cylinder (without the caps)
+ @type density: float
+ @type direction: int
+ @type radius: float
+ @type length: float
+ """
+ dMassSetCapsule(&self._mass, density, direction, radius, length)
+
+ def setCapsuleTotal(self, total_mass, direction, radius, length):
+ """setCapsuleTotal(total_mass, direction, radius, length)
+
+ Set the mass parameters to represent a capsule of the given parameters
+ and mass, with the center of mass at (0,0,0) relative to the body. The
+ radius of the cylinder (and the spherical cap) is radius. The length of
+ the cylinder (not counting the spherical cap) is length. The cylinder's
+ long axis is oriented along the body's x, y or z axis according to the
+ value of direction (1=x, 2=y, 3=z). The first function accepts the
+ density of the object, the second accepts its total mass.
+
+ @param total_mass: The total mass of the capsule
+ @param direction: The direction of the capsule's cylinder (1=x axis, 2=y axis, 3=z axis)
+ @param radius: The radius of the capsule's cylinder
+ @param length: The length of the capsule's cylinder (without the caps)
+ @type total_mass: float
+ @type direction: int
+ @type radius: float
+ @type length: float
+ """
+ dMassSetCapsuleTotal(&self._mass, total_mass, direction,
+ radius, length)
+
+ def setCylinder(self, density, direction, r, h):
+ """setCylinder(density, direction, r, h)
+
+ Set the mass parameters to represent a flat-ended cylinder of
+ the given parameters and density, with the center of mass at
+ (0,0,0) relative to the body. The radius of the cylinder is r.
+ The length of the cylinder is h. The cylinder's long axis is
+ oriented along the body's x, y or z axis according to the value
+ of direction (1=x, 2=y, 3=z).
+
+ @param density: The density of the cylinder
+ @param direction: The direction of the cylinder (1=x axis, 2=y axis, 3=z axis)
+ @param r: The radius of the cylinder
+ @param h: The length of the cylinder
+ @type density: float
+ @type direction: int
+ @type r: float
+ @type h: float
+ """
+ dMassSetCylinder(&self._mass, density, direction, r, h)
+
+ def setCylinderTotal(self, total_mass, direction, r, h):
+ """setCylinderTotal(total_mass, direction, r, h)
+
+ Set the mass parameters to represent a flat-ended cylinder of
+ the given parameters and mass, with the center of mass at
+ (0,0,0) relative to the body. The radius of the cylinder is r.
+ The length of the cylinder is h. The cylinder's long axis is
+ oriented along the body's x, y or z axis according to the value
+ of direction (1=x, 2=y, 3=z).
+
+ @param total_mass: The total mass of the cylinder
+ @param direction: The direction of the cylinder (1=x axis, 2=y axis, 3=z axis)
+ @param r: The radius of the cylinder
+ @param h: The length of the cylinder
+ @type total_mass: float
+ @type direction: int
+ @type r: float
+ @type h: float
+ """
+ dMassSetCylinderTotal(&self._mass, total_mass, direction, r, h)
+
+ def setBox(self, density, lx, ly, lz):
+ """setBox(density, lx, ly, lz)
+
+ Set the mass parameters to represent a box of the given
+ dimensions and density, with the center of mass at (0,0,0)
+ relative to the body. The side lengths of the box along the x,
+ y and z axes are lx, ly and lz.
+
+ @param density: The density of the box
+ @param lx: The length along the x axis
+ @param ly: The length along the y axis
+ @param lz: The length along the z axis
+ @type density: float
+ @type lx: float
+ @type ly: float
+ @type lz: float
+ """
+ dMassSetBox(&self._mass, density, lx, ly, lz)
+
+ def setBoxTotal(self, total_mass, lx, ly, lz):
+ """setBoxTotal(total_mass, lx, ly, lz)
+
+ Set the mass parameters to represent a box of the given
+ dimensions and mass, with the center of mass at (0,0,0)
+ relative to the body. The side lengths of the box along the x,
+ y and z axes are lx, ly and lz.
+
+ @param total_mass: The total mass of the box
+ @param lx: The length along the x axis
+ @param ly: The length along the y axis
+ @param lz: The length along the z axis
+ @type total_mass: float
+ @type lx: float
+ @type ly: float
+ @type lz: float
+ """
+ dMassSetBoxTotal(&self._mass, total_mass, lx, ly, lz)
+
+ def adjust(self, newmass):
+ """adjust(newmass)
+
+ Adjust the total mass. Given mass parameters for some object,
+ adjust them so the total mass is now newmass. This is useful
+ when using the setXyz() methods to set the mass parameters for
+ certain objects - they take the object density, not the total
+ mass.
+
+ @param newmass: The new total mass
+ @type newmass: float
+ """
+ dMassAdjust(&self._mass, newmass)
+
+ def translate(self, t):
+ """translate(t)
+
+ Adjust mass parameters. Given mass parameters for some object,
+ adjust them to represent the object displaced by (x,y,z)
+ relative to the body frame.
+
+ @param t: Translation vector (x, y, z)
+ @type t: 3-tuple of floats
+ """
+ dMassTranslate(&self._mass, t[0], t[1], t[2])
+
+# def rotate(self, R):
+# """
+# Given mass parameters for some object, adjust them to
+# represent the object rotated by R relative to the body frame.
+# """
+# pass
+
+ def add(self, Mass b):
+ """add(b)
+
+ Add the mass b to the mass object. Masses can also be added using
+ the + operator.
+
+ @param b: The mass to add to this mass
+ @type b: Mass
+ """
+ dMassAdd(&self._mass, &b._mass)
+
+ def __getattr__(self, name):
+ if name == "mass":
+ return self._mass.mass
+ elif name == "c":
+ return self._mass.c[0], self._mass.c[1], self._mass.c[2]
+ elif name == "I":
+ return ((self._mass.I[0], self._mass.I[1], self._mass.I[2]),
+ (self._mass.I[4], self._mass.I[5], self._mass.I[6]),
+ (self._mass.I[8], self._mass.I[9], self._mass.I[10]))
+ else:
+ raise AttributeError("Mass object has no attribute '%s'" % name)
+
+ def __setattr__(self, name, value):
+ if name == "mass":
+ self.adjust(value)
+ elif name == "c":
+ raise AttributeError("Use the setParameter() method to change c")
+ elif name == "I":
+ raise AttributeError("Use the setParameter() method to change I")
+ else:
+ raise AttributeError("Mass object has no attribute '%s" % name)
+
+ def __add__(self, Mass b):
+ self.add(b)
+ return self
+
+ def __str__(self):
+ m = str(self._mass.mass)
+ sc0 = str(self._mass.c[0])
+ sc1 = str(self._mass.c[1])
+ sc2 = str(self._mass.c[2])
+ I11 = str(self._mass.I[0])
+ I22 = str(self._mass.I[5])
+ I33 = str(self._mass.I[10])
+ I12 = str(self._mass.I[1])
+ I13 = str(self._mass.I[2])
+ I23 = str(self._mass.I[6])
+ return ("Mass=%s\n"
+ "Cg=(%s, %s, %s)\n"
+ "I11=%s I22=%s I33=%s\n"
+ "I12=%s I13=%s I23=%s" %
+ (m, sc0, sc1, sc2, I11, I22, I33, I12, I13, I23))
+# return ("Mass=%s / "
+# "Cg=(%s, %s, %s) / "
+# "I11=%s I22=%s I33=%s "
+# "I12=%s I13=%s I23=%s" %
+# (m, sc0, sc1, sc2, I11, I22, I33, I12, I13, I23))
+
+
+cdef class Contact:
+ """This class represents a contact between two bodies in one point.
+
+ A Contact object stores all the input parameters for a ContactJoint.
+ This class wraps the ODE dContact structure which has 3 components::
+
+ struct dContact {
+ dSurfaceParameters surface;
+ dContactGeom geom;
+ dVector3 fdir1;
+ };
+
+ This wrapper class provides methods to get and set the items of those
+ structures.
+ """
+
+ cdef dContact _contact
+
+ def __cinit__(self):
+ self._contact.surface.mode = ContactBounce
+ self._contact.surface.mu = dInfinity
+
+ self._contact.surface.bounce = 0.1
+
+ # getMode
+ def getMode(self):
+ """getMode() -> flags
+
+ Return the contact flags.
+ """
+ return self._contact.surface.mode
+
+ # setMode
+ def setMode(self, flags):
+ """setMode(flags)
+
+ Set the contact flags. The argument m is a combination of the
+ ContactXyz flags (ContactMu2, ContactBounce, ...).
+
+ @param flags: Contact flags
+ @type flags: int
+ """
+ self._contact.surface.mode = flags
+
+ # getMu
+ def getMu(self):
+ """getMu() -> float
+
+ Return the Coulomb friction coefficient.
+ """
+ return self._contact.surface.mu
+
+ # setMu
+ def setMu(self, mu):
+ """setMu(mu)
+
+ Set the Coulomb friction coefficient.
+
+ @param mu: Coulomb friction coefficient (0..Infinity)
+ @type mu: float
+ """
+ self._contact.surface.mu = mu
+
+ # getMu2
+ def getMu2(self):
+ """getMu2() -> float
+
+ Return the optional Coulomb friction coefficient for direction 2.
+ """
+ return self._contact.surface.mu2
+
+ # setMu2
+ def setMu2(self, mu):
+ """setMu2(mu)
+
+ Set the optional Coulomb friction coefficient for direction 2.
+
+ @param mu: Coulomb friction coefficient (0..Infinity)
+ @type mu: float
+ """
+ self._contact.surface.mu2 = mu
+
+ # getBounce
+ def getBounce(self):
+ """getBounce() -> float
+
+ Return the restitution parameter.
+ """
+ return self._contact.surface.bounce
+
+ # setBounce
+ def setBounce(self, b):
+ """setBounce(b)
+
+ @param b: Restitution parameter (0..1)
+ @type b: float
+ """
+ self._contact.surface.bounce = b
+
+ # getBounceVel
+ def getBounceVel(self):
+ """getBounceVel() -> float
+
+ Return the minimum incoming velocity necessary for bounce.
+ """
+ return self._contact.surface.bounce_vel
+
+ # setBounceVel
+ def setBounceVel(self, bv):
+ """setBounceVel(bv)
+
+ Set the minimum incoming velocity necessary for bounce. Incoming
+ velocities below this will effectively have a bounce parameter of 0.
+
+ @param bv: Velocity
+ @type bv: float
+ """
+ self._contact.surface.bounce_vel = bv
+
+ # getSoftERP
+ def getSoftERP(self):
+ """getSoftERP() -> float
+
+ Return the contact normal "softness" parameter.
+ """
+ return self._contact.surface.soft_erp
+
+ # setSoftERP
+ def setSoftERP(self, erp):
+ """setSoftERP(erp)
+
+ Set the contact normal "softness" parameter.
+
+ @param erp: Softness parameter
+ @type erp: float
+ """
+ self._contact.surface.soft_erp = erp
+
+ # getSoftCFM
+ def getSoftCFM(self):
+ """getSoftCFM() -> float
+
+ Return the contact normal "softness" parameter.
+ """
+ return self._contact.surface.soft_cfm
+
+ # setSoftCFM
+ def setSoftCFM(self, cfm):
+ """setSoftCFM(cfm)
+
+ Set the contact normal "softness" parameter.
+
+ @param cfm: Softness parameter
+ @type cfm: float
+ """
+ self._contact.surface.soft_cfm = cfm
+
+ # getMotion1
+ def getMotion1(self):
+ """getMotion1() -> float
+
+ Get the surface velocity in friction direction 1.
+ """
+ return self._contact.surface.motion1
+
+ # setMotion1
+ def setMotion1(self, m):
+ """setMotion1(m)
+
+ Set the surface velocity in friction direction 1.
+
+ @param m: Surface velocity
+ @type m: float
+ """
+ self._contact.surface.motion1 = m
+
+ # getMotion2
+ def getMotion2(self):
+ """getMotion2() -> float
+
+ Get the surface velocity in friction direction 2.
+ """
+ return self._contact.surface.motion2
+
+ # setMotion2
+ def setMotion2(self, m):
+ """setMotion2(m)
+
+ Set the surface velocity in friction direction 2.
+
+ @param m: Surface velocity
+ @type m: float
+ """
+ self._contact.surface.motion2 = m
+
+ # getSlip1
+ def getSlip1(self):
+ """getSlip1() -> float
+
+ Get the coefficient of force-dependent-slip (FDS) for friction
+ direction 1.
+ """
+ return self._contact.surface.slip1
+
+ # setSlip1
+ def setSlip1(self, s):
+ """setSlip1(s)
+
+ Set the coefficient of force-dependent-slip (FDS) for friction
+ direction 1.
+
+ @param s: FDS coefficient
+ @type s: float
+ """
+ self._contact.surface.slip1 = s
+
+ # getSlip2
+ def getSlip2(self):
+ """getSlip2() -> float
+
+ Get the coefficient of force-dependent-slip (FDS) for friction
+ direction 2.
+ """
+ return self._contact.surface.slip2
+
+ # setSlip2
+ def setSlip2(self, s):
+ """setSlip2(s)
+
+ Set the coefficient of force-dependent-slip (FDS) for friction
+ direction 1.
+
+ @param s: FDS coefficient
+ @type s: float
+ """
+ self._contact.surface.slip2 = s
+
+ # getFDir1
+ def getFDir1(self):
+ """getFDir1() -> (x, y, z)
+
+ Get the "first friction direction" vector that defines a direction
+ along which frictional force is applied.
+ """
+ return (self._contact.fdir1[0],
+ self._contact.fdir1[1],
+ self._contact.fdir1[2])
+
+ # setFDir1
+ def setFDir1(self, fdir):
+ """setFDir1(fdir)
+
+ Set the "first friction direction" vector that defines a direction
+ along which frictional force is applied. It must be of unit length
+ and perpendicular to the contact normal (so it is typically
+ tangential to the contact surface).
+
+ @param fdir: Friction direction
+ @type fdir: 3-sequence of floats
+ """
+ self._contact.fdir1[0] = fdir[0]
+ self._contact.fdir1[1] = fdir[1]
+ self._contact.fdir1[2] = fdir[2]
+
+ # getContactGeomParams
+ def getContactGeomParams(self):
+ """getContactGeomParams() -> (pos, normal, depth, geom1, geom2)
+
+ Get the ContactGeom structure of the contact.
+
+ The return value is a tuple (pos, normal, depth, geom1, geom2)
+ where pos and normal are 3-tuples of floats and depth is a single
+ float. geom1 and geom2 are the Geom objects of the geoms in contact.
+ """
+ cdef size_t id1, id2
+
+ pos = (self._contact.geom.pos[0],
+ self._contact.geom.pos[1],
+ self._contact.geom.pos[2])
+ normal = (self._contact.geom.normal[0],
+ self._contact.geom.normal[1],
+ self._contact.geom.normal[2])
+ depth = self._contact.geom.depth
+
+ id1 = <size_t>self._contact.geom.g1
+ id2 = <size_t>self._contact.geom.g2
+ g1 = _geom_c2py_lut[id1]
+ g2 = _geom_c2py_lut[id2]
+ return pos, normal, depth, g1, g2
+
+ # setContactGeomParams
+ def setContactGeomParams(self, pos, normal, depth, g1=None, g2=None):
+ """setContactGeomParams(pos, normal, depth, geom1=None, geom2=None)
+
+ Set the ContactGeom structure of the contact.
+
+ @param pos: Contact position, in global coordinates
+ @type pos: 3-sequence of floats
+ @param normal: Unit length normal vector
+ @type normal: 3-sequence of floats
+ @param depth: Depth to which the two bodies inter-penetrate
+ @type depth: float
+ @param geom1: Geometry object 1 that collided
+ @type geom1: Geom
+ @param geom2: Geometry object 2 that collided
+ @type geom2: Geom
+ """
+
+ cdef size_t id
+
+ self._contact.geom.pos[0] = pos[0]
+ self._contact.geom.pos[1] = pos[1]
+ self._contact.geom.pos[2] = pos[2]
+ self._contact.geom.normal[0] = normal[0]
+ self._contact.geom.normal[1] = normal[1]
+ self._contact.geom.normal[2] = normal[2]
+ self._contact.geom.depth = depth
+ if g1 != None:
+ id = g1._id()
+ self._contact.geom.g1 = <dGeomID>id
+ else:
+ self._contact.geom.g1 = <dGeomID>0
+
+ if g2 != None:
+ id = g2._id()
+ self._contact.geom.g2 = <dGeomID>id
+ else:
+ self._contact.geom.g2 = <dGeomID>0
+
+
+# World
+cdef class World:
+ """Dynamics world.
+
+ The world object is a container for rigid bodies and joints.
+
+
+ Constructor::
+
+ World()
+ """
+
+ cdef dWorldID wid
+
+ def __cinit__(self):
+ self.wid = dWorldCreate()
+
+ def __dealloc__(self):
+ if self.wid != NULL:
+ dWorldDestroy(self.wid)
+
+ # setGravity
+ def setGravity(self, gravity):
+ """setGravity(gravity)
+
+ Set the world's global gravity vector.
+
+ @param gravity: Gravity vector
+ @type gravity: 3-sequence of floats
+ """
+ dWorldSetGravity(self.wid, gravity[0], gravity[1], gravity[2])
+
+ # getGravity
+ def getGravity(self):
+ """getGravity() -> 3-tuple
+
+ Return the world's global gravity vector as a 3-tuple of floats.
+ """
+ cdef dVector3 g
+ dWorldGetGravity(self.wid, g)
+ return g[0], g[1], g[2]
+
+ # setERP
+ def setERP(self, erp):
+ """setERP(erp)
+
+ Set the global ERP value, that controls how much error
+ correction is performed in each time step. Typical values are
+ in the range 0.1-0.8. The default is 0.2.
+
+ @param erp: Global ERP value
+ @type erp: float
+ """
+ dWorldSetERP(self.wid, erp)
+
+ # getERP
+ def getERP(self):
+ """getERP() -> float
+
+ Get the global ERP value, that controls how much error
+ correction is performed in each time step. Typical values are
+ in the range 0.1-0.8. The default is 0.2.
+ """
+ return dWorldGetERP(self.wid)
+
+ # setCFM
+ def setCFM(self, cfm):
+ """setCFM(cfm)
+
+ Set the global CFM (constraint force mixing) value. Typical
+ values are in the range 10E-9 - 1. The default is 10E-5 if
+ single precision is being used, or 10E-10 if double precision
+ is being used.
+
+ @param cfm: Constraint force mixing value
+ @type cfm: float
+ """
+ dWorldSetCFM(self.wid, cfm)
+
+ # getCFM
+ def getCFM(self):
+ """getCFM() -> float
+
+ Get the global CFM (constraint force mixing) value. Typical
+ values are in the range 10E-9 - 1. The default is 10E-5 if
+ single precision is being used, or 10E-10 if double precision
+ is being used.
+ """
+ return dWorldGetCFM(self.wid)
+
+ # step
+ def step(self, stepsize):
+ """step(stepsize)
+
+ Step the world. This uses a "big matrix" method that takes
+ time on the order of O(m3) and memory on the order of O(m2), where m
+ is the total number of constraint rows.
+
+ For large systems this will use a lot of memory and can be
+ very slow, but this is currently the most accurate method.
+
+ @param stepsize: Time step
+ @type stepsize: float
+ """
+
+ dWorldStep(self.wid, stepsize)
+
+ # quickStep
+ def quickStep(self, stepsize):
+ """quickStep(stepsize)
+
+ Step the world. This uses an iterative method that takes time
+ on the order of O(m*N) and memory on the order of O(m), where m is
+ the total number of constraint rows and N is the number of
+ iterations.
+
+ For large systems this is a lot faster than dWorldStep, but it
+ is less accurate.
+
+ @param stepsize: Time step
+ @type stepsize: float
+ """
+ dWorldQuickStep(self.wid, stepsize)
+
+ # setQuickStepNumIterations
+ def setQuickStepNumIterations(self, num):
+ """setQuickStepNumIterations(num)
+
+ Set the number of iterations that the QuickStep method
+ performs per step. More iterations will give a more accurate
+ solution, but will take longer to compute. The default is 20
+ iterations.
+
+ @param num: Number of iterations
+ @type num: int
+ """
+
+ dWorldSetQuickStepNumIterations(self.wid, num)
+
+ # getQuickStepNumIterations
+ def getQuickStepNumIterations(self):
+ """getQuickStepNumIterations() -> int
+
+ Get the number of iterations that the QuickStep method
+ performs per step. More iterations will give a more accurate
+ solution, but will take longer to compute. The default is 20
+ iterations.
+ """
+ return dWorldGetQuickStepNumIterations(self.wid)
+
+ # setQuickStepNumIterations
+ def setContactMaxCorrectingVel(self, vel):
+ """setContactMaxCorrectingVel(vel)
+
+ Set the maximum correcting velocity that contacts are allowed
+ to generate. The default value is infinity (i.e. no
+ limit). Reducing this value can help prevent "popping" of
+ deeply embedded objects.
+
+ @param vel: Maximum correcting velocity
+ @type vel: float
+ """
+ dWorldSetContactMaxCorrectingVel(self.wid, vel)
+
+ # getQuickStepNumIterations
+ def getContactMaxCorrectingVel(self):
+ """getContactMaxCorrectingVel() -> float
+
+ Get the maximum correcting velocity that contacts are allowed
+ to generate. The default value is infinity (i.e. no
+ limit). Reducing this value can help prevent "popping" of
+ deeply embedded objects.
+
+ """
+ return dWorldGetContactMaxCorrectingVel(self.wid)
+
+ # setContactSurfaceLayer
+ def setContactSurfaceLayer(self, depth):
+ """setContactSurfaceLayer(depth)
+
+ Set the depth of the surface layer around all geometry
+ objects. Contacts are allowed to sink into the surface layer
+ up to the given depth before coming to rest. The default value
+ is zero. Increasing this to some small value (e.g. 0.001) can
+ help prevent jittering problems due to contacts being
+ repeatedly made and broken.
+
+ @param depth: Surface layer depth
+ @type depth: float
+ """
+ dWorldSetContactSurfaceLayer(self.wid, depth)
+
+ # getContactSurfaceLayer
+ def getContactSurfaceLayer(self):
+ """getContactSurfaceLayer()
+
+ Get the depth of the surface layer around all geometry
+ objects. Contacts are allowed to sink into the surface layer
+ up to the given depth before coming to rest. The default value
+ is zero. Increasing this to some small value (e.g. 0.001) can
+ help prevent jittering problems due to contacts being
+ repeatedly made and broken.
+ """
+ return dWorldGetContactSurfaceLayer(self.wid)
+
+ # setAutoDisableFlag
+ def setAutoDisableFlag(self, flag):
+ """setAutoDisableFlag(flag)
+
+ Set the default auto-disable flag for newly created bodies.
+
+ @param flag: True = Do auto disable
+ @type flag: bool
+ """
+ dWorldSetAutoDisableFlag(self.wid, flag)
+
+ # getAutoDisableFlag
+ def getAutoDisableFlag(self):
+ """getAutoDisableFlag() -> bool
+
+ Get the default auto-disable flag for newly created bodies.
+ """
+ return dWorldGetAutoDisableFlag(self.wid)
+
+ # setAutoDisableLinearThreshold
+ def setAutoDisableLinearThreshold(self, threshold):
+ """setAutoDisableLinearThreshold(threshold)
+
+ Set the default auto-disable linear threshold for newly created
+ bodies.
+
+ @param threshold: Linear threshold
+ @type threshold: float
+ """
+ dWorldSetAutoDisableLinearThreshold(self.wid, threshold)
+
+ # getAutoDisableLinearThreshold
+ def getAutoDisableLinearThreshold(self):
+ """getAutoDisableLinearThreshold() -> float
+
+ Get the default auto-disable linear threshold for newly created
+ bodies.
+ """
+ return dWorldGetAutoDisableLinearThreshold(self.wid)
+
+ # setAutoDisableAngularThreshold
+ def setAutoDisableAngularThreshold(self, threshold):
+ """setAutoDisableAngularThreshold(threshold)
+
+ Set the default auto-disable angular threshold for newly created
+ bodies.
+
+ @param threshold: Angular threshold
+ @type threshold: float
+ """
+ dWorldSetAutoDisableAngularThreshold(self.wid, threshold)
+
+ # getAutoDisableAngularThreshold
+ def getAutoDisableAngularThreshold(self):
+ """getAutoDisableAngularThreshold() -> float
+
+ Get the default auto-disable angular threshold for newly created
+ bodies.
+ """
+ return dWorldGetAutoDisableAngularThreshold(self.wid)
+
+ # setAutoDisableSteps
+ def setAutoDisableSteps(self, steps):
+ """setAutoDisableSteps(steps)
+
+ Set the default auto-disable steps for newly created bodies.
+
+ @param steps: Auto disable steps
+ @type steps: int
+ """
+ dWorldSetAutoDisableSteps(self.wid, steps)
+
+ # getAutoDisableSteps
+ def getAutoDisableSteps(self):
+ """getAutoDisableSteps() -> int
+
+ Get the default auto-disable steps for newly created bodies.
+ """
+ return dWorldGetAutoDisableSteps(self.wid)
+
+ # setAutoDisableTime
+ def setAutoDisableTime(self, time):
+ """setAutoDisableTime(time)
+
+ Set the default auto-disable time for newly created bodies.
+
+ @param time: Auto disable time
+ @type time: float
+ """
+ dWorldSetAutoDisableTime(self.wid, time)
+
+ # getAutoDisableTime
+ def getAutoDisableTime(self):
+ """getAutoDisableTime() -> float
+
+ Get the default auto-disable time for newly created bodies.
+ """
+ return dWorldGetAutoDisableTime(self.wid)
+
+ # setLinearDamping
+ def setLinearDamping(self, scale):
+ """setLinearDamping(scale)
+
+ Set the world's linear damping scale.
+ @param scale The linear damping scale that is to be applied to bodies.
+ Default is 0 (no damping). Should be in the interval [0, 1].
+ @type scale: float
+ """
+ dWorldSetLinearDamping(self.wid, scale)
+
+ # getLinearDamping
+ def getLinearDamping(self):
+ """getLinearDamping() -> float
+
+ Get the world's linear damping scale.
+ """
+ return dWorldGetLinearDamping(self.wid)
+
+ # setAngularDamping
+ def setAngularDamping(self, scale):
+ """setAngularDamping(scale)
+
+ Set the world's angular damping scale.
+ @param scale The angular damping scale that is to be applied to bodies.
+ Default is 0 (no damping). Should be in the interval [0, 1].
+ @type scale: float
+ """
+ dWorldSetAngularDamping(self.wid, scale)
+
+ # getAngularDamping
+ def getAngularDamping(self):
+ """getAngularDamping() -> float
+
+ Get the world's angular damping scale.
+ """
+ return dWorldGetAngularDamping(self.wid)
+
+ # impulseToForce
+ def impulseToForce(self, stepsize, impulse):
+ """impulseToForce(stepsize, impulse) -> 3-tuple
+
+ If you want to apply a linear or angular impulse to a rigid
+ body, instead of a force or a torque, then you can use this
+ function to convert the desired impulse into a force/torque
+ vector before calling the dBodyAdd... function.
+
+ @param stepsize: Time step
+ @param impulse: Impulse vector
+ @type stepsize: float
+ @type impulse: 3-tuple of floats
+ """
+ cdef dVector3 force
+ dWorldImpulseToForce(self.wid, stepsize,
+ impulse[0], impulse[1], impulse[2], force)
+ return force[0], force[1], force[2]
+
+ # createBody
+# def createBody(self):
+# return Body(self)
+
+ # createBallJoint
+# def createBallJoint(self, jointgroup=None):
+# return BallJoint(self, jointgroup)
+
+ # createHingeJoint
+# def createHingeJoint(self, jointgroup=None):
+# return HingeJoint(self, jointgroup)
+
+ # createHinge2Joint
+# def createHinge2Joint(self, jointgroup=None):
+# return Hinge2Joint(self, jointgroup)
+
+ # createSliderJoint
+# def createSliderJoint(self, jointgroup=None):
+# return SliderJoint(self, jointgroup)
+
+ # createFixedJoint
+# def createFixedJoint(self, jointgroup=None):
+# return FixedJoint(self, jointgroup)
+
+ # createContactJoint
+# def createContactJoint(self, jointgroup, contact):
+# return ContactJoint(self, jointgroup, contact)
+
+
+# Body
+cdef class Body:
+ """The rigid body class encapsulating the ODE body.
+
+ This class represents a rigid body that has a location and orientation
+ in space and that stores the mass properties of an object.
+
+ When creating a Body object you have to pass the world it belongs to
+ as argument to the constructor::
+
+ >>> import ode
+ >>> w = ode.World()
+ >>> b = ode.Body(w)
+ """
+
+ cdef dBodyID bid
+ # A reference to the world so that the world won't be destroyed while
+ # there are still joints using it.
+ cdef object world
+
+ # A dictionary with user attributes
+ # (set via __getattr__ and __setattr__)
+ cdef object userattribs
+
+ def __cinit__(self, World world not None):
+ self.bid = dBodyCreate(world.wid)
+
+ def __init__(self, World world not None):
+ """Constructor.
+
+ @param world: The world in which the body should be created.
+ @type world: World
+ """
+ self.world = world
+ self.userattribs = {}
+
+ def __dealloc__(self):
+ if self.bid != NULL:
+ dBodyDestroy(self.bid)
+
+ def __getattr__(self, name):
+ try:
+ return self.userattribs[name]
+ except:
+ raise AttributeError("Body object has no attribute '%s'" % name)
+
+ def __setattr__(self, name, value):
+ self.userattribs[name] = value
+
+ def __delattr__(self, name):
+ try:
+ del self.userattribs[name]
+ except:
+ raise AttributeError("Body object has no attribute '%s'" % name)
+
+ # setPosition
+ def setPosition(self, pos):
+ """setPosition(pos)
+
+ Set the position of the body.
+
+ @param pos: The new position
+ @type pos: 3-sequence of floats
+ """
+ dBodySetPosition(self.bid, pos[0], pos[1], pos[2])
+
+ # getPosition
+ def getPosition(self):
+ """getPosition() -> 3-tuple
+
+ Return the current position of the body.
+ """
+ cdef dReal* p
+ # The "const" in the original return value is cast away
+ p = <dReal*>dBodyGetPosition(self.bid)
+ return p[0], p[1], p[2]
+
+ # setRotation
+ def setRotation(self, R):
+ """setRotation(R)
+
+ Set the orientation of the body. The rotation matrix must be
+ given as a sequence of 9 floats which are the elements of the
+ matrix in row-major order.
+
+ @param R: Rotation matrix
+ @type R: 9-sequence of floats
+ """
+ cdef dMatrix3 m
+ m[0] = R[0]
+ m[1] = R[1]
+ m[2] = R[2]
+ m[3] = 0
+ m[4] = R[3]
+ m[5] = R[4]
+ m[6] = R[5]
+ m[7] = 0
+ m[8] = R[6]
+ m[9] = R[7]
+ m[10] = R[8]
+ m[11] = 0
+ dBodySetRotation(self.bid, m)
+
+ # getRotation
+ def getRotation(self):
+ """getRotation() -> 9-tuple
+
+ Return the current rotation matrix as a tuple of 9 floats (row-major
+ order).
+ """
+ cdef dReal* m
+ # The "const" in the original return value is cast away
+ m = <dReal*>dBodyGetRotation(self.bid)
+ return m[0], m[1], m[2], m[4], m[5], m[6], m[8], m[9], m[10]
+
+ # getQuaternion
+ def getQuaternion(self):
+ """getQuaternion() -> 4-tuple
+
+ Return the current rotation as a quaternion. The return value
+ is a list of 4 floats.
+ """
+ cdef dReal* q
+ q = <dReal*>dBodyGetQuaternion(self.bid)
+ return q[0], q[1], q[2], q[3]
+
+ # setQuaternion
+ def setQuaternion(self, q):
+ """setQuaternion(q)
+
+ Set the orientation of the body. The quaternion must be given as a
+ sequence of 4 floats.
+
+ @param q: Quaternion
+ @type q: 4-sequence of floats
+ """
+ cdef dQuaternion w
+ w[0] = q[0]
+ w[1] = q[1]
+ w[2] = q[2]
+ w[3] = q[3]
+ dBodySetQuaternion(self.bid, w)
+
+ # setLinearVel
+ def setLinearVel(self, vel):
+ """setLinearVel(vel)
+
+ Set the linear velocity of the body.
+
+ @param vel: New velocity
+ @type vel: 3-sequence of floats
+ """
+ dBodySetLinearVel(self.bid, vel[0], vel[1], vel[2])
+
+ # getLinearVel
+ def getLinearVel(self):
+ """getLinearVel() -> 3-tuple
+
+ Get the current linear velocity of the body.
+ """
+ cdef dReal* p
+ # The "const" in the original return value is cast away
+ p = <dReal*>dBodyGetLinearVel(self.bid)
+ return p[0], p[1], p[2]
+
+ # setAngularVel
+ def setAngularVel(self, vel):
+ """setAngularVel(vel)
+
+ Set the angular velocity of the body.
+
+ @param vel: New angular velocity
+ @type vel: 3-sequence of floats
+ """
+ dBodySetAngularVel(self.bid, vel[0], vel[1], vel[2])
+
+ # getAngularVel
+ def getAngularVel(self):
+ """getAngularVel() -> 3-tuple
+
+ Get the current angular velocity of the body.
+ """
+ cdef dReal* p
+ # The "const" in the original return value is cast away
+ p = <dReal*>dBodyGetAngularVel(self.bid)
+ return p[0], p[1], p[2]
+
+ # setMass
+ def setMass(self, Mass mass):
+ """setMass(mass)
+
+ Set the mass properties of the body. The argument mass must be
+ an instance of a Mass object.
+
+ @param mass: Mass properties
+ @type mass: Mass
+ """
+ dBodySetMass(self.bid, &mass._mass)
+
+ # getMass
+ def getMass(self):
+ """getMass() -> mass
+
+ Return the mass properties as a Mass object.
+ """
+ cdef Mass m
+ m = Mass()
+ dBodyGetMass(self.bid, &m._mass)
+ return m
+
+ # addForce
+ def addForce(self, f):
+ """addForce(f)
+
+ Add an external force f given in absolute coordinates. The force
+ is applied at the center of mass.
+
+ @param f: Force
+ @type f: 3-sequence of floats
+ """
+ dBodyAddForce(self.bid, f[0], f[1], f[2])
+
+ # addTorque
+ def addTorque(self, t):
+ """addTorque(t)
+
+ Add an external torque t given in absolute coordinates.
+
+ @param t: Torque
+ @type t: 3-sequence of floats
+ """
+ dBodyAddTorque(self.bid, t[0], t[1], t[2])
+
+ # addRelForce
+ def addRelForce(self, f):
+ """addRelForce(f)
+
+ Add an external force f given in relative coordinates
+ (relative to the body's own frame of reference). The force
+ is applied at the center of mass.
+
+ @param f: Force
+ @type f: 3-sequence of floats
+ """
+ dBodyAddRelForce(self.bid, f[0], f[1], f[2])
+
+ # addRelTorque
+ def addRelTorque(self, t):
+ """addRelTorque(t)
+
+ Add an external torque t given in relative coordinates
+ (relative to the body's own frame of reference).
+
+ @param t: Torque
+ @type t: 3-sequence of floats
+ """
+ dBodyAddRelTorque(self.bid, t[0], t[1], t[2])
+
+ # addForceAtPos
+ def addForceAtPos(self, f, p):
+ """addForceAtPos(f, p)
+
+ Add an external force f at position p. Both arguments must be
+ given in absolute coordinates.
+
+ @param f: Force
+ @param p: Position
+ @type f: 3-sequence of floats
+ @type p: 3-sequence of floats
+ """
+ dBodyAddForceAtPos(self.bid, f[0], f[1], f[2], p[0], p[1], p[2])
+
+ # addForceAtRelPos
+ def addForceAtRelPos(self, f, p):
+ """addForceAtRelPos(f, p)
+
+ Add an external force f at position p. f is given in absolute
+ coordinates and p in absolute coordinates.
+
+ @param f: Force
+ @param p: Position
+ @type f: 3-sequence of floats
+ @type p: 3-sequence of floats
+ """
+ dBodyAddForceAtRelPos(self.bid, f[0], f[1], f[2], p[0], p[1], p[2])
+
+ # addRelForceAtPos
+ def addRelForceAtPos(self, f, p):
+ """addRelForceAtPos(f, p)
+
+ Add an external force f at position p. f is given in relative
+ coordinates and p in relative coordinates.
+
+ @param f: Force
+ @param p: Position
+ @type f: 3-sequence of floats
+ @type p: 3-sequence of floats
+ """
+ dBodyAddRelForceAtPos(self.bid, f[0], f[1], f[2], p[0], p[1], p[2])
+
+ # addRelForceAtRelPos
+ def addRelForceAtRelPos(self, f, p):
+ """addRelForceAtRelPos(f, p)
+
+ Add an external force f at position p. Both arguments must be
+ given in relative coordinates.
+
+ @param f: Force
+ @param p: Position
+ @type f: 3-sequence of floats
+ @type p: 3-sequence of floats
+ """
+ dBodyAddRelForceAtRelPos(self.bid, f[0], f[1], f[2], p[0], p[1], p[2])
+
+ # getForce
+ def getForce(self):
+ """getForce() -> 3-tuple
+
+ Return the current accumulated force.
+ """
+ cdef dReal* f
+ # The "const" in the original return value is cast away
+ f = <dReal*>dBodyGetForce(self.bid)
+ return f[0], f[1], f[2]
+
+ # getTorque
+ def getTorque(self):
+ """getTorque() -> 3-tuple
+
+ Return the current accumulated torque.
+ """
+ cdef dReal* f
+ # The "const" in the original return value is cast away
+ f = <dReal*>dBodyGetTorque(self.bid)
+ return f[0], f[1], f[2]
+
+ # setForce
+ def setForce(self, f):
+ """setForce(f)
+
+ Set the body force accumulation vector.
+
+ @param f: Force
+ @type f: 3-tuple of floats
+ """
+ dBodySetForce(self.bid, f[0], f[1], f[2])
+
+ # setTorque
+ def setTorque(self, t):
+ """setTorque(t)
+
+ Set the body torque accumulation vector.
+
+ @param t: Torque
+ @type t: 3-tuple of floats
+ """
+ dBodySetTorque(self.bid, t[0], t[1], t[2])
+
+ # getRelPointPos
+ def getRelPointPos(self, p):
+ """getRelPointPos(p) -> 3-tuple
+
+ Utility function that takes a point p on a body and returns
+ that point's position in global coordinates. The point p
+ must be given in body relative coordinates.
+
+ @param p: Body point (local coordinates)
+ @type p: 3-sequence of floats
+ """
+
+ cdef dVector3 res
+ dBodyGetRelPointPos(self.bid, p[0], p[1], p[2], res)
+ return res[0], res[1], res[2]
+
+ # getRelPointVel
+ def getRelPointVel(self, p):
+ """getRelPointVel(p) -> 3-tuple
+
+ Utility function that takes a point p on a body and returns
+ that point's velocity in global coordinates. The point p
+ must be given in body relative coordinates.
+
+ @param p: Body point (local coordinates)
+ @type p: 3-sequence of floats
+ """
+ cdef dVector3 res
+ dBodyGetRelPointVel(self.bid, p[0], p[1], p[2], res)
+ return res[0], res[1], res[2]
+
+ # getPointVel
+ def getPointVel(self, p):
+ """getPointVel(p) -> 3-tuple
+
+ Utility function that takes a point p on a body and returns
+ that point's velocity in global coordinates. The point p
+ must be given in global coordinates.
+
+ @param p: Body point (global coordinates)
+ @type p: 3-sequence of floats
+ """
+ cdef dVector3 res
+ dBodyGetPointVel(self.bid, p[0], p[1], p[2], res)
+ return res[0], res[1], res[2]
+
+ # getPosRelPoint
+ def getPosRelPoint(self, p):
+ """getPosRelPoint(p) -> 3-tuple
+
+ This is the inverse of getRelPointPos(). It takes a point p in
+ global coordinates and returns the point's position in
+ body-relative coordinates.
+
+ @param p: Body point (global coordinates)
+ @type p: 3-sequence of floats
+ """
+ cdef dVector3 res
+ dBodyGetPosRelPoint(self.bid, p[0], p[1], p[2], res)
+ return res[0], res[1], res[2]
+
+ # vectorToWorld
+ def vectorToWorld(self, v):
+ """vectorToWorld(v) -> 3-tuple
+
+ Given a vector v expressed in the body coordinate system, rotate
+ it to the world coordinate system.
+
+ @param v: Vector in body coordinate system
+ @type v: 3-sequence of floats
+ """
+ cdef dVector3 res
+ dBodyVectorToWorld(self.bid, v[0], v[1], v[2], res)
+ return res[0], res[1], res[2]
+
+ # vectorFromWorld
+ def vectorFromWorld(self, v):
+ """vectorFromWorld(v) -> 3-tuple
+
+ Given a vector v expressed in the world coordinate system, rotate
+ it to the body coordinate system.
+
+ @param v: Vector in world coordinate system
+ @type v: 3-sequence of floats
+ """
+ cdef dVector3 res
+ dBodyVectorFromWorld(self.bid, v[0], v[1], v[2], res)
+ return res[0], res[1], res[2]
+
+ # Enable
+ def enable(self):
+ """enable()
+
+ Manually enable a body.
+ """
+ dBodyEnable(self.bid)
+
+ # Disable
+ def disable(self):
+ """disable()
+
+ Manually disable a body. Note that a disabled body that is connected
+ through a joint to an enabled body will be automatically re-enabled
+ at the next simulation step.
+ """
+ dBodyDisable(self.bid)
+
+ # isEnabled
+ def isEnabled(self):
+ """isEnabled() -> bool
+
+ Check if a body is currently enabled.
+ """
+ return dBodyIsEnabled(self.bid)
+
+ # setFiniteRotationMode
+ def setFiniteRotationMode(self, mode):
+ """setFiniteRotationMode(mode)
+
+ This function controls the way a body's orientation is updated at
+ each time step. The mode argument can be:
+
+ - 0: An "infinitesimal" orientation update is used. This is
+ fast to compute, but it can occasionally cause inaccuracies
+ for bodies that are rotating at high speed, especially when
+ those bodies are joined to other bodies. This is the default
+ for every new body that is created.
+
+ - 1: A "finite" orientation update is used. This is more
+ costly to compute, but will be more accurate for high speed
+ rotations. Note however that high speed rotations can result
+ in many types of error in a simulation, and this mode will
+ only fix one of those sources of error.
+
+ @param mode: Rotation mode (0/1)
+ @type mode: int
+ """
+ dBodySetFiniteRotationMode(self.bid, mode)
+
+ # getFiniteRotationMode
+ def getFiniteRotationMode(self):
+ """getFiniteRotationMode() -> mode (0/1)
+
+ Return the current finite rotation mode of a body (0 or 1).
+ See setFiniteRotationMode().
+ """
+ return dBodyGetFiniteRotationMode(self.bid)
+
+ # setFiniteRotationAxis
+ def setFiniteRotationAxis(self, a):
+ """setFiniteRotationAxis(a)
+
+ Set the finite rotation axis of the body. This axis only has a
+ meaning when the finite rotation mode is set
+ (see setFiniteRotationMode()).
+
+ @param a: Axis
+ @type a: 3-sequence of floats
+ """
+ dBodySetFiniteRotationAxis(self.bid, a[0], a[1], a[2])
+
+ # getFiniteRotationAxis
+ def getFiniteRotationAxis(self):
+ """getFiniteRotationAxis() -> 3-tuple
+
+ Return the current finite rotation axis of the body.
+ """
+ cdef dVector3 p
+ # The "const" in the original return value is cast away
+ dBodyGetFiniteRotationAxis(self.bid, p)
+ return p[0], p[1], p[2]
+
+ # getNumJoints
+ def getNumJoints(self):
+ """getNumJoints() -> int
+
+ Return the number of joints that are attached to this body.
+ """
+ return dBodyGetNumJoints(self.bid)
+
+ # setGravityMode
+ def setGravityMode(self, mode):
+ """setGravityMode(mode)
+
+ Set whether the body is influenced by the world's gravity
+ or not. If mode is True it is, otherwise it isn't.
+ Newly created bodies are always influenced by the world's gravity.
+
+ @param mode: Gravity mode
+ @type mode: bool
+ """
+ dBodySetGravityMode(self.bid, mode)
+
+ # getGravityMode
+ def getGravityMode(self):
+ """getGravityMode() -> bool
+
+ Return True if the body is influenced by the world's gravity.
+ """
+ return dBodyGetGravityMode(self.bid)
+
+ def setDynamic(self):
+ """setDynamic()
+
+ Set a body to the (default) "dynamic" state, instead of "kinematic".
+ See setKinematic() for more information.
+ """
+ dBodySetDynamic(self.bid)
+
+ def setKinematic(self):
+ """setKinematic()
+
+ Set the kinematic state of the body (change it into a kinematic body)
+
+ Kinematic bodies behave as if they had infinite mass. This means they don't react
+ to any force (gravity, constraints or user-supplied); they simply follow
+ velocity to reach the next position. [from ODE wiki]
+
+ """
+ dBodySetKinematic(self.bid)
+
+ def isKinematic(self):
+ """isKinematic() -> bool
+
+ Return True if the body is kinematic (not influenced by other forces).
+
+ Kinematic bodies behave as if they had infinite mass. This means they don't react
+ to any force (gravity, constraints or user-supplied); they simply follow
+ velocity to reach the next position. [from ODE wiki]
+
+ """
+ return dBodyIsKinematic(self.bid)
+
+ def setMaxAngularSpeed(self, max_speed):
+ """setMaxAngularSpeed(max_speed)
+
+ You can also limit the maximum angular speed. In contrast to the damping
+ functions, the angular velocity is affected before the body is moved.
+ This means that it will introduce errors in joints that are forcing the
+ body to rotate too fast. Some bodies have naturally high angular
+ velocities (like cars' wheels), so you may want to give them a very high
+ (like the default, dInfinity) limit.
+
+ """
+ dBodySetMaxAngularSpeed(self.bid, max_speed)
+
+
+# JointGroup
+cdef class JointGroup:
+ """Joint group.
+
+ Constructor::
+
+ JointGroup()
+ """
+
+ # JointGroup ID
+ cdef dJointGroupID gid
+ # A list of Python joints that were added to the group
+ cdef object jointlist
+
+ def __cinit__(self):
+ self.gid = dJointGroupCreate(0)
+
+ def __init__(self):
+ self.jointlist = []
+
+ def __dealloc__(self):
+ if self.gid != NULL:
+ for j in self.jointlist:
+ j._destroyed()
+ dJointGroupDestroy(self.gid)
+
+ # empty
+ def empty(self):
+ """empty()
+
+ Destroy all joints in the group.
+ """
+ dJointGroupEmpty(self.gid)
+ for j in self.jointlist:
+ j._destroyed()
+ self.jointlist = []
+
+ def _addjoint(self, j):
+ """_addjoint(j)
+
+ Add a joint to the group. This is an internal method that is
+ called by the joints. The group has to know the Python
+ wrappers because it has to notify them when the group is
+ emptied (so that the ODE joints won't get destroyed
+ twice). The notification is done by calling _destroyed() on
+ the Python joints.
+
+ @param j: The joint to add
+ @type j: Joint
+ """
+ self.jointlist.append(j)
+
+
+######################################################################
+
+# Joint
+cdef class Joint:
+ """Base class for all joint classes."""
+
+ # Joint id as returned by dJointCreateXxx()
+ cdef dJointID jid
+ # A reference to the world so that the world won't be destroyed while
+ # there are still joints using it.
+ cdef object world
+ # The feedback buffer
+ cdef dJointFeedback* feedback
+
+ cdef object body1
+ cdef object body2
+
+ # A dictionary with user attributes
+ # (set via __getattr__ and __setattr__)
+ cdef object userattribs
+
+ def __cinit__(self, *a, **kw):
+ self.jid = NULL
+ self.world = None
+ self.feedback = NULL
+ self.body1 = None
+ self.body2 = None
+ self.userattribs = {}
+
+ def __init__(self, *a, **kw):
+ raise NotImplementedError("Joint base class can't be used directly")
+
+ def __dealloc__(self):
+ self.setFeedback(False)
+ if self.jid != NULL:
+ dJointDestroy(self.jid)
+
+ def __getattr__(self, name):
+ try:
+ return self.userattribs[name]
+ except:
+ raise AttributeError("Joint object has no attribute '%s'" % name)
+
+ def __setattr__(self, name, value):
+ self.userattribs[name] = value
+
+ def __delattr__(self, name):
+ try:
+ del self.userattribs[name]
+ except:
+ raise AttributeError("Joint object has no attribute '%s'" % name)
+
+ # _destroyed
+ def _destroyed(self):
+ """Notify the joint object about an external destruction of the ODE joint.
+
+ This method has to be called when the underlying ODE object
+ was destroyed by someone else (e.g. by a joint group). The Python
+ wrapper will then refrain from destroying it again.
+ """
+ self.jid = NULL
+
+ # enable
+ def enable(self):
+ """enable()
+
+ Enable the joint. Disabled joints are completely ignored during the
+ simulation. Disabled joints don't lose the already computed information
+ like anchors and axes.
+ """
+ dJointEnable(self.jid)
+
+ # disable
+ def disable(self):
+ """disable()
+
+ Disable the joint. Disabled joints are completely ignored during the
+ simulation. Disabled joints don't lose the already computed information
+ like anchors and axes.
+ """
+ dJointDisable(self.jid)
+
+ # isEnabled
+ def isEnabled(self):
+ """isEnabled() -> bool
+
+ Determine whether the joint is enabled. Disabled joints are completely
+ ignored during the simulation. Disabled joints don't lose the already
+ computed information like anchors and axes.
+ """
+ return dJointIsEnabled(self.jid)
+
+ # attach
+ def attach(self, Body body1, Body body2):
+ """attach(body1, body2)
+
+ Attach the joint to some new bodies. A body can be attached
+ to the environment by passing None as second body.
+
+ @param body1: First body
+ @param body2: Second body
+ @type body1: Body
+ @type body2: Body
+ """
+ cdef dBodyID id1, id2
+
+ if body1 == None:
+ id1 = NULL
+ else:
+ id1 = body1.bid
+
+ if body2 == None:
+ id2 = NULL
+ else:
+ id2 = body2.bid
+
+ self.body1 = body1
+ self.body2 = body2
+ dJointAttach(self.jid, id1, id2)
+
+ # getBody
+ def getBody(self, index):
+ """getBody(index) -> Body
+
+ Return the bodies that this joint connects. If index is 0 the
+ "first" body will be returned, corresponding to the body1
+ argument of the attach() method. If index is 1 the "second" body
+ will be returned, corresponding to the body2 argument of the
+ attach() method.
+
+ @param index: Bodx index (0 or 1).
+ @type index: int
+ """
+
+ if index == 0:
+ return self.body1
+ elif index == 1:
+ return self.body2
+ else:
+ raise IndexError()
+
+ # setFeedback
+ def setFeedback(self, flag=1):
+ """setFeedback(flag=True)
+
+ Create a feedback buffer. If flag is True then a buffer is
+ allocated and the forces/torques applied by the joint can
+ be read using the getFeedback() method. If flag is False the
+ buffer is released.
+
+ @param flag: Specifies whether a buffer should be created or released
+ @type flag: bool
+ """
+
+ if flag:
+ # Was there already a buffer allocated? then we're finished
+ if self.feedback != NULL:
+ return
+ # Allocate a buffer and pass it to ODE
+ self.feedback = <dJointFeedback*>malloc(sizeof(dJointFeedback))
+ if self.feedback == NULL:
+ raise MemoryError("can't allocate feedback buffer")
+ dJointSetFeedback(self.jid, self.feedback)
+ else:
+ if self.feedback != NULL:
+ # Free a previously allocated buffer
+ dJointSetFeedback(self.jid, NULL)
+ free(self.feedback)
+ self.feedback = NULL
+
+ # getFeedback
+ def getFeedback(self):
+ """getFeedback() -> (force1, torque1, force2, torque2)
+
+ Get the forces/torques applied by the joint. If feedback is
+ activated (i.e. setFeedback(True) was called) then this method
+ returns a tuple (force1, torque1, force2, torque2) with the
+ forces and torques applied to body 1 and body 2. The
+ forces/torques are given as 3-tuples.
+
+ If feedback is deactivated then the method always returns None.
+ """
+ cdef dJointFeedback* fb
+
+ fb = dJointGetFeedback(self.jid)
+ if fb == NULL:
+ return None
+
+ f1 = (fb.f1[0], fb.f1[1], fb.f1[2])
+ t1 = (fb.t1[0], fb.t1[1], fb.t1[2])
+ f2 = (fb.f2[0], fb.f2[1], fb.f2[2])
+ t2 = (fb.t2[0], fb.t2[1], fb.t2[2])
+ return f1, t1, f2, t2
+
+######################################################################
+
+
+# BallJoint
+cdef class BallJoint(Joint):
+ """Ball joint.
+
+ Constructor::
+
+ BallJoint(world, jointgroup=None)
+ """
+
+ def __cinit__(self, World world not None, jointgroup=None):
+ cdef JointGroup jg
+ cdef dJointGroupID jgid
+
+ jgid = NULL
+ if jointgroup != None:
+ jg = jointgroup
+ jgid = jg.gid
+ self.jid = dJointCreateBall(world.wid, jgid)
+
+ def __init__(self, World world not None, jointgroup=None):
+ self.world = world
+ if jointgroup != None:
+ jointgroup._addjoint(self)
+
+ # setAnchor
+ def setAnchor(self, pos):
+ """setAnchor(pos)
+
+ Set the joint anchor point which must be specified in world
+ coordinates.
+
+ @param pos: Anchor position
+ @type pos: 3-sequence of floats
+ """
+ dJointSetBallAnchor(self.jid, pos[0], pos[1], pos[2])
+
+ # getAnchor
+ def getAnchor(self):
+ """getAnchor() -> 3-tuple of floats
+
+ Get the joint anchor point, in world coordinates. This
+ returns the point on body 1. If the joint is perfectly
+ satisfied, this will be the same as the point on body 2.
+ """
+
+ cdef dVector3 p
+ dJointGetBallAnchor(self.jid, p)
+ return p[0], p[1], p[2]
+
+ # getAnchor2
+ def getAnchor2(self):
+ """getAnchor2() -> 3-tuple of floats
+
+ Get the joint anchor point, in world coordinates. This
+ returns the point on body 2. If the joint is perfectly
+ satisfied, this will be the same as the point on body 1.
+ """
+
+ cdef dVector3 p
+ dJointGetBallAnchor2(self.jid, p)
+ return p[0], p[1], p[2]
+
+ # setParam
+ def setParam(self, param, value):
+ pass
+
+ # getParam
+ def getParam(self, param):
+ return 0.0
+
+
+# HingeJoint
+cdef class HingeJoint(Joint):
+ """Hinge joint.
+
+ Constructor::
+
+ HingeJoint(world, jointgroup=None)
+ """
+
+ def __cinit__(self, World world not None, jointgroup=None):
+ cdef JointGroup jg
+ cdef dJointGroupID jgid
+
+ jgid = NULL
+ if jointgroup != None:
+ jg = jointgroup
+ jgid = jg.gid
+ self.jid = dJointCreateHinge(world.wid, jgid)
+
+ def __init__(self, World world not None, jointgroup=None):
+ self.world = world
+ if jointgroup != None:
+ jointgroup._addjoint(self)
+
+ # setAnchor
+ def setAnchor(self, pos):
+ """setAnchor(pos)
+
+ Set the hinge anchor which must be given in world coordinates.
+
+ @param pos: Anchor position
+ @type pos: 3-sequence of floats
+ """
+ dJointSetHingeAnchor(self.jid, pos[0], pos[1], pos[2])
+
+ # getAnchor
+ def getAnchor(self):
+ """getAnchor() -> 3-tuple of floats
+
+ Get the joint anchor point, in world coordinates. This returns
+ the point on body 1. If the joint is perfectly satisfied, this
+ will be the same as the point on body 2.
+ """
+ cdef dVector3 p
+ dJointGetHingeAnchor(self.jid, p)
+ return p[0], p[1], p[2]
+
+ # getAnchor2
+ def getAnchor2(self):
+ """getAnchor2() -> 3-tuple of floats
+
+ Get the joint anchor point, in world coordinates. This returns
+ the point on body 2. If the joint is perfectly satisfied, this
+ will be the same as the point on body 1.
+ """
+ cdef dVector3 p
+ dJointGetHingeAnchor2(self.jid, p)
+ return p[0], p[1], p[2]
+
+ # setAxis
+ def setAxis(self, axis):
+ """setAxis(axis)
+
+ Set the hinge axis.
+
+ @param axis: Hinge axis
+ @type axis: 3-sequence of floats
+ """
+ dJointSetHingeAxis(self.jid, axis[0], axis[1], axis[2])
+
+ # getAxis
+ def getAxis(self):
+ """getAxis() -> 3-tuple of floats
+
+ Get the hinge axis.
+ """
+ cdef dVector3 a
+ dJointGetHingeAxis(self.jid, a)
+ return a[0], a[1], a[2]
+
+ # getAngle
+ def getAngle(self):
+ """getAngle() -> float
+
+ Get the hinge angle. The angle is measured between the two
+ bodies, or between the body and the static environment. The
+ angle will be between -pi..pi.
+
+ When the hinge anchor or axis is set, the current position of
+ the attached bodies is examined and that position will be the
+ zero angle.
+ """
+
+ return dJointGetHingeAngle(self.jid)
+
+ # getAngleRate
+ def getAngleRate(self):
+ """getAngleRate() -> float
+
+ Get the time derivative of the angle.
+ """
+ return dJointGetHingeAngleRate(self.jid)
+
+ # addTorque
+ def addTorque(self, torque):
+ """addTorque(torque)
+
+ Applies the torque about the hinge axis.
+
+ @param torque: Torque magnitude
+ @type torque: float
+ """
+ dJointAddHingeTorque(self.jid, torque)
+
+ # setParam
+ def setParam(self, param, value):
+ """setParam(param, value)
+
+ Set limit/motor parameters for the joint.
+
+ param is one of ParamLoStop, ParamHiStop, ParamVel, ParamFMax,
+ ParamFudgeFactor, ParamBounce, ParamCFM, ParamStopERP, ParamStopCFM,
+ ParamSuspensionERP, ParamSuspensionCFM.
+
+ These parameter names can be optionally followed by a digit (2
+ or 3) to indicate the second or third set of parameters.
+
+ @param param: Selects the parameter to set
+ @param value: Parameter value
+ @type param: int
+ @type value: float
+ """
+
+ dJointSetHingeParam(self.jid, param, value)
+
+ # getParam
+ def getParam(self, param):
+ """getParam(param) -> float
+
+ Get limit/motor parameters for the joint.
+
+ param is one of ParamLoStop, ParamHiStop, ParamVel, ParamFMax,
+ ParamFudgeFactor, ParamBounce, ParamCFM, ParamStopERP, ParamStopCFM,
+ ParamSuspensionERP, ParamSuspensionCFM.
+
+ These parameter names can be optionally followed by a digit (2
+ or 3) to indicate the second or third set of parameters.
+
+ @param param: Selects the parameter to read
+ @type param: int
+ """
+ return dJointGetHingeParam(self.jid, param)
+
+
+# SliderJoint
+cdef class SliderJoint(Joint):
+ """Slider joint.
+
+ Constructor::
+
+ SlideJoint(world, jointgroup=None)
+ """
+
+ def __cinit__(self, World world not None, jointgroup=None):
+ cdef JointGroup jg
+ cdef dJointGroupID jgid
+
+ jgid = NULL
+ if jointgroup != None:
+ jg = jointgroup
+ jgid = jg.gid
+ self.jid = dJointCreateSlider(world.wid, jgid)
+
+ def __init__(self, World world not None, jointgroup=None):
+ self.world = world
+ if jointgroup != None:
+ jointgroup._addjoint(self)
+
+ # setAxis
+ def setAxis(self, axis):
+ """setAxis(axis)
+
+ Set the slider axis parameter.
+
+ @param axis: Slider axis
+ @type axis: 3-sequence of floats
+ """
+ dJointSetSliderAxis(self.jid, axis[0], axis[1], axis[2])
+
+ # getAxis
+ def getAxis(self):
+ """getAxis() -> 3-tuple of floats
+
+ Get the slider axis parameter.
+ """
+ cdef dVector3 a
+ dJointGetSliderAxis(self.jid, a)
+ return a[0], a[1], a[2]
+
+ # getPosition
+ def getPosition(self):
+ """getPosition() -> float
+
+ Get the slider linear position (i.e. the slider's "extension").
+
+ When the axis is set, the current position of the attached
+ bodies is examined and that position will be the zero
+ position.
+ """
+
+ return dJointGetSliderPosition(self.jid)
+
+ # getPositionRate
+ def getPositionRate(self):
+ """getPositionRate() -> float
+
+ Get the time derivative of the position.
+ """
+ return dJointGetSliderPositionRate(self.jid)
+
+ # addForce
+ def addForce(self, force):
+ """addForce(force)
+
+ Applies the given force in the slider's direction.
+
+ @param force: Force magnitude
+ @type force: float
+ """
+ dJointAddSliderForce(self.jid, force)
+
+ # setParam
+ def setParam(self, param, value):
+ dJointSetSliderParam(self.jid, param, value)
+
+ # getParam
+ def getParam(self, param):
+ return dJointGetSliderParam(self.jid, param)
+
+
+# UniversalJoint
+cdef class UniversalJoint(Joint):
+ """Universal joint.
+
+ Constructor::
+
+ UniversalJoint(world, jointgroup=None)
+ """
+
+ def __cinit__(self, World world not None, jointgroup=None):
+ cdef JointGroup jg
+ cdef dJointGroupID jgid
+
+ jgid = NULL
+ if jointgroup != None:
+ jg = jointgroup
+ jgid = jg.gid
+ self.jid = dJointCreateUniversal(world.wid, jgid)
+
+ def __init__(self, World world not None, jointgroup=None):
+ self.world = world
+ if jointgroup != None:
+ jointgroup._addjoint(self)
+
+ # setAnchor
+ def setAnchor(self, pos):
+ """setAnchor(pos)
+
+ Set the universal anchor.
+
+ @param pos: Anchor position
+ @type pos: 3-sequence of floats
+ """
+ dJointSetUniversalAnchor(self.jid, pos[0], pos[1], pos[2])
+
+ # getAnchor
+ def getAnchor(self):
+ """getAnchor() -> 3-tuple of floats
+
+ Get the joint anchor point, in world coordinates. This returns
+ the point on body 1. If the joint is perfectly satisfied, this
+ will be the same as the point on body 2.
+ """
+
+ cdef dVector3 p
+ dJointGetUniversalAnchor(self.jid, p)
+ return p[0], p[1], p[2]
+
+ # getAnchor2
+ def getAnchor2(self):
+ """getAnchor2() -> 3-tuple of floats
+
+ Get the joint anchor point, in world coordinates. This returns
+ the point on body 2. If the joint is perfectly satisfied, this
+ will be the same as the point on body 1.
+ """
+
+ cdef dVector3 p
+ dJointGetUniversalAnchor2(self.jid, p)
+ return p[0], p[1], p[2]
+
+ # setAxis1
+ def setAxis1(self, axis):
+ """setAxis1(axis)
+
+ Set the first universal axis. Axis 1 and axis 2 should be
+ perpendicular to each other.
+
+ @param axis: Joint axis
+ @type axis: 3-sequence of floats
+ """
+ dJointSetUniversalAxis1(self.jid, axis[0], axis[1], axis[2])
+
+ # getAxis1
+ def getAxis1(self):
+ """getAxis1() -> 3-tuple of floats
+
+ Get the first univeral axis.
+ """
+ cdef dVector3 a
+ dJointGetUniversalAxis1(self.jid, a)
+ return a[0], a[1], a[2]
+
+ # setAxis2
+ def setAxis2(self, axis):
+ """setAxis2(axis)
+
+ Set the second universal axis. Axis 1 and axis 2 should be
+ perpendicular to each other.
+
+ @param axis: Joint axis
+ @type axis: 3-sequence of floats
+ """
+ dJointSetUniversalAxis2(self.jid, axis[0], axis[1], axis[2])
+
+ # getAxis2
+ def getAxis2(self):
+ """getAxis2() -> 3-tuple of floats
+
+ Get the second univeral axis.
+ """
+ cdef dVector3 a
+ dJointGetUniversalAxis2(self.jid, a)
+ return a[0], a[1], a[2]
+
+ # addTorques
+ def addTorques(self, torque1, torque2):
+ """addTorques(torque1, torque2)
+
+ Applies torque1 about axis 1, and torque2 about axis 2.
+
+ @param torque1: Torque 1 magnitude
+ @param torque2: Torque 2 magnitude
+ @type torque1: float
+ @type torque2: float
+ """
+ dJointAddUniversalTorques(self.jid, torque1, torque2)
+
+ def getAngle1(self):
+ return dJointGetUniversalAngle1(self.jid)
+
+ def getAngle2(self):
+ return dJointGetUniversalAngle2(self.jid)
+
+ def getAngle1Rate(self):
+ return dJointGetUniversalAngle1Rate(self.jid)
+
+ def getAngle2Rate(self):
+ return dJointGetUniversalAngle2Rate(self.jid)
+
+ # setParam
+ def setParam(self, param, value):
+ dJointSetUniversalParam(self.jid, param, value)
+
+ # getParam
+ def getParam(self, param):
+ return dJointGetUniversalParam(self.jid, param)
+
+
+# Hinge2Joint
+cdef class Hinge2Joint(Joint):
+ """Hinge2 joint.
+
+ Constructor::
+
+ Hinge2Joint(world, jointgroup=None)
+ """
+
+ def __cinit__(self, World world not None, jointgroup=None):
+ cdef JointGroup jg
+ cdef dJointGroupID jgid
+
+ jgid = NULL
+ if jointgroup != None:
+ jg = jointgroup
+ jgid = jg.gid
+ self.jid = dJointCreateHinge2(world.wid, jgid)
+
+ def __init__(self, World world, jointgroup=None):
+ self.world = world
+ if jointgroup != None:
+ jointgroup._addjoint(self)
+
+ # setAnchor
+ def setAnchor(self, pos):
+ """setAnchor(pos)
+
+ Set the hinge-2 anchor.
+
+ @param pos: Anchor position
+ @type pos: 3-sequence of floats
+ """
+ dJointSetHinge2Anchor(self.jid, pos[0], pos[1], pos[2])
+
+ # getAnchor
+ def getAnchor(self):
+ """getAnchor() -> 3-tuple of floats
+
+ Get the joint anchor point, in world coordinates. This returns
+ the point on body 1. If the joint is perfectly satisfied, this
+ will be the same as the point on body 2.
+ """
+
+ cdef dVector3 p
+ dJointGetHinge2Anchor(self.jid, p)
+ return p[0], p[1], p[2]
+
+ # getAnchor2
+ def getAnchor2(self):
+ """getAnchor2() -> 3-tuple of floats
+
+ Get the joint anchor point, in world coordinates. This returns
+ the point on body 2. If the joint is perfectly satisfied, this
+ will be the same as the point on body 1.
+ """
+
+ cdef dVector3 p
+ dJointGetHinge2Anchor2(self.jid, p)
+ return p[0], p[1], p[2]
+
+ # setAxis1
+ def setAxis1(self, axis):
+ """setAxis1(axis)
+
+ Set the first hinge-2 axis. Axis 1 and axis 2 must not lie
+ along the same line.
+
+ @param axis: Joint axis
+ @type axis: 3-sequence of floats
+ """
+
+ dJointSetHinge2Axis1(self.jid, axis[0], axis[1], axis[2])
+
+ # getAxis1
+ def getAxis1(self):
+ """getAxis1() -> 3-tuple of floats
+
+ Get the first hinge-2 axis.
+ """
+ cdef dVector3 a
+ dJointGetHinge2Axis1(self.jid, a)
+ return a[0], a[1], a[2]
+
+ # setAxis2
+ def setAxis2(self, axis):
+ """setAxis2(axis)
+
+ Set the second hinge-2 axis. Axis 1 and axis 2 must not lie
+ along the same line.
+
+ @param axis: Joint axis
+ @type axis: 3-sequence of floats
+ """
+ dJointSetHinge2Axis2(self.jid, axis[0], axis[1], axis[2])
+
+ # getAxis2
+ def getAxis2(self):
+ """getAxis2() -> 3-tuple of floats
+
+ Get the second hinge-2 axis.
+ """
+ cdef dVector3 a
+ dJointGetHinge2Axis2(self.jid, a)
+ return a[0], a[1], a[2]
+
+ # getAngle
+ def getAngle1(self):
+ """getAngle1() -> float
+
+ Get the first hinge-2 angle (around axis 1).
+
+ When the anchor or axis is set, the current position of the
+ attached bodies is examined and that position will be the zero
+ angle.
+ """
+ return dJointGetHinge2Angle1(self.jid)
+
+ # getAngle1Rate
+ def getAngle1Rate(self):
+ """getAngle1Rate() -> float
+
+ Get the time derivative of the first hinge-2 angle.
+ """
+ return dJointGetHinge2Angle1Rate(self.jid)
+
+ # getAngle2Rate
+ def getAngle2Rate(self):
+ """getAngle2Rate() -> float
+
+ Get the time derivative of the second hinge-2 angle.
+ """
+ return dJointGetHinge2Angle2Rate(self.jid)
+
+ # addTorques
+ def addTorques(self, torque1, torque2):
+ """addTorques(torque1, torque2)
+
+ Applies torque1 about axis 1, and torque2 about axis 2.
+
+ @param torque1: Torque 1 magnitude
+ @param torque2: Torque 2 magnitude
+ @type torque1: float
+ @type torque2: float
+ """
+ dJointAddHinge2Torques(self.jid, torque1, torque2)
+
+ # setParam
+ def setParam(self, param, value):
+ dJointSetHinge2Param(self.jid, param, value)
+
+ # getParam
+ def getParam(self, param):
+ return dJointGetHinge2Param(self.jid, param)
+
+
+# FixedJoint
+cdef class FixedJoint(Joint):
+ """Fixed joint.
+
+ Constructor::
+
+ FixedJoint(world, jointgroup=None)
+ """
+
+ def __cinit__(self, World world not None, jointgroup=None):
+ cdef JointGroup jg
+ cdef dJointGroupID jgid
+
+ jgid = NULL
+ if jointgroup != None:
+ jg = jointgroup
+ jgid = jg.gid
+ self.jid = dJointCreateFixed(world.wid, jgid)
+
+ def __init__(self, World world not None, jointgroup=None):
+ self.world = world
+ if jointgroup != None:
+ jointgroup._addjoint(self)
+
+ # setFixed
+ def setFixed(self):
+ """setFixed()
+
+ Call this on the fixed joint after it has been attached to
+ remember the current desired relative offset and desired
+ relative rotation between the bodies.
+ """
+ dJointSetFixed(self.jid)
+
+
+# ContactJoint
+cdef class ContactJoint(Joint):
+ """Contact joint.
+
+ Constructor::
+
+ ContactJoint(world, jointgroup, contact)
+ """
+
+ def __cinit__(self, World world not None, jointgroup, Contact contact):
+ cdef JointGroup jg
+ cdef dJointGroupID jgid
+ jgid = NULL
+ if jointgroup != None:
+ jg = jointgroup
+ jgid = jg.gid
+ self.jid = dJointCreateContact(world.wid, jgid, &contact._contact)
+
+ def __init__(self, World world not None, jointgroup, Contact contact):
+ self.world = world
+ if jointgroup != None:
+ jointgroup._addjoint(self)
+
+# AMotor
+cdef class AMotor(Joint):
+ """AMotor joint.
+
+ Constructor::
+
+ AMotor(world, jointgroup=None)
+ """
+
+ def __cinit__(self, World world not None, jointgroup=None):
+ cdef JointGroup jg
+ cdef dJointGroupID jgid
+
+ jgid = NULL
+ if jointgroup != None:
+ jg = jointgroup
+ jgid = jg.gid
+ self.jid = dJointCreateAMotor(world.wid, jgid)
+
+ def __init__(self, World world not None, jointgroup=None):
+ self.world = world
+ if jointgroup != None:
+ jointgroup._addjoint(self)
+
+ # setMode
+ def setMode(self, mode):
+ """setMode(mode)
+
+ Set the angular motor mode. mode must be either AMotorUser or
+ AMotorEuler.
+
+ @param mode: Angular motor mode
+ @type mode: int
+ """
+ dJointSetAMotorMode(self.jid, mode)
+
+ # getMode
+ def getMode(self):
+ """getMode()
+
+ Return the angular motor mode (AMotorUser or AMotorEuler).
+ """
+ return dJointGetAMotorMode(self.jid)
+
+ # setNumAxes
+ def setNumAxes(self, int num):
+ """setNumAxes(num)
+
+ Set the number of angular axes that will be controlled by the AMotor.
+ num may be in the range from 0 to 3.
+
+ @param num: Number of axes (0-3)
+ @type num: int
+ """
+ dJointSetAMotorNumAxes(self.jid, num)
+
+ # getNumAxes
+ def getNumAxes(self):
+ """getNumAxes() -> int
+
+ Get the number of angular axes that are controlled by the AMotor.
+ """
+ return dJointGetAMotorNumAxes(self.jid)
+
+ # setAxis
+ def setAxis(self, int anum, int rel, axis):
+ """setAxis(anum, rel, axis)
+
+ Set an AMotor axis.
+
+ The anum argument selects the axis to change (0,1 or 2).
+ Each axis can have one of three "relative orientation" modes,
+ selected by rel:
+
+ 0: The axis is anchored to the global frame.
+ 1: The axis is anchored to the first body.
+ 2: The axis is anchored to the second body.
+
+ The axis vector is always specified in global coordinates
+ regardless of the setting of rel.
+
+ @param anum: Axis number
+ @param rel: Relative orientation mode
+ @param axis: Axis
+ @type anum: int
+ @type rel: int
+ @type axis: 3-sequence of floats
+ """
+ dJointSetAMotorAxis(self.jid, anum, rel, axis[0], axis[1], axis[2])
+
+ # getAxis
+ def getAxis(self, int anum):
+ """getAxis(anum)
+
+ Get an AMotor axis.
+
+ @param anum: Axis index (0-2)
+ @type anum: int
+ """
+ cdef dVector3 a
+ dJointGetAMotorAxis(self.jid, anum, a)
+ return a[0], a[1], a[2]
+
+ # getAxisRel
+ def getAxisRel(self, int anum):
+ """getAxisRel(anum) -> int
+
+ Get the relative mode of an axis.
+
+ @param anum: Axis index (0-2)
+ @type anum: int
+ """
+ return dJointGetAMotorAxisRel(self.jid, anum)
+
+ # setAngle
+ def setAngle(self, int anum, angle):
+ """setAngle(anum, angle)
+
+ Tell the AMotor what the current angle is along axis anum.
+
+ @param anum: Axis index
+ @param angle: Angle
+ @type anum: int
+ @type angle: float
+ """
+ dJointSetAMotorAngle(self.jid, anum, angle)
+
+ # getAngle
+ def getAngle(self, int anum):
+ """getAngle(anum) -> float
+
+ Return the current angle for axis anum.
+
+ @param anum: Axis index
+ @type anum: int
+ """
+ return dJointGetAMotorAngle(self.jid, anum)
+
+ # getAngleRate
+ def getAngleRate(self, int anum):
+ """getAngleRate(anum) -> float
+
+ Return the current angle rate for axis anum.
+
+ @param anum: Axis index
+ @type anum: int
+ """
+ return dJointGetAMotorAngleRate(self.jid, anum)
+
+ # addTorques
+ def addTorques(self, torque0, torque1, torque2):
+ """addTorques(torque0, torque1, torque2)
+
+ Applies torques about the AMotor's axes.
+
+ @param torque0: Torque 0 magnitude
+ @param torque1: Torque 1 magnitude
+ @param torque2: Torque 2 magnitude
+ @type torque0: float
+ @type torque1: float
+ @type torque2: float
+ """
+ dJointAddAMotorTorques(self.jid, torque0, torque1, torque2)
+
+ # setParam
+ def setParam(self, param, value):
+ dJointSetAMotorParam(self.jid, param, value)
+
+ # getParam
+ def getParam(self, param):
+ return dJointGetAMotorParam(self.jid, param)
+
+
+# LMotor
+cdef class LMotor(Joint):
+ """LMotor joint.
+
+ Constructor::
+
+ LMotor(world, jointgroup=None)
+ """
+
+ def __cinit__(self, World world not None, jointgroup=None):
+ cdef JointGroup jg
+ cdef dJointGroupID jgid
+
+ jgid = NULL
+ if jointgroup != None:
+ jg = jointgroup
+ jgid = jg.gid
+ self.jid = dJointCreateLMotor(world.wid, jgid)
+
+ def __init__(self, World world not None, jointgroup=None):
+ self.world = world
+ if jointgroup != None:
+ jointgroup._addjoint(self)
+
+ # setNumAxes
+ def setNumAxes(self, int num):
+ """setNumAxes(num)
+
+ Set the number of angular axes that will be controlled by the LMotor.
+ num may be in the range from 0 to 3.
+
+ @param num: Number of axes (0-3)
+ @type num: int
+ """
+ dJointSetLMotorNumAxes(self.jid, num)
+
+ # getNumAxes
+ def getNumAxes(self):
+ """getNumAxes() -> int
+
+ Get the number of angular axes that are controlled by the LMotor.
+ """
+ return dJointGetLMotorNumAxes(self.jid)
+
+ # setAxis
+ def setAxis(self, int anum, int rel, axis):
+ """setAxis(anum, rel, axis)
+
+ Set an LMotor axis.
+
+ The anum argument selects the axis to change (0,1 or 2).
+ Each axis can have one of three "relative orientation" modes,
+ selected by rel:
+
+ 0: The axis is anchored to the global frame.
+ 1: The axis is anchored to the first body.
+ 2: The axis is anchored to the second body.
+
+ @param anum: Axis number
+ @param rel: Relative orientation mode
+ @param axis: Axis
+ @type anum: int
+ @type rel: int
+ @type axis: 3-sequence of floats
+ """
+ dJointSetLMotorAxis(self.jid, anum, rel, axis[0], axis[1], axis[2])
+
+ # getAxis
+ def getAxis(self, int anum):
+ """getAxis(anum)
+
+ Get an LMotor axis.
+
+ @param anum: Axis index (0-2)
+ @type anum: int
+ """
+ cdef dVector3 a
+ dJointGetLMotorAxis(self.jid, anum, a)
+ return a[0], a[1], a[2]
+
+ # setParam
+ def setParam(self, param, value):
+ dJointSetLMotorParam(self.jid, param, value)
+
+ # getParam
+ def getParam(self, param):
+ return dJointGetLMotorParam(self.jid, param)
+
+
+# Plane2DJoint
+cdef class Plane2DJoint(Joint):
+ """Plane-2D Joint.
+
+ Constructor::
+
+ Plane2DJoint(world, jointgroup=None)
+ """
+
+ def __cinit__(self, World world not None, jointgroup=None):
+ cdef JointGroup jg
+ cdef dJointGroupID jgid
+
+ jgid = NULL
+ if jointgroup != None:
+ jg = jointgroup
+ jgid = jg.gid
+ self.jid = dJointCreatePlane2D(world.wid, jgid)
+
+ def __init__(self, World world not None, jointgroup=None):
+ self.world = world
+ if jointgroup != None:
+ jointgroup._addjoint(self)
+
+ def setXParam(self, param, value):
+ dJointSetPlane2DXParam(self.jid, param, value)
+
+ def setYParam(self, param, value):
+ dJointSetPlane2DYParam(self.jid, param, value)
+
+ def setAngleParam(self, param, value):
+ dJointSetPlane2DAngleParam(self.jid, param, value)
+
+
+# PRJoint
+cdef class PRJoint(Joint):
+ """Prismatic and Rotoide Joint.
+
+ Constructor::
+
+ PRJoint(world, jointgroup=None)
+ """
+
+ def __cinit__(self, World world not None, jointgroup=None):
+ cdef JointGroup jg
+ cdef dJointGroupID jgid
+
+ jgid = NULL
+ if jointgroup != None:
+ jg = jointgroup
+ jgid = jg.gid
+ self.jid = dJointCreatePR(world.wid, jgid)
+
+ def __init__(self, World world not None, jointgroup=None):
+ self.world = world
+ if jointgroup != None:
+ jointgroup._addjoint(self)
+
+ def getPosition(self):
+ """getPosition()
+
+ Get a PRJoint's linear extension. (i.e. the prismatic's extension)
+ """
+ return dJointGetPRPosition(self.jid)
+
+ def setAnchor(self, pos):
+ """setAnchor(pos)
+
+ Set a PRJoint anchor.
+
+ @param pos: Anchor position
+ @type pos: 3-sequence of floats
+ """
+ dJointSetPRAnchor(self.jid, pos[0], pos[1], pos[2])
+
+ def getAnchor(self):
+ """getAnchor()
+
+ Get a PRJoint anchor.
+ """
+ cdef dVector3 a
+ dJointGetPRAnchor(self.jid, a)
+ return a[0], a[1], a[2]
+
+ def setAxis1(self, axis):
+ """setAxis1(axis)
+
+ Set a PRJoint's prismatic axis.
+
+ @param axis: Axis
+ @type axis: 3-sequence of floats
+ """
+ dJointSetPRAxis1(self.jid, axis[0], axis[1], axis[2])
+
+ def getAxis1(self):
+ """getAxis1()
+
+ Get a PRJoint's prismatic axis.
+ """
+ cdef dVector3 a
+ dJointGetPRAxis1(self.jid, a)
+ return a[0], a[1], a[2]
+
+ def setAxis2(self, axis):
+ """setAxis2(axis)
+
+ Set a PRJoint's rotoide axis.
+
+ @param axis: Axis
+ @type axis: 3-sequence of floats
+ """
+ dJointSetPRAxis2(self.jid, axis[0], axis[1], axis[2])
+
+ def getAxis2(self):
+ """getAxis2()
+
+ Get a PRJoint's rotoide axis.
+ """
+ cdef dVector3 a
+ dJointGetPRAxis2(self.jid, a)
+ return a[0], a[1], a[2]
+
+
+# Geom base class
+cdef class GeomObject:
+ """This is the abstract base class for all geom objects.
+ """
+
+ # The id of the geom object as returned by dCreateXxxx()
+ cdef dGeomID gid
+ # The space in which the geom was placed (or None). This reference
+ # is kept so that the space won't be destroyed while there are still
+ # geoms around that might use it.
+ cdef object space
+ # The body that the geom was attached to (or None).
+ cdef object body
+
+ # A dictionary with user defined attributes
+ cdef object attribs
+
+ cdef object __weakref__
+
+ def __cinit__(self, *a, **kw):
+ self.gid = NULL
+ self.space = None
+ self.body = None
+ self.attribs = {}
+
+ def __init__(self, *a, **kw):
+ raise NotImplementedError(
+ "GeomObject base class can't be used directly")
+
+ def __dealloc__(self):
+ if self.gid != NULL:
+ dGeomDestroy(self.gid)
+ self.gid = NULL
+
+ def __getattr__(self, name):
+ if name in self.attribs:
+ return self.attribs[name]
+ else:
+ raise AttributeError("geom has no attribute '%s'" % name)
+
+ def __setattr__(self, name, val):
+ self.attribs[name] = val
+
+ def __delattr__(self, name):
+ if name in self.attribs:
+ del self.attribs[name]
+ else:
+ raise AttributeError("geom has no attribute '%s'" % name)
+
+ def _id(self):
+ """_id() -> int
+
+ Return the internal id of the geom (dGeomID) as returned by
+ the dCreateXyz() functions.
+
+ This method has to be overwritten in derived methods.
+ """
+ raise NotImplementedError("Bug: The _id() method is not implemented")
+
+ def placeable(self):
+ """placeable() -> bool
+
+ Returns True if the geom object is a placeable geom.
+
+ This method has to be overwritten in derived methods.
+ """
+ return False
+
+ def setBody(self, Body body):
+ """setBody(body)
+
+ Set the body associated with a placeable geom.
+
+ @param body: The Body object or None.
+ @type body: Body
+ """
+
+ if not self.placeable():
+ raise ValueError(
+ "Non-placeable geoms cannot have a body associated to them")
+
+ if body == None:
+ dGeomSetBody(self.gid, NULL)
+ else:
+ dGeomSetBody(self.gid, body.bid)
+ self.body = body
+
+ def getBody(self):
+ """getBody() -> Body
+
+ Get the body associated with this geom.
+ """
+ if not self.placeable():
+ return environment
+
+ return self.body
+
+ def setPosition(self, pos):
+ """setPosition(pos)
+
+ Set the position of the geom. If the geom is attached to a body,
+ the body's position will also be changed.
+
+ @param pos: Position
+ @type pos: 3-sequence of floats
+ """
+ if not self.placeable():
+ raise ValueError("Cannot set a position on non-placeable geoms")
+ dGeomSetPosition(self.gid, pos[0], pos[1], pos[2])
+
+ def getPosition(self):
+ """getPosition() -> 3-tuple
+
+ Get the current position of the geom. If the geom is attached to
+ a body the returned value is the body's position.
+ """
+ if not self.placeable():
+ raise ValueError("Non-placeable geoms do not have a position")
+
+ cdef dReal* p
+ p = <dReal*>dGeomGetPosition(self.gid)
+ return p[0], p[1], p[2]
+
+ def setRotation(self, R):
+ """setRotation(R)
+
+ Set the orientation of the geom. If the geom is attached to a body,
+ the body's orientation will also be changed.
+
+ @param R: Rotation matrix
+ @type R: 9-sequence of floats
+ """
+ if not self.placeable():
+ raise ValueError("Cannot set a rotation on non-placeable geoms")
+
+ cdef dMatrix3 m
+ m[0] = R[0]
+ m[1] = R[1]
+ m[2] = R[2]
+ m[3] = 0
+ m[4] = R[3]
+ m[5] = R[4]
+ m[6] = R[5]
+ m[7] = 0
+ m[8] = R[6]
+ m[9] = R[7]
+ m[10] = R[8]
+ m[11] = 0
+ dGeomSetRotation(self.gid, m)
+
+ def getRotation(self):
+ """getRotation() -> 9-tuple
+
+ Get the current orientation of the geom. If the geom is attached to
+ a body the returned value is the body's orientation.
+ """
+ if not self.placeable():
+ raise ValueError("Non-placeable geoms do not have a rotation")
+
+ cdef dReal* m
+ m = <dReal*>dGeomGetRotation(self.gid)
+ return [m[0], m[1], m[2], m[4], m[5], m[6], m[8], m[9], m[10]]
+
+ def getQuaternion(self):
+ """getQuaternion() -> (w,x,y,z)
+
+ Get the current orientation of the geom. If the geom is attached to
+ a body the returned value is the body's orientation.
+ """
+ if not self.placeable():
+ raise ValueError("Non-placeable geoms do not have an orientation")
+
+ cdef dQuaternion q
+ dGeomGetQuaternion(self.gid, q)
+ return q[0], q[1], q[2], q[3]
+
+ def setQuaternion(self, q):
+ """setQuaternion(q)
+
+ Set the orientation of the geom. If the geom is attached to a body,
+ the body's orientation will also be changed.
+
+ @param q: Quaternion (w,x,y,z)
+ @type q: 4-sequence of floats
+ """
+ if not self.placeable():
+ raise ValueError("Cannot set a quaternion on non-placeable geoms")
+
+ cdef dQuaternion cq
+ cq[0] = q[0]
+ cq[1] = q[1]
+ cq[2] = q[2]
+ cq[3] = q[3]
+ dGeomSetQuaternion(self.gid, cq)
+
+ def setOffsetPosition(self, pos):
+ """setOffsetPosition(pos)
+
+ Set the offset position of the geom. The geom must be attached to a
+ body. If the geom did not have an offset, it is automatically created.
+ This sets up an additional (local) transformation for the geom, since
+ geoms attached to a body share their global position and rotation.
+
+ @param pos: Position
+ @type pos: 3-sequence of floats
+ """
+ if self.body == None:
+ raise ValueError("Cannot set an offset position on a geom before "
+ "calling setBody")
+ dGeomSetOffsetPosition(self.gid, pos[0], pos[1], pos[2])
+
+ def getOffsetPosition(self):
+ """getOffsetPosition() -> 3-tuple
+
+ Get the offset position of the geom.
+ """
+ cdef dReal* p
+ p = <dReal*>dGeomGetOffsetPosition(self.gid)
+ return (p[0],p[1],p[2])
+
+ def setOffsetRotation(self, R):
+ """setOffsetRotation(R)
+
+ Set the offset rotation of the geom. The geom must be attached to a
+ body. If the geom did not have an offset, it is automatically created.
+ This sets up an additional (local) transformation for the geom, since
+ geoms attached to a body share their global position and rotation.
+
+ @param R: Rotation matrix
+ @type R: 9-sequence of floats
+ """
+ if self.body == None:
+ raise ValueError("Cannot set an offset rotation on a geom before "
+ "calling setBody")
+
+ cdef dMatrix3 m
+ m[0] = R[0]
+ m[1] = R[1]
+ m[2] = R[2]
+ m[3] = 0
+ m[4] = R[3]
+ m[5] = R[4]
+ m[6] = R[5]
+ m[7] = 0
+ m[8] = R[6]
+ m[9] = R[7]
+ m[10] = R[8]
+ m[11] = 0
+ dGeomSetOffsetRotation(self.gid, m)
+
+ def getOffsetRotation(self):
+ """getOffsetRotation() -> 9-tuple
+
+ Get the offset rotation of the geom.
+ """
+ cdef dReal* m
+ m = <dReal*>dGeomGetOffsetRotation(self.gid)
+ return [m[0], m[1], m[2], m[4], m[5], m[6], m[8], m[9], m[10]]
+
+ def clearOffset(self):
+ """clearOffset()
+
+ Disable the offset transform of the geom.
+ """
+ dGeomClearOffset(self.gid)
+
+ def getAABB(self):
+ """getAABB() -> 6-tuple
+
+ Return an axis aligned bounding box that surrounds the geom.
+ The return value is a 6-tuple (minx, maxx, miny, maxy, minz, maxz).
+ """
+ cdef dReal aabb[6]
+
+ dGeomGetAABB(self.gid, aabb)
+ return aabb[0], aabb[1], aabb[2], aabb[3], aabb[4], aabb[5]
+
+ def isSpace(self):
+ """isSpace() -> bool
+
+ Return 1 if the given geom is a space, or 0 if not."""
+ return dGeomIsSpace(self.gid)
+
+ def getSpace(self):
+ """getSpace() -> Space
+
+ Return the space that the given geometry is contained in,
+ or return None if it is not contained in any space."""
+ return self.space
+
+ def setCollideBits(self, bits):
+ """setCollideBits(bits)
+
+ Set the "collide" bitfields for this geom.
+
+ @param bits: Collide bit field
+ @type bits: int/long
+ """
+ dGeomSetCollideBits(self.gid, long(bits))
+
+ def setCategoryBits(self, bits):
+ """setCategoryBits(bits)
+
+ Set the "category" bitfields for this geom.
+
+ @param bits: Category bit field
+ @type bits: int/long
+ """
+ dGeomSetCategoryBits(self.gid, long(bits))
+
+ def getCollideBits(self):
+ """getCollideBits() -> long
+
+ Return the "collide" bitfields for this geom.
+ """
+ return dGeomGetCollideBits(self.gid)
+
+ def getCategoryBits(self):
+ """getCategoryBits() -> long
+
+ Return the "category" bitfields for this geom.
+ """
+ return dGeomGetCategoryBits(self.gid)
+
+ def enable(self):
+ """enable()
+
+ Enable the geom."""
+ dGeomEnable(self.gid)
+
+ def disable(self):
+ """disable()
+
+ Disable the geom."""
+ dGeomDisable(self.gid)
+
+ def isEnabled(self):
+ """isEnabled() -> bool
+
+ Return True if the geom is enabled."""
+ return dGeomIsEnabled(self.gid)
+
+
+# _SpaceIterator
+class _SpaceIterator:
+ """Iterates over the geoms inside a Space.
+ """
+
+ def __init__(self, space):
+ self.space = space
+ self.idx = 0
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ if self.idx >= self.space.getNumGeoms():
+ raise StopIteration
+ else:
+ res = self.space.getGeom(self.idx)
+ self.idx = self.idx + 1
+ return res
+
+
+# SpaceBase
+cdef class SpaceBase(GeomObject):
+ """Space class (container for geometry objects).
+
+ A Space object is a container for geometry objects which are used
+ to do collision detection.
+ The space does high level collision culling, which means that it
+ can identify which pairs of geometry objects are potentially
+ touching.
+
+ This Space class can be used for both, a SimpleSpace and a HashSpace
+ (see ODE documentation).
+
+ >>> space = Space(type=0) # Create a SimpleSpace
+ >>> space = Space(type=1) # Create a HashSpace
+ """
+
+ # The id of the space. Actually this is a copy of the value in self.gid
+ # (as the Space is derived from GeomObject) which can be used without
+ # casting whenever a *space* id is required.
+ cdef dSpaceID sid
+
+ # Dictionary with Geomobjects. Key is the ID (geom._id()) and the value
+ # is the geom object (Python wrapper). This is used in collide_callback()
+# cdef object geom_dict
+
+ def __cinit__(self, *a, **kw):
+ pass
+
+ def __init__(self, *a, **kw):
+ raise NotImplementedError("The SpaceBase class can't be used directly")
+
+ def __dealloc__(self):
+ if self.gid != NULL:
+ dSpaceDestroy(self.sid)
+ self.sid = NULL
+ self.gid = NULL
+
+# def _addgeom(self, geom):
+# """Insert the geom object into the dictionary (internal method).
+#
+# This method has to called in the constructor of a geom object.
+# """
+# self.geom_dict[geom._id()]=geom
+
+# def _id2geom(self, id):
+# """Get the Python wrapper that corresponds to an ID.
+#
+# The ID is the integer value, as returned by geom._id().
+# If the ID is unknown then None is returned.
+# """
+# if id in self.geom_dict:
+# return self.geom_dict[id]
+# else:
+# return None
+
+ def _id(self):
+ cdef size_t id
+ id = <size_t>self.sid
+ return id
+
+ def __len__(self):
+ return self.getNumGeoms()
+
+ def __iter__(self):
+ return _SpaceIterator(self)
+
+ def add(self, GeomObject geom):
+ """add(geom)
+
+ Add a geom to a space. This does nothing if the geom is
+ already in the space.
+
+ @param geom: Geom object to add
+ @type geom: GeomObject
+ """
+
+ dSpaceAdd(self.sid, geom.gid)
+
+ def remove(self, GeomObject geom):
+ """remove(geom)
+
+ Remove a geom from a space.
+
+ @param geom: Geom object to remove
+ @type geom: GeomObject
+ """
+ dSpaceRemove(self.sid, geom.gid)
+
+ def query(self, GeomObject geom):
+ """query(geom) -> bool
+
+ Return True if the given geom is in the space.
+
+ @param geom: Geom object to check
+ @type geom: GeomObject
+ """
+ return dSpaceQuery(self.sid, geom.gid)
+
+ def getNumGeoms(self):
+ """getNumGeoms() -> int
+
+ Return the number of geoms contained within the space.
+ """
+ return dSpaceGetNumGeoms(self.sid)
+
+ def getGeom(self, int idx):
+ """getGeom(idx) -> GeomObject
+
+ Return the geom with the given index contained within the space.
+
+ @param idx: Geom index (0,1,...,getNumGeoms()-1)
+ @type idx: int
+ """
+ cdef dGeomID gid
+
+ # Check the index
+ if idx < 0 or idx >= dSpaceGetNumGeoms(self.sid):
+ raise IndexError("geom index out of range")
+
+ gid = dSpaceGetGeom(self.sid, idx)
+ if <size_t>gid not in _geom_c2py_lut:
+ raise RuntimeError(
+ "geom id cannot be translated to a Python object")
+
+ return _geom_c2py_lut[<size_t>gid]
+
+ def collide(self, arg, callback):
+ """collide(arg, callback)
+
+ Call a callback function one or more times, for all
+ potentially intersecting objects in the space. The callback
+ function takes 3 arguments:
+
+ def NearCallback(arg, geom1, geom2):
+
+ The arg parameter is just passed on to the callback function.
+ Its meaning is user defined. The geom1 and geom2 arguments are
+ the geometry objects that may be near each other. The callback
+ function can call the function collide() (not the Space
+ method) on geom1 and geom2, perhaps first determining
+ whether to collide them at all based on other information.
+
+ @param arg: A user argument that is passed to the callback function
+ @param callback: Callback function
+ @type callback: callable
+ """
+
+ cdef void* data
+ cdef object tup
+ tup = (callback, arg)
+ data = <void*>tup
+ dSpaceCollide(self.sid, data, collide_callback)
+
+
+# Callback function for the dSpaceCollide() call in the Space.collide() method
+# The data parameter is a tuple (Python-Callback, Arguments).
+# The function calls a Python callback function with 3 arguments:
+# def callback(UserArg, Geom1, Geom2)
+# Geom1 and Geom2 are instances of GeomXyz classes.
+cdef void collide_callback(void* data, dGeomID o1, dGeomID o2):
+ cdef object tup
+# cdef Space space
+ cdef size_t id1, id2
+
+# if (dGeomGetBody(o1)==dGeomGetBody(o2)):
+# return
+
+ tup = <object>data
+ callback, arg = tup
+ id1 = <size_t>o1
+ id2 = <size_t>o2
+ g1 = _geom_c2py_lut[id1]
+ g2 = _geom_c2py_lut[id2]
+ callback(arg, g1, g2)
+
+
+# SimpleSpace
+cdef class SimpleSpace(SpaceBase):
+ """Simple space.
+
+ This does not do any collision culling - it simply checks every
+ possible pair of geoms for intersection, and reports the pairs
+ whose AABBs overlap. The time required to do intersection testing
+ for n objects is O(n**2). This should not be used for large numbers
+ of objects, but it can be the preferred algorithm for a small
+ number of objects. This is also useful for debugging potential
+ problems with the collision system.
+ """
+
+ def __cinit__(self, space=None):
+ cdef SpaceBase sp
+ cdef dSpaceID parentid
+
+ parentid = NULL
+ if space != None:
+ sp = space
+ parentid = sp.sid
+
+ self.sid = dSimpleSpaceCreate(parentid)
+
+ # Copy the ID
+ self.gid = <dGeomID>self.sid
+
+ dSpaceSetCleanup(self.sid, 0)
+ _geom_c2py_lut[<size_t>self.sid] = self
+
+ def __init__(self, space=None):
+ pass
+
+# HashSpace
+cdef class HashSpace(SpaceBase):
+ """Multi-resolution hash table space.
+
+ This uses an internal data structure that records how each geom
+ overlaps cells in one of several three dimensional grids. Each
+ grid has cubical cells of side lengths 2**i, where i is an integer
+ that ranges from a minimum to a maximum value. The time required
+ to do intersection testing for n objects is O(n) (as long as those
+ objects are not clustered together too closely), as each object
+ can be quickly paired with the objects around it.
+ """
+
+ def __cinit__(self, space=None):
+ cdef SpaceBase sp
+ cdef dSpaceID parentid
+
+ parentid = NULL
+ if space != None:
+ sp = space
+ parentid = sp.sid
+
+ self.sid = dHashSpaceCreate(parentid)
+
+ # Copy the ID
+ self.gid = <dGeomID>self.sid
+
+ dSpaceSetCleanup(self.sid, 0)
+ _geom_c2py_lut[<size_t>self.sid] = self
+
+ def __init__(self, space=None):
+ pass
+
+ def setLevels(self, int minlevel, int maxlevel):
+ """setLevels(minlevel, maxlevel)
+
+ Sets the size of the smallest and largest cell used in the
+ hash table. The actual size will be 2^minlevel and 2^maxlevel
+ respectively.
+ """
+
+ if minlevel > maxlevel:
+ raise ValueError(
+ "minlevel (%d) must be less than or equal to maxlevel (%d)" %
+ (minlevel, maxlevel))
+
+ dHashSpaceSetLevels(self.sid, minlevel, maxlevel)
+
+ def getLevels(self):
+ """getLevels() -> (minlevel, maxlevel)
+
+ Gets the size of the smallest and largest cell used in the
+ hash table. The actual size is 2^minlevel and 2^maxlevel
+ respectively.
+ """
+
+ cdef int minlevel
+ cdef int maxlevel
+ dHashSpaceGetLevels(self.sid, &minlevel, &maxlevel)
+ return minlevel, maxlevel
+
+
+# QuadTreeSpace
+cdef class QuadTreeSpace(SpaceBase):
+ """Quadtree space.
+
+ This uses a pre-allocated hierarchical grid-based AABB tree to
+ quickly cull collision checks. It's exceptionally quick for large
+ amounts of objects in landscape-shaped worlds. The amount of
+ memory used is 4**depth * 32 bytes.
+
+ Currently getGeom() is not implemented for the quadtree space.
+ """
+
+ def __cinit__(self, center, extents, depth, space=None):
+ cdef SpaceBase sp
+ cdef dSpaceID parentid
+ cdef dVector3 c
+ cdef dVector3 e
+
+ parentid = NULL
+ if space != None:
+ sp = space
+ parentid = sp.sid
+
+ c[0] = center[0]
+ c[1] = center[1]
+ c[2] = center[2]
+ e[0] = extents[0]
+ e[1] = extents[1]
+ e[2] = extents[2]
+ self.sid = dQuadTreeSpaceCreate(parentid, c, e, depth)
+
+ # Copy the ID
+ self.gid = <dGeomID>self.sid
+
+ dSpaceSetCleanup(self.sid, 0)
+ _geom_c2py_lut[<size_t>self.sid] = self
+
+ def __init__(self, center, extents, depth, space=None):
+ pass
+
+
+def Space(space_type=0):
+ """Space factory function.
+
+ Depending on the type argument this function either returns a
+ SimpleSpace (space_type=0) or a HashSpace (space_type=1).
+
+ This function is provided to remain compatible with previous
+ versions of PyODE where there was only one Space class.
+
+ >>> space = Space(space_type=0) # Create a SimpleSpace
+ >>> space = Space(space_type=1) # Create a HashSpace
+ """
+ if space_type == 0:
+ return SimpleSpace()
+ elif space_type == 1:
+ return HashSpace()
+ else:
+ raise ValueError("Unknown space type (%d)" % space_type)
+
+
+# GeomSphere
+cdef class GeomSphere(GeomObject):
+ """Sphere geometry.
+
+ This class represents a sphere centered at the origin.
+
+ Constructor::
+
+ GeomSphere(space=None, radius=1.0)
+ """
+
+ def __cinit__(self, space=None, radius=1.0):
+ cdef SpaceBase sp
+ cdef dSpaceID sid
+
+ sid = NULL
+ if space != None:
+ sp = space
+ sid = sp.sid
+ self.gid = dCreateSphere(sid, radius)
+# if space != None:
+# space._addgeom(self)
+
+ _geom_c2py_lut[<size_t>self.gid] = self
+
+ def __init__(self, space=None, radius=1.0):
+ self.space = space
+ self.body = None
+
+ def placeable(self):
+ return True
+
+ def _id(self):
+ cdef size_t id
+ id = <size_t>self.gid
+ return id
+
+ def setRadius(self, radius):
+ """setRadius(radius)
+
+ Set the radius of the sphere.
+
+ @param radius: New radius
+ @type radius: float
+ """
+ dGeomSphereSetRadius(self.gid, radius)
+
+ def getRadius(self):
+ """getRadius() -> float
+
+ Return the radius of the sphere.
+ """
+ return dGeomSphereGetRadius(self.gid)
+
+ def pointDepth(self, p):
+ """pointDepth(p) -> float
+
+ Return the depth of the point p in the sphere. Points inside
+ the geom will have positive depth, points outside it will have
+ negative depth, and points on the surface will have zero
+ depth.
+
+ @param p: Point
+ @type p: 3-sequence of floats
+ """
+ return dGeomSpherePointDepth(self.gid, p[0], p[1], p[2])
+
+
+# GeomBox
+cdef class GeomBox(GeomObject):
+ """Box geometry.
+
+ This class represents a box centered at the origin.
+
+ Constructor::
+
+ GeomBox(space=None, lengths=(1.0, 1.0, 1.0))
+ """
+
+ def __cinit__(self, space=None, lengths=(1.0, 1.0, 1.0)):
+ cdef SpaceBase sp
+ cdef dSpaceID sid
+
+ sid = NULL
+ if space != None:
+ sp = space
+ sid = sp.sid
+ self.gid = dCreateBox(sid, lengths[0], lengths[1], lengths[2])
+# if space != None:
+# space._addgeom(self)
+
+ _geom_c2py_lut[<size_t>self.gid] = self
+
+ def __init__(self, space=None, lengths=(1.0, 1.0, 1.0)):
+ self.space = space
+ self.body = None
+
+ def placeable(self):
+ return True
+
+ def _id(self):
+ cdef size_t id
+ id = <size_t>self.gid
+ return id
+
+ def setLengths(self, lengths):
+ dGeomBoxSetLengths(self.gid, lengths[0], lengths[1], lengths[2])
+
+ def getLengths(self):
+ cdef dVector3 res
+ dGeomBoxGetLengths(self.gid, res)
+ return res[0], res[1], res[2]
+
+ def pointDepth(self, p):
+ """pointDepth(p) -> float
+
+ Return the depth of the point p in the box. Points inside the
+ geom will have positive depth, points outside it will have
+ negative depth, and points on the surface will have zero
+ depth.
+
+ @param p: Point
+ @type p: 3-sequence of floats
+ """
+ return dGeomBoxPointDepth(self.gid, p[0], p[1], p[2])
+
+
+# GeomPlane
+cdef class GeomPlane(GeomObject):
+ """Plane geometry.
+
+ This class represents an infinite plane. The plane equation is:
+ n.x*x + n.y*y + n.z*z = dist
+
+ This object can't be attached to a body.
+ If you call getBody() on this object it always returns ode.environment.
+
+ Constructor::
+
+ GeomPlane(space=None, normal=(0,0,1), dist=0)
+
+ """
+
+ def __cinit__(self, space=None, normal=(0, 0, 1), dist=0):
+ cdef SpaceBase sp
+ cdef dSpaceID sid
+
+ sid = NULL
+ if space != None:
+ sp = space
+ sid = sp.sid
+ self.gid = dCreatePlane(sid, normal[0], normal[1], normal[2], dist)
+# if space != None:
+# space._addgeom(self)
+
+ _geom_c2py_lut[<size_t>self.gid] = self
+
+ def __init__(self, space=None, normal=(0, 0, 1), dist=0):
+ self.space = space
+
+ def _id(self):
+ cdef size_t id
+ id = <size_t>self.gid
+ return id
+
+ def setParams(self, normal, dist):
+ dGeomPlaneSetParams(self.gid, normal[0], normal[1], normal[2], dist)
+
+ def getParams(self):
+ cdef dVector4 res
+ dGeomPlaneGetParams(self.gid, res)
+ return ((res[0], res[1], res[2]), res[3])
+
+ def pointDepth(self, p):
+ """pointDepth(p) -> float
+
+ Return the depth of the point p in the plane. Points inside the
+ geom will have positive depth, points outside it will have
+ negative depth, and points on the surface will have zero
+ depth.
+
+ @param p: Point
+ @type p: 3-sequence of floats
+ """
+ return dGeomPlanePointDepth(self.gid, p[0], p[1], p[2])
+
+
+# GeomCapsule
+cdef class GeomCapsule(GeomObject):
+ """Capped cylinder geometry.
+
+ This class represents a capped cylinder aligned along the local Z axis
+ and centered at the origin.
+
+ Constructor::
+
+ GeomCapsule(space=None, radius=0.5, length=1.0)
+
+ The length parameter does not include the caps.
+ """
+
+ def __cinit__(self, space=None, radius=0.5, length=1.0):
+ cdef SpaceBase sp
+ cdef dSpaceID sid
+
+ sid = NULL
+ if space != None:
+ sp = space
+ sid = sp.sid
+ self.gid = dCreateCapsule(sid, radius, length)
+# if space != None:
+# space._addgeom(self)
+
+ _geom_c2py_lut[<size_t>self.gid] = self
+
+ def __init__(self, space=None, radius=0.5, length=1.0):
+ self.space = space
+ self.body = None
+
+ def placeable(self):
+ return True
+
+ def _id(self):
+ cdef size_t id
+ id = <size_t>self.gid
+ return id
+
+ def setParams(self, radius, length):
+ dGeomCapsuleSetParams(self.gid, radius, length)
+
+ def getParams(self):
+ cdef dReal radius, length
+ dGeomCapsuleGetParams(self.gid, &radius, &length)
+ return radius, length
+
+ def pointDepth(self, p):
+ """pointDepth(p) -> float
+
+ Return the depth of the point p in the cylinder. Points inside the
+ geom will have positive depth, points outside it will have
+ negative depth, and points on the surface will have zero
+ depth.
+
+ @param p: Point
+ @type p: 3-sequence of floats
+ """
+ return dGeomCapsulePointDepth(self.gid, p[0], p[1], p[2])
+
+GeomCCylinder = GeomCapsule # backwards compatibility
+
+
+# GeomCylinder
+cdef class GeomCylinder(GeomObject):
+ """Plain cylinder geometry.
+
+ This class represents an uncapped cylinder aligned along the local Z axis
+ and centered at the origin.
+
+ Constructor::
+
+ GeomCylinder(space=None, radius=0.5, length=1.0)
+ """
+
+ def __cinit__(self, space=None, radius=0.5, length=1.0):
+ cdef SpaceBase sp
+ cdef dSpaceID sid
+
+ sid = NULL
+ if space != None:
+ sp = space
+ sid = sp.sid
+ self.gid = dCreateCylinder(sid, radius, length)
+# if space != None:
+# space._addgeom(self)
+
+ _geom_c2py_lut[<size_t>self.gid] = self
+
+ def __init__(self, space=None, radius=0.5, length=1.0):
+ self.space = space
+ self.body = None
+
+ def placeable(self):
+ return True
+
+ def _id(self):
+ cdef size_t id
+ id = <size_t>self.gid
+ return id
+
+ def setParams(self, radius, length):
+ dGeomCylinderSetParams(self.gid, radius, length)
+
+ def getParams(self):
+ cdef dReal radius, length
+ dGeomCylinderGetParams(self.gid, &radius, &length)
+ return radius, length
+
+ ## dGeomCylinderPointDepth not implemented upstream in ODE 0.7
+
+
+# GeomRay
+cdef class GeomRay(GeomObject):
+ """Ray object.
+
+ A ray is different from all the other geom classes in that it does
+ not represent a solid object. It is an infinitely thin line that
+ starts from the geom's position and extends in the direction of
+ the geom's local Z-axis.
+
+ Constructor::
+
+ GeomRay(space=None, rlen=1.0)
+
+ """
+
+ def __cinit__(self, space=None, rlen=1.0):
+ cdef SpaceBase sp
+ cdef dSpaceID sid
+
+ sid = NULL
+ if space != None:
+ sp = space
+ sid = sp.sid
+ self.gid = dCreateRay(sid, rlen)
+# if space != None:
+# space._addgeom(self)
+
+ _geom_c2py_lut[<size_t>self.gid] = self
+
+ def __init__(self, space=None, rlen=1.0):
+ self.space = space
+ self.body = None
+
+ def _id(self):
+ cdef size_t id
+ id = <size_t>self.gid
+ return id
+
+ def placeable(self):
+ return True
+
+ def setLength(self, rlen):
+ '''setLength(rlen)
+
+ Set length of the ray.
+
+ @param rlen: length of the ray
+ @type rlen: float'''
+ dGeomRaySetLength(self.gid, rlen)
+
+ def getLength(self):
+ '''getLength() -> length
+
+ Get the length of the ray.
+
+ @returns: length of the ray (float)'''
+ return dGeomRayGetLength(self.gid)
+
+ def set(self, p, u):
+ '''set(p, u)
+
+ Set the position and rotation of a ray.
+
+ @param p: position
+ @type p: 3-sequence of floats
+ @param u: rotation
+ @type u: 3-sequence of floats'''
+ dGeomRaySet(self.gid, p[0], p[1], p[2], u[0], u[1], u[2])
+
+ def get(self):
+ '''get() -> ((p[0], p[1], p[2]), (u[0], u[1], u[2]))
+
+ Return the position and rotation as a pair of
+ tuples.
+
+ @returns: position and rotation'''
+ cdef dVector3 start
+ cdef dVector3 dir
+ dGeomRayGet(self.gid, start, dir)
+ return (start[0], start[1], start[2]), (dir[0], dir[1], dir[2])
+
+
+# GeomTransform
+cdef class GeomTransform(GeomObject):
+ """GeomTransform.
+
+ A geometry transform "T" is a geom that encapsulates another geom
+ "E", allowing E to be positioned and rotated arbitrarily with
+ respect to its point of reference.
+
+ Constructor::
+
+ GeomTransform(space=None)
+ """
+
+ cdef object geom
+
+ def __cinit__(self, space=None):
+ cdef SpaceBase sp
+ cdef dSpaceID sid
+
+ sid = NULL
+ if space != None:
+ sp = space
+ sid = sp.sid
+ self.gid = dCreateGeomTransform(sid)
+ # Set cleanup mode to 0 as a contained geom will be deleted
+ # by its Python wrapper class
+ dGeomTransformSetCleanup(self.gid, 0)
+# if space != None:
+# space._addgeom(self)
+
+ _geom_c2py_lut[<size_t>self.gid] = self
+
+ def __init__(self, space=None):
+ self.space = space
+ self.body = None
+ self.geom = None
+
+ self.attribs = {}
+
+ def placeable(self):
+ return True
+
+ def _id(self):
+ cdef size_t id
+ id = <size_t>self.gid
+ return id
+
+ def setGeom(self, GeomObject geom not None):
+ """setGeom(geom)
+
+ Set the geom that the geometry transform encapsulates.
+ A ValueError exception is thrown if a) the geom is not placeable,
+ b) the geom was already inserted into a space or c) the geom is
+ already associated with a body.
+
+ @param geom: Geom object to encapsulate
+ @type geom: GeomObject
+ """
+ cdef size_t id
+
+ if not geom.placeable():
+ raise ValueError(
+ "Only placeable geoms can be encapsulated by a GeomTransform")
+ if dGeomGetSpace(geom.gid) != <dSpaceID>0:
+ raise ValueError(
+ "The encapsulated geom was already inserted into a space")
+ if dGeomGetBody(geom.gid) != <dBodyID>0:
+ raise ValueError(
+ "The encapsulated geom is already associated with a body")
+
+ id = geom._id()
+ dGeomTransformSetGeom(self.gid, <dGeomID>id)
+ self.geom = geom
+
+ def getGeom(self):
+ """getGeom() -> GeomObject
+
+ Get the geom that the geometry transform encapsulates.
+ """
+ return self.geom
+
+ def setInfo(self, int mode):
+ """setInfo(mode)
+
+ Set the "information" mode of the geometry transform.
+
+ With mode 0, when a transform object is collided with another
+ object, the geom field of the ContactGeom structure is set to the
+ geom that is encapsulated by the transform object.
+
+ With mode 1, the geom field of the ContactGeom structure is set
+ to the transform object itself.
+
+ @param mode: Information mode (0 or 1)
+ @type mode: int
+ """
+ if mode < 0 or mode > 1:
+ raise ValueError(
+ "Invalid information mode (%d). Must be either 0 or 1." % mode)
+ dGeomTransformSetInfo(self.gid, mode)
+
+ def getInfo(self):
+ """getInfo() -> int
+
+ Get the "information" mode of the geometry transform (0 or 1).
+
+ With mode 0, when a transform object is collided with another
+ object, the geom field of the ContactGeom structure is set to the
+ geom that is encapsulated by the transform object.
+
+ With mode 1, the geom field of the ContactGeom structure is set
+ to the transform object itself.
+ """
+ return dGeomTransformGetInfo(self.gid)
+
+######################################################################
+
+
+cdef class TriMeshData:
+ """This class stores the mesh data.
+ """
+
+ cdef dTriMeshDataID tmdid
+ cdef dReal* vertex_buffer
+ cdef int* face_buffer
+
+ def __cinit__(self):
+ self.tmdid = dGeomTriMeshDataCreate()
+ self.vertex_buffer = NULL
+ self.face_buffer = NULL
+
+ def __dealloc__(self):
+ if self.tmdid != NULL:
+ dGeomTriMeshDataDestroy(self.tmdid)
+ if self.vertex_buffer != NULL:
+ free(self.vertex_buffer)
+ if self.face_buffer != NULL:
+ free(self.face_buffer)
+
+ def build(self, verts, faces):
+ """build(verts, faces)
+
+ @param verts: Vertices
+ @type verts: Sequence of 3-sequences of floats
+ @param faces: Face definitions (three indices per face)
+ @type faces: Sequence of 3-sequences of ints
+ """
+ cdef int numverts
+ cdef int numfaces
+ cdef dReal* vp
+ cdef int* fp
+ cdef int a, b, c
+
+ numverts = len(verts)
+ numfaces = len(faces)
+ # Allocate the vertex and face buffer
+ self.vertex_buffer = <dReal*>malloc(numverts * 4 * sizeof(dReal))
+ self.face_buffer = <int*>malloc(numfaces * 3 * sizeof(int))
+
+ # Fill the vertex buffer
+ vp = self.vertex_buffer
+ for v in verts:
+ vp[0] = v[0]
+ vp[1] = v[1]
+ vp[2] = v[2]
+ vp[3] = 0
+ vp = vp + 4
+
+ # Fill the face buffer
+ fp = self.face_buffer
+ for f in faces:
+ a = f[0]
+ b = f[1]
+ c = f[2]
+ if (a < 0 or b < 0 or c < 0 or a >= numverts or b >= numverts or c >= numverts):
+ raise ValueError("Vertex index out of range")
+ fp[0] = a
+ fp[1] = b
+ fp[2] = c
+ fp = fp + 3
+
+ # Pass the data to ODE
+ dGeomTriMeshDataBuildSimple(self.tmdid, self.vertex_buffer, numverts,
+ self.face_buffer, numfaces * 3)
+
+######################################################################
+
+
+# GeomTriMesh
+cdef class GeomTriMesh(GeomObject):
+ """TriMesh object.
+
+ To construct the trimesh geom you need a TriMeshData object that
+ stores the actual mesh. This object has to be passed as first
+ argument to the constructor.
+
+ Constructor::
+
+ GeomTriMesh(data, space=None)
+ """
+
+ # Keep a reference to the data
+ cdef TriMeshData data
+
+ def __cinit__(self, TriMeshData data not None, space=None):
+ cdef SpaceBase sp
+ cdef dSpaceID sid
+
+ self.data = data
+
+ sid = NULL
+ if space != None:
+ sp = space
+ sid = sp.sid
+ self.gid = dCreateTriMesh(sid, data.tmdid, NULL, NULL, NULL)
+
+ _geom_c2py_lut[<size_t>self.gid] = self
+
+ def __init__(self, TriMeshData data not None, space=None):
+ self.space = space
+ self.body = None
+
+ def placeable(self):
+ return True
+
+ def _id(self):
+ cdef size_t id
+ id = <size_t>self.gid
+ return id
+
+ def clearTCCache(self):
+ """clearTCCache()
+
+ Clears the internal temporal coherence caches.
+ """
+ dGeomTriMeshClearTCCache(self.gid)
+
+ def getTriangle(self, int idx):
+ """getTriangle(idx) -> (v0, v1, v2)
+
+ @param idx: Triangle index
+ @type idx: int
+ """
+
+ cdef dVector3 v0, v1, v2
+ cdef dVector3* vp0
+ cdef dVector3* vp1
+ cdef dVector3* vp2
+
+ vp0 = <dVector3*>v0
+ vp1 = <dVector3*>v1
+ vp2 = <dVector3*>v2
+
+ dGeomTriMeshGetTriangle(self.gid, idx, vp0, vp1, vp2)
+ return ((v0[0], v0[1], v0[2]),
+ (v1[0], v1[1], v1[2]),
+ (v2[0], v2[1], v2[2]))
+
+ def getTriangleCount(self):
+ """getTriangleCount() -> n
+
+ Returns the number of triangles in the TriMesh."""
+
+ return dGeomTriMeshGetTriangleCount(self.gid)
+
+######################################################################
+
+
+def collide(geom1, geom2):
+ """collide(geom1, geom2) -> contacts
+
+ Generate contact information for two objects.
+
+ Given two geometry objects that potentially touch (geom1 and geom2),
+ generate contact information for them. Internally, this just calls
+ the correct class-specific collision functions for geom1 and geom2.
+
+ [flags specifies how contacts should be generated if the objects
+ touch. Currently the lower 16 bits of flags specifies the maximum
+ number of contact points to generate. If this number is zero, this
+ function just pretends that it is one - in other words you can not
+ ask for zero contacts. All other bits in flags must be zero. In
+ the future the other bits may be used to select other contact
+ generation strategies.]
+
+ If the objects touch, this returns a list of Contact objects,
+ otherwise it returns an empty list.
+
+ @param geom1: First Geom
+ @type geom1: GeomObject
+ @param geom2: Second Geom
+ @type geom2: GeomObject
+ @returns: Returns a list of Contact objects.
+ """
+
+ cdef dContactGeom c[150]
+ cdef size_t id1
+ cdef size_t id2
+ cdef int i, n
+ cdef Contact cont
+
+ id1 = geom1._id()
+ id2 = geom2._id()
+
+ n = dCollide(<dGeomID>id1, <dGeomID>id2, 150, c, sizeof(dContactGeom))
+ res = []
+ i = 0
+ while i < n:
+ cont = Contact()
+ cont._contact.geom = c[i]
+ res.append(cont)
+ i = i + 1
+
+ return res
+
+
+def collide2(geom1, geom2, arg, callback):
+ """collide2(geom1, geom2, arg, callback)
+
+ Calls the callback for all potentially intersecting pairs that contain
+ one geom from geom1 and one geom from geom2.
+
+ @param geom1: First Geom
+ @type geom1: GeomObject
+ @param geom2: Second Geom
+ @type geom2: GeomObject
+ @param arg: A user argument that is passed to the callback function
+ @param callback: Callback function
+ @type callback: callable
+ """
+ cdef void* data
+ cdef object tup
+ cdef size_t id1
+ cdef size_t id2
+
+ id1 = geom1._id()
+ id2 = geom2._id()
+
+ tup = (callback, arg)
+ data = <void*>tup
+ # collide_callback is defined in space.pyx
+ dSpaceCollide2(<dGeomID>id1, <dGeomID>id2, data, collide_callback)
+
+
+def areConnected(Body body1, Body body2):
+ """areConnected(body1, body2) -> bool
+
+ Return True if the two bodies are connected together by a joint,
+ otherwise return False.
+
+ @param body1: First body
+ @type body1: Body
+ @param body2: Second body
+ @type body2: Body
+ @returns: True if the bodies are connected
+ """
+
+ if body1 is environment:
+ return False
+ if body2 is environment:
+ return False
+
+ return bool(dAreConnected(<dBodyID> body1.bid, <dBodyID> body2.bid))
+
+
+def CloseODE():
+ """CloseODE()
+
+ Deallocate some extra memory used by ODE that can not be deallocated
+ using the normal destroy functions.
+ """
+ dCloseODE()
+
+
+def InitODE():
+ '''InitODE()
+
+ Initialize some ODE internals. This will be called for you when you
+ "import ode", but you should call this again if you CloseODE().'''
+ dInitODE()
+
+
+#environment = Body(None)
+environment = None
+InitODE()
diff --git a/libs/ode-0.16.1/bindings/python/setup.py b/libs/ode-0.16.1/bindings/python/setup.py new file mode 100644 index 0000000..f0c5763 --- /dev/null +++ b/libs/ode-0.16.1/bindings/python/setup.py @@ -0,0 +1,48 @@ +#! /usr/bin/env python +from distutils.core import setup +from distutils.extension import Extension +from subprocess import Popen, PIPE, CalledProcessError + + +try: + from Cython.Distutils import build_ext +except ImportError: + raise SystemExit("Requires Cython (http://cython.org/)") + +try: + ode_cflags = Popen( + ["pkg-config", "--cflags", "ode"], + stdout=PIPE).stdout.read().decode('ascii').split() + ode_libs = Popen( + ["pkg-config", "--libs", "ode"], + stdout=PIPE).stdout.read().decode('ascii').split() +except (OSError, CalledProcessError): + raise SystemExit("Failed to find ODE with 'pkg-config'. Please make sure " + "that it is installed and available on your system path.") + +ode_ext = Extension("ode", ["ode.pyx"], + extra_compile_args=ode_cflags, + extra_link_args=ode_libs) + +if __name__ == "__main__": + setup( + name="Open Dynamics Engine", + version="0.12", + author="Gideon Klompje", +# author_email="", +# maintainer="", +# maintainer_email="", + url="http://www.ode.org", + description="Bindings for the Open Dynamics Engine", + long_description=( + "A free, industrial quality library for simulating articulated " + "rigid body dynamics - for example ground vehicles, legged " + "creatures, and moving objects in VR environments. It's fast, " + "flexible & robust. Built-in collision detection."), +# download_url="https://opende.svn.sourceforge.net/svnroot/opende", +# classifiers=[], +# platforms=[], + license="BSD License, GNU Lesser General Public License (LGPL)", + cmdclass={"build_ext": build_ext}, + ext_modules=[ode_ext] + ) diff --git a/libs/ode-0.16.1/bootstrap b/libs/ode-0.16.1/bootstrap new file mode 100755 index 0000000..24e91f0 --- /dev/null +++ b/libs/ode-0.16.1/bootstrap @@ -0,0 +1,28 @@ +#!/bin/sh + +echo "Please make sure that you use automake 1.11 or later" + echo "Warnings about underquoted definitions are harmless" +if [ `uname -s` = Darwin ]; then + echo "On OSX, install latest libtool, as the OS provided glibtoolize will not work" +fi + +echo "Running aclocal" +aclocal -I m4 --install || exit 1 +echo "Running libtoolize" +libtoolize --copy --automake --install || exit 1 +echo "Running autoheader" +autoheader || exit 1 +echo "Running automake" +automake --foreign --add-missing --copy || exit 1 +echo "Running autoconf" +autoconf || exit 1 + +echo "Running bootstrap in ou directory" +(cd ou && ./bootstrap) + +if [ -d libccd ]; then + echo "Running bootstrap in libccd directory" + (cd libccd && ./bootstrap) +fi; + +echo "Now you are ready to run ./configure" diff --git a/libs/ode-0.16.1/build/config-default.h b/libs/ode-0.16.1/build/config-default.h new file mode 100644 index 0000000..a51e309 --- /dev/null +++ b/libs/ode-0.16.1/build/config-default.h @@ -0,0 +1,113 @@ +/* This file was autogenerated by Premake */
+#ifndef _ODE_CONFIG_H_
+#define _ODE_CONFIG_H_
+
+
+/******************************************************************
+ * CONFIGURATON SETTINGS - you can change these, and then rebuild
+ * ODE to modify the behavior of the library.
+ *
+ * dTRIMESH_ENABLED - enable/disable trimesh support
+ * dTRIMESH_OPCODE - use the OPCODE trimesh engine
+ * dTRIMESH_GIMPACT - use the GIMPACT trimesh engine
+ * Only one trimesh engine should be enabled.
+ *
+ * dTRIMESH_16BIT_INDICES (todo: opcode only)
+ * Setup the trimesh engine to use 16 bit
+ * triangle indices. The default is to use
+ * 32 bit indices. Use the dTriIndex type to
+ * detect the correct index size.
+ *
+ * dTRIMESH_OPCODE_USE_NEWOLD_TRIMESH_TRIMESH_COLLIDER
+ * Use old implementation of trimesh-trimesh collider
+ * (for backward compatibility only)
+ *
+ * dOU_ENABLED
+ * dATOMICS_ENABLED
+ * dTLS_ENABLED
+ * Use generic features of OU library, atomic API
+ * and TLS API respectively.
+ * Generic features and atomic API are always enabled,
+ * unless threading interface support is disabled.
+ * Using TLS for global variables allows calling ODE
+ * collision detection functions from multiple threads.
+ *
+ * dBUILTIN_THREADING_IMPL_ENABLED
+ * Include built-in multithreaded threading
+ * implementation (still must be created and assigned
+ * to be used).
+ *
+ ******************************************************************/
+
+#define dTRIMESH_ENABLED 1
+#define dTRIMESH_OPCODE 1
+#define dTRIMESH_16BIT_INDICES 0
+
+#define dTRIMESH_OPCODE_USE_OLD_TRIMESH_TRIMESH_COLLIDER 0
+
+/* #define dOU_ENABLED 1 */
+/* #define dATOMICS_ENABLED 1 */
+/* #define dTLS_ENABLED 1 */
+
+/* #define dTHREADING_INTF_DISABLED 1 */
+/* #define dBUILTIN_THREADING_IMPL_ENABLED 1 */
+
+
+/******************************************************************
+ * SYSTEM SETTINGS - you shouldn't need to change these. If you
+ * run into an issue with these settings, please report it to
+ * the ODE bug tracker at:
+ * http://sf.net/tracker/?group_id=24884&atid=382799
+ ******************************************************************/
+
+/* Try to identify the platform */
+#if defined(_XENON)
+ #define ODE_PLATFORM_XBOX360
+#elif defined(SN_TARGET_PSP_HW)
+ #define ODE_PLATFORM_PSP
+#elif defined(SN_TARGET_PS3)
+ #define ODE_PLATFORM_PS3
+#elif defined(_MSC_VER) || defined(__CYGWIN32__) || defined(__MINGW32__)
+ #define ODE_PLATFORM_WINDOWS
+#elif defined(__linux__)
+ #define ODE_PLATFORM_LINUX
+#elif defined(__APPLE__) && defined(__MACH__)
+ #define ODE_PLATFORM_OSX
+#else
+ #error "Need some help identifying the platform!"
+#endif
+
+/* Additional platform defines used in the code */
+#if defined(ODE_PLATFORM_WINDOWS) && !defined(WIN32)
+ #define WIN32
+#endif
+
+#if defined(__CYGWIN32__) || defined(__MINGW32__)
+ #define CYGWIN
+#endif
+
+#if defined(ODE_PLATFORM_OSX)
+ #define macintosh
+#endif
+
+#if !defined(ODE_PLATFORM_OSX) && !defined(ODE_PLATFORM_PS3)
+ #include <malloc.h>
+#endif
+
+#if !defined(ODE_PLATFORM_WINDOWS)
+ #include <alloca.h>
+#endif
+ + +/* Basic OU functionality is required if either atomic API or TLS support
+ * is enabled. */
+#if (dATOMICS_ENABLED || dTLS_ENABLED) && !dOU_ENABLED
+#undef dOU_ENABLED
+#define dOU_ENABLED 1
+#endif
+
+
+#include "typedefs.h"
+
+
+#endif
diff --git a/libs/ode-0.16.1/build/premake4.exe b/libs/ode-0.16.1/build/premake4.exe Binary files differnew file mode 100644 index 0000000..b4230f1 --- /dev/null +++ b/libs/ode-0.16.1/build/premake4.exe diff --git a/libs/ode-0.16.1/build/premake4.lua b/libs/ode-0.16.1/build/premake4.lua new file mode 100644 index 0000000..b97f6ac --- /dev/null +++ b/libs/ode-0.16.1/build/premake4.lua @@ -0,0 +1,590 @@ +---------------------------------------------------------------------- +-- Premake4 configuration script for OpenDE +-- Contributed by Jason Perkins (starkos@industriousone.com) +-- For more information on Premake: http://industriousone.com/premake +---------------------------------------------------------------------- + + ode_version = "0.16.1" + +---------------------------------------------------------------------- +-- Demo list: add/remove demos from here and the rest of the build +-- should just work. +---------------------------------------------------------------------- + + local demos = { + "boxstack", + "buggy", + "cards", + "chain1", + "chain2", + "collision", + "convex", + "crash", + "cylvssphere", + "dball", + "dhinge", + "feedback", + "friction", + "gyroscopic", + "gyro2", + "heightfield", + "hinge", + "I", + "jointPR", + "jointPU", + "joints", + "kinematic", + "motion", + "motor", + "ode", + "piston", + "plane2d", + "rfriction", + "slider", + "space", + "space_stress", + "step", + "transmission" + } + + local trimesh_demos = { + "basket", + "cyl", + "moving_convex", + "moving_trimesh", + "tracks", + "trimesh" + } + + if not _OPTIONS["no-trimesh"] then + demos = table.join(demos, trimesh_demos) + end + + + +---------------------------------------------------------------------- +-- Configuration options +---------------------------------------------------------------------- + + newoption { + trigger = "with-demos", + description = "Builds the demo applications and DrawStuff library" + } + + newoption { + trigger = "with-tests", + description = "Builds the unit test application" + } + + newoption { + trigger = "with-gimpact", + description = "Use GIMPACT for trimesh collisions (experimental)" + } + + newoption { + trigger = "all-collis-libs", + description = "Include sources of all collision libraries into the project" + } + + newoption { + trigger = "with-libccd", + description = "Uses libccd for handling some collision tests absent in ODE." + } + + newoption { + trigger = "no-dif", + description = "Exclude DIF (Dynamics Interchange Format) exports" + } + + newoption { + trigger = "no-trimesh", + description = "Exclude trimesh collision geometry" + } + + newoption { + trigger = "with-ou", + description = "Use TLS for global caches (allows threaded collision checks for separated spaces)" + } + + newoption { + trigger = "no-builtin-threading-impl", + description = "Disable built-in multithreaded threading implementation" + } + + newoption { + trigger = "no-threading-intf", + description = "Disable threading interface support (external implementations cannot be assigned)" + } + + newoption { + trigger = "16bit-indices", + description = "Use 16-bit indices for trimeshes (default is 32-bit)" + } + + newoption { + trigger = "old-trimesh", + description = "Use old OPCODE trimesh-trimesh collider" + } + + newoption { + trigger = "to", + value = "path", + description = "Set the output location for the generated project files" + } + + newoption { + trigger = "only-shared", + description = "Only build shared (DLL) version of the library" + } + + newoption { + trigger = "only-static", + description = "Only build static versions of the library" + } + + newoption { + trigger = "only-single", + description = "Only use single-precision math" + } + + newoption { + trigger = "only-double", + description = "Only use double-precision math" + } + + -- always clean all of the optional components and toolsets + if _ACTION == "clean" then + _OPTIONS["with-demos"] = "" + _OPTIONS["with-tests"] = "" + for action in premake.action.each() do + os.rmdir(action.trigger) + end + os.remove("../ode/src/config.h") + os.remove("../include/ode/version.h") + os.remove("../include/ode/precision.h") + os.remove("../libccd/src/ccd/precision.h") + end + + -- special validation for Xcode + if _ACTION == "xcode3" and (not _OPTIONS["only-static"] and not _OPTIONS["only-shared"]) then + error( + "Xcode does not support different library types in a single project.\n" .. + "Please use one of the flags: --only-static or --only-shared", 0) + end + + -- build the list of configurations, based on the flags. Ends up + -- with configurations like "Debug", "DebugSingle" or "DebugSingleShared" + local configs = { "Debug", "Release" } + + local function addconfigs(...) + local newconfigs = { } + for _, root in ipairs(configs) do + for _, suffix in ipairs(arg) do + table.insert(newconfigs, root .. suffix) + end + end + configs = newconfigs + end + + + if not _OPTIONS["only-single"] and not _OPTIONS["only-double"] then + addconfigs("Single", "Double") + end + + if not _OPTIONS["only-shared"] and not _OPTIONS["only-static"] then + addconfigs("DLL", "Lib") + end + + +---------------------------------------------------------------------- +-- The solution, and solution-wide settings +---------------------------------------------------------------------- + + solution "ode" + + language "C++" + uuid "4DA77C12-15E5-497B-B1BB-5100D5161E15" + location ( _OPTIONS["to"] or _ACTION ) + + includedirs { + "../include", + "../ode/src" + } + + defines { "_MT" } + + -- apply the configuration list built above + configurations (configs) + + configuration { "Debug*" } + defines { "_DEBUG" } + flags { "Symbols" } + + configuration { "Release*" } + defines { "NDEBUG", "dNODEBUG" } + flags { "OptimizeSpeed", "NoFramePointer" } + + configuration { "*Single*" } + defines { "dIDESINGLE", "CCD_IDESINGLE" } + + configuration { "*Double*" } + defines { "dIDEDOUBLE", "CCD_IDEDOUBLE" } + + configuration { "Windows" } + defines { "WIN32" } + + configuration { "MacOSX" } + linkoptions { "-framework Carbon" } + + -- give each configuration a unique output directory + for _, name in ipairs(configurations()) do + configuration { name } + targetdir ( "../lib/" .. name ) + end + + -- disable Visual Studio security warnings + configuration { "vs*" } + defines { "_CRT_SECURE_NO_DEPRECATE", "_SCL_SECURE_NO_WARNINGS" } + + -- enable M_* macros from math.h + configuration { "vs*" } + defines { "_USE_MATH_DEFINES" } + + -- don't remember why we had to do this + configuration { "vs2002 or vs2003", "*Lib" } + flags { "StaticRuntime" } + + + +---------------------------------------------------------------------- +-- The demo projects, automated from list above. These go first so +-- they will be selected as the active project automatically in IDEs +---------------------------------------------------------------------- + + if _OPTIONS["with-demos"] then + for _, name in ipairs(demos) do + + project ( "demo_" .. name ) + + kind "ConsoleApp" + location ( _OPTIONS["to"] or _ACTION ) + files { "../ode/demo/demo_" .. name .. ".*" } + links { "ode", "drawstuff" } + + configuration { "Windows" } + files { "../drawstuff/src/resources.rc" } + links { "user32", "winmm", "gdi32", "opengl32", "glu32" } + + configuration { "MacOSX" } + linkoptions { "-framework Carbon -framework OpenGL -framework AGL" } + + configuration { "not Windows", "not MacOSX" } + links { "GL", "GLU" } + + end + end + + + +---------------------------------------------------------------------- +-- The ODE library project +---------------------------------------------------------------------- + + project "ode" + + -- kind "StaticLib" + location ( _OPTIONS["to"] or _ACTION ) + + includedirs { + "../ode/src/joints", + "../OPCODE", + "../GIMPACT/include", + "../libccd/src/custom", + "../libccd/src" + } + + files { + "../include/ode/*.h", + "../ode/src/joints/*.h", + "../ode/src/joints/*.cpp", + "../ode/src/*.h", + "../ode/src/*.c", + "../ode/src/*.cpp", + } + + excludes { + "../ode/src/collision_std.cpp", + } + + includedirs { "../ou/include" } + files { "../ou/include/**.h", "../ou/src/**.h", "../ou/src/**.cpp" } + defines { "_OU_NAMESPACE=odeou" } + + if _OPTIONS["with-ou"] then + defines { "_OU_FEATURE_SET=_OU_FEATURE_SET_TLS" } + elseif not _OPTIONS["no-threading-intf"] then + defines { "_OU_FEATURE_SET=_OU_FEATURE_SET_ATOMICS" } + else + defines { "_OU_FEATURE_SET=_OU_FEATURE_SET_BASICS" } + end + + if _OPTIONS["with-ou"] or not _OPTIONS["no-threading-intf"] then + if _ACTION == "gmake" then + if os.get() == "windows" then + buildoptions { "-mthreads" } + linkoptions { "-mthreads" } + defines { "HAVE_PTHREAD_ATTR_SETINHERITSCHED=1", "HAVE_PTHREAD_ATTR_SETSTACKLAZY=1" } + else + buildoptions { "-pthread" } + linkoptions { "-pthread" } + end + end + end + + + configuration { "no-dif" } + excludes { "../ode/src/export-dif.cpp" } + + configuration { "no-trimesh" } + excludes { + "../ode/src/collision_trimesh_colliders.h", + "../ode/src/gimpact_contact_export_helper.cpp", + "../ode/src/gimpact_contact_export_helper.h", + "../ode/src/gimpact_gim_contact_accessor.h", + "../ode/src/gimpact_plane_contact_accessor.h", + "../ode/src/collision_trimesh_internal.cpp", + "../ode/src/collision_trimesh_opcode.cpp", + "../ode/src/collision_trimesh_gimpact.cpp", + "../ode/src/collision_trimesh_box.cpp", + "../ode/src/collision_trimesh_ccylinder.cpp", + "../ode/src/collision_cylinder_trimesh.cpp", + "../ode/src/collision_trimesh_ray.cpp", + "../ode/src/collision_trimesh_sphere.cpp", + "../ode/src/collision_trimesh_trimesh.cpp", + "../ode/src/collision_trimesh_trimesh_old.cpp", + "../ode/src/collision_trimesh_plane.cpp", + "../ode/src/collision_convex_trimesh.cpp" + } + + configuration { "not no-trimesh", "with-gimpact or all-collis-libs" } + files { "../GIMPACT/**.h", "../GIMPACT/**.cpp" } + + configuration { "not no-trimesh", "not with-gimpact" } + files { "../OPCODE/**.h", "../OPCODE/**.cpp" } + + configuration { "not no-trimesh", "not all-collis-libs", "with-gimpact" } + excludes { + "../ode/src/collision_trimesh_opcode.cpp" + } + + configuration { "not no-trimesh", "not all-collis-libs", "not with-gimpact" } + excludes { + "../ode/src/gimpact_contact_export_helper.cpp", + "../ode/src/gimpact_contact_export_helper.h", + "../ode/src/gimpact_gim_contact_accessor.h", + "../ode/src/gimpact_plane_contact_accessor.h", + "../ode/src/collision_trimesh_gimpact.cpp" + } + + configuration { "with-libccd" } + files { "../libccd/src/custom/ccdcustom/*.h", "../libccd/src/ccd/*.h", "../libccd/src/*.c" } + defines { "dLIBCCD_ENABLED", "dLIBCCD_INTERNAL", + "dLIBCCD_BOX_CYL", "dLIBCCD_CYL_CYL", "dLIBCCD_CAP_CYL", "dLIBCCD_CONVEX_BOX", + "dLIBCCD_CONVEX_CAP", "dLIBCCD_CONVEX_CYL", "dLIBCCD_CONVEX_SPHERE", "dLIBCCD_CONVEX_CONVEX" } + + configuration { "not with-libccd" } + excludes { "../ode/src/collision_libccd.cpp", "../ode/src/collision_libccd.h" } + + configuration { "windows" } + links { "user32" } + + configuration { "only-static or *Lib" } + kind "StaticLib" + defines "ODE_LIB" + + configuration { "only-shared or *DLL" } + kind "SharedLib" + defines "ODE_DLL" + + configuration { "*DLL" } + defines "_DLL" + + configuration { "Debug" } + targetname "oded" + + configuration { "Release" } + targetname "ode" + + configuration { "DebugSingle*" } + targetname "ode_singled" + + configuration { "ReleaseSingle*" } + targetname "ode_single" + + configuration { "DebugDouble*" } + targetname "ode_doubled" + + configuration { "ReleaseDouble*" } + targetname "ode_double" + + +---------------------------------------------------------------------- +-- Write a custom <config.h> to build, based on the supplied flags +---------------------------------------------------------------------- + + if _ACTION and _ACTION ~= "clean" then + local infile = io.open("config-default.h", "r") + local text = infile:read("*a") + + if _OPTIONS["no-trimesh"] then + text = string.gsub(text, "#define dTRIMESH_ENABLED 1", "/* #define dTRIMESH_ENABLED 1 */") + text = string.gsub(text, "#define dTRIMESH_OPCODE 1", "/* #define dTRIMESH_OPCODE 1 */") + elseif (_OPTIONS["with-gimpact"]) then + text = string.gsub(text, "#define dTRIMESH_OPCODE 1", "#define dTRIMESH_GIMPACT 1") + end + + text = string.gsub(text, "/%* #define dOU_ENABLED 1 %*/", "#define dOU_ENABLED 1") + if _OPTIONS["with-ou"] or not _OPTIONS["no-threading-intf"] then + text = string.gsub(text, "/%* #define dATOMICS_ENABLED 1 %*/", "#define dATOMICS_ENABLED 1") + end + + if _OPTIONS["with-ou"] then + text = string.gsub(text, "/%* #define dTLS_ENABLED 1 %*/", "#define dTLS_ENABLED 1") + end + + if _OPTIONS["no-threading-intf"] then + text = string.gsub(text, "/%* #define dTHREADING_INTF_DISABLED 1 %*/", "#define dTHREADING_INTF_DISABLED 1") + elseif not _OPTIONS["no-builtin-threading-impl"] then + text = string.gsub(text, "/%* #define dBUILTIN_THREADING_IMPL_ENABLED 1 %*/", "#define dBUILTIN_THREADING_IMPL_ENABLED 1") + end + + if _OPTIONS["16bit-indices"] then + text = string.gsub(text, "#define dTRIMESH_16BIT_INDICES 0", "#define dTRIMESH_16BIT_INDICES 1") + end + + if _OPTIONS["old-trimesh"] then + text = string.gsub(text, "#define dTRIMESH_OPCODE_USE_OLD_TRIMESH_TRIMESH_COLLIDER 0", "#define dTRIMESH_OPCODE_USE_OLD_TRIMESH_TRIMESH_COLLIDER 1") + end + + local outfile = io.open("../ode/src/config.h", "w") + outfile:write(text) + outfile:close() + end + +---------------------------- +-- Write precision headers +---------------------------- + if _ACTION and _ACTION ~= "clean" then + function generateheader(headerfile, placeholder, precstr) + local outfile = io.open(headerfile, "w") + for i in io.lines(headerfile .. ".in") + do + local j,_ = string.gsub(i, placeholder, precstr) + --print("writing " .. j .. " into " .. headerfile) + outfile:write(j .. "\n") + end + outfile:close() + end + + function generate(precstr) + generateheader("../include/ode/precision.h", "@ODE_PRECISION@", "d" .. precstr) + generateheader("../libccd/src/ccd/precision.h", "@CCD_PRECISION@", "CCD_" .. precstr) + end + + if _OPTIONS["only-single"] then + generate("SINGLE") + elseif _OPTIONS["only-double"] then + generate("DOUBLE") + else + generate("UNDEFINEDPRECISION") + end + + generateheader("../include/ode/version.h", "@ODE_VERSION@", ode_version) + + end + + +---------------------------------------------------------------------- +-- The DrawStuff library project +---------------------------------------------------------------------- + + if _OPTIONS["with-demos"] then + + project "drawstuff" + + location ( _OPTIONS["to"] or _ACTION ) + + files { + "../include/drawstuff/*.h", + "../drawstuff/src/internal.h", + "../drawstuff/src/drawstuff.cpp" + } + + configuration { "Debug*" } + targetname "drawstuffd" + + configuration { "only-static or *Lib" } + kind "StaticLib" + defines { "DS_LIB" } + + configuration { "only-shared or *DLL" } + kind "SharedLib" + defines { "DS_DLL", "USRDLL" } + + configuration { "Windows" } + files { "../drawstuff/src/resource.h", "../drawstuff/src/resources.rc", "../drawstuff/src/windows.cpp" } + links { "user32", "opengl32", "glu32", "winmm", "gdi32" } + + configuration { "MacOSX" } + defines { "HAVE_APPLE_OPENGL_FRAMEWORK" } + files { "../drawstuff/src/osx.cpp" } + linkoptions { "-framework Carbon -framework OpenGL -framework AGL" } + + configuration { "not Windows", "not MacOSX" } + files { "../drawstuff/src/x11.cpp" } + links { "X11", "GL", "GLU" } + + end + + +---------------------------------------------------------------------- +-- The automated test application +---------------------------------------------------------------------- + + + if _OPTIONS["with-tests"] then + + project "tests" + + kind "ConsoleApp" + location ( _OPTIONS["to"] or _ACTION ) + + includedirs { + "../tests/UnitTest++/src" + } + + files { + "../tests/*.cpp", + "../tests/joints/*.cpp", + "../tests/UnitTest++/src/*" + } + + links { "ode" } + + configuration { "Windows" } + files { "../tests/UnitTest++/src/Win32/*" } + + configuration { "not Windows" } + files { "../tests/UnitTest++/src/Posix/*" } + + -- add post-build step to automatically run test executable + local path_to_lib = path.getrelative(location(), "../lib") + local command = path.translate(path.join(path_to_lib, "%s/tests")) + + for _, name in ipairs(configurations()) do + configuration { name } + postbuildcommands { command:format(name) } + end + + end + diff --git a/libs/ode-0.16.1/cmake/cmake_uninstall.cmake.in b/libs/ode-0.16.1/cmake/cmake_uninstall.cmake.in new file mode 100644 index 0000000..6aff17a --- /dev/null +++ b/libs/ode-0.16.1/cmake/cmake_uninstall.cmake.in @@ -0,0 +1,17 @@ +if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") +endif() + +file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" FILES) +string(REGEX REPLACE "\n" ";" FILES "${FILES}") + +foreach(FILE ${FILES}) + message(STATUS "Uninstalling: ${FILE}") + if(EXISTS "${FILE}") + file(REMOVE ${FILE}) + elseif(IS_SYMLINK "${FILE}") + file(REMOVE ${FILE}) + else() + message(STATUS "File \"${FILE}\" does not exist.") + endif() +endforeach() diff --git a/libs/ode-0.16.1/compile b/libs/ode-0.16.1/compile new file mode 100755 index 0000000..a85b723 --- /dev/null +++ b/libs/ode-0.16.1/compile @@ -0,0 +1,347 @@ +#! /bin/sh +# Wrapper for compilers which do not understand '-c -o'. + +scriptversion=2012-10-14.11; # UTC + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Written by Tom Tromey <tromey@cygnus.com>. +# +# 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 2, 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 <http://www.gnu.org/licenses/>. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to <bug-automake@gnu.org> or send patches to +# <automake-patches@gnu.org>. + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file 'INSTALL'. + +Report bugs to <bug-automake@gnu.org>. +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no '-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # '.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use '[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/libs/ode-0.16.1/config.guess b/libs/ode-0.16.1/config.guess new file mode 100755 index 0000000..1659250 --- /dev/null +++ b/libs/ode-0.16.1/config.guess @@ -0,0 +1,1441 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2015 Free Software Foundation, Inc. + +timestamp='2015-08-20' + +# This file 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 <http://www.gnu.org/licenses/>. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# +# Please send patches to <config-patches@gnu.org>. + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <config-patches@gnu.org>." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2015 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case "${UNAME_SYSTEM}" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval $set_cc_for_build + cat <<-EOF > $dummy.c + #include <features.h> + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + /sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || \ + echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + earmv*) + arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` + machine=${arch}${endian}-unknown + ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # Determine ABI tags. + case "${UNAME_MACHINE_ARCH}" in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}${abi}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:Sortix:*:*) + echo ${UNAME_MACHINE}-unknown-sortix + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include <stdio.h> /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <sys/systemcfg.h> + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/lslpp ] ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include <stdlib.h> + #include <unistd.h> + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <unistd.h> + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW64*:*) + echo ${UNAME_MACHINE}-pc-mingw64 + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + *:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="gnulibc1" ; fi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + else + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + e2k:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:Linux:*:*) + echo ${UNAME_MACHINE}-pc-linux-${LIBC} + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } + ;; + openrisc*:Linux:*:*) + echo or1k-unknown-linux-${LIBC} + exit ;; + or32:Linux:*:* | or1k*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-${LIBC} + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; + PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; + *) echo hppa-unknown-linux-${LIBC} ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-${LIBC} + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-${LIBC} + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-${LIBC} + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-${LIBC} + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-${LIBC} + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-pc-linux-${LIBC} + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` + echo ${UNAME_MACHINE}-pc-isc$UNAME_REL + elif /bin/uname -X 2>/dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says <Richard.M.Bartel@ccMail.Census.GOV> + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes <hewes@openmarket.com>. + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + eval $set_cc_for_build + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # Avoid executing cc on OS X 10.9, as it ships with a stub + # that puts up a graphical alert prompting to install + # developer tools. Any system running Mac OS X 10.7 or + # later (Darwin 11 and later) is required to have a 64-bit + # processor. This is not true of the ARM version of Darwin + # that Apple uses in portable devices. + UNAME_PROCESSOR=x86_64 + fi + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; +esac + +cat >&2 <<EOF +$0: unable to guess system type + +This script, last modified $timestamp, has failed to recognize +the operating system you are using. It is advised that you +download the most up to date version of the config scripts from + + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +and + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +If the version you run ($0) is already up to date, please +send the following data and any information you think might be +pertinent to <config-patches@gnu.org> in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/libs/ode-0.16.1/config.h.cmake.in b/libs/ode-0.16.1/config.h.cmake.in new file mode 100644 index 0000000..d2f9599 --- /dev/null +++ b/libs/ode-0.16.1/config.h.cmake.in @@ -0,0 +1,109 @@ +#ifndef ODE_CONFIG_H +#define ODE_CONFIG_H + +/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix). */ +#cmakedefine HAVE_ALLOCA_H 1 + +/* Use the Apple OpenGL framework. */ +#cmakedefine HAVE_APPLE_OPENGL_FRAMEWORK 1 + +/* Define to 1 if you have the `gettimeofday' function. */ +#cmakedefine HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have the <inttypes.h> header file. */ +#cmakedefine HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `isnan' function. */ +#cmakedefine HAVE_ISNAN 1 + +/* Define to 1 if you have the `isnanf' function. */ +#cmakedefine HAVE_ISNANF 1 + +/* Define to 1 if you have the <malloc.h> header file. */ +#cmakedefine HAVE_MALLOC_H 1 + +/* Define to 1 if you have the `pthread_attr_setstacklazy' function. */ +#cmakedefine HAVE_PTHREAD_ATTR_SETSTACKLAZY 1 + +/* Define to 1 if you have the `pthread_condattr_setclock' function. */ +#cmakedefine HAVE_PTHREAD_CONDATTR_SETCLOCK 1 + +/* Define to 1 if you have the <stdint.h> header file. */ +#cmakedefine HAVE_STDINT_H 1 + +/* Define to 1 if you have the <sys/time.h> header file. */ +#cmakedefine HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the <sys/types.h> header file. */ +#cmakedefine HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the <unistd.h> header file. */ +#cmakedefine HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `_isnan' function. */ +#cmakedefine HAVE__ISNAN 1 + +/* Define to 1 if you have the `_isnanf' function. */ +#cmakedefine HAVE__ISNANF 1 + +/* Define to 1 if you have the `__isnan' function. */ +#cmakedefine HAVE___ISNAN 1 + +/* Define to 1 if you have the `__isnanf' function. */ +#cmakedefine HAVE___ISNANF 1 + +/* compiling for a pentium on a gcc-based platform? */ +#cmakedefine PENTIUM 1 + +/* compiling for a X86_64 system on a gcc-based platform? */ +#cmakedefine X86_64_SYSTEM 1 + +/* Try to identify the platform */ +#if defined(_XENON) +#define ODE_PLATFORM_XBOX360 +#elif defined(SN_TARGET_PSP_HW) +#define ODE_PLATFORM_PSP +#elif defined(SN_TARGET_PS3) +#define ODE_PLATFORM_PS3 +#elif defined(_MSC_VER) || defined(__CYGWIN32__) || defined(__MINGW32__) +#define ODE_PLATFORM_WINDOWS +#elif defined(__linux__) +#define ODE_PLATFORM_LINUX +#elif defined(__APPLE__) && defined(__MACH__) +#define ODE_PLATFORM_OSX +#else +#error "Need some help identifying the platform!" +#endif + +/* Additional platform defines used in the code */ +#if defined(ODE_PLATFORM_WINDOWS) && !defined(WIN32) +#define WIN32 +#endif + +#if defined(__CYGWIN32__) || defined(__MINGW32__) +#define CYGWIN +#endif + +#if defined(ODE_PLATFORM_OSX) +#define macintosh +#endif + +#ifdef HAVE_ALLOCA_H +#include <alloca.h> +#endif + +#ifdef HAVE_MALLOC_H +#include <malloc.h> +#endif + +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif + +#ifdef HAVE_INTTYPES_H +#include <inttypes.h> +#endif + +#include "typedefs.h" + +#endif // ODE_CONFIG_H diff --git a/libs/ode-0.16.1/config.sub b/libs/ode-0.16.1/config.sub new file mode 100755 index 0000000..1acc966 --- /dev/null +++ b/libs/ode-0.16.1/config.sub @@ -0,0 +1,1813 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright 1992-2015 Free Software Foundation, Inc. + +timestamp='2015-08-20' + +# This file 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 <http://www.gnu.org/licenses/>. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches to <config-patches@gnu.org>. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <config-patches@gnu.org>." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2015 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze*) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | ba \ + | be32 | be64 \ + | bfin \ + | c4x | c8051 | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | e2k | epiphany \ + | fido | fr30 | frv | ft32 \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 | nios2eb | nios2el \ + | ns16k | ns32k \ + | open8 | or1k | or1knd | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | riscv32 | riscv64 \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | visium \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + leon|leon[3-9]) + basic_machine=sparc-$basic_machine + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | ba-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | c8051-* | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | e2k-* | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | k1om-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa32r6-* | mipsisa32r6el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64r6-* | mipsisa64r6el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | or1k*-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | riscv32-* | riscv64-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | visium-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + asmjs) + basic_machine=asmjs-unknown + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + leon-*|leon[3-9]-*) + basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; + mingw32) + basic_machine=i686-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + moxiebox) + basic_machine=moxie-unknown + os=-moxiebox + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i686-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* | -plan9* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* | -cloudabi* | -sortix* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + c8051-*) + os=-elf + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/libs/ode-0.16.1/configure b/libs/ode-0.16.1/configure new file mode 100755 index 0000000..03ea74f --- /dev/null +++ b/libs/ode-0.16.1/configure @@ -0,0 +1,21593 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for ODE 0.16.1. +# +# Report bugs to <ode@ode.org>. +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and ode@ode.org about +$0: your system, including any error possibly output before +$0: this message. Then install a modern shell, or manually +$0: run the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 </dev/null +exec 6>&1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='ODE' +PACKAGE_TARNAME='ode' +PACKAGE_VERSION='0.16.1' +PACKAGE_STRING='ODE 0.16.1' +PACKAGE_BUGREPORT='ode@ode.org' +PACKAGE_URL='' + +ac_unique_file="ode/src/ode.cpp" +# Factoring default headers for most tests. +ac_includes_default="\ +#include <stdio.h> +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#ifdef STDC_HEADERS +# include <stdlib.h> +# include <stddef.h> +#else +# ifdef HAVE_STDLIB_H +# include <stdlib.h> +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include <memory.h> +# endif +# include <string.h> +#endif +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif +#ifdef HAVE_INTTYPES_H +# include <inttypes.h> +#endif +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif" + +enable_option_checking=no +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBCCD_CONVEX_CONVEX_FALSE +LIBCCD_CONVEX_CONVEX_TRUE +LIBCCD_CONVEX_SPHERE_FALSE +LIBCCD_CONVEX_SPHERE_TRUE +LIBCCD_CONVEX_CYL_FALSE +LIBCCD_CONVEX_CYL_TRUE +LIBCCD_CONVEX_CAP_FALSE +LIBCCD_CONVEX_CAP_TRUE +LIBCCD_CONVEX_BOX_FALSE +LIBCCD_CONVEX_BOX_TRUE +LIBCCD_CAP_CYL_FALSE +LIBCCD_CAP_CYL_TRUE +LIBCCD_CYL_CYL_FALSE +LIBCCD_CYL_CYL_TRUE +LIBCCD_BOX_CYL_FALSE +LIBCCD_BOX_CYL_TRUE +LIBCCD_INTERNAL_FALSE +LIBCCD_INTERNAL_TRUE +LIBCCD_FALSE +LIBCCD_TRUE +CCD_LIBS +CCD_CFLAGS +ENABLE_OU_FALSE +ENABLE_OU_TRUE +subdirs +ALLOCA +LIBOBJS +ENABLE_DEMOS_FALSE +ENABLE_DEMOS_TRUE +LIBSTDCXX +ENABLE_DRAWSTUFF_FALSE +ENABLE_DRAWSTUFF_TRUE +OSX_FALSE +OSX_TRUE +X11_FALSE +X11_TRUE +WIN32_FALSE +WIN32_TRUE +GL_LIBS +X11_LIBS +X11_CFLAGS +EXTRA_LIBTOOL_LDFLAGS +ODE_PRECISION +TRIMESH_FALSE +TRIMESH_TRUE +GIMPACT_FALSE +GIMPACT_TRUE +OPCODE_FALSE +OPCODE_TRUE +X86_64_SYSTEM_FALSE +X86_64_SYSTEM_TRUE +HAVE_DOXYGEN_FALSE +HAVE_DOXYGEN_TRUE +DOXYGEN +PKG_CONFIG_LIBDIR +PKG_CONFIG_PATH +PKG_CONFIG +ac_ct_WINDRES +WINDRES +CXXCPP +LT_SYS_LIBRARY_PATH +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +RANLIB +ac_ct_AR +AR +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +EGREP +GREP +SED +LIBTOOL +OBJDUMP +DLLTOOL +AS +LN_S +CPP +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +ac_ct_CC +CFLAGS +CC +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CXX +CPPFLAGS +LDFLAGS +CXXFLAGS +CXX +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +ODE_VERSION_INFO +ODE_VERSION +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +runstatedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_version_info +enable_silent_rules +enable_dependency_tracking +enable_shared +enable_static +with_pic +enable_fast_install +with_aix_soname +with_gnu_ld +with_sysroot +enable_libtool_lock +with_trimesh +enable_double_precision +with_drawstuff +enable_demos +enable_old_trimesh +enable_gprof +enable_threading_intf +enable_ou +enable_builtin_threading_impl +enable_libccd +with_cylinder_cylinder +with_box_cylinder +with_capsule_cylinder +with_convex_box +with_convex_capsule +with_convex_cylinder +with_convex_sphere +with_convex_convex +with_libccd +enable_asserts +' + ac_precious_vars='build_alias +host_alias +target_alias +CXX +CXXFLAGS +LDFLAGS +LIBS +CPPFLAGS +CCC +CC +CFLAGS +CPP +LT_SYS_LIBRARY_PATH +CXXCPP +PKG_CONFIG +PKG_CONFIG_PATH +PKG_CONFIG_LIBDIR +DOXYGEN +X11_CFLAGS +X11_LIBS +CCD_CFLAGS +CCD_LIBS' +ac_subdirs_all='ou +libccd' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir runstatedir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures ODE 0.16.1 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/ode] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of ODE 0.16.1:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-version-info don't encode version information in the generated + library + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build + --enable-shared[=PKGS] build shared libraries [default=no] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + --enable-double-precision + Configure ODE to work with double precision, if not + specified, single precision is used [default=no] + --disable-demos don't build demos + --enable-old-trimesh enable use of the old trimesh collider + --enable-gprof enable profiling with gprof + --disable-threading-intf + disable threading interface support (external + implementations cannot be assigned) + --enable-ou use TLS for global caches (allows threaded collision + checks for isolated spaces) + --disable-builtin-threading-impl + disable built-in multithreaded threading + implementation + --enable-libccd enable all libccd colliders (except box-cylinder) + --disable-asserts disables debug error checking + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use + both] + --with-aix-soname=aix|svr4|both + shared library versioning (aka "SONAME") variant to + provide on AIX, [default=aix]. + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-sysroot[=DIR] Search for dependent libraries within DIR (or the + compiler's sysroot if not specified). + --with-trimesh=[opcode|gimpact|none] + use the specified system for trimesh support + [default=opcode] + --with-drawstuff=X11|Win32|OSX|none + force a particular drawstuff implementation or + disable it.[default=autodetect] + --with-cylinder-cylinder=[none,libccd] + use specific collider for cylinder-cylinder + --with-box-cylinder=[default,libccd] + use specific collider for box-cylinder + --with-capsule-cylinder=[none,libccd] + use specific collider for capsule-cylinder + --with-convex-box=[none,libccd] + use specific collider for convex-box + --with-convex-capsule=[none,libccd] + use specific collider for convex-capsule + --with-convex-cylinder=[none,libccd] + use specific collider for convex-cylinder + --with-convex-sphere=[default,libccd] + use specific collider for convex-sphere + --with-convex-convex=[default,libccd] + use specific collider for convex-convex + --with-libccd=[internal|system] + use the specified libccd [default=system] + +Some influential environment variables: + CXX C++ compiler command + CXXFLAGS C++ compiler flags + LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a + nonstandard directory <lib dir> + LIBS libraries to pass to the linker, e.g. -l<library> + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if + you have headers in a nonstandard directory <include dir> + CC C compiler command + CFLAGS C compiler flags + CPP C preprocessor + LT_SYS_LIBRARY_PATH + User-defined run-time library search path. + CXXCPP C++ preprocessor + PKG_CONFIG path to pkg-config utility + PKG_CONFIG_PATH + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path + DOXYGEN set to doxygen binary to generate doxygen docs + X11_CFLAGS C compiler flags for X11, overriding pkg-config + X11_LIBS linker flags for X11, overriding pkg-config + CCD_CFLAGS C compiler flags for CCD, overriding pkg-config + CCD_LIBS linker flags for CCD, overriding pkg-config + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to <ode@ode.org>. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +ODE configure 0.16.1 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case <limits.h> declares $2. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_cxx_try_cpp LINENO +# ------------------------ +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_cpp + +# ac_fn_cxx_try_link LINENO +# ------------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_link + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## -------------------------- ## +## Report this to ode@ode.org ## +## -------------------------- ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type + +# ac_fn_c_find_intX_t LINENO BITS VAR +# ----------------------------------- +# Finds a signed integer type with width BITS, setting cache variable VAR +# accordingly. +ac_fn_c_find_intX_t () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5 +$as_echo_n "checking for int$2_t... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + # Order is important - never check a type that is potentially smaller + # than half of the expected target width. + for ac_type in int$2_t 'int' 'long int' \ + 'long long int' 'short int' 'signed char'; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default + enum { N = $2 / 2 - 1 }; +int +main () +{ +static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default + enum { N = $2 / 2 - 1 }; +int +main () +{ +static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1) + < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + case $ac_type in #( + int$2_t) : + eval "$3=yes" ;; #( + *) : + eval "$3=\$ac_type" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if eval test \"x\$"$3"\" = x"no"; then : + +else + break +fi + done +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_find_intX_t + +# ac_fn_c_find_uintX_t LINENO BITS VAR +# ------------------------------------ +# Finds an unsigned integer type with width BITS, setting cache variable VAR +# accordingly. +ac_fn_c_find_uintX_t () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5 +$as_echo_n "checking for uint$2_t... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + # Order is important - never check a type that is potentially smaller + # than half of the expected target width. + for ac_type in uint$2_t 'unsigned int' 'unsigned long int' \ + 'unsigned long long int' 'unsigned short int' 'unsigned char'; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !((($ac_type) -1 >> ($2 / 2 - 1)) >> ($2 / 2 - 1) == 3)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + case $ac_type in #( + uint$2_t) : + eval "$3=yes" ;; #( + *) : + eval "$3=\$ac_type" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if eval test \"x\$"$3"\" = x"no"; then : + +else + break +fi + done +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_find_uintX_t +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by ODE $as_me 0.16.1, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ODE_VERSION=0.16.1 + + +# Those are instructions from the Libtool manual: +# 1. Start with version information of `0:0:0' for each libtool library. +# +# 2. Update the version information only immediately before a public +# release of your software. More frequent updates are unnecessary, +# and only guarantee that the current interface number gets larger +# faster. +# +# 3. If the library source code has changed at all since the last +# update, then increment REVISION (`C:R:A' becomes `C:r+1:A'). +# +# 4. If any interfaces have been added, removed, or changed since the +# last update, increment CURRENT, and set REVISION to 0. +# +# 5. If any interfaces have been added since the last public release, +# then increment AGE. +# +# 6. If any interfaces have been removed since the last public release, +# then set AGE to 0. +CURRENT=8 +REVISION=1 +AGE=0 + +# Check whether --enable-version-info was given. +if test "${enable_version_info+set}" = set; then : + enableval=$enable_version_info; version_info=$enableval +else + version_info=yes +fi + +if test x$version_info = xyes +then + ODE_VERSION_INFO="-version-info $CURRENT:$REVISION:$AGE" +else + ODE_VERSION_INFO="-avoid-version" +fi + + + + + + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + + +am__api_version='1.15' + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='ode' + VERSION='0.16.1' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: <http://www.gnu.org/software/coreutils/>. + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi + +ac_config_headers="$ac_config_headers ode/src/config.h" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5 +$as_echo_n "checking whether the C++ compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C++ compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5 +$as_echo_n "checking for C++ compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C++ compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CXX_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdio.h> +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4.6' +macro_revision='2.4.6' + + + + + + + + + + + + + +ltmain=$ac_aux_dir/ltmain.sh + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case $ECHO in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_FGREP" || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in + *GNU* | *'with BFD'*) + test no != "$with_gnu_ld" && break + ;; + *) + test yes != "$with_gnu_ld" && break + ;; + esac + fi + done + IFS=$lt_save_ifs +else + lt_cv_path_LD=$LD # Let the user override the test with a path. +fi +fi + +LD=$lt_cv_path_LD +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + lt_cv_prog_gnu_ld=yes + ;; +*) + lt_cv_prog_gnu_ld=no + ;; +esac +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM=$NM +else + lt_nm_to_check=${ac_tool_prefix}nm + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break 2 + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break 2 + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS=$lt_save_ifs + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols -headers" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test : != "$DUMPBIN"; then + NM=$DUMPBIN + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring=ABCD + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test 17 != "$i" # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n "$lt_cv_sys_max_cmd_len"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +$as_echo_n "checking how to convert $build file names to $host format... " >&6; } +if ${lt_cv_to_host_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +$as_echo "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } +if ${lt_cv_to_tool_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +$as_echo "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test yes != "$GCC"; then + reload_cmds=false + fi + ;; + darwin*) + if test yes = "$GCC"; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# 'unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +$as_echo_n "checking how to associate runtime and link libraries... " >&6; } +if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd=$ECHO + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cru} + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +$as_echo_n "checking for archiver @FILE support... " >&6; } +if ${lt_cv_ar_at_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -eq "$ac_status"; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -ne "$ac_status"; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +$as_echo "$lt_cv_ar_at_file" >&6; } + +if test no = "$lt_cv_ar_at_file"; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + bitrig* | openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test ia64 = "$host_cpu"; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS=conftstm.$ac_objext + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test yes = "$pipe_works"; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; +else + with_sysroot=no +fi + + +lt_sysroot= +case $with_sysroot in #( + yes) + if test yes = "$GCC"; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 +$as_echo "$with_sysroot" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +$as_echo "${lt_sysroot:-no}" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 +$as_echo_n "checking for a working dd... " >&6; } +if ${ac_cv_path_lt_DD+:} false; then : + $as_echo_n "(cached) " >&6 +else + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +if test -z "$lt_DD"; then + ac_path_lt_DD_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in dd; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_lt_DD" || continue +if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi + $ac_path_lt_DD_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_lt_DD"; then + : + fi +else + ac_cv_path_lt_DD=$lt_DD +fi + +rm -f conftest.i conftest2.i conftest.out +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 +$as_echo "$ac_cv_path_lt_DD" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 +$as_echo_n "checking how to truncate binary pipes... " >&6; } +if ${lt_cv_truncate_bin+:} false; then : + $as_echo_n "(cached) " >&6 +else + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 +$as_echo "$lt_cv_truncate_bin" >&6; } + + + + + + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test no = "$enable_libtool_lock" || enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE=32 + ;; + *ELF-64*) + HPUX_IA64_MODE=64 + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test yes = "$lt_cv_prog_gnu_ld"; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test yes != "$lt_cv_cc_needs_belf"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS=$SAVE_CFLAGS + fi + ;; +*-*solaris*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*|x86_64-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD=${LD-ld}_sol2 + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks=$enable_libtool_lock + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +$as_echo "$MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if ${lt_cv_path_mainfest_tool+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +$as_echo "$lt_cv_path_mainfest_tool" >&6; } +if test yes != "$lt_cv_path_mainfest_tool"; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "$LT_MULTI_MODULE"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&5 + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if ${lt_cv_ld_force_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&5 + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + 10.[012][,.]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test yes = "$lt_cv_apple_cc_single_mod"; then + _lt_dar_single_mod='$single_module' + fi + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' + fi + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <string.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ctype.h> +#include <stdlib.h> +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + + +func_stripname_cnf () +{ + case $2 in + .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;; + *) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;; + esac +} # func_stripname_cnf + + + + + +# Set options +# Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_shared=no +fi + + + + + + + +enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. +set dummy ${ac_tool_prefix}as; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AS+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AS"; then + ac_cv_prog_AS="$AS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AS="${ac_tool_prefix}as" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AS=$ac_cv_prog_AS +if test -n "$AS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 +$as_echo "$AS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AS"; then + ac_ct_AS=$AS + # Extract the first word of "as", so it can be a program name with args. +set dummy as; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AS+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AS"; then + ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AS="as" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AS=$ac_cv_prog_ac_ct_AS +if test -n "$ac_ct_AS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5 +$as_echo "$ac_ct_AS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AS" = x; then + AS="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AS=$ac_ct_AS + fi +else + AS="$ac_cv_prog_AS" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + + ;; +esac + +test -z "$AS" && AS=as + + + + + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + enable_dlopen=no + + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + pic_mode=default +fi + + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[5-9]*,yes) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 +$as_echo_n "checking which variant of shared library versioning to provide... " >&6; } + +# Check whether --with-aix-soname was given. +if test "${with_aix_soname+set}" = set; then : + withval=$with_aix_soname; case $withval in + aix|svr4|both) + ;; + *) + as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname +else + if ${lt_cv_with_aix_soname+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_with_aix_soname=aix +fi + + with_aix_soname=$lt_cv_with_aix_soname +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 +$as_echo "$with_aix_soname" >&6; } + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS=$ltmain + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld=$lt_cv_prog_gnu_ld + +old_CC=$CC +old_CFLAGS=$CFLAGS + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +func_cc_basename $compiler +cc_basename=$func_cc_basename_result + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/${ac_tool_prefix}file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC=$CC +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test yes = "$GCC"; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test yes = "$GCC"; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + lt_prog_compiler_pic='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +$as_echo "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works"; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works"; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test no = "$hard_links"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test yes != "$GCC"; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd* | bitrig*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test yes = "$with_gnu_ld"; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test yes = "$lt_use_gnu_ld_interface"; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='$wl' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + export_dynamic_flag_spec='$wl--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test ia64 != "$host_cpu"; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='$wl--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test linux-dietlibc = "$host_os"; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test no = "$tmp_diet" + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + tcc*) + export_dynamic_flag_spec='-rdynamic' + ;; + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test no = "$ld_shlibs"; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then + aix_use_runtimelinking=yes + break + fi + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + hardcode_direct=no + hardcode_direct_absolute=no + ;; + esac + + if test yes = "$GCC"; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + export_dynamic_flag_spec='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' $wl-bernotok' + allow_undefined_flag=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test yes = "$GCC"; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='$wl-E' + ;; + + hpux10*) + if test yes,no = "$GCC,$with_gnu_ld"; then + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test yes,no = "$GCC,$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if ${lt_cv_prog_compiler__b+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test yes = "$lt_cv_prog_compiler__b"; then + archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test yes = "$GCC"; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if ${lt_cv_irix_exported_symbol+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_irix_exported_symbol=yes +else + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +$as_echo "$lt_cv_irix_exported_symbol" >&6; } + if test yes = "$lt_cv_irix_exported_symbol"; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' + fi + link_all_deplibs=no + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + ld_shlibs=yes + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + else + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + osf3*) + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test yes = "$GCC"; then + wlarc='$wl' + archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='$wl' + archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. GCC discards it without '$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test yes = "$GCC"; then + whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test sequent = "$host_vendor"; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='$wl-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='$wl-z,text' + allow_undefined_flag='$wl-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test sni = "$host_vendor"; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='$wl-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test no = "$ld_shlibs" && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test yes = "$GCC"; then + case $host_os in + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary... + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo = "/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's|/\([A-Za-z]:\)|\1|g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + + + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib<name>.so + # instead of lib<name>.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a(lib.so.V)' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test yes = "$hardcode_automatic"; then + + # We can hardcode non-existent directories. + if test no != "$hardcode_direct" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && + test no != "$hardcode_minus_L"; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test relink = "$hardcode_action" || + test yes = "$inherit_rpath"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test yes != "$enable_dlopen"; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen=load_add_on + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen=LoadLibrary + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else + + lt_cv_dlopen=dyld + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + lt_cv_dlopen=shl_load +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + lt_cv_dlopen=dlopen +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test no = "$lt_cv_dlopen"; then + enable_dlopen=no + else + enable_dlopen=yes + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS=$LDFLAGS + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS=$LIBS + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test yes = "$lt_cv_dlopen_self"; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP"; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report what library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC=$lt_save_CC + + if test -n "$CXX" && ( test no != "$CXX" && + ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || + (test g++ != "$CXX"))); then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if ${ac_cv_prog_CXXCPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +else + _lt_caught_CXX_error=yes +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +compiler_needs_object_CXX=no +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_direct_absolute_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +inherit_rpath_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +reload_flag_CXX=$reload_flag +reload_cmds_CXX=$reload_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_caught_CXX_error"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + + # save warnings/boilerplate of simple test code + ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + + ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + compiler_CXX=$CC + func_cc_basename $compiler +cc_basename=$func_cc_basename_result + + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test yes = "$GXX"; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' + else + lt_prog_compiler_no_builtin_flag_CXX= + fi + + if test yes = "$GXX"; then + # Set up default GNU C++ configuration + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in + *GNU* | *'with BFD'*) + test no != "$with_gnu_ld" && break + ;; + *) + test yes != "$with_gnu_ld" && break + ;; + esac + fi + done + IFS=$lt_save_ifs +else + lt_cv_path_LD=$LD # Let the user override the test with a path. +fi +fi + +LD=$lt_cv_path_LD +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + lt_cv_prog_gnu_ld=yes + ;; +*) + lt_cv_prog_gnu_ld=no + ;; +esac +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test yes = "$with_gnu_ld"; then + archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='$wl' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + ld_shlibs_CXX=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix[4-9]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + file_list_spec_CXX='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + hardcode_direct_CXX=no + hardcode_direct_absolute_CXX=no + ;; + esac + + if test yes = "$GXX"; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag=$shared_flag' $wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + export_dynamic_flag_spec_CXX='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + always_export_symbols_CXX=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + # The "-G" linker flag allows undefined symbols. + no_undefined_flag_CXX='-bernotok' + # Determine the default libpath from the value encoded in an empty + # executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec_CXX='$wl-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' $wl-bernotok' + allow_undefined_flag_CXX=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + fi + archive_cmds_need_lc_CXX=yes + archive_expsym_cmds_CXX='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared + # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_CXX=' ' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=yes + file_list_spec_CXX='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' + enable_shared_with_static_runtimes_CXX=yes + # Don't use ranlib + old_postinstall_cmds_CXX='chmod 644 $oldlib' + postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + export_dynamic_flag_spec_CXX='$wl--export-all-symbols' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + + + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec_CXX='' + fi + link_all_deplibs_CXX=yes + allow_undefined_flag_CXX=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds_CXX="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + if test yes != "$lt_cv_apple_cc_single_mod"; then + archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" + archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" + fi + + else + ld_shlibs_CXX=no + fi + + ;; + + os2*) + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_minus_L_CXX=yes + allow_undefined_flag_CXX=unsupported + shrext_cmds=.dll + archive_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes_CXX=yes + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + ld_shlibs_CXX=no + ;; + + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + + haiku*) + archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + link_all_deplibs_CXX=yes + ;; + + hpux9*) + hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='$wl-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + export_dynamic_flag_spec_CXX='$wl-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + interix[3-9]*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + hardcode_libdir_separator_CXX=: + inherit_rpath_CXX=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [1-5].* | *pgcpp\ [1-5].*) + prelink_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + old_archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='$wl--rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + whole_archive_flag_spec_CXX='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' + hardcode_libdir_flag_spec_CXX='-R$libdir' + whole_archive_flag_spec_CXX='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object_CXX=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + ld_shlibs_CXX=yes + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + hardcode_direct_absolute_CXX=yes + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='$wl-E' + whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + ld_shlibs_CXX=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + case $host in + osf3*) + allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' + archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + ;; + *) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ + $RM $lib.exp' + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + ;; + esac + + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes,no = "$GXX,$with_gnu_ld"; then + allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' + case $host in + osf3*) + archive_cmds_CXX='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + *) + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test yes,no = "$GXX,$with_gnu_ld"; then + no_undefined_flag_CXX=' $wl-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require '-G' NOT '-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir' + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + whole_archive_flag_spec_CXX='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='$wl-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_CXX='$wl-z,text' + allow_undefined_flag_CXX='$wl-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-R,$libdir' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ + '"$old_archive_cmds_CXX" + reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ + '"$reload_cmds_CXX" + ;; + *) + archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } + test no = "$ld_shlibs_CXX" && can_build_shared=no + + GCC_CXX=$GXX + LD_CXX=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + # Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF + + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $prev$p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test x-L = "$p" || + test x-R = "$p"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test no = "$pre_test_object_deps_done"; then + case $prev in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX=$prev$p + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} $prev$p" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX=$prev$p + else + postdeps_CXX="${postdeps_CXX} $prev$p" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test no = "$pre_test_object_deps_done"; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX=$p + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX=$p + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +case $host_os in +interix[3-9]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; +esac + + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + compiler_lib_search_dirs_CXX= +if test -n "${compiler_lib_search_path_CXX}"; then + compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | $SED -e 's! -L! !g' -e 's!^ !!'` +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + + + # C++ specific cases for pic, static, wl, etc. + if test yes = "$GXX"; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + lt_prog_compiler_pic_CXX='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic_CXX='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static_CXX='$wl-static' + ;; + esac + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static_CXX= + ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix[4-9]*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='$wl-a ${wl}archive' + if test ia64 != "$host_cpu"; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='$wl-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64, which still supported -KPIC. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-qpic' + lt_prog_compiler_static_CXX='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } +lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } +if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_CXX=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works_CXX=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_CXX=yes + fi + else + lt_cv_prog_compiler_static_works_CXX=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then + : +else + lt_prog_compiler_static_CXX= +fi + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test no = "$hard_links"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + case $host_os in + aix[4-9]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX=$ltdll_cmds + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + ;; + esac + ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs_CXX=no + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } +test no = "$ld_shlibs_CXX" && can_build_shared=no + +with_gnu_ld_CXX=$with_gnu_ld + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc_CXX=no + else + lt_cv_archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } + archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + + + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib<name>.so + # instead of lib<name>.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a(lib.so.V)' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec_CXX='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || + test -n "$runpath_var_CXX" || + test yes = "$hardcode_automatic_CXX"; then + + # We can hardcode non-existent directories. + if test no != "$hardcode_direct_CXX" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" && + test no != "$hardcode_minus_L_CXX"; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 +$as_echo "$hardcode_action_CXX" >&6; } + +if test relink = "$hardcode_action_CXX" || + test yes = "$inherit_rpath_CXX"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test yes != "$_lt_caught_CXX_error" + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + +if test -n "$ac_tool_prefix"; then + for ac_prog in windres + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_WINDRES+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$WINDRES"; then + ac_cv_prog_WINDRES="$WINDRES" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_WINDRES="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +WINDRES=$ac_cv_prog_WINDRES +if test -n "$WINDRES"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WINDRES" >&5 +$as_echo "$WINDRES" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$WINDRES" && break + done +fi +if test -z "$WINDRES"; then + ac_ct_WINDRES=$WINDRES + for ac_prog in windres +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_WINDRES+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_WINDRES"; then + ac_cv_prog_ac_ct_WINDRES="$ac_ct_WINDRES" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_WINDRES="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_WINDRES=$ac_cv_prog_ac_ct_WINDRES +if test -n "$ac_ct_WINDRES"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_WINDRES" >&5 +$as_echo "$ac_ct_WINDRES" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_WINDRES" && break +done + + if test "x$ac_ct_WINDRES" = x; then + WINDRES="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + WINDRES=$ac_ct_WINDRES + fi +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 +$as_echo_n "checking whether byte ordering is bigendian... " >&6; } +if ${ac_cv_c_bigendian+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_bigendian=unknown + # See if we're dealing with a universal compiler. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + # Check for potential -arch flags. It is not universal unless + # there are at least two -arch flags with different values. + ac_arch= + ac_prev= + for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do + if test -n "$ac_prev"; then + case $ac_word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then + ac_arch=$ac_word + else + ac_cv_c_bigendian=universal + break + fi + ;; + esac + ac_prev= + elif test "x$ac_word" = "x-arch"; then + ac_prev=arch + fi + done +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test $ac_cv_c_bigendian = unknown; then + # See if sys/param.h defines the BYTE_ORDER macro. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + #include <sys/param.h> + +int +main () +{ +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ + && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ + && LITTLE_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + #include <sys/param.h> + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <limits.h> + +int +main () +{ +#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to _BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <limits.h> + +int +main () +{ +#ifndef _BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # Compile a test program. + if test "$cross_compiling" = yes; then : + # Try to guess by grepping values from an object file. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +short int ascii_mm[] = + { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; + short int ascii_ii[] = + { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; + int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; + } + short int ebcdic_ii[] = + { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; + short int ebcdic_mm[] = + { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; + int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; + } + extern int foo; + +int +main () +{ +return use_ascii (foo) == use_ebcdic (foo); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then + ac_cv_c_bigendian=yes + fi + if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_bigendian=no +else + ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 +$as_echo "$ac_cv_c_bigendian" >&6; } + case $ac_cv_c_bigendian in #( + yes) + $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h +;; #( + no) + ;; #( + universal) + +$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h + + ;; #( + *) + as_fn_error $? "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 +$as_echo_n "checking for inline... " >&6; } +if ${ac_cv_c_inline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_inline=$ac_kw +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 +$as_echo "$ac_cv_c_inline" >&6; } + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working volatile" >&5 +$as_echo_n "checking for working volatile... " >&6; } +if ${ac_cv_c_volatile+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +volatile int x; +int * volatile y = (int *) 0; +return !x && !y; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_volatile=yes +else + ac_cv_c_volatile=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_volatile" >&5 +$as_echo "$ac_cv_c_volatile" >&6; } +if test $ac_cv_c_volatile = no; then + +$as_echo "#define volatile /**/" >>confdefs.h + +fi + + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi +fi + + +for ac_prog in doxygen +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DOXYGEN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DOXYGEN"; then + ac_cv_prog_DOXYGEN="$DOXYGEN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DOXYGEN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DOXYGEN=$ac_cv_prog_DOXYGEN +if test -n "$DOXYGEN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DOXYGEN" >&5 +$as_echo "$DOXYGEN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DOXYGEN" && break +done + + if test x$DOXYGEN = xdoxygen; then + HAVE_DOXYGEN_TRUE= + HAVE_DOXYGEN_FALSE='#' +else + HAVE_DOXYGEN_TRUE='#' + HAVE_DOXYGEN_FALSE= +fi + + + +pentium=no +cpu64=no +case "$host_cpu" in + i586 | i686 | i786 ) + pentium=yes + +$as_echo "#define PENTIUM 1" >>confdefs.h + + ;; + x86_64* ) + pentium=yes + cpu64=yes + +$as_echo "#define X86_64_SYSTEM 1" >>confdefs.h + + ;; +esac + + if test x$cpu64 = xyes; then + X86_64_SYSTEM_TRUE= + X86_64_SYSTEM_FALSE='#' +else + X86_64_SYSTEM_TRUE='#' + X86_64_SYSTEM_FALSE= +fi + + + + + + + +for ac_header in alloca.h stdio.h inttypes.h stdint.h stdlib.h math.h \ + string.h stdarg.h malloc.h float.h time.h sys/time.h \ + limits.h stddef.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +opcode=no +gimpact=no + +# Check whether --with-trimesh was given. +if test "${with_trimesh+set}" = set; then : + withval=$with_trimesh; trimesh=$withval +else + trimesh=opcode + +fi + +if test "$trimesh" = opcode +then + opcode=yes +fi +if test "$trimesh" = gimpact +then + gimpact=yes +fi + + if test $opcode = yes; then + OPCODE_TRUE= + OPCODE_FALSE='#' +else + OPCODE_TRUE='#' + OPCODE_FALSE= +fi + + if test $gimpact = yes; then + GIMPACT_TRUE= + GIMPACT_FALSE='#' +else + GIMPACT_TRUE='#' + GIMPACT_FALSE= +fi + + if test $opcode = yes -o $gimpact = yes; then + TRIMESH_TRUE= + TRIMESH_FALSE='#' +else + TRIMESH_TRUE='#' + TRIMESH_FALSE= +fi + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if double precision is requested" >&5 +$as_echo_n "checking if double precision is requested... " >&6; } +# Check whether --enable-double-precision was given. +if test "${enable_double_precision+set}" = set; then : + enableval=$enable_double_precision; usedouble=$enableval +else + usedouble=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $usedouble" >&5 +$as_echo "$usedouble" >&6; } +if test "$usedouble" = yes; +then + ODE_PRECISION=dDOUBLE +else + ODE_PRECISION=dSINGLE +fi + + + + +# Check whether --with-drawstuff was given. +if test "${with_drawstuff+set}" = set; then : + withval=$with_drawstuff; drawstuff=$withval +else + drawstuff= +fi + + +EXTRA_LIBTOOL_LDFLAGS= +case "$host_os" in + cygwin* | mingw*) + if test "x$drawstuff" = x + then + drawstuff="Win32" # if in a Windows enviroment + fi + EXTRA_LIBTOOL_LDFLAGS="-no-undefined" + ;; + *apple* | *darwin*) # For Mac OS X + if test "x$drawstuff" = x + then + drawstuff="OSX" + fi + CC="$CXX" + LINK="$CXXLINK" + ;; + *) + if test "x$drawstuff" = x + then + drawstuff="X11" # if anything else default to X11 + fi + ;; +esac + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking which drawstuff lib to build" >&5 +$as_echo_n "checking which drawstuff lib to build... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $drawstuff" >&5 +$as_echo "$drawstuff" >&6; } + +if test "x$drawstuff" = "xX11" +then + # The built-in macro, X_PATH, causes too many problems, these days everyone uses Xorg, + # so we can ask pkg-config to find it for us. + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X11" >&5 +$as_echo_n "checking for X11... " >&6; } + +if test -n "$X11_CFLAGS"; then + pkg_cv_X11_CFLAGS="$X11_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"x11\""; } >&5 + ($PKG_CONFIG --exists --print-errors "x11") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_X11_CFLAGS=`$PKG_CONFIG --cflags "x11" 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$X11_LIBS"; then + pkg_cv_X11_LIBS="$X11_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"x11\""; } >&5 + ($PKG_CONFIG --exists --print-errors "x11") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_X11_LIBS=`$PKG_CONFIG --libs "x11" 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + X11_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "x11" 2>&1` + else + X11_PKG_ERRORS=`$PKG_CONFIG --print-errors "x11" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$X11_PKG_ERRORS" >&5 + + drawstuff="none" +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + drawstuff="none" +else + X11_CFLAGS=$pkg_cv_X11_CFLAGS + X11_LIBS=$pkg_cv_X11_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi +fi + +if test "x$drawstuff" = "xOSX"; then + +$as_echo "#define HAVE_APPLE_OPENGL_FRAMEWORK 1" >>confdefs.h + + GL_LIBS="-framework OpenGL -framework GLUT" +elif test "x$drawstuff" != "xnone"; then + have_gl_headers=yes + for ac_header in GL/gl.h GL/glu.h GL/glext.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#ifdef WIN32 + #include <windows.h> + #endif + #if HAVE_GL_GL_H + #include <GL/gl.h> + #endif + #if HAVE_GL_GLU_H + #include <GL/glu.h> + #endif + +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +else + have_gl_headers=no +fi + +done + + have_gl=no + have_glu=no + TEMP_LDFLAGS="$LDFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lGL" >&5 +$as_echo_n "checking for main in -lGL... " >&6; } +if ${ac_cv_lib_GL_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lGL $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_GL_main=yes +else + ac_cv_lib_GL_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GL_main" >&5 +$as_echo "$ac_cv_lib_GL_main" >&6; } +if test "x$ac_cv_lib_GL_main" = xyes; then : + GL_LIBS="-lGL"; have_gl=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lGLU" >&5 +$as_echo_n "checking for main in -lGLU... " >&6; } +if ${ac_cv_lib_GLU_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lGLU -lGL $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_GLU_main=yes +else + ac_cv_lib_GLU_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GLU_main" >&5 +$as_echo "$ac_cv_lib_GLU_main" >&6; } +if test "x$ac_cv_lib_GLU_main" = xyes; then : + GL_LIBS="-lGLU $GL_LIBS"; have_glu=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lopengl32" >&5 +$as_echo_n "checking for main in -lopengl32... " >&6; } +if ${ac_cv_lib_opengl32_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lopengl32 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_opengl32_main=yes +else + ac_cv_lib_opengl32_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_opengl32_main" >&5 +$as_echo "$ac_cv_lib_opengl32_main" >&6; } +if test "x$ac_cv_lib_opengl32_main" = xyes; then : + GL_LIBS="-lopengl32"; have_gl=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lglu32" >&5 +$as_echo_n "checking for main in -lglu32... " >&6; } +if ${ac_cv_lib_glu32_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lglu32 -lopengl32 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_glu32_main=yes +else + ac_cv_lib_glu32_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_glu32_main" >&5 +$as_echo "$ac_cv_lib_glu32_main" >&6; } +if test "x$ac_cv_lib_glu32_main" = xyes; then : + GL_LIBS="-lglu32 $GL_LIBS"; have_glu=yes +fi + + LDFLAGS="$TEMP_LDFLAGS" + if test $have_gl = no -o $have_glu = no -o $have_gl_headers = no; then + drawstuff="none" + fi +fi + + + if test x$drawstuff = xWin32; then + WIN32_TRUE= + WIN32_FALSE='#' +else + WIN32_TRUE='#' + WIN32_FALSE= +fi + + if test x$drawstuff = xX11; then + X11_TRUE= + X11_FALSE='#' +else + X11_TRUE='#' + X11_FALSE= +fi + + if test x$drawstuff = xOSX; then + OSX_TRUE= + OSX_FALSE='#' +else + OSX_TRUE='#' + OSX_FALSE= +fi + + if test x$drawstuff != xnone; then + ENABLE_DRAWSTUFF_TRUE= + ENABLE_DRAWSTUFF_FALSE='#' +else + ENABLE_DRAWSTUFF_TRUE='#' + ENABLE_DRAWSTUFF_FALSE= +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if demos should be built" >&5 +$as_echo_n "checking if demos should be built... " >&6; } +# Check whether --enable-demos was given. +if test "${enable_demos+set}" = set; then : + enableval=$enable_demos; enable_demos=$enableval +else + enable_demos=yes +fi + +if test x$drawstuff = xnone -a x$enable_demos = xyes ; then + enable_demos=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_demos" >&5 +$as_echo "$enable_demos" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Demos will not be built because OpenGL doesn't seem to work. See \`config.log' for details." >&5 +$as_echo "$as_me: WARNING: Demos will not be built because OpenGL doesn't seem to work. See \`config.log' for details." >&2;} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_demos" >&5 +$as_echo "$enable_demos" >&6; } +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lstdc++" >&5 +$as_echo_n "checking for main in -lstdc++... " >&6; } +if ${ac_cv_lib_stdcpp_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lstdc++ $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_stdcpp_main=yes +else + ac_cv_lib_stdcpp_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_stdcpp_main" >&5 +$as_echo "$ac_cv_lib_stdcpp_main" >&6; } +if test "x$ac_cv_lib_stdcpp_main" = xyes; then : + LIBSTDCXX="-lstdc++" +else + LIBSTDCXX= +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lpthread" >&5 +$as_echo_n "checking for main in -lpthread... " >&6; } +if ${ac_cv_lib_pthread_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthread $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_pthread_main=yes +else + ac_cv_lib_pthread_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_main" >&5 +$as_echo "$ac_cv_lib_pthread_main" >&6; } +if test "x$ac_cv_lib_pthread_main" = xyes; then : + LIBS="$LIBS -lpthread" +fi + + + + if test x$enable_demos = xyes; then + ENABLE_DEMOS_TRUE= + ENABLE_DEMOS_FALSE='#' +else + ENABLE_DEMOS_TRUE='#' + ENABLE_DEMOS_FALSE= +fi + + + +old_trimesh=no +# Check whether --enable-old-trimesh was given. +if test "${enable_old_trimesh+set}" = set; then : + enableval=$enable_old_trimesh; old_trimesh=$enableval + +fi + +if test x$old_trimesh = xyes -a $trimesh = opcode; then + +$as_echo "#define dTRIMESH_OPCODE_USE_OLD_TRIMESH_TRIMESH_COLLIDER 1" >>confdefs.h + +else + old_trimesh=no +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gprof" >&5 +$as_echo_n "checking for gprof... " >&6; } +# Check whether --enable-gprof was given. +if test "${enable_gprof+set}" = set; then : + enableval=$enable_gprof; gprof=$enableval +else + gprof=no +fi + +if test "$gprof" != no +then + CFLAGS="-pg $CFLAGS" + CXXFLAGS="-pg $CXXFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled" >&5 +$as_echo "enabled" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lgmon" >&5 +$as_echo_n "checking for main in -lgmon... " >&6; } +if ${ac_cv_lib_gmon_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lgmon $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_gmon_main=yes +else + ac_cv_lib_gmon_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gmon_main" >&5 +$as_echo "$ac_cv_lib_gmon_main" >&6; } +if test "x$ac_cv_lib_gmon_main" = xyes; then : + LIBS="$LIBS -lgmon" +fi + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Checks for typedefs, structures, and compiler characteristics. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5 +$as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } +if ${ac_cv_header_stdbool_h+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include <stdbool.h> + #ifndef bool + "error: bool is not defined" + #endif + #ifndef false + "error: false is not defined" + #endif + #if false + "error: false is not 0" + #endif + #ifndef true + "error: true is not defined" + #endif + #if true != 1 + "error: true is not 1" + #endif + #ifndef __bool_true_false_are_defined + "error: __bool_true_false_are_defined is not defined" + #endif + + struct s { _Bool s: 1; _Bool t; } s; + + char a[true == 1 ? 1 : -1]; + char b[false == 0 ? 1 : -1]; + char c[__bool_true_false_are_defined == 1 ? 1 : -1]; + char d[(bool) 0.5 == true ? 1 : -1]; + /* See body of main program for 'e'. */ + char f[(_Bool) 0.0 == false ? 1 : -1]; + char g[true]; + char h[sizeof (_Bool)]; + char i[sizeof s.t]; + enum { j = false, k = true, l = false * true, m = true * 256 }; + /* The following fails for + HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ + _Bool n[m]; + char o[sizeof n == m * sizeof n[0] ? 1 : -1]; + char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; + /* Catch a bug in an HP-UX C compiler. See + http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html + http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html + */ + _Bool q = true; + _Bool *pq = &q; + +int +main () +{ + + bool e = &s; + *pq |= q; + *pq |= ! q; + /* Refer to every declared value, to avoid compiler optimizations. */ + return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l + + !m + !n + !o + !p + !q + !pq); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdbool_h=yes +else + ac_cv_header_stdbool_h=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5 +$as_echo "$ac_cv_header_stdbool_h" >&6; } + ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default" +if test "x$ac_cv_type__Bool" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE__BOOL 1 +_ACEOF + + +fi + + +if test $ac_cv_header_stdbool_h = yes; then + +$as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 +$as_echo_n "checking for inline... " >&6; } +if ${ac_cv_c_inline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_inline=$ac_kw +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 +$as_echo "$ac_cv_c_inline" >&6; } + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + +ac_fn_c_find_intX_t "$LINENO" "32" "ac_cv_c_int32_t" +case $ac_cv_c_int32_t in #( + no|yes) ;; #( + *) + +cat >>confdefs.h <<_ACEOF +#define int32_t $ac_cv_c_int32_t +_ACEOF +;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for obstacks" >&5 +$as_echo_n "checking for obstacks... " >&6; } +if ${ac_cv_func_obstack+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default + #include "obstack.h" +int +main () +{ +struct obstack mem; + #define obstack_chunk_alloc malloc + #define obstack_chunk_free free + obstack_init (&mem); + obstack_free (&mem, 0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_func_obstack=yes +else + ac_cv_func_obstack=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_obstack" >&5 +$as_echo "$ac_cv_func_obstack" >&6; } +if test $ac_cv_func_obstack = yes; then + +$as_echo "#define HAVE_OBSTACK 1" >>confdefs.h + +else + case " $LIBOBJS " in + *" obstack.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS obstack.$ac_objext" + ;; +esac + +fi + +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + +ac_fn_c_find_uintX_t "$LINENO" "32" "ac_cv_c_uint32_t" +case $ac_cv_c_uint32_t in #( + no|yes) ;; #( + *) + +$as_echo "#define _UINT32_T 1" >>confdefs.h + + +cat >>confdefs.h <<_ACEOF +#define uint32_t $ac_cv_c_uint32_t +_ACEOF +;; + esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lm" >&5 +$as_echo_n "checking for main in -lm... " >&6; } +if ${ac_cv_lib_m_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lm $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_m_main=yes +else + ac_cv_lib_m_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_main" >&5 +$as_echo "$ac_cv_lib_m_main" >&6; } +if test "x$ac_cv_lib_m_main" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBM 1 +_ACEOF + + LIBS="-lm $LIBS" + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lsunmath" >&5 +$as_echo_n "checking for main in -lsunmath... " >&6; } +if ${ac_cv_lib_sunmath_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsunmath $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_sunmath_main=yes +else + ac_cv_lib_sunmath_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sunmath_main" >&5 +$as_echo "$ac_cv_lib_sunmath_main" >&6; } +if test "x$ac_cv_lib_sunmath_main" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSUNMATH 1 +_ACEOF + + LIBS="-lsunmath $LIBS" + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lrt" >&5 +$as_echo_n "checking for main in -lrt... " >&6; } +if ${ac_cv_lib_rt_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lrt $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_rt_main=yes +else + ac_cv_lib_rt_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_main" >&5 +$as_echo "$ac_cv_lib_rt_main" >&6; } +if test "x$ac_cv_lib_rt_main" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBRT 1 +_ACEOF + + LIBS="-lrt $LIBS" + +fi + +for ac_func in atan2f clock_gettime copysign copysignf cosf fabsf floor fmodf gettimeofday isnan _isnan __isnan isnanf _isnanf __isnanf memmove memset pthread_attr_setstacklazy pthread_attr_setinheritsched pthread_condattr_setclock sinf snprintf sqrt sqrtf strchr strstr vsnprintf +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works +# for constant arguments. Useless! +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5 +$as_echo_n "checking for working alloca.h... " >&6; } +if ${ac_cv_working_alloca_h+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <alloca.h> +int +main () +{ +char *p = (char *) alloca (2 * sizeof (int)); + if (p) return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_working_alloca_h=yes +else + ac_cv_working_alloca_h=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5 +$as_echo "$ac_cv_working_alloca_h" >&6; } +if test $ac_cv_working_alloca_h = yes; then + +$as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 +$as_echo_n "checking for alloca... " >&6; } +if ${ac_cv_func_alloca_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __GNUC__ +# define alloca __builtin_alloca +#else +# ifdef _MSC_VER +# include <malloc.h> +# define alloca _alloca +# else +# ifdef HAVE_ALLOCA_H +# include <alloca.h> +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ +void *alloca (size_t); +# endif +# endif +# endif +# endif +#endif + +int +main () +{ +char *p = (char *) alloca (1); + if (p) return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_func_alloca_works=yes +else + ac_cv_func_alloca_works=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5 +$as_echo "$ac_cv_func_alloca_works" >&6; } + +if test $ac_cv_func_alloca_works = yes; then + +$as_echo "#define HAVE_ALLOCA 1" >>confdefs.h + +else + # The SVR3 libPW and SVR4 libucb both contain incompatible functions +# that cause trouble. Some versions do not even contain alloca or +# contain a buggy version. If you still want to use their alloca, +# use ar to extract alloca.o from them instead of compiling alloca.c. + +ALLOCA=\${LIBOBJDIR}alloca.$ac_objext + +$as_echo "#define C_ALLOCA 1" >>confdefs.h + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5 +$as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; } +if ${ac_cv_os_cray+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined CRAY && ! defined CRAY2 +webecray +#else +wenotbecray +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "webecray" >/dev/null 2>&1; then : + ac_cv_os_cray=yes +else + ac_cv_os_cray=no +fi +rm -f conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5 +$as_echo "$ac_cv_os_cray" >&6; } +if test $ac_cv_os_cray = yes; then + for ac_func in _getb67 GETB67 getb67; do + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + +cat >>confdefs.h <<_ACEOF +#define CRAY_STACKSEG_END $ac_func +_ACEOF + + break +fi + + done +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5 +$as_echo_n "checking stack direction for C alloca... " >&6; } +if ${ac_cv_c_stack_direction+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_c_stack_direction=0 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +find_stack_direction (int *addr, int depth) +{ + int dir, dummy = 0; + if (! addr) + addr = &dummy; + *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; + dir = depth ? find_stack_direction (addr, depth - 1) : 0; + return dir + dummy; +} + +int +main (int argc, char **argv) +{ + return find_stack_direction (0, argc + !argv + 20) < 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_stack_direction=1 +else + ac_cv_c_stack_direction=-1 +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5 +$as_echo "$ac_cv_c_stack_direction" >&6; } +cat >>confdefs.h <<_ACEOF +#define STACK_DIRECTION $ac_cv_c_stack_direction +_ACEOF + + +fi + + +ac_fn_c_check_func "$LINENO" "pthread_condattr_setclock" "ac_cv_func_pthread_condattr_setclock" +if test "x$ac_cv_func_pthread_condattr_setclock" = xyes; then : + +else + ac_cv_func_no_pthread_condattr_setclock=yes +fi + +for ac_func in no_pthread_condattr_setclock +do : + ac_fn_c_check_func "$LINENO" "no_pthread_condattr_setclock" "ac_cv_func_no_pthread_condattr_setclock" +if test "x$ac_cv_func_no_pthread_condattr_setclock" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_NO_PTHREAD_CONDATTR_SETCLOCK 1 +_ACEOF + +fi +done + + + +# Check whether --enable-threading-intf was given. +if test "${enable_threading_intf+set}" = set; then : + enableval=$enable_threading_intf; threading_intf=$enableval +else + threading_intf=yes +fi + +# Check whether --enable-ou was given. +if test "${enable_ou+set}" = set; then : + enableval=$enable_ou; use_ou_tls=$enableval +else + use_ou_tls=no +fi + +use_ou="no" +if test x$use_ou_tls = xyes -o x$threading_intf = xyes +then + use_ou="yes" +fi + +OU_NAMESPACE=odeou + + +$as_echo "#define _OU_NAMESPACE odeou" >>confdefs.h + + +$as_echo "#define dOU_ENABLED 1" >>confdefs.h + + +if test x$use_ou_tls = xyes +then + OU_FEATURE_SET=_OU_FEATURE_SET_TLS + +$as_echo "#define _OU_FEATURE_SET _OU_FEATURE_SET_TLS" >>confdefs.h + +elif test x$use_ou = xyes +then + OU_FEATURE_SET=_OU_FEATURE_SET_ATOMICS + +$as_echo "#define _OU_FEATURE_SET _OU_FEATURE_SET_ATOMICS" >>confdefs.h + +else + OU_FEATURE_SET=_OU_FEATURE_SET_BASICS + +$as_echo "#define _OU_FEATURE_SET _OU_FEATURE_SET_BASICS" >>confdefs.h + +fi + + +if test x$use_ou = xyes +then + +$as_echo "#define dATOMICS_ENABLED 1" >>confdefs.h + + if test x$use_ou_tls = xyes + then + +$as_echo "#define dTLS_ENABLED 1" >>confdefs.h + + fi +fi + +case "$host_os" in + cygwin* | mingw*) + targetos=_OU_TARGET_OS_WINDOWS + ;; + *qnx*) + targetos=_OU_TARGET_OS_QNX + ;; + *apple* | *darwin*) + targetos=_OU_TARGET_OS_MAC + ;; + *sunos*) + targetos=_OU_TARGET_OS_SUNOS + ;; + *aix*) + targetos=_OU_TARGET_OS_AIX + ;; + *) + targetos=_OU_TARGET_OS_GENUNIX + ;; +esac + +if test $targetos = _OU_TARGET_OS_MAC +then + MAC_OS_X_VERSION=1000 + ac_fn_c_check_func "$LINENO" "OSAtomicAdd32Barrier" "ac_cv_func_OSAtomicAdd32Barrier" +if test "x$ac_cv_func_OSAtomicAdd32Barrier" = xyes; then : + MAC_OS_X_VERSION=1040 +fi + + ac_fn_c_check_func "$LINENO" "OSAtomicAnd32OrigBarrier" "ac_cv_func_OSAtomicAnd32OrigBarrier" +if test "x$ac_cv_func_OSAtomicAnd32OrigBarrier" = xyes; then : + MAC_OS_X_VERSION=1050 +fi + + +cat >>confdefs.h <<_ACEOF +#define MAC_OS_X_VERSION $MAC_OS_X_VERSION +_ACEOF + +fi + +if test $targetos = _OU_TARGET_OS_SUNOS +then + ac_fn_c_check_func "$LINENO" "atomic_inc_32_nv" "ac_cv_func_atomic_inc_32_nv" +if test "x$ac_cv_func_atomic_inc_32_nv" = xyes; then : + +else + targetos=_OU_TARGET_OS_GENUNIX +fi + +fi + + +cat >>confdefs.h <<_ACEOF +#define _OU_TARGET_OS $targetos +_ACEOF + + + + +subdirs="$subdirs ou" + + if true; then + ENABLE_OU_TRUE= + ENABLE_OU_FALSE='#' +else + ENABLE_OU_TRUE='#' + ENABLE_OU_FALSE= +fi + + +if test x$threading_intf = xyes +then + # Check whether --enable-builtin-threading-impl was given. +if test "${enable_builtin_threading_impl+set}" = set; then : + enableval=$enable_builtin_threading_impl; use_builtin_threading_impl=$enableval +else + use_builtin_threading_impl=yes +fi + + if test x$use_builtin_threading_impl = xyes + then + +$as_echo "#define dBUILTIN_THREADING_IMPL_ENABLED 1" >>confdefs.h + + fi +else + +$as_echo "#define dTHREADING_INTF_DISABLED 1" >>confdefs.h + + use_builtin_threading_impl=no +fi + +col_cylinder_cylinder=none +col_box_cylinder=default +col_capsule_cylinder=none +col_convex_box=none +col_convex_capsule=none +col_convex_cylinder=none +col_convex_sphere=default +col_convex_convex=default + + +use_libccd=no +libccd_all=no +# Check whether --enable-libccd was given. +if test "${enable_libccd+set}" = set; then : + enableval=$enable_libccd; libccd_all=$enableval +fi + +if test x$libccd_all = xyes +then + col_cylinder_cylinder=libccd + col_capsule_cylinder=libccd + col_convex_box=libccd + col_convex_capsule=libccd + col_convex_cylinder=libccd + col_convex_sphere=libccd + col_convex_convex=libccd + use_libccd=yes +fi + + + +# Check whether --with-cylinder-cylinder was given. +if test "${with_cylinder_cylinder+set}" = set; then : + withval=$with_cylinder_cylinder; col_cylinder_cylinder=$withval +fi + + + +# Check whether --with-box-cylinder was given. +if test "${with_box_cylinder+set}" = set; then : + withval=$with_box_cylinder; col_box_cylinder=$withval +fi + + + +# Check whether --with-capsule-cylinder was given. +if test "${with_capsule_cylinder+set}" = set; then : + withval=$with_capsule_cylinder; col_capsule_cylinder=$withval +fi + + + +# Check whether --with-convex-box was given. +if test "${with_convex_box+set}" = set; then : + withval=$with_convex_box; col_convex_box=$withval +fi + + + +# Check whether --with-convex-capsule was given. +if test "${with_convex_capsule+set}" = set; then : + withval=$with_convex_capsule; col_convex_capsule=$withval +fi + + + +# Check whether --with-convex-cylinder was given. +if test "${with_convex_cylinder+set}" = set; then : + withval=$with_convex_cylinder; col_convex_cylinder=$withval +fi + + + +# Check whether --with-convex-sphere was given. +if test "${with_convex_sphere+set}" = set; then : + withval=$with_convex_sphere; col_convex_sphere=$withval +fi + + + +# Check whether --with-convex-convex was given. +if test "${with_convex_convex+set}" = set; then : + withval=$with_convex_convex; col_convex_convex=$withval +fi + + +if test x$col_cylinder_cylinder = xlibccd -o \ + x$col_box_cylinder = xlibccd -o \ + x$col_capsule_cylinder = xlibccd -o \ + x$col_convex_box = xlibccd -o \ + x$col_convex_capsule = libccd -o \ + x$col_convex_cylinder = xlibccd -o \ + x$col_convex_sphere = libccd -o \ + x$col_convex_convex = libccd +then + use_libccd=yes +fi + + +libccd_source=internal + + +# Check whether --with-libccd was given. +if test "${with_libccd+set}" = set; then : + withval=$with_libccd; libccd_source=$withval +else + libccd_source=system +fi + + +if test x$use_libccd = xyes +then + if test x$libccd_source = xsystem + then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for CCD" >&5 +$as_echo_n "checking for CCD... " >&6; } + +if test -n "$CCD_CFLAGS"; then + pkg_cv_CCD_CFLAGS="$CCD_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ccd\""; } >&5 + ($PKG_CONFIG --exists --print-errors "ccd") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_CCD_CFLAGS=`$PKG_CONFIG --cflags "ccd" 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$CCD_LIBS"; then + pkg_cv_CCD_LIBS="$CCD_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ccd\""; } >&5 + ($PKG_CONFIG --exists --print-errors "ccd") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_CCD_LIBS=`$PKG_CONFIG --libs "ccd" 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + CCD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "ccd" 2>&1` + else + CCD_PKG_ERRORS=`$PKG_CONFIG --print-errors "ccd" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$CCD_PKG_ERRORS" >&5 + + libccd_source=internal +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + libccd_source=internal +else + CCD_CFLAGS=$pkg_cv_CCD_CFLAGS + CCD_LIBS=$pkg_cv_CCD_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + fi +fi + +# Configure libccd unconditionally as that may be needed for special make targets +subdirs="$subdirs libccd" + + + if test x$use_libccd != xno; then + LIBCCD_TRUE= + LIBCCD_FALSE='#' +else + LIBCCD_TRUE='#' + LIBCCD_FALSE= +fi + + if test x$libccd_source = xinternal; then + LIBCCD_INTERNAL_TRUE= + LIBCCD_INTERNAL_FALSE='#' +else + LIBCCD_INTERNAL_TRUE='#' + LIBCCD_INTERNAL_FALSE= +fi + + if test x$col_box_cylinder = xlibccd; then + LIBCCD_BOX_CYL_TRUE= + LIBCCD_BOX_CYL_FALSE='#' +else + LIBCCD_BOX_CYL_TRUE='#' + LIBCCD_BOX_CYL_FALSE= +fi + + if test x$col_cylinder_cylinder = xlibccd; then + LIBCCD_CYL_CYL_TRUE= + LIBCCD_CYL_CYL_FALSE='#' +else + LIBCCD_CYL_CYL_TRUE='#' + LIBCCD_CYL_CYL_FALSE= +fi + + if test x$col_capsule_cylinder = xlibccd; then + LIBCCD_CAP_CYL_TRUE= + LIBCCD_CAP_CYL_FALSE='#' +else + LIBCCD_CAP_CYL_TRUE='#' + LIBCCD_CAP_CYL_FALSE= +fi + + if test x$col_convex_box = xlibccd; then + LIBCCD_CONVEX_BOX_TRUE= + LIBCCD_CONVEX_BOX_FALSE='#' +else + LIBCCD_CONVEX_BOX_TRUE='#' + LIBCCD_CONVEX_BOX_FALSE= +fi + + if test x$col_convex_capsule = xlibccd; then + LIBCCD_CONVEX_CAP_TRUE= + LIBCCD_CONVEX_CAP_FALSE='#' +else + LIBCCD_CONVEX_CAP_TRUE='#' + LIBCCD_CONVEX_CAP_FALSE= +fi + + if test x$col_convex_cylinder = xlibccd; then + LIBCCD_CONVEX_CYL_TRUE= + LIBCCD_CONVEX_CYL_FALSE='#' +else + LIBCCD_CONVEX_CYL_TRUE='#' + LIBCCD_CONVEX_CYL_FALSE= +fi + + if test x$col_convex_sphere = xlibccd; then + LIBCCD_CONVEX_SPHERE_TRUE= + LIBCCD_CONVEX_SPHERE_FALSE='#' +else + LIBCCD_CONVEX_SPHERE_TRUE='#' + LIBCCD_CONVEX_SPHERE_FALSE= +fi + + if test x$col_convex_convex = xlibccd; then + LIBCCD_CONVEX_CONVEX_TRUE= + LIBCCD_CONVEX_CONVEX_FALSE='#' +else + LIBCCD_CONVEX_CONVEX_TRUE='#' + LIBCCD_CONVEX_CONVEX_FALSE= +fi + + + + +# Check whether --enable-asserts was given. +if test "${enable_asserts+set}" = set; then : + enableval=$enable_asserts; asserts=$enableval +else + asserts=yes +fi + +if test x$asserts = xno +then + CPPFLAGS="$CPPFLAGS -DdNODEBUG -DNDEBUG" +fi + + + + + +ac_config_files="$ac_config_files Makefile drawstuff/Makefile drawstuff/src/Makefile drawstuff/dstest/Makefile include/Makefile include/drawstuff/Makefile include/ode/Makefile include/ode/version.h include/ode/precision.h ode/Makefile ode/doc/Doxyfile ode/doc/Makefile ode/src/Makefile ode/src/joints/Makefile ode/demo/Makefile OPCODE/Makefile OPCODE/Ice/Makefile GIMPACT/Makefile GIMPACT/include/Makefile GIMPACT/include/GIMPACT/Makefile GIMPACT/src/Makefile tests/Makefile tests/joints/Makefile tests/UnitTest++/Makefile tests/UnitTest++/src/Makefile tests/UnitTest++/src/Posix/Makefile tests/UnitTest++/src/Win32/Makefile ode-config ode.pc" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +if test -z "${HAVE_DOXYGEN_TRUE}" && test -z "${HAVE_DOXYGEN_FALSE}"; then + as_fn_error $? "conditional \"HAVE_DOXYGEN\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${X86_64_SYSTEM_TRUE}" && test -z "${X86_64_SYSTEM_FALSE}"; then + as_fn_error $? "conditional \"X86_64_SYSTEM\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${OPCODE_TRUE}" && test -z "${OPCODE_FALSE}"; then + as_fn_error $? "conditional \"OPCODE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${GIMPACT_TRUE}" && test -z "${GIMPACT_FALSE}"; then + as_fn_error $? "conditional \"GIMPACT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${TRIMESH_TRUE}" && test -z "${TRIMESH_FALSE}"; then + as_fn_error $? "conditional \"TRIMESH\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${WIN32_TRUE}" && test -z "${WIN32_FALSE}"; then + as_fn_error $? "conditional \"WIN32\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${X11_TRUE}" && test -z "${X11_FALSE}"; then + as_fn_error $? "conditional \"X11\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${OSX_TRUE}" && test -z "${OSX_FALSE}"; then + as_fn_error $? "conditional \"OSX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ENABLE_DRAWSTUFF_TRUE}" && test -z "${ENABLE_DRAWSTUFF_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_DRAWSTUFF\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ENABLE_DEMOS_TRUE}" && test -z "${ENABLE_DEMOS_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_DEMOS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ENABLE_OU_TRUE}" && test -z "${ENABLE_OU_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_OU\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${LIBCCD_TRUE}" && test -z "${LIBCCD_FALSE}"; then + as_fn_error $? "conditional \"LIBCCD\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${LIBCCD_INTERNAL_TRUE}" && test -z "${LIBCCD_INTERNAL_FALSE}"; then + as_fn_error $? "conditional \"LIBCCD_INTERNAL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${LIBCCD_BOX_CYL_TRUE}" && test -z "${LIBCCD_BOX_CYL_FALSE}"; then + as_fn_error $? "conditional \"LIBCCD_BOX_CYL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${LIBCCD_CYL_CYL_TRUE}" && test -z "${LIBCCD_CYL_CYL_FALSE}"; then + as_fn_error $? "conditional \"LIBCCD_CYL_CYL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${LIBCCD_CAP_CYL_TRUE}" && test -z "${LIBCCD_CAP_CYL_FALSE}"; then + as_fn_error $? "conditional \"LIBCCD_CAP_CYL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${LIBCCD_CONVEX_BOX_TRUE}" && test -z "${LIBCCD_CONVEX_BOX_FALSE}"; then + as_fn_error $? "conditional \"LIBCCD_CONVEX_BOX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${LIBCCD_CONVEX_CAP_TRUE}" && test -z "${LIBCCD_CONVEX_CAP_FALSE}"; then + as_fn_error $? "conditional \"LIBCCD_CONVEX_CAP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${LIBCCD_CONVEX_CYL_TRUE}" && test -z "${LIBCCD_CONVEX_CYL_FALSE}"; then + as_fn_error $? "conditional \"LIBCCD_CONVEX_CYL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${LIBCCD_CONVEX_SPHERE_TRUE}" && test -z "${LIBCCD_CONVEX_SPHERE_FALSE}"; then + as_fn_error $? "conditional \"LIBCCD_CONVEX_SPHERE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${LIBCCD_CONVEX_CONVEX_TRUE}" && test -z "${LIBCCD_CONVEX_CONVEX_FALSE}"; then + as_fn_error $? "conditional \"LIBCCD_CONVEX_CONVEX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by ODE $as_me 0.16.1, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to <ode@ode.org>." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +ODE config.status 0.16.1 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' +configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' +predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' +postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' +predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' +postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' +LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' +reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' +reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' +GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' +inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' +link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' +always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' +exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' +predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' +postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' +predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' +postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in AS \ +DLLTOOL \ +OBJDUMP \ +SHELL \ +ECHO \ +PATH_SEPARATOR \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_import \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +lt_cv_nm_interface \ +nm_file_list_spec \ +lt_cv_truncate_bin \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib \ +compiler_lib_search_dirs \ +predep_objects \ +postdep_objects \ +predeps \ +postdeps \ +compiler_lib_search_path \ +LD_CXX \ +reload_flag_CXX \ +compiler_CXX \ +lt_prog_compiler_no_builtin_flag_CXX \ +lt_prog_compiler_pic_CXX \ +lt_prog_compiler_wl_CXX \ +lt_prog_compiler_static_CXX \ +lt_cv_prog_compiler_c_o_CXX \ +export_dynamic_flag_spec_CXX \ +whole_archive_flag_spec_CXX \ +compiler_needs_object_CXX \ +with_gnu_ld_CXX \ +allow_undefined_flag_CXX \ +no_undefined_flag_CXX \ +hardcode_libdir_flag_spec_CXX \ +hardcode_libdir_separator_CXX \ +exclude_expsyms_CXX \ +include_expsyms_CXX \ +file_list_spec_CXX \ +compiler_lib_search_dirs_CXX \ +predep_objects_CXX \ +postdep_objects_CXX \ +predeps_CXX \ +postdeps_CXX \ +compiler_lib_search_path_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +configure_time_dlsearch_path \ +configure_time_lt_sys_library_path \ +reload_cmds_CXX \ +old_archive_cmds_CXX \ +old_archive_from_new_cmds_CXX \ +old_archive_from_expsyms_cmds_CXX \ +archive_cmds_CXX \ +archive_expsym_cmds_CXX \ +module_cmds_CXX \ +module_expsym_cmds_CXX \ +export_symbols_cmds_CXX \ +prelink_cmds_CXX \ +postlink_cmds_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' + +# See if we are running on zsh, and set the options that allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + RM='$RM' + ofile='$ofile' + + + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "ode/src/config.h") CONFIG_HEADERS="$CONFIG_HEADERS ode/src/config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "drawstuff/Makefile") CONFIG_FILES="$CONFIG_FILES drawstuff/Makefile" ;; + "drawstuff/src/Makefile") CONFIG_FILES="$CONFIG_FILES drawstuff/src/Makefile" ;; + "drawstuff/dstest/Makefile") CONFIG_FILES="$CONFIG_FILES drawstuff/dstest/Makefile" ;; + "include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;; + "include/drawstuff/Makefile") CONFIG_FILES="$CONFIG_FILES include/drawstuff/Makefile" ;; + "include/ode/Makefile") CONFIG_FILES="$CONFIG_FILES include/ode/Makefile" ;; + "include/ode/version.h") CONFIG_FILES="$CONFIG_FILES include/ode/version.h" ;; + "include/ode/precision.h") CONFIG_FILES="$CONFIG_FILES include/ode/precision.h" ;; + "ode/Makefile") CONFIG_FILES="$CONFIG_FILES ode/Makefile" ;; + "ode/doc/Doxyfile") CONFIG_FILES="$CONFIG_FILES ode/doc/Doxyfile" ;; + "ode/doc/Makefile") CONFIG_FILES="$CONFIG_FILES ode/doc/Makefile" ;; + "ode/src/Makefile") CONFIG_FILES="$CONFIG_FILES ode/src/Makefile" ;; + "ode/src/joints/Makefile") CONFIG_FILES="$CONFIG_FILES ode/src/joints/Makefile" ;; + "ode/demo/Makefile") CONFIG_FILES="$CONFIG_FILES ode/demo/Makefile" ;; + "OPCODE/Makefile") CONFIG_FILES="$CONFIG_FILES OPCODE/Makefile" ;; + "OPCODE/Ice/Makefile") CONFIG_FILES="$CONFIG_FILES OPCODE/Ice/Makefile" ;; + "GIMPACT/Makefile") CONFIG_FILES="$CONFIG_FILES GIMPACT/Makefile" ;; + "GIMPACT/include/Makefile") CONFIG_FILES="$CONFIG_FILES GIMPACT/include/Makefile" ;; + "GIMPACT/include/GIMPACT/Makefile") CONFIG_FILES="$CONFIG_FILES GIMPACT/include/GIMPACT/Makefile" ;; + "GIMPACT/src/Makefile") CONFIG_FILES="$CONFIG_FILES GIMPACT/src/Makefile" ;; + "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; + "tests/joints/Makefile") CONFIG_FILES="$CONFIG_FILES tests/joints/Makefile" ;; + "tests/UnitTest++/Makefile") CONFIG_FILES="$CONFIG_FILES tests/UnitTest++/Makefile" ;; + "tests/UnitTest++/src/Makefile") CONFIG_FILES="$CONFIG_FILES tests/UnitTest++/src/Makefile" ;; + "tests/UnitTest++/src/Posix/Makefile") CONFIG_FILES="$CONFIG_FILES tests/UnitTest++/src/Posix/Makefile" ;; + "tests/UnitTest++/src/Win32/Makefile") CONFIG_FILES="$CONFIG_FILES tests/UnitTest++/src/Win32/Makefile" ;; + "ode-config") CONFIG_FILES="$CONFIG_FILES ode-config" ;; + "ode.pc") CONFIG_FILES="$CONFIG_FILES ode.pc" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' <conf$$subs.awk | sed ' +/^[^""]/{ + N + s/\n// +} +' >>$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' <confdefs.h | sed ' +s/'"$ac_delim"'/"\\\ +"/g' >>$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options that allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST + fi + + cfgfile=${ofile}T + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL +# Generated automatically by $as_me ($PACKAGE) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + +# Copyright (C) 2014 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool 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 2 of of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 <http://www.gnu.org/licenses/>. + + +# The names of the tagged configurations supported by this script. +available_tags='CXX ' + +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} + +# ### BEGIN LIBTOOL CONFIG + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Assembler program. +AS=$lt_AS + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Object dumper program. +OBJDUMP=$lt_OBJDUMP + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shared archive member basename,for filename based shared library versioning on AIX. +shared_archive_member_spec=$shared_archive_member_spec + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The PATH separator for the build system. +PATH_SEPARATOR=$lt_PATH_SEPARATOR + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm into a list of symbols to manually relocate. +global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# The name lister interface. +nm_interface=$lt_lt_cv_nm_interface + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and where our libraries should be installed. +lt_sysroot=$lt_sysroot + +# Command to truncate a binary pipe. +lt_truncate_bin=$lt_lt_cv_truncate_bin + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Detected run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path + +# Explicit LT_SYS_LIBRARY_PATH set during ./configure time. +configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects +postdep_objects=$lt_postdep_objects +predeps=$lt_predeps +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + +# ### END LIBTOOL CONFIG + +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + + +# ### END FUNCTIONS SHARED WITH CONFIGURE + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain=$ac_aux_dir/ltmain.sh + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + + cat <<_LT_EOF >> "$ofile" + +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# How to create reloadable object files. +reload_flag=$lt_reload_flag_CXX +reload_cmds=$lt_reload_cmds_CXX + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds_CXX + +# A language specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU compiler? +with_gcc=$GCC_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object_CXX + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld_CXX + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute_CXX + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath_CXX + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds_CXX + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds_CXX + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec_CXX + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects_CXX +postdep_objects=$lt_postdep_objects_CXX +predeps=$lt_predeps_CXX +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_CXX + +# ### END LIBTOOL TAG CONFIG: CXX +_LT_EOF + + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + +export OU_NAMESPACE=$OU_NAMESPACE +export OU_FEATURE_SET=$OU_FEATURE_SET + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi + +# +# CONFIG_SUBDIRS section. +# +if test "$no_recursion" != yes; then + + # Remove --cache-file, --srcdir, and --disable-option-checking arguments + # so they do not pile up. + ac_sub_configure_args= + ac_prev= + eval "set x $ac_configure_args" + shift + for ac_arg + do + if test -n "$ac_prev"; then + ac_prev= + continue + fi + case $ac_arg in + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \ + | --c=*) + ;; + --config-cache | -C) + ;; + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + ;; + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + ;; + --disable-option-checking) + ;; + *) + case $ac_arg in + *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append ac_sub_configure_args " '$ac_arg'" ;; + esac + done + + # Always prepend --prefix to ensure using the same prefix + # in subdir configurations. + ac_arg="--prefix=$prefix" + case $ac_arg in + *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + ac_sub_configure_args="'$ac_arg' $ac_sub_configure_args" + + # Pass --silent + if test "$silent" = yes; then + ac_sub_configure_args="--silent $ac_sub_configure_args" + fi + + # Always prepend --disable-option-checking to silence warnings, since + # different subdirs can have different --enable and --with options. + ac_sub_configure_args="--disable-option-checking $ac_sub_configure_args" + + ac_popdir=`pwd` + for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue + + # Do not complain, so a configure script can configure whichever + # parts of a large source tree are present. + test -d "$srcdir/$ac_dir" || continue + + ac_msg="=== configuring in $ac_dir (`pwd`/$ac_dir)" + $as_echo "$as_me:${as_lineno-$LINENO}: $ac_msg" >&5 + $as_echo "$ac_msg" >&6 + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + cd "$ac_dir" + + # Check for guested configure; otherwise get Cygnus style configure. + if test -f "$ac_srcdir/configure.gnu"; then + ac_sub_configure=$ac_srcdir/configure.gnu + elif test -f "$ac_srcdir/configure"; then + ac_sub_configure=$ac_srcdir/configure + elif test -f "$ac_srcdir/configure.in"; then + # This should be Cygnus configure. + ac_sub_configure=$ac_aux_dir/configure + else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: no configuration information is in $ac_dir" >&5 +$as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2;} + ac_sub_configure= + fi + + # The recursion is here. + if test -n "$ac_sub_configure"; then + # Make the cache file name correct relative to the subdirectory. + case $cache_file in + [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;; + *) # Relative name. + ac_sub_cache_file=$ac_top_build_prefix$cache_file ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5 +$as_echo "$as_me: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;} + # The eval makes quoting arguments work. + eval "\$SHELL \"\$ac_sub_configure\" $ac_sub_configure_args \ + --cache-file=\"\$ac_sub_cache_file\" --srcdir=\"\$ac_srcdir\"" || + as_fn_error $? "$ac_sub_configure failed for $ac_dir" "$LINENO" 5 + fi + + cd "$ac_popdir" + done +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + +chmod +x ode-config + +BUILDDIR=`pwd` + +echo "Configuration:" +echo " Build system type: $build" +echo " Host system type: $host" +echo " Use double precision: $usedouble" +echo " Use drawstuff: $drawstuff" +echo " Demos enabled: $enable_demos" +echo " Use OPCODE: $opcode" +echo " Use GIMPACT: $gimpact" +echo " Use libccd: $use_libccd" + +if test x$use_libccd = xyes +then +echo " libccd source: $libccd_source" +fi + +echo " Custom colliders:" +echo " cylinder-cylinder: $col_cylinder_cylinder" +echo " box-cylinder: $col_box_cylinder" +echo " capsule-cylinder: $col_capsule_cylinder" +echo " convex-box: $col_convex_box" +echo " convex-capsule: $col_convex_capsule" +echo " convex-cylinder: $col_convex_cylinder" +echo " convex-sphere: $col_convex_sphere" +echo " convex-convex: $col_convex_convex" +echo " Is target a Pentium: $pentium" +echo " Is target x86-64: $cpu64" +echo " Use old opcode trimesh collider: $old_trimesh" +echo " TLS for global caches: $use_ou_tls" +echo " Threading intf enabled: $threading_intf" +echo " Built-in threading included: $use_builtin_threading_impl" +echo " Enable debug error check: $asserts" +echo " Headers will be installed in $includedir/ode" +echo " Libraries will be installed in $libdir" +echo " Building in directory $BUILDDIR" + diff --git a/libs/ode-0.16.1/configure.ac b/libs/ode-0.16.1/configure.ac new file mode 100644 index 0000000..6ea9e7c --- /dev/null +++ b/libs/ode-0.16.1/configure.ac @@ -0,0 +1,605 @@ +dnl AC_INIT does not take a macro as a version nr: set it separately! - Bram +AC_INIT([ODE],[0.16.1],[ode@ode.org]) +ODE_VERSION=0.16.1 +AC_SUBST(ODE_VERSION) + +# Those are instructions from the Libtool manual: +# 1. Start with version information of `0:0:0' for each libtool library. +# +# 2. Update the version information only immediately before a public +# release of your software. More frequent updates are unnecessary, +# and only guarantee that the current interface number gets larger +# faster. +# +# 3. If the library source code has changed at all since the last +# update, then increment REVISION (`C:R:A' becomes `C:r+1:A'). +# +# 4. If any interfaces have been added, removed, or changed since the +# last update, increment CURRENT, and set REVISION to 0. +# +# 5. If any interfaces have been added since the last public release, +# then increment AGE. +# +# 6. If any interfaces have been removed since the last public release, +# then set AGE to 0. +CURRENT=8 +REVISION=1 +AGE=0 + +AC_ARG_ENABLE(version-info, + AS_HELP_STRING([--disable-version-info], + [don't encode version information in the generated library]), + version_info=$enableval, + version_info=yes) +if test x$version_info = xyes +then + ODE_VERSION_INFO="-version-info $CURRENT:$REVISION:$AGE" +else + ODE_VERSION_INFO="-avoid-version" +fi +AC_SUBST(ODE_VERSION_INFO) + + +AC_CONFIG_SRCDIR([ode/src/ode.cpp]) +AC_CONFIG_MACRO_DIR([m4]) + +AC_CANONICAL_HOST + +AM_INIT_AUTOMAKE([1.10 foreign]) +AC_CONFIG_HEADERS([ode/src/config.h]) + +dnl This is needed because we have subdirectories +AC_PROG_MAKE_SET +AC_PROG_CXX +AC_PROG_CC +AM_PROG_CC_C_O +AC_PROG_CPP +AC_PROG_AWK +AC_PROG_INSTALL +AC_PROG_LN_S +AC_PROG_MKDIR_P +LT_INIT([disable-shared win32-dll]) +AC_CHECK_TOOLS([WINDRES], [windres]) + +AC_C_BIGENDIAN +AC_C_INLINE +AC_C_VOLATILE +PKG_PROG_PKG_CONFIG + +AC_ARG_VAR([DOXYGEN], [set to doxygen binary to generate doxygen docs]) +AC_CHECK_PROGS([DOXYGEN], [doxygen]) +AM_CONDITIONAL([HAVE_DOXYGEN], [test x$DOXYGEN = xdoxygen]) + + +dnl this may NOT be the machine on which the code is going to run in, +dnl so allow users to compile programs for their target machine. +pentium=no +cpu64=no +case "$host_cpu" in + i586 | i686 | i786 ) + pentium=yes + AC_DEFINE(PENTIUM,1,[compiling for a pentium on a gcc-based platform?]) + ;; + x86_64* ) + pentium=yes + cpu64=yes + AC_DEFINE(X86_64_SYSTEM,1,[compiling for a X86_64 system on a gcc-based platform?]) + ;; +esac + +AM_CONDITIONAL(X86_64_SYSTEM, test x$cpu64 = xyes) + + + + + + +dnl check for required headers +AC_CHECK_HEADERS( [alloca.h stdio.h inttypes.h stdint.h stdlib.h math.h \ + string.h stdarg.h malloc.h float.h time.h sys/time.h \ + limits.h stddef.h]) + + +opcode=no +gimpact=no +AC_ARG_WITH(trimesh, AS_HELP_STRING([--with-trimesh=@<:@opcode|gimpact|none@:>@], + [use the specified system for trimesh support @<:@default=opcode@:>@]), + trimesh=$withval,trimesh=opcode +) +if test "$trimesh" = opcode +then + opcode=yes +fi +if test "$trimesh" = gimpact +then + gimpact=yes +fi + +AM_CONDITIONAL(OPCODE, test $opcode = yes) +AM_CONDITIONAL(GIMPACT, test $gimpact = yes) +AM_CONDITIONAL(TRIMESH, test $opcode = yes -o $gimpact = yes) + + +AC_MSG_CHECKING(if double precision is requested) +AC_ARG_ENABLE(double-precision, + AS_HELP_STRING([--enable-double-precision], + [Configure ODE to work with double precision, if not specified, single precision is used @<:@default=no@:>@]), + usedouble=$enableval,usedouble=no) +AC_MSG_RESULT([$usedouble]) +if test "$usedouble" = yes; +then + ODE_PRECISION=dDOUBLE +else + ODE_PRECISION=dSINGLE +fi +AC_SUBST(ODE_PRECISION) + + +AC_ARG_WITH([drawstuff], + AS_HELP_STRING([--with-drawstuff=X11|Win32|OSX|none], + [force a particular drawstuff implementation or disable it.[default=autodetect]]), + [drawstuff=$withval],[drawstuff=]) + +dnl Set some Platform Specific Variables +EXTRA_LIBTOOL_LDFLAGS= +case "$host_os" in + cygwin* | mingw*) + if test "x$drawstuff" = x + then + drawstuff="Win32" # if in a Windows enviroment + fi + EXTRA_LIBTOOL_LDFLAGS="-no-undefined" + ;; + *apple* | *darwin*) # For Mac OS X + if test "x$drawstuff" = x + then + drawstuff="OSX" + fi + dnl We need to use C++ compilation and linking for ode on Mac + dnl Might as well do it for all code. + CC="$CXX" + LINK="$CXXLINK" + ;; + *) + if test "x$drawstuff" = x + then + drawstuff="X11" # if anything else default to X11 + fi + ;; +esac +AC_SUBST(EXTRA_LIBTOOL_LDFLAGS) + + +dnl Set Drawstuff variables +AC_MSG_CHECKING([which drawstuff lib to build]) +AC_MSG_RESULT($drawstuff) + +if test "x$drawstuff" = "xX11" +then + # The built-in macro, X_PATH, causes too many problems, these days everyone uses Xorg, + # so we can ask pkg-config to find it for us. + PKG_CHECK_MODULES(X11, x11, [], [drawstuff="none"]) +fi + +dnl Check for OpenGL +if test "x$drawstuff" = "xOSX"; then + AC_DEFINE([HAVE_APPLE_OPENGL_FRAMEWORK], [1], + [Use the Apple OpenGL framework.]) + GL_LIBS="-framework OpenGL -framework GLUT" +elif test "x$drawstuff" != "xnone"; then + have_gl_headers=yes + AC_CHECK_HEADERS(GL/gl.h GL/glu.h GL/glext.h, , + [have_gl_headers=no], + [[#ifdef WIN32 + #include <windows.h> + #endif + #if HAVE_GL_GL_H + #include <GL/gl.h> + #endif + #if HAVE_GL_GLU_H + #include <GL/glu.h> + #endif + ]]) + have_gl=no + have_glu=no + TEMP_LDFLAGS="$LDFLAGS" + AC_CHECK_LIB(GL, main, [GL_LIBS="-lGL"; have_gl=yes]) + AC_CHECK_LIB(GLU, main, [GL_LIBS="-lGLU $GL_LIBS"; have_glu=yes], , -lGL) + AC_CHECK_LIB(opengl32, main, [GL_LIBS="-lopengl32"; have_gl=yes]) + AC_CHECK_LIB(glu32, main, [GL_LIBS="-lglu32 $GL_LIBS"; have_glu=yes], , -lopengl32) + LDFLAGS="$TEMP_LDFLAGS" + if test $have_gl = no -o $have_glu = no -o $have_gl_headers = no; then + drawstuff="none" + fi +fi +AC_SUBST(GL_LIBS) + +dnl Set Conditionals +AM_CONDITIONAL(WIN32, test x$drawstuff = xWin32) +AM_CONDITIONAL(X11, test x$drawstuff = xX11) +AM_CONDITIONAL(OSX, test x$drawstuff = xOSX) +AM_CONDITIONAL(ENABLE_DRAWSTUFF, test x$drawstuff != xnone) + +dnl Check if we want to build demos +AC_MSG_CHECKING(if demos should be built) +AC_ARG_ENABLE(demos, + AS_HELP_STRING([--disable-demos], [don't build demos]), + enable_demos=$enableval,enable_demos=yes) +if test x$drawstuff = xnone -a x$enable_demos = xyes ; then + enable_demos=no + AC_MSG_RESULT($enable_demos) + AC_MSG_WARN([Demos will not be built because OpenGL doesn't seem to work. See `config.log' for details.]) +else + AC_MSG_RESULT($enable_demos) +fi + + +dnl stdc++ is required when linking C programs against ode +AC_CHECK_LIB(stdc++,main,[LIBSTDCXX="-lstdc++"],[LIBSTDCXX=]) +AC_SUBST(LIBSTDCXX) +AC_CHECK_LIB(pthread,main,[LIBS="$LIBS -lpthread"]) + + +dnl test if we will build demos +AM_CONDITIONAL(ENABLE_DEMOS, test x$enable_demos = xyes) + + +dnl Check if the user wants the old timesh collider +old_trimesh=no +AC_ARG_ENABLE([old-trimesh], AS_HELP_STRING([--enable-old-trimesh],[enable use of the old trimesh collider]), + [old_trimesh=$enableval] + ) +if test x$old_trimesh = xyes -a $trimesh = opcode; then + AC_DEFINE(dTRIMESH_OPCODE_USE_OLD_TRIMESH_TRIMESH_COLLIDER, 1, + [Use the old trimesh-trimesh collider]) +else + old_trimesh=no +fi + + +dnl Check if the user wants to profile ODE using gprof +AC_MSG_CHECKING(for gprof) +AC_ARG_ENABLE([gprof], + AS_HELP_STRING([--enable-gprof],[enable profiling with gprof]), + gprof=$enableval, + gprof=no) +if test "$gprof" != no +then + CFLAGS="-pg $CFLAGS" + CXXFLAGS="-pg $CXXFLAGS" + AC_MSG_RESULT(enabled) + AC_CHECK_LIB(gmon, main,[LIBS="$LIBS -lgmon"]) +else + AC_MSG_RESULT(no) +fi + +# Checks for typedefs, structures, and compiler characteristics. +AC_HEADER_STDBOOL +AC_C_INLINE +AC_TYPE_INT32_T +AC_FUNC_OBSTACK +AC_TYPE_SIZE_T +AC_TYPE_UINT32_T + +dnl Check for autoscan sugested functions +AC_CHECK_LIB(m, [main]) +AC_CHECK_LIB(sunmath, [main]) +AC_CHECK_LIB(rt, [main]) +AC_CHECK_FUNCS([atan2f clock_gettime copysign copysignf cosf fabsf floor fmodf gettimeofday isnan _isnan __isnan isnanf _isnanf __isnanf memmove memset pthread_attr_setstacklazy pthread_attr_setinheritsched pthread_condattr_setclock sinf snprintf sqrt sqrtf strchr strstr vsnprintf]) +AC_FUNC_ALLOCA + +dnl This trick allows having additional define in case if a function is not found. +dnl It fakes cached value for an inexistent function which is then used to fool function check to produce desired result. +AC_CHECK_FUNC(pthread_condattr_setclock,,ac_cv_func_no_pthread_condattr_setclock=yes) +AC_CHECK_FUNCS(no_pthread_condattr_setclock) + + +AC_ARG_ENABLE([threading-intf], + AS_HELP_STRING([--disable-threading-intf], + [disable threading interface support (external implementations cannot be assigned)] + ), + threading_intf=$enableval,threading_intf=yes) +AC_ARG_ENABLE([ou], + AS_HELP_STRING([--enable-ou], + [use TLS for global caches (allows threaded collision checks for isolated spaces)] + ), + use_ou_tls=$enableval,use_ou_tls=no) +use_ou="no" +if test x$use_ou_tls = xyes -o x$threading_intf = xyes +then + use_ou="yes" +fi + +OU_NAMESPACE=odeou +AC_CONFIG_COMMANDS_POST([export OU_NAMESPACE=$OU_NAMESPACE]) +AC_DEFINE([_OU_NAMESPACE],[odeou],[libou namespace for ODE]) +AC_DEFINE([dOU_ENABLED],[1],[Generic OU features are enabled]) + +if test x$use_ou_tls = xyes +then + OU_FEATURE_SET=_OU_FEATURE_SET_TLS + AC_DEFINE([_OU_FEATURE_SET],[_OU_FEATURE_SET_TLS],[OU features enabled]) +elif test x$use_ou = xyes +then + OU_FEATURE_SET=_OU_FEATURE_SET_ATOMICS + AC_DEFINE([_OU_FEATURE_SET],[_OU_FEATURE_SET_ATOMICS],[OU features enabled]) +else + OU_FEATURE_SET=_OU_FEATURE_SET_BASICS + AC_DEFINE([_OU_FEATURE_SET],[_OU_FEATURE_SET_BASICS],[OU features enabled]) +fi +AC_CONFIG_COMMANDS_POST([export OU_FEATURE_SET=$OU_FEATURE_SET]) + +if test x$use_ou = xyes +then + AC_DEFINE([dATOMICS_ENABLED],[1],[Atomic API of OU is enabled]) + if test x$use_ou_tls = xyes + then + AC_DEFINE([dTLS_ENABLED],[1],[Thread Local Storage API of OU is enabled]) + fi +fi + +case "$host_os" in + cygwin* | mingw*) + targetos=_OU_TARGET_OS_WINDOWS + ;; + *qnx*) + targetos=_OU_TARGET_OS_QNX + ;; + *apple* | *darwin*) + targetos=_OU_TARGET_OS_MAC + ;; + *sunos*) + targetos=_OU_TARGET_OS_SUNOS + ;; + *aix*) + targetos=_OU_TARGET_OS_AIX + ;; + *) + targetos=_OU_TARGET_OS_GENUNIX + ;; +esac + +if test $targetos = _OU_TARGET_OS_MAC +then + MAC_OS_X_VERSION=1000 + AC_CHECK_FUNC([OSAtomicAdd32Barrier], [MAC_OS_X_VERSION=1040]) + AC_CHECK_FUNC([OSAtomicAnd32OrigBarrier], [MAC_OS_X_VERSION=1050]) + AC_DEFINE_UNQUOTED(MAC_OS_X_VERSION, $MAC_OS_X_VERSION, [Mac OS X version setting for OU Library]) +fi + +if test $targetos = _OU_TARGET_OS_SUNOS +then + AC_CHECK_FUNC(atomic_inc_32_nv, [], + [targetos=_OU_TARGET_OS_GENUNIX]) +fi + +AC_DEFINE_UNQUOTED(_OU_TARGET_OS, $targetos, [Target OS setting for OU Library]) + +AC_CONFIG_SUBDIRS([ou]) +AM_CONDITIONAL(ENABLE_OU, true) + +if test x$threading_intf = xyes +then + AC_ARG_ENABLE([builtin-threading-impl], + AS_HELP_STRING([--disable-builtin-threading-impl], + [disable built-in multithreaded threading implementation] + ), + use_builtin_threading_impl=$enableval,use_builtin_threading_impl=yes) + if test x$use_builtin_threading_impl = xyes + then + AC_DEFINE([dBUILTIN_THREADING_IMPL_ENABLED],[1],[Built-in multithreaded threading implementation is included]) + fi +else + AC_DEFINE([dTHREADING_INTF_DISABLED],[1],[Threading interface is disabled]) + use_builtin_threading_impl=no +fi + +col_cylinder_cylinder=none +col_box_cylinder=default +col_capsule_cylinder=none +col_convex_box=none +col_convex_capsule=none +col_convex_cylinder=none +col_convex_sphere=default +col_convex_convex=default + + +use_libccd=no +libccd_all=no +AC_ARG_ENABLE(libccd, AS_HELP_STRING([--enable-libccd], + [enable all libccd colliders (except box-cylinder)]), + libccd_all=$enableval) +if test x$libccd_all = xyes +then + col_cylinder_cylinder=libccd + col_capsule_cylinder=libccd + col_convex_box=libccd + col_convex_capsule=libccd + col_convex_cylinder=libccd + col_convex_sphere=libccd + col_convex_convex=libccd + use_libccd=yes +fi + + +AC_ARG_WITH([cylinder-cylinder], AS_HELP_STRING([--with-cylinder-cylinder=@<:@none,libccd@:>@], [use specific collider for cylinder-cylinder]), + col_cylinder_cylinder=$withval) + +AC_ARG_WITH([box-cylinder], + AS_HELP_STRING([--with-box-cylinder=@<:@default,libccd@:>@], [use specific collider for box-cylinder]), + col_box_cylinder=$withval) + +AC_ARG_WITH([capsule-cylinder], AS_HELP_STRING([--with-capsule-cylinder=@<:@none,libccd@:>@], [use specific collider for capsule-cylinder]), + col_capsule_cylinder=$withval) + +AC_ARG_WITH([convex-box], AS_HELP_STRING([--with-convex-box=@<:@none,libccd@:>@], [use specific collider for convex-box]), + col_convex_box=$withval) + +AC_ARG_WITH([convex-capsule], AS_HELP_STRING([--with-convex-capsule=@<:@none,libccd@:>@], [use specific collider for convex-capsule]), + col_convex_capsule=$withval) + +AC_ARG_WITH([convex-cylinder], AS_HELP_STRING([--with-convex-cylinder=@<:@none,libccd@:>@], [use specific collider for convex-cylinder]), + col_convex_cylinder=$withval) + +AC_ARG_WITH([convex-sphere], AS_HELP_STRING([--with-convex-sphere=@<:@default,libccd@:>@], [use specific collider for convex-sphere]), + col_convex_sphere=$withval) + +AC_ARG_WITH([convex-convex], AS_HELP_STRING([--with-convex-convex=@<:@default,libccd@:>@], [use specific collider for convex-convex]), + col_convex_convex=$withval) + +if test x$col_cylinder_cylinder = xlibccd -o \ + x$col_box_cylinder = xlibccd -o \ + x$col_capsule_cylinder = xlibccd -o \ + x$col_convex_box = xlibccd -o \ + x$col_convex_capsule = libccd -o \ + x$col_convex_cylinder = xlibccd -o \ + x$col_convex_sphere = libccd -o \ + x$col_convex_convex = libccd +then + use_libccd=yes +fi + + +libccd_source=internal + +AC_ARG_WITH(libccd, + [AS_HELP_STRING([--with-libccd=@<:@internal|system@:>@], + [use the specified libccd @<:@default=system@:>@])], + [libccd_source=$withval], + [libccd_source=system]) + +if test x$use_libccd = xyes +then + if test x$libccd_source = xsystem + then + PKG_CHECK_MODULES(CCD, ccd, ,[libccd_source=internal]) + fi +fi + +# Configure libccd unconditionally as that may be needed for special make targets +AC_CONFIG_SUBDIRS([libccd]) + +AM_CONDITIONAL(LIBCCD, test x$use_libccd != xno) +AM_CONDITIONAL(LIBCCD_INTERNAL, test x$libccd_source = xinternal) +AM_CONDITIONAL(LIBCCD_BOX_CYL, test x$col_box_cylinder = xlibccd) +AM_CONDITIONAL(LIBCCD_CYL_CYL, test x$col_cylinder_cylinder = xlibccd) +AM_CONDITIONAL(LIBCCD_CAP_CYL, test x$col_capsule_cylinder = xlibccd) +AM_CONDITIONAL(LIBCCD_CONVEX_BOX, test x$col_convex_box = xlibccd) +AM_CONDITIONAL(LIBCCD_CONVEX_CAP, test x$col_convex_capsule = xlibccd) +AM_CONDITIONAL(LIBCCD_CONVEX_CYL, test x$col_convex_cylinder = xlibccd) +AM_CONDITIONAL(LIBCCD_CONVEX_SPHERE, test x$col_convex_sphere = xlibccd) +AM_CONDITIONAL(LIBCCD_CONVEX_CONVEX, test x$col_convex_convex = xlibccd) + + + +AC_ARG_ENABLE([asserts], + AS_HELP_STRING([--disable-asserts], + [disables debug error checking]), + asserts=$enableval,asserts=yes) +if test x$asserts = xno +then + CPPFLAGS="$CPPFLAGS -DdNODEBUG -DNDEBUG" +fi + + +dnl include found system headers into config.h +AH_TOP([ +#ifndef ODE_CONFIG_H +#define ODE_CONFIG_H +]) +AH_BOTTOM([ + +#ifdef HAVE_ALLOCA_H +#include <alloca.h> +#endif +#ifdef HAVE_MALLOC_H +#include <malloc.h> +#endif +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif +#ifdef HAVE_INTTYPES_H +#include <inttypes.h> +#endif + + +#include "typedefs.h" + + +#endif /* #define ODE_CONFIG_H */ +]) + +dnl Finally write our Makefiles +AC_CONFIG_FILES([ + Makefile + drawstuff/Makefile + drawstuff/src/Makefile + drawstuff/dstest/Makefile + include/Makefile + include/drawstuff/Makefile + include/ode/Makefile + include/ode/version.h + include/ode/precision.h + ode/Makefile + ode/doc/Doxyfile + ode/doc/Makefile + ode/src/Makefile + ode/src/joints/Makefile + ode/demo/Makefile + OPCODE/Makefile + OPCODE/Ice/Makefile + GIMPACT/Makefile + GIMPACT/include/Makefile + GIMPACT/include/GIMPACT/Makefile + GIMPACT/src/Makefile + tests/Makefile + tests/joints/Makefile + tests/UnitTest++/Makefile + tests/UnitTest++/src/Makefile + tests/UnitTest++/src/Posix/Makefile + tests/UnitTest++/src/Win32/Makefile + ode-config + ode.pc + ]) +AC_OUTPUT + +chmod +x ode-config + +BUILDDIR=`pwd` + +dnl Print some useful information +echo "Configuration:" +echo " Build system type: $build" +echo " Host system type: $host" +echo " Use double precision: $usedouble" +echo " Use drawstuff: $drawstuff" +echo " Demos enabled: $enable_demos" +echo " Use OPCODE: $opcode" +echo " Use GIMPACT: $gimpact" +echo " Use libccd: $use_libccd" + +if test x$use_libccd = xyes +then +echo " libccd source: $libccd_source" +fi + +echo " Custom colliders:" +echo " cylinder-cylinder: $col_cylinder_cylinder" +echo " box-cylinder: $col_box_cylinder" +echo " capsule-cylinder: $col_capsule_cylinder" +echo " convex-box: $col_convex_box" +echo " convex-capsule: $col_convex_capsule" +echo " convex-cylinder: $col_convex_cylinder" +echo " convex-sphere: $col_convex_sphere" +echo " convex-convex: $col_convex_convex" +echo " Is target a Pentium: $pentium" +echo " Is target x86-64: $cpu64" +echo " Use old opcode trimesh collider: $old_trimesh" +echo " TLS for global caches: $use_ou_tls" +echo " Threading intf enabled: $threading_intf" +echo " Built-in threading included: $use_builtin_threading_impl" +echo " Enable debug error check: $asserts" +echo " Headers will be installed in $includedir/ode" +echo " Libraries will be installed in $libdir" +echo " Building in directory $BUILDDIR" + diff --git a/libs/ode-0.16.1/depcomp b/libs/ode-0.16.1/depcomp new file mode 100755 index 0000000..fc98710 --- /dev/null +++ b/libs/ode-0.16.1/depcomp @@ -0,0 +1,791 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2013-05-30.07; # UTC + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. + +# 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 2, 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 <http://www.gnu.org/licenses/>. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>. + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to <bug-automake@gnu.org>. +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Avoid interferences from the environment. +gccflag= dashmflag= + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The second -e expression handles DOS-style file names with drive + # letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the "deleted header file" problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. +## Some versions of gcc put a space before the ':'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like '#:fec' to the end of the + # dependency line. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" + echo >> "$depfile" + # The second pass generates a dummy entry for each header file. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" + ;; + +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts '$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + aix_post_process_depfile + ;; + +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\' : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi + + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" + + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + echo >> "$depfile" # make sure the fragment doesn't end with a backslash + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for ':' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. + "$@" $dashmflag | + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/libs/ode-0.16.1/drawstuff/Makefile.am b/libs/ode-0.16.1/drawstuff/Makefile.am new file mode 100644 index 0000000..def863c --- /dev/null +++ b/libs/ode-0.16.1/drawstuff/Makefile.am @@ -0,0 +1,4 @@ +if ENABLE_DRAWSTUFF +SUBDIRS = src dstest +EXTRA_DIST = textures +endif diff --git a/libs/ode-0.16.1/drawstuff/Makefile.in b/libs/ode-0.16.1/drawstuff/Makefile.in new file mode 100644 index 0000000..a57e158 --- /dev/null +++ b/libs/ode-0.16.1/drawstuff/Makefile.in @@ -0,0 +1,641 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = drawstuff +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ode/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = src dstest +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_CFLAGS = @CCD_CFLAGS@ +CCD_LIBS = @CCD_LIBS@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSTDCXX = @LIBSTDCXX@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ODE_PRECISION = @ODE_PRECISION@ +ODE_VERSION = @ODE_VERSION@ +ODE_VERSION_INFO = @ODE_VERSION_INFO@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +@ENABLE_DRAWSTUFF_TRUE@SUBDIRS = src dstest +@ENABLE_DRAWSTUFF_TRUE@EXTRA_DIST = textures +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign drawstuff/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign drawstuff/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/drawstuff/dstest/Makefile.am b/libs/ode-0.16.1/drawstuff/dstest/Makefile.am new file mode 100644 index 0000000..cf7550c --- /dev/null +++ b/libs/ode-0.16.1/drawstuff/dstest/Makefile.am @@ -0,0 +1,14 @@ +noinst_PROGRAMS= dstest +AM_CPPFLAGS = -I$(top_srcdir)/drawstuff/src -I$(top_srcdir)/include + +dstest_SOURCES= dstest.cpp +dstest_LDADD=$(top_builddir)/drawstuff/src/libdrawstuff.la \ + @GL_LIBS@ + +if WIN32 +resources.o: $(top_srcdir)/drawstuff/src/resources.rc $(top_srcdir)/drawstuff/src/resource.h + $(WINDRES) $(top_srcdir)/drawstuff/src/resources.rc -o resources.o + +dstest_LDADD += resources.o +endif + diff --git a/libs/ode-0.16.1/drawstuff/dstest/Makefile.in b/libs/ode-0.16.1/drawstuff/dstest/Makefile.in new file mode 100644 index 0000000..e043d07 --- /dev/null +++ b/libs/ode-0.16.1/drawstuff/dstest/Makefile.in @@ -0,0 +1,614 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +noinst_PROGRAMS = dstest$(EXEEXT) +@WIN32_TRUE@am__append_1 = resources.o +subdir = drawstuff/dstest +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ode/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +PROGRAMS = $(noinst_PROGRAMS) +am_dstest_OBJECTS = dstest.$(OBJEXT) +dstest_OBJECTS = $(am_dstest_OBJECTS) +dstest_DEPENDENCIES = $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(am__append_1) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +SOURCES = $(dstest_SOURCES) +DIST_SOURCES = $(dstest_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_CFLAGS = @CCD_CFLAGS@ +CCD_LIBS = @CCD_LIBS@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSTDCXX = @LIBSTDCXX@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ODE_PRECISION = @ODE_PRECISION@ +ODE_VERSION = @ODE_VERSION@ +ODE_VERSION_INFO = @ODE_VERSION_INFO@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = -I$(top_srcdir)/drawstuff/src -I$(top_srcdir)/include +dstest_SOURCES = dstest.cpp +dstest_LDADD = $(top_builddir)/drawstuff/src/libdrawstuff.la @GL_LIBS@ \ + $(am__append_1) +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign drawstuff/dstest/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign drawstuff/dstest/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +dstest$(EXEEXT): $(dstest_OBJECTS) $(dstest_DEPENDENCIES) $(EXTRA_dstest_DEPENDENCIES) + @rm -f dstest$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(dstest_OBJECTS) $(dstest_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dstest.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstPROGRAMS cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +@WIN32_TRUE@resources.o: $(top_srcdir)/drawstuff/src/resources.rc $(top_srcdir)/drawstuff/src/resource.h +@WIN32_TRUE@ $(WINDRES) $(top_srcdir)/drawstuff/src/resources.rc -o resources.o + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/drawstuff/dstest/dstest.cpp b/libs/ode-0.16.1/drawstuff/dstest/dstest.cpp new file mode 100644 index 0000000..27f042f --- /dev/null +++ b/libs/ode-0.16.1/drawstuff/dstest/dstest.cpp @@ -0,0 +1,125 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <stdio.h> +#include <math.h> +#include <drawstuff/drawstuff.h> + + +#ifndef M_PI +#define M_PI (3.14159265358979323846) +#endif + + +void start() +{ + // adjust the starting viewpoint a bit + float xyz[3],hpr[3]; + dsGetViewpoint (xyz,hpr); + hpr[0] += 7; + dsSetViewpoint (xyz,hpr); +} + + +void simLoop (int pause) +{ + float pos[3]; + float R[12]; + static float a = 0; + + if (!pause) a += 0.02f; + if (a > (2*M_PI)) a -= (float) (2*M_PI); + float ca = (float) cos(a); + float sa = (float) sin(a); + + dsSetTexture (DS_WOOD); + + float b = (a > M_PI) ? (2*(a-(float)M_PI)) : a*2; + pos[0] = -0.3f; + pos[1] = 0; + pos[2] = (float) (0.1f*(2*M_PI*b - b*b) + 0.65f); + R[0] = ca; R[1] = 0; R[2] = -sa; + R[4] = 0; R[5] = 1; R[6] = 0; + R[8] = sa; R[9] = 0; R[10] = ca; + dsSetColor (1,0.8f,0.6f); + dsDrawSphere (pos,R,0.3f); + + dsSetTexture (DS_NONE); + + pos[0] = -0.2f; + pos[1] = 0.8f; + pos[2] = 0.4f; + R[0] = ca; R[1] = -sa; R[2] = 0; + R[4] = sa; R[5] = ca; R[6] = 0; + R[8] = 0; R[9] = 0; R[10] = 1; + float sides[3] = {0.1f,0.4f,0.8f}; + dsSetColor (0.6f,0.6f,1); + dsDrawBox (pos,R,sides); + + dsSetTexture (DS_WOOD); + + float r = 0.3f; // cylinder radius + float d = (float)cos(a*2) * 0.4f; + float cd = (float)cos(-d/r); + float sd = (float)sin(-d/r); + pos[0] = -0.2f; + pos[1] = -1 + d; + pos[2] = 0.3f; + R[0] = 0; R[1] = 0; R[2] = -1; + R[4] = -sd; R[5] = cd; R[6] = 0; + R[8] = cd; R[9] = sd; R[10] = 0; + dsSetColor (0.4f,1,1); + dsDrawCylinder (pos,R,0.8f,r); + + pos[0] = 0; + pos[1] = 0; + pos[2] = 0.2f; + R[0] = 0; R[1] = sa; R[2] = -ca; + R[4] = 0; R[5] = ca; R[6] = sa; + R[8] = 1; R[9] = 0; R[10] = 0; + dsSetColor (1,0.9f,0.2f); + dsDrawCappedCylinder (pos,R,0.8f,0.2f); +} + + +void command (int cmd) +{ + dsPrint ("received command %d (`%c')\n",cmd,cmd); +} + + +int main (int argc, char **argv) +{ + // setup pointers to callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = command; + fn.stop = 0; + fn.path_to_textures = 0; // uses default + + // run simulation + dsSimulationLoop (argc,argv,400,400,&fn); + + return 0; +} diff --git a/libs/ode-0.16.1/drawstuff/src/Makefile.am b/libs/ode-0.16.1/drawstuff/src/Makefile.am new file mode 100644 index 0000000..911f4fd --- /dev/null +++ b/libs/ode-0.16.1/drawstuff/src/Makefile.am @@ -0,0 +1,26 @@ +# Drawstuff is meant as an aid for testing and not as a full +# rendering library. + +noinst_LTLIBRARIES = libdrawstuff.la +libdrawstuff_la_SOURCES = drawstuff.cpp internal.h +AM_CPPFLAGS = -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/ode/src \ + -DDEFAULT_PATH_TO_TEXTURES='"$(top_srcdir)/drawstuff/textures/"' \ + $(X11_CFLAGS) + +if WIN32 +libdrawstuff_la_SOURCES+= windows.cpp resource.h resources.rc +libdrawstuff_la_LIBADD = -lwinmm -lgdi32 +libdrawstuff_la_LDFLAGS = -no-undefined +endif + +if X11 +libdrawstuff_la_SOURCES+= x11.cpp +libdrawstuff_la_LIBADD = $(X11_LIBS) +endif + +if OSX +libdrawstuff_la_SOURCES+= osx.cpp +endif + diff --git a/libs/ode-0.16.1/drawstuff/src/Makefile.in b/libs/ode-0.16.1/drawstuff/src/Makefile.in new file mode 100644 index 0000000..4fb86f7 --- /dev/null +++ b/libs/ode-0.16.1/drawstuff/src/Makefile.in @@ -0,0 +1,655 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Drawstuff is meant as an aid for testing and not as a full +# rendering library. + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@WIN32_TRUE@am__append_1 = windows.cpp resource.h resources.rc +@X11_TRUE@am__append_2 = x11.cpp +@OSX_TRUE@am__append_3 = osx.cpp +subdir = drawstuff/src +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ode/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +am__DEPENDENCIES_1 = +@X11_TRUE@libdrawstuff_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am__libdrawstuff_la_SOURCES_DIST = drawstuff.cpp internal.h \ + windows.cpp resource.h resources.rc x11.cpp osx.cpp +@WIN32_TRUE@am__objects_1 = windows.lo +@X11_TRUE@am__objects_2 = x11.lo +@OSX_TRUE@am__objects_3 = osx.lo +am_libdrawstuff_la_OBJECTS = drawstuff.lo $(am__objects_1) \ + $(am__objects_2) $(am__objects_3) +libdrawstuff_la_OBJECTS = $(am_libdrawstuff_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libdrawstuff_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(AM_CXXFLAGS) $(CXXFLAGS) $(libdrawstuff_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libdrawstuff_la_SOURCES) +DIST_SOURCES = $(am__libdrawstuff_la_SOURCES_DIST) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_CFLAGS = @CCD_CFLAGS@ +CCD_LIBS = @CCD_LIBS@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSTDCXX = @LIBSTDCXX@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ODE_PRECISION = @ODE_PRECISION@ +ODE_VERSION = @ODE_VERSION@ +ODE_VERSION_INFO = @ODE_VERSION_INFO@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LTLIBRARIES = libdrawstuff.la +libdrawstuff_la_SOURCES = drawstuff.cpp internal.h $(am__append_1) \ + $(am__append_2) $(am__append_3) +AM_CPPFLAGS = -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/ode/src \ + -DDEFAULT_PATH_TO_TEXTURES='"$(top_srcdir)/drawstuff/textures/"' \ + $(X11_CFLAGS) + +@WIN32_TRUE@libdrawstuff_la_LIBADD = -lwinmm -lgdi32 +@X11_TRUE@libdrawstuff_la_LIBADD = $(X11_LIBS) +@WIN32_TRUE@libdrawstuff_la_LDFLAGS = -no-undefined +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign drawstuff/src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign drawstuff/src/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libdrawstuff.la: $(libdrawstuff_la_OBJECTS) $(libdrawstuff_la_DEPENDENCIES) $(EXTRA_libdrawstuff_la_DEPENDENCIES) + $(AM_V_CXXLD)$(libdrawstuff_la_LINK) $(libdrawstuff_la_OBJECTS) $(libdrawstuff_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drawstuff.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/osx.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/windows.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x11.Plo@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/drawstuff/src/drawstuff.cpp b/libs/ode-0.16.1/drawstuff/src/drawstuff.cpp new file mode 100644 index 0000000..351be93 --- /dev/null +++ b/libs/ode-0.16.1/drawstuff/src/drawstuff.cpp @@ -0,0 +1,1671 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +simple graphics. + +the following command line flags can be used (typically under unix) + -notex Do not use any textures + -noshadow[s] Do not draw any shadows + -pause Start the simulation paused + -texturepath <path> Inform an alternative textures path + +TODO +---- + +manage openGL state changes better + +*/ + +#ifdef WIN32 +#include <windows.h> +#endif + +#include <ode/ode.h> +#include "config.h" + +#ifdef HAVE_APPLE_OPENGL_FRAMEWORK +#include <OpenGL/gl.h> +#include <OpenGL/glu.h> +#else +#include <GL/gl.h> +#include <GL/glu.h> +#endif + +#include "drawstuff/drawstuff.h" +#include "internal.h" + +//*************************************************************************** +// misc + +#ifndef DEFAULT_PATH_TO_TEXTURES +#if 0 +#define DEFAULT_PATH_TO_TEXTURES "..\\textures\\" +#else +#define DEFAULT_PATH_TO_TEXTURES "../textures/" +#endif +#endif + +#ifndef M_PI +#define M_PI (3.14159265358979323846) +#endif + +// constants to convert degrees to radians and the reverse +#define RAD_TO_DEG (180.0/M_PI) +#define DEG_TO_RAD (M_PI/180.0) + +// light vector. LIGHTZ is implicitly 1 +#define LIGHTX (1.0f) +#define LIGHTY (0.4f) + +// ground and sky +#define SHADOW_INTENSITY (0.65f) +#define GROUND_R (0.5f) // ground color for when there's no texture +#define GROUND_G (0.5f) +#define GROUND_B (0.3f) + +const float ground_scale = 1.0f/1.0f; // ground texture scale (1/size) +const float ground_ofsx = 0.5; // offset of ground texture +const float ground_ofsy = 0.5; +const float sky_scale = 1.0f/4.0f; // sky texture scale (1/size) +const float sky_height = 1.0f; // sky height above viewpoint + +//*************************************************************************** +// misc mathematics stuff + +static void normalizeVector3 (float v[3]) +{ + float len = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; + if (len <= 0.0f) { + v[0] = 1; + v[1] = 0; + v[2] = 0; + } + else { + len = 1.0f / (float)sqrt(len); + v[0] *= len; + v[1] *= len; + v[2] *= len; + } +} + +static void crossProduct3(float res[3], const float a[3], const float b[3]) +{ + float res_0 = a[1]*b[2] - a[2]*b[1]; + float res_1 = a[2]*b[0] - a[0]*b[2]; + float res_2 = a[0]*b[1] - a[1]*b[0]; + // Only assign after all the calculations are over to avoid incurring memory aliasing + res[0] = res_0; + res[1] = res_1; + res[2] = res_2; +} + +//*************************************************************************** +// PPM image object + +typedef unsigned char byte; + +class Image { + int image_width,image_height; + byte *image_data; +public: + Image (char *filename); + // load from PPM file + ~Image(); + int width() { return image_width; } + int height() { return image_height; } + byte *data() { return image_data; } +}; + + +// skip over whitespace and comments in a stream. + +static void skipWhiteSpace (char *filename, FILE *f) +{ + int c,d; + for(;;) { + c = fgetc(f); + if (c==EOF) dsError ("unexpected end of file in \"%s\"",filename); + + // skip comments + if (c == '#') { + do { + d = fgetc(f); + if (d==EOF) dsError ("unexpected end of file in \"%s\"",filename); + } while (d != '\n'); + continue; + } + + if (c > ' ') { + ungetc (c,f); + return; + } + } +} + + +// read a number from a stream, this return 0 if there is none (that's okay +// because 0 is a bad value for all PPM numbers anyway). + +static int readNumber (char *filename, FILE *f) +{ + int c,n=0; + for(;;) { + c = fgetc(f); + if (c==EOF) dsError ("unexpected end of file in \"%s\"",filename); + if (c >= '0' && c <= '9') n = n*10 + (c - '0'); + else { + ungetc (c,f); + return n; + } + } +} + + +Image::Image (char *filename) +{ + FILE *f = fopen (filename,"rb"); + if (!f) dsError ("Can't open image file `%s'",filename); + + // read in header + if (fgetc(f) != 'P' || fgetc(f) != '6') + dsError ("image file \"%s\" is not a binary PPM (no P6 header)",filename); + skipWhiteSpace (filename,f); + + // read in image parameters + image_width = readNumber (filename,f); + skipWhiteSpace (filename,f); + image_height = readNumber (filename,f); + skipWhiteSpace (filename,f); + int max_value = readNumber (filename,f); + + // check values + if (image_width < 1 || image_height < 1) + dsError ("bad image file \"%s\"",filename); + if (max_value != 255) + dsError ("image file \"%s\" must have color range of 255",filename); + + // read either nothing, LF (10), or CR,LF (13,10) + int c = fgetc(f); + if (c == 10) { + // LF + } + else if (c == 13) { + // CR + c = fgetc(f); + if (c != 10) ungetc (c,f); + } + else ungetc (c,f); + + // read in rest of data + image_data = new byte [image_width*image_height*3]; + if (fread (image_data,image_width*image_height*3,1,f) != 1) + dsError ("Can not read data from image file `%s'",filename); + fclose (f); +} + + +Image::~Image() +{ + delete[] image_data; +} + +//*************************************************************************** +// Texture object. + +class Texture { + Image *image; + GLuint name; +public: + Texture (char *filename); + ~Texture(); + void bind (int modulate); +}; + + +Texture::Texture (char *filename) +{ + image = new Image (filename); + glGenTextures (1,&name); + glBindTexture (GL_TEXTURE_2D,name); + + // set pixel unpacking mode + glPixelStorei (GL_UNPACK_SWAP_BYTES, 0); + glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei (GL_UNPACK_ALIGNMENT, 1); + glPixelStorei (GL_UNPACK_SKIP_ROWS, 0); + glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0); + + // glTexImage2D (GL_TEXTURE_2D, 0, 3, image->width(), image->height(), 0, + // GL_RGB, GL_UNSIGNED_BYTE, image->data()); + gluBuild2DMipmaps (GL_TEXTURE_2D, 3, image->width(), image->height(), + GL_RGB, GL_UNSIGNED_BYTE, image->data()); + + // set texture parameters - will these also be bound to the texture??? + glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_LINEAR); + + glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); +} + + +Texture::~Texture() +{ + delete image; + glDeleteTextures (1,&name); +} + + +void Texture::bind (int modulate) +{ + glBindTexture (GL_TEXTURE_2D,name); + glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, + modulate ? GL_MODULATE : GL_DECAL); +} + +//*************************************************************************** +// the current drawing state (for when the user's step function is drawing) + +static float color[4] = {0,0,0,0}; // current r,g,b,alpha color +static int tnum = 0; // current texture number + +//*************************************************************************** +// OpenGL utility stuff + +static void setCamera (float x, float y, float z, float h, float p, float r) +{ + glMatrixMode (GL_MODELVIEW); + glLoadIdentity(); + glRotatef (90, 0,0,1); + glRotatef (90, 0,1,0); + glRotatef (r, 1,0,0); + glRotatef (p, 0,1,0); + glRotatef (-h, 0,0,1); + glTranslatef (-x,-y,-z); +} + + +// sets the material color, not the light color + +static void setColor (float r, float g, float b, float alpha) +{ + GLfloat light_ambient[4],light_diffuse[4],light_specular[4]; + light_ambient[0] = r*0.3f; + light_ambient[1] = g*0.3f; + light_ambient[2] = b*0.3f; + light_ambient[3] = alpha; + light_diffuse[0] = r*0.7f; + light_diffuse[1] = g*0.7f; + light_diffuse[2] = b*0.7f; + light_diffuse[3] = alpha; + light_specular[0] = r*0.2f; + light_specular[1] = g*0.2f; + light_specular[2] = b*0.2f; + light_specular[3] = alpha; + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, light_ambient); + glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, light_diffuse); + glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, light_specular); + glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 5.0f); +} + + +static void setTransform (const float pos[3], const float R[12]) +{ + GLfloat matrix[16]; + matrix[0]=R[0]; + matrix[1]=R[4]; + matrix[2]=R[8]; + matrix[3]=0; + matrix[4]=R[1]; + matrix[5]=R[5]; + matrix[6]=R[9]; + matrix[7]=0; + matrix[8]=R[2]; + matrix[9]=R[6]; + matrix[10]=R[10]; + matrix[11]=0; + matrix[12]=pos[0]; + matrix[13]=pos[1]; + matrix[14]=pos[2]; + matrix[15]=1; + glPushMatrix(); + glMultMatrixf (matrix); +} +static void setTransformD (const double pos[3], const double R[12]) +{ + GLdouble matrix[16]; + matrix[0]=R[0]; + matrix[1]=R[4]; + matrix[2]=R[8]; + matrix[3]=0; + matrix[4]=R[1]; + matrix[5]=R[5]; + matrix[6]=R[9]; + matrix[7]=0; + matrix[8]=R[2]; + matrix[9]=R[6]; + matrix[10]=R[10]; + matrix[11]=0; + matrix[12]=pos[0]; + matrix[13]=pos[1]; + matrix[14]=pos[2]; + matrix[15]=1; + glPushMatrix(); + glMultMatrixd (matrix); +} + + +// set shadow projection transform + +static void setShadowTransform() +{ + GLfloat matrix[16]; + for (int i=0; i<16; i++) matrix[i] = 0; + matrix[0]=1; + matrix[5]=1; + matrix[8]=-LIGHTX; + matrix[9]=-LIGHTY; + matrix[15]=1; + glPushMatrix(); + glMultMatrixf (matrix); +} + +static void drawConvex (const float *_planes, unsigned int _planecount, + const float *_points, unsigned int /*_pointcount*/, + const unsigned int *_polygons) +{ + unsigned int polyindex=0; + for(unsigned int i=0;i<_planecount;++i) + { + unsigned int pointcount=_polygons[polyindex]; + polyindex++; + glBegin (GL_POLYGON); + glNormal3f(_planes[(i*4)+0], + _planes[(i*4)+1], + _planes[(i*4)+2]); + for(unsigned int j=0;j<pointcount;++j) + { + glVertex3f(_points[_polygons[polyindex]*3], + _points[(_polygons[polyindex]*3)+1], + _points[(_polygons[polyindex]*3)+2]); + polyindex++; + } + glEnd(); + } +} + +static void drawConvexD (const double *_planes, unsigned int _planecount, + const double *_points, unsigned int /*_pointcount*/, + const unsigned int *_polygons) +{ + unsigned int polyindex=0; + for(unsigned int i=0;i<_planecount;++i) + { + unsigned int pointcount=_polygons[polyindex]; + polyindex++; + glBegin (GL_POLYGON); + glNormal3d(_planes[(i*4)+0], + _planes[(i*4)+1], + _planes[(i*4)+2]); + for(unsigned int j=0;j<pointcount;++j) + { + glVertex3d(_points[_polygons[polyindex]*3], + _points[(_polygons[polyindex]*3)+1], + _points[(_polygons[polyindex]*3)+2]); + polyindex++; + } + glEnd(); + } +} + +static void drawBox (const float sides[3]) +{ + float lx = sides[0]*0.5f; + float ly = sides[1]*0.5f; + float lz = sides[2]*0.5f; + + // sides + glBegin (GL_TRIANGLE_STRIP); + glNormal3f (-1,0,0); + glVertex3f (-lx,-ly,-lz); + glVertex3f (-lx,-ly,lz); + glVertex3f (-lx,ly,-lz); + glVertex3f (-lx,ly,lz); + glNormal3f (0,1,0); + glVertex3f (lx,ly,-lz); + glVertex3f (lx,ly,lz); + glNormal3f (1,0,0); + glVertex3f (lx,-ly,-lz); + glVertex3f (lx,-ly,lz); + glNormal3f (0,-1,0); + glVertex3f (-lx,-ly,-lz); + glVertex3f (-lx,-ly,lz); + glEnd(); + + // top face + glBegin (GL_TRIANGLE_FAN); + glNormal3f (0,0,1); + glVertex3f (-lx,-ly,lz); + glVertex3f (lx,-ly,lz); + glVertex3f (lx,ly,lz); + glVertex3f (-lx,ly,lz); + glEnd(); + + // bottom face + glBegin (GL_TRIANGLE_FAN); + glNormal3f (0,0,-1); + glVertex3f (-lx,-ly,-lz); + glVertex3f (-lx,ly,-lz); + glVertex3f (lx,ly,-lz); + glVertex3f (lx,-ly,-lz); + glEnd(); +} + + +// This is recursively subdivides a triangular area (vertices p1,p2,p3) into +// smaller triangles, and then draws the triangles. All triangle vertices are +// normalized to a distance of 1.0 from the origin (p1,p2,p3 are assumed +// to be already normalized). Note this is not super-fast because it draws +// triangles rather than triangle strips. + +static void drawPatch (float p1[3], float p2[3], float p3[3], int level) +{ + int i; + if (level > 0) { + float q1[3],q2[3],q3[3]; // sub-vertices + for (i=0; i<3; i++) { + q1[i] = 0.5f*(p1[i]+p2[i]); + q2[i] = 0.5f*(p2[i]+p3[i]); + q3[i] = 0.5f*(p3[i]+p1[i]); + } + float length1 = (float)(1.0/sqrt(q1[0]*q1[0]+q1[1]*q1[1]+q1[2]*q1[2])); + float length2 = (float)(1.0/sqrt(q2[0]*q2[0]+q2[1]*q2[1]+q2[2]*q2[2])); + float length3 = (float)(1.0/sqrt(q3[0]*q3[0]+q3[1]*q3[1]+q3[2]*q3[2])); + for (i=0; i<3; i++) { + q1[i] *= length1; + q2[i] *= length2; + q3[i] *= length3; + } + drawPatch (p1,q1,q3,level-1); + drawPatch (q1,p2,q2,level-1); + drawPatch (q1,q2,q3,level-1); + drawPatch (q3,q2,p3,level-1); + } + else { + glNormal3f (p1[0],p1[1],p1[2]); + glVertex3f (p1[0],p1[1],p1[2]); + glNormal3f (p2[0],p2[1],p2[2]); + glVertex3f (p2[0],p2[1],p2[2]); + glNormal3f (p3[0],p3[1],p3[2]); + glVertex3f (p3[0],p3[1],p3[2]); + } +} + + +// draw a sphere of radius 1 + +static int sphere_quality = 1; + +static void drawSphere() +{ + // icosahedron data for an icosahedron of radius 1.0 +# define ICX 0.525731112119133606f +# define ICZ 0.850650808352039932f + static GLfloat idata[12][3] = { + {-ICX, 0, ICZ}, + {ICX, 0, ICZ}, + {-ICX, 0, -ICZ}, + {ICX, 0, -ICZ}, + {0, ICZ, ICX}, + {0, ICZ, -ICX}, + {0, -ICZ, ICX}, + {0, -ICZ, -ICX}, + {ICZ, ICX, 0}, + {-ICZ, ICX, 0}, + {ICZ, -ICX, 0}, + {-ICZ, -ICX, 0} + }; + + static int index[20][3] = { + {0, 4, 1}, {0, 9, 4}, + {9, 5, 4}, {4, 5, 8}, + {4, 8, 1}, {8, 10, 1}, + {8, 3, 10}, {5, 3, 8}, + {5, 2, 3}, {2, 7, 3}, + {7, 10, 3}, {7, 6, 10}, + {7, 11, 6}, {11, 0, 6}, + {0, 1, 6}, {6, 1, 10}, + {9, 0, 11}, {9, 11, 2}, + {9, 2, 5}, {7, 2, 11}, + }; + + static GLuint listnum = 0; + if (listnum==0) { + listnum = glGenLists (1); + glNewList (listnum,GL_COMPILE); + glBegin (GL_TRIANGLES); + for (int i=0; i<20; i++) { + drawPatch (&idata[index[i][2]][0],&idata[index[i][1]][0], + &idata[index[i][0]][0],sphere_quality); + } + glEnd(); + glEndList(); + } + glCallList (listnum); +} + + +static void drawSphereShadow (float px, float py, float pz, float radius) +{ + // calculate shadow constants based on light vector + static int init=0; + static float len2,len1,scale; + if (!init) { + len2 = LIGHTX*LIGHTX + LIGHTY*LIGHTY; + len1 = 1.0f/(float)sqrt(len2); + scale = (float) sqrt(len2 + 1); + init = 1; + } + + // map sphere center to ground plane based on light vector + px -= LIGHTX*pz; + py -= LIGHTY*pz; + + const float kx = 0.96592582628907f; + const float ky = 0.25881904510252f; + float x=radius, y=0; + + glBegin (GL_TRIANGLE_FAN); + for (int i=0; i<24; i++) { + // for all points on circle, scale to elongated rotated shadow and draw + float x2 = (LIGHTX*x*scale - LIGHTY*y)*len1 + px; + float y2 = (LIGHTY*x*scale + LIGHTX*y)*len1 + py; + glTexCoord2f (x2*ground_scale+ground_ofsx,y2*ground_scale+ground_ofsy); + glVertex3f (x2,y2,0); + + // rotate [x,y] vector + float xtmp = kx*x - ky*y; + y = ky*x + kx*y; + x = xtmp; + } + glEnd(); +} + + +static void drawTriangle (const float *v0, const float *v1, const float *v2, int solid) +{ + float u[3],v[3],normal[3]; + u[0] = v1[0] - v0[0]; + u[1] = v1[1] - v0[1]; + u[2] = v1[2] - v0[2]; + v[0] = v2[0] - v0[0]; + v[1] = v2[1] - v0[1]; + v[2] = v2[2] - v0[2]; + crossProduct3(normal,u,v); + normalizeVector3 (normal); + + glBegin(solid ? GL_TRIANGLES : GL_LINE_STRIP); + glNormal3fv (normal); + glVertex3fv (v0); + glVertex3fv (v1); + glVertex3fv (v2); + glEnd(); +} + +static void drawTriangleD (const double *v0, const double *v1, const double *v2, int solid) +{ + float u[3],v[3],normal[3]; + u[0] = float( v1[0] - v0[0] ); + u[1] = float( v1[1] - v0[1] ); + u[2] = float( v1[2] - v0[2] ); + v[0] = float( v2[0] - v0[0] ); + v[1] = float( v2[1] - v0[1] ); + v[2] = float( v2[2] - v0[2] ); + crossProduct3(normal,u,v); + normalizeVector3 (normal); + + glBegin(solid ? GL_TRIANGLES : GL_LINE_STRIP); + glNormal3fv (normal); + glVertex3dv (v0); + glVertex3dv (v1); + glVertex3dv (v2); + glEnd(); +} + + +// draw a capped cylinder of length l and radius r, aligned along the x axis + +static int capped_cylinder_quality = 3; + +static void drawCapsule (float l, float r) +{ + int i,j; + float tmp,nx,ny,nz,start_nx,start_ny,a,ca,sa; + // number of sides to the cylinder (divisible by 4): + const int n = capped_cylinder_quality*4; + + l *= 0.5; + a = float(M_PI*2.0)/float(n); + sa = (float) sin(a); + ca = (float) cos(a); + + // draw cylinder body + ny=1; nz=0; // normal vector = (0,ny,nz) + glBegin (GL_TRIANGLE_STRIP); + for (i=0; i<=n; i++) { + glNormal3d (ny,nz,0); + glVertex3d (ny*r,nz*r,l); + glNormal3d (ny,nz,0); + glVertex3d (ny*r,nz*r,-l); + // rotate ny,nz + tmp = ca*ny - sa*nz; + nz = sa*ny + ca*nz; + ny = tmp; + } + glEnd(); + + // draw first cylinder cap + start_nx = 0; + start_ny = 1; + for (j=0; j<(n/4); j++) { + // get start_n2 = rotated start_n + float start_nx2 = ca*start_nx + sa*start_ny; + float start_ny2 = -sa*start_nx + ca*start_ny; + // get n=start_n and n2=start_n2 + nx = start_nx; ny = start_ny; nz = 0; + float nx2 = start_nx2, ny2 = start_ny2, nz2 = 0; + glBegin (GL_TRIANGLE_STRIP); + for (i=0; i<=n; i++) { + glNormal3d (ny2,nz2,nx2); + glVertex3d (ny2*r,nz2*r,l+nx2*r); + glNormal3d (ny,nz,nx); + glVertex3d (ny*r,nz*r,l+nx*r); + // rotate n,n2 + tmp = ca*ny - sa*nz; + nz = sa*ny + ca*nz; + ny = tmp; + tmp = ca*ny2- sa*nz2; + nz2 = sa*ny2 + ca*nz2; + ny2 = tmp; + } + glEnd(); + start_nx = start_nx2; + start_ny = start_ny2; + } + + // draw second cylinder cap + start_nx = 0; + start_ny = 1; + for (j=0; j<(n/4); j++) { + // get start_n2 = rotated start_n + float start_nx2 = ca*start_nx - sa*start_ny; + float start_ny2 = sa*start_nx + ca*start_ny; + // get n=start_n and n2=start_n2 + nx = start_nx; ny = start_ny; nz = 0; + float nx2 = start_nx2, ny2 = start_ny2, nz2 = 0; + glBegin (GL_TRIANGLE_STRIP); + for (i=0; i<=n; i++) { + glNormal3d (ny,nz,nx); + glVertex3d (ny*r,nz*r,-l+nx*r); + glNormal3d (ny2,nz2,nx2); + glVertex3d (ny2*r,nz2*r,-l+nx2*r); + // rotate n,n2 + tmp = ca*ny - sa*nz; + nz = sa*ny + ca*nz; + ny = tmp; + tmp = ca*ny2- sa*nz2; + nz2 = sa*ny2 + ca*nz2; + ny2 = tmp; + } + glEnd(); + start_nx = start_nx2; + start_ny = start_ny2; + } +} + + +// draw a cylinder of length l and radius r, aligned along the z axis + +static void drawCylinder (float l, float r, float zoffset) +{ + int i; + float tmp,ny,nz,a,ca,sa; + const int n = 24; // number of sides to the cylinder (divisible by 4) + + l *= 0.5; + a = float(M_PI*2.0)/float(n); + sa = (float) sin(a); + ca = (float) cos(a); + + // draw cylinder body + ny=1; nz=0; // normal vector = (0,ny,nz) + glBegin (GL_TRIANGLE_STRIP); + for (i=0; i<=n; i++) { + glNormal3d (ny,nz,0); + glVertex3d (ny*r,nz*r,l+zoffset); + glNormal3d (ny,nz,0); + glVertex3d (ny*r,nz*r,-l+zoffset); + // rotate ny,nz + tmp = ca*ny - sa*nz; + nz = sa*ny + ca*nz; + ny = tmp; + } + glEnd(); + + // draw top cap + glShadeModel (GL_FLAT); + ny=1; nz=0; // normal vector = (0,ny,nz) + glBegin (GL_TRIANGLE_FAN); + glNormal3d (0,0,1); + glVertex3d (0,0,l+zoffset); + for (i=0; i<=n; i++) { + if (i==1 || i==n/2+1) + setColor (color[0]*0.75f,color[1]*0.75f,color[2]*0.75f,color[3]); + glNormal3d (0,0,1); + glVertex3d (ny*r,nz*r,l+zoffset); + if (i==1 || i==n/2+1) + setColor (color[0],color[1],color[2],color[3]); + + // rotate ny,nz + tmp = ca*ny - sa*nz; + nz = sa*ny + ca*nz; + ny = tmp; + } + glEnd(); + + // draw bottom cap + ny=1; nz=0; // normal vector = (0,ny,nz) + glBegin (GL_TRIANGLE_FAN); + glNormal3d (0,0,-1); + glVertex3d (0,0,-l+zoffset); + for (i=0; i<=n; i++) { + if (i==1 || i==n/2+1) + setColor (color[0]*0.75f,color[1]*0.75f,color[2]*0.75f,color[3]); + glNormal3d (0,0,-1); + glVertex3d (ny*r,nz*r,-l+zoffset); + if (i==1 || i==n/2+1) + setColor (color[0],color[1],color[2],color[3]); + + // rotate ny,nz + tmp = ca*ny + sa*nz; + nz = -sa*ny + ca*nz; + ny = tmp; + } + glEnd(); +} + +//*************************************************************************** +// motion model + +// current camera position and orientation +static float view_xyz[3]; // position x,y,z +static float view_hpr[3]; // heading, pitch, roll (degrees) + + +// initialize the above variables + +static void initMotionModel() +{ + view_xyz[0] = 2; + view_xyz[1] = 0; + view_xyz[2] = 1; + view_hpr[0] = 180; + view_hpr[1] = 0; + view_hpr[2] = 0; +} + + +static void wrapCameraAngles() +{ + for (int i=0; i<3; i++) { + while (view_hpr[i] > 180) view_hpr[i] -= 360; + while (view_hpr[i] < -180) view_hpr[i] += 360; + } +} + + +// call this to update the current camera position. the bits in `mode' say +// if the left (1), middle (2) or right (4) mouse button is pressed, and +// (deltax,deltay) is the amount by which the mouse pointer has moved. + +void dsMotion (int mode, int deltax, int deltay) +{ + float side = 0.01f * float(deltax); + float fwd = (mode==4) ? (0.01f * float(deltay)) : 0.0f; + float s = (float) sin (view_hpr[0]*DEG_TO_RAD); + float c = (float) cos (view_hpr[0]*DEG_TO_RAD); + + if (mode==1) { + view_hpr[0] += float (deltax) * 0.5f; + view_hpr[1] += float (deltay) * 0.5f; + } + else { + view_xyz[0] += -s*side + c*fwd; + view_xyz[1] += c*side + s*fwd; + if (mode==2 || mode==5) view_xyz[2] += 0.01f * float(deltay); + } + wrapCameraAngles(); +} + +//*************************************************************************** +// drawing loop stuff + +// the current state: +// 0 = uninitialized +// 1 = dsSimulationLoop() called +// 2 = dsDrawFrame() called +static int current_state = 0; + +// textures and shadows +static int use_textures=1; // 1 if textures to be drawn +static int use_shadows=1; // 1 if shadows to be drawn +static Texture *sky_texture = 0; +static Texture *ground_texture = 0; +static Texture *wood_texture = 0; +static Texture *checkered_texture = 0; + +static Texture *texture[4+1]; // +1 since index 0 is not used + + + +#if !defined(macintosh) || defined(ODE_PLATFORM_OSX) + +void dsStartGraphics (int /*width*/, int /*height*/, dsFunctions *fn) +{ + + const char *prefix = DEFAULT_PATH_TO_TEXTURES; + if (fn->version >= 2 && fn->path_to_textures) prefix = fn->path_to_textures; + char *s = (char*) alloca (strlen(prefix) + 20); + + strcpy (s,prefix); + strcat (s,"/sky.ppm"); + texture[DS_SKY] = sky_texture = new Texture (s); + + strcpy (s,prefix); + strcat (s,"/ground.ppm"); + texture[DS_GROUND] = ground_texture = new Texture (s); + + strcpy (s,prefix); + strcat (s,"/wood.ppm"); + texture[DS_WOOD] = wood_texture = new Texture (s); + + strcpy (s,prefix); + strcat (s,"/checkered.ppm"); + texture[DS_CHECKERED] = checkered_texture = new Texture (s); +} + +#else // macintosh + +void dsStartGraphics (int width, int height, dsFunctions *fn) +{ + + // All examples build into the same dir + char *prefix = "::::drawstuff:textures"; + char *s = (char*) alloca (strlen(prefix) + 20); + + strcpy (s,prefix); + strcat (s,":sky.ppm"); + sky_texture = new Texture (s); + + strcpy (s,prefix); + strcat (s,":ground.ppm"); + ground_texture = new Texture (s); + + strcpy (s,prefix); + strcat (s,":wood.ppm"); + wood_texture = new Texture (s); +} + +#endif + + +void dsStopGraphics() +{ + delete sky_texture; + delete ground_texture; + delete wood_texture; + sky_texture = 0; + ground_texture = 0; + wood_texture = 0; +} + + +static void drawSky (float view_xyz[3]) +{ + glDisable (GL_LIGHTING); + if (use_textures) { + glEnable (GL_TEXTURE_2D); + sky_texture->bind (0); + } + else { + glDisable (GL_TEXTURE_2D); + glColor3f (0,0.5,1.0); + } + + // make sure sky depth is as far back as possible + glShadeModel (GL_FLAT); + glEnable (GL_DEPTH_TEST); + glDepthFunc (GL_LEQUAL); + glDepthRange (1,1); + + const float ssize = 1000.0f; + static float offset = 0.0f; + + float x = ssize*sky_scale; + float z = view_xyz[2] + sky_height; + + glBegin (GL_QUADS); + glNormal3f (0,0,-1); + glTexCoord2f (-x+offset,-x+offset); + glVertex3f (-ssize+view_xyz[0],-ssize+view_xyz[1],z); + glTexCoord2f (-x+offset,x+offset); + glVertex3f (-ssize+view_xyz[0],ssize+view_xyz[1],z); + glTexCoord2f (x+offset,x+offset); + glVertex3f (ssize+view_xyz[0],ssize+view_xyz[1],z); + glTexCoord2f (x+offset,-x+offset); + glVertex3f (ssize+view_xyz[0],-ssize+view_xyz[1],z); + glEnd(); + + offset = offset + 0.002f; + if (offset > 1) offset -= 1; + + glDepthFunc (GL_LESS); + glDepthRange (0,1); +} + + +static void drawGround() +{ + glDisable (GL_LIGHTING); + glShadeModel (GL_FLAT); + glEnable (GL_DEPTH_TEST); + glDepthFunc (GL_LESS); + // glDepthRange (1,1); + + if (use_textures) { + glEnable (GL_TEXTURE_2D); + ground_texture->bind (0); + } + else { + glDisable (GL_TEXTURE_2D); + glColor3f (GROUND_R,GROUND_G,GROUND_B); + } + + // ground fog seems to cause problems with TNT2 under windows + /* + GLfloat fogColor[4] = {0.5, 0.5, 0.5, 1}; + glEnable (GL_FOG); + glFogi (GL_FOG_MODE, GL_EXP2); + glFogfv (GL_FOG_COLOR, fogColor); + glFogf (GL_FOG_DENSITY, 0.05f); + glHint (GL_FOG_HINT, GL_NICEST); // GL_DONT_CARE); + glFogf (GL_FOG_START, 1.0); + glFogf (GL_FOG_END, 5.0); + */ + + const float gsize = 100.0f; + const float offset = 0; // -0.001f; ... polygon offsetting doesn't work well + + glBegin (GL_QUADS); + glNormal3f (0,0,1); + glTexCoord2f (-gsize*ground_scale + ground_ofsx, + -gsize*ground_scale + ground_ofsy); + glVertex3f (-gsize,-gsize,offset); + glTexCoord2f (gsize*ground_scale + ground_ofsx, + -gsize*ground_scale + ground_ofsy); + glVertex3f (gsize,-gsize,offset); + glTexCoord2f (gsize*ground_scale + ground_ofsx, + gsize*ground_scale + ground_ofsy); + glVertex3f (gsize,gsize,offset); + glTexCoord2f (-gsize*ground_scale + ground_ofsx, + gsize*ground_scale + ground_ofsy); + glVertex3f (-gsize,gsize,offset); + glEnd(); + + glDisable (GL_FOG); +} + + +static void drawPyramidGrid() +{ + // setup stuff + glEnable (GL_LIGHTING); + glDisable (GL_TEXTURE_2D); + glShadeModel (GL_FLAT); + glEnable (GL_DEPTH_TEST); + glDepthFunc (GL_LESS); + + // draw the pyramid grid + for (int i=-1; i<=1; i++) { + for (int j=-1; j<=1; j++) { + glPushMatrix(); + glTranslatef ((float)i,(float)j,(float)0); + if (i==1 && j==0) setColor (1,0,0,1); + else if (i==0 && j==1) setColor (0,0,1,1); + else setColor (1,1,0,1); + const float k = 0.03f; + glBegin (GL_TRIANGLE_FAN); + glNormal3f (0,-1,1); + glVertex3f (0,0,k); + glVertex3f (-k,-k,0); + glVertex3f ( k,-k,0); + glNormal3f (1,0,1); + glVertex3f ( k, k,0); + glNormal3f (0,1,1); + glVertex3f (-k, k,0); + glNormal3f (-1,0,1); + glVertex3f (-k,-k,0); + glEnd(); + glPopMatrix(); + } + } +} + + +void dsDrawFrame (int width, int height, dsFunctions *fn, int pause) +{ + if (current_state < 1) dsDebug ("internal error"); + current_state = 2; + + // setup stuff + glEnable (GL_LIGHTING); + glEnable (GL_LIGHT0); + glDisable (GL_TEXTURE_2D); + glDisable (GL_TEXTURE_GEN_S); + glDisable (GL_TEXTURE_GEN_T); + glShadeModel (GL_FLAT); + glEnable (GL_DEPTH_TEST); + glDepthFunc (GL_LESS); + glEnable (GL_CULL_FACE); + glCullFace (GL_BACK); + glFrontFace (GL_CCW); + + // setup viewport + glViewport (0,0,width,height); + glMatrixMode (GL_PROJECTION); + glLoadIdentity(); + const float vnear = 0.1f; + const float vfar = 100.0f; + const float k = 0.8f; // view scale, 1 = +/- 45 degrees + if (width >= height) { + float k2 = float(height)/float(width); + glFrustum (-vnear*k,vnear*k,-vnear*k*k2,vnear*k*k2,vnear,vfar); + } + else { + float k2 = float(width)/float(height); + glFrustum (-vnear*k*k2,vnear*k*k2,-vnear*k,vnear*k,vnear,vfar); + } + + // setup lights. it makes a difference whether this is done in the + // GL_PROJECTION matrix mode (lights are scene relative) or the + // GL_MODELVIEW matrix mode (lights are camera relative, bad!). + static GLfloat light_ambient[] = { 0.5, 0.5, 0.5, 1.0 }; + static GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; + static GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 }; + glLightfv (GL_LIGHT0, GL_AMBIENT, light_ambient); + glLightfv (GL_LIGHT0, GL_DIFFUSE, light_diffuse); + glLightfv (GL_LIGHT0, GL_SPECULAR, light_specular); + glColor3f (1.0, 1.0, 1.0); + + // clear the window + glClearColor (0.5,0.5,0.5,0); + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // snapshot camera position (in MS Windows it is changed by the GUI thread) + float view2_xyz[3]; + float view2_hpr[3]; + memcpy (view2_xyz,view_xyz,sizeof(float)*3); + memcpy (view2_hpr,view_hpr,sizeof(float)*3); + + // go to GL_MODELVIEW matrix mode and set the camera + glMatrixMode (GL_MODELVIEW); + glLoadIdentity(); + setCamera (view2_xyz[0],view2_xyz[1],view2_xyz[2], + view2_hpr[0],view2_hpr[1],view2_hpr[2]); + + // set the light position (for some reason we have to do this in model view. + static GLfloat light_position[] = { LIGHTX, LIGHTY, 1.0, 0.0 }; + glLightfv (GL_LIGHT0, GL_POSITION, light_position); + + // draw the background (ground, sky etc) + drawSky (view2_xyz); + drawGround(); + + // draw the little markers on the ground + drawPyramidGrid(); + + // leave openGL in a known state - flat shaded white, no textures + glEnable (GL_LIGHTING); + glDisable (GL_TEXTURE_2D); + glShadeModel (GL_FLAT); + glEnable (GL_DEPTH_TEST); + glDepthFunc (GL_LESS); + glColor3f (1,1,1); + setColor (1,1,1,1); + + // draw the rest of the objects. set drawing state first. + color[0] = 1; + color[1] = 1; + color[2] = 1; + color[3] = 1; + tnum = 0; + if (fn->step) fn->step (pause); +} + + +int dsGetShadows() +{ + return use_shadows; +} + + +void dsSetShadows (int a) +{ + use_shadows = (a != 0); +} + + +int dsGetTextures() +{ + return use_textures; +} + + +void dsSetTextures (int a) +{ + use_textures = (a != 0); +} + +//*************************************************************************** +// C interface + +// sets lighting and texture modes, sets current color +static void setupDrawingMode() +{ + glEnable (GL_LIGHTING); + if (tnum) { + if (use_textures) { + glEnable (GL_TEXTURE_2D); + texture[tnum]->bind (1); + glEnable (GL_TEXTURE_GEN_S); + glEnable (GL_TEXTURE_GEN_T); + glTexGeni (GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); + glTexGeni (GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); + static GLfloat s_params[4] = {1.0f,1.0f,0.0f,1}; + static GLfloat t_params[4] = {0.817f,-0.817f,0.817f,1}; + glTexGenfv (GL_S,GL_OBJECT_PLANE,s_params); + glTexGenfv (GL_T,GL_OBJECT_PLANE,t_params); + } + else { + glDisable (GL_TEXTURE_2D); + } + } + else { + glDisable (GL_TEXTURE_2D); + } + setColor (color[0],color[1],color[2],color[3]); + + if (color[3] < 1) { + glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + } + else { + glDisable (GL_BLEND); + } +} + + +static void setShadowDrawingMode() +{ + glDisable (GL_LIGHTING); + if (use_textures) { + glEnable (GL_TEXTURE_2D); + ground_texture->bind (1); + glColor3f (SHADOW_INTENSITY,SHADOW_INTENSITY,SHADOW_INTENSITY); + glEnable (GL_TEXTURE_2D); + glEnable (GL_TEXTURE_GEN_S); + glEnable (GL_TEXTURE_GEN_T); + glTexGeni (GL_S,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR); + glTexGeni (GL_T,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR); + static GLfloat s_params[4] = {ground_scale,0,0,ground_ofsx}; + static GLfloat t_params[4] = {0,ground_scale,0,ground_ofsy}; + glTexGenfv (GL_S,GL_EYE_PLANE,s_params); + glTexGenfv (GL_T,GL_EYE_PLANE,t_params); + } + else { + glDisable (GL_TEXTURE_2D); + glColor3f (GROUND_R*SHADOW_INTENSITY,GROUND_G*SHADOW_INTENSITY, + GROUND_B*SHADOW_INTENSITY); + } + glDepthRange (0,0.9999); +} + + +extern "C" void dsSimulationLoop (int argc, char **argv, + int window_width, int window_height, + dsFunctions *fn) +{ + if (current_state != 0) dsError ("dsSimulationLoop() called more than once"); + current_state = 1; + + // look for flags that apply to us + int initial_pause = 0; + for (int i=1; i<argc; i++) { + if (strcmp(argv[i],"-notex")==0) use_textures = 0; + if (strcmp(argv[i],"-noshadow")==0) use_shadows = 0; + if (strcmp(argv[i],"-noshadows")==0) use_shadows = 0; + if (strcmp(argv[i],"-pause")==0) initial_pause = 1; + if (strcmp(argv[i],"-texturepath")==0) + if (++i < argc) + fn->path_to_textures = argv[i]; + } + + if (fn->version > DS_VERSION) + dsDebug ("bad version number in dsFunctions structure"); + + initMotionModel(); + dsPlatformSimLoop (window_width,window_height,fn,initial_pause); + + current_state = 0; +} + + +extern "C" void dsSetViewpoint (float xyz[3], float hpr[3]) +{ + if (current_state < 1) dsError ("dsSetViewpoint() called before simulation started"); + if (xyz) { + view_xyz[0] = xyz[0]; + view_xyz[1] = xyz[1]; + view_xyz[2] = xyz[2]; + } + if (hpr) { + view_hpr[0] = hpr[0]; + view_hpr[1] = hpr[1]; + view_hpr[2] = hpr[2]; + wrapCameraAngles(); + } +} + + +extern "C" void dsGetViewpoint (float xyz[3], float hpr[3]) +{ + if (current_state < 1) dsError ("dsGetViewpoint() called before simulation started"); + if (xyz) { + xyz[0] = view_xyz[0]; + xyz[1] = view_xyz[1]; + xyz[2] = view_xyz[2]; + } + if (hpr) { + hpr[0] = view_hpr[0]; + hpr[1] = view_hpr[1]; + hpr[2] = view_hpr[2]; + } +} + + +extern "C" void dsSetTexture (int texture_number) +{ + if (current_state != 2) dsError ("drawing function called outside simulation loop"); + tnum = texture_number; +} + + +extern "C" void dsSetColor (float red, float green, float blue) +{ + if (current_state != 2) dsError ("drawing function called outside simulation loop"); + color[0] = red; + color[1] = green; + color[2] = blue; + color[3] = 1; +} + + +extern "C" void dsSetColorAlpha (float red, float green, float blue, + float alpha) +{ + if (current_state != 2) dsError ("drawing function called outside simulation loop"); + color[0] = red; + color[1] = green; + color[2] = blue; + color[3] = alpha; +} + + +extern "C" void dsDrawBox (const float pos[3], const float R[12], + const float sides[3]) +{ + if (current_state != 2) dsError ("drawing function called outside simulation loop"); + setupDrawingMode(); + glShadeModel (GL_FLAT); + setTransform (pos,R); + drawBox (sides); + glPopMatrix(); + + if (use_shadows) { + setShadowDrawingMode(); + setShadowTransform(); + setTransform (pos,R); + drawBox (sides); + glPopMatrix(); + glPopMatrix(); + glDepthRange (0,1); + } +} + +extern "C" void dsDrawConvex (const float pos[3], const float R[12], + const float *_planes,unsigned int _planecount, + const float *_points, unsigned int _pointcount, + const unsigned int *_polygons) +{ + if (current_state != 2) dsError ("drawing function called outside simulation loop"); + setupDrawingMode(); + glShadeModel (GL_FLAT); + setTransform (pos,R); + drawConvex(_planes,_planecount,_points,_pointcount,_polygons); + glPopMatrix(); + if (use_shadows) { + setShadowDrawingMode(); + setShadowTransform(); + setTransform (pos,R); + drawConvex(_planes,_planecount,_points,_pointcount,_polygons); + glPopMatrix(); + glPopMatrix(); + glDepthRange (0,1); + } +} + + +extern "C" void dsDrawSphere (const float pos[3], const float R[12], + float radius) +{ + if (current_state != 2) dsError ("drawing function called outside simulation loop"); + setupDrawingMode(); + glEnable (GL_NORMALIZE); + glShadeModel (GL_SMOOTH); + setTransform (pos,R); + glScaled (radius,radius,radius); + drawSphere(); + glPopMatrix(); + glDisable (GL_NORMALIZE); + + // draw shadows + if (use_shadows) { + glDisable (GL_LIGHTING); + if (use_textures) { + ground_texture->bind (1); + glEnable (GL_TEXTURE_2D); + glDisable (GL_TEXTURE_GEN_S); + glDisable (GL_TEXTURE_GEN_T); + glColor3f (SHADOW_INTENSITY,SHADOW_INTENSITY,SHADOW_INTENSITY); + } + else { + glDisable (GL_TEXTURE_2D); + glColor3f (GROUND_R*SHADOW_INTENSITY,GROUND_G*SHADOW_INTENSITY, + GROUND_B*SHADOW_INTENSITY); + } + glShadeModel (GL_FLAT); + glDepthRange (0,0.9999); + drawSphereShadow (pos[0],pos[1],pos[2],radius); + glDepthRange (0,1); + } +} + + +extern "C" void dsDrawTriangle (const float pos[3], const float R[12], + const float *v0, const float *v1, + const float *v2, int solid) +{ + if (current_state != 2) dsError ("drawing function called outside simulation loop"); + setupDrawingMode(); + glShadeModel (GL_FLAT); + setTransform (pos,R); + drawTriangle (v0, v1, v2, solid); + glPopMatrix(); +} + + +extern "C" void dsDrawTriangles (const float pos[3], const float R[12], + const float *v, int n, int solid) +{ + if (current_state != 2) dsError ("drawing function called outside simulation loop"); + setupDrawingMode(); + glShadeModel (GL_FLAT); + setTransform (pos,R); + int i; + for (i = 0; i < n; ++i, v += 9) + drawTriangle (v, v + 3, v + 6, solid); + glPopMatrix(); +} + + +extern "C" void dsDrawCylinder (const float pos[3], const float R[12], + float length, float radius) +{ + if (current_state != 2) dsError ("drawing function called outside simulation loop"); + setupDrawingMode(); + glShadeModel (GL_SMOOTH); + setTransform (pos,R); + drawCylinder (length,radius,0); + glPopMatrix(); + + if (use_shadows) { + setShadowDrawingMode(); + setShadowTransform(); + setTransform (pos,R); + drawCylinder (length,radius,0); + glPopMatrix(); + glPopMatrix(); + glDepthRange (0,1); + } +} + + +extern "C" void dsDrawCapsule (const float pos[3], const float R[12], + float length, float radius) +{ + if (current_state != 2) dsError ("drawing function called outside simulation loop"); + setupDrawingMode(); + glShadeModel (GL_SMOOTH); + setTransform (pos,R); + drawCapsule (length,radius); + glPopMatrix(); + + if (use_shadows) { + setShadowDrawingMode(); + setShadowTransform(); + setTransform (pos,R); + drawCapsule (length,radius); + glPopMatrix(); + glPopMatrix(); + glDepthRange (0,1); + } +} + + +static void drawLine(const float pos1[3], const float pos2[3]) +{ + glDisable (GL_LIGHTING); + glLineWidth (2); + glShadeModel (GL_FLAT); + glBegin (GL_LINES); + glVertex3f (pos1[0],pos1[1],pos1[2]); + glVertex3f (pos2[0],pos2[1],pos2[2]); + glEnd(); +} + + +extern "C" void dsDrawLine (const float pos1[3], const float pos2[3]) +{ + setupDrawingMode(); + glColor4f(color[0], color[1], color[2], color[3]); + drawLine(pos1, pos2); + + if (use_shadows) { + setShadowDrawingMode(); + setShadowTransform(); + + drawLine(pos1, pos2); + + glPopMatrix(); + glDepthRange (0,1); + } +} + + +extern "C" void dsDrawBoxD (const double pos[3], const double R[12], + const double sides[3]) +{ + int i; + float pos2[3],R2[12],fsides[3]; + for (i=0; i<3; i++) pos2[i]=(float)pos[i]; + for (i=0; i<12; i++) R2[i]=(float)R[i]; + for (i=0; i<3; i++) fsides[i]=(float)sides[i]; + dsDrawBox (pos2,R2,fsides); +} + +extern "C" void dsDrawConvexD (const double pos[3], const double R[12], + const double *_planes, unsigned int _planecount, + const double *_points, unsigned int _pointcount, + const unsigned int *_polygons) +{ + if (current_state != 2) dsError ("drawing function called outside simulation loop"); + setupDrawingMode(); + glShadeModel (GL_FLAT); + setTransformD (pos,R); + drawConvexD(_planes,_planecount,_points,_pointcount,_polygons); + glPopMatrix(); + if (use_shadows) { + setShadowDrawingMode(); + setShadowTransform(); + setTransformD (pos,R); + drawConvexD(_planes,_planecount,_points,_pointcount,_polygons); + glPopMatrix(); + glPopMatrix(); + glDepthRange (0,1); + } +} + +void dsDrawSphereD (const double pos[3], const double R[12], float radius) +{ + int i; + float pos2[3],R2[12]; + for (i=0; i<3; i++) pos2[i]=(float)pos[i]; + for (i=0; i<12; i++) R2[i]=(float)R[i]; + dsDrawSphere (pos2,R2,radius); +} + + +void dsDrawTriangleD (const double pos[3], const double R[12], + const double *v0, const double *v1, + const double *v2, int solid) +{ + int i; + float pos2[3],R2[12]; + for (i=0; i<3; i++) pos2[i]=(float)pos[i]; + for (i=0; i<12; i++) R2[i]=(float)R[i]; + + setupDrawingMode(); + glShadeModel (GL_FLAT); + setTransform (pos2,R2); + drawTriangleD (v0, v1, v2, solid); + glPopMatrix(); +} + + +extern "C" void dsDrawTrianglesD (const double pos[3], const double R[12], + const double *v, int n, int solid) +{ + int i; + float pos2[3],R2[12]; + for (i=0; i<3; i++) pos2[i]=(float)pos[i]; + for (i=0; i<12; i++) R2[i]=(float)R[i]; + + if (current_state != 2) dsError ("drawing function called outside simulation loop"); + setupDrawingMode(); + glShadeModel (GL_FLAT); + setTransform (pos2,R2); + for (i = 0; i < n; ++i, v += 9) + drawTriangleD (v, v + 3, v + 6, solid); + glPopMatrix(); +} + + +void dsDrawCylinderD (const double pos[3], const double R[12], + float length, float radius) +{ + int i; + float pos2[3],R2[12]; + for (i=0; i<3; i++) pos2[i]=(float)pos[i]; + for (i=0; i<12; i++) R2[i]=(float)R[i]; + dsDrawCylinder (pos2,R2,length,radius); +} + + +void dsDrawCapsuleD (const double pos[3], const double R[12], + float length, float radius) +{ + int i; + float pos2[3],R2[12]; + for (i=0; i<3; i++) pos2[i]=(float)pos[i]; + for (i=0; i<12; i++) R2[i]=(float)R[i]; + dsDrawCapsule (pos2,R2,length,radius); +} + + +void dsDrawLineD (const double _pos1[3], const double _pos2[3]) +{ + int i; + float pos1[3],pos2[3]; + for (i=0; i<3; i++) pos1[i]=(float)_pos1[i]; + for (i=0; i<3; i++) pos2[i]=(float)_pos2[i]; + dsDrawLine (pos1,pos2); +} + + +void dsSetSphereQuality (int n) +{ + sphere_quality = n; +} + + +void dsSetCapsuleQuality (int n) +{ + capped_cylinder_quality = n; +} + +void dsSetDrawMode(int mode) +{ + switch(mode) + { + case DS_POLYFILL: + glPolygonMode(GL_FRONT,GL_FILL); + break; + case DS_WIREFRAME: + glPolygonMode(GL_FRONT,GL_LINE); + break; + } +} diff --git a/libs/ode-0.16.1/drawstuff/src/internal.h b/libs/ode-0.16.1/drawstuff/src/internal.h new file mode 100644 index 0000000..de1aa11 --- /dev/null +++ b/libs/ode-0.16.1/drawstuff/src/internal.h @@ -0,0 +1,50 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* functions supplied and used by the platform specific code */ + +#ifndef __DS_INTERNAL_H +#define __DS_INTERNAL_H + +#include "drawstuff/drawstuff.h" + + +// supplied by platform specific code + +void dsPlatformSimLoop (int window_width, int window_height, + dsFunctions *fn, int initial_pause); + + +// used by platform specific code + +void dsStartGraphics (int width, int height, dsFunctions *fn); +void dsDrawFrame (int width, int height, dsFunctions *fn, int pause); +void dsStopGraphics(); +void dsMotion (int mode, int deltax, int deltay); + +int dsGetShadows(); +void dsSetShadows (int a); + +int dsGetTextures(); +void dsSetTextures (int a); + +#endif diff --git a/libs/ode-0.16.1/drawstuff/src/osx.cpp b/libs/ode-0.16.1/drawstuff/src/osx.cpp new file mode 100644 index 0000000..bc69bfe --- /dev/null +++ b/libs/ode-0.16.1/drawstuff/src/osx.cpp @@ -0,0 +1,347 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// Platform-specific code for Mac OS X using Carbon+AGL +// +// Created using x11.cpp and the window-initialization -routines from GLFW +// as reference. +// Not thoroughly tested and is certain to contain deficiencies and bugs + +#include <ode/odeconfig.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include "config.h" +#include "common.h" + +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif + +#include <drawstuff/drawstuff.h> +#include <drawstuff/version.h> +#include "internal.h" + +#include <OpenGL/gl.h> +#include <GLUT/glut.h> + +// Global variables + +static bool paused = false; // 1 if in `pause' mode +static bool singlestep = false; // 1 if single step key pressed +static bool writeframes = false; // 1 if frame files to be written + +static int windowWidth = -1; +static int windowHeight = -1; +static int mouseButtonMode = 0; +static bool mouseWithOption = false; // Set if dragging the mouse with alt pressed +static bool mouseWithControl = false; // Set if dragging the mouse with ctrl pressed + +static dsFunctions* functions = NULL; +static int windowReference; +static int frame = 1; +static int prev_x = 0; +static int prev_y = 0; + +//*************************************************************************** +// error handling for unix + +static void printMessage (const char *msg1, const char *msg2, va_list ap) +{ + fflush (stderr); + fflush (stdout); + fprintf (stderr,"\n%s: ",msg1); + vfprintf (stderr,msg2,ap); + fprintf (stderr,"\n"); + fflush (stderr); +} + +extern "C" void dsError (const char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + printMessage ("Error",msg,ap); + va_end (ap); + exit (1); +} + + +extern "C" void dsDebug (const char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + printMessage ("INTERNAL ERROR",msg,ap); + va_end (ap); + // *((char *)0) = 0; ... commit SEGVicide ? + abort(); +} + +extern "C" void dsPrint (const char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + vprintf (msg,ap); + va_end (ap); +} + +static void captureFrame( int num ){ + + fprintf( stderr,"\rcapturing frame %04d", num ); + unsigned char buffer[windowWidth*windowHeight][3]; + glReadPixels( 0, 0, windowWidth, windowHeight, GL_RGB, GL_UNSIGNED_BYTE, &buffer ); + char s[100]; + sprintf (s,"frame%04d.ppm",num); + FILE *f = fopen (s,"wb"); + if( !f ){ + dsError( "can't open \"%s\" for writing", s ); + } + fprintf( f,"P6\n%d %d\n255\n", windowWidth, windowHeight ); + for( int y=windowHeight-1; y>-1; y-- ){ + fwrite( buffer[y*windowWidth], 3*windowWidth, 1, f ); + } + fclose (f); +} + +extern "C" void dsStop() +{ +} + +extern "C" double dsElapsedTime() +{ +#if HAVE_GETTIMEOFDAY + static double prev=0.0; + timeval tv ; + + gettimeofday(&tv, 0); + double curr = tv.tv_sec + (double) tv.tv_usec / 1000000.0 ; + if (!prev) + prev=curr; + double retval = curr-prev; + prev=curr; + if (retval>1.0) retval=1.0; + if (retval<dEpsilon) retval=dEpsilon; + return retval; +#else + return 0.01666; // Assume 60 fps +#endif +} + +int osxGetModifierMask() +{ + return glutGetModifiers() & ~GLUT_ACTIVE_SHIFT; +} + +void osxKeyEventHandler( unsigned char key, int x, int y ) +{ + unsigned char uppercase; + if (key >= 'a' && key <= 'z') + uppercase = key - ('a' - 'A'); + else + uppercase = key; + + int modifierMask = osxGetModifierMask(); + if (modifierMask == 0) + { + if( key >= ' ' && key <= 126 && functions -> command ) + functions -> command( key ); + } + else if (modifierMask & GLUT_ACTIVE_CTRL) + { + // ctrl+key was pressed + uppercase += 'A' - 1; + switch(uppercase ){ + case 'T': + dsSetTextures( !dsGetTextures() ); + break; + case 'S': + dsSetShadows( !dsGetShadows() ); + break; + case 'X': + exit(0); + break; + case 'P': + paused = !paused; + singlestep = false; + break; + case 'O': + if( paused ){ + singlestep = true; + } + break; + case 'V': { + float xyz[3],hpr[3]; + dsGetViewpoint( xyz,hpr ); + printf( "Viewpoint = (%.4f,%.4f,%.4f,%.4f,%.4f,%.4f)\n", xyz[0], xyz[1], xyz[2], hpr[0], hpr[1], hpr[2] ); + break; + } + case 'W': + writeframes = !writeframes; + if( writeframes ){ + printf( "Now writing frames to PPM files\n" ); + } + break; + } + } +} + +void osxMouseEventHandler(int button, int state, int x, int y) +{ + prev_x = x; + prev_y = y; + bool buttonDown = false; + switch( state ){ + case GLUT_DOWN: + buttonDown = true; + case GLUT_UP: + if( button == GLUT_LEFT_BUTTON ){ + int modifierMask = osxGetModifierMask(); + if( modifierMask & GLUT_ACTIVE_CTRL ){ + // Ctrl+button == right + button = GLUT_RIGHT_BUTTON; + mouseWithControl = true; + } + else if( modifierMask & GLUT_ACTIVE_ALT ){ + // Alt+button == left+right + mouseButtonMode = 5; + mouseWithOption = true; + return; + } + } + if( buttonDown ){ + if( button == GLUT_LEFT_BUTTON ) mouseButtonMode |= 1; // Left + if( button == GLUT_MIDDLE_BUTTON ) mouseButtonMode |= 2; // Middle + if( button == GLUT_RIGHT_BUTTON ) mouseButtonMode |= 4; // Right + } + else{ + if( button == GLUT_LEFT_BUTTON ) mouseButtonMode &= (~1); // Left + if( button == GLUT_MIDDLE_BUTTON ) mouseButtonMode &= (~2); // Middle + if( button == GLUT_RIGHT_BUTTON ) mouseButtonMode &= (~4); // Right + } + return; + } +} + +void osxMotionEventHandler(int x, int y) +{ + dsMotion( mouseButtonMode, x - prev_x, y - prev_y ); + prev_x = x; + prev_y = y; +} + +void osxWindowReshapeEventHandler(int width, int height) +{ + windowWidth = width; + windowHeight = height; +} + +static void osxCreateMainWindow( int width, int height ) +{ + int argc = 1; + char* argv[2]; + argv[0] = (char*)""; + argv[1] = NULL; + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); + glutInitWindowSize(width, height); + + windowReference = glutCreateWindow("ODE - Drawstuff"); + windowWidth = width; + windowHeight = height; +} + +void osxRedisplayEventHandler() +{ + dsDrawFrame( windowWidth, windowHeight, functions, paused && !singlestep ); + singlestep = false; + glutSwapBuffers(); + + // capture frames if necessary + if( !paused && writeframes ){ + captureFrame( frame ); + frame++; + } +} + +void osxTimerEventHandler(int); + +void osxInstallTimerHandler() +{ + glutTimerFunc(1000/60, osxTimerEventHandler, 0); +} + +void osxTimerEventHandler(int) +{ + glutPostRedisplay(); + osxInstallTimerHandler(); +} + +int osxInstallEventHandlers() +{ + glutKeyboardFunc(osxKeyEventHandler); + glutMouseFunc(osxMouseEventHandler); + glutMotionFunc(osxMotionEventHandler); + glutDisplayFunc(osxRedisplayEventHandler); + glutReshapeFunc(osxWindowReshapeEventHandler); + osxInstallTimerHandler(); + return GL_TRUE; +} + +extern void dsPlatformSimLoop( int givenWindowWidth, int givenWindowHeight, dsFunctions *fn, int givenPause ){ + + functions = fn; + + paused = givenPause; + + osxCreateMainWindow( givenWindowWidth, givenWindowHeight ); + osxInstallEventHandlers(); + + dsStartGraphics( windowWidth, windowHeight, fn ); + + static bool firsttime=true; + if( firsttime ) + { + fprintf + ( + stderr, + "\n" + "Simulation test environment v%d.%02d\n" + " Ctrl-P : pause / unpause (or say `-pause' on command line).\n" + " Ctrl-O : single step when paused.\n" + " Ctrl-T : toggle textures (or say `-notex' on command line).\n" + " Ctrl-S : toggle shadows (or say `-noshadow' on command line).\n" + " Ctrl-V : print current viewpoint coordinates (x,y,z,h,p,r).\n" + " Ctrl-W : write frames to ppm files: frame/frameNNN.ppm\n" + " Ctrl-X : exit.\n" + "\n" + "Change the camera position by clicking + dragging in the window.\n" + " Left button - pan and tilt.\n" + " Right button (or Ctrl + button) - forward and sideways.\n" + " Left + Right button (or middle button, or Alt + button) - sideways and up.\n" + "\n",DS_VERSION >> 8,DS_VERSION & 0xff + ); + firsttime = false; + } + + if( fn -> start ) fn->start(); + + glutMainLoop(); +} diff --git a/libs/ode-0.16.1/drawstuff/src/resource.h b/libs/ode-0.16.1/drawstuff/src/resource.h new file mode 100644 index 0000000..15802b6 --- /dev/null +++ b/libs/ode-0.16.1/drawstuff/src/resource.h @@ -0,0 +1,28 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by resources.rc +// +#define IDD_MSGDLG 101 +#define IDR_MENU1 102 +#define IDD_ABOUT 103 +#define IDR_ACCELERATOR1 104 +#define IDC_LIST1 1000 +#define IDM_EXIT 40001 +#define IDM_ABOUT 40002 +#define IDM_PAUSE 40003 +#define IDM_PERF_MONITOR 40004 +#define IDM_SHADOWS 40005 +#define IDM_TEXTURES 40006 +#define IDM_SAVE_SETTINGS 40007 +#define IDM_SINGLE_STEP 40008 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 108 +#define _APS_NEXT_COMMAND_VALUE 40009 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/libs/ode-0.16.1/drawstuff/src/resources.rc b/libs/ode-0.16.1/drawstuff/src/resources.rc new file mode 100644 index 0000000..61611f7 --- /dev/null +++ b/libs/ode-0.16.1/drawstuff/src/resources.rc @@ -0,0 +1,153 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +//#include "afxres.h" + +// added by RLS to make this work with windres +#include "winresrc.h" +#define IDC_STATIC (-1) + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUT DIALOG DISCARDABLE 0, 0, 257, 105 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "About" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,200,84,50,14 + LTEXT "Simulation test environment",IDC_STATIC,7,7,243,8 + LTEXT "Change the camera position by clicking + dragging in the main window.", + IDC_STATIC,7,24,243,8 + LTEXT "Left button - pan and tilt.",IDC_STATIC,25,37,225,8 + LTEXT "Right button - forward and sideways.",IDC_STATIC,25,48, + 225,8 + LTEXT "Left + Right button (or middle button) - sideways and up.", + IDC_STATIC,25,59,225,8 +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + //"#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MENU1 MENU DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&Exit\tCtrl+X", IDM_EXIT + END + POPUP "&Simulation" + BEGIN + MENUITEM "&Pause\tCtrl+P", IDM_PAUSE + MENUITEM "Single Step\tCtrl+O", IDM_SINGLE_STEP + MENUITEM "Performance &Monitor", IDM_PERF_MONITOR, GRAYED + MENUITEM SEPARATOR + MENUITEM "&Shadows\tCtrl+S", IDM_SHADOWS, CHECKED + MENUITEM "&Textures\tCtrl+T", IDM_TEXTURES, CHECKED + MENUITEM SEPARATOR + MENUITEM "S&ave Settings", IDM_SAVE_SETTINGS, GRAYED + END + POPUP "&Help" + BEGIN + MENUITEM "&About", IDM_ABOUT + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_ABOUT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 250 + VERTGUIDE, 25 + TOPMARGIN, 7 + BOTTOMMARGIN, 98 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDR_ACCELERATOR1 ACCELERATORS DISCARDABLE +BEGIN + "O", IDM_SINGLE_STEP, VIRTKEY, CONTROL, NOINVERT + "P", IDM_PAUSE, VIRTKEY, CONTROL, NOINVERT + "S", IDM_SHADOWS, VIRTKEY, CONTROL, NOINVERT + "T", IDM_TEXTURES, VIRTKEY, CONTROL, NOINVERT + "X", IDM_EXIT, VIRTKEY, CONTROL, NOINVERT +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/libs/ode-0.16.1/drawstuff/src/windows.cpp b/libs/ode-0.16.1/drawstuff/src/windows.cpp new file mode 100644 index 0000000..b136ddc --- /dev/null +++ b/libs/ode-0.16.1/drawstuff/src/windows.cpp @@ -0,0 +1,536 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#if defined(WIN32) || defined(__CYGWIN__)// this prevents warnings when dependencies built +#include <windows.h> +#endif +#include <process.h> +#include <ode/odeconfig.h> +#include <GL/gl.h> + +#include "config.h" +#include "common.h" +#include "resource.h" +#include "internal.h" + +//*************************************************************************** +// application globals + +static HINSTANCE ghInstance = 0; +static int gnCmdShow = 0; +static HACCEL accelerators = 0; +static HWND main_window = 0; + +//*************************************************************************** +// error and message handling + +static void errorBox (const char *title, const char *msg, va_list ap) +{ + char s[1000]; + vsprintf (s,msg,ap); + MessageBox (0,s,title,MB_OK | MB_APPLMODAL | MB_ICONEXCLAMATION); +} + + +static void dsWarning (const char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + errorBox ("Warning",msg,ap); + va_end (ap); +} + + +extern "C" void dsError (const char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + errorBox ("Error",msg,ap); + va_end (ap); + exit (1); +} + + +extern "C" void dsDebug (const char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + errorBox ("INTERNAL ERROR",msg,ap); + va_end (ap); + // *((char *)0) = 0; ... commit SEGVicide ? + abort(); + exit (1); // should never get here, but just in case... +} + + +extern "C" void dsPrint (const char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + vprintf (msg,ap); + va_end (ap); +} + +//*************************************************************************** +// rendering thread + +// globals used to communicate with rendering thread + +static volatile int renderer_run = 1; +static volatile int renderer_pause = 0; // 0=run, 1=pause +static volatile int renderer_ss = 0; // single step command +static volatile int renderer_width = 1; +static volatile int renderer_height = 1; +static dsFunctions *renderer_fn = 0; +static volatile HDC renderer_dc = 0; +static volatile int keybuffer[16]; // fifo ring buffer for keypresses +static volatile int keybuffer_head = 0; // index of next key to put in (modified by GUI) +static volatile int keybuffer_tail = 0; // index of next key to take out (modified by renderer) + + +static void setupRendererGlobals() +{ + renderer_run = 1; + renderer_pause = 0; + renderer_ss = 0; + renderer_width = 1; + renderer_height = 1; + renderer_fn = 0; + renderer_dc = 0; + keybuffer[16]; + keybuffer_head = 0; + keybuffer_tail = 0; +} + + +static unsigned CALLBACK renderingThread (LPVOID lpParam) +{ + // create openGL context and make it current + HGLRC glc = wglCreateContext (renderer_dc); + if (glc==NULL) dsError ("could not create OpenGL context"); + if (wglMakeCurrent (renderer_dc,glc) != TRUE) + dsError ("could not make OpenGL context current"); + + // test openGL capabilities + int maxtsize=0; + glGetIntegerv (GL_MAX_TEXTURE_SIZE,&maxtsize); + if (maxtsize < 128) dsWarning ("max texture size too small (%dx%d)", + maxtsize,maxtsize); + + dsStartGraphics (renderer_width,renderer_height,renderer_fn); + if (renderer_fn->start) renderer_fn->start(); + + while (renderer_run) { + // need to make local copy of renderer_ss to help prevent races + int ss = renderer_ss; + dsDrawFrame (renderer_width,renderer_height,renderer_fn, + renderer_pause && !ss); + if (ss) renderer_ss = 0; + + // read keys out of ring buffer and feed them to the command function + while (keybuffer_head != keybuffer_tail) { + if (renderer_fn->command) renderer_fn->command (keybuffer[keybuffer_tail]); + keybuffer_tail = (keybuffer_tail+1) & 15; + } + + // swap buffers + SwapBuffers (renderer_dc); + } + + if (renderer_fn->stop) renderer_fn->stop(); + dsStopGraphics(); + + // delete openGL context + wglMakeCurrent (NULL,NULL); + wglDeleteContext (glc); + + return 123; // magic value used to test for thread termination +} + +//*************************************************************************** +// window handling + +// callback function for "about" dialog box + +static LRESULT CALLBACK AboutDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, + LPARAM lParam) +{ + switch (uMsg) { + case WM_INITDIALOG: + return TRUE; + case WM_COMMAND: + switch (wParam) { + case IDOK: + EndDialog (hDlg, TRUE); + return TRUE; + } + break; + } + return FALSE; +} + + +// callback function for the main window + +static LRESULT CALLBACK mainWndProc (HWND hWnd, UINT msg, WPARAM wParam, + LPARAM lParam) +{ + static int button=0,lastx=0,lasty=0; + int ctrl = int(wParam & MK_CONTROL); + + switch (msg) { + case WM_LBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + if (msg==WM_LBUTTONDOWN) button |= 1; + else if (msg==WM_MBUTTONDOWN) button |= 2; + else button |= 4; + lastx = SHORT(LOWORD(lParam)); + lasty = SHORT(HIWORD(lParam)); + SetCapture (hWnd); + break; + + case WM_LBUTTONUP: + case WM_MBUTTONUP: + case WM_RBUTTONUP: + if (msg==WM_LBUTTONUP) button &= ~1; + else if (msg==WM_MBUTTONUP) button &= ~2; + else button &= ~4; + if (button==0) ReleaseCapture(); + break; + + case WM_MOUSEMOVE: { + int x = SHORT(LOWORD(lParam)); + int y = SHORT(HIWORD(lParam)); + if (button) dsMotion (button,x-lastx,y-lasty); + lastx = x; + lasty = y; + break; + } + + case WM_CHAR: { + if (wParam >= ' ' && wParam <= 126) { + int nexth = (keybuffer_head+1) & 15; + if (nexth != keybuffer_tail) { + keybuffer[keybuffer_head] = int(wParam); + keybuffer_head = nexth; + } + } + break; + } + + case WM_SIZE: + // lParam will contain the size of the *client* area! + renderer_width = LOWORD(lParam); + renderer_height = HIWORD(lParam); + break; + + case WM_COMMAND: + switch (wParam & 0xffff) { + case IDM_ABOUT: + DialogBox (ghInstance,MAKEINTRESOURCE(IDD_ABOUT),hWnd, + (DLGPROC) AboutDlgProc); + break; + case IDM_PAUSE: { + renderer_pause ^= 1; + CheckMenuItem (GetMenu(hWnd),IDM_PAUSE, + renderer_pause ? MF_CHECKED : MF_UNCHECKED); + if (renderer_pause) renderer_ss = 0; + break; + } + case IDM_SINGLE_STEP: { + if (renderer_pause) + renderer_ss = 1; + else + SendMessage( hWnd, WM_COMMAND, IDM_PAUSE, 0 ); + break; + } + case IDM_PERF_MONITOR: { + dsWarning ("Performance monitor not yet implemented."); + break; + } + case IDM_TEXTURES: { + static int tex = 1; + tex ^= 1; + CheckMenuItem (GetMenu(hWnd),IDM_TEXTURES, + tex ? MF_CHECKED : MF_UNCHECKED); + dsSetTextures (tex); + break; + } + case IDM_SHADOWS: { + static int shadows = 1; + shadows ^= 1; + CheckMenuItem (GetMenu(hWnd),IDM_SHADOWS, + shadows ? MF_CHECKED : MF_UNCHECKED); + dsSetShadows (shadows); + break; + } + case IDM_SAVE_SETTINGS: { + dsWarning ("\"Save Settings\" not yet implemented."); + break; + } + case IDM_EXIT: + PostQuitMessage (0); + break; + } + break; + + case WM_CLOSE: + PostQuitMessage (0); + break; + + default: + return (DefWindowProc (hWnd, msg, wParam, lParam)); + } + + return 0; +} + + +// this comes from an MSDN example. believe it or not, this is the recommended +// way to get the console window handle. + +static HWND GetConsoleHwnd() +{ + // the console window title to a "unique" value, then find the window + // that has this title. + char title[1024]; + wsprintf (title,"DrawStuff:%d/%d",GetTickCount(),GetCurrentProcessId()); + SetConsoleTitle (title); + Sleep(40); // ensure window title has been updated + return FindWindow (NULL,title); +} + + +static void drawStuffStartup() +{ + static int startup_called = 0; + if (startup_called) return; + startup_called = 1; + if (!ghInstance) + ghInstance = GetModuleHandleA (NULL); + gnCmdShow = SW_SHOWNORMAL; // @@@ fix this later + + // redirect standard I/O to a new console (except on cygwin and mingw) +#if !defined(__CYGWIN__) && !defined(__MINGW32__) + FreeConsole(); + if (AllocConsole()==0) dsError ("AllocConsole() failed"); + if (freopen ("CONIN$","rt",stdin)==0) dsError ("could not open stdin"); + if (freopen ("CONOUT$","wt",stdout)==0) dsError ("could not open stdout"); + if (freopen ("CONOUT$","wt",stderr)==0) dsError ("could not open stderr"); + BringWindowToTop (GetConsoleHwnd()); + SetConsoleTitle ("DrawStuff Messages"); +#endif + + // register the window class + WNDCLASS wc; + wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW; + wc.lpfnWndProc = mainWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = ghInstance; + wc.hIcon = LoadIcon (NULL,IDI_APPLICATION); + wc.hCursor = LoadCursor (NULL,IDC_ARROW); + wc.hbrBackground = (HBRUSH) (COLOR_WINDOW+1); + wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1); + wc.lpszClassName = "SimAppClass"; + if (RegisterClass (&wc)==0) dsError ("could not register window class"); + + // load accelerators + accelerators = LoadAccelerators (ghInstance, + MAKEINTRESOURCE(IDR_ACCELERATOR1)); + if (accelerators==NULL) dsError ("could not load accelerators"); +} + + +void dsPlatformSimLoop (int window_width, int window_height, + dsFunctions *fn, int initial_pause) +{ + drawStuffStartup(); + setupRendererGlobals(); + renderer_pause = initial_pause; + + // create window - but first get window size for desired size of client area. + // if this adjustment isn't made then the openGL area will be shifted into + // the nonclient area and determining the frame buffer coordinate from the + // client area coordinate will be hard. + RECT winrect; + winrect.left = 50; + winrect.top = 80; + winrect.right = winrect.left + window_width; + winrect.bottom = winrect.top + window_height; + DWORD style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; + AdjustWindowRect (&winrect,style,1); + char title[100]; + sprintf (title,"Simulation test environment v%d.%02d", + DS_VERSION >> 8,DS_VERSION & 0xff); + main_window = CreateWindow ("SimAppClass",title,style, + winrect.left,winrect.top,winrect.right-winrect.left,winrect.bottom-winrect.top, + NULL,NULL,ghInstance,NULL); + if (main_window==NULL) dsError ("could not create main window"); + ShowWindow (main_window, gnCmdShow); + + HDC dc = GetDC (main_window); // get DC for this window + if (dc==NULL) dsError ("could not get window DC"); + + // set pixel format for DC + + PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd + 1, // version number + PFD_DRAW_TO_WINDOW | // support window + PFD_SUPPORT_OPENGL | // support OpenGL + PFD_DOUBLEBUFFER, // double buffered + PFD_TYPE_RGBA, // RGBA type + 24, // 24-bit color depth + 0, 0, 0, 0, 0, 0, // color bits ignored + 0, // no alpha buffer + 0, // shift bit ignored + 0, // no accumulation buffer + 0, 0, 0, 0, // accum bits ignored + 32, // 32-bit z-buffer + 0, // no stencil buffer + 0, // no auxiliary buffer + PFD_MAIN_PLANE, // main layer + 0, // reserved + 0, 0, 0 // layer masks ignored + }; + // get the best available match of pixel format for the device context + int iPixelFormat = ChoosePixelFormat (dc,&pfd); + if (iPixelFormat==0) + dsError ("could not find a good OpenGL pixel format"); + // set the pixel format of the device context + if (SetPixelFormat (dc,iPixelFormat,&pfd)==FALSE) + dsError ("could not set DC pixel format for OpenGL"); + + // ********** + // start the rendering thread + + // set renderer globals + renderer_dc = dc; + renderer_width = window_width; + renderer_height = window_height; + renderer_fn = fn; + + unsigned threadId; + HANDLE hThread; + + hThread = (HANDLE)_beginthreadex( + NULL, // no security attributes + 0, // use default stack size + &renderingThread, // thread function + NULL, // argument to thread function + 0, // use default creation flags + &threadId); // returns the thread identifier + + if (hThread==NULL) dsError ("Could not create rendering thread"); + + // ********** + // start GUI message processing + + MSG msg; + while (GetMessage (&msg,main_window,0,0)) { + if (!TranslateAccelerator (main_window,accelerators,&msg)) { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + } + + // terminate rendering thread + renderer_run = 0; + DWORD ret = WaitForSingleObject (hThread,2000); + if (ret==WAIT_TIMEOUT) dsWarning ("Could not kill rendering thread (1)"); + DWORD exitcode=0; + if (!(GetExitCodeThread (hThread,&exitcode) && exitcode == 123)) + dsWarning ("Could not kill rendering thread (2)"); + CloseHandle (hThread); // dont need thread handle anymore + + // destroy window + DestroyWindow (main_window); +} + + +extern "C" void dsStop() +{ + // just calling PostQuitMessage() here wont work, as this function is + // typically called from the rendering thread, not the GUI thread. + // instead we must post the message to the GUI window explicitly. + + if (main_window) PostMessage (main_window,WM_QUIT,0,0); +} + + +extern "C" double dsElapsedTime() +{ + static double prev=0.0; + double curr = timeGetTime()/1000.0; + if (!prev) + prev=curr; + double retval = curr-prev; + prev=curr; + if (retval>1.0) retval=1.0; + if (retval<dEpsilon) retval=dEpsilon; + return retval; +} + + +// JPerkins: if running as a DLL, grab my module handle at load time so +// I can find the accelerators table later + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + ghInstance = hinstDLL; + break; + } + return TRUE; +} + + +// JPerkins: the new build system can set the entry point of the tests to +// main(); this code is no longer necessary +/* + +//*************************************************************************** +// windows entry point +// +// NOTE: WinMain is not guaranteed to be called with MinGW, because MinGW +// always calls main if it is defined and most users of this library will +// define their own main. So the startup functionality is kept in +// zDriverStartup(), which is also called when dsSimulationLoop() is called. + +extern "C" int main (int argc, char **argv); + + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + LPSTR lpCmdLine, int nCmdShow) +{ + drawStuffStartup(); + return main (0,0); // @@@ should really pass cmd line arguments +} + +*/ + + + diff --git a/libs/ode-0.16.1/drawstuff/src/x11.cpp b/libs/ode-0.16.1/drawstuff/src/x11.cpp new file mode 100644 index 0000000..2d6d313 --- /dev/null +++ b/libs/ode-0.16.1/drawstuff/src/x11.cpp @@ -0,0 +1,459 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// main window and event handling for X11 + +#include <ode/odeconfig.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include <X11/Xlib.h> +#include <X11/Xatom.h> +#include <X11/keysym.h> +#include <GL/glx.h> +#include "config.h" +#include "common.h" + +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#include <drawstuff/drawstuff.h> +#include <drawstuff/version.h> +#include "internal.h" + +//*************************************************************************** +// error handling for unix + +static void printMessage (const char *msg1, const char *msg2, va_list ap) +{ + fflush (stderr); + fflush (stdout); + fprintf (stderr,"\n%s: ",msg1); + vfprintf (stderr,msg2,ap); + fprintf (stderr,"\n"); + fflush (stderr); +} + + +extern "C" void dsError (const char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + printMessage ("Error",msg,ap); + va_end (ap); + exit (1); +} + + +extern "C" void dsDebug (const char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + printMessage ("INTERNAL ERROR",msg,ap); + va_end (ap); + // *((char *)0) = 0; ... commit SEGVicide ? + abort(); +} + + +extern "C" void dsPrint (const char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + vprintf (msg,ap); + va_end (ap); +} + +//*************************************************************************** +// openGL window + +// X11 display info +static Display *display=0; +static int screen=0; +static XVisualInfo *visual=0; // best visual for openGL +static Colormap colormap=0; // window's colormap +static Atom wm_protocols_atom = 0; +static Atom wm_delete_window_atom = 0; + +// window and openGL +static Window win=0; // X11 window, 0 if not initialized +static int width=0,height=0; // window size +static GLXContext glx_context=0; // openGL rendering context +static int last_key_pressed=0; // last key pressed in the window +static int run=1; // 1 if simulation running +static int pausemode=0; // 1 if in `pause' mode +static int singlestep=0; // 1 if single step key pressed +static int writeframes=0; // 1 if frame files to be written + + +static void createMainWindow (int _width, int _height) +{ + // create X11 display connection + display = XOpenDisplay (NULL); + if (!display) dsError ("can not open X11 display"); + screen = DefaultScreen(display); + + // get GL visual + static int attribListDblBuf[] = {GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE,16, + GLX_RED_SIZE,4, GLX_GREEN_SIZE,4, GLX_BLUE_SIZE,4, None}; + static int attribList[] = {GLX_RGBA, GLX_DEPTH_SIZE,16, + GLX_RED_SIZE,4, GLX_GREEN_SIZE,4, GLX_BLUE_SIZE,4, None}; + visual = glXChooseVisual (display,screen,attribListDblBuf); + if (!visual) visual = glXChooseVisual (display,screen,attribList); + if (!visual) dsError ("no good X11 visual found for OpenGL"); + + // create colormap + colormap = XCreateColormap (display,RootWindow(display,screen), + visual->visual,AllocNone); + + // initialize variables + win = 0; + width = _width; + height = _height; + glx_context = 0; + last_key_pressed = 0; + + if (width < 1 || height < 1) dsDebug (0,"bad window width or height"); + + // create the window + XSetWindowAttributes attributes; + attributes.background_pixel = BlackPixel(display,screen); + attributes.colormap = colormap; + attributes.event_mask = ButtonPressMask | ButtonReleaseMask | + KeyPressMask | KeyReleaseMask | ButtonMotionMask | PointerMotionHintMask | + StructureNotifyMask; + win = XCreateWindow (display,RootWindow(display,screen),50,50,width,height, + 0,visual->depth, InputOutput,visual->visual, + CWBackPixel | CWColormap | CWEventMask,&attributes); + + // associate a GLX context with the window + glx_context = glXCreateContext (display,visual,0,GL_TRUE); + if (!glx_context) dsError ("can't make an OpenGL context"); + + // set the window title + XTextProperty window_name; + window_name.value = (unsigned char *) "Simulation"; + window_name.encoding = XA_STRING; + window_name.format = 8; + window_name.nitems = strlen((char *) window_name.value); + XSetWMName (display,win,&window_name); + + // participate in the window manager 'delete yourself' protocol + wm_protocols_atom = XInternAtom (display,"WM_PROTOCOLS",False); + wm_delete_window_atom = XInternAtom (display,"WM_DELETE_WINDOW",False); + if (XSetWMProtocols (display,win,&wm_delete_window_atom,1)==0) + dsError ("XSetWMProtocols() call failed"); + + // pop up the window + XMapWindow (display,win); + XSync (display,win); +} + + +static void destroyMainWindow() +{ + glXDestroyContext (display,glx_context); + XDestroyWindow (display,win); + XSync (display,0); + XCloseDisplay(display); + display = 0; + win = 0; + glx_context = 0; +} + + +static void handleEvent (XEvent &event, dsFunctions *fn) +{ + static int mx=0,my=0; // mouse position + static int mode = 0; // mouse button bits + + switch (event.type) { + + case ButtonPress: { + if (event.xbutton.button == Button1) mode |= 1; + if (event.xbutton.button == Button2) mode |= 2; + if (event.xbutton.button == Button3) mode |= 4; + mx = event.xbutton.x; + my = event.xbutton.y; + } + return; + + case ButtonRelease: { + if (event.xbutton.button == Button1) mode &= (~1); + if (event.xbutton.button == Button2) mode &= (~2); + if (event.xbutton.button == Button3) mode &= (~4); + mx = event.xbutton.x; + my = event.xbutton.x; + } + return; + + case MotionNotify: { + if (event.xmotion.is_hint) { + Window root,child; + unsigned int mask; + XQueryPointer (display,win,&root,&child,&event.xbutton.x_root, + &event.xbutton.y_root,&event.xbutton.x,&event.xbutton.y, + &mask); + } + dsMotion (mode, event.xmotion.x - mx, event.xmotion.y - my); + mx = event.xmotion.x; + my = event.xmotion.y; + } + return; + + case KeyPress: { + KeySym key; + XLookupString (&event.xkey,NULL,0,&key,0); + if ((event.xkey.state & ControlMask) == 0) { + if (key >= ' ' && key <= 126 && fn->command) fn->command (key); + } + else if (event.xkey.state & ControlMask) { + switch (key) { + case 't': case 'T': + dsSetTextures (dsGetTextures() ^ 1); + break; + case 's': case 'S': + dsSetShadows (dsGetShadows() ^ 1); + break; + case 'x': case 'X': + run = 0; + break; + case 'p': case 'P': + pausemode ^= 1; + singlestep = 0; + break; + case 'o': case 'O': + if (pausemode) singlestep = 1; + break; + case 'v': case 'V': { + float xyz[3],hpr[3]; + dsGetViewpoint (xyz,hpr); + printf ("Viewpoint = (%.4f,%.4f,%.4f,%.4f,%.4f,%.4f)\n", + xyz[0],xyz[1],xyz[2],hpr[0],hpr[1],hpr[2]); + break; + } + case 'w': case 'W': + writeframes ^= 1; + if (writeframes) printf ("Now writing frames to PPM files\n"); + break; + } + } + last_key_pressed = key; // a kludgy place to put this... + } + return; + + case KeyRelease: { + // hmmmm... + } + return; + + case ClientMessage: + if (event.xclient.message_type == wm_protocols_atom && + event.xclient.format == 32 && + Atom(event.xclient.data.l[0]) == wm_delete_window_atom) { + run = 0; + return; + } + return; + + case ConfigureNotify: + width = event.xconfigure.width; + height = event.xconfigure.height; + return; + } +} + + +// return the index of the highest bit +static int getHighBitIndex (unsigned int x) +{ + int i = 0; + while (x) { + i++; + x >>= 1; + } + return i-1; +} + + +// shift x left by i, where i can be positive or negative +#define SHIFTL(x,i) (((i) >= 0) ? ((x) << (i)) : ((x) >> (-i))) + + +static void captureFrame (int num) +{ + fprintf (stderr,"capturing frame %04d\n",num); + + char s[100]; + sprintf (s,"frame/frame%04d.ppm",num); + FILE *f = fopen (s,"wb"); + if (!f) dsError ("can't open \"%s\" for writing",s); + fprintf (f,"P6\n%d %d\n255\n",width,height); + XImage *image = XGetImage (display,win,0,0,width,height,~0,ZPixmap); + + int rshift = 7 - getHighBitIndex (image->red_mask); + int gshift = 7 - getHighBitIndex (image->green_mask); + int bshift = 7 - getHighBitIndex (image->blue_mask); + + for (int y=0; y<height; y++) { + for (int x=0; x<width; x++) { + unsigned long pixel = XGetPixel (image,x,y); + unsigned char b[3]; + b[0] = SHIFTL(pixel & image->red_mask,rshift); + b[1] = SHIFTL(pixel & image->green_mask,gshift); + b[2] = SHIFTL(pixel & image->blue_mask,bshift); + fwrite (b,3,1,f); + } + } + fclose (f); + XDestroyImage (image); +} + +void processDrawFrame(int *frame, dsFunctions *fn) +{ + dsDrawFrame (width,height,fn,pausemode && !singlestep); + singlestep = 0; + + glFlush(); + glXSwapBuffers (display,win); + XSync (display,0); + + // capture frames if necessary + if (pausemode==0 && writeframes) { + captureFrame (*frame); + (*frame)++; + } +} + +void microsleep(int usecs) +{ +#ifdef HAVE_UNISTD_H + usleep(usecs); +#endif +} + +void dsPlatformSimLoop (int window_width, int window_height, dsFunctions *fn, + int initial_pause) +{ + pausemode = initial_pause; + createMainWindow (window_width, window_height); + glXMakeCurrent (display,win,glx_context); + + dsStartGraphics (window_width,window_height,fn); + + static bool firsttime=true; + if (firsttime) + { + fprintf + ( + stderr, + "\n" + "Simulation test environment v%d.%02d\n" + " Ctrl-P : pause / unpause (or say `-pause' on command line).\n" + " Ctrl-O : single step when paused.\n" + " Ctrl-T : toggle textures (or say `-notex' on command line).\n" + " Ctrl-S : toggle shadows (or say `-noshadow' on command line).\n" + " Ctrl-V : print current viewpoint coordinates (x,y,z,h,p,r).\n" + " Ctrl-W : write frames to ppm files: frame/frameNNN.ppm\n" + " Ctrl-X : exit.\n" + "\n" + "Change the camera position by clicking + dragging in the window.\n" + " Left button - pan and tilt.\n" + " Right button - forward and sideways.\n" + " Left + Right button (or middle button) - sideways and up.\n" + "\n",DS_VERSION >> 8,DS_VERSION & 0xff + ); + firsttime = false; + } + + if (fn->start) fn->start(); + +#if HAVE_GETTIMEOFDAY + timeval tv; + gettimeofday(&tv, 0); + double prev = tv.tv_sec + (double) tv.tv_usec / 1000000.0 ; +#endif + + int frame = 1; + run = 1; + while (run) { + // read in and process all pending events for the main window + XEvent event; + while (run && XPending (display)) { + XNextEvent (display,&event); + handleEvent (event,fn); + } + +#if HAVE_GETTIMEOFDAY + gettimeofday(&tv, 0); + double curr = tv.tv_sec + (double) tv.tv_usec / 1000000.0 ; + if (curr-prev >= 1.0/60.0) + { + prev = curr; + processDrawFrame(&frame, fn); + } + else + microsleep(1000); +#else + processDrawFrame(&frame, fn); +#endif + }; + + if (fn->stop) fn->stop(); + dsStopGraphics(); + + destroyMainWindow(); +} + + +extern "C" void dsStop() +{ + run = 0; +} + + +extern "C" double dsElapsedTime() +{ +#if HAVE_GETTIMEOFDAY + static double prev=0.0; + timeval tv ; + + gettimeofday(&tv, 0); + double curr = tv.tv_sec + (double) tv.tv_usec / 1000000.0 ; + if (!prev) + prev=curr; + double retval = curr-prev; + prev=curr; + if (retval>1.0) retval=1.0; + if (retval<dEpsilon) retval=dEpsilon; + return retval; +#else + return 0.01666; // Assume 60 fps +#endif +} + + + diff --git a/libs/ode-0.16.1/drawstuff/textures/checkered.ppm b/libs/ode-0.16.1/drawstuff/textures/checkered.ppm Binary files differnew file mode 100644 index 0000000..f5428fb --- /dev/null +++ b/libs/ode-0.16.1/drawstuff/textures/checkered.ppm diff --git a/libs/ode-0.16.1/drawstuff/textures/ground.ppm b/libs/ode-0.16.1/drawstuff/textures/ground.ppm new file mode 100644 index 0000000..5154c31 --- /dev/null +++ b/libs/ode-0.16.1/drawstuff/textures/ground.ppm @@ -0,0 +1,6 @@ +P6 +# Created by Paint Shop Pro +256 256 +255 +››”‹„‹œ››¦§¨œ¤¦ƒ„„œ¤¦œ¤¦ƒ„„œ¤¦„„Š“““¦§¨›”›“Œ”¦§¨mtt‹…’œ››‹’Š’ŒŒ”š”‚v{œ¤¦‘ˆ}”››{{tdc\„Š„‹‹‹„Š}dc\…‹‹„Š„‹’Š”››„Š}¦§¨ƒ||UTSu{{bVU{{t‹„„„Š„|„…Œ”•lritt{‹‹‹‹‹‹zllf]c‹„‹“Œ”SKJŒ‹“™š¤Œ”•‹…’|„…{ttlekzll””‹‹‹„|‚z[[Ttslƒƒ|uztœ¤¦‹’ŠlriŒ”•„Š„””‹ƒ„„“““ƒƒ|ƒƒ|“Œ”ƒ‚uƒ||ƒ}ƒƒ}ƒ¨©´„„Šmtttts“Œ”lks}|’Œ‹“lekŒ‹“›”›‹‹‹lld|‚z”š”|‚zSKJ]bZƒ}ƒttsddc{tt[TTult{tttll‚v{tllŠƒ}cbV‹„„dc\lrijcVsre[TTsleSKJj]\\[[¦§¨:97*)(ztlJHFlddJHFVTL‘…„bVUVTLddcb[U…‹‹lrib[Uultmttlldllklld|„…dc\|‚z‹‹‹mtt“““‹‹‹Œ”•tslƒƒ|‚|utts‹„‹ddc„Š„{{tŒ”•mtt\UZ‹„„‹„„Œ‹“‹„„lj‘Œ…ƒ||ŠŠ}ttslldkd\lddult|‚z|‚zu{{ek]ƒƒ|lri|‚zztltsltslztl[[T„„Š{u{Œ”•]bZldd]cddc\mttUMRlddƒ}ƒVZTSKJD;9mttlld\[[Œ”•JHFUTSJHF[TT‹‹‹Œ‹“Œ”•‹„„ƒ||Œ”•œ¤¦tzlŒ”•mttŒ‹“|„…lksddc|„……„’“Œ”Œ”•{{ƒ}‡’|„…œ§²}|’”“›™š¤|„…}|’|„…„„Š{{ƒ›²„„ŠŒŒš™š¤„†™Œ”•™š¤›²{{ƒ{{ƒŒ”•}‡’…‹š¬¶Ã™š¤™š¤¬¶Ãœ§²…‹‹tts“Œ”llk“““‹‹„{{tš””{||„Š„ƒ||‹‹‹{||…‹‹”š”„Š}¤¤¦§¨›¢›¦§¨«²«‹’Šmttd\\tllultVTL‹„‹ƒƒ|‹‹„cbVœ››{ttƒ}ƒ{ttµ¶·“Œ”ult‹„‹r]gultf]c‹’Šƒ„„bVU‘ˆ}Š}ƒtll“Œ”„Š„tlllekztl{{t{tt”››mttult“Œ”{u{tllultŠƒ}{||‹„‹‹„‹“Œ”{{ƒŒŒšldd…‹’{{ƒ™š¤]cdƒ}ƒ“Œ”£œ¥ª³·…‹‹¦§¨ª³·‹„„{{ƒ‹„‹ƒ„„|„…u{{„„Š…‹‹{{ƒlksŒ”•”“›ª³·ƒ„„’…‹‹‹‹‹„„UUYldddc\ŠŠ}{{t‹‹„‹„‹‹„„’ŒŒ‘…„ultŠƒ}sre{zmttsj]\VTL„Š„SKJrg]iWU‚v{ekd¦§¨:97$kd\uztultultlddbVUVTLSKJkk]ŠŠ}‘Œ…ŠŠ}››”ztlVTLtzl{||lld‚|utts””‹tsl‹‹‹‹‹‹tsl…‹‹dc\tzlsle|„…u{{ekdtyglri”“›{||]cd{u{tzl‚v{ztl{{t|‚z‹„‹‚v{‚|uƒ||VTLddcb[UbVZ|‚z[TT[[Tlri{tt{u{rfklldttsd\\ult‹„‹‹„„{tti\Vredtzlllk{{ƒiq]{ttdc\ekddc\ztlƒ„„tzl]cd…‹‹JHFjcVLKRŠƒ}™š¤¦§¨uzt{{ƒ”“››¢›mttd\\\[[|„…|‚zuztnv‚mttlks{{ƒ„„Šœ¤¦}‡’^^qŒ”•mttddcŒ”•ŒŒš{{ƒnv‚}|’|„…lks}‡’…‹’yl„nv‚›²ª³·…„’ª³·nv‚Œ‹“}‡’{{ƒŒ—£Œ”•ª³·™š¤™š¤™š¤Œ”•ŒŒš“““Œ‹“Œ”•edk{{ƒ”“›Œ”•f]c|‚z‚|u”š”ƒƒ|{{t””‹ƒ„„ƒƒ||„…””‹„Š}{||JHF|„…{{ƒultredƒ}ƒŒ”•|‚z{||ª³·“Œ”ƒ}ƒzll›¢›‹’Š‹’Šƒ„„’…‹‹„‹|‚z„Š}jcVtll„Š}¤¤‰‰w{||„Š}ttsmttœ¤¦u{{tt{ttsu{{VTLlrimtt\[[|‚zlrilldmtttt{lks|„…tsl|„…„Š„™š¤‹…’\[bf]c‹…’lkslriƒ|||„……‹‹lks‹’Šƒ}Šdc\ultƒ}Š{u{tts…„’ŒŒš”š”‹’Šu{{ddc|„…‹‹‹‹„‹UUYŠƒ}]bZtslddc“Œ”slesre‹„„‚v{lddslecbVSKJ{{tdc\kd\tzltslƒ||‰v|j]\[[T“Œ”:97:97cbVlrid\\tlltllldd[[T|‚zcbV„„Š””‹‹’ŠŠŠ}£››ŠŠ}“““{||lkscbV””‹„Š}tzl{u{ƒ„„{tt„Š}ekd{{tek]f]c{u{‹’Šddctll{u{lekƒ}ƒtll‹‹„dc\‹„„{tt{||{||ult‰v|ultult]bZ‹‹„‘Œ…{||tzledk]cd…‹‹‹‹‹fkktllsle[[T\[[ttslriekdmtt|„…tsllri\[[b[U{{t‹„‹‹‹„uzt[[Tddc[[T|‚z{{ƒd\\UTSult{tt{{tyl„lkstt{ult|„…|„…{{ƒ{{ƒ{{ƒ|„…{{t{{ƒŒ”•lks{{ƒ…„’Œ”•|„…nv‚{{ƒ|„…Œ—£fkk…‹’{{ƒ}|’^fsŒ”•™š¤Œ—£lkslksnv‚}‡’™š¤Œ—£Œ—£Œ—£|„…nv‚}‡’¡¡»ÂÇ»ÂǪ³·œ¤¦Œ”•ekd¦§¨…‹‹uztƒ„„‹‹„¦§¨“Œ”‚utlld‹‹„”“›Œ”•„Š}™š¤™š¤{{ƒ™š¤”š”œ¤¦„Š„ddcedkddclritsl{{ƒŒŒš‹‹‹‹‹‹lek””‹‚|u‹‹„lddztlred’ŒŒ‚|uŒ‹“]bZtslSKJf]cœ››‘ˆ}œ¤¦[[T‰v|“Œ”ƒ||{{ƒ‹„‹ƒ}ƒŠ}ƒult“Œ”f]c[TTlddd\\ƒ||\[b[TTUMRult|„…£œ¥¦§¨š””ƒ||¦§¨lld“Œ”‹‹‹|„…lksd\\{tttt{{|||„…‹‹‹ƒƒ|‹‹‹{u{rfkŒŒštt{ª³·|„…›¢›…‹‹|„…‹’Š”››uztf]clddrfk{{tsle‹„‹‘Œ…tll‚|urfkzllb[Ukk]ztlztldc\cbV|‚z{{tbVZ[TTSKJ‚utllk¦§¨LKR*)(rg]llk‹’Šlekult{u{VTLVTLllkƒƒ|uztVTLVTLedk|‚z{{t”“›‹„‹tsl|‚z|‚z“““ddcddcekd”š”VTLlri‹‹„f]cult…‹’ƒ„„tslŠƒ}™š¤{{ƒztl{{ttslƒ||sle]cdtll{{t{{tultŠ}ƒ|‚z{{tult{||mttVZ[JHF]bZ|„…lks‚v{f]cekdtt{‹„‹tll[[Tƒ}ƒƒ||Œ‹“{{ƒ{u{{{t]bZ{tt””‹¤¤‚|u‹’Štts‹‹„lld]bZ\[bSKJlksd\\tll“Œ”{{ƒttsu{{Œ”•tslu{{{{ƒmttek]}‡’„„Š|„…{{ƒ„†™u{{Œ”•Œ”•mtt|„…„„Šttsmttyl„nv‚^^q\[b\[bnv‚tt{†~‘u{{}‡’\[bnv‚n…œ§²Œ—£œ§²n…œ¤¦œ››Œ”•”š”‹’Š‹‹„{{tŒ”•”š”¨©´œ¤¦ƒ„„™š¤{||Œ‹“’ŒŒ“Œ”…‹’Œ‹“‹‹‹”š”™š¤œ››ƒ}ƒ‚utult™š¤lekddc…„’„„Š„„Š”“›{{ƒ‹„‹tsl‹„„‹‹„“““{{tƒ„„leklks¦§¨{tt¨©´‹„„“Œ”’…‹‹„‹„„Š|„…£››Š}|“““ƒ}ƒ²¬µbVZultlksŒ—£ƒ„„„„Šedktsl{{t…‹‹lks|„…llkdc\ttsfkk|‚z|‚zuztuztztllld››”{tt¦§¨u{{|‚zƒƒ|“““Œ‹“””‹‹„„„Š„tt{“Œ”…‹‹™š¤‹’Šuztœ¤¦œ¤¦{u{‹’Š„„ŠŒ”•‹’Šdc\{u{ƒƒ|‹‹„lldtt{£››‚v{ƒ||j]\‚ut{{trg]PF=]bZ[TTlri{{t{{tddcSKJbVUlldUTS¦§¨JHF*)(d\\ŠŠ}‹‹„{tt‹„‹lddlldsref]cf]clritslsleƒ„„llkš””„Š„u{{‹‹‹ekdlrilrimttlks{zm|‚z‹’ŠaWM‹„„lek‹…’|„…red\[[dc\ttsUTSš””››”‹„‹Š~‹tsl›”›‹„„kk]ult{{tƒƒ|ultd\\‚|uultf]cLKR:97MRKŒ”•“““›¢›””‹llk‹’Š{||{{ttzllri\[[llktslu{{¦§¨ƒƒ|ƒ„„œ››[[Tztlƒ‚u{{ƒ[[Tlrirfk\[[VTLmtt‹’Š{||‚v‚ƒ}ƒ‹„‹{{t|„…uzt”››]cd|„…tt{fkk{{ƒ|„…{{ƒŒŒš{{ƒ|„…Œ—£~’“‰Š¡|„…”“›|„…ttsnv‚…‹’}‡’}‡’{{ƒŒŒšnv‚lks{{ƒ…‹’™š¤}|’…„’ƒ}ŠŒŒšnv‚mk…Œ”•Œ”•™š¤ƒ}ƒƒ„„Œ”•{{t™š¤‹’Š«²«œ¤¦™š¤Œ‹“…‹‹™š¤¦§¨”“›tts‹‹‹llk™š¤”“›{{ƒƒ}Šult£œ¥{{ƒlks|„…\UZ£œ¥’ŒŒ¨©´”“›‹„‹“Œ”£œ¥tts£œ¥“Œ”|„…œ››œ››²¬µ£››f]c“““red|‚zuzttts{{tJHFƒ||’…‹lddldd{ttultSKJ‹„‹›”›VZT{u{uzt…‹’{{ƒ|„…ƒ‚u”“›““““Œ”ƒ}ƒ‹‹‹|‚z£œ¥ƒ„„œ¤¦uztƒ}Š|„…‚v{‹…’|„…Œ‹“…‹’tt{edk|„…lks‹„‹{{ƒmtt]cdŒ”•|„…{{ƒtt{tll{{tmtt„Š}‹„‹lldrfk„Š}Š}ƒŒ”•ultrfk‘Œ…ztl””‹Šƒ}ztf{zmd\\|‚zdc\dc\]bZƒ}ƒaWMtt{\UZFD;™š¤?;C?;Cred””‹lldj]\f]ctlllldƒ„„{{ƒllk„„Šekdƒ||j]\ultlektt{\[[ldd…‹‹tygek]ult\UZ]bZƒ||lridc\{ttult…‹‹„Š}{u{rfk…‹’lri|„…ult‹‹„{||ƒ||tslŒ”•|„…ƒ‚uƒƒ|{{tdc\cbVƒ„„¦§¨„Š„„Š„MRK*)(UTSlldƒ„„”››mtt„Š„ddc”“›ekdllkttsllk{u{]bZƒ„„\[[…‹‹‚|u””‹„Š}ƒƒ|‹„„ddcleklldŠƒ}kjVSKJUMR‹’Šƒ}ƒ™š¤£œ¥…‹‹tts|„…|„…Œ‹“lks{{ƒ“Œ”u{{‹‹‹mtt†~‘Œ—£Œ”•Ž¡›}‡’}‡’™š¤¨©´…‹‹|„…^^q}‡’n…tt{Œ—£{{ƒ…‹’™š¤™š¤“Œ”…„’Œ—£™š¤Œ”•|‚zu{{Œ”•ƒƒ|ª³·‹’Š›¢›‹„„{||‹’Š|„…”š””››|‚z‹„‹œ››ƒ„„¦§¨²««¨©´™š¤llk„„Štt{œ¤¦œ§²’…‹Œ”•‹…š‹’Š|„…lks‚v‚ttsllk”“›™š¤“““…‹‹…‹‹ƒ||›¢›‹’Š‘…„’ŒŒƒ„„red£›››”›sre””‹’ˆ{{t{zmuztlddlldsle„Š„\UZtts‰Š¡tts|„…{u{{{ƒ‹…š’ŒŒ“Œ”‹„‹{{tuztƒ„„¦§¨””‹{tt‹‹„ƒƒ|rg]kk]ƒ„„’ŒŒ‹’Š“““™š¤¨©´”››¨©´|„…„„Š{{tœ¤¦…‹’”š”Œ‹“|„…|„…u{{fkk‹’Š”››”š”mtt|„…ª³·‹‹‹JHF‚v{™š¤tzli\VtslbVU‚v{”š”rfkr]gyleSKJtsl\[[„Š„leklldƒƒ|JHFztfb[U]bZ[[T¦§¨UUY:97lldsleuztrfkr]gekdVTLj]\d\\\[bdc\‚|u””‹ƒ||{u{{||tsl|„…‰ƒv[TTkk]lri‚|u|‚zu{{{tttsl{tt‹‹‹’…‹{||‹‹‹ultsle{u{\[[|„…‹‹‹…‹‹¦§¨š””ƒƒ|‹„‹{||ekd“““bVU‹’Šƒ„„“““lldtts{ttJHF:97o€wVTLuzttzlƒƒ|‹‹„lldrg]j]\ƒ‚usreJHFlrillkrg]dc\’ŒŒ‘Œ…ŠŠ}ddcƒ„„|‚z]bZ|„…mttSKJmwf]cf]clkslks“Œ”„„Š‹’Š|‚z|„…ult{{ƒ{{ƒƒ„„{||‹’Š…„’mttŒ—£{{ƒ}‡’„„Šn…{{ƒyl„Œ‹“mtt|„…{{ƒ}|’nv‚™š¤Œ—£^fs{{ƒ…‹’mtt¨©´™š¤Œ—£œ§²…„’Œ—£}|’lksedk›¢›“Œ”””‹“““›¢›œ¤¦··Ä‹„„™š¤„„Šƒ}ƒ£²£››¨©´”“›¨©´‹…’tts{{ƒmtt{{tŒ”•‹‹„llk”š”…„’ztl{{ƒ\[bŒ‹“bVZred{||ztl‹’Š¤¤¦§¨„Š„””‹u{{ekdlek”“›mttœ¤¦Œ”•tslœ¤¦Œ”•lriu{{tts{||’ŒŒ…‹’{u{\[b‹…’{u{{{ƒ|„…ŒŒš…‹‹f]ctll”š”Œ”•|‚z]cd|„…edk|„……„’{{ƒ”››ttsŒ‹“u{{{{ƒŒ‹“{{ƒ²¬µ™š¤„„ŠŒ”•lek‹’Š››”tts…‹‹mttlkstt{„Š„Œ”•„Š„lriddc|„…|„…uzt™š¤sreUMR„„Š|„…tllbVUƒ||Š}ƒ“““SKJ‚utŠƒ}kd\‚wlultdc\“Œ”‹‹„””‹llkPF=]bZSKJVTL¨©´f]c:97lekztl‘Œ…ƒ‚uƒ„„‹‹‹tzllek[TTf]clks]bZ””‹‹‹„u{{{{ƒtsltll{||Š}|„Š}\[[u{{“Œ”mttVTL„Š}{tt‹„„‹‹„{{ƒ‹„‹œ››srettsLKRmtt{||sletzl‹‹„””‹“Œ”†~‘ulttts‹„„lks“““‹„„›”›f]cbVZUTSVTL[TT]cdƒ}ƒƒ||lddf]c{tt“Œ”[TT[TT{u{d\\UMRJHFJHFlekekdŠƒ}tzl]cdkd\ultu{{„Š„„Š„r]gf]cJHFddclrilriultŒ‹“Œ‹“…‹’Œ”•„vŒ{u{\[blks|„…mtt|„…]cdmttŒŒšmtt…‹‹Œ—£ƒ}Š™š¤…„’|„…|„…\[bmttOS`Œ—£lksŒ—£{{ƒ™š¤}‡’¨©´œ¤¦¬¶Ã…‹š|„…{{ƒŒ—£œ§²…‹šƒ}ƒ‹…’£²¨©´Œ”•›¢›œ¤¦‹„„›”›“““tts›¢›”“›“Œ”‹„„“Œ”slekk]”“›ƒƒ|tt{tts‹’Š{||uzt“““‹‹„ultztlekdtll{tttslƒ||››”‹‹‹ƒ||£œ¥”“›f]c“Œ”‹„„““““Œ”‹„‹“Œ”tt{„vŒlddJHFMRKfkkiq]uzttts™š¤Œ‹“lks™š¤\[b]bZlksultŒ—£]cdlri]cdSKJbVU‹„„MSS{{ƒ|„…\UZult|„…Œ”•tt{u{{ŒŒšƒ„„{u{lddŒ‹“mttlld‹„‹{||””‹œ››lrilri””‹|‚z‹‹„lldtsldc\dc\ƒƒ|mtt|‚zuztSKJtllkd\{ttultzlliWUztlsleSKJzllslekd\‚v{ekdtslUTS]bZllkVTLd\\VTLek]…‹‹\[b*)(f]credtllsre{{tekd[TTddcult‹„‹dc\dc\tsltsl|‚zu{{‹’Š„„Šƒ}ƒsreƒ‚u››”Œ”•ztl„Š„””‹‹„„ŠŠ}b[Ub[UŒ”•\UZlekulttt{„Š}|‚z„„Š„„Š”š”{u{ƒƒ|™š¤sletslsreœ¤¦“““’ŒŒƒƒ|{u{f]cedkUUYUMR|„…{{ƒ…‹‹Œ‹“lri„Š„ztl{u{|‚ztllUMR‹’ŠVTL\[[ƒƒ||‚zkd\sle””‹llk[TTult{tt“Œ”kd\D;9edkJHFllkd\\sretts|„…Š}ƒœ››llklkslks\[b}‡’ekd…‹’{{ƒo€w…‹’¦§¨|„…{{ƒlks{||ult{{ƒmttmtt^fsu{{}|’}‡’nv‚nv‚|„…|„…mttœ¤¦}‡’œ§²}‡’Œ”•¬¶Ã„„ŠŒ—£Œ”•|„…Œ‹“ª³·Œ”•„Š„›²œ¤¦··Ä™š¤uztlriœ¤¦Œ”•ƒƒ|„„Š„Š„tzl””‹b[Uƒ||ƒ„„Š~‹ƒ„„u{{‹’Š{||‹„„lks™š¤lek„„Š…‹‹™š¤“Œ”ztlƒ||¤¤¦§¨””‹lri‹„‹¨©´””‹”“›£››ƒƒ|{{tdc\¦§¨ultŠŠ}‹„„„Š„‹„„ƒƒ|››”|‚zƒ}ƒœ››ƒ„„Œ‹“lek]cd\[bUTStt{ƒ}Š{{tSKJ[TTtt{lldŒ”•fkkŒ—£Š~‹Œ”•{{ƒŒŒšŒ”•“““‹…’ult”“›ttsultƒ||\[bultf]c‹„„…„’u{{{u{|„…™š¤tt{ttslddŠ}|‹‹„|‚zdc\j]\d\\VTLlri¤¤{ttf]ctslldd‚v‚š””ztl{ttldd‹„‹‚v{cbVuztƒ}ƒtllVTLllktsl¦§¨\[b)+2mtt‚|utlltsllekb[Urg]ƒ‚uƒ„„{||dc\ek]|‚z“Œ”¨©´›”›™š¤‹„‹zllsreƒƒ||„…{|||‚z|‚z‚|uƒ‚ulldztlttstt{ultttsulttt{rg]ƒ||{u{”“›‘Œ…’…‹ƒƒ|ult‚v‚Œ”•red’ŒŒŒ‹“‹„‹ldd’ŒŒ‹„‹ƒ}ƒd\\[TTƒ||ƒ}ƒlek|„…‹‹‹lri{u{lld{||\[[ek]SKJtsl[TTb[Ulld|„…dc\ƒ‚usresle\UZldd{u{ztltsl[TT>B9o€wulttslnv‚“Œ”£œ¥Œ‹“Œ‹“…„’ŒŒš}‡’{||”“›Œ”•|„…ultnv‚Œ”•™š¤{{ƒ„†™™š¤…„’ŒŒšŒ”•u{{u{{|„…lksmk…Œ—£œ§²{{ƒ‰Š¡Œ”•}‡’{{ƒ™š¤Œ”•˜Ž£™š¤™š¤ŒŒš™š¤„Š„|‚z”››œ››{||”š””š”£››‹„‹““““““redƒ„„…‹‹‹‹„{u{‹’Šlri””‹‹„„|‚zƒ||‹‹„š””{tttslƒ||ƒ„„™š¤„„Š{tt„Š„sle‹‹‹’ŒŒ‹’Šz‚l”››ƒƒ|uzt¦§¨ŒŒš{u{’ŒŒ›”›{u{„Š„ztl{{tlldœ¤¦ƒ‚usle“““sleŠŠ}tt{j]\f]cf]cultult™š¤˜Ž£lks{ttedk\[b{{ƒllkddc]bZ{{tlld{ttƒ}ƒ¦§¨‹„„]cd„„Š{u{tts…‹‹UTS|‚ztts“““uztekdlld|„…›¢›ztl\[b‹‹„£œ¥“““‹‹‹„„Šmtt›¢›lksSKJ{ttlrikk]dc\UUYsle[[TjcVmttkd\ƒ||rg]tts{||‹‹„tllsleJHFddcdc\b[Uult{||›”›\[[:97‹„„zll{{ttslztlsreUMRztltts\UZ{{t{{tttslekŠ}|”“›ult…„’{{tŠƒ}kk]d\\{u{„‰vtzlŒ”•‹„„tslzlllrif]c‹„‹‚|u‚utUTSult‹‹‹tzl“Œ”’ŒŒ“““Œ‹“f]cƒ||‹‹‹‹„‹‹„„ult{u{{u{ƒƒ|Š}ƒldd[TTSKJ{{t“Œ”Š~‹ztl{tt{ttreddc\{tt‹„„‹…’‹„„””‹{||uztSKJ{zmek]lrittsldd‚v‚u{{UMRultD;9UTSLKRlri…‹’›¢›{u{{u{’ŒŒ{{ƒŒ”•{{ƒtt{lekttslriƒ}ƒtts]cd{{ƒu{{{{ƒlks˜Ž£‰Š¡„†™‹„‹¦§¨ª³·mtt{{ƒ^fsœ¤¦…„’…‹’…‹šŒŒš|„…œ¤¦Œ—£mttœ¤¦Œ”•œ¤¦{{ƒŒ”•~’“™š¤tt{…‹‹”“›tllƒ„„“Œ”Œ”•ŒŒš“Œ”„„Š{{ƒ‹…’Œ‹“””‹{|||‚zedk|„…|„…¦§¨„Š„{tt“Œ”’ŒŒ£››ƒ„„SKJ’ŒŒš””{ttŠ}|j]\tllJHF{{ƒ™š¤{{ƒlri|‚zdc\ƒ„„tsl{||{{ƒ‹’Š„„Š{{ƒkd\ztl””‹š””„„Š…‹‹\UZƒ}ƒƒƒ|{||f]c‚v‚Š~‹f]c{{ƒ˜Ž£¦§¨{tt”››ƒ||lek‚|u{ttuztult…‹’ttsŒ”•ƒ}ƒƒ||Š}ƒƒ}ƒ””‹lldƒ}ƒ{tt‹…’™š¤“Œ”u{{ultlks’…‹“““Œ”•{{ƒ‹„„œ››‹‹‹Œ”•tts|‚z\UZllk[TTddctsl]bZtzlSKJreduzt”“›u{{lddŠ}|‹‹„{ttekd‹„„ztfred[[T{{tek]redllkŠƒ}¦§¨[TT:97‹‹„zll””‹kk]d\\kd\lldred\[bf]clldlri{u{„„Š’ŒŒ{||tzllddœ¤¦f]cƒƒ|llkult’ŒŒ{zmztl”“›ŠŠ}‚v{kd\tts‘…„£œ¥lks‹„‹ƒ}ƒmttu{{mttuzt‹„„ƒ„„]cd‹„„’ŒŒult‚ut|„…“““ƒ„„¤¤„Š„„Š„ƒƒ|[[T|„…{ttƒƒ|ƒ„„{||ƒ||lri„Š„ƒ||‹…’ztlbVZ“““[[T‹‹„ƒ||cbVlldMRKd\\ekdƒ}ƒƒ„„SKJj]\SKJUMRultƒ„„{zmƒƒ|mwŒ‹“Œ‹“{{ƒŒ”•ƒ}ƒƒ}Šult…‹‹…„’„†™Œ‹“‹‹„{{ƒƒ„„›²„„Š|„…œ¤¦…„’”“›”››Œ”•]cd]cd}‡’lkslks…„’tt{˜Ž£{{ƒ\[b{{ƒf]c…‹’mtt™š¤„„Š…‹‹™š¤{zmƒ}Š‚v{”“›„„Š…‹’œ¤¦œ¤¦™š¤¨©´¨©´¬¶Ã“““‹’Š¤¤‹’Š‹’Š¨©´‹‹‹ª³·œ¤¦›¢›{zm‹’Š‹‹„ƒ„„“Œ”tts|„…„„Š]cd“Œ”„„Šlek…‹‹tsltt{ztltts|‚ztsl{zm£››£œ¥tsl‹‹‹ultu{{tll‰|vƒƒ|tlltsl{{ƒŠŠ}b[U‰Š¡™š¤“Œ”‹…š‚v{ƒ}ƒ‚v{ldd”“›{{ƒ”“›…‹‹fkkƒ}ŠUTSƒ}ƒ“Œ”‹„‹“Œ”‹‹‹{|||„…„„Šllk{tt{{t‹„‹š””£››‹„‹£››ƒ}ƒtlllek‚v‚ƒ}Šldd{u{ƒ||tt{Œ‹“|„……„’‹‹‹{u{‹„„cbV„„Š|„…lldiq]jV[Šƒ}”››››”ztl‹„„tslSKJ‚utVTLlri‚v‚lriUTSlddJHFFD;llktts›¢›SKJ:97lld{u{Œ”•‘…„£››ƒ||rg]JHFlek[[T|‚zekdldd™š¤bVU‹‹‹|‚zVTLek]|‚zdc\…‹‹|‚z„Š}‹‹‹‹‹„š””ƒƒ|ƒƒ|tsl‹‹‹…‹’£œ¥tll‹„‹‹‹‹„„Š‚ut{||tt{‹‹„llk“Œ”ekd‘…„tllƒ‚uƒ„„{{t[[Tœ››{{ƒ…‹‹|‚z{{ƒVTLtt{””‹tllttsŠ}ƒtsl“Œ”{tttts[TTyl„{u{lddekdVTLUMR‚wlsre{u{kd\lksu{{\UZf]csleg\rred™š¤mtt‚v{{||Œ‹“{u{ƒ}ƒƒ||lek{||{{ƒ{{ƒŒ‹“™š¤{||‹…š}‡’‹„‹„„Š{{ƒ…‹šŒ”•tt{„„Š…‹’|„…mttmtt^fs{{ƒ‰Š¡|„…„„Š{{ƒ{{ƒŒ‹“Œ”•{{ƒ¦§¨|„…Œ‹“Œ”•‹‹‹¨©´¦§¨™š¤…‹’™š¤¨©´„Š„›¢›}‡’¦§¨¨©´··Äƒ„„‹‹‹ƒ}ƒldd‚v{‹‹‹‹’ŠšŒ›¢›””‹™š¤tlluzt“Œ”tsl{{tf]cJHFf]cult¦§¨Œ”•tt{œ¤¦Œ”•œ››ƒ‚u”š”Œ”•‹‹‹ƒƒ||„…œ¤¦™š¤”“›[[Tsle[[Tkd\f]c‹„„›”›“Œ”Œ‹“ƒ||tt{\UZ{{ƒ|„…\[blkslri]bZ¦§¨ttssle{ttŒ”•tts„Š„zllkd\tllultŠ}ƒlekmttedk“Œ”{{ƒ“Œ”{{ƒ{{ƒ…‹‹{{ƒlld¨©´ƒ„„|‚z„Š„lld‹‹‹¦§¨¦§¨œ››lri¦§¨tts…‹‹‹’ŠcbVUTStt{|‚z\[[{{t\UZ{ttttssre„Š„slerfkƒ||‚|u{ttƒ„„fkkddc[[Tllkz‚lmttlriztl¦§¨UMR:97ƒƒ|‚|ukd\ztlu{{šŒylekd\{tttll„Š„ek]llk|„…{ttƒ||{||‚wl„Š}]bZ‹’Šlriuzt…‹‹””‹ldd”“›ƒ}ƒ{{t‚|u‹„‹uztult“Œ”{{ƒult{||”š”ƒ||“““ƒƒ||‚z{{ƒf]czllultƒ||SKJ{ttsleuztƒ||{{ƒMRKUMRlek‘Œ…””‹“Œ”š””f]c{ttdc\tlld\\tsltllj]\VTLVTL‹u…tt{‚v‚tslƒƒ|[[T[TT\UZult’ŒŒzll“Œ”ultedkldd|‚z””‹{u{›”›lddddc{{ƒtts{{ƒ”“›Œ”•…‹’‹„‹{{ƒyl„„„Š™š¤lksŒŒšŒ—£|„…\UZŒ‹“mtt|„…{{ƒnv‚{{ƒ…‹š¦§¨˜Ž£“Œ”Œ‹“™š¤‹„‹|„…”“›{{ƒnv‚{{ƒ{{ƒ}‡’”›››¢›‹‹„Œ—£››”‹…’¦§¨“““’ŒŒ¨©´ª³·u{{”››”››„Š}™š¤‹’Š…‹‹Œ”•lri‹‹‹uzt”š”llk‹‹„lek{||f]c\[[›”›¤¤œ›››¢›“Œ”Œ‹“”“›…‹‹‹‹‹“““„„Š‹’Šllk|‚zŒ”•Œ”•{ttultmwlekb[Ulri”š”‘…„”››mtt’…‹“““f]cƒ„„sle“Œ”›¢›{ttVZ[mtt‹’Š]cdnv‚|„…lks]bZŒ”•£››››”Œ”•Œ”•‹‹„‹‹„‹„‹¦§¨‹…’“Œ”“Œ”ª³·‹‹‹zlltsl‹‹‹”š”ldd{ttultfkku{{“““{{ƒ™š¤Œ”•‹„‹‹…’ldd„Š„tsl\[[lri{{t¤¤tt{d\\VTLƒ||‹‹‹””‹ttslrikd\ƒƒ|SKJaWM[[Tf]c[TTVTL‹’Šlldlri«²«JHFUUYsleƒ||lddƒ||‹’Š‹„‹…‹‹{ttultedk‰ƒvlritsltts{{ƒƒ||{zmult’ŒŒƒ‚ntzlsretts|‚zztl‹‹„{tt{{t{{ƒ|‚z‹‹„£²tll£››‚ut”š”¨©´’ŒŒƒƒ|]bZkd\’ŒŒŒ‹“{u{ztlldd{{ƒd\\edktt{‹‹„œ››ƒ||UUY[[TLKR{{ƒf]cultttslksultUMRlksddc\UZ\UZlekƒ}ƒrfkŠ}|‹„„tsl|„…{{tultttsƒ}ƒ{||šŒtll“Œ”f]cmtt{{tj]\f]cƒ}ƒmk…{tt|‚zmttu{{lks{{ƒ|„…lksult\UZtlllek‹…’ƒ„„\[bƒƒ|^^qŒ”•\[[mtt|„…Œ”•n…{{ƒMSSultœ§²¨©´›²{{ƒ~’“{{ƒœ¤¦^fs}‡’Œ—£œ¤¦‰Š¡š””š””¦§¨“““‹‹‹¦§¨‹„„‹’Š“““œ¤¦›¢›{||„„Š}‡’Œ‹“™š¤|„…›¢›œ¤¦‹’ŠŒ”•llk{ttƒƒ|]bZƒƒ|‹‹‹„Š„„Š}ƒ„„{{ƒ‚ut“Œ”tll‹’Š¨©´œ››‹„„“““ƒƒ|ƒ‚uƒ||‹„„‹„‹¦§¨œ¤¦{{tƒ||‹‹‹…‹‹lriŒ”•|‚z‹„‹tt{{||SKJekdƒ„„{{t„Š„œ¤¦|„…{{ƒlri|„…Œ‹“œ››ƒƒ|‹„‹{{t“““‹‹‹uzt”š””››‹’Šœ¤¦”››œ››Œ‹“¦§¨”“›‹‹‹£œ¥””‹“Œ”“Œ”{u{ƒ}ƒŒ—£mttfkkult‚|uuztuzt”››lks¨©´ult“Œ”ttsb[U|‚zult””‹lekƒ||ƒƒ|srerg]ƒ||d\\ddc„Š„ztllldFD;f]clkskk]|‚z|‚z””‹””‹››”llk3+*ttsUMRf]cr]g{u{‹„‹Œ”•tsl‹„„lek{zmsletzl…‹‹š””„Š„lek’…‹””‹£œ¥Šƒ}Šƒ}ttsldd|‚zztl{{t{u{{||Š}ƒƒ||Š}|Š}|‹„„kd\ult{{ƒ‹’Š›¢›Œ”•…‹‹tslƒƒ|ƒ}Š‹„‹{u{[[TddclldŒ‹“„Š„ƒ„„{||VTLJHFVZTtsllks‹„„{u{„„Š“““{||{{t{{ƒ„„Š\[[\[[„Š}f]c{ttlldš””tts‹‹„f]c‚|uttskk]aWMVTLedklksmttƒ||f]clddtt{\[bult{||Œ‹“ŒŒš„„Š™š¤ŒŒšŒŒš{{ƒ‹„‹{u{|„…{{t™š¤ƒ}Š„Š„{{ƒttstts…‹’mtt™š¤\[bedk\[bŒŒš™š¤™š¤™š¤…‹šmttª³·Œ”•{{ƒmttnv‚Œ”•œ§²µ¶·£œ¥£²Š~‹{{t’ŒŒ‹‹‹”››¦§¨¦§¨…‹‹ttssreƒƒ|tts{||‹…’œ¤¦|„…‹’Š›¢›¦§¨|„…‹’Štts…‹‹|‚z„Š}œ¤¦‹’Š|‚z„Š}”››„Š„¦§¨“““¦§¨{{t|‚z‚wlƒ‚u£››’ŒŒ’ŒŒ²««{u{ultŒŒš›”›tt{œ››lek””‹“““‹’Š™š¤\[[ƒ||{||llk{{ƒ\[blks}‡’}‡’VZ[UMRedk…‹’uzt™š¤ƒ}ƒ{{t™š¤¨©´ª³·œ¤¦œ¤¦™š¤›¢›”š”‹’Š”››œ¤¦œ¤¦fkk{{ƒ{{ƒ{{ƒ‘…„f]cŠ}ƒ“““‹„‹ultult[[Tmttfkk„„Šƒ„„…‹‹‹„‹lek{tt„Š„{tt¨©´ƒƒ|‹„„ddckk]yfdtts£œ¥ƒ||kk]|„…ttsSKJtt{tzl[[T]cdlek‘ˆ}²««UTS*)(“Œ”ultbVZlek{{t{u{ƒ||{{ƒ‚wluztlri””‹u{{{||f]cu{{|‚zƒ||‹„„£››Š}|šŒultrg]››”‚wl””‹£››Œ”•‹‹„sle‚utƒ||{ttƒƒ|tt{…‹’œ››{{t|‚z’ŒŒƒƒ|‹’ŠŒ‹“uztf]c[TTddctlld\\tllkd\ldd\[[ultttsekdlks‹„‹lksƒ||UTSd\\llk…‹‹VTLtt{ttsƒƒ|{||{||[[Tg\rLKR‹„„lksf]cek]dc\‹„„VTLkd\]cd]cdek]ƒ||ƒ„„‹…’™š¤”“›…„’ƒ}Š…‹‹…„’“““ultŒ”•|„…llk¦§¨”“›œ¤¦™š¤lks“Œ”mtt{{ƒ{{ƒ|„…{{ƒedk|„…\[[edk{{ƒ{{ƒ„vŒŒ”•uzt{{ƒ™š¤{{ƒtt{™š¤Œ”•œ¤¦™š¤¦§¨ƒ„„Š}ƒ{u{‹„„|‚z››”‹’Š“Œ”™š¤tsllksultultƒ||œ¤¦„„Štllƒƒ|Œ”•¨©´|„…{||„„Šœ››…‹‹Œ”•]bZtts”“›tt{…‹‹…‹‹\[[lri””‹|‚z¦§¨tzl]bZttsu{{tll‚wlƒ}Šƒ„„ƒ‚uƒ„„|‚zedkuztu{{Œ”•{{ƒ™š¤ƒ„„…‹’mttult{{t{{ƒlri\[b]cdmtt|‚zz}lri|„…lksœ¤¦„„Š¨©´Œ”•œ¤¦…‹’Œ”•œ¤¦ª³·”››f]c|„…‹’Šš””u{{œ››Œ‹““Œ”\UZŠ}|ultƒ}ƒtll{tt‚|uUMRllk“Œ”{{t£œ¥™š¤lksultlks‹…’{u{mttttsŠƒ}ƒ}ƒ[[TSKJbVZŠƒ}tt{‹„„„Š}[TTllktslkd\ƒ||sle|‚ztll{{t¦§¨llk74,SKJtll’…‹ddcmttldd{{tsle‘Œ…“Œ”f]cslesle|„…lri|‚z‚|u{tt‹‹„£››¦§¨‚|u…‹‹ƒ„„‹’Šsreƒƒ|Œ‹“™š¤’ŒŒlld‹‹‹mtt‹„„ƒƒ|ddctt{”š”‹’Š„Š„{u{tslr]Zu{{‹‹„‚|uultllkfkkSKJ]bZ]bZF=CF=Cmttlriœ¤¦ƒ„„|„…{{t‹…’Œ”•tsllkstlltts]bZlekuzt|„…ddc„Š„lkslrid\\sleu{{slesred\\cbVtllƒ}ƒuztlritll{tt„„Š…‹‹Œ‹“ŒŒš£œ¥œ§²{{ƒ‹„‹œ¤¦™š¤ŒŒšllk™š¤‹„‹Œ‹“‹„‹{u{ƒ}ƒlks|„…{{ƒŒ”•|„…tt{|„…|„…›²›”›nv‚|„…{{ƒlks“Œ”{||…„’ƒ}Š£²“Œ”£œ¥™š¤{{ƒ™š¤tll‹„„tts[TT{ttŒŒš”“›¦§¨¦§¨ƒ}ƒ’…‹‚v{š””‹‹‹ztlƒ||mtt{u{…„’{||Œ”•œ¤¦ƒ„„™š¤SKJŒ‹“‚|u{{tŠ~‹…‹’Œ‹“{{ƒ|„…”š”edk|„…tsltzl{{t‹’Š‹‹‹›¢››¢›’ŒŒ{{ƒƒ„„lekŒ”•Œ‹“tt{Œ”•…‹’{{ƒmttldd]cd‚v‚lksu{{\[bUUYŒ—£mttŒ—£|„…{{ƒ{{ƒVZ[„„Š…‹‹Œ”•«²«™š¤¦§¨|„…mtt”“›™š¤™š¤tt{„„Šlks™š¤lks…„’Œ‹“ult\[[dc\ƒ||UMRyflreddc\j]\„„Šj]\{ttllkedkb[Uultult]cddc\[TTVTLtll[[Ttllr]gƒ}ƒ{{t››”‹‹„ekdultbVZj]\UTSC8.JHFldd²««›¢›JHF!ekd{{ƒ{{tultllksle|‚zb[Uš””‹„‹{{ƒ“Œ”£››ƒ||œ››…‹‹ƒƒ|’ŒŒŠŠ}{ttŠŠ}‹„„œ››‚v{‹„„‘Œ…ƒƒ|ttssle’ŒŒƒ‚uƒ„„„Š„‹„‹œ¤¦”››f]cŠƒ}’ŒŒmtt{{t…‹‹lri|„…‹’Š{||‹„‹tt{™š¤dc\tllekdlld‚v‚mk…mttŒ”•œ››Œ”•„„Š{|||„…„Š„rfkekdƒ„„[TTekdlld‹‹„mttek]…‹‹ƒ}ƒ‹„„lek\UZVTLlksŠ}ƒred’ŒŒult„„Š‹‹„d\\“““››”…„’”“›…‹’‹…’{{ƒŒŒš{||¦§¨}‡’˜Ž£\[[ddcult{||ƒ}Šƒ„„¦§¨lks|„…ttsŒ”•„Š„ŒŒš‹‹‹|„…”››„vŒ‹…’…‹‹„„Š|„…”››|„…”››™š¤Œ‹“Š~‹™š¤‹…’Œ”•|„…Œ”•œ¤¦™š¤”››Œ”•›”›‹‹„£œ¥”“›lks{u{£œ¥›”›…‹‹“““…‹‹…‹‹ldd{{ƒ‹‹‹mttœ¤¦Œ”•œ¤¦MSSUTSttsŒ”•“~ˆztl‹„‹‰v|]bZ””‹cbV¦§¨””‹|‚z””‹Œ‹“Œ‹“„„Š„„Š„„Š\UZddc\[[[TT{||™š¤Œ”•|„…™š¤mtt\UZlksultJHF\[bŒŒšUMRƒ}Š|„…Œ”•ƒ||œ››“““ult{{tultœ¤¦œ¤¦…„’Œ‹“™š¤µ¶·|„…|‚z‹’ŠŒ”•…‹’“Œ”Š~‹‹„‹{{ƒœ¤¦£œ¥ƒ}Šf]c[TTleksleztl{u{red“Œ”{tt‹„„‘…„™š¤rfkultƒƒ|ddc‹‹‹”“›ztlƒƒ|œ››ƒ||j]\„„Šƒ‚uƒƒ|cbVddcztlllkƒ}ƒkd\ƒ‚u{{tƒ||{zmµ¶·MRK*)(|‚ztlltts[TTlriredtslƒƒ|””‹ƒ}ƒ’ŒŒlldƒ||„„Š‹‹‹ƒ‚n‹„„²¬µƒƒ|‚|uŠƒ}œ››«²«‹„‹“““{zmlri™š¤’ŒŒztlbVUŒ‹“{tt|‚ztt{””‹uzttts””‹‹’Š‹„„|‚z”››ƒ||“Œ”tts‹‹‹…‹‹“Œ”š””“““mttUTS^^qlks{u{…‹‹™š¤…‹‹Œ”•{{ƒŒ”•{||‹’Šlddztldc\œ››ult„Š„…‹‹ŠŠ}‹„„‹…’ƒ||ƒ}ƒ{{ƒ”“›…‹‹“““£››Š}ƒ\UZ{{ƒƒ||ƒ}ƒµ¶·¦§¨Œ‹“™š¤‹‹‹†~‘|„…Œ‹“{u{uzt…‹‹{{ƒ|„…‹‹‹ult‹‹‹„„Š„„Šœ¤¦mtt™š¤…‹‹œ¤¦…‹’…‹’Œ”•ƒ„„¦§¨„„Š™š¤””‹“““edk‹‹‹“““Œ”•{tt…‹‹¦§¨™š¤llkŒ‹“‹’Šult|„…ult“““Œ”•“““‹‹‹›¢›œ››¨©´|‚zƒƒ|{||£››‹‹„tzl‹’Šsle{||„„Š|„……‹‹”š”‹‹„]bZŒ”•ult{||{zmƒ||{{ƒ|‚zŒ”•›¢›{{t””‹„Š}{{t{{tƒƒ|£›››¢›ƒ„„{{tdc\tsl[TT‹‹„kk]f]cf]c{{ƒtt{„„Štt{lek|„…tt{fkkmtt]cdŒ”•}‡’…„’™š¤”š”’ŒŒ£œ¥‹…’|„…£²¬¶Ã™š¤™š¤‰Š¡{{ƒ”“›£œ¥™š¤™š¤””‹š””ultƒƒ|”“›ƒ}ƒ{||tsl{||llkedkŒ”•„„Š‹„‹¨©´ƒ}ƒƒ||“Œ”Œ‹“{u{“Œ”ldd“Œ”{tt“Œ”ƒ||slesleŒ‹“‹„„{{tj]\„Š}kd\ek]dc\ekdredVTLb[UVTL]bZSKJlksµ¶·VTL*)(ƒƒ|{u{{u{ztltts‚utsre‚|u””‹{{ƒ‹’Š™š¤b[U|‚zult‚ut”››|„…iq]{{t””‹‹‹„œ››{||™‹†b[U{zmŒ”•Œ”•{{t‹‹‹‹„‹|‚z{||{u{tt{tt{”››«²«”š”tslmttuzt|‚z…‹‹ƒ}ƒŒ‹“„„Štts¤¤uztlritsl]cdMRKllkmtttll‹’Š\[[Œ‹“|„…ztl{{ƒ{{t{tt‚|utsl{tt|‚zbVZ‹‹‹Š}ƒŠ}ƒ“““‹„‹›”›{ttmtt‹‹„‘Œ…lldSKJlddJHF’ŒŒ|‚zƒ}ƒ|„…ƒ}Šlri’…‹œ››mtt£œ¥‹„„mtt{{ƒ|„…ƒ}ƒ›”›‚wl†~‘¨©´¦§¨™š¤Œ”•œ››œ¤¦mtt|‚z”››œ¤¦…‹’tt{|„……‹’‹…’{||…‹‹ultu{{mttmttŒ—£…„’lks””‹¦§¨«²«¦§¨¦§¨œ››œ¤¦{||Œ”•”››…„’œ¤¦„„Š”“›lks…‹‹|„……‹’ddcf]c”“›µ¶·{{ƒ{u{¦§¨…‹‹ƒ„„Œ‹“lks””‹[TT\[[dc\|‚ztsl“Œ””“›«²«„Š„››”œ››|‚z‹‹„Šƒ}ƒ}ƒ{{ƒd\\llk’ŒŒ‹‹„tsl™š¤{{tƒ}ƒttsdc\ult[[TUUYlriuztMRKtllllkyl„ddc{{ƒ“Œ”£²ŒŒš”“›ult””‹{||ƒ}ƒ‹…’™š¤tt{¨©´„„Šƒ„„ƒ„„Œ”•„„Šztl„Š„”š”{||tsltt{u{{ddc”“›™š¤œ¤¦”“›”››‹’Š„Š„‹‹‹„Š„Œ”•“Œ”\[blldlddedkdc\‹’Š{{t‹„„lldj]\{ttSKJSKJ]bZlridc\d\\j]\j]\lddekdttsƒ„„²««UTS*)({tti\Vldd{ttŒ‹“‹„‹Šƒ}£››zllsre‹„„{{t{{tllkš””’ŒŒtsl›”›lrid\\yle’ŒŒ‹’Š¦§¨ƒ||“Œ”‹‹„{u{lldyle‹‹‹ttsŠ}|{||„„Šd\\…‹‹‚|u‹‹„ƒƒ|{|||„…lrikd\…‹‹kd\„Š„œ¤¦”››“Œ”uztu{{uzt]cdUMR]cdddcd\\Œ‹“]bZult\UZd\\ƒ‚nsleu{{ƒ||{ttf]c{{tdc\ƒƒ|ƒ„„Šƒ}JHF{tt[TT‚|utslƒƒ|mwUMRtts“Œ”‹„„lksultlkstts{u{‹’Š™š¤“““{{ƒš””£œ¥|„…|„…{||œ››“Œ”””‹Œ—£„Š„‹…’ŒŒš…‹’ƒ„„…‹‹{{t¡¡“““|„…lks{{ƒ{{ƒ…‹’¨©´{{ƒ”“›‰Š¡{{ƒ{{ƒ…„’{{ƒnv‚lksŒ”•»ÂÇŒ‹“…‹š”“›…‹‹››””š”œ››‹’Š„„Š¨©´œ¤¦”››ult‹’Šu{{‹„„›”›‹„‹“Œ”¦§¨‚ut„„Š”“›‹’Š£œ¥™š¤{{ƒ”“›tts{{ƒ{||‹„„”›››”›¦§¨ŒŒš…‹’¦§¨“Œ”\UZŒ‹“”“›ult‹…’]cdult„„Š{ttult™š¤“Œ”llkŒ‹“|„…ultedk“Œ”…„’Œ‹“tts\[bf]cult¨©´{u{ŒŒš{{ƒŒ”•ƒ„„„„Šttsmtt|„…tt{„„ŠmttŒ”•{{ƒ›¢›Œ‹“œ¤¦‹’ŠŠƒ}Œ”•lld|‚z‹…’œ››“““dc\‚v{tts”š”|‚z„Š„š””d\\lks…‹‹|„…d\\red{{ƒ“““ƒ}Š\[[tslSKJƒ||tsl{ttultdkVSKJVTLVZTmtt\UZredtllztl\[[SKJ{{t²««JHF*)(dc\ultd\\i\Vƒ„„{tt››”‘Œ…ƒƒ|~’“…„’sre‹„„d\\‚v{„„Š’ŒŒƒ„„lldek]f]c‹„„…‹‹|‚zƒ||£››‹„„’…‹””‹zll‹‹„ƒ„„‹‹„tll‹’Š‹„„„Š„{tt‹‹„””‹ƒ„„tt{|‚z‹‹„|„…llk››”™š¤|„…ƒ||„Š}ek]|„…cbV„„Šlldmttd\\lldllkedk{{ƒŒ‹“llkultttsŠ~‹’…‹bVU››”[[T‹„‹ƒƒ|sreddcttsf]c‰v|ƒ||ƒ„„sleb[U‚|u‹‹‹ƒ„„tt{d\\\[bLKR™š¤”“›™š¤“Œ”{{ƒƒ„„“Œ”llku{{”››”“›{||Š}ƒrfkŠ}ƒ™š¤{{ƒ{u{zllœ¤¦Œ”•¦§¨Œ‹“u{{…‹‹™š¤™š¤ult™š¤…„’ult…„’™š¤{{ƒ‹…’{{ƒ›²›²œ§²”“›{{ƒ‹‹‹™š¤””‹”“›œ››“““tsl…‹‹”“›ƒ}ƒŒ‹“Œ”•|„…{||lldmtt…‹‹›¢›Ž¡›œ¤¦¦§¨lri›¢›Œ”•tts…‹‹‹‹„slemtt\[bultƒ}ƒ|‚z“““uzt‹‹‹›¢›…‹‹lld„Š„‹‹‹…‹‹ttslri“““œ››ƒ‚uƒ„„rfkƒ}ƒ“Œ”‹„„dc\JHFf]cƒ„„ultlldult{u{f]cƒ}Š…‹‹{||mttlldŒ”•œ¤¦{{ƒ”“›‹„‹ƒ}ƒ„„Š…‹‹™š¤›”›{u{”››ztl|‚z¤¤‹‹‹{{ttslsleƒ‚udc\„Š„ztlƒƒ|tzl“““slelksekd{{t¦§¨{||ultleksleUTSŒ‹“{||d\\slett{‰ƒvldd{ttsle‹’Š{{tUUYztlult|„…ƒ„„”š”sremttSKJcbV””‹F=C*)(d\\tts[TT‚v{{tt”“›{{tƒ‚u{zmultred{{tŠƒ}ldd‘Œ…“Œ”llk|‚z\[blld{{ƒ‹‹‹Œ‹“ƒ„„‹‹„‚|uƒ‚u””‹£››|„…µ¶·”“›„„Šult„Š„‹„‹|‚z“““››”‹‹„”š”f]c”››|‚z‹’Š„Š„Šƒ}ttsu{{]cd”š”JHFƒ}Š[[Tf]c\[[tt{ulttlllriŒ”•{{ƒƒ}ƒlekedkllk|‚z„Š„‚|u‚|udc\llkb[Ui\VUTSlddUMRkd\VTLrg]f]cf]c“Œ”‹„‹¦§¨‹„‹‚|u|„……„’„„Š…‹‹‰ƒv…„’ŒŒšƒ„„œ¤¦Œ‹“™š¤{{ƒ{||tll¦§¨Šƒ}‹„‹™š¤”“›Œ”•“““Œ”•ª³·ƒ„„ƒƒ|‹’Šuztlks{{ƒ{{ƒ™š¤Œ‹“‹’Š…‹’|„…}‡’{{ƒ^fs}|’~’““Œ”œ¤¦œ¤¦ƒ}Šƒ„„‹‹‹ƒ„„tllƒƒ|tt{‹‹„œ¤¦tsl››”lriƒ‚u‹„‹llkƒ}ƒlektt{¦§¨¨©´ƒ}ƒŒ‹““Œ”‹’Šlld“Œ”f]ctts{tt|„…uztj]\™š¤’ŒŒœ››‹‹„ƒƒ|„Š}tzl””‹ŠŠ}”››µ¶·ƒ‚ukjVš””ƒ||ztlšŒtll\[[„„Šddcult‹…’„„Šult‹„‹›”›{u{{{ƒtll‹’Šuzt‚|uœ››tll{{ƒ˜Ž£„„Š|„……‹’”››…‹‹{{ƒ“Œ”{u{Œ‹“u{{ƒ„„œ¤¦œ››{||]bZlriUTSd\\u{{‹„‹f]cŠ}ƒult{||™š¤d\\{ttsle‚|uztlƒ}ƒ‹„‹u{{Œ”•ƒƒ|’ŒŒ{||{u{ƒ||’…‹¦§¨„Š„¦§¨‹’Š{||ƒƒ|ƒƒ|Œ”•Œ”•‚|uƒ}ƒJHF[TTkd\¤¤VTL74,ulttsltts“Œ””š”“Œ”bVUƒƒ|‚wl[TTsle{tt{ttult‰ƒvlek‹„‹lldlriekdƒ||tllŒ”•|„…‚ut‚|uŠŠ}ƒƒ|’ŒŒ{||‹‹„|‚z‹„„„„Š””‹{tt{{t›”›¤¤‹‹„|‚zult…‹’„Š„‹’Štslultƒ}ƒ”“›{||”››ekdf]cUMRVZ[\[bƒ}ƒƒ||‹‹‹u{{Œ”•ek]”››”“›™š¤‹„„[TTlri{{ƒƒƒ|ddclridc\j]\Œ”•lriultlekŠ}ƒ””‹[TTƒ}ƒ„„Š…‹‹¨©´Šƒ}Œ”•”››™š¤£²…‹‹…‹‹¦§¨{{ƒŠ~‹|„…„Š„ŒŒštt{ƒ}ƒuzt“Œ”lriƒ}ƒ„„Š™š¤Œ”•”“›‹’Š|‚zu{{Œ‹“lriuzt{||“Œ”“““Œ”•lkstt{‹…’›”›™š¤¨©´™š¤¨©´¨©´{{ƒ™š¤Œ”•¨©´™š¤“““ƒ||lld|„…”››|‚zƒ|||‚z”››œ››¦§¨¦§¨››”¦§¨‘…„tts{tt“Œ”Œ‹“¨©´“““£œ¥…‹‹‹‹„lekŒ”•UTSttsŒ‹“‹…’„„Š‹‹‹ƒ„„“Œ”ƒ}ƒš””Š}|£››{zm¤¤¤¤››”œ››¦§¨‹‹„{{t‚v{tts„Š„““““““VTLlldlldSKJ‹„‹™š¤lekedk›¢›«²«œ§²uztttsƒ}ƒƒ}ƒƒ„„…„’™š¤£œ¥“Œ”™š¤‹„‹{u{”“›{ttult¨©´µ¶·Š~‹ttsƒ||mttf]cŒŒšƒ}Šƒ„„lld‹‹„‚v{”››‹…’ƒ}ƒtt{ztlrfkult›”›bVU™š¤u{{ƒƒ|ult…‹‹sle”“›‰ƒv‹„„{{ƒƒ„„‹‹„ƒ}ƒ{||„Š„‹‹‹’ŒŒcbV{{tedk{||„Š„¤¤JHF*)({{ƒlddttsztl“““ultcbVƒ||””‹rfk{zm’ŒŒ„Š}tll‹‹„j]\‘Œ…uztuztztflddd\\ƒƒ|tt{¦§¨™š¤ƒ‚uƒƒ|’ŒŒ{||„„Šlri{{t”“›œ››››”™š¤‹„„”“›ƒƒ|llklek…‹‹«²«£››{||ƒ||‹’Štts…‹‹|„…‘Œ…‹„‹|„…}‡’mttƒ}ƒd\\š””{||srett{Œ”•›¢››”›™š¤lekztltzlkd\“Œ”ƒƒ|kk]kd\{zmƒ}Š{ttu{{lrilld‹„„f]cztlŠ~‹{{tddc‹„„Œ”•„vŒŒ”•„Š„…‹‹mtt›”›rfkUTStsl{{ƒ|„…lld’ŒŒ‹…’…‹‹tslyl„ult™š¤{||…‹’mtt{||{{tleku{{›”›ƒ}ƒ‹„‹|„…Œ‹“‹’Š“Œ”œ¤¦œ››¨©´”“›„„Š{u{„Š„”“›Œ”•ƒ„„Œ”•lri‹’Šƒ„„œ¤¦‹’Š…‹‹uzt{u{··Ä“““¨©´„„Š’ŒŒŠ}ƒ’ŒŒ’ŒŒbVZ„„Šsle£››“Œ”‹’Šult””‹¦§¨›”›‘Œ…Š}ƒ¦§¨²¬µ›”›”“›¨©´¦§¨lek¢—‹’Š›¢›œ››››”›¢›“““rg]sleŠŠ}lri{zm“““tzl{{t””‹[[Tllduztƒ‚u™š¤Œ”•{{ƒmtt„„Š™š¤ƒ}Š]bZ…„’ult‹uŠ{u{‹„‹“Œ”£œ¥“Œ”ult‹…’tsl“Œ”lksVZT{{ƒŒ”•u{{‹„‹™š¤ƒ}ƒ{u{ƒ}ƒ„„Š‹…’‹…’{{ƒƒ}Šlldsle|‚z{{ttslkd\ultlksultƒ}ƒddcu{{bVZ…‹‹„Š„’ŒŒ[TTd\\{tt{tttygtts{{t‹‹„lektllkd\‚|ulkslldtsl£œ¥FD;*)(Œ”•‰|vtt{rg]ƒƒ|ƒ„„‚|u‹‹„tsltsltll{u{kd\|„…‰ƒvztl›”›lri‹’Š’ŒŒedk{{ƒ£››Œ‹“‚|uultz‚llld{{ƒŠ}ƒ›”›”››lldf]cƒ}Š{{tŒ”•tll“““›¢›Œ”•ttsœ¤¦”››¦§¨|„…\[[rfkƒ||uzt|‚z”“›Œ”•u{{‹„‹ŒŒšlri{{ƒ””‹‹’Š…‹‹{{ƒ‹„„|‚zœ››ƒ||ƒ}Š‹’ŠŒ”•{ttƒ}ƒrg]‹‹‹{{t|‚z„Š}ƒ}ƒ“““|‚zlriuztƒ}ƒlek‹…’‹„„lldllk”š”†~‘u{{…‹‹llkŒ‹“{u{Œ‹“ƒ||{||ttsœ››™š¤{||‚v‚tts‹„„{ttf]ctt{£››|„…‹„„”“›{{t”š”{{t›¢›ddcƒ}ƒu{{¸Á¹œ§²™š¤¦§¨¦§¨‹’Štts{{ƒ|„…mtt™š¤œ¤¦tt{Œ‹“u{{{{ƒ|„…”“›”››“Œ”ƒ||‹‹‹²¬µœ¤¦””‹{u{edk‹„„{{ƒ…„’”››“““u{{¦§¨”“›‹…’’ŒŒ£››¤¤£››¦§¨¨©´Œ‹““Œ”¨©´¦§¨”“›‹‹„redtllš””›¢›¦§¨Šƒ}£œ¥VTLztl„Š}¤¤ƒ‚u‹„„sleztlVTL{u{Œ‹“Š}ƒ“Œ”“Œ”‹„‹f]c™š¤£²£œ¥…„’|„…u{{mtttt{lksŒ”•“““œ¤¦™š¤™š¤œ¤¦››”ƒƒ||‚z„Š„|„…‹’Š‹‹„|„…u{{¨©´Œ‹““Œ”“~ˆbVUtslŠ~‹”››„„ŠJHFek]lks\[[¦§¨lrilri\UZbVUŒŒšƒ„„’…‹ult“““kd\zll[TTd\\uzt‚|usre’ŒŒd\\uztmw[[TSKJƒƒ|JHFd\\ult”“›JHF*)(‚|uztl”š”redƒ‚ulekrg]ztl¦§¨’…‹”š”‹‹„ult‹’ŠŠƒ}sre£››ult|‚z‘Œ…tts‹„‹fkk|‚zŠ}ƒ‹„„””‹£››’ŒŒ“Œ”sre…‹‹œ¤¦llk{u{›¢›“Œ”¤¤ƒ„„›¢›{||„Š„¨©´¦§¨¦§¨”››{u{lldu{{…‹š|„…uztultLKRVTL\UZlek“Œ””››”››uzt‹„„‹‹‹tts{u{…‹’™š¤œ¤¦[[T{{ƒlldultllkƒƒ|‚|u‹’Šztlƒ}ƒred„Š„ƒ„„‚v‚lddš””tsl{ttœ››¨©´uzt…‹‹lldlksƒ||Š~‹›”›‹„„lri[TTtslf]c„„Š‚uttsltll‚v{Š}ƒ”“›ƒ||ƒ||‹„‹lksƒ||‹‹‹|‚zult{{ƒ¦§¨Œ”•œ¤¦™š¤Œ”•¡¡œ¤¦œ¤¦|„…|„…Œ”•„„Š¦§¨{{ƒ”“›„„Š“Œ”£œ¥™š¤™š¤‹„‹¨©´¦§¨{{ƒ¨©´›”›™š¤™š¤““““Œ”Š}ƒ²««{u{llk…‹‹’…‹··Ä‚v‚yfdƒ||‹‹‹‹„‹™š¤™š¤rfk“Œ”‹…’ƒ}ƒ‹’Š›”›™š¤ƒ„„‹‹‹Œ‹“{||ƒ„„ztluztlri‹’Š|„…lrillktt{|„…‹’Š{{ƒ]cd]cdœ¤¦mttfkkfkk{{ƒŒ—£¬¶Ã™š¤|„…}‡’™š¤…‹’…„’”“›|„…Œ”•{{ƒ‹…’mtt{||„„Š‹‹‹¸Á¹lld””‹Œ”•lri‹‹„kk]ƒ„„ƒ„„lldŒ‹“…‹‹‹„‹…‹’ddc|‚zlld‹„‹ƒ||„„Šddcldd{{ƒ{{ƒJHFUUYu{{lddJHFf]clddƒ||ttsllkŒ‹“lri‚v{ddclldj]\dc\Š}ƒ„„Šƒ}ƒlriƒƒ|¦§¨JHFJHFuztlld{ttztlšŒllkjV[|‚z|‚zkd\“Œ””š”Œ”•uzttsl””‹‘…„„„Š„Š}|‚z“““ztlŠƒ}tsltts{tt„Š„¦§¨‹„„œ¤¦”››{||“Œ”Œ‹“ult|‚zlek£››µ¶·ª³·›¢›…‹’¦§¨Œ”•‹‹‹£œ¥œ¤¦‹‹‹”››uzt]bZMRKlld]bZ|„…tt{‹„‹…‹‹‹‹„™š¤{{tllk…‹‹‹’Šƒ||œ››u{{…‹‹„Š„ƒƒ|Œ‹“|‚zbVUtsl‹’Šlldfkk|„…‹„„tslsred\\fkklddŠ}|{{tƒ}Š¦§¨{||…„’‹’Štts]bZ{u{¦§¨†~‘¤¤ƒƒ|ƒ||{u{tts{||f]c‚|u“Œ”|„…ttsœ¤¦””‹ŒŒšŠ~‹ldduztu{{…‹‹…‹’ƒ„„|„……‹‹Œ—£Œ”•}‡’|„…|„…mtt|„…ƒ„„‰Š¡Œ”•‹…’œ››™š¤{{ƒ|„…Œ”•™š¤|„…£œ¥‹…’“Œ”ttstt{²¬µ””‹¨©´“Œ”…‹‹™š¤uzt{ttƒ„„‚ut¦§¨Š~‹“Œ”ƒ}ƒ‘Œ…Š~‹f]cmw’…‹ƒ}ƒš”””“›‹„‹ª³·‹„‹llklek“““œ››tts{{ƒlrilri’ŒŒŒ‹“…‹‹…‹’™š¤edkultJHFlks{{ƒ…‹š{{ƒlksedk|‚z’ˆ|‚zŒ—£Œ”•lks””‹|‚zuzt‹‹‹„Š„¦§¨¦§¨‹„‹Œ‹“›¢›Š}|””‹Šƒ}ƒƒ|ƒ‚u””‹VTL””‹‰|vŠŠ}slerr]tzl|‚zƒƒ|[TTƒƒ|lriŠŠ}‹’Šƒƒ|tslUTS”“›d\\|„…ekd‹…’uztyl„[[TŠƒ}“““‹„‹Š~‹””‹VZT””‹lek‚v‚lldultztlf]c{ttF=Ckk]rg]²««UTS*)(slej]\…‹‹Š}|‚|ulddŠŠ}ŠŠ}‹’Š›”›”“›””‹“““ttsrg]sle‚|utt{VTLsleztlŠ}ƒ„„Š‹„„zll›”›”š”””‹¤¤ƒƒ|œ¤¦“Œ”¦§¨Š}ƒ‹„‹u{{{{ƒ“Œ”¤¤’…‹Œ”•ttsŒ‹“‹’Š¦§¨“Œ”¦§¨£œ¥™š¤|‚z‹‹‹lriUTSJHF[TT{{ƒ{{ƒƒ„„œ››ŠŠ}œ¤¦ƒƒ|uzt{{t{||fkkŒ”•œ¤¦tslmttsre{ttu{{Šƒ}b[Uƒ„„…‹‹ƒ}ƒ{||””‹tzlkd\74,{u{ztlŠƒ}ztl™š¤ƒƒ|ƒƒ|uztmtt{u{™š¤‹…’f]clriŒ”•‹„„d\\„„ŠŒ‹“ƒ„„lddttsultult›²Œ‹“ƒ}Š“““ƒ„„[TTlks{{ƒŒ”•‹‹‹…„’|‚z|„…fkk‹’Š|„…‹’Š|„…¦§¨““““Œ”{{ƒ“Œ”‹‹‹‹…’”“›ttsu{{›¢›””‹]cdtts{u{ƒ||\[[ƒ}ƒ”“›“Œ”ƒƒ|kd\{zm‹‹‹Œ‹“ttsšŒŒ”•ekdttsf]ctlldc\tzlJHF{||lkstll’…‹¦§¨’…‹£œ¥‹…’”“›{{ƒ”“›¦§¨lkszlld\\dc\‚v{red‰v|{u{f]cedku{{ª³·””‹ƒ„„“~ˆllkekduzt›¢›|‚z‹’Š›¢›‹’ŠŒ”•ttsmtt‹’Š‹‹‹ƒ}Š£››“““›¢›{||tll„Š„kk]{||tll›¢›‹‹„llklri|‚zVTLek]„Š„””‹dc\‹’Š|‚z””‹ƒƒ|dc\{{t{||lksmttultœ¤¦mtt{{ƒƒ}ƒ{{ƒ…„’Œ”•‹‹„””‹™š¤ƒƒ|[TTsresle{||lld]bZrr]JHFttsJHF{zm‚|u””‹JHF:97tsllrilldƒƒ|Šƒ}‹„„ƒƒ|‘Œ…‹’Š””‹Œ‹“‹’Šƒ„„‹’ŠŠƒ}Šƒ}‘Œ…’ŒŒƒ‚uƒ‚ukd\Œ”•‚v{™š¤œ¤¦Œ‹“””‹››”ƒƒ|”“›¦§¨“Œ”Œ”•tt{ƒ}ƒ{u{”“›Œ‹“›”›u{{“Œ”lksƒ||lriš””œ¤¦’ŒŒƒ„„|„…|„…{||llkmttf]c{{ƒ{||“Œ”‹‹„{{t|‚zœ››ƒ„„Œ”•”š”uzt„Š„lek„„Šdc\tt{Œ‹“kk]lekƒ||d\\|‚z|‚z{||ƒ||ƒ||‹‹„kd\VTL{||tll£œ¥sre¨©´¦§¨|„…„Š„ƒ||”š”’…‹UMR†~‘’ŒŒœ››ƒ}ƒ‹„„{ttš””œ››‹’Šƒ||kk]ƒ}ƒ{{ƒ›”›¦§¨‹„‹‹’Š{u{Œ”•{{ƒ|„…{tt‹’Š|‚zƒƒ|„„Š“““Œ‹“„Š„{||{||{{ƒ…‹‹™š¤ƒ„„{||„Š„…‹‹„„Šœ¤¦„Š}ttsuztUTSUTSSKJSKJƒƒ|‹„‹“Œ”…‹’Œ‹“Š}ƒ‚ut£œ¥ultš””sle„Š„lksddcd\\lekƒ||uztddctslƒ}ƒ¦§¨{u{…‹‹\[bƒ}ƒ””‹„„Š„„Š{{ƒf]c]cdJHFultllkŒ”•‹‹‹tslƒ||””‹lddD;9lldbVUuztekd|‚z{ttek]|‚z›¢›Œ”•‹’Š‹‹„|‚z|‚z””‹‹’Š›¢›‹’Š“““‹’Šœ¤¦Œ”•|‚z|‚z‹‹„ƒ„„ƒƒ|‘Œ…ƒƒ|yle‘…„ekd’ŒŒ‘ˆ}ƒ||ƒ||[[TbVU‹’Š‹„„ƒ„„‹‹‹”“›{||‹’Šœ››Œ‹“ƒ||{{t‹…’|„…™š¤dc\…‹‹\[[mtt›”›lld[[TSKJVTLƒ„„„Š}tts‹„„|„…\[b{{tj]\””‹JHF*)({tt|‚z‹‹„‚|uŠŠ}Šƒ}‚|u{zmdc\‹‹„leklld|„…‘…„{{t››”slellk””‹””‹ƒ||‹‹„’ŒŒuzt{||Š}ƒz‚lƒ||ƒ||llkš””{u{|‚z†~‘“Œ””š”{{ƒ‚v{¦§¨Œ‹“mttlekŒ”•ƒ‚u™š¤Œ”•¦§¨œ››‹‹„llk{{ƒldd|„…{{ƒekdœ§²{ttƒ„„”“›|‚z…‹‹ƒ„„‹’Šƒƒ|tts“Œ”ldd{u{|‚z‹…’‚|u|‚z›”›tllztldc\‹’Šœ¤¦‹„„””‹››”b[U[[TddcVZTtlldc\ekdldduztlriƒ||{ttlek‹„„ƒ}ƒ„Š„u{{ekd’ŒŒ{||™š¤¤¤ƒ}ƒzll{{ƒ‹„‹ult¦§¨¦§¨£œ¥’ŒŒ‹‹„›”›mtt{{ƒ¦§¨{{ƒƒ„„{{ƒŒ‹“‹‹‹”››™š¤mttek]lriƒƒ|ƒ„„|‚zœ¤¦…„’|‚z‹‹‹”š”{{t„Š„‹‹„lldultttsUUYŒ‹“dc\“““›”›„„Š‹„„£››‰v|£››··Ä’ŒŒŠ}|‚v{s_qred”“›ƒ}ƒVTL‹„„]cd’ŒŒ¦§¨›¢›tzl‹‹„tzlmtt‹’Š{||‹‹‹f]c[[T|„…lksedk‹„‹\[[ƒ}ƒ‹„‹tt{‚|u{{ƒƒ}ƒb[U{{ƒd\\tt{|„…™š¤mtt{{ƒ”››{{ƒ…‹’™š¤¦§¨£²‹‹‹ŒŒš‹’Š“““Š}ƒšŒ‹„„ƒƒ|œ¤¦”››ƒ||‹‹‹redslej]\ultbVU£œ¥r]Z‹„„cbVkd\sle‹„„lddkd\{tt“Œ”tll‹…’\UZ„Š„VZ[dc\edkŒ”•uzt[[TŒ‹“[TT\UZƒ„„lld[[Tzll‹…’””‹kd\š””‹„„›”›ŒŒšVTLj]\œ¤¦>EC:97ultŒ”•|‚z{{t“““zll ztl”š”‘Œ…VTLƒƒ|„Š}Š}|šŒ£››‹‹„„Š„š””Š}|red”“›{tt”“›{tttll”š”“““tts‹uŠult™š¤‹…’…„’“Œ”ƒƒ|™š¤¦§¨ƒƒ|ultdc\{u{“““¦§¨’ŒŒŠ}ƒ„Š„‚v‚…‹’edk„„Š{{ƒ{|||„…LKRtslmtt‹‹‹u{{‹‹„ttsd\\ttsuztldduztj]\ƒƒ|tt{llklddkk]tt{‚|uldd|„…›¢›™š¤{zm„Š„™š¤„Š„„„Š|‚zlrid\\‹„„ƒ||ekdlekœ¤¦|‚z|‚z{u{{zm[TT|‚zttsUTS‚|u{{t‹’Š’ŒŒ›”›ƒ||Œ”•œ¤¦™š¤˜Ž£{{ƒ“““{tt“Œ”fkklks{{ƒŒ”•‹…’ŒŒšª³·‹‹‹…‹‹Œ”•Œ‹“|„…”››]cd…‹’tt{fkktt{|„…|„…”››mttulttts”“›™š¤…‹’‹„‹“Œ”“Œ”£œ¥f]c|‚z¦§¨|‚z”››{u{“Œ”‹…’{u{‹’Šult’ŒŒ’…‹“Œ”kd\SKJkd\tllŒ‹“Œ”•’ŒŒ…‹’ƒ}Š{{t{{t„Š}‚uttslSKJJHFb[Uƒƒ|tsl‰ƒvlddƒƒ|]bZ”“›dc\mtt|„…ttsVZTult…‹’|„…{{ƒ‹…’ŒŒšƒ}ƒ{u{‹„‹ƒ}ƒ’ŒŒ··Ä‹…’£œ¥ƒ||bVU“““››”Š~‹ult|‚zŠŠ}dc\ldd|‚ztslUTSSKJ””‹‹‹„lld[TTslej]\\[[MRKŒ”•[[T{{tƒ„„„Š„lksllk{||œ››{||Œ”•mttlrimttddc[TTj]\„Š„Šƒ}kk]lddtsl‹‹„‹‹„£››u{{{u{\[bVZ[ƒ}ƒƒƒ|JHF*)(tll|‚z‚|u””‹‹’Šyle‚utkd\sleƒ||j]\{{t“““‰ƒv¤¤›¢›””‹ddcŠƒ}kk]ztl’…‹’ŒŒ‹„‹ƒ||ƒ}ƒtts‹’ŠŠ}|ƒ„„{tt…‹‹„„Štt{Œ‹“£œ¥™š¤”“›|‚z”š”””‹„„Štts{tttslƒ„„{{t{u{tsllriŒŒš‹uŠVTL\[b[[Tedk‚|u¦§¨ƒ„„|‚zlektt{{{ƒlddttsƒ||leklddlldtllŠƒ}‘Œ……‹‹››”tllƒ||„Š„tsl\[[{||ult{{tMSS|‚z|‚zu{{ƒƒ|„„Š„Š„lddu{{|„…”“›{ttƒƒ|sleSKJfkkVTL{ttztltzl‚|uŠƒ}“Œ”{{t„„Š{{ƒ‹‹‹{zmtll‚v{“Œ”ult›”›{{ƒƒ„„”“›ƒ„„¦§¨”››|‚znv‚ultmtt„Š„…‹’£œ¥œ››“““œ¤¦“““”“›ult‹‹‹|‚z…‹‹ª³·²¬µ£œ¥”“›œ››™š¤œ››¦§¨¦§¨¦§¨‘Œ…ttstt{Œ”•ƒƒ|{{tkd\›”›„„Š”“›dc\”“›{{ƒ‹‹„kd\ultŠƒ}‹„„‹’Š{tt’ŒŒŠƒ}šŒ‘…„“Œ”‹‹„kd\iq]|‚zUTSƒƒ|””‹{tt‹’Šllk‹‹‹[TTedklksu{{„„Š]bZVZ[lri]cdlek‹„‹|„…lekllk„„Šllkkk]‹‹„‹‹‹{ttœ¤¦{{tllkƒ||ƒ‚u””‹››”‹‹„‚|ulksllkb[Udc\VTLjcVcbV]bZlddVTLƒ}ƒ”“›dc\\[[uzt{{tlksttslddmtt|‚z™š¤]cd“““‹„„‹‹„lld{u{‹’Š[[TVTL{{tlrillk{{tƒ‚uddc[[TedkmttUMR‹‹„>EC74,ƒ|||‚z„Š„‘Œ…tsl‚|utllkd\{zmldd|‚z]bZ‹‹„‚|uŠƒ}Šƒ}¤¤œ››tt{{zmœ¤¦ƒƒ|ztl{u{lks‹„„”››|‚zŠ}|“Œ”ƒ}ƒ£œ¥‹’Šu{{”“›’…‹ƒ||‹„‹œ››Œ”•Œ”•{ttf]c[[Tsre{|||‚ztsl‹‹„ldd„„Š“Œ”]cdtt{””‹{{ƒlks|„…™š¤œ››lksfkkƒ||ƒ„„tllSKJlddSKJ[[TlekŠƒ}‹‹„ƒ„„‹‹‹ult‹‹„ekdlld\[[ƒƒ|‹„„‚|uMSS\[b\[[lld„Š„Œ”•Œ”•d\\edk„Š„”š”š””f]cœ››kd\|‚z„Š„ultƒ|||‚z¤¤ult‹‹‹ƒ„„’ŒŒ“Œ”ultŠ}|ƒ„„edkf]c{{ƒœ¤¦…‹’›”›„„Šlksƒ„„|„…{{ƒmttmtt|„…{u{…‹‹›¢›œ¤¦Œ‹“|„…tsl{{ƒ{{ƒŒ‹“¨©´™š¤Œ‹“£œ¥¦§¨£œ¥¦§¨µ¶·»ÂǦ§¨Šƒ}sre‹’Š‚ut“Œ”sreŠŠ}”š”{{t{u{‹‹‹¦§¨Œ”•Œ‹“’ŒŒ‹„„{tt›”››”›¦§¨…‹‹|‚z¦§¨š””‰‰w‰ƒv{{tƒ‚ukd\‚|ulldtslŒ”•›¢›{{tœ¤¦…‹‹tt{lek…„’lks‹„‹“Œ”™š¤ultŒ‹“›¢›£œ¥‹…’ƒ}ƒu{{ulttts{ttŠ~‹ultllkƒ||ƒƒ|£œ¥llkœ¤¦Œ”•u{{™š¤ttsƒƒ|‹„„‘Œ…kd\‹„„ƒ||ult|‚zllk’…‹kd\ƒ‚usre„Š}VZTŒ”•ekd„Š„lksJHFUMRlri|„…]cd…„’›¢›‹„‹ƒ„„bVZ|‚zlldUTS‚|ulldƒƒ|ƒƒ|dc\sleVTLJHFJHFJHFztlJHF3+*{u{››”ƒ‚u]bZtsl‚|u{tt‚ut{{tjcVb[Ukd\ttssle£›››¢›ƒ||{u{’…‹{u{’ŒŒrfk‚ut“““fkkƒ}ƒƒ„„llkœ››ult‹„„{||Œ”•ƒ}ƒ›”››”›„„Š’…‹‹’Š|‚z„„Šf]c{u{‹‹‹‹’Š‹„‹zll\[[tt{”››…‹’lekdc\\[bf]cult{{tllk„Š„‹‹„llkƒ„„lddƒ}ƒ‹„‹‹„„ƒ‚u‹„‹f]c‚v{‚|u‹„„“““ultVTL›¢›“““uztttsslef]cƒ||ddc\[[|‚z„Š}œ››u{{Œ”•ldd…‹’…‹‹„Š„ƒ||Œ—£››”ª³·|„…tllrfktts™š¤””‹lek{||{||ƒ„„‹…’tzlƒ„„{{t¦§¨“““|„…{u{|„…Šƒ}lriedkllkƒ}Š{{ƒ¦§¨|„…|„…ƒ„„“““…‹‹Œ”•|‚z””‹‹’Š›¢›‹’Š|„……‹‹„Š„…‹‹”››”“›{{ƒ¦§¨”“›™š¤ƒ||š””bVU¦§¨ª³·redtll£œ¥‹’Š’ŒŒ‹„„ÃÄƨ©´¦§¨Œ”•‹„‹“““’ŒŒ‘Œ…‚|uš””dc\ŠŠ}‚|u””‹””‹‚v‚›¢›‰‘~]bZuztkd\lek‰‘~\UZ‹‹„Œ”•ª³·›”›””‹|„…bVZultf]cf]cƒ}Šƒ}ƒƒ}Š‹’Š™š¤fkk{{ƒ{{ƒmttUTStzl‹„‹Œ‹“Š}ƒ‹„‹›”›tllultult”š”£››‹…’{{tultdc\Œ‹“u{{uztekd[[Tlridc\|‚z„Š„lrisleddctzldc\VZ[lriUTS\[[ddcVZT|„…‹„„fkkƒ}ƒbVU™š¤tt{ƒƒ|tsl‹„„lld{zmlriƒ‚ulldf]c{ttUTS|‚z›¢›JHF*)(lksuztuzt””‹”››zllƒ‚uƒ‚u{tt{tt£››uzt””‹šŒŠƒ}””‹’ŒŒ{u{ƒƒ|bVU‚|uŠƒ}tllƒ}ƒ{||ª³·‹„‹Œ”•¦§¨uzt‹‹„›¢›”“›œ¤¦{u{£œ¥lek‚v‚Œ‹“tts{||’}™‚v{{u{{||{{t{u{SKJlld{{t|„…{u{””‹„„Š…‹šult{u{lld{||{||{tt„Š„ƒ}ƒj]\Š}ƒs_qzllƒ}ƒ‹„„‹„‹tsl‚|ud\\zllcbVtslŒ”•mtt„Š„tsl\[[tll\UZ{zmuzt›¢›”š”u{{ª³·u{{|„…„„Š{{tƒ}ƒ“Œ”œ››š””¦§¨ttslekŠƒ}uzt{{tult‘ˆ}{tt{{ƒŠ~‹‹‹„‹’Š””‹ƒ„„š””ttstt{{{ƒuzt…‹‹”“›‹‹‹™š¤™š¤…„’tt{lddƒ„„™š¤|‚zu{{Œ”•ª³·‹‹„|‚z„Š„|„…”š”›¢›tslƒ„„…‹‹tt{tt{ddcddcSKJ{tttll“Œ”™š¤”“›‚v{…‹‹ƒ}ƒ‹„„£œ¥¦§¨£œ¥“Œ”¨©´“Œ”¨©´¦§¨µ¶·ƒ||™š¤ztl“Œ”””‹mw‹‹„{||uztfkkMRKlrilrillk”››ddc…‹‹ŠŠ}{||edk{{ƒf]cleku{{”››u{{mtt{{ƒtslŒ”•ƒƒ|‹’Šmtt”››™š¤„„Š|‚z{||Œ”•™š¤”“›¦§¨œ››tslƒƒ|dc\Œ”•{u{edkƒƒ|JHF„Š„VTLVTLŒ”•iq]VTLu{{]bZ„Š„lekllkuzt\UZ‹„‹ttsJHF]bZ‚v‚JHF]cd]bZSKJ‹„„›”›‚utƒ}ƒŒ‹“ƒ‚ub[UlldcbVzll|„…Šƒ}|„…{{t|‚zmttmttšŒJHF*)(ldd”š”{zm‰ƒvƒ‚u{zmŠŠ}ƒƒ|{{t‚ut‰|vŒ‹“””‹¤¤‚ut‹‹‹‚v{{||tts‘Œ…‚|u’ŒŒ¦§¨™š¤{tttts““““Œ”{zm“Œ”“Œ”ƒ}ƒ‹’ŠŒ‹“{u{tll‘…„tt{ztl|„…{||ƒ}Š‚v‚{||llktlllldlddlri‹’Š˜Ž£Œ‹“ƒ}ƒ{{ƒf]cultƒ||ƒ}ƒŒ”•mtt’ŒŒ‹‹„f]cƒ||ultrfkulttll“Œ”Š~‹ŠŠ}{tt{||{ttddctzluzt‹’ŠŒ”•‹‹‹£››š””ttsuztƒƒ|‹’Šƒƒ|edkttsŒ”•›¢›{||Œ”•œ››ŒŒš²¬µ””‹¦§¨{{ƒ›”›{{tmtt””‹ƒ||’ŒŒ{tt”“›¦§¨¦§¨Šƒ}””‹Œ”•ƒƒ|ttsƒ}ƒd\\lekttstt{‹‹‹|„…„„Šƒ}Š›”›‹„„“Œ”ƒ}ƒ™š¤£œ¥‹„‹’ŒŒƒ„„”“›Œ”•tts{tt¤¤™š¤”››“““ekdŒ‹“Š}|b[Uzll„„Š{tt¦§¨œ››œ¤¦Œ”•ƒ}ƒlksult{u{“Œ”†~‘™š¤™š¤²¬µƒ}ƒ™š¤tll“““Œ‹“¨©´‚v{£œ¥’ŒŒ“Œ”‚v{tll£››‹’Š{{ƒ|‚z|‚z„Š„Œ”•‹‹„””‹‹‹„lld„„Š…„’f]cƒ}Š„„Š”“›{{ƒ…‹‹]cduzt™š¤ª³·›¢›œ¤¦”››¦§¨„Š„‹’Šƒ}ƒ£››{{ƒœ¤¦…‹’„Š„””‹‹’Š‘ˆ}“Œ”‚v{[[Tuzt{||{{tVTLcbVllk|„…tzl[[TuztUTSuzt\UZVZ[‹„‹Œ”•ekdtll\[[uztUMRlri[[Tttsƒ}ƒ’ŒŒ£œ¥|‚zƒ„„‘Œ…kk]ekd{zmƒ„„‹’Šƒƒ||‚ztzl[[Tedk‚v{:973+*|‚ztts‹‹„lld{zm‘ˆ}ƒ||ztl”š”„Š„lddœ¤¦””‹¤¤‚|utslƒ||‹„„Œ‹“‹‹„‹‹„¦§¨‹„‹”“›Œ”•’…‹™š¤››”‹‹„¦§¨£œ¥…‹’¦§¨™š¤“Œ”{tt”›››”›ŒŒšµ¶·™š¤··Ä…‹’‹‹‹{{t“““‹‹‹{u{ƒ||lrif]c{{ƒ\UZ\[b™š¤f]c{{ƒŒ‹“‹‹‹…‹‹™š¤…‹‹Š}ƒ“Œ”ƒ||[TTƒ}ƒ\UZ{u{sle’‘~””‹”“›“Œ”‚ut|‚zƒƒ|‹’Š‹’ŠlriuztSKJ{||ult“Œ”œ››‹„„lksMSS|„…„„ŠŒ”•{{ƒ”š”‹‹‹ƒ}ƒ‹‹„|‚zlks¦§¨’ŒŒ{||‹„‹ƒ||‹„‹„Š}‹„‹µ¶·œ›››”›ƒƒ|‹„„›”›uztƒ}Š{ttttsŒ”•‹„„„Š„„„ŠŒ‹“Œ‹“ƒ||ultƒ}ƒ„vŒ¦§¨ƒ„„uzt””‹’…‹ƒ„„ª³·tts…‹‹Œ‹““Œ”lddŒ”•lddtsl›¢›‹…’£››¦§¨™š¤µ¶·lksŒ‹“Š}ƒ“““ultlks™š¤ult‹‹‹™š¤„„ŠlddlddŠ~‹‹„‹ƒ||™š¤Š}ƒ…‹’Œ”•”››”“›ultœ¤¦tllŠƒ}“““””‹¤¤™š¤|‚zlridc\“““|‚zekd„Š„lri|„…tslŒ”•f]c™š¤ƒ||{{tŒ”•ƒ„„ƒ„„{{ƒ…‹‹uzt“Œ”„„Šµ¶·¦§¨|‚zƒ„„ƒƒ|lldllduztkk]“““]bZ””‹{tt„„Šllk[[T|„…mttddc‹’Šƒ„„‹’ŠVTL{{ƒ”››ƒ}ƒŒ‹“f]cUTSlkslkslri{||Œ”•lksttsult››”ultlks‹„„£››””‹ŠŠ}ƒƒ|‹‹„{{tdc\]bZ|‚z[[T[[T¦§¨LKR*)({{ƒtll””‹œ››{zm|‚z‘Œ…{{t””‹””‹£››™…””‹‘}zŠ}|””‹{tttt{Œ‹“uzt“Œ”£››ƒ}ƒ“Œ”{||ƒ}ƒŒ‹“Š}|””‹“Œ”œ››Œ‹“ddcƒ„„“““”“›’ŒŒ…‹‹{u{Œ”•™š¤{{ƒ¨©´Œ”•{||ttslek‹„„u{{ttslek\UZlddVZ[£œ¥ƒ}ƒlkstt{{||tll’ŒŒttsrfkŠ}|‰v|lddrg]‚v{„„Š“““„„Š‘Œ…Œ”•‚utldd‹’Šlldekdtzlekd„Š„tlllldŠ~‹{{ƒŒ‹““““}‡’\[[f]cŒŒš|‚z{||’ŒŒllk‹‹„llkƒ„„”››‹‹‹{tt’ŒŒšŒ²««››”“““£œ¥‹…’‹‹„|„…š””lldƒ„„tts{u{‹„‹‹„„{{ƒ“Œ”{{ƒ™š¤…‹‹Œ”•ƒ„„ddc¨©´ttsult™š¤ult{{ƒ¦§¨””‹Œ”•|‚z‹‹„{{ƒ™š¤Š}ƒd\\„„Š{tt‚v{ƒ}Štt{tll”“›œ¤¦…‹‹“Œ”›”›™š¤“Œ”f]c‚ut{{ƒ“Œ”\UZ‹„‹rfk™š¤ultƒƒ|ƒ||“““‘Œ…uzt¦§¨llkŠ}ƒ‹„‹›”›‹„‹ƒ„„sle{u{”“›‹’Šœ››d\\]bZtslŒ”•lrillkmtt{ttmtt‹„‹d\\ƒ|||„…Œ”•”››™š¤…‹‹„„Š…„’“Œ”“Œ”¨©´‚v{…‹‹ultŒ‹“|„…‹’Štsltzl{||ƒƒ|lriuztlks“Œ”””‹ztlƒƒ|‘Œ…|‚z{{t{{t[TTlldekdƒ}ƒd\\{u{d\\[TTJHFVZTuzt{||ekdf]c{{ƒlekƒ||‹„‹…‹‹lrizllztl“““tzl|‚z{{t„Š„]bZ‹’Š]cdu{{²²¬:97*)(kk][TTƒ‚uƒƒ|uzt‘Œ…Šƒ}””‹²²¬””‹‘ˆ}Šƒ}””‹sleŠ}|””‹¦§¨›”›™š¤œ¤¦‘Œ…“Œ”“Œ”ultƒ„„¦§¨¦§¨ƒ„„Š}|››”²««™š¤‹‹‹ƒ„„“Œ”£œ¥œ››“““œ››””‹„„Š“Œ””››£››{||‹‹„‹’ŠŒ‹“edk|‚zŠƒ}{{ƒd\\]cd‹’Š|‚zŒ‹“ƒ}Š”››£››™š¤ƒ}ƒ›”›Š~‹ylemttkd\ddcf]c{u{sreŠ}ƒttskd\“Œ”‹’Šzlldc\llktslttsd\\|„…ultu{{tts‹’Šlrilksddc”“›lksddcƒ||lksŠƒ}¦§¨Šƒ}|„…””‹|‚z{{ƒ…‹‹Œ‹“››”{tt‹‹‹Œ‹“‹„„rfk{zmtsl{{tŒ”•“““‹„‹””‹œ››‚v‚{{ƒ¨©´™š¤ƒ}ƒ‹„‹ttsƒƒ|ƒ„„…‹‹”“›‹„‹{{t¦§¨ƒƒ|™š¤ttsŒ”•Œ‹“„„Š£œ¥”š”¦§¨ƒƒ|‹„„{{t“Œ”‘Œ…™š¤‰v|‹‹„‹‹„¦§¨Š}ƒƒ}ŠŒ‹“’}™„„Š„„Š”“›ƒ}ƒ‹…š\[b£²ƒ}ƒddc”š”{{ttllf]cƒ‚ulritsl›”›Š}|{zmƒ||ƒ}ƒ„Š}]cd„„Šu{{u{{[TT{{ƒmtt‚v{”“›|„…ztl…‹‹{{ƒtll{u{¦§¨œ¤¦…‹’…‹‹{{ƒ|‚z‹‹‹™š¤…‹’”“›”“›Œ‹“š””|‚z‹’Š|‚z””‹lrikk]|‚z”š”Šƒ}tzl¤¤“““tllƒ„„llk“Œ”“Œ”{ttŒ‹“ƒƒ|\[[kk]ƒ||tllVZT‹‹‹|„…u{{tt{|‚z‹„‹]bZƒ}ƒ[TTtt{lri{||ultlld|‚zllkekd[TT{||mtttzltll{||²««F=C7-2‚ut‹‹‹„Š„ztlƒ||‹„‹{zmsrekd\{{t¤¤sle›¢›ult””‹‹‹„‘…„‹„‹ƒ„„z‚l’ŒŒ‚utš””{u{‹„‹Šƒ}ƒ}ƒmtt£››Šƒ}™š¤{u{‹’ŠŒ‹“‹…’Œ”•“Œ”“Œ”™š¤uztŒ‹“›”›…‹’‹’Š’ŒŒ|„…„Š„lksmttŒŒš{ttu{{{{tuztŒ”•dc\tt{ult{||ƒ„„›¢›…„’ƒ||tll‹„„[TT{{tddc‚ut{||„Š„\[[Œ‹“{||Œ‹“‹‹„ekdlldƒƒ|{{t{||tts\[blksƒƒ|™š¤‹‹„lrilks}‡’Œ”•™š¤‹‹„›”›llklddllk„„Šllkf]c\[[“Œ”””‹›”›‘Œ…œ››tts‹„‹Œ‹“‚|u’ŒŒƒ„„lldu{{£››™š¤œ¤¦…‹‹”“››”›edk‹…’“Œ”™š¤Š}ƒƒ„„„„Š‹…š‹…’””‹Š}ƒ‘Œ…‚ut‹„‹‘ˆ}‚|u‹’Š{||Š}|tts‹’Šsreƒ„„Šƒ}Š}ƒ£œ¥£››Œ‹“‹’Š„Š}™š¤›”›“Œ”‹u…œ››“Œ”Š}ƒ{{ƒ“Œ”“Œ”‹‹‹„„Šf]c{u{‹„„zllldd‹’Š£››ztl{ttttslksedkFD;kd\””‹z‚l[TTŒ”•“Œ”™š¤}‡’UMR\UZ…‹’|„…„„Šlks…‹šedk…‹‹UTS…„’Œ‹“™š¤u{{u{{™š¤|‚zyl„¦§¨{{tŠƒ}‹‹‹{{tllkd\\ƒ||{{ƒ|„…ult{||]bZ{{t”››””‹lddVTL¦§¨„Š„{||”“›ƒ||“““{{t|„…mttf]cuztultlks‹„‹llktt{{u{edkrfktllƒ}ƒlri{{ƒ{tt‚|u„Š}ztl[[TztlŠ~‹|„…{{tlldlld²««JHF*)(tsld\\|‚z’ŒŒƒ„„ztl‚wl[[TŠŠ}‚v{’ŒŒu{{‘Œ…’ŒŒƒ}ƒ‹‹„‘…„{ttƒ}ƒ„Š„‹’Š“~ˆzll‹‹‹£››„Š}‰‘~„„Š‹‹„„Š„“Œ”™š¤ttstts{u{‹‹‹|‚z¦§¨Œ”•‹’Š™š¤{||™š¤ƒ||tll‹’Šlritt{\[b|„…ƒ}Šœ¤¦ekdldd|„…ƒƒ|‹„„ŒŒšllk{{t|‚z|‚ztslƒ}ƒ‹„‹{{ƒult…‹‹{{tcbV{ttŠ}ƒ“Œ”ƒ||cbV‚|u{||”š”›¢›‹’Š„„ŠVTL\UZŒ‹“Œ”•Œ”•ƒƒ|œ¤¦{{ƒŒ‹“ƒ„„”š”‹’Š“““|„…ƒ||‚|uyle|„…{tt„Š„ƒƒ|ƒ„„ƒ„„‘…„”“›tllŒ‹“llktts|‚ztts‹‹„„„Š”“›ƒ||Š~‹Œ”•„Š„|„…f]c{{ƒŒ‹““Œ”Š~‹ƒƒ|¨©´lld{u{{{ƒ›”›“Œ”lri{{ƒ’…‹Œ”•‘…„£œ¥‹„‹{{ƒŒ”•›”›™š¤‹‹‹ztl‹„„¦§¨‹‹„ƒ„„””‹“““Šƒ}‹„‹tlltsl‹‹‹ƒ}Šf]c{u{tts{||‹‹„Œ‹“[[T¢“d\\zllj]\‹„‹‚v‚“Œ”‘Œ…››”SKJ‚v{sre\[[œ››””‹Šƒ}|„……‹‹{{ƒmtt„„Šf]cŠ}ƒttsƒ}ƒtzlVZTƒ}Š\[[ultdc\lri|„…{{tu{{œ¤¦œ¤¦””‹…‹‹‹‹‹‹„„””‹ƒ„„ultƒ}ƒddc”“›Š}|VZTVTLuztmttJHF|‚z|‚z”››lld›¢›„Š}›¢›‹‹‹lld‹‹‹ƒ}ƒtts|„…ultf]cddc[TTtslf]c”“›‹„‹{{trfkŒ‹“>EC{{tVTLlldllk{ttfkktsl|‚z”š”]bZ›¢›£››:97:97Š}ƒƒ||››”tll‚|u¦§¨{{t|„…ztl{{t¦§¨‚|uŠƒ}“Œ”ƒ‚uŠƒ}¦§¨|„…ult””‹dc\sle“Œ”‹„‹‹…’“Œ”‘…„rfkƒƒ|‚v{“Œ”ƒ„„¦§¨{{t‹„‹‹‹‹“““¨©´ƒ„„|„…{||‚v‚tt{¦§¨{{t]cd…‹’tt{uzt…„’{ttœ¤¦ddclri]bZrfk“Œ”|„…{{tŒ‹“|„…u{{ultlriredu{{ƒƒ|r]g{{tƒ}ƒlddƒ||‹„„lddredred›¢›¦§¨œ¤¦„Š„›¢›mttUMRu{{{tt{||srett{ƒ}ƒŒ”•{{ƒª³·””‹£œ¥›¢›ƒ||””‹rfk{||{||ttslri…‹‹‹‹„œ››”“›{||¦§¨‹‹‹ŠŠ}‹‹‹“““›¢›‹„„”“›Œ”•{tt…‹‹‹‹‹”“›Š~‹f]c‚v‚ƒƒ|œ¤¦\[[‚v‚…‹‹Œ”•tt{„„Š“Œ”llk“Œ”‚|u|‚zœ››„„Š‹‹„|„…–¢‹‹…’”››ƒ||lld”š”tt{ƒ„„‹‹„ztfŠƒ}¨©´’…‹”“›„Š„‹’Š{||dc\f]c‹„‹ƒ}ƒ””‹Š}|””‹Šƒ}kd\‹’ŠlekVZTlrisleredzlltllztlsreVTL{{t‹‹„£››‹…š‹„‹‹‹‹‚v‚{{ƒlks|‚z’ŒŒ„Š„uztsle…‹‹\[b]cdƒ}ƒŠ~‹ƒ„„uztmtt”››Œ”•Œ”•ttsmttddc{|||‚z{||sleJHFƒƒ|\[[‹’Š[TTdc\„Š„„Š}lri”“›|‚z\[[›¢›ƒ„„]cd‹’Š„Š„rg]š””ekdtslƒ||ddcuzttt{ƒƒ|Œ‹“„„Šlld‰|vdc\u{{SKJdc\tslVTLlld[TTsreƒ||lriaWMSKJ|‚z£››D;9*)(ƒ„„“Œ”Šƒ}tslƒ‚u’ŒŒ››”‘Œ…’ŒŒ””‹“Œ”Šƒ}£››¦§¨£››{{t¦§¨ƒƒ|‹’Š“““lek‹’ŠaWMª³·‹„‹›”›…‹‹‚ut‹’Š£››Œ”•|„…””‹ŠŠ}£››Œ‹“œ››²¬µµ¶·Œ”•›”›ƒ}ƒŒ”•ƒƒ|[[T’ŒŒ[[T]bZmttd\\ƒ„„{zm’…‹„Š„tsl„„ŠŒ‹“{{t’ŒŒƒ||„Š„ƒ}ƒš””lriztlŠƒ}{ttldd„Š}{u{Œ‹“”“›‹„„‹„‹Š}ƒult…‹‹|„…„Š„|‚z‹‹„‹’Š|‚z””‹„Š„ekd””‹u{{f]cztlƒ„„…‹š”››¦§¨ttsƒ„„„Š}ztfddc‹„„{{tsre‹„‹„Š„ƒ||{tt{||„„ŠŒ”•”š”¦§¨…‹‹›¢›””‹‹‹‹lksult™š¤Œ‹“ƒ„„tt{llk{{ƒsle{{ƒŒ‹“‹‹‹|„…¦§¨Œ‹“…‹‹{{t‹„‹ultŠ}ƒ‰ƒvœ¤¦„„Š’ŒŒ…‹‹llk„„ŠtllcbVŒ‹“’…‹|‚zƒƒ|ztltt{‹„„¦§¨{||mwsreƒ„„‹’Šsleult{tt…‹‹‹„„ŠŠ}ƒ„„ƒ‚uzll‚utylelritll£œ¥‹„‹””‹tlltzlkd\b[UddcŠƒ}lek™š¤›”›edk›”›‚utƒ||„Š„|„…u{{‹’Š|‚zllk{{ƒƒƒ|Œ”•tslŒ”•››”‹‹„™š¤u{{ƒ}ƒlldƒ}ƒUTS””‹|‚z[[Tultuzt¦§¨tt{mtt{{t{{tlld]bZbVUultultUMRŠ}ƒ{||‘Œ…‹’Šb[Uztlf]c{{ƒ…‹‹ultult””‹|„…{||{{ƒ{{ƒkd\„„Štt{fkkf]cd\\‹‹‹‚utzll{{tlrilridc\\[[ekduztš””:97*)(tzlsre‹‹„ƒ}ƒ{tttts””‹¤¤£››“““’ŒŒ‘…„“Œ”²««ƒƒ|‘Œ…ƒ„„{ttttsƒƒ||‚z«²«Œ”•{tt¨©´£œ¥¤¤…‹‹‘Œ…ƒ||¦§¨“““›”›¦§¨›”›™š¤‹‹‹¤¤œ››‹’ŠddclddŒ‹“|„…]bZ\[bƒ||tt{‹’Š‚v‚ƒ}ƒb[U‹‹„|‚z‹’ŠŒ‹“ƒƒ|‹‹‹‹„„{||u{{ldd›”›‹‹‹{u{ŠŠ}kd\zllkd\lek”“›‚v{kd\edkŠƒ}{{ƒ“““|„…£››tts„„Š„Š„[[T{{ƒ‹’Šmttdc\]cdSKJlek…‹‹lkskk]‹‹„{||“““tsllldllkslelld[[T{ttƒ}ƒ£œ¥‹„‹››”’ŒŒ|„…£œ¥””‹ddc|‚zlddƒ}ƒŒ”•‚v{¦§¨‹‹‹Œ‹“’ŒŒult“Œ”œ¤¦ŒŒš“Œ”uztttsŒ”•ldd…„’mwƒ„„{tt“Œ”“““‹‹‹“Œ”’ŒŒultŒ‹“”“›”“›‚v{ƒ„„{||™š¤”››ƒƒ|‹„‹tllš””Œ‹“œ››tsl{{tŒ”•””‹{||\UZ{{ƒ‹‹„µ¶·‹‹‹œ¤¦ƒƒ|{tt‹‹„”š”‹„‹£œ¥’ŒŒ‘Œ…SKJttsjcVldd]bZƒƒ|‹„‹ƒ„„™š¤Š}|lekf]c‹„‹dc\“““„Š„‹’Šttsœ››„Š„“““¨©´„„Š{{ƒŠƒ}lri…‹‹{{ƒƒ}ƒyl„edkbVZj]\›”›[[T‚|uekdd\\{{ƒ{ttddcttsf]c[[Tek]sleult“““lksFD;zllztlƒ||‹„‹tt{UMRfkkultu{{‚|uJHFƒ„„red“Œ”ƒ}ƒŠƒ}{{ƒ{||\UZztl{||ƒƒ||‚z”š”]bZkk]dc\\[[UTS]bZ¦§¨:97*)({{t{ttlddred’ŒŒƒ}ƒ¤¤{zm„Š}²²¬š…Ž‹’Šztfztl¦§¨ƒƒ|“Œ”„Š„£œ¥µ¶·“““¦§¨¦§¨“Œ”…‹‹”š”¦§¨£œ¥›¢›ƒ}ƒ¨©´’ŒŒ‹„„””‹{||””‹‹‹‹„Š„{ttƒ||{||››”ddc{{ƒ‹‹„ƒ||lek”“›Œ”•”“›tlld\\lld‹’Šœ¤¦ƒ}ƒ“Œ”‹„‹sredc\Œ”•“Œ”„Š„u{{{||sleSKJ‹„‹ƒƒ|tlltllzll‹„„r]g“Œ”mtt„„Š“““¤¤Œ”•{||ƒ„„tslƒ}Šœ¤¦|‚z{{tuztd\\ƒ||”››ddc‹’Š–¢‹ƒƒ|ztllritts‹‹‹ztlƒ„„|‚zƒƒ|ƒ||{u{‚ut’ŒŒ‹„„„Š„{{ƒ‹’Šlld‹„‹{{tƒ}ƒ““““Œ”Š}|lek“Œ””“›ultƒ}ƒ™š¤“Œ”tt{tts”š””››œ››{{ƒUTSlksttslriœ››‹‹‹“Œ”tts{u{ƒ||›¢›ƒ}ƒ‹„‹„„Š‚|uek]™š¤‚|u²««{||”“›tsl“““Œ”•{{t””‹ƒ||{||tts|‚z‘Œ…“““ƒ„„š””{{t£œ¥‹‹„”“›\UZ£››ddcztl‹’Šdc\VTLVTLek]tllŒ”•ª³·{ttyfltt{\[[ƒ}Š[TTtt{leku{{VTL]cduzt…‹‹„„Š„„Šu{{lksd\\|‚z››”f]c¦§¨lri{u{j]\edkttsllk]bZllkƒ„„{{ƒ\[[SKJek]tll‰|v””‹VZT“Œ”[TT{||dc\ldd[[T‚v‚lksf]cƒ}ƒttsf]cJHF]cd{{ƒlek“Œ”‹‹„tt{Œ”•fkkƒ}ƒ‚v{|‚zsle\[b‰‘~lrisre]bZ[[TFD;ƒ||“Œ”:97:97rfkkd\‹‹„{tt£œ¥””‹‹’Š›¢›{{t£››ƒƒ|””‹›¢›‹„„²¬µ‹’Š™š¤£œ¥š””‹‹„¤¤”“›²¬µ“““œ››™š¤””‹”š”››”|„…µ¶·‹’Š¦§¨¦§¨œ¤¦›”›œ››ƒ„„š””‹‹‹‹„‹¦§¨|‚zultƒ}ƒ‹‹‹”š”¤¤¦§¨{{ƒlektts{{tllkŒ”•{u{‹‹‹‹‹„…‹‹¤¤™š¤‹‹‹{{ƒ”“›‹„‹{ttb[UbVZtslƒƒ|ult£››ztf”››‚v{œ››{u{llkztl„Š„ƒ„„UTS‹‹„{{ƒsre™š¤ƒƒ|mtt‹„„ƒ||”š”…‹‹mttŠƒ}‹„„‹„„ek]Šƒ}{{ƒ’ŒŒ\[[lrisle{u{ƒ}ƒrfkš””ƒ}ƒ‹’Š£œ¥‹‹„lri‹„‹ƒƒ||„…|„…™š¤””‹““““Œ”ƒ}Š™š¤‹‹‹“““tslultmtt…‹‹„Š„ƒ||…‹‹llk‚|uƒ}ƒ{u{‹„‹Š}ƒ”“›ttsllkŠƒ}¦§¨{||š””dc\{||ult|‚z{{ttslultš””ƒ||£›››¢›uzt‹‹„›¢›Œ”•„„Š£œ¥¬¶Ã“Œ”£œ¥›”›‹’Š²¬µƒƒ|{||{||‹‹„Œ‹“‘Œ…lld‹’Š‰ƒvŠƒ}‹‹‹ŠŠ}Œ”•ƒ„„ultbVUf]clddƒ}ƒedk[[Tlriult›”›”››™š¤‹„„ultlri”“›ek]{{tdkVmttƒ}Šztlult’ŒŒ„„Štt{llkUMRLKRƒ}ƒ“Œ”{tttts{{ƒ\[[ttsttsŠ}|kk]llk|„…ƒ||£œ¥uztlek™š¤Š}ƒ{{ƒf]cJHF‹‹‹{||VTLlriƒ}ƒ|„…Œ”•mttllk\[b{u{ultllkttssre{{trg]|‚zuztMRK\[[dc\¦§¨:97*)(dc\ztl’ŒŒ‹‹„„Š}””‹‹‹„ƒ||››”¤¤{u{ƒ‚uŠ}|’ŒŒ¨©´œ¤¦{||¦§¨”››‹’Š«²«µ¶·œ¤¦œ¤¦”“›“Œ”œ››„„Š¦§¨„„Šƒ}ƒ™š¤“““”››‹‹‹‹’Š‹‹‹ƒ‚u‹’Š¦§¨£œ¥²¬µ”››uzt‹‹‹²««{{tœ¤¦‹’ŠŒ”•{{ƒ{u{SKJ[TT|‚z“Œ”kd\‹‹„„Š„‹„„u{{‘Œ…UTSƒ||j]\{zmlddƒ}ƒrfk{{ƒtll’ŒŒ{tt‹„‹{tt“Œ””››™š¤£››{||„Š„JHFtsl‚v{{{tu{{”››„Š„uzt‹„„ttsŒ”•|‚z””‹lldd\\“““¤¤‹‹‹‚v{|‚z„Š}‚|ullkf]cultult‚|u”š”{tt|‚z{||Œ”•œ¤¦”››Œ”•”“›„vŒ|„…yl„“““Œ”•’ŒŒ””‹ult{u{|„…{u{{||ztl‹…’‹‹„ult[TT{tt’ŒŒ‹„‹{{ƒ‹„‹[TT‹‹‹‹„‹‹‹‹tlltsl{u{tlltslred‘ˆ}’ŒŒ›”››”›{||Œ‹“¦§¨”š”ttsœ¤¦¨©´…‹‹‹‹‹“““›”›“Œ”{tt‹„„|„…uzt{u{ƒ||¨©´››”‹’Š‹…’ƒƒ|‹‹‹|‚z“““‹‹‹“““ƒ„„“Œ”Œ‹“{tt{{ƒ[TT]bZb[UlriŒ‹“uztdc\{tt{{tredult|‚z{||{{t{zm{{t{{t“““‹’ŠVTLŒ”•‹…š\UZtts‹„‹d\\ƒ„„œ››ƒ}ƒddcƒ||\UZek]SKJ{{ttt{UMRŒ‹“{{t‹„‹‹„‹„„Šd\\VZTUMRlri{ttddc…‹‹ƒ||„Š}‹…’d\\tsltts[TT|„…„Š„Š}|u{{z‚llriŠƒ}ddcUTS[TTlektslFD;,55‹‹‹››”Šƒ}yleŠƒ}‹‹„’ŒŒ‚ut””‹ƒ||‹‹„Š}ƒ{{ƒƒƒ|ƒ}ƒ‹‹„„„Š…‹‹›¢›¤¤¤¤‹’ŠŠ~‹¤¤‹…’‘Œ…˜Ž£ƒƒ|‹„‹sre›”›|‚zœ››ƒ„„‚|ulri|„…‹‹„“Œ”tll‹„‹™š¤…‹’u{{|‚z‹„‹‹‹‹…‹’ŠŠ}ult‰|v{||dc\£œ¥fkkleklks’ŒŒ†~‘£››ƒƒ|œ››Œ”•{||””‹j]\tllŠ~‹{u{‚ut‚ut“Œ”tts{u{ƒ}ƒ„„Š{||”“›‹‹„uztuztllklld\UZ„Š„Œ”•VTL{{ƒ|‚z|„…›¢›œ¤¦lrikk]‹„„‹„„{{t™š¤ƒ}ƒtllrr]””‹{{ttt{lddf]c’…‹‚v{‹‹‹¦§¨lri™š¤‹‹‹”››¦§¨Œ”•Œ‹“Œ‹“¦§¨£²ƒƒ|”“›Š~‹”››{{ƒ…„’|„…]bZŠ}ƒŠ~‹“““fkkŠ}|llkb[U‘…„{u{£œ¥ƒ||d\\‹’Šƒ||’…‹tzldc\cbV{{ƒdc\””‹‘Œ…j]\ddc‹…’Š}ƒœ››Œ”•œ§²|‚z”“›u{{tslŠŠ}¦§¨‹„‹{||…‹‹™š¤‹’ŠleklekŠƒ}‹„„zll|‚z‹„‹‰ƒv²²¬…‹’sle…‹‹“Œ”ƒ}ƒ‚v{VZ[ultultbVZ‘…„ƒ}Šƒƒ|tll…‹‹SKJVZ[uztUUYUTS|„…‹‹„ddctslllkŒ‹“™š¤‹„‹‹’Š¦§¨‹‹„{{ƒƒ}ŠŒ‹“{tt‹„‹lekŒ‹““Œ”u{{lri{{ƒ{{tztltll[TT™š¤{{ƒ{tt‚utƒ}ƒ‹„‹ddcUUYllkœ››lri‹„„tt{ztl‹„‹VTLƒƒ|{{tldd“Œ”tslmtt‹‹„ƒ„„lriztl‹’ŠtslUTSJHF’…‹:97*)(Œ‹“„Š}“““{||””‹Šut„Š}tll¦§¨{{t‹‹„››””š”””‹“““œ¤¦¦§¨ztlµ¶·‹‹„µ¶·””‹Œ‹“”š”ult“““’ŒŒuzt™š¤‹‹‹£œ¥ƒ„„{{t‹‹‹›¢›|„…‹‹‹{||‚|uƒƒ|ƒ}ƒ|‚zŒ”•lksƒ„„{tt‹‹‹…‹‹Œ‹“…‹’ƒƒ|tslœ¤¦{ttŒ”•›”›¦§¨“Œ”‹„„ƒƒ|ƒƒ|‹’Š‚v{””‹ddc‚utJHFƒ}ƒtts„„ŠŠƒ}bVU{u{{{t{u{‹„‹{{ƒ…„’slerfk{{ƒ|„…{{tult\[[]cd[[TmttlriVTLlri|„…œ››ztlƒ||lld””‹ƒƒ|{ttd\\{{ƒ””‹Šƒ}{{ƒtllŠ~‹’…‹“Œ”™š¤ƒ||›”›„Š}‹‹‹’ŒŒ£œ¥ƒ„„‹‹„™š¤ƒ}ƒ…‹’‹„„œ¤¦lri{tt{||ƒ„„llkzll|„…sle‹’Šllk{u{‹„„sletll‚|uƒ||Šƒ}lkstzl“Œ”ƒ||”“›„Š„ƒ‚uŒ‹“lld’ŒŒ””‹‰|v“~ˆ‹„‹™š¤™š¤“““ƒ„„{tt{u{\[[„Š}œ››“““{||uzt[[Trfk‹‹„d\\{u{š…ŽŒ‹“¦§¨œ››ƒ„„“““tsl|‚z‚|uƒ„„ult{u{UUY\[[ldd{{t{u{‚utult{{tƒ}ƒ…‹‹Œ”•ult‹’Šj]\lek„„Štt{ztllriddcŒ”•‹„„{ttb[ULKRVZ[lks…‹šf]cttslddult‹’Šƒ||{u{ult‚ut{{tbVU{||VZT\[[Œ‹“{{t’ŒŒtll¦§¨‹‹„VZ[mtt{ttmtt{{tf]cSKJ{u{ƒƒ|„„Š\UZztldc\SKJ‚v{tsl{{tuztuzt|„…\[[VZTUTS¤¤:97*)(ƒ||kd\›¢›{{t››”¤¤‹‹‹›”›ztl‘Œ…¤¤™‹†ƒ||sretts£››‹‹‹¦§¨”š”’ŒŒtslœ¤¦ª³·µ¶·¦§¨™š¤‹‹‹”š”‹„‹”“›”“›””‹¦§¨ª³·¦§¨¦§¨tt{Šƒ}|‚z”“›{u{£œ¥UTSztl|‚z{||…‹‹ƒ„„‹’Šttsƒ„„{||œ¤¦ekd‹„„“““™š¤bVZekdƒ‚u›”›‚|uVTL\UZ{||“Œ”f]cŒŒšult{u{‹‹„“Œ”Š}ƒ|„…lek‚v{{u{›”›leklksf]clldUMR{{ƒcbV…‹‹””‹‹„‹ddcSKJuztddc‚|u‹‹„“Œ”sleœ››{u{››”Š}ƒƒ„„„Š„kd\ult‹„‹Œ”•Š}ƒ”“››¢›™š¤“Œ”¦§¨¦§¨œ¤¦„„Š«²«£››™š¤‹„„ƒ„„“““ƒ}ƒ‹’Š‹„‹“Œ”£œ¥Œ”•{{t{{ƒ‹„‹¨©´{ttdc\‹‹„…„’zllztl‚utƒƒ||‚z››”‹„‹‚v{{tt„Š„tslŒ‹“ƒƒ|‘…„kd\ƒ}ƒ’ŒŒj]\Š~‹£››‹’Š‘Œ…œ››”“›…‹‹œ¤¦‹’Š”“›{{ƒ{tttts[TT”š”mttu{{kk]lekƒ‚u””‹ƒ„„–¢‹‘…„…‹‹{ttuztlekedklrimttd\\\[[ƒ||{{ƒult‚wl{u{Œ”•Œ”•‹’ŠUTSedkd\\ƒƒ|UUYtllf]ctts‹„‹ŠŠ}|‚zƒ||UTS\[[llkœ¤¦UMRrededk{{ƒ‹‹„ƒƒ|lek|„…sreƒ||‚utddclrimtttt{{u{ƒƒ|””‹lri\[b\[b[[Tlri{||lldf]c‹…’™š¤¨©´mtt›”›tll„Š„lekdc\ƒ‚u‹‹‹ƒ‚uttsmtt‚v{[[Tekd£œ¥:97*)(ztlƒ‚u›¢›tsl››”‹’Š‹‹‹”››„Š}£›››¢›””‹”“›ƒ||¸Á¹¨©´£››{tt£››ƒƒ|‹‹„„„Š“““™š¤““““Œ”Œ”•¨©´Œ‹“”“›ƒƒ|{{ƒ›¢›ŠŠ}tsl”››ƒ}ƒ‹‹‹‹„„“Œ”{tt|‚zUTS]cdlritllŒŒš‹„‹|„…lkslldtsl…„’mttŒ”•Œ‹“”“›Œ”•ƒƒ|‚|uult””‹‚wltslrfkƒ}ƒj]\\[[uztleksresre{||{u{‹‹‹£››’…‹“““ƒ||‹‹‹“Œ”{||d\\ƒ}ƒ{tttt{|‚z‚|ulks”“›”››“““››”Šƒ}››”²¬µ›¢››”›‚|u‹…’lld„Š„Šƒ}ª³·¨©´“Œ”š””‹„‹|‚z™š¤’…‹|„…Œ‹“ƒ„„tllu{{’…‹””‹ƒ||ƒƒ|¦§¨œ››u{{”“›”“›…‹‹„„Šƒƒ|sleƒ}ƒ£œ¥{u{‹‹„Šƒ}œ››ldd””‹Œ‹“›”›œ››››”™š¤…‹‹“““¦§¨‹‹„£œ¥›¢›‚v{‚|u“Œ”‹„„‹„‹mwtll{{tŠƒ}Šƒ}ttsfkklri{{t’ŒŒ“Œ”{||‹’Š‹’Š|‚z‹„„ƒ„„tts{u{b[U{||i\V‰ƒv¤¤llkŠƒ}‹‹‹tt{‹‹‹lriSKJb[U]bZ{u{llk{tt‹„‹dc\uztfkk„Š„ddc{u{ƒ||””‹Šƒ}tzl{zmtsl{ttztllldllktt{„„Šƒ||lri{u{slef]c|„…{{t›”›MRK…„’sretzlsretslUUYUTSŠ~‹ttsldd¦§¨{||{u{\[b[TTf]ctslcbVtlltt{ƒ„„b[UUUY{{ƒkd\ultJHFleklld{ttfkkƒ}ƒUTSJHFVTL|‚zŠƒ}JHF*)(„Š}‹‹„‹’Š‚ut„Š„›”›|‚z“““¦§¨‘…„¤¤ƒ||‘ˆ}‹‹‹£››”“›””‹‹’Š››”{ttµ¶·£››Š}ƒ{||‚v{œ¤¦”“›¨©´Œ”•‹‹‹ƒ||›¢›uzt|‚zttsŒ”•|„…lri‚|u”š”‹‹‹edk]cd]cdf]ctsl{u{|‚z{{ƒtt{ult‹’Šœ¤¦‹’Š‹’ŠŒ‹“‹„„‹„„”“›››”’ŒŒƒƒ|„Š„bVUlriŒ‹“f]cJHFbVZlekƒƒ|ult‚v‚sleƒ„„zll‹„„“““‹„„tt{ƒ}Šfkk„Š„j]\ƒ}ƒ‹„‹{ttultŒ”•‹‹„{zm{||ƒƒ|‹„„ƒƒ|¦§¨ƒ„„Š}|’…‹Š~‹ƒ‚n|‚z””‹™š¤‹„„…‹‹tll’ŒŒ””‹{u{‹„„…‹‹“Œ”‹‹„Œ‹“{{t|‚zœ››Œ‹“ddctll„Š„¨©´“Œ”Œ”•œ››’…‹”š”ztl{{ƒ|‚z’ŒŒ‹’Š‹‹„ƒƒ|Š}ƒ‹…’Œ”•Š}ƒŒ‹“Šƒ}¤¤’…‹’ŒŒ‹„‹Šƒ}{||‹„‹ƒƒ|ƒ||ƒƒ|ƒ||Š~‹ult…‹‹‹‹‹zll‹‹‹„Š„{||llkkd\lek£››Š}ƒsle‹„‹ƒ„„{tt”š”‹’Š‹„„‚|ullkllkzll””‹Š~‹[[Ttlltt{[TT\[[ddcSKJ‚utredu{{tt{‹„„|‚z‹’Š|‚zlridc\tt{‹‹‹„Š„Œ”•””‹lrif]c{u{{||{u{Œ‹“lkslektllylezlltsl„„ŠmttsleultJHF{{ƒek]lld…‹‹zlllldekdztl‹’Š‹‹‹‹‹„|‚zŒ”•]cd|„…ekd’ŒŒœ¤¦UTSultJHFVTLkd\Œ‹“‚v{sleƒƒ|tt{tll{{tttsƒ}ƒlek{{tlks]bZ¤¤F=C*)(lld|‚z‹’Š‹‹„£››“Œ”£œ¥š””µ¶·š””””‹’ŒŒ¦§¨‘…„¦§¨|„…tsl””‹””‹’ŒŒ‰ƒv£››tllŒ‹“Š~‹rfk„„Š’ŒŒ{{ƒtts{||”“›ttstllƒ||ƒ„„”š”Œ‹“‹‹„sre‹„‹mttu{{fkk|„…uzt{ttuztmttƒ}ƒ{||‹„‹|„…|‚z‹’ŠŒ‹“{||uztƒ||‘…„š””tts“Œ”ƒ}ƒtt{f]cJHFfkk{||ddc{ttš””ƒ}ƒult‹„‹¨©´‘Œ…ult“Œ”|‚zddcsleƒ„„„„Šƒ„„…‹’Š}ƒ„„ŠlrillkŒ”•”››ƒƒ|£››’…‹£››‹’Š›”›sleƒ||tllƒƒ|‹’Š“Œ”{{ƒƒ||‹„‹šŒlrilks“““¦§¨“Œ”‚|u{||…‹’ƒ„„ƒ||{u{tll‹„‹|‚ztt{”š”¨©´ƒ„„Œ‹“¦§¨š””Œ”•“Œ”œ››‚v‚””‹[[T‚|uš””™š¤‹‹‹™š¤›¢›’ŒŒ|„…ztl‚|u‚wl‹„‹‹’ŠzllsleuztŠut{u{yfdllklld‹‹‹¦§¨{||‹…’{u{cbVƒ}ƒƒ„„”››¤¤ƒ||Œ”•‹’Š‹‹‹””‹‹‹‹’ŒŒttszllb[U‹’ŠŠƒ}’ŒŒtts“Œ”rg]ult“Œ”UMRrfk[TT{||ttslldllkJHFedk{zm]bZredƒ||„Š„cbVlkslksŠ}|ultrfk…‹’ulttts|„…ultƒ„„¦§¨››”ŒŒš[TTztlVTL{{ƒƒƒ|ult[[T‹‹„{zmfkklrilekJHFdc\tsl‰‘~Œ”•lddlldlriƒƒ|{{t‹‹‹“Œ”ztlSKJƒ||mttiWUd\\lritzl„Š}ldd{||ƒ„„“Œ”tzl‹’Šfkk²««LKR*)(u{{”›››¢›£››ƒ||‹„„“Œ””“›²²¬¦§¨²««‹„„‘…„ƒƒ|‹‹„””‹›¢›””‹£››¤¤¦§¨“Œ”‚v{£››£œ¥‹„‹Œ‹“”››‹’Š‹„‹™š¤¦§¨””‹|‚z{|||‚z…‹‹ƒ}ƒ{||²««‹‹‹¨©´™š¤…‹‹››”‹‹„{||‹’Šlks„„ŠlddlrilriŒ”•„Š„{{ƒ‹„„ƒƒ|‚|uƒ||ztlŒ‹““““{||„„Š„„Š‚|uJHFƒƒ|rfk{tt“Œ”{{ƒkd\‹„‹lek’…‹š””lks”››f]cmtt‹‹‹bVUƒ„„ult[TTtts]bZdc\tsl”“›››”‹„„‚v{ztlttsekdƒ||‹„„”š”ƒ‚u‹‹„‹„‹ddc\UZsle‹„„‹‹„”š”{ttu{{‹’Štts„„Š…‹‹‘Œ…š””|‚z{tt²««|‚z{u{ƒ„„™š¤™š¤ttsœ››‹‹‹…‹‹ƒ||‹‹„™š¤‹„„\UZztl‚wlƒƒ|‹‹‹„„Š¦§¨™š¤mw””‹ƒƒ|‚|urfkœ››‘Œ…š…Ž””‹Š}|“Œ”f]cult‹‹„slešŒƒ‚u{{ƒƒ„„””‹ƒ}Š{{ƒ£››¦§¨uzt\[[ƒ„„{||››”‹…’‚utƒ}ƒŠ}ƒzllztfVTL‹‹„”››lekddcŠ}ƒ‹„„lddultkd\mtt…„’š””ekd]bZƒ||SKJuzt\UZ„Š„ƒ„„dc\kk]{||zll‹‹‹‚v{Œ‹“‹…’£œ¥|„…tts{{t{{t““““Œ”UTSdc\tt{JHF]cdddcjcVlriyflu{{›¢›Œ‹“{{ƒ[[Tmtt|‚z™š¤lri“Œ”|‚zlks{{tmttVTLredcbV“Œ”lksdc\ttsƒ„„uzt‹’Šƒ||tsl{||ddcfkk]bZ‹’Š››”JHF*)(|„…‹’Š|‚z‚|u””‹Š}|‹‹‹“““š””²²¬›¢›Œ”•Š~‹Š}ƒ“““””‹››”“Œ”š””sre›”›²««›”›“Œ”¨©´£œ¥›”›£››¨©´¦§¨Œ‹“Œ”•„Š}„„Š„„Š…‹’|‚z|„…tslƒ„„ƒ||tt{™š¤œ¤¦¨©´‹’Š|„…u{{mttlekulttsl„Š„tts{||Œ‹“Œ‹“lldslelldultŒ‹“™š¤f]c‹’Šƒ}ƒfkktt{…‹‹f]c‹„‹{{tlritll|„…ldd‹’Šult“““…‹‹ultttslldƒ}ƒ{u{{zmtllultekd›”›ƒƒ|’ŒŒŒ‹“£œ¥‘Œ…{zmƒ„„‚|uultult‹‹„‹‹„£››|„…ttsddc‘Œ…’…‹{{tedkred¦§¨{{ƒƒ„„ƒ}ƒ…‹‹ttsƒ}ƒ¦§¨œ¤¦£œ¥‹‹„“Œ”|„…llkŒ‹“{{ƒ…‹‹£››ƒ}ƒ‹„„‹„„{||ult‹‹‹‹„„“Œ”ƒ„„››”‹„‹ª³·£²š””™š¤‚|u‚|usle„Š„¤¤Šƒ}‹„„sle£œ¥yfl[TT{||‘Œ…ddc{||”››„Š„lri“Œ”¤¤””‹’ŒŒ{tttslŒ‹“‹‹„œ››“““lks“Œ”£››i\V‚|u{u{{tttll{u{‰Š¡{{ƒ‹„‹rg]tllƒ}ƒ‚v{ttsred“““tslztltslVZT\[[ekdu{{ek]ultbVZf]clekƒƒ|ldduztƒ}ƒŒ‹“rfk‹„‹¤¤‹‹‹lksu{{ult|‚z|„…›¢›{||lld[TTf]clriƒƒ|{||]bZddcllduzt”››|„…lld‹’Šuztƒ}ƒbVUtlltlltll‹‹‹ƒ‚u‰ƒv|‚zfkktzltslllkllklek\[b|‚zVTLsle¤¤\[b:97]bZrr]œ››””‹œ››‚ut£œ¥²««¦§¨²²¬¦§¨¦§¨«²«¦§¨‹’Šµ¶·“Œ”œ››«²«‘Œ…²¬µ¨©´„„Šƒ}Š“Œ”Œ”•‹„„œ¤¦Œ”•œ¤¦£œ¥“““ztlƒƒ|\[[{tt|„…kd\lld{{t’…‹ultu{{tt{ultu{{lksmttedk{{ƒƒ||{||„„Štll|‚zf]cƒ„„ƒ||kd\”š”tlllldlldƒ}ƒ“““llkƒ||{{ƒ|‚zultedkekd{u{ƒ||JHFtll”››„Š„UTSmttultuzt\UZŒ‹“Š}ƒ|‚zd\\ultŒ”•]bZ”š”d\\””‹tts{zm’ŒŒtts¤¤š””š””ƒƒ|””‹ƒ||[TT…‹‹ƒƒ|””‹’…‹ƒƒ|ƒ„„lldƒ|||‚z|‚z{{ƒ|‚zƒ||“““œ¤¦“Œ”™š¤“Œ”u{{dc\{u{‹„‹llkƒ}ƒƒ}ƒ™š¤ƒƒ|›”›¦§¨šŒƒ||‚v{›”›ƒ||ƒ||ƒ||lksƒ}ƒ””‹{tt‹„„’ŒŒ”š”‹’Š‘Œ…šŒ‚|uult‹‹‹ultleklek„„ŠŠƒ}””‹‹‹„‹‹„¦§¨Œ”•’ŒŒƒ||‚ut‹‹‹‚ut””‹fkk‹‹„ddcŠŠ}‚wlj]\{yfj]\f]c‚|uekdllk‚v{ultd\\i\V[TT‚v{‚v{tts‚ut™š¤ek]lddƒ||\[[ult{{ttllfkk|„…f]c‹„„‹„„”š”™š¤„Š„””‹uztldd{u{uztŠ}ƒŒ”•u{{””‹|„…UTS…‹‹„Š„‹„„ƒ„„ult{{t”š”„„Š]cd“““VZ[„Š}›¢›uztJHFMRK{{t|‚zSKJ\UZlld„„Šƒ}Š{{ƒllduztƒ„„„Š„llk“““tllƒƒ|JHFJHFVTLllk¦§¨\[[&&ek]{||Œ”•¤¤Š}|™š¤¦§¨²««£œ¥‹‹‹£››‹‹‹¦§¨›¢›¤¤””‹“““””‹‹’Šƒ||¦§¨¨©´›”›‹„‹¨©´{{ƒ››”“““’ŒŒ‹’Š™š¤“““”š”Œ”•ldd„Š„ƒ„„|„…|‚zŠŠ}{||ƒ}ƒ|„…lriultlksmtt„Š„lriUMR{{ƒsle{{ƒŒ”•lriultŠ}ƒ››”bVZtslfkkƒ}ƒ‹‹‹{u{ddc{tt]cdUTS|„…mw’ŒŒ{||d\\ƒƒ|dc\“Œ”llk£œ¥{||lriƒ||{ttu{{ultlddŠŠ}{ttUTS…‹‹VTL…‹‹rfk„Š„{u{sle››”lritll››”ztllld”š”š””{||ƒ}ƒddc”››{ttƒƒ|tts‰v|b[U„„ŠŒ”•uzt‹‹„|„……‹‹”“›’ŒŒ“Œ”„„Š…‹‹…‹’“Œ”{||…„’œ››‹‹‹“““sle’ŒŒ{{tttsult¨©´™š¤tsl’ŒŒtllultred‚|ulddVTLcbVœ›››¢›Šƒ}ƒ||’…‹’…‹Œ”•ldd‹„‹ƒ||Š}ƒ‚v‚‹‹„Š}|ƒƒ|””‹‹‹„¦§¨¤¤››”ttsttsœ››ddctsl‹‹‹‘Œ…lek‹‹„””‹SKJd\\{{t\[[dc\ƒ}Š‹„‹ult”š”…‹’{||¦§¨llkƒ||‹’Šœ¤¦‚v{‹„„{u{mttlldƒ„„f]cbVZ‹„‹f]cŠ}ƒddcttslekŠ}ƒ\UZ‚v‚›”›‚|uultredUUY{zmmtt«²«|‚z›”›{{tultƒ||ƒ||„Š„~’“lrilriŒ”•™š¤tsltsl|‚z|‚zf]cu{{{tttllƒ„„£œ¥llklddekd|‚ztzlƒƒ|ztlƒ}ƒ\UZlek\[[VTLslemtt¤¤MRK%&‹‹‹tsl–¢‹››”lldƒ„„{tt’ŒŒ‹’Š¦§¨¦§¨“““””‹šŒ¦§¨””‹µ¶·œ››””‹¤¤œ¤¦›”›¨©´”“›„„Š¦§¨ƒ||ƒ„„Œ‹“ult‹’Š””‹¦§¨œ¤¦š””‹„„uztuzt|‚zƒƒ|›”›‹‹‹UTS|„…{{ƒ|„…[[T\[[]cdlekd\\{ttlek“Œ”lrif]cldd{{ƒŠƒ}sleƒ}ƒ’ŒŒ‹’Š‹„‹mttSKJllklldsleƒ„„{ttddc{ttj]\llk‹„„lritlluzt|„…‹‹‹lld™š¤ƒƒ|™š¤Šƒ}{ttbVU]cdVZTlld’ŒŒ‹‹„ult””‹””‹’ŒŒ£››slef]cdc\ztl‹„„ŒŒšŒ”•ƒ||œ››‹‹„”š”{||ƒ||‹’Šmtt››”…‹‹ƒ„„›”›Œ”•„Š„ƒ„„tsl”››œ¤¦mtt{{ƒtlltt{ƒƒ|tll{{ƒsleztl„„Š¤¤{u{ƒ||›”›‚|ukk]‚v{dc\™š¤¦§¨‰v|f]cŒ‹“™š¤ŠŠ}‰|v””‹”“›’ŒŒŒ”•ƒ}ƒf]c‹…’“Œ”Š}ƒƒ||‚|u„„Š‹‹‹¦§¨kd\ƒ||kd\””‹ƒ}ƒ\[[ztlsre“““{tt{{t{||sre[[Tlddkk]””‹{||bVZ{{t{{tzll”š”f]c’ŒŒlek‹„„¦§¨¦§¨“““{tttsltt{ztl‹‹‹‹„„lek“Œ”ultŠ}ƒ{{tf]c’…‹‚|uddc›”›{{ƒj]\{u{f]c\[b™š¤Œ—£…‹‹|‚zlekƒƒ|mttlek„Š„ƒ„„œ¤¦]cdtts|‚zƒ}ƒ[[T{tt„Š„lddlld„Š„lldƒ}ƒ‹‹„ekd\[[dc\lri”››‹‹„ƒ„„u{{{u{ƒ}ƒllkmttf]clddddc››”MRK*)(VZTmttztl””‹™š¤™š¤””‹’ŒŒ””‹‚|uŠ}|‹’Š””‹””‹‹‹„¦§¨š””¦§¨›¢›Šƒ}‹…’¨©´›”›„„Š“““›¢›“““™š¤{{t‹’Š”››¦§¨¦§¨œ››£œ¥›¢›“““‹’Š|‚z“““ƒ„„lek‹’Š…‹‹llkƒ„„tsl|‚z…‹‹ƒ}Š[TTd\\{{ƒ{u{ƒ„„ƒ}Šf]cttstsl‹„„Œ‹“’ŒŒ‹‹„{tttslmttJHFlld‹„‹ƒ„„[[T{{ƒllkj]\VTLƒ||“Œ”“Œ”ldd|‚z{ttllkult¤¤’…‹|‚z‹„„{||ƒ„„MRKƒ‚utll””‹‹„„››”‰|vƒƒ|j]\‹„„ƒ}ƒlldsle‘Œ…ultttsƒ}ƒ””‹ƒƒ|œ¤¦”š”Šƒ}|‚zš””ƒ„„›”›‹‹‹ƒ„„Œ‹“…‹‹‹‹„ƒ}ƒƒ}ƒtt{“Œ”™š¤|‚z‹„‹‹‹„œ››ƒ}ƒ{ttƒ}ƒ‚ut‹‹‹rfkb[Utll“Œ”[[TlksbVZ“Œ”Š}|{tt‘Œ…”š”rg]””‹Šƒ}¤¤›¢›ŠŠ}ult‹„‹tt{tts‹„‹‹„‹‘ˆ}ŠŠ}£››‘…„lksrfkƒƒ|j]\{{tllkllk‹‹„‹‹‹ƒ}ƒ‚ut{u{lri„Š„Šƒ}ddckk]ƒƒ|{u{ttstll|„…lek‹‹‹b[U{tttts{zmuzt“Œ”‹„‹{tt“““uztztl”››lddƒ}Š{{ƒƒ}ƒ£œ¥¦§¨ƒ}ƒƒƒ|tsl[[Tƒ||ƒ}ƒtll“Œ”‹’Šyl„\UZ|„…œ§²„„Šƒ}ƒ[TT„„ŠVZTtlllri|„……„’‹’Štllztlrfkultd\\ult|‚zŒ”•ƒ‚u{tt{{t{{tlldŒ‹“{||]bZtzl‹‹‹‹’Š””‹{{ƒlekmttlldztl‹‹‹¦§¨dc\>EC‹’Š„Š„››”“““’ŒŒ“Œ”ttsœ››“““¤¤“““{u{Š}|‘Œ…£›››”›š””ƒ„„›¢›››”™š¤¦§¨“Œ”¦§¨Œ‹“ƒƒ|¦§¨¦§¨‹‹‹|‚z“Œ”{{ƒ|‚z‹’Š””‹‹„‹”››‹’Šuzt“Œ”ƒ}ƒSKJ|„…]bZVTLkd\lld]cd\[blek{u{{tt{{ƒ‹‹‹ekdlldult‘…„‘Œ…””‹{||Œ‹“›”›{tt{{t{ttSKJlld|„…™š¤‹‹„‹„‹„Š„£››lri‹„‹uzt|„…‹‹„‹‹‹{ttƒ||u{{u{{{{ƒ|„…“Œ”ulttt{lri›¢›‹„„››”‹‹‹²««‘Œ…”“›ƒƒ|zllttstts„Š„œ¤¦tt{…‹‹kk]‹‹‹¤¤£œ¥‹’Š‚utŒ”•Š}ƒ„Š„”››Œ”•”“›{u{…‹‹tllttsƒ}ƒ…‹‹™š¤™š¤„Š„tts„Š}œ¤¦‚v{‚|u…‹‹mtt“Œ”ldd[[Tlldsleztlult¨©´“Œ”’ŒŒ£œ¥llkƒƒ|lddš””ztlŒ‹“{{tœ››““““““mtt{tt{u{›”›‹‹„zll‚utš””„Š}››”{{tƒ||››”‘ˆ}ƒ||tsl››”{||‹‹‹sle‹‹‹“““[[T‹„„lldlriŒ”•{{ƒ‹‹‹{{ƒtt{{u{lks‹„„uzt{||sled\\SKJƒ„„[[Tuzt””‹{||ƒƒ|ƒ}ƒš”””“›{u{ƒ„„‹„„‹‹„‹’Š|„…’ŒŒ“Œ”tsl‹„‹|‚z{||ƒ|||„…lks]bZmttslemttedktsl¦§¨mttldd{{t”“›{||ultttsj]\„„Šllk‹‹‹lld{ttƒ}Šlek{{ƒŒ‹“tts‹‹„tll[[TmttŠ}ƒlek„Š„{||{{tlldlld²¬µ]cd-1+tsl‹„„››”ƒƒ|{||··Ä¤¤£››‹‹‹”š”¦§¨ult²¬µ£œ¥ƒƒ|¤¤¦§¨¤¤ƒƒ|Œ”•š””Œ‹“¨©´’ŒŒª³·œ››µ¶·œ››š””¤¤”“›››””š”|‚z…‹’ƒ}ƒƒ}ƒ‹‹„œ¤¦ƒƒ|‹„„lddu{{uztllkŒ‹“”››tt{Œ—£‹‹‹lek{u{…‹š‹„‹‹‹‹ƒƒ|ztl››”ƒ‚u‹‹„{||{||ƒ}ƒ„Š}Šƒ}kd\‹„‹lld‹‹‹…‹‹„Š„{||u{{£››…‹’zll¦§¨lkstzlmtt‘…„‹„„š””tts“Œ”{||ldd{||…‹‹mtt|‚zƒƒ|œ››”“›ŠŠ}ŠŠ}ddcœ››‹‹„’…‹{zm|‚z“““{ttlriddcŠƒ}‹‹„Œ”•™š¤Šƒ}‹’Š›”›‹‹‹ƒ„„tt{{{ƒŒ‹“„„Š“Œ”{{ƒ¦§¨{{ƒ’ŒŒ‹„‹”š”tllttsfkktsl‹‹„…‹‹{||“““{ttƒ„„{u{d\\SKJu{{rfk‚v{™š¤Œ‹“‹‹„””‹zll{{tƒƒ|ƒƒ|{{tƒ‚u{||Œ‹“tts‹„„‹…’kd\tsl‹‹‹¦§¨ƒ||lek‚utƒƒ|ƒ„„‹‹‹””‹u{{ƒ„„ztl”š”””‹’ŒŒ‹’Š‹‹„sre{||]bZtsl{||tlluztuztsle{ttedkzll|‚ztsltllj]\zllslelld‹‹„Œ”•ƒƒ|’ŒŒ{ttƒ||tsldc\tsltt{lrikd\slered{u{lddddc‚|u\[bllk…‹‹mtt¦§¨SKJtsl„„Š…‹’lrib[Uedk{{ƒœ››ƒ„„ultedkƒ}ƒ|‚ztll”š”Šƒ}‹‹‹zll\UZllktt{ttslksmtttt{[[T„„Šultlri{{t„„Šlrisle\[b¦§¨LKR%&£››Œ”•£œ¥£œ¥™š¤£²£››¦§¨””‹„Š„‹‹‹ƒ}ƒ£››››”¦§¨››”¤¤{||ƒ„„‹’Šœ¤¦¤¤··Ä¦§¨¦§¨‹’Š£››…‹’ƒƒ|{{ƒ{tt„Š}{{ƒ{{tŒ”•”š”|„…Œ‹“Œ‹“‚|u››”tll…‹’|‚zVTLlddmttmtt…‹‹lks¦§¨ttsultŒ”•|‚z‹‹‹\[[¦§¨ztl‹‹‹d\\””‹tll‹‹„’ŒŒlld™š¤“““™š¤{{ƒtsl{{ƒsleŒ”•œ››™š¤“Œ”‹…’|„…lldƒ||{tt„„ŠUTSlek„Š„{zm{{ƒLKRekd„Š„‚|ukk]‹‹‹¤¤””‹Œ”•|‚zœ››{ttttsƒ‚u’ŒŒ‹„‹uztƒ}ƒƒ||””‹{{t{||‚|uƒƒ|šŒfkk””‹ƒ„„tts{||„„Š{||Œ‹“„Š„|‚z£››{||ttsu{{Œ”•lddlddd\\‘Œ…ttsŠ~‹™š¤[[T„Š„tsl‹„‹ƒ||’ŒŒŠ}ƒƒ}Š‹’ŠŠƒ}‚|u’ŒŒ{{t\[[¦§¨j]\lriSKJ£œ¥„„Š“““Šƒ}ƒ„„ƒ||Š}||‚ztzlƒ„„Šƒ}’ŒŒ‹‹„{ttŠƒ}lddƒƒ|{{tƒ„„”››tll{||¤¤lddrg]{u{”››lrilri\[[|„…„„Š‹„‹mtt{{t|‚z{{tVTLbVZztl“Œ”{{ttsldc\]bZllk‹„‹ƒƒ|ttsldd‹‹„™š¤{u{ƒƒ|tt{‹u…‹…’‚|u„„Š{||Œ”•[[TŒ”•œ§²{{ƒ\[b¦§¨Œ”•tt{‹’Šb[Umtt{{ƒ{ttrfk’…‹{u{UTSlritlltts”››ƒ}ƒult‹‹„{||ddclri‹„‹{||…‹’tsl|„…b[Utts‹„‹llk‹„‹[TT\[[¦§¨ek]FD;Œ”•””‹¦§¨œ¤¦ƒ}ƒ¨©´‹„„¦§¨µ¶·¦§¨¤¤’‘~£œ¥¦§¨¦§¨²²¬‹’Š“““ª³·œ¤¦™š¤‘…„œ¤¦Œ”•|„…‹‹„š””„Š„™š¤¨©´‹„‹”“›¦§¨““““Œ”››”{{t”“›‹„„ƒ||{tt’ŒŒ|„…lri{u{llklri“““\[[{{ƒ{||{u{dc\›”›‹’Š“Œ”””‹£››{tttslƒ„„zllƒ||{tt£œ¥Šƒ}ƒ}ƒ‹‹‹Œ”•‹„‹ƒ||‘…„sre‚utƒ„„›”›{||ddcƒ}Š…‹‹tts“Œ”›”›‹’Š„„Šƒ„„’ŒŒ‹„„Œ”•lrikk]š””llkllkš””‹„„lld{{t‘…„UMRttstslŒ”•ultŒ”•››”››”››”uzt„„Š¤¤„Š}”š”{ttƒ„„ult‹‹‹”“›‹‹„lekekdlriddcu{{ƒ}ƒlldtt{uzttts{{t|„…ƒ}ƒldd‹„„ult›¢›Š~‹|‚zŠ}ƒSKJ{u{‚v{sre‹„„ƒƒ|ztlŠƒ}””‹ƒƒ|ƒƒ|ƒ||mttllk„„Š„Š}{tt‚v{ƒ„„Šƒ}ldd‹…’\[[’ŒŒ’ŒŒ¨©´””‹”š”‹‹„lldjcV‘ˆ}]bZkk]bVZ{ttƒ„„„Š}ƒ‚u{zm‹’ŠVTL‹‹„\[[|„…\[[f]clddekdƒƒ|sle{tt’ŒŒ‚utf]cVTLƒƒ|UTS“““œ¤¦‹‹‹’ŒŒ]bZztluztlri””‹dc\Œ”•’ŒŒƒ}ƒrfk\UZ“““|‚z„„ŠŒ”•|„…u{{{{ƒttsƒ}ƒ¦§¨¦§¨‹‹„u{{„Š„“Œ”Œ‹“¦§¨tt{u{{|‚zŠ}|lri”“›lddf]cVZT”“›{||UTS“Œ”ttsVTLtslŠ~‹‹„‹dc\ultu{{ultŒ‹“llk¨©´UTS)+2››”ƒ||ƒ„„ƒ„„š””¨©´¦§¨«²«›¢›™‹†››”‹„‹’ŒŒ””‹“““‹‹„™š¤››”ƒƒ|”›››”›”š”œ›››¢›“““™š¤”“›¦§¨Œ”•¨©´”››Œ‹““““”››””‹z‚l¦§¨œ››…„’{{tƒƒ|ƒƒ||‚z{{ƒ“““ƒ„„ddc{||lksƒ}Š‹…’ƒ„„“Œ”‹’Šuzt{{t„Š}œ››“Œ”‹„„{u{{u{‚utlddf]ctllztlƒ‚uVTLultƒƒ|d\\Œ‹“ultVTLƒ}ƒ{{ƒllkllk{tt‘…„£œ¥Œ”•‹‹„{u{u{{Œ”•‹‹‹‹‹‹‹‹„„Š„ztlŒ”•tts¦§¨š””“““‹’Škd\‹„‹JHFlriƒƒ|tll‹’Š¦§¨›”›””‹¤¤Œ”•ƒƒ|ƒ||¦§¨œ››lldƒƒ|tll‹’Šsle“““Œ‹“|„…“““…‹’‹„‹ztl\[[””‹ƒ}Šš””{||Œ‹“‹‹„tt{ƒƒ|”š”‹…’|„…zll{{tŒ‹“ƒ}ƒllkƒ„„‹„‹ƒ„„dc\‹‹„yleƒ‚u’ŒŒ‹„‹tllttsƒ}ƒ{tt„Š}uzt¤¤Šƒ}{tt{u{“Œ”ttsdc\{||””‹{{tllk‹‹„ztlztflddœ››lrillkddc‹’Šek]|‚zdc\|‚zdc\lddUTSf]clekred…‹‹¤¤[[T{{ƒ“Œ”‚|u{{t„Š}”››„Š„edkŠ}|’ŒŒ„Š„Œ‹“››”œ¤¦‹…šsre”››tt{{u{‹’Šlrimttuztddcekd”“›uzt””‹]bZ™š¤edk|‚ziq]lks{||sletll‚utultµ¶·{||uztu{{ƒ„„dc\tts‹„‹{{ƒŒ”•dc\‹…’tts\[[|‚zddc{ttuzt‹„‹ƒ}ƒ{u{”š”tll¦§¨\[bLKR|‚z…‹‹ª³·Œ‹“’ŒŒ“Œ”››”ƒ‚u–¢‹„Š}¦§¨‰ƒv’ŒŒ‹‹„¤¤|„…¦§¨››”ƒ||‹‹‹”››’ŒŒ£››‹’Š¨©´£œ¥··Äœ¤¦‹…’¨©´¦§¨¦§¨„„Šª³·š””¤¤¤¤œ¤¦ƒ„„ƒ||š””ƒ||fkkƒ„„{{ƒ‹„‹{||””‹{{ƒ£œ¥“Œ”ƒ}ƒult{u{tslŒ‹“tt{””‹Š}ƒ››”‹„‹tslldd‘Œ…¦§¨’ŒŒdc\rg]llk{ttlldsle‚ut‘…„”››ultŠŠ}llk{||d\\“Œ”‚|u‹‹„›¢›™š¤Œ”•|„…{{ƒllkdc\]bZ‹„„ttslek‚|u‘Œ…ldd«²«Œ‹“{u{ƒ}ƒcbV”š”ƒ„„{||””‹’ŒŒ¤¤‹‹‹š””{ttƒ‚u¦§¨„Š„‹’Š¨©´{ttŒ”•‹‹‹‹„„£œ¥”“›‹‹‹{||{{ƒ‹‹‹…‹‹ƒƒ|‹‹‹|‚z{u{…‹‹ttsult{||fkk\[[Œ‹“u{{‹‹„Œ”•{u{{ttƒƒ|“Œ”{tt{zm{tt‹‹„‚|u””‹ƒƒ|ldd\UZ‹’Š“Œ”‹’Š“““sle’ŒŒd\\kd\{tt{{tlldmtt]bZekdttsƒ„„šŒƒ}ƒbVZŠ}ƒ…‹‹llklldkd\SKJddc{u{ztlllktzlb[U{u{{tt{{tu{{lriƒ||r]g¦§¨ƒ||¦§¨”š”…‹‹ƒ‚u‹‹‹›”›cbV””‹‹„‹|‚z„„Š‹’Š›¢›œ¤¦‹„„ƒ}ƒ””‹„Š„‹’Š|„…|‚zekdœ§²|‚z|‚z‹‹‹mttuztƒ||d\\UMR›¢›‹’Šƒ||lksf]c››””››{{t›¢›]bZŒ”•‚|u“Œ”uztmtt[[Tttslri|‚zdc\JHFƒ}ƒtllƒ}ƒ[TT{ttultd\\¦§¨MSSLKRœ¤¦›”›”“›£œ¥‚v{ƒ||’…‹””‹¦§¨¦§¨¤¤²¬µ“Œ”¦§¨ƒƒ|“““tzlª³·‹’Š¨©´‹’Š£œ¥Ÿ±¯¦§¨¦§¨”“›…‹‹¦§¨£œ¥””‹™š¤…‹‹ƒ„„“““‹‹‹™š¤””‹’ŒŒ…‹‹‹…’edk‘Œ…\[bŒ”•ƒ}Šµ¶·lks™š¤œ¤¦„„Š‹„‹‹…’ƒ||œ¤¦ƒ||Œ‹“llkztl’ŒŒ|‚z„Š„{{t“Œ”ƒ||’…‹lld‚|u’ŒŒtsl{||…‹‹Šƒ}‹„„sleu{{’ŒŒ‹‹„|‚z\[[ttsƒ‚u“Œ”ƒ}ƒekd‹‹‹llkœ¤¦tt{ddctzltsljcVƒ||¤¤œ››‘Œ……„’‹‹„‘…„‹‹‹{||›¢›|‚z“““‹’Š‹„„zllŠ}|ƒƒ|{tt’…‹‹’ŠŒ‹“u{{“““‹‹‹zll’ŒŒƒ„„{{tŒ‹“„Š„‹„„”“›ƒ||{tt”“›ƒƒ|tt{tsltts›¢›tllŒ‹“tt{tt{\[[“““ultllkƒ}ƒlks¤¤„Š„‹u…{{tƒƒ|››”Œ‹““Œ”ƒ}ƒtts{u{ƒ||ttsœ››””‹”“›‘Œ…ƒ||Š}|{ttsle{tt[TTkd\tsl{u{ƒ„„{{tŒ‹“kd\””‹{u{‚v{JHFŠ}|ztllri‹‹„{ttultbVUdc\{u{lekŠƒ}ttstts‚utƒƒ|ƒƒ|{{ƒ‚ut«²«›¢›„Š„{||„„Š‹„„‹‹‹ztlƒ„„|‚z£œ¥‹’Š¦§¨Œ”•sleƒ„„š””|„…tzlŒ—£…‹‹Œ”•|„…]bZ|„…]bZu{{\[buztJHF\[b{tt]bZyle\UZŒ‹“{||tllredVZTek]fkklddlekedk|„…ttsu{{]bZ]bZ|‚z‚v{ultƒ„„‹‹‹ƒƒ|ƒ||sle\[b¦§¨MRKUTS|„…cbVƒ„„£œ¥“~ˆ‹„„””‹Š}ƒ|‚zƒ‚n’ŒŒš””sle|„…{||“““¦§¨›¢›¦§¨¨©´£›››¢›«²«lld‹‹‹«²«œ¤¦”“›“““œ››Œ”•¡¡’ŒŒª³·”“›llk‹‹„lri‹’Š‚|u{||‚|u{{ƒŒ”•ult‹‹‹{{ƒƒ}Š{{ƒlkslldd\\‚utƒ}ƒƒ}ƒztl‹‹„‚ut‚v{‹‹„lek‚|ured’…‹{u{{u{{ttŠƒ}lddldddc\sle‘…„›”›‹„„ƒƒ|¦§¨|‚z\[[{||‹„„ult‹‹‹{u{\UZllkƒ„„f]cf]ctzlsreSKJƒƒ|tzl[TT‚ut‹…’sle‚|u“Œ”[[Tƒ‚u””‹”“›™š¤››”›”›¦§¨¦§¨{||‘…„tsltsltsluzttts’…‹ƒ}Šš””š””„„ŠŒ”•‚|uƒ}ƒ›”›uzt™š¤š””ƒ„„ldd‹’Š{{tlddŒ”•ƒƒ|ƒƒ|ztlƒ}ƒf]cuztultœ›››”›Œ‹“””‹‚|u|‚ztslœ¤¦ƒ„„ŠŠ}¦§¨ult“Œ”””‹”››ƒ„„”››’ŒŒ‘…„ƒ}ƒŠ}|ult{||d\\“Œ”Šƒ}ultƒƒ|{{tƒƒ|‚|u‘…„yle{||‚|usle{{t¤¤ƒƒ|ƒƒ|tsllldFD;uztllktzllld\[[lldƒ}Šdc\bVZSKJtzlztl‹’Šlriultztl“““kd\””‹¦§¨›”›ª³·{{tkk]ztlŒ”•tsl…‹‹uzt„Š„u{{mtt‚v{u{{{||lksddcllkMSSlldult‹…š„Š}{{tUMRf]clektll”š”{{tlld{||u{{„„Štll\[[dc\]cd]bZlri‹’Š‹„‹„„Š‚utultŠƒ}Š~‹UMRf]c£››JHF?;C„Š„„„Š“Œ”£››‹„‹ƒƒ|‹‹„’ŒŒŠŠ}””‹Šƒ}Œ”•¸Á¹¦§¨¦§¨›¢›”š”¦§¨œ¤¦œ¤¦¦§¨‹„„œ¤¦‹’Š‹uŠƒ„„…‹‹“““¨©´¦§¨Œ”•…‹’Œ‹““Œ”ŠŠ}’ŒŒœ››|‚ztsl‹„‹£œ¥‹„„uztUUY¦§¨Š}ƒlksultlksmtt…‹’ƒƒ|ƒ||œ¤¦{u{ƒ}ƒ{{tƒ||“Œ”|‚z”››“““‹„‹‹„‹‹‹‹Šƒ}ldd†~‘{u{™š¤‹‹‹“Œ”””‹cbV{{tƒ‚uƒ‚u{zm‹„„j]\‹’Šƒ||¦§¨ttstts|‚ztllf]cƒ}ƒƒƒ|lrilriƒ‚ulri„Š„{tt{||zll‚ut‹„‹““““““ƒƒ|›”›™š¤’ŒŒ‘…„¦§¨ƒ||””‹ƒ|||‚z{u{{{ƒ”š”ult‹„„’ŒŒƒ„„tll„„Š‹’Š’ŒŒ{u{’ŒŒu{{“Œ”ƒ„„tsl{{t…‹‹ƒƒ|ƒ„„tllf]cƒ„„”“›“““{{ƒƒ||{tt{{ƒzll\[[ƒ||‹„„{||ƒ‚uu{{b[Usle‘…„jV[‚|u‹‹‹ƒ„„””‹ƒ„„ztlŠƒ}œ¤¦š””tts““““Œ”Œ”•‚v{ƒ}ƒj]\‰|v‘…„””‹¤¤‘…„{tt{tt‹‹‹[TT‚|u£œ¥Š}|ylett{sreƒ||tll‹‹‹‘Œ…lddiq]{u{‹…’|„…ƒ||kd\{{ttsl„„Šf]ctll{u{b[Ulksztl|„…™š¤uzt{{t‹„‹mtt{||\[b|„…lks…‹‹UTS“Œ”{||\[[|„…lkssle\[bllk\[bUMRttsuzt\[b{{ƒlekdc\tt{ƒ‚u‹‹„\[[{{tƒƒ|[[T”š”{{t|„…{{tultlddƒ}ƒtll™š¤”“›››”lddbVZldd¦§¨\UZJHFlks|„…‹„‹£œ¥™š¤‚|uŠƒ}”š”””‹””‹””‹«²«¤¤¤¤””‹œ¤¦¦§¨‹’Š¨©´«²«µ¶·›¢›{{t””‹¨©´œ¤¦Œ”•”››Œ”•’ŒŒ‹‹‹Œ‹“™š¤¦§¨|‚zœ¤¦‚|u‹’Š„Š„yleult¦§¨]cd{{tlekultŒ‹“edklksu{{|„…”š”dc\„„Šlek”“›{||¤¤‹„‹{{tlri{ttŒ‹“’ŒŒ¨©´ultlddUTS¦§¨ƒƒ|ƒ„„ƒ||”››sleddc\[[lriƒƒ|lek[[T{tttll‚|u„Š„ƒ„„|„…uztJHFlkscbV|‚zllk””‹|‚z„Š}””‹””‹Š}|kd\ƒ„„Œ”•|‚z‹‹„tll„Š}‹„‹›”›²««“Œ”¤¤tll„Š}Œ‹“š””‹’Š{{ƒ‹‹„ƒ||{tt“““’ŒŒƒƒ|“Œ”’…‹‹„‹ddcult“““‹„„””‹‹’Š„„Štll[TT“Œ”„Š„{u{ƒ„„ƒ}ƒœ››ƒ}ƒ²²¬’ŒŒ|‚z„Š„ƒ‚n„„Š”š”{||{{t‹‹„lddmwŠ}|‹‹‹|„…“Œ”ƒ„„Šƒ}ylebVZŠ}|œ››ekdƒ}ƒ{ttkd\zll{ttš””‹„„’ŒŒ‹„„‘…„››”’ŒŒ{u{ult“Œ”‘…„[TTƒ}ƒ[TT„Š„lri{u{{ttŠƒ}mtttt{‹‹‹ultllkztlUTS£››tll…‹‹›”›‹„„“Œ”{tt{tt[[Tllkš””\[[››”‹„„ttsLKR[TTtzl\[[SKJmtt|„…mttœ¤¦ddcu{{lekœ¤¦dc\ult’ŒŒ“““‹„„lks{u{ult[[Tœ›››¢›‹’Štzl{{tƒ}ƒfkkfkkƒƒ|{||uztƒ„„uzt{tt{{tŠ}ƒult£›››”›kd\tll£››JHF*)(”››“““‹„„‘…„‹‹„”“››”›””‹|‚zz‚l£››œ››œ››“““›¢›··Ä«²«ª³·¦§¨µ¶·«²«œ››²²¬Œ”•‹’Šœ¤¦£œ¥œ¤¦‹’Š”š”œ¤¦”“›Š}|¦§¨œ¤¦œ¤¦Š}ƒŒ”•‹‹„lldƒ}Šult„„Š””‹Œ‹““Œ”{u{„„Šllk|„…›¢›‘…„“““lri{tt“Œ”””‹‹„„š””””‹“Œ”ƒ||‚ut£››œ››””‹‹„‹ddc„Š„ƒ||„„Š’ŒŒ‹„‹{u{f]c[TTlldcbVŠ}ƒUTSšŒ‹„„’ŒŒƒ‚n[[Tlrikd\{{ƒlri{{t‹‹„lri{zm{tt›¢›ƒƒ|“““zll{{t‹‹‹‹‹‹“““Šƒ}|‚zƒ||ƒ„„‘…„¦§¨’ŒŒ{{t‹…’ƒƒ|œ¤¦Šƒ}””‹”“›‹„„‹„„fkk‚ut“““tslult‹‹‹œ››u{{ƒ}ƒ”š”‹’Šƒ}ƒddcŒ‹“tt{ƒ||lddlddƒ„„{{ƒd\\ult‹‹„‚v{{tt››”lri‚ut|‚z„Š}uztztlzllƒ||tllttsš””¦§¨‹’Šuzt‚|u›”››”›lddztl„„Šttsƒ||lek‚|uttsek]ƒ||Šƒ}“Œ”‘ˆ}£››š””ŠŠ}“““lekƒ||ztlsle‚wl‹„„dc\uztztl{ttuzt„Š„‹’Š„„Š“““‹‹„|‚z¤¤Œ‹“ƒ„„llkldd„„Š“““‹‹„œ››u{{ƒƒ|{{t]bZ{u{SKJUMRmttSKJ]cd]bZ|‚zŒ”•mtt‹’ŠŒ”•lri„„ŠMRKƒ}ƒf]clldJHFdc\UTSd\\mtt|„…tll‹„„‹‹„lriekdlriƒƒ|\[[tlltt{dc\lridc\{u{{{ƒlddlektllƒ}ƒd\\ldd¦§¨JHF$›¢›ƒƒ|”“›’ŒŒ”š”£œ¥™š¤‘Œ…””‹¦§¨””‹¦§¨¦§¨š””¦§¨œ¤¦ª³·¨©´¦§¨µ¶·‹’Šœ››£››‹’ŠŒ”•”››Œ‹“”››œ››lek‹’Š™š¤‹‹‹¦§¨ª³·…‹‹’ŒŒ„Š„tsl{{t£œ¥‹…’\UZUTSƒƒ|{ttlri|„…lri|„…z‚l’ŒŒ””‹„Š„„„Š‹‹‹tll“Œ”‹„„›”›‚utŒ‹“‰ƒv£››Œ”•””‹ƒ„„{||tts‹„‹sle¦§¨ƒ„„bVU‹’Šldd|‚zdc\ƒƒ|j]\dc\redzlluzt”š”ttsJHFlek{{ƒsretsl{||Œ”•œ››››”{zm{||Šƒ}sleultƒƒ|uztŠŠ}tts”››ƒ||ult¤¤œ››tzl{||‹’Š”š”„Š„”š””š”‹‹‹››”tt{ƒƒ|lri…‹‹‚v{{u{ƒ|||‚zmtt‹„„ult‹…’ek]š””{u{tts‹‹„“Œ”zll’ŒŒ“Œ”‚v{‹‹‹lekƒ‚utslcbV|‚zuztkd\ƒ„„„Š}zll’ŒŒ£œ¥Šƒ}tsl|‚z„Š„“““‚|u‚v{’ŒŒ‘…„red„„Š{{ƒ“““r]glrilld{u{{u{Š}|[[Tkd\‘ˆ}‚|u‹‹„|‚zj]\lddf]ckd\{u{Œ‹“Šƒ}[TT‹‹„dc\|„…‹‹‹ek][TTlld{{t{||¦§¨“““{u{ult¦§¨¦§¨›”›{||›¢›|„…mtt{{tUTSddc|‚zŒ‹“\[blri””‹‹’Šmtt™š¤uztŒŒšlriu{{leku{{lksŒ‹“mttlri{{ƒ{||{{t{{ƒ|„…zllddcttsuztllk„„Šuzt|‚zlekdc\ztl{u{ultƒ„„ƒ}ƒŠ}ƒ{tt“Œ”{||ttsult¦§¨VZT*)(”››“Œ”””‹‚|utsl’ŒŒ‚wlŠŠ}””‹¤¤µ¶·””‹£››››”£››ƒ„„””‹¦§¨£››¤¤»ÂǤ¤¤¤œ¤¦|‚z‹’Š··Äœ¤¦„„Šƒ||Œ”•œ¤¦…‹‹››””››tzl””‹œ¤¦“““|‚z“Œ”‹„‹|„…|‚z™š¤[TTVTL[TTlriu{{‚ut‚v{tllŒ”•”“›””‹’…‹ƒ||‚v{Šƒ}Š}ƒzll£››Š}ƒƒ„„lld{{tlld”“›lekyfd†~‘ƒ}ƒkd\tsl{tt’…‹””‹{{t{ttƒ||‰v|uztllklddŒ”•cbV{u{SKJlri|‚z‹‹‹tzldc\””‹‹‹„“Œ”‘Œ…‘…„{u{{zm‹’Š{tt„„Š””‹{ttŠƒ}tsltsl|‚z›”›|‚z””‹‹’Šƒ‚uŒ‹“tsl‚|uttsƒ||‹‹‹ŠŠ}ultult|„…ttsuzt{{tƒ}ƒ‚|utsl‹’Š{{ƒtlltts{{t™š¤²««‹„‹ult|‚zdc\tslƒ„„‚v{ƒ||{{t”š”œ¤¦‚|u£››“Œ”‹„„‚ut{{tuzttzl{zmŠ}|‚|u‚|u’ŒŒš””„Š„uztƒ||“Œ”‹„‹Š}ƒ|‚ztllztfb[Uekdttsj]\ƒ‚u|‚zllkŒ‹“{u{Š~‹{u{{||ƒ||[[T”š”ƒƒ|]cdUTS‚|uf]cbVU‘Œ…b[U{{tj]\Œ”•llk{||Š}ƒ‹‹‹‹‹„{tt[[T[[Td\\llk“Œ”|‚z{tt{{ƒ|„…Œ”•lksŒ”•ª³·œ¤¦{{ƒ‹’ŠMSSlriVTLbVUf]cUMR>B9ƒ||ª³·“Œ”|„…]cdtts]cd|„…ek]™š¤„Š„Šƒ}…‹‹{{t|‚z{tt’ŒŒb[U‹„‹{u{ult{tt’ŒŒr]Z‹„‹{ttœ››MRK*)(””‹²¬µ£œ¥””‹ultmw””‹Ä¿¤¤””‹›¢›£››²««””‹£œ¥¦§¨¦§¨£››£››¦§¨²²¬‚wl‹‹„””‹›¢›{||£œ¥œ¤¦‹„„¦§¨‹„‹{ttllk¦§¨“““Œ‹“ƒ‚u„Š„’ŒŒ|‚z¤¤‹‹‹…‹’FD;„Š„ultu{{u{{fkkUTS{ttzll‹„‹…‹‹ƒ}ƒ‹‹„š””d\\{u{lld‹„„Š}|ƒ||‹‹„ƒ}ƒuzt{ttkk]ƒ„„UMRrfk‚utttsSKJztlrfk””‹tsl\UZ“““‹’Š‘Œ…‚wlllkttsb[Uldd{||{||¦§¨kk]ƒ}ƒek]|„…””‹‹„„‹‹„š””ult“““‹‹‹lld”š”llk{ttƒ}ƒslesle{tttsl{u{”š”«²«¤¤”š”ƒ„„Šƒ}Š}|‚ut‹‹„“““ƒƒ|’ŒŒuztƒ„„u{{{{ƒ{{tƒ}ƒlri‹’Š“““ƒ||ttslriƒ„„”“›Œ‹“ult{tt{{tkk]{{tultttsllddc\{{t{zm{{tj]\zll‚v{‹„„{u{tllƒƒ|tzlb[U{{tŠ}|š””tllŠ}|œ¤¦ƒ}ƒult“Œ”£››Š}ƒlrilri“Œ”VTL{zm‚|u‚|u“““›¢›ultlddzll‘…„ztlf]ctts|‚z{tt{||uztlldtsl{||fkkek]tts{zmddctllš””VTLultuztbVUlriuztekdŒ”•””‹¦§¨Œ‹“f]c‹’Š…‹‹…‹’”››œ¤¦ttstt{u{{UUYJHF]bZƒ}Š{{ƒ[[Ttsl{{ƒŒ”•‹’ŠmttŒ”•‰ƒv{{tldduztttslriuztuzt{zmƒ„„llkf]ctllkd\ldd‚v{rfkztl‚v{leklek«²«JHF,55llklksƒ}ƒ””‹š””£››¤¤››”|‚z¤¤’‘~µ¶·²²¬²««š””¦§¨¤¤‚v{uzt„Š}¤¤£››¦§¨‹‹„|‚zœ››œ¤¦”“›{ttœ››ƒ||ztl‹‹„‰|v\[[lritlllld{{t{{tƒ„„Š~‹…„’tyguzttll‹‹„|‚zŠ}ƒ{||rg]‹‹‹kk]‹‹‹‹‹‹ƒ}ƒƒƒ|ult‹„‹ƒƒ|›”›‘Œ…“““œ››Œ‹“tsllekŠƒ}‚v{zll[[Tb[Uultrfkƒƒ|‚|u{u{„Š}£››”“›{{ƒŠ}|{u{…‹‹ƒ}ƒ‹‹„‹„„ƒ„„tt{jcVi\Vƒ‚uƒ||ƒƒ|›¢›¦§¨“““””‹‹‹‹{u{ƒƒ|sreztf{u{‚|u|‚z‘…„{zm|„…tsl‹‹‹‹’Š|‚z…‹‹›”›|‚z“Œ”ƒƒ|ƒ}ƒ”“›œ¤¦ƒƒ|tll{{tŒ”•Œ”•Š}ƒŒ”•Š~‹{u{‹’Š’…‹ƒ}ƒfkku{{tll’…‹ult{ttš””\[b{{tƒƒ|sleƒƒ|lektll|‚zƒ‚u{u{‚|u£››£œ¥‹‹‹ƒ}ƒ‹’Š”››{||tsltslrg]ƒƒ|sle’ŒŒ“““{{tƒƒ|“Œ”tsl’…‹››”kk]ult‹„„ƒƒ|ƒ||lld‹‹‹ƒ}ƒ‚ut{||bVUrg]kd\lek£››ƒ||tslƒ„„uzttts{u{z‚lmtt{zmztlj]\tts{{ƒ‘…„ŒŒšz‚lekdtll|„…„Š„„Š„yl„]bZ‹’Š‚|u{||‹’Š‹‹‹Œ‹“Œ‹“‹‹„¨©´fkk|„…\[b„„ŠUTSD;9lksmtt‚|u{{ƒlks”š”mtt{{ƒŠ}ƒ’ŒŒ“Œ”‹’Š‹‹‹{||tts‚uttsltt{|‚ztlllekredf]cf]cƒ}ƒ{ttŠƒ}tlltll¦§¨MRK*)(ƒ„„ƒ||¦§¨¦§¨£››²²¬¦§¨‰ƒv¦§¨µ¶·ÃÄƤ¤µ¶·“Œ”””‹”š”£œ¥¦§¨µ¶·››”””‹‹„„‹‹‹œ››“Œ”tts¦§¨™š¤²²¬””‹¤¤‹’Š”››Šƒ}ttsVTLtts”š”‹‹‹uzt{ttttsƒ„„]bZƒƒ|¦§¨uztllk„Š„{{tztlƒƒ|‹‹‹Œ”•uztd\\lddƒ||‚|uztlŠ}ƒ””‹‚utedk„Š„tts“Œ”lld’ŒŒldd™š¤Šƒ}„Š}‹‹„Šƒ}f]c‹‹‹{{tldd„„Š‹‹„™š¤‚uttts[TTSKJŒ‹“lriekdƒ‚uŠƒ}tts‰v|“Œ”²¬µ¤¤¤¤£››‹‹‹ƒ}ƒ™š¤ƒ‚ukk]‹„‹””‹ƒ||‹‹‹››”‹’Šztlultƒƒ|‹’Š””‹‹„„“Œ”ƒ}ƒŠƒ}{||ƒƒ|Œ”•{ttlrikk]{u{…‹‹¨©´ƒƒ|tll{||Œ”•‹‹„ƒ}ƒ{||u{{‹„„{{tult‚|uƒ}ƒ”š”””‹tsl””‹œ¤¦‚v{›”›{{trg]{{t‘Œ…ƒ||›”›‚ut“Œ”“Œ”››”{{t’ŒŒ’…‹d\\ttskk]’ŒŒ”“›‰‘~¦§¨ttsŒ”•œ››‰|vsre››”‚|u{{tdc\kk]ƒ||ƒƒ|d\\{u{slered{tt{tttll\[[{u{lld{||VTL{tt|„…ttslldztl’ŒŒŒ”•lks{||‹„‹lritts‹„‹Œ”•uzt™š¤lddtll|‚z”››llk{||ƒ„„‹’Š’ŒŒ‹’ŠVZT\UZlrislef]cu{{{{ƒ‹…štlldc\UTSlri‹’Šlks…‹‹ƒƒ|‹„‹{|||„…œ¤¦{|||‚zddctslƒ}ƒekd{tt[TTƒƒ|{tt{u{Šƒ}{tt››”Šƒ}dc\µ¶·JHF*)(„Š}“Œ”œ¤¦‘ˆ}””‹£œ¥‘Œ…£››””‹»ÂǦ§¨²²¬²««²««¦§¨¦§¨œ››¨©´›”›£››“““ƒƒ|ƒ||tzl™š¤…‹‹ƒ}ƒ‹’Š¤¤¦§¨£œ¥ŠŠ}ƒ‚u¦§¨uztuzt“Œ”››”ƒ}ƒ‹‹‹tslttsŠƒ}ddc‹’Š|‚z„Š}|‚zlridc\ƒ||ttsuzt„Š„ƒ||ldd{u{d\\zll£››š””œ¤¦¦§¨¦§¨¦§¨ƒƒ|‹‹‹”š”{{ƒ²¬µ’ŒŒ£››‘Œ…‹‹„tllƒ}ƒtts…‹‹„Š„‹„‹yleš””tllƒƒ|mttVTL’ŒŒtt{”“›ƒƒ|kd\ƒ„„ƒ‚uVTL’ŒŒ‚|u‚wlš””tt{‚|ullkdc\tslult‹„„ƒ||‘Œ…‘Œ…‹‹‹jcVmw{zm¦§¨£œ¥‹…’™š¤‹’Š›”›{u{{||‹‹„“““{u{‹‹‹Œ”•Œ‹“{||‹‹‹ƒ„„{{t‹‹‹tslƒ|||„……‹‹{||‹„„›”›ƒ}ƒ‹„‹tts‹‹„|‚z{zm¤¤tll{u{ƒƒ|{{t›¢›{{t””‹ƒ||ƒ||{{t‹’Š|„…‚|uŠ}ƒyleƒ||red„Š„””‹ƒ||’ŒŒ‘Œ…””‹ƒ„„dc\uzt””‹‹’Šƒ||slekd\mtttzl\[[ultƒ||’…‹‘…„sle“Œ”ƒ||‹‹‹ƒ„„|‚z„„Š{{tb[UtllŒ”•„Š„lld…‹‹”“›ƒ||””‹„„Šœ››|„…ztlœ››„Š„Œ”•’…‹lddŒ”•tts„Š}|‚zmtt™š¤”“››¢›{tt{{ƒmtt””‹|„…Œ”•tt{ƒ}ƒred‚v{lksŒ”•ekdleklksztllek„„Šuzt„Š„dc\[[Tekdlekƒ}ƒlld{||[TTtlllddlek{tt‚ut„Š}Š}|]bZ··ÄJHFF=C‹„„Š~‹””‹²««²««£œ¥””‹ƒƒ|‰‘~¢—£››ƒƒ|šŒ‘…„‘Œ…š””²««››”²¬µ··Ä“Œ”œ››Œ”•›¢›llk“““‹‹‹{tt››”£››Š}ƒ‹„„¦§¨ŠŠ}‹‹‹„„Š…‹‹lritts‘Œ…‹‹„tsldc\ttsƒƒ|\[[[[Tkd\VTL[[Tr]g‹‹‹‹’Šek]“Œ”{ttlldllk‚ut”š”‹„„ƒƒ|‹’Štts„Š„‹‹‹zlldc\{||“Œ”rfk¤¤”“›››”„„Štsl‹’Šƒƒ|‹’Š“““‹‹„ƒ||tllllktzlƒ||‚wlŒ‹“{||redsleSKJ{{tƒƒ|zllsletsl{zmlekf]c„Š„rg]„‰vttsŠ}ƒ{||š””””‹¦§¨‹‹„””‹sle|‚z””‹“Œ”“Œ”‹’Šƒ}Šu{{{tt¤¤‹„„‚utƒ}Štt{ƒ}ƒllkllkƒƒ|“Œ”lld‹‹‹{tt”“›”››‹‹„{ttult‹‹„‹„„f]c›¢›ƒƒ|ƒ‚u‹‹„ƒ„„‹„‹›”›‹„„¤¤ŠŠ}sre£œ¥{||‹‹„„Š„‚|u{tt‹„„llk{tt””‹JHFtts{zmrg]{{tŒ”•ƒ„„{{t‹„„¦§¨£››jcVdc\sre]cd{{t¤¤¦§¨“Œ”š””‚uttts‚utœ››Œ‹“‹’Š[TTddcsref]clldult‹’Š„Š„™š¤u{{›”›kk]“Œ””“›ª³·ztl„Š}‹’Šult“Œ”Œ‹“u{{š””„„Š‹‹„|„…‹’Š“““lri]bZlldfkkVZT]cdllk{ttŒ‹“‚|u‹„„VZ[mttŠƒ}‹…’llkŒ”•{ttmtt]bZedkdc\{||fkk{u{lddzll{{ƒtllultyfdred››”ldd‹’Šƒ||ƒƒ|¤¤JHF*)(tsl’ŒŒ”š”²²¬¢—š””””‹’‘~‚wl””‹¦§¨‘Œ…£››¤¤“Œ”²¬µ¨©´²¬µ“““œ¤¦¦§¨£œ¥«²«‹‹„“““™š¤‹‹‹„Š„¦§¨‘Œ…£œ¥¦§¨‰|v¤¤™š¤u{{‹‹‹››”Šƒ}¦§¨{||dc\uzt„Š„]bZ{||ƒƒ|‹’Štzllriƒ}ƒŒ”•‹‹„Œ‹“‚|u{tt{ttƒƒ|‘Œ…Šƒ}kd\r]gztl¦§¨tsl{||llkVTLtt{‹„„‹„„Šƒ}uzt’ŒŒ„Š„‹„„{||sre{{tƒ„„‹‹‹sle’ŒŒtslƒƒ|“““lddtt{{{ƒkd\sre‹„‹|‚z‹‹‹tllƒ||{zm„Š}f]cVTLztl‰|v’ŒŒŒ‹“sle„„Šœ¤¦ƒ‚u‹’Šƒƒ|£››‹’ŠŠŠ}“““Œ‹“”“›…‹‹’ŒŒmtttsl››”›”›‹„‹Œ”•ultd\\lks‹„‹“““ldd|‚z‹„„™š¤™š¤tts‹‹„‹„„Š}ƒtsl[TTƒƒ|{zmdc\ztl‹‹„‹„‹{tt‚|u¦§¨ŠŠ}””‹{{tult{ttlri„Š}”“›zllult‹‹‹tll‚|u””‹f]cultŠŠ}Œ”•sreŒ”•””‹«²«’…‹“““ƒƒ|lddredSKJtslcbVtllƒ||ƒ||sle£œ¥‹„‹VTLb[Uddc‹‹‹|„…tll‹„‹{{tllkuzt|‚zSKJlri{||‹„„£œ¥“““‹‹„¦§¨{tt›¢››”›‹„‹’ŒŒlriŒ”•{{ƒkd\¨©´Œ”•™š¤uzt„Š„ŠŠ}JHF|„…lriƒ}ƒf]c\UZ]bZult|„…ƒ}ƒƒ}ƒ’…‹lkslrimtt|‚zttsSKJlriuztedklksƒ||ƒƒ|tts‹‹‹ttsrfkd\\{u{Š}ƒ‹‹„Š}ƒ{||£››:97*)(œ¤¦’ŒŒŠƒ}²««²««²««š””¦§¨””‹‘ˆ}µ¶·²««“Œ”²««²¬µ²¬µ¦§¨™š¤‹‹‹¤¤ƒ}ƒ¦§¨“Œ”“““œ¤¦”“›Œ‹“››”¦§¨””‹£››“Œ”llk²²¬{{tuzt£œ¥ƒ„„tll£œ¥¦§¨Œ”•|„…‹’Š|‚ztzl‹’Š‹…’lri””‹ƒ„„”“›{zmŒ”•””‹{tt{ttƒƒ|Šutztltsl››”Šƒ}“““‘Œ…{||{zm{||„„Š{{ƒ{u{ƒƒ|uzt{{tVTLf]c|‚z‹‹‹{||ƒ„„d\\£››£››{zmdkV[[Tddc‹’Šƒ}Š‚|u[[Tƒ„„{{ƒ„„Š{ttsleƒƒ|ƒƒ|f]c{u{ƒ„„”››š””Š}ƒ’ŒŒ{ttŒ”•‘Œ…””‹£››¤¤¤¤‹‹‹’ŒŒ“Œ”ƒƒ|‹‹„œ››tsl“““‹„„‹‹‹tt{ult‹…’zllddc’ŒŒ{ttƒ||{{tu{{‹’Š”“›‚ut‚|u“Œ”Œ‹“tll{zm„Š„ƒ||ƒƒ|‚wl“““‚v{šŒyl„›”›””‹‘Œ…Š}ƒ{ttsleŠƒ}{{t{tt›”›ƒ„„{ttlddekd‹‹‹‚ut„Š}””‹””‹{{tµ¶·“““¦§¨’ŒŒ”››„Š„redkd\VTLsleldd{||‚|u{ttŠŠ}|‚z{tt‘…„ƒ„„lldlriztl››”‹„„{{tVZ[‹’Štts]bZ{||Š}ƒ‹„‹tllŠƒ}{zm{tt{||””‹‹‹‹‹„„‹„„ztlfkk“Œ”rg]Œ”•™š¤tt{mtttsl”“›ddc…‹‹MRKlkslriƒ}ƒtlltts{{ƒ“Œ”{{ƒŠ}|Œ”•{||ekduztttsedk””‹lrilksŒ‹“ƒƒ|lri[TT{{ƒ{u{ƒ||kd\{tttlltts{{t‹’Š””‹:97*)(£››¦§¨””‹’…‹£››ƒ||£››ŠŠ}‘ˆ}››”””‹£››²¬µ²¬µ²««£œ¥²¬µ™š¤£››”››ƒ||““““““µ¶·„„Š”š”¦§¨››”››”Š}ƒš””ƒ}ƒ”š”„Š}¦§¨ƒ}ƒ£››‹‹„Š}ƒ‚|u‹‹‹|‚z‹’Š[[Tkk]|‚z¦§¨“Œ”|‚z„Š}¨©´”š”{zm|„…›¢›£››‹„‹‚|uztl‹‹„‹„„””‹””‹Œ‹“ƒ‚u|‚z‹‹‹{||f]cttstll{{t‹’Škd\ƒ„„“Œ”’ŒŒtzl„„Šf]c\UZ‘Œ…{{t‚ut{tt|‚zekdƒ}ƒttsz‚lrg]‹…’’…‹ƒ‚uƒ||››”‹’Š””‹ƒ}ƒ‹„„‹„„{||‚utf]c‹„„{||lddkd\tll¦§¨sle‹’Š|‚zƒ||{||„„Šƒ„„{ttttsŠŠ}š””ƒ||„„Š‹‹‹£²’ŒŒŒ”•œ››ƒƒ|{u{|‚z|‚z]cdtts{{ƒ‹„„„„Šƒƒ|ƒ„„ƒ||tts’ŒŒ‹„„””‹‹’Štts”“›ult{||””‹ztl‚wl””‹zll„Š}{{t‹‹„œ¤¦£››ƒ„„\UZ””‹‹’Š{{t{{tš””››”ƒ‚n{||…‹‹‚wl“Œ”ldd‘Œ…{zm{u{mwzllbVUkd\lddslef]c[[Tredtlluzt{zm\[b‹„‹””‹j]\ƒ„„VTL|‚z{{tVTLlri{tt‘…„\UZek]…‹‹lld{{ƒ‹’Štt{ddclddUMRlld…„’ztl“““tt{ddcleklddf]c‚v{lksVZTf]ccbV{{ƒlldddc{{ƒult‚v‚‹‹‹lksfkk…‹‹|‚zuztœ¤¦lld\[[mtt{||ldd|‚ztt{ƒ}ƒllklddztf‹„„ttsƒƒ|lriVTL’ŒŒ:97*)(›”›¨©´«²«²««’…‹Š}|²²¬²¬µ‹‹„‘Œ…””‹¦§¨£œ¥²««²««£œ¥µ¶·¨©´‹‹‹Šƒ}„Š„‹‹„’…‹™š¤„Š„”››“Œ”››”ŠŠ}µ¶·›”›Š~‹‹’Š¦§¨¨©´‹„‹‹„‹ŠŠ}””‹ƒ‚uƒ||dc\llkƒ||{{tiq]…„’|‚zuzt‹‹„tzlŒ‹“{{t‹‹‹‚|u‹„‹„Š}‘…„’…‹sleŠƒ}¤¤²²¬““““Œ”“““‹’Šttstlltsluzttzl”››d\\{ttlddrfkkd\{{tdc\{tt‚ut‹„„u{{tllrg]UTStll„Š„sleš””ult„„Šred‚|uš””‹’Š‹’Š{{tœ››|„…[[Trg]j]\tllldd{{ttsl{ttzll‚|u›¢›„Š„“Œ”‹‹‹ddclld‘Œ…“““’ŒŒƒ„„¦§¨{{ƒŒ‹“…„’{||{||””‹lekŒ”•‹’Š{{ƒlldultmtt{ttdc\„Š„‘Œ…{ttŠƒ}{ttuzt””‹œ¤¦£››‘…„‘Œ…{u{ƒ}ƒztl’ŒŒ””‹£››“““ŠŠ}“Œ”tsl„Š„ulttts|‚z„Š„ult‚utrg]{{t‚|uVTLSKJkd\|„…ƒ||{{tztlttsd\\ztltll””‹zllkd\f]clld[TT\UZultVTLsrelri]bZ{ttd\\:97{ttekdƒ‚ntt{ztljV[{u{VTL[[Tdc\‹‹‹ƒƒ|lek|„…”››{ttultŒ‹“lddŒ‹“{||lldŠ}|UMRbVUƒ}ƒmttFD;llkuztf]clri{{ƒult{tt[[TVZ[nv‚\[b]cd‹’Štsllkstsluztf]clddd\\lkstsllekƒ}ƒbVUzllƒ||tllƒƒ|ddcb[U‘Œ…:97*)(£››¦§¨‹‹„£››£œ¥¤¤»ÂÇœ¤¦–¢‹¤¤¤¤¤¤²««‘Œ…šŒ“““œ¤¦¦§¨”š”ƒ‚u{zmzllƒ}ƒ‹„‹ƒƒ|{||VZTœ›››¢›¨©´ŒŒš“““””‹£››‹‹‹ƒƒ|“Œ”‘Œ…sle‹‹„ult”š”tzl‚utƒƒ|u{{‹‹‹|„…]bZ[TT{{ƒƒ‚ukd\Œ”•””‹sletsl‘…„“““{zmŠŠ}”š”””‹‹‹„””‹„Š„{{tttsƒ}ƒœ››Œ”•{||ƒƒ|ddc{||SKJzllslesreUUY‹„‹‚|uƒƒ|UTS{ttVTLJHFƒƒ|{u{{{taWMmtttsl{u{Š}|œ››””‹‹‹‹…„’tzldc\uzt‚ut{||ƒ}ƒ“Œ”‘Œ…š””‹‹‹‹„‹{tt“““¦§¨ƒ}Šult‚ut„Š„ƒ}ƒ|„…‹„„™š¤””‹|„…lek”“›‹„‹Œ”•ƒ||’ŒŒ“““{{ƒllk‹‹„\[[uzttlllldlks‚|u’ŒŒ‹’Š””‹|‚z‹’Šƒ||“““”“›ƒ}ƒŠ}ƒƒƒ|‚|u””‹‹‹„tllƒ}ƒƒ‚u””‹ƒƒ||‚zƒ}ƒVTL‹‹„„‰vek]tll{zmaWMlldVTLkk]rg]\[[‹’Š‹‹‹‹„„{tttts{u{‚|u{{tultƒ||[TTultbVUSKJŠ}ƒdc\dc\‹„‹{||ldd[TTlrildddc\‚|u‹‹„ƒ||‚v{™š¤‹‹‹tzl{{t{{tƒ‚utllƒ„„{{t¦§¨{ttŒ‹“Šƒ}‚v{„Š„™š¤‹’Š‹„„Š~‹ƒ}ƒedkVZ[\UZVZTfkklldUUY{|||‚z]cdekd|„…|„…mttlekVZTlksuzt|„…u{{lek‹‹„ƒ„„f]clddultsleultƒ||ztl‹‹„{ttsre‹„„JHF74,ƒ}ƒ£››””‹£››£››£››››”››”››”£››‘ˆ}™‹†››”‘Œ…²««š””›”›‹’Š‹‹‹””‹””‹‹‹„ƒ||”››ƒ„„¦§¨„„Šµ¶·¦§¨‚v{œ¤¦{{ƒ™š¤””‹¨©´{{t¨©´‹‹‹tsl¦§¨ƒ||‹‹„™š¤ƒƒ|{tttslddcMRKuztsre\UZ‹’Š‹„„‹’Šƒ||‹„„ƒƒ|‘…„‘…„Š}ƒ””‹‘Œ…ztl”“›ƒ‚uƒ„„lldVTLƒ||{u{ƒ}Š‹‹„lddf]c{{ƒrfkŠ~‹rr]››”ƒ}ƒ‚v{ƒ||Šƒ}ƒ||£››tzl‹’Š‹‹‹’ŒŒ”“›‹„„…‹‹…‹‹“Œ”””‹’ŒŒ|‚z{||“Œ”lksƒƒ|{{ƒ‚|uƒ„„ƒ||”“›‘}z‘Œ…š””ƒƒ|””‹{{tƒƒ|“Œ”tt{›”›‹‹„‚ut“““{tt’ŒŒ¦§¨›”›{{ƒ…„’|‚z…‹‹“Œ”’ŒŒ‹„‹|‚zƒ||‹‹„tt{mttƒƒ|””‹Œ‹“‚|u‹‹„{{tztlƒƒ|””‹‹’Šƒƒ|“Œ”lekƒ}ƒlri”š”rg]|‚z{ttddc‹„„‚wl|‚z”“›œ¤¦{ttŠŠ}dc\‚|uŠŠ}‚wlcbVkd\ztld\\tzl{{t‹‹„lldkd\tllllk››”£œ¥‹„„{ttsred\\””‹llklekŠ}ƒredkd\SKJekd\[[dc\\[[UTSsre\[b{{ƒdc\rfkult›¢›„Š„›¢›Œ”•””‹ultƒ}ƒllkƒ}ƒUMR\[[lldddc{||{u{ƒƒ|{{t{ttulttll›”›ƒ}Š|„…£œ¥|‚z|„…tt{ƒ}ƒ™š¤„Š„MRK{{ƒmtt{||tsl{||mtt|„…ttsƒ}ƒŒ‹“{{ƒUMRSKJred‹„„‹‹‹ƒƒ|lddd\\ttsƒ‚u””‹>B9:97‹„„Š}|‘ˆ}‘ˆ}Š}|£œ¥¤¤‚|u–¢‹£››²²¬£œ¥‹’Š£››£››“““œ¤¦ƒ„„‹‹‹”š”‹’Š’ŒŒ””‹”š”””‹¦§¨£œ¥£œ¥”“›””‹ƒ||“““ƒ‚u””‹“““sre¦§¨‚|u{||Šƒ}tlllri‹‹„‘…„lritslult„„Šmtt|‚z„„Š‚|u‹„‹tsltslrfkƒ„„””‹{tt„Š}‹„‹ƒƒ|„Š}¦§¨kd\[[T|‚zkk]””‹„„ŠŠŠ}‹‹„redUMRbVUrfkƒ||VTL‹‹‹ldd{tt‹„‹‹„„‚ut‚|u‚ut[[TVTLb[Uztl£››f]clks‹„„‚utŠƒ}“““|‚z„„Šred‚|ulri””‹tsllekƒ„„Œ‹“zll”“›‹’Š‹„„ƒƒ||‚z{ttƒ}ƒ…‹‹‹„„ƒ||Œ‹“‹„„‹„„‹’Š™š¤|„…Œ”•›¢›ekd“““Š}|tts|„…”š”|„…tslŠ~‹Œ‹“œ¤¦{u{sle{{ƒyle’ŒŒƒ„„‚utŠ}|f]ctts‹„‹‹„‹lri››”‹„„–¢‹š””‹‹„‹‹„‹„„›¢›UTSd\\lldtsltzl””‹llk¢—{yfsle‚wltsltllƒƒ|ƒ„„lek‚|u‹uŠiWUslettsƒ„„sleƒ„„lekƒ||ult‹…’ult|„…VTLztlkk]Š}ƒ{||]bZƒ‚ulddtt{tts{zmbVUƒ}ƒf]c„„Šœ››|„…””‹Œ”•ttstslƒ„„{u{‹’Š„„ŠŠ}ƒlektll|‚zaWM£››lks{{ƒ{||‹…’¦§¨Œ‹“š””…‹‹ƒ}ƒfkk|„…\[[VZ[ult\[bttsekdf]c“““{{ƒ{||‹„‹„Š„ƒ„„srett{j]\‚|uj]\lddlddddc‹‹‹lri””‹JHF-1+“Œ”™‹†sle£››››”‘…„‰ƒv‚|u¢—‘ˆ}¤¤¤¤””‹{zm¨©´²¬µ£œ¥””‹¦§¨ƒƒ|””‹ztf„Š}{tt”›››¢›„Š„£››‹’Šš””¨©´“Œ”””‹Œ‹“[TT“~ˆ“Œ”‹’Š‹„„‚|utll[[Tr]Zrfkult{||œ¤¦„„Šllk”š”¦§¨ƒ||UMR“Œ”ƒ}ƒŠƒ}ŠŠ}tllbVZ›”›{zm„Š}šŒtsl‹‹„kk]uzttslš””UTSmw¤¤\UZ{{ƒSKJ’ŒŒkd\ztfdc\‹‹‹{u{‚|u‚utƒ||Šƒ}“Œ”lld{tt|‚zŠ}|’ŒŒzll{{tƒ||’ŒŒ‘…„‘Œ…ekd\UZ{{ƒrg]{zmjcVlldultƒ||œ››››”ƒƒ|‹‹„‹‹‹„Š„lri“““›”›‹‹‹£œ¥‹„‹ƒ||{zmu{{tsltt{llkmttUUY…‹‹“Œ”redu{{llk|‚z…‹‹“““uzt›”›‹’Š“Œ”{||Š}|dc\ƒ}ƒ’…‹£››ƒ||lksf]credult””‹{{tsle¦§¨{ttœ¤¦“““’ŒŒrr]tt{‹…’ƒ„„‘Œ…ƒƒ|””‹ƒ||ƒƒ|{zm{{t‘Œ…‚wltllztlƒƒ|j]\VTLƒƒ|Šƒ}‰ƒvd\\ult‹‹„‹‹„ƒ„„tllultf]cuztlri{||[[Tztlf]c‹„‹‚utek]ekduzt{{ƒztltllult„„Š¦§¨ƒƒ|lri””‹›¢›tt{ztl”“›lek{{t|‚z‹„„”››{tt“““Šƒ}“Œ”{{ƒŒ‹“”“›{{ƒ\[[|„…“Œ”ƒƒ|lks…‹’|„……‹‹u{{{{ƒVZTllkztlult{{t{{ƒƒ„„{{ƒttsƒƒ|tslƒ}ƒlddbVUbVU‹„„tts{{tuzttsl‰ƒvMRK*)(‚wl‘…„{tt£››››”””‹¤¤š””¢—’ŒŒ‹‹‹Šƒ}µ¶·¦§¨¦§¨²««²««“““œ››‘Œ…””‹””‹Šƒ}Œ”•‹‹„ƒ„„‹„„ƒ||ƒ||{{ƒ””‹››”“Œ”¦§¨ƒ}ƒ£œ¥ƒƒ|‹’Šlj¦§¨“Œ”sle‚utyflƒ||…‹’‹„‹{{ƒ„Š„¦§¨…‹‹‹„‹ŠŠ}Šƒ}‹„„Šƒ}|„…Š}ƒ‹‹‹²««››”¤¤ultuztztl\[[‚v‚””‹“Œ”””‹¦§¨„Š„‹„„lldddc{tt‚utƒ}Šttsƒ„„b[U£››lkstts£››bVUUMRj]\zllztfiWUƒ}ƒd\\Š}|‚utult››”ƒƒ|ƒ„„ldd‹’ŠtslSKJlddredƒ||ƒ„„œ››””‹i\VŠƒ}|‚z‹‹‹‚v{‹‹‹ƒ„„ƒ}ƒ“Œ”œ¤¦‹„„“““ƒ„„ƒ„„lldedktslƒ„„‚|uzllddclksztl‹…’›¢›‹’Šƒƒ|Šƒ}{u{“Œ”llk„Š„¦§¨kd\“~ˆllktslttsƒ}ƒd\\{{tlld‘Œ…llkƒ||‹‹‹ƒ||‚v{‚|u¦§¨”š”£››£››{{ƒ‹„‹¤¤‹’Šƒƒ|‹‹‹sre””‹œ¤¦kd\‹’Š{u{¦§¨”“›lekƒ||uzt‹’Š{{tddcttsfkk‚v{ƒ}ƒƒ„„UTS{{tƒ||‘Œ…Š~‹”“›…‹‹„Š„‹‹„uzt{||‘ˆ}kd\“Œ”kd\›”›rg]lritzl“““„Š„uztŒ‹“›”›”“›z‚l””‹›¢›tts”“›‹„„{tttllŒ”•|„…{{ƒƒ||f]cddc‚utŒ‹“ƒ„„…‹’|„…lrif]cŒ”•ƒ}ƒ„„Šddcuztu{{tts[TTllk“Œ”{tt{u{bVU’ŒŒlek{ttldd””‹‹‹„{{t¦§¨JHF*)(zll‚wl‹„„’ŒŒ’ŒŒÃ¼¿¤¤””‹Ä¿’ŒŒ‚wlŠ}|‘…„¦§¨£››‹„‹£››¦§¨””‹””‹‹‹„‘Œ…Šƒ}‹‹‹››”‹’Š„Š„“Œ”œ››¦§¨¨©´£œ¥¨©´¦§¨‹…’ƒ}ƒ›”›““““Œ”””‹‘…„i\Vtslzll””‹llkƒ||tllekdlri‹’Šƒ}ƒœ››”››“Œ”ƒ‚u‹„„‹„„‹„„«²«¦§¨{{tslelldlrilldaWM[[Tj]\›”›ŠŠ}|‚zƒ„„dc\ult“Œ”‚utSKJ\[[VTLtllztl‚v{‹‹‹lekUMR{||\UZzllƒ‚usledc\{{ƒ{u{‚ut{tt‚|uƒ„„llkd\\ƒƒ|{ttŠƒ}{tt‹„„ƒ||’ŒŒƒƒ|‘…„””‹‹„„””‹tts‹„„‹„‹ƒ„„fkk‚v{ƒ„„›”›tll‹„‹leklks„„Š|‚z|„…ƒ||’ŒŒult{{ƒult{||ƒ„„Œ”•{ttlldƒ}ŠlddUTStsl‹„„Šƒ}ƒ}ƒ{ttztff]cUTSd\\lriƒƒ|tsllldVTL[[Tsre{u{lldtslddc{ttŠƒ}slekd\llkƒ‚u‹’Š””‹„Š}{ttœ¤¦{{t“““ƒ}ƒtsl„Š}‰|vkk]‹‹‹llkuztultƒ}ƒultldd“Œ”{ttttstts{zmtslƒ||’ŒŒœ¤¦ƒ„„ƒƒ|lkstzllks‹‹‹lekdc\‚utsleVTLlekƒƒ|{||b[U{u{ƒ}ƒ|„…‹’Šsle{||tll{{ƒƒƒ|‰|vtll{{ƒ†~‘“““tslldd{tt‹‹‹{{ƒ\[[mtt|„…lks“Œ”„Š„›”›™š¤„„Š|‚z{{ƒ\[[‹„‹…‹‹‘Œ…“Œ”š””slered{u{‹‹„ƒ„„„Š„„Š„ƒƒ|£››:97*)(’ŒŒšŒšŒš””£››¤¤‹‹„¼À¯¤¤²²¬œ››£››²««£››²¬µ¨©´²²¬µ¶·›¢›””‹š””Š}ƒŠŠ}“““¦§¨¦§¨ƒ}ƒ£››£››£œ¥Š}ƒ£››‹„‹””‹ult{ttƒ}ƒ{{tzll‹‹„›”›‘ˆ}slezllUTSVTLtsltts{||‹‹„‹’Šœ››{u{ƒ„„¦§¨‘Œ…Œ”•{tt¦§¨¦§¨„Š}””‹‚uttsl{||‚|u‚|uUTSredrfkuztdc\VTLƒ}ƒ{tt£œ¥””‹VTLƒ}ƒd\\›”›uztyfd‚|udc\Šutƒ||Š}|f]c{ttƒƒ|ttsUTS’ŒŒƒ‚u{||kd\Œ‹“ƒƒ|ƒ„„‹„„sleŠƒ}‹‹‹{tt‹„‹œ››Šƒ}šŒ’ŒŒƒ||‹‹„‹’Šƒ||’ŒŒ…‹‹Šƒ}ƒ}ƒlektsldc\{zmtt{{{ƒtt{ƒƒ|{{ƒƒ||“““™š¤bVZƒ„„”››{||‹‹‹{tttts”“›d\\[TT[[T‹„„‹‹„ulttllŠ~‹tll{u{ƒ||Šƒ}VTLƒƒ|››”ztl…‹‹{||aWMbVUVTLSKJcbVlek[[TaWMMRKrg]››”{||””‹ŠŠ}‹„„d\\‚v{Šƒ}‹„„{tt{{tVTLƒ‚u„Š„¦§¨b[U{tt\UZ{{tUTSkd\{||ult{{ttslb[Uult‹„‹{{t™š¤|„…{{tbVUŠƒ}lek\UZ‹„‹zll›¢›£œ¥ƒƒ|tll]bZ‹„‹‹‹‹{{tŒ”•š””Œ‹“ƒ„„Œ‹“””‹ƒ„„¦§¨„„Š{u{tts|‚zƒ}ƒttsf]c{{ƒ\[[\[b]cd]cd\[b…‹‹{u{{{ƒ{{ƒuzt|„…tslu{{‹‹‹{{ƒ’ŒŒ“Œ”‚utztlkd\ztllld‹‹„‹‹„[[T¦§¨D;9:97””‹£››‚wl™…‹„„””‹¦§¨””‹¤¤“““¦§¨¤¤²««£››²««£››¦§¨¦§¨””‹””‹™‹†’ŒŒ„„Šƒƒ|””‹¦§¨Œ”•£œ¥²««¨©´£››¦§¨£››’ŒŒ‚utult{tt‹’Š£››‘ˆ}›”›‚|u››”››”Œ”•lld‚|ubVZuzt„Š}{yfŠƒ}lri£››ƒ}ƒŠƒ}ƒ„„ttsƒ‚uš””ƒƒ|‘Œ…ƒƒ|ztl¦§¨‹‹„‚|usre“Œ”lddkk]kd\[[T[[T{tt‚|ub[Uredƒ}ƒult‚v{|„…Š}|ƒ||Œ”•f]cr]Zult’ŒŒcbVjcV{||‹‹„ultred‹‹‹{{tlldrfklrillk|‚z‹„„‹‹‹“Œ”rfkƒ„„„Š}Š}|¦§¨ƒ||ƒƒ|„Š}tll‹‹‹u{{’ŒŒ‹„„edkœ››|‚zlld|„…‚utddcmtt…‹‹ƒ||Š~‹jV[edkzll“Œ”lri…‹‹‹’Šu{{tt{‹‹„sleuzt¤¤‚|uultš””{u{‹‹‹’ŒŒrg]¤¤mtt|‚zƒ‚u{tt[TTbVUb[U[TT3+*kd\kd\ek]cbVlld‘ˆ}ztl‹„„‘ˆ}{ttƒƒ|‚utŒ‹“tsl””‹“Œ”VTLtsl‚|u|‚zŒ”•{tt‚v{“““\[[‹„‹dc\b[Uddcb[Ub[U””‹lld\[[{u{£››lldultllddc\tsllekllkŠ~‹sleuztlritsl””‹u{{ultlddƒ„„„‰vŠƒ}Š}|Š}|Œ”•››”£œ¥{u{‹„‹f]cllk›¢›ƒ}ƒlddlekmttmttdc\tt{mttedktll“Œ”|„…ƒ}ƒlri\[[{{tuztŒ‹“‚utslezll‹„„’ŒŒkd\red{ttdc\uztlldµ¶·UMR:97‘ˆ}ljljŠƒ}Šƒ}sle‹„„‘ˆ}›¢›‘Œ…””‹£››£››²¬µµ¶·šŒ¦§¨¦§¨””‹””‹›¢›d\\|‚ztsltzl‹‹‹”“›““““““‹„„£œ¥£››””‹‚|u‰v|””‹¦§¨ƒƒ|”š”‘Œ…„„Šztl‹‹„tts‚v{“““””‹{{ƒ”“›ƒ„„uzt{{ƒlld{tt²¬µ””‹dc\{{t²««“Œ”””‹ƒƒ|”š”››”lldrfk{||ƒ||Š}|ƒ„„‚|ulldlldbVU{tt‚v{yleek]{ttddcƒ||]bZtsl‹‹„‹„‹“Œ”{zmldd‚utdc\aWMddcttsredš””tll››”{{tzll{{tldd‚ut‘Œ…‹‹„£››b[U„Š}ƒ„„‹‹„‹‹‹uzt‘ˆ}„Š„{ttsle\[[ƒ||llktts‹„„{||‹’Šlri…„’ƒ„„fkk|„…rg]ult‚|ullk{||llkƒ„„|„…‹‹‹|‚ztll„Š„kd\llk¤¤””‹£œ¥’ŒŒuzt‘…„Œ”•f]c{{ttsl‹’Šsle|‚ztllultVTLj]\{ttrfk‚|u“““‹’Šb[U‰ƒv“““šŒVTL‚|ulld{{t‹„„dc\‹‹‹ƒƒ|uzttslsledkV‹‹„ƒ‚uƒƒ|llk{tt‚v{tsl’ŒŒrg]lldVTLlri‚v‚tts¦§¨””‹‹‹„llkb[Ullkttsrfk{u{›”›£››llk‹‹„”››|‚zƒƒ|{{ƒd\\ldd”š”‚|u’ŒŒ‘…„”“›lriƒ‚u‹‹‹ultf]cldd|„…tt{ddctt{{{ƒedklri\[bu{{ultd\\lksek]lkslri\[[{ttƒ„„ƒ}ƒ‹„‹Š}|tlllddi\Vlri‚wlj]\ƒƒ|ƒƒ|tzl¤¤VTLJHF‚wl‰ƒv“~ˆŠ}|‘…„””‹µ¶·£œ¥š””¦§¨²²¬²««›”›£œ¥Â¾Æ²««²««²¬µ‘…„‹„„””‹tts„Š}›¢›‹‹„›¢›‹‹‹¦§¨¦§¨£œ¥¦§¨£››””‹œ¤¦¢—Šƒ}’ŒŒ›¢›››”‹„„ttsldd‘Œ…„Š„tll{{ƒ‚ut“““ult…‹‹„Š„‹„„lrilekƒ‚u£››{{tƒ||’ŒŒš””””‹ttslriultttsŠƒ}£œ¥””‹’ŒŒ‹„„ƒ‚u›¢›kk]SKJ“““j]\‘Œ…ldd„„Š[TTƒ}ƒ|‚ztt{ƒ||zllbVUVTLbVZ{tt{tt“““{{t]bZyleš””“Œ”ƒ||„„Šd\\|„…{{t‹‹‹‚|u‘Œ…Š}ƒ””‹‹’Š‹„„sletsl‹„„„Š„tll””‹tll|„…ztllek{u{{tt{{tœ¤¦Œ‹“ttsttsu{{ult›”›ttstllulttt{ddc…‹‹llkulttlltt{ƒƒ|””‹ulttsl[TTtllœ››tslƒ||›”›š””‹‹„ultztlkd\‚|ullk‘Œ…‘Œ…kk]”››‘…„UMR„Š„„Š}”š”srezll‚|uyleŠ}ƒSKJllk{ttsreVTLƒ‚uuzt{{t£››ztl”š”ƒ„„„Š„‹‹‹\[[{tt{ttŠ}|j]\{ttƒƒ|sletllzllƒ}ƒ‹„„„Š}LKRuzt‚utŒ‹“ljedk‚v{‚|uttslridc\””‹‚|u”“›{tt‚|utsl‹’Š”“›¦§¨‹„‹tslŠ~‹lksttsf]cztl]cd[TTtzl{||mtt{{ƒu{{‹’ŠUUY]cdkd\uztƒƒ|””‹lriUTS{||d\\{tt{u{‹„„yleyleyleJHFkd\red{{t{{tŠƒ}¤¤JHF*)( ””‹£››‚wl’ŒŒ“““¦§¨›¢›¢—²««Ã¼¿²¬µ²««£œ¥£œ¥Ã¼¿²¬µ””‹ƒ||“Œ””š”””‹¦§¨¤¤””‹›¢›“Œ”””‹›¢›ƒƒ|Œ”•Š}|¤¤ult“Œ”š””””‹‹‹„œ››ƒƒ|rfk””‹²««‹„„jcV{{t“Œ”‹‹‹ldd””‹”š”ƒ„„{||ƒ„„|‚z’ŒŒƒ„„ult‹‹‹j]\””‹lldldd{{tcbV{tt„„Š„Š„‚wl‹„„””‹{{tcbVSKJš””‚|ukd\j]\lld’ŒŒ{ttœ››tllƒ}ƒ™…kd\tsl‚ut¤¤tyg””‹|‚zdc\‚uttllƒ}ƒšŒtll{{t‹’Šœ¤¦ƒ„„’ŒŒŠƒ}f]csle‹„„uztŠƒ}ƒƒ|ƒƒ|rg]b[U{u{{u{lld{tt{tttts{||ƒƒ|„Š„„Š„ƒ}Š‹‹‹ƒƒ|“““ldd›”›{u{u{{””‹“““„Š„Œ”•tlllekŒ”•œ››””‹{{ƒ„Š„”“›{tt‘…„ƒƒ|š””‚v{Š}|ƒ||ztl{{tsleVTL[[Tzll””‹ŠŠ}¦§¨£œ¥‘}z“Œ”›¢›¦§¨ƒƒ|’ŒŒŠ}|’ŒŒredtsldc\‹‹„]bZldd¤¤ƒ„„{||”››ek]mtt“““|„…rfkzllultƒ}ƒ“Œ”‹„„kd\tslcbV„Š}edktll’ŒŒš””{ttuzt{{ƒd\\VTLbVUlrib[Uldddc\dc\„Š}ŠŠ}¨©´¨©´‚|uztl””‹“Œ”¤¤”“›ƒ„„{tt{{tf]ctsl{tt|‚zmttVTLdc\|„…{{ƒ{{ƒœ¤¦tt{ekdddcƒ„„{{t{||ƒƒ|d\\uztlldtlltllƒ||tllztlllkr]Zƒ}ƒŠ}ƒŠƒ}kk]{{t²²¬FD;74,¤¤“~ˆ’‘~‘ˆ}£››¦§¨š””£››£››¤¤£››¤¤¦§¨²¬µš””››”›”›œ››¦§¨£œ¥‹’Š£œ¥‹‹‹œ¤¦µ¶·””‹ƒ||‹‹„‚|u‹„„“““œ››{{t‹‹„›”›tsl‘ˆ}sre‹’Š‹‹„tts“Œ”‘ˆ}Œ‹“bVUddc™š¤Š}ƒlek„„Š‘Œ…‹‹‹|„…ƒ||””‹‚|u„„Šƒ„„››”™š¤””‹“Œ”‹„„{{ttsl£››ƒ}ƒ|‚z‚|u‹…’¢“‹‹‹[[Tj]\\[[tts‚|uƒƒ|¦§¨mtt“Œ”ult‹’ŠbVUŠƒ}VTLcbV[TTŠƒ}rfkekd\[[uzt‹‹‹j]\MRKultrg]sle{{t‹’Šƒ„„{tt{||’ŒŒtllƒ||tts‹„„ƒ||‹‹„|‚zj]\yle“Œ”“““‹„‹ƒ||Œ”•“““ƒ„„|‚z¨©´™š¤|„…llk”›››”›“““|‚z{u{””‹¦§¨d\\“““ƒƒ|ult{||ƒ„„|‚z…‹‹„Š„ƒ}ƒŠ}|‹‹„[TTƒ||‹‹„››”ƒ„„ztl{zmrg]d\\ekdztl‚wltslƒ}ƒŒ‹“ƒ||’ŒŒ‹‹„™‹†Šƒ}‚ut‹„‹™‹†Šƒ}”“›‚utdc\£››kk]¤¤„Š}””‹{{tƒ||ƒƒ|ultlekkk]{ttsleŠ}|yleƒ||[[Tek]tzltllultult‚utb[UŒ‹“lri\[[bVZ‚wld\\””‹sleultƒ„„ztl‹’Š’ŒŒ™š¤{u{ƒ}ƒ{zm‚uttll‘ˆ}¦§¨”“›™š¤„Š„ƒ„„‚|uƒƒ|tsl{{tMRK‹‹‹ƒ„„‹‹„{||{||lri{||””‹lddekd“Œ”d\\f]cddc‹‹„{tt‘…„‘ˆ}{ttcbV‹‹‹‚|u{{tšŒ‚|u‚|u‹’Š¦§¨VTL-1+””‹‹„„‘ˆ}’…‹£œ¥¦§¨›¢›£››œ››Šƒ}¢—£››£››²««£œ¥²««””‹£œ¥¦§¨¢—‹„‹ƒ„„uzt{{t››”µ¶·Œ”•‘ˆ}“Œ”Œ‹“”››“Œ”¦§¨„Š}‹‹‹‘Œ…llkdc\ƒ‚uztfsre’ŒŒrg]Œ‹“lddttsultƒ‚urfkŠ}ƒ{{t{ttƒ„„‘Œ…‹„„››”{||‹„„ƒ‚u¨©´š””{{ƒšŒ‹‹„tzllddultsleŠƒ}‹„‹Š}ƒttsVTLrfkf]c‚v{ƒƒ|lri“Œ”{||{||lld‚|u’ŒŒztlkd\ƒ„„ztl‚|u[TTdc\‚|utsltllbVZƒ||Š}|tslsre|‚z¦§¨ƒƒ|cbVkk]{||{tt›¢›{||tslƒ„„‹‹„¤¤‚|u“““ŒŒštts{||{ttuzt\[[ŒŒš›¢›‹’Šƒƒ|Œ”•lks™š¤£œ¥“Œ”ztl“Œ”“““‚|uekd‹„„{ttƒ||f]cŠ}ƒdc\{||lldmttrfkldd{ttŠ}ƒ‹‹„ƒƒ|zllŠ}|ztltllƒ||‹„„{{t{tt{{tƒƒ|“““‚|uš””kd\kk]™š¤™š¤tsl‰v|red””‹ƒ}ƒ‚|u””‹tll¦§¨ztlddclri|‚zŒŒš{||uztŠƒ}{ttzll“““‹‹„ztlddcllduzt{{ttll{ttŠ}|zllultldd{u{lldr]g{{ƒsleztl{{ƒuzt£››tsl‚|uœ¤¦™š¤{||‰|vƒƒ|¨©´²««{u{”“›“Œ”{u{{u{rfklri|‚zult‹’Š››”Œ”•“““ttsƒ}ƒVZ[ƒ„„‹„‹|‚zlritts{|||‚z]bZtslsleš””ztlŠ}|‰|vdc\llkŠ}|‚ut››”{tt|‚z¦§¨[[T*)(tll‚wl‘…„ƒ}ƒ’ŒŒ››”“Œ”›”›¦§¨£››£››£››“Œ”ü¿²««¦§¨£œ¥£››£œ¥”››£››Š}ƒŠŠ}š””‹’ŠŒ‹“Š}ƒª³·’…‹‹„„””‹ƒƒ|””‹ƒ„„{ttŠ}ƒztf„Š„””‹¤¤{zm“““ƒ‚uultb[UlldVTLrg]ultzlltsltllult£››””‹slef]cƒ}ƒ|‚z‹„„””‹œ››llkƒ„„‘…„{{t£œ¥ztlbVUŠ}ƒtll\UZJHF[TTtllllk[TTldd{u{f]c{tt{||sleulti\VVTLVTLkd\ztlekdcbVcbVƒ„„Œ‹“ttstlllddtll’ŒŒ‚ut‹’Š‹’ŠŠƒ}lddŠƒ}ƒ}ƒ‹„‹tts””‹š””šŒ‘Œ…ultƒ||{ttƒƒ|f]c{{t{{ƒŠƒ}{{ƒ|‚znv‚{u{‹‹‹‹’Š…„’›”›”“›„„ŠŒ‹“››”„Š„…‹‹ƒ||ult¨©´Œ”•{u{‹‹„ƒƒ|„Š}tts‹„‹ƒƒ|rg]{ttƒƒ|jcVSKJjcV{{tf]c£››{zmtslƒ„„tzltll\UZzllƒ||‘Œ…ŠŠ}ult‚v{‚|ušŒŠ}|‹‹„“““ƒ||ƒ}ƒ{||zllf]cdc\tsl{{ƒ‚|uƒƒ|[[T‹‹„Š}ƒ’…‹…‹‹{||Š}|ek]‰‘~|„…slef]cmttzlltllbVZSKJ{||ƒ||{{ƒ“Œ”{{t‹„„{||„Š„”š”›¢›‹„„\UZ‚v{{tt¨©´””‹‹„„””‹lek‚utztlƒ„„„„Š{ttŠƒ}VTLŠƒ}‹’Š„Š„‘…„{{t„„Šu{{ultult{ttŒ‹“„Š„“Œ”„Š„‹’Šuzt|‚zƒ}ƒ‘…„{ttb[U‚|utllyle{tt‚ut‰ƒvŠŠ}sre¦§¨D;9*)(Š}|š””“Œ”‰|v¦§¨ŠŠ}²¬µ¤¤²²¬£››””‹¤¤›”›¦§¨šŒšŒ“~ˆ£››œ››…‹‹sre‹‹„Šƒ}‘…„¦§¨›¢›šŒ”š”Š}ƒƒ||ƒƒ|‹‹„‹„„ƒ}ƒ”“›„Š„‹‹‹ƒƒ|z‚ltslŠƒ}‹„„””‹tt{‚v{‹‹„Šƒ}VTLultult‘Œ…‹„„”››“““›”›‹„„tt{“““ƒƒ|›¢›‹’Šf]c‹‹„{||‹‹„kd\ƒ}ƒsrebVUbVUult{u{\[[sleultlldƒ||b[U”“›“““Œ‹“ƒ„„tslbVUSKJFD;]bZSKJsrekd\[[Tlddd\\‹„„ztltzlƒ„„”š”ttskk]sle‚ut‚|u{tt™š¤”››œ››“Œ”‘…„¦§¨‚v‚ƒ„„£››‹„‹‹„‹ztl‹„‹Œ”•™š¤ƒ|||‚z|‚zlksf]ctt{fkklksUMRŒ”•‹‹„Š}ƒ”››tslœ››œ¤¦£››“Œ”{{ƒ‹‹‹”“›lldŒ”•›”›lekƒ‚uƒ||ƒ||lldsletslb[Uztfldd{tt‘Œ…Œ”•{{t{{tlldultcbV‚ut‚|u‚|ušŒ£››ultŠ}ƒj]\{tttts‰|vrg]tll{ttd\\„Š„uzt””‹{{tuztrg]bVZlddlddtts‚|u’…‹ƒ}ƒMRK|„…tslƒ„„rfk‚v{UMRbVZƒ„„‹‹„ƒ}ŠŠ}ƒƒƒ|{{ƒtll{tt„Š}œ››sre‹„„tts‹‹‹Œ‹““““Šƒ}f]cŠutŠ}|{{tš””™š¤“““dc\‹‹‹dc\ƒ}ƒƒ||ƒƒ|ƒƒ|„„Šddcf]cf]c‹‹‹{||“Œ”‘Œ…{{ƒŒ”•‚utƒ„„ŠŠ}‹‹‹zlltllredj]\‚|utslj]\redƒ||‹‹„ztl›¢›JHF*)(™š¤’‘~²««‚ut‹„‹£››²²¬£››””‹””‹£››Ã¼¿””‹“““ü¿””‹²««›”›‹‹‹”“››¢›£››¦§¨š””””‹¤¤tslšŒ‹‹„“““ƒ||ztl‘Œ…uztš””Œ‹“””‹“““ztl‚utkd\rfk””‹ldd‹‹‹‹„‹’ŒŒ‹‹‹’ŒŒ£››‚utJHFuzt{||””‹£››‹„„›”›””‹{||uztŒ‹“”››tzl£œ¥{{t{{ƒlrizllrg]{||lddlrijcVtts‚v{””‹ultf]cSKJ”“›tll{||Š}|{{t{tt[[TUTSVTLj]\llklddlkstts‚v‚š””Š}ƒƒ„„{||r]Zekdddc‹‹„””‹ƒ„„ƒƒ|‹„‹ƒ||ztl’…‹{||ƒ||Š}ƒj]\{tt™š¤llkuzt{{ƒ’ŒŒ„„Š|„…u{{{||{{ƒlksedk{u{”š”ƒ„„ŒŒštsl|‚z|‚ztts“Œ”¦§¨“Œ”lks{{tkd\lksttsedk{tt{u{{{tultllddc\redred‚ut{tt””‹tts¦§¨ƒ||ttstllkd\yfd””‹zll£››‚|uŒ‹“ultdc\d\\””‹‹„„‹„„{tt{u{Š}ƒ„Š„ldd{{ttts‹„‹”››‰v|lddllk{ttŠ}ƒ‹‹„‚|usre{||tsllddlek‚|uUMRultbVZtts[[T{u{ƒ||tslƒƒ|tllƒ„„“Œ”‹‹„’ŒŒ‹„„ultƒ„„ƒ||š””ultbVU™š¤{{t‹„‹Œ”•d\\[TT|„…tzlšŒ”š”fkkŠƒ}sre™š¤Œ‹“{||““““““lri‚|uldd…‹‹{||‹‹‹{||ƒ||Š}|{u{‚wl{zmtlld\\‚ut‚wl‰v|rg]rg]¤¤FD;74,””‹‘}z£››j]\’ŒŒ¤¤Ã¼¿£œ¥²««™‹†²¬µ‹„„£œ¥œ››””‹£››šŒ|‚z‹„„””‹‰ƒvŠƒ}””‹¤¤¦§¨µ¶·››”’ŒŒƒ||{{tsle””‹››”š””’ŒŒllk‹‹„{{t›¢›ƒƒ|ƒƒ|{tt‹‹„tt{{tttts{zmztlƒ||£œ¥tllƒ||‹„„”“›œ››‹’Šƒ}ƒƒ||‹‹‹’ŒŒ|‚zlddtts[[T‹‹‹{{tƒ„„tzlkd\{tt{u{[TTd\\[TT‹„‹ƒ}Š{tt{{tŒ‹“ddc™š¤ƒ„„[TTd\\ekdrg]kk]bVZllkldd[TTtzllritllš””‹‹„“Œ”[[Td\\b[U{{t{tt›¢›{{t‹‹„‹„‹ttsŠ}|Š}ƒƒ}ƒ‹„„ƒƒ|‹„„{u{‹’Šƒ||“Œ”ƒ„„u{{{{tƒ„„llkƒ„„tt{{{ƒ…‹‹|„…“Œ””››„Š„ƒ}ƒtts„Š„„Š}ƒƒ|ƒ„„‚v‚””‹tt{Š}|{u{tll{u{{u{ƒ}ƒƒ||›”›››”llkdc\red‘}zf]cƒ}ƒ’ŒŒ{||‹’Š‚ut{{tUTS‚|utllsre‹‹‹‘Œ…ylettsŠƒ}‘Œ…ƒƒ|yfd{{tƒ||sleyflƒ}ƒŒ‹“{{tŒ”•‚ut‹‹„ƒ}ƒ{{ƒƒ||‚v{{u{Šƒ}“Œ”‚v{„Š„‹‹‹VTL‚v‚{{ƒ””‹edktllf]c‹‹„[[T‹„‹››”slelddllk””‹››”{zm‹„„“Œ”””‹u{{¦§¨””‹ultztlrg]{zm{{t|„…„„Štll{{t|„…²««…‹‹]bZ‹‹‹…‹‹tt{”“›|‚zlek|„…Œ”•ŠŠ}ddclekd\\kd\llkddc{tt‹„„Š}|uztldd\UZf]cŠ}|‘Œ…‰ƒv‹„„””‹>B93+*ƒ||‘…„£››£››”“›µ¶·Ã¼¿š””””‹‘ˆ}¤¤¦§¨£››”“›²««š””ª³·Š}||‚z¤¤›¢›£››¦§¨‹‹„”“›””‹¦§¨¦§¨œ¤¦tt{ƒ‚u‹„„‰‘~’ŒŒ‘…„’ŒŒ‘Œ…‹‹‹››”””‹lld{ttkd\tts‘…„{ttlldj]\tll’ŒŒ£››ƒ„„‚v{f]c‹„„tsl{tt‹„„ƒ„„{ttrg]ddctllƒƒ|šŒ”“›ƒ„„”š”Š}|’ŒŒ›”›llkiWU]bZtlluztœ¤¦tsl{{t{||ultlekdc\Š}|JHF{||ƒƒ|ttsƒ„„rfktllJHF{||‹‹‹‚v{srellkddckd\b[Utslslekk]d\\{||ƒƒ|lekyleztl’…‹Šƒ}ddctts›”›„Š}Œ”•‹‹‹‹„„u{{uzt|‚zƒ„„Œ”•‹„‹œ¤¦…„’…‹’™š¤uztddc\[[|‚zƒƒ|„Š„‹„„ƒ}ƒ\[bf]clks“Œ”lddƒ||ƒ}ƒœ¤¦ƒ}ŠŒ‹“…‹‹œ¤¦“Œ”‘Œ…„Š}œ››ƒƒ|j]\‹‹‹lld””‹i\V{{tzllkd\ldd„Š}ƒƒ|i\Vƒ||llktlllld{||llkŠ}|b[UbVU‚utbVZ‹„‹{ttsre‹’Šttszllƒ}ƒult‹„‹ƒ||{ttŠŠ}lek{{tƒ}ƒ[[Tddcttstlledktll{{ƒƒƒ|¦§¨Œ‹“Š}ƒsrecbV{{tsre™š¤u{{kk]‘Œ…ƒ„„Œ”•£››£œ¥tll‰|vzll‚|uƒ||ƒ||ult{ttƒƒ|‹‹‹‹’Š„Š„‹’Šµ¶·{||{||Œ‹“Œ”•“““ƒ‚n{u{Šƒ}ultƒƒ|tsld\\rfk„Š„Š}|{zm‹„„tll{zmŠ}|zllyleztlkd\kd\””‹:97*)(ƒ„„‹„„Šƒ}¦§¨¤¤²¬µ£››£œ¥š””²¬µ ¦§¨¦§¨£œ¥£››’…‹šŒ›¢›ƒ‚uƒƒ|””‹››”””‹£››«²«¦§¨£››ƒ„„’ŒŒ‹‹„ƒ||’ŒŒztf{u{yfd‚ut”š”„„Š‹‹„£››{zm‹„„ƒ‚ulddšŒ‹‹‹tsl‚v{ƒ}ƒœ››Šƒ}…‹‹Š}ƒ’ŒŒllksle{{ƒ…‹‹„Š„ƒƒ|ƒ‚uldd„Š„ŠŠ}››”Œ”•‹‹„tzl‚|uddcƒ„„lriƒƒ|FD;d\\u{{]bZllkd\\rfklddlddsrezllSKJŠ}ƒtsl|‚zsleVTLtsldc\ƒƒ|lddsleVTLzll‹‹„lld’…‹››”rg]sre‹‹‹ldd‹„„ultd\\{u{ƒ||‹„„{ttŒ‹“‚|uztlƒ||‹„‹‹„‹mttllk|„…{{ƒœ¤¦|„……‹’ƒ}ƒŒ”•Œ‹“ƒ||œ¤¦ddcŒ‹“lriuzt‹‹„{ttlkslekUUY‹„‹ƒ}Šƒ||‹„‹‹„„kk]ldddc\‹’Šƒ}ƒ‹„„š””‘Œ…š””’…‹tllsrekd\bVZultlld‚v{bVZbVZœ››lddlriŠ~‹kd\‚v‚Šƒ}{{ƒƒƒ|Š}|f]c›”›lddultœ››ldd{||llkd\\kk]‹„„{u{‹‹„‚v{ƒ||ƒ||ƒƒ|{||tsl{u{‹‹‹VTL{zmbVUddctts„„Š™š¤lriztltllUTSš”””“›””‹››”ulttsl…‹‹š…Ž¦§¨Œ‹“‰|vttsrg]ƒ||tsl‚v‚ƒ||›¢›kd\[[T„„Š‹’Š¦§¨£››£››œ¤¦Œ”•“Œ”‹‹‹{{ƒ’ŒŒtllƒ„„ƒ„„ƒƒ|lekƒ||{tt‰|v‚utztfzllsle‹„„ƒ||kd\‚wl‹‹„¤¤:97*)(ldd‹„‹Šutš””œ›››”›š””£››‘ˆ}¢“‘ˆ}£››™š¤¦§¨£››µ¶·£››¦§¨{{tƒ‚u¦§¨””‹‘Œ…‚ut¤¤”š”œ››‚|uƒ||ƒ}Š¤¤””‹š””tts‚wl‚v{{{t“““‚|u‹‹„›¢›“Œ”‚|u‹„„’ŒŒ„Š„š””””‹“Œ”Š}|sle{||f]crfk“““{{tƒ||ƒ}ƒ«²«‹‹‹zll‘Œ…{||‹’Š¦§¨›¢›Œ”•d\\rg]redldd…‹‹ztlllkf]cŠ}ƒrfk[[Ttll‘ˆ}tt{j]\VTLkk]lldslettslridc\ƒ||tll„Š}dc\‹„‹tyg|„…ztllddj]\mtt{zm‚ut””‹{{t‹’Šš””ƒ||f]c‚v{tlllddd\\’ŒŒ‹„„ƒ}ƒŒ‹“ƒ„„›”›ƒ„„ƒ}ƒ„Š„ekdŒŒš|„……‹‹{{ƒtt{“““„„Š|‚z{u{””‹‹’Š‹‹‹„Š„tlllek{||Š~‹{{ƒ“Œ”‹„‹™š¤{{tllkleksle›¢›””‹|‚z‹„„sle‚|u{ttllklriredkk]VZTzllredbVZ[[T{{t{ttƒ}ƒultddc{ttƒƒ|””‹Šutredrfk‘…„{u{ƒ„„{{ƒ{||ŠŠ}lriztl]bZ\[[‚ut‘Œ…“Œ”VTLƒƒ|lld“Œ”lriddctsl{zm[[Tf]c„„Štsl{ttƒ}ƒš””””‹‹„„‚v{“Œ”„„Š£››‘…„lek{||bVZ‹„‹‘Œ…™š¤Šƒ}{u{ztl‹„„{{tš””kd\‹‹„uztuzt|‚zƒƒ|š””{{ƒ“Œ”|„…|‚z…‹‹œ››tt{‚ut{||{{t{zm‹„‹lldlldd\\sletll‚|u‘…„zllldd‘…„Š}|yleƒƒ|Šƒ}>B9&&‹‹‹£œ¥“Œ”‹‹‹›”››”›››”£œ¥¢“¦§¨Š~‹{tt“Œ”¦§¨£œ¥²««£›››¢›ŠŠ}‘Œ…š””ƒ‚u£››œ¤¦«²«{{tœ››ƒƒ|ƒ||¦§¨‚ut¤¤””‹’ŒŒrr]redtsl{u{tsl£œ¥ŠŠ}ztl¤¤Œ”•’ŒŒ‹’ŠŠ}|’ŒŒ{{tŠƒ}{{t{||‹‹„zllš””sle“““‹„„Œ”•ƒƒ|tllŠƒ}‹‹‹Šƒ}ultƒ„„{tttllsle’ŒŒultllksretts‹‹‹„„Škd\\[[tllf]c‹„‹sreztl‹„„d\\tts”š”‹„‹””‹tllŠƒ}{{tVTLUTS[[Tlldztlkd\b[U{||ŠŠ}kk]ekduztƒ||kd\lddlkszllƒ||“““{ttkd\‘Œ…‹’Šu{{“Œ”{{ƒ””‹ddcek]lks|„…”››…‹’mtt‹„‹Œ‹“|„…edkƒ}ƒ‹‹‹|„…ƒƒ|‹‹‹š””{u{„„Š““““Œ”ƒ}ƒ£œ¥ddc{||‘Œ…ƒ||“Œ”””‹“~ˆcbVkk]tllkd\“Œ”f]clrib[U‹‹‹ƒ||”››j]\ztf{||{u{{zmƒ||ldd{ttƒƒ|‹‹‹ƒ‚ud\\Š}ƒƒ||rfkŠƒ}‚|utslttsœ››‹’Š{||tslkk]ƒ}ƒ‚ut‹‹„{ttredsrej]\‹‹„ttsUTS”š”tts’ŒŒ{u{{||£œ¥“Œ”‹„„¤¤{tt›”›’ŒŒ””‹Š~‹ultŠ}|uzttts™š¤zll{||‚|u“~ˆ{zmztlƒƒ|£œ¥zll””‹srelriƒ}ƒ‹„„Œ”•¨©´¦§¨|‚zekd“““‹’Šekdslellkldd‚|u‚|uƒƒ|tzl“Œ”‚|u{zmƒƒ|‘Œ…{tt‘ˆ}‰|vredkk]i\V””‹D;9*)(››”œ¤¦””‹{{t“““œ››¦§¨“Œ”‰|v£œ¥””‹‘…„£››£œ¥£œ¥“Œ”£››|„…‹‹„ƒƒ|¦§¨š””Šƒ}ƒ„„ƒ‚u››”‹„„œ››‚|u‹„‹‚utztl‘ˆ}‹‹„„Š}yleb[U[[Tzllf]czllŠ~‹{ttult‹‹„””‹š””tsl{u{kd\{tt|‚zš””kd\”“›‹„„š””ƒ||Œ”•£œ¥zllƒƒ|›”›‹‹‹‹‹‹ƒ„„ultlldzll‰|vŠ}|sledkV‚v{dc\Œ”•dc\{ttƒ||ƒ}ƒ“““lridc\kk]mttSKJ‹’Š{{trfk“““FD;sre{{ttll{{t|„…[TTb[UsleŠƒ}b[U{{tsreƒ||tll{||‹’ŠtllŠ}ƒŠ~‹‚v{‹„‹ƒ||š”””š”‹‹„“““tt{lldultuztmtt{{ƒ{{ƒ{{ƒlrilksŒ”•‹’Š|‚zŒ‹“{u{‹’Šuztultƒ||ƒ}ƒœ¤¦ttsldd‹„„lks”“›{u{‹‹„Œ‹“{{t‹„„‰ƒvu{{{u{ƒƒ|Š}ƒ’…‹Œ”•‹’Šyle{||tsl{{ƒztlkd\d\\f]cuztŠƒ}tzl{||””‹›¢›œ¤¦””‹bVUrg]ƒ}ƒ‹‹„‰|v{tttslkd\ŠŠ}‹‹‹ƒƒ|ƒ||“Œ”{u{{ttrg]kd\[[Tlldtsl]bZult””‹››”{tt{{ƒ‹’Šsle›”›ztlztfš””ƒ„„š””””‹‹„„ztl‚utƒ}ƒ…‹‹ƒ||²²¬”“›‚|u“Œ”ztlsle“““Š}ƒ‹‹„lekœ››|‚z‚wlŠŠ}tll‹‹‹„Š}ek]{||™š¤„Š„{||‹‹„ƒ„„tsl‘Œ…ƒ||{||{ttƒ||JHFŠƒ}i\V‹„„ŠutztlŠ}|‹„„‚wlred²²¬FD;*)(„‰v““““““£››£››¦§¨£››£››šŒ‘…„²¬µ£››¤¤››”²««²¬µ²¬µ¦§¨ƒƒ|‘ˆ}‚ut¢—’ŒŒ’ŒŒ‹‹‹“~ˆ‚v‚”š”£››‹„„ldd£››››”“Œ”‹‹„{ttƒ‚ubVUš””{||tsltll{{t{||‹‹„„Š„‹‹„‹’ŠŒ‹“ult››”uztttsƒ‚u’ŒŒŠ}|{tt’ŒŒƒ„„{||‹‹„‚|u’ŒŒ„Š}”š”””‹lri‹‹‹Š}ƒsleldd›”›Šƒ}FD;{||ult|‚zƒ}ƒlri{ttttsllkekdu{{lldb[Ulri‚utUTStygtll„Š„sreuztŠƒ}„Š„ztlsre[TTaWM|‚zztl‹‹„rfklldƒ||ŠŠ}tllƒ}ƒ£››‹„‹tllš””ƒ|||‚zƒ„„‹„‹lks„„Šlrilek]cd|„…”“›|„……‹’lkstt{Œ”•Œ”•Œ‹“ƒ}ƒfkkllk{ttultlek“Œ”„„Šƒ„„sle£››{{ƒ“Œ”›”›£œ¥{{t{{t|‚z„Š}{u{‘Œ…ultrfktsltt{rg]lld‹‹‹‚utUTSzllyleslekk]{{t{||lddƒ„„ƒ„„““““““’ŒŒ‚utlekf]c{u{{u{r]gƒ||ƒ||{||ƒƒ|Šƒ}‹…’tllredtzlsleVTL|‚z{{ttllŒ”•‹‹„‹‹„ƒ„„ttsllk{tt‚v{œ››ƒ||””‹‹„„¦§¨‹„„£››£››¦§¨ƒ„„]bZ{{ƒ„‰v™š¤¤¤™š¤£››ulttslƒ||Šƒ}tsl{{t‹‹„Šƒ}ŠŠ}mttmtt“Œ”£››“““u{{‹’Š›”›””‹{{t‹‹‹lddlldtzlllk{ttj]\‹„„lddsleƒ||‚|uztlsletslrg]¦§¨JHF*)(’‘~{{t‘ˆ}²¬µ£œ¥²««¦§¨“““£››šŒ£››£œ¥¤¤‘…„²¬µ£››šŒ‹‹‹ŠŠ}‘Œ…‹‹„‚|uzll›”›››”£››Šƒ}‘Œ…‹‹„{{t™š¤‹‹„Šƒ}ƒ„„‰|v’…‹|‚zŠƒ}‹„„’ŒŒ„Š„{||srelri‹’Š‹’Š””‹„Š}„Š}ƒ}ƒ‚|u…‹‹‹‹„’ŒŒ‹‹„|‚z{{ƒŠƒ}{{t™š¤yfl””‹Šƒ}sle„„Š””‹llkŒ‹“””‹r]ZbVZ“““““““Œ”“““ƒ„„ƒ„„Œ”•llkred{ttddc[[Tlld‹‹„Šƒ}lldlldƒ||tzltll[[Tddc{||rg]dc\b[Usreslesleƒ‚nsreŠŠ}{{ttllƒƒ|lritzl””‹²¬µ‹„„zlltllƒ}ƒŒ”•tts{{ƒult„„Š]cd|‚z{{ƒ|„…Œ”•|„…u{{Œ”•…‹‹|„…mttlriultuzt{{ƒultf]clks\[bmtt›”›’ŒŒultŒŒš‹‹‹ƒ„„lddztldc\kk]‹‹‹{tt‚utƒ}ƒ‹„‹llkddcƒƒ|””‹Œ‹“sre{tt‚utzllztl{{ƒ{u{kd\d\\ƒ„„¦§¨‚ut{u{¤¤š””‚utred{tt{||ztltllkk]\[[¤¤lriŠƒ}ultŠƒ}uzt‚wl|‚zmttŒ”•Š}ƒtt{’…‹””‹£œ¥mtt]bZ„Š„Š}ƒttsŠƒ}‘…„‘Œ…š””sre™š¤””‹µ¶·tts{u{{||¦§¨œ¤¦š””››”“Œ”“““„Š„‹„‹””‹‚v{ztl››”[[T‹‹‹‹„„‹‹‹‘ˆ}z‚l”››ƒ„„…‹’‹„„„Š}lldttscbVlldttssrerg]sle{{t‚utztl‚|ui\V‘…„zllƒ‚utll””‹JHF!””‹”š”›”›œ››²²¬¦§¨²¬µ£››‘Œ…””‹š””‹„„£››’…‹Â¾Æ£œ¥£››“Œ”ƒ‚u£››œ¤¦’ŒŒŠƒ}£œ¥{{t‘ˆ}{tt{{t„„Š‹’Š””‹’ŒŒœ››””‹””‹’ŒŒttsztl””‹‚|uƒ„„{||‹„„™š¤ƒƒ|lldŠƒ}tsldc\dc\kk]tsl›¢›ƒƒ|‚ut£››ƒ||ƒƒ|„Š„‹„‹Šƒ}””‹zllllk‹„‹œ››{u{{tt‹„„b[Uš””ƒ}Š{{ttsl{{ƒ„„ŠlribVZlritlllriVZTUTStlluztf]c„Š}ƒ„„‹‹‹mtttslkd\ƒ||‹‹‹‰ƒvuztyle››”‹„„šŒ{zm{u{JHFƒ||‹‹„|„…ƒƒ|“““{zm“Œ”¦§¨œ››|„…”››„Š}„Š„{{ƒ“““|„…|„…‹‹„…‹’lkslksekd“Œ”}‡’™š¤|„…„„Š„†™‹„‹fkk„Š„dc\ult‹‹‹tt{ƒƒ|lddd\\tsl”“›{u{œ¤¦tts‚|uVTLƒ‚nƒ}ƒ‹‹„ult£››f]cult|‚z‘Œ…ƒ„„lks{{ƒƒ||ztl‚|u{{t„Š„lekttsldd”š”Œ”•{||‹„„‘Œ…lddrfkbVZdc\{{t››”””‹u{{tll{{t{ttƒƒ|ŠutŠ}||‚zŠ}|ƒ‚uŒ‹“{zmkd\u{{ztlrg]ƒ||llk›¢›ƒ‚uƒ}ƒ‘Œ…’ŒŒŠ}|ƒ||Šƒ}¤¤£››š””“Œ”{ttlri’…‹””‹‹„‹””‹{ttŠ}|²««“““‹‹‹‹„„Š}ƒ„Š„{||‘Œ…sre“Œ”{{t‹‹‹|‚z””‹{{tƒƒ|ƒƒ|sletslŠƒ}{{t{{tztl[[Tƒ‚u[TTsleultb[UztlŠƒ}ƒƒ|{ttŠŠ}‚v{ult>B9*)(””‹¦§¨””‹ƒ||‹‹‹²««²««£››¦§¨¦§¨”š”¦§¨¤¤›¢›¤¤¦§¨¦§¨¤¤””‹””‹”››¤¤‚v{‹‹‹‚v{zll‹„„tts’…‹“Œ”“““””‹£››“Œ”’‘~‹„„dc\lekyle‚v{’ŒŒ{{ƒ‹‹‹{{ƒldd{||’ŒŒ{{td\\[[Tuztllkƒ‚n””‹£››‘Œ…ƒ}ƒƒ‚uldd“Œ”œ››¢—sle|‚z£œ¥ƒ„„ztlƒ„„ƒ‚u‚|uƒ||tts|‚ztts‹‹‹œ¤¦{tt„Š„‹‹‹‚|uƒ„„{{t[[T””‹\[[ƒ||‹‹„ƒƒ|ldd‹‹„Š}|ttsƒ||ƒƒ|Š}|slesle””‹jcVƒ||kd\‹‹„tzlttsƒƒ|ƒ„„ƒ‚u£››‰|v’…‹“Œ”ƒ}ƒ‹’Š{tt{||‹‹„{{ƒ„Š„ƒ„„{{ƒ…‹‹ƒ}ƒŒ”•{{ƒtslmttmttŒ”•mttmttuztŒ‹“\[b\[[{||lddƒ„„lekultult’ŒŒ„„Š|„…rfkœ¤¦‹„„{ttlddƒ„„”š”œ››dc\ƒ}ƒ“Œ”tsllldttsldddc\[[Tlld‘Œ…‹„„lld{{t{{ƒ[[TbVUkd\tts„„Šldd‹’Šedkzll\UZd\\tll‹„„{||uzt””‹“““‹’Šlriultzll\UZ{{ttyg[TTMRK\[[llk\UZŒ‹“{ttult‹’Š¦§¨¦§¨‹„„‹‹„ƒ}ƒ‚wlkk]››”‘…„µ¶·’…‹™š¤‹…’ƒ||‹„„‹‹‹£››’ŒŒ’ŒŒ£››™š¤ttsztl‘Œ…‹’Šdc\{{tƒ‚ulld››”ƒ||tzl|‚zŒ”•{zmkd\ƒƒ|lriiq]lldtllsrebVU{zmztl‹‹„ztlŠƒ}‚|u””‹tllyleŠƒ}“““”š”D;9*)(‘Œ…‹‹„£››’ŒŒ›”›“Œ”²««£››£››‘Œ…”“›ŠŠ}‚wl¦§¨µ¶·£››£››ƒƒ|«²«””‹‹‹„‚wlƒ||””‹kd\„Š„{{t{||{tt{{t£››¤¤ƒ‚u„Š„››”{||{{trfkrg]ƒ}ƒ””‹Š}ƒ{{t{u{‹’Š‹’Š‚wlƒƒ|{tt{u{„Š„d\\ƒƒ|¤¤š””˜Ž£µ¶·’ŒŒƒ‚u‹’Šztlƒ‚uƒƒ|ƒ„„ztlƒƒ|SKJttssle“Œ”Šƒ}bVU[[Tultllkult„„Šlksƒƒ|ƒ„„llk‚|u[[Td\\tts|„…ƒ‚u{{t‚|u‚|u“Œ”„Š„‹‹‹‹’Š‚|u{{tf]c””‹’ŒŒ‘…„sleƒ||{{tsleztl””‹lld‚v{ztl“Œ”””‹tsl”š”tll‹‹‹™š¤edklld{{ƒ{{ƒ|‚z…„’›¢›tt{…„’|„…mtt{{ƒmttu{{{||‹„‹{{ƒllduztd\\\UZlks[[Tf]clld{u{llkŒŒš{{tldd››”cbV”š”‹„„ultlddultƒ||ƒ}ƒdc\{{t{tt[TTUMR{ttb[UmwVTLrfk{u{VTLSKJ{tt{{t‚v{‚v‚red„Š„ldd[TTtsldc\|„…‹‹„„Š„””‹šŒƒ„„‚utsle‘}z„Š}ekdllkllk„„Šldd{||’ŒŒ£››ƒ„„{{ƒuzt””‹‹‹„Šƒ}sre‹„‹Š}ƒ²««²²¬£››£››‰|vlekllk’ŒŒ‹‹‹‹‹‹‹‹„Š}|zll‹„‹ƒ}ƒ’ŒŒ‹„„ƒ||‹„„ttsƒƒ|£››Œ”•›¢›{{t„Š}„Š„|„…ztl‹„‹b[Uƒƒ|{tt‘Œ…{||{{tlddtts‹‹‹‚|u‚utztlƒ||’ŒŒ‚ut””‹ƒ||‚wlŠƒ}:97*)(››”¤¤²««£œ¥µ¶·š””””‹‘Œ…š””µ¶·µ¶·š””«²«²²¬£››¦§¨¢“ƒƒ||‚zƒ‚u‹‹„¦§¨£›››”›‹‹„tll””‹‹‹„œ¤¦{||¢“’ŒŒ¤¤tts‹‹„ƒ||‘Œ…f]cultttssleb[U’ŒŒ‚v‚ƒ‚u‹’Š“Œ”››”]bZ[TT|‚zddcb[U|‚z›”›‚|u‹„„‹„‹ƒƒ|tslŠƒ}kd\{zm‹‹‹‚v{ª³·ƒ||llk’ŒŒ›”›lddsleŠƒ}‹„„›¢›ult”“››”›ttsb[Uƒ}ƒcbV„Š}‘Œ…Œ”•ƒ||‹‹„tlli\VVTLSKJkd\‹‹‹tll{{t‚|uyletll‚|u‘ˆ}‚|u‹„„tslsle{||b[U’…‹””‹{tt‘…„‹„„tsltsldc\{u{{ttlks‹‹„{{ƒ{||uzt{{ƒ›¢›mtt„„Š|„…Œ—£mtt|‚z|„…|‚z›”›|„…{||llk{ttlek{||{{ƒd\\bVZbVZ{u{£››|‚zƒ}ƒ””‹‚|uƒ„„ƒ„„z‚lult‹‹‹‹‹‹tlluztdc\redUTSztf›”›kk]SKJƒƒ|‹„‹lekkd\f]ctllVTLmttd\\tslƒƒ|”“›ƒƒ|‚|u\[[””‹“Œ”‹’Š“““£››‹‹‹kd\{||‹„„{tt‹„„sle‹„‹ƒ}ƒldd„„Š{{ƒ‚v{ƒ}ŠlksmtttllsleultztlultUMRldd””‹’…‹“““‚utllkuzt™š¤tts“Œ”£œ¥’ŒŒ¤¤£œ¥ƒ„„‹„‹šŒzllsre‹‹‹ƒƒ|››”””‹Šƒ}‚|uŠƒ}„Š„ŠŠ}“““lddztfsre‘Œ…ƒƒ|ƒƒ|]bZredƒ||ƒ‚u{{t‹„„‹„„‚wlztlztlšŒƒ||tsl‚wlJHF*)(£››¦§¨ÃÄƵ¶·¦§¨‹„„£››šŒ‘…„£››²²¬¸Á¹””‹µ¶·£œ¥š””Šƒ}¦§¨””‹ƒ‚u‹‹„‰|v“Œ”“““›”›£››’ŒŒ‚|uƒ}ƒ›”›‹„„yleŠŠ}ƒ„„’ŒŒ“““’…‹“Œ”£››„Š„ƒƒ|‚|uuzt‹„‹’ŒŒ””‹””‹››”mtt{{td\\ƒƒ|‚|uŒ‹“£››Šƒ}{zm‚|u‹‹‹ƒƒ|‚|uŠƒ}ƒƒ|„„Š”š”{||f]csresre‘Œ…Š}ƒultllksle{||ultultuztlldd\\{u{VTL]bZ{{tsre“Œ”‘Œ…{zmƒ}ƒJHFSKJdc\dc\‚|uztf[[Ttllkd\‚|u””‹ƒ||Šƒ}Šƒ}lldkd\ztlj]\‹„‹‘…„{tt‘Œ…tsl{{t{ttttstllddclddlekmttu{{mttœ¤¦|„…tt{{{ƒŒŒš{{ƒttslks“““²¬µtt{Œ”•|„…”“›Š}ƒ‹…’“Œ”ƒ||ttsf]cƒ}ƒbVZylelri¤¤|‚zsre{||kk]’ŒŒ{||‚|uldd„Š„|‚zkd\rg]‘Œ…œ¤¦‰|vsreztl‹„‹rfkƒƒ|Šƒ}‹„‹rfk“““ztlkk]b[U‚|uƒ}ƒzlltlltllf]c”š”{{t‹‹‹„„Šrfkrg]rfk””‹uzt|‚z„Š}{u{leklektlllekƒ||ttsmtt£››‹’Š‚utŠ}|‚v‚zll’ŒŒƒ‚nllkŠ}|‹„„‹„‹ult™š¤f]c‹‹„””‹Š}|‘Œ…‹„‹lddšŒ‹‹‹£››tsl{u{‹’ŠŠƒ}””‹‹‹„Šƒ}tll„Š„{||Šƒ}‹„‹¤¤‚wlŠƒ}{{t[[Tdc\tll””‹tslŠƒ}‚|uƒ||‚|u‘ˆ}{tt“~ˆ’ŒŒ‹„„ztlD;9*)(£›››¢›²¬µ¦§¨²««¦§¨²««²««£››’…‹µ¶·²²¬‹’Š””‹››”£œ¥šŒ‹’Š¤¤«²«››”ƒ‚u£››‹‹‹‚ut››”‹„„‹’ŠŠŠ}lld’ŒŒ’ŒŒ¦§¨‚wl{tt{u{zll’ŒŒ{{t‹’ŠttsŠ}ƒMRK‹‹‹sre|‚zŠ}ƒ‚|udc\‹‹‹¦§¨‹‹„››”‹’Šƒ||{{tlriƒ‚u‹’Š‹’Š‚utŠŠ}‚|utsl‹‹„››”Š}|“““ƒ||zllƒ||ƒ||ztld\\ddcsre„Š„\UZ{{tƒƒ|Š}|‹‹‹ƒ‚u{{t‘Œ…””‹‹‹„dc\j]\f]cVTLsleƒ„„lddttsuztŠƒ}ŠŠ}b[Utll‰|vyleztlkd\kd\‚wlf]ctsl‘Œ…Šƒ}Šƒ}d\\ƒ||Š}ƒƒ„„{ttllk“““ƒ„„„„Štts{{ƒn…{{ƒƒ„„mttŒ”•lkslksultlek„„Š™š¤|„…mtt’ŒŒtt{ult]cd‚v{bVZ{tttt{tsllld{{tz‚l{{t‹‹„ƒ‚utsl’…‹f]cj]\llk{{tŒ”•””‹{{t‚ut{{t‹„„‘Œ…ƒ‚u{{tlek{zm‚|urfklks…‹‹„Š„ƒ||kd\Šƒ}ƒƒ|SKJf]ccbVƒ||sre›¢›lddƒ}ƒƒ„„slesletsl‘Œ…‚|uzllttsult””‹‹…’“““lriekd”››œ››|„…„„Š{tt“Œ”ƒ||£››¤¤‹‹„š””{tt{||{ttƒ„„rfkƒ||‹„„Š}ƒ{u{Šƒ}‹„‹tll‚|ud\\‚|u[[Ttsl‚|usrekd\lldŠƒ}œ››‹’Š››”lldrg]ƒ‚u‹‹„‹’Š‹’Šƒƒ|‚v{””‹kd\ƒ||r]Zš””sle‚|uredredVTLcbV£››FD;*)(¢—¦§¨£œ¥’ŒŒš””šŒ£œ¥¼À¯µ¶·¦§¨¦§¨¦§¨¤¤²²¬‰|v£››¦§¨››”›¢›{zm{{t‘ˆ}Šƒ}››”{{tƒ‚u‹„„‚|u{u{¦§¨£œ¥››”‹’Šƒ||‹„„{{taWM’ŒŒœ››llkƒƒ|ƒ„„{{t‹„„”š”‹‹„redllk{||„„Š‹’Š‚ut¦§¨›¢›{ttŠƒ}tzlSKJJHFVTLš””{tt››”{zm””‹‹‹‹b[U|„…£››ult{tt‚utldd[TT””‹ult{ttd\\slej]\kd\|‚zƒ‚udc\slelddkd\f]ctslb[UJHFƒƒ|tts{u{””‹dc\{tt‚|u‘ˆ}llk‰ƒv‹„„‹‹„””‹ttsƒƒ|lddƒ„„””‹tts{{ttslcbV‹„‹””‹ƒ||{{tƒ}ƒtts…‹‹…‹‹lks|„…|„…{{ƒ{{ƒŒ”•VZ[]bZfkklksleklkslrimttƒƒ|\[[\UZUUY{ttldd{u{‹‹‹›”›„Š„{{t””‹cbV‘…„‹’Š[[Ttllultldd{||sretsl‹‹„tts‹„‹{zmkk]lldƒ}ƒƒ||{||ƒ‚ušŒd\\‹„„tll|‚z‚v{kd\b[Utzlu{{tsl|‚ztslƒ||‹‹„tll„Š}{{tkd\‰|vVTLlldslelri{tt{u{ƒ„„‹‹‹lksmtttt{|‚z¨©´œ¤¦”š”ƒƒ|›¢›Šƒ}ƒ||{||tsl{tt‘Œ…›”›ultƒ}ƒ{||uzt“Œ”kd\ƒ||Š}|Šƒ}‹‹‹bVU{ttd\\ttstslƒ‚uuzttslƒƒ|{||{{tuztf]cult{zmzll‘Œ…””‹uztŠƒ}ztl””‹rg]d\\j]\tllrg]rg]Š}|ƒ||{{tztl¦§¨UTS*)(¤¤¤¤£››šŒ“Œ”¦§¨²««¤¤¦§¨¤¤¤¤¸Á¹””‹›¢›šŒ²¬µ™š¤””‹›¢›‘ˆ}‚|u{ttrfk{{tœ››’ŒŒ£››ztl‹‹‹‘Œ…“Œ”tll{{t‹„„‹‹‹{||rg]{{t{||zll|‚zƒ||ƒ„„tts{||š””‹„„{{t\[[llk‚|u”“›š””””‹›”››”›ƒ„„Š}||‚ztyg‚v{ttsj]\“Œ”¦§¨‘Œ…Š}|Œ‹“‚|u{u{bVUztlŠƒ}VTL]bZldd„„Šllk\[[UMRtll[[Ttsl{||›”›dc\{zmlrij]\tll{zmtsltlldc\{{tztlŠ}ƒ{ttkd\VTLlldbVUb[U{{tŠ}|Šƒ}rfkŠ}ƒƒƒ|‹„„”š”‹„„››”‹„‹ƒ„„VTLsre{{ƒ|„…tt{Œ‹“|„…Œ”•„Š„{{ƒllk…‹’nv‚{||mttd\\{{ƒfkk|„…ttsf]cUTSlks\[[bVZƒ}ƒ‚v‚‚|u’…‹”š”Šƒ}‰‘~sreƒƒ|llk{{tttsllkd\\ztllri[[Tƒƒ||‚z‹„‹„Š„„Š}sreŠ}ƒƒ}ƒƒ„„dc\tllf]c{ttŠ}ƒƒƒ|tts‹„‹{{ƒ{u{„Š„”“›sle{{t|‚zŠƒ}{{t{{ƒ{{t[TTtllVZT[[Tƒ||{||ƒƒ|bVU{u{llk‹„‹…‹‹”››‹’Š‹‹‹œ››¦§¨|‚zu{{ƒ||£››’ŒŒ‹‹„¦§¨{||\UZ{{ƒlri‹„„”š”zll””‹zll¦§¨““““““sle‹‹„“Œ”tts››”{tt‹‹‹‹‹„‰ƒv|‚z{{tlddj]\ztl{zmslesleƒƒ|ƒ}ƒ‹„„’ŒŒztltsl{ttSKJlldek]‰ƒvƒ||sle‚utsle²««SKJ*)(‘ˆ}“Œ”²««›”›ÃÄƨ©´£››™‹†””‹””‹””‹›¢›¤¤””‹£œ¥¦§¨”››‹‹„Šƒ}{zm{zmtllŠ}ƒƒ||ƒƒ|›”›„Š„‹‹„tll‹‹„‹„„Œ”•’ŒŒ“““{u{„„Šlld[TTlrisleƒ„„‹‹„‹‹„Š}|{{t¤¤¦§¨|‚z‹‹‹’…‹ek]{tt››”‹‹„ƒ}ƒ‚|u„„Š‹„„sle{{tldd‘Œ…¦§¨¦§¨£››zllš””‹‹„{tt‹„„ƒ||{ttkd\{u{{{tttsttsƒ}ƒlldSKJ]bZuztkd\tslŠ}ƒ{{ttllVTLd\\[TTD;9{{tlld‚v{sre{||‹„‹kd\ztldkVkd\‹„„ƒƒ|b[U{{t””‹ƒ}ƒ‹’Š””‹¦§¨‹„„ztlƒƒ|’ŒŒ{{tlrisle‹‹‹ƒ„„Œ”•œ¤¦lksmttmtt{{ƒVZ[{{ƒ…‹‹fkkmtt…‹‹{u{ulttsllksƒ„„d\\d\\„„Š£››“Œ”š””llkƒ„„¤¤‚|u””‹kk]sreuztttskd\tt{\[[lldredztl{{t””‹Š}ƒllksle‚|utll“““‹„‹\UZƒ||’…‹ult{u{{tt{||dc\jcVtslult{{t’ŒŒ‚|u{zm{{ttts{tt{u{j]\d\\edkekdƒƒ|{{ƒ{||tts{{ƒ˜Ž£Œ‹“ŠŠ}u{{…‹‹‹‹„{{tš””‹’ŠŒ‹“tts››”‹‹„””‹“Œ”‹‹„ƒ„„ƒ}ƒ“““uztƒƒ|{tt¦§¨£››‚v{ƒƒ|{||›”›{{tŠŠ}ttslld‹„„ttsult››”{{t…‹‹›¢›Šƒ}lridc\b[UcbVƒƒ|‘Œ…llkkk]‚|utsl{tt‚ut‹„„ztlrg]ddcƒ„„ƒ||red¤¤D;9:97£››£››¦§¨²¬µ¤¤¦§¨£œ¥””‹¤¤’ŒŒµ¶·¤¤¦§¨«²«¦§¨“Œ”£››”š”””‹‚wlŠƒ}ƒ||“Œ”“““„Š}¦§¨ƒ}ƒ’ŒŒ{tt¤¤ƒ||²««ƒ||ƒ„„{ttŒ”•‹„„‚|uuzt‹’Š””‹rg]llktts{zmš””ultb[U\[[‹‹‹[TT{||kd\{||{ttsled\\ƒƒ|‹‹‹‹‹„œ››””‹£››ƒ„„‚|u‘Œ…‚v{tsl”š”j]\‹’Šdc\sled\\ƒ||kd\lek{{ƒddcldd\[[dc\[[Td\\“Œ”f]cslesle{ttb[U[TT]bZrfkldd‚utƒƒ|bVZj]\ztlztlŠ}|kd\|‚z{zm‹‹„“““ztf|‚zŠŠ}„Š„ŠŠ}rfktsl{||’ŒŒ|‚zkd\tt{‹‹‹{{ƒlri‹„‹{ttlri\[[|„…„„Š”››…‹‹mtt…‹‹{{ƒ…‹‹]cd\[bttsf]c{u{lks{{ƒf]cddc\UZ{||ƒƒ|lld{{tƒƒ|kk]kk]{{tlri„„Šldd{{ttllddcult]bZŠ~‹uzt{{tb[Uƒ}ƒf]cf]c{ttj]\’ŒŒ{tt‹„‹sresle‚|u‹‹‹lddult{{tttsƒƒ|››”‚|u‹„‹‹’Š{||‚|u|‚zult„Š„UTS{ttttsttsf]c{{ƒ{u{’ŒŒ„Š„„Š„ztl”š”‹„‹„Š}Œ”•‚ut{{ƒ{||’ŒŒ’ŒŒƒ}ƒ‹„„ƒ„„{||…‹‹lrizllŠƒ}‘Œ…”“›””‹‹„„ƒ‚u‹‹„ƒ‚u{||‚|uuztttsƒ||{{ttsluzt‹‹„ƒ||“““‹‹„ƒƒ|sre{{t‚wl{{ttslztf‹‹‹kd\ztlŠ}|sre’ŒŒƒ||{{ttsl{||¦§¨FD;*)(‰ƒv£œ¥¦§¨””‹£œ¥²¬µ¦§¨šŒ››”¤¤¤¤””‹””‹””‹“““µ¶·£œ¥‹’Š‰ƒvƒ‚uƒ||redredƒ‚u””‹‹‹‹{u{œ››ƒ„„””‹ƒ||‹„„Š}ƒ‹’Šƒ„„{ttztlŠƒ}{||Šƒ}””‹š””””‹œ¤¦lld{{tred[TTldd{ttslelekrg]sledc\tslƒ||“Œ”ƒƒ|‹‹‹š””‘Œ…””‹ƒ}ƒ‘…„‹„„tll‚v{[[Td\\ƒ„„‚|uztltll{||”“›ƒ}Š”“›uztf]c]bZlddb[Ulddd\\{u{{{t‚ut‹„„ƒ‚uldd„‰vredVTLkk]lddbVZ‚|uslelddŠ}|ldd{ttllkƒƒ|‚|u‚|u{{tŠƒ}{||sle‚utztl’ŒŒƒ||lriƒ„„|„…{{ƒŒŒš{{ƒtt{]cdult{{ƒmtt{{ƒ|„…tt{edkf]clksllkekdmtt{{t‹„‹ƒ„„lks{u{lek\[[d\\ek]lldllkkd\ƒƒ|‹„„tslsreldd\[[d\\sleƒ}ƒllkŒ‹“tsl‹„‹“““‹‹„sleŒ‹“ddclddtt{‚ut‚v{{ttultldd‚|u‘Œ…‹‹‹VTLkd\UTSƒ‚uœ¤¦ƒƒ|Šƒ}{tt{||uzt‘…„ldd…‹‹]bZtsllksœ››{{ƒ{u{lksult[[Tlektsl””‹œ¤¦‹’Šllkuzt|‚z‹‹„‹’Štzl“Œ”Š}ƒ¦§¨lekŠƒ}|‚zlld{u{ƒƒ|ƒƒ|’ŒŒ‹‹‹‹‹‹ƒ„„b[USKJd\\mwFD;[TTllkƒƒ|ttsƒ‚udc\{tt››”{zmŒ”•ek]llkcbV[[TŠƒ}{{t]bZtllsre{ttjcVyle‹„„’…‹Šƒ}sle£››SKJ*)(Šƒ}œ¤¦£œ¥“““£›››”››”›¤¤£œ¥µ¶·“Œ”ƒƒ|„Š}«²«ƒ„„”“›‹’Š””‹””‹‹‹„””‹ƒ„„{ttlld„Š„‹’Š{ttlldƒ||‹‹„š””Šƒ}|‚z’ŒŒ›”›{||“Œ”{{t‹‹‹„Š„‘Œ…“Œ”ƒ„„|‚z{{ttts{||‹„„ƒ„„ult‚|uŠ}ƒ‰|v{zmtyg’…‹rfk‘…„{{t„Š}ƒƒ|{tt›”›tsl’ŒŒƒ||zllƒ||ztlƒ}ƒ{ttldd[TTƒ}ƒ„Š„{{tddc{||tsltlltsl{u{ek]lektllrfkztl{ttlddkk]kd\ddcf]ckd\b[Uekdd\\zllaWMMRKƒ||{||‹‹„lri{ttj]\{zmŠŠ}{yf|‚zkk]ŠŠ}{tt”“›””‹‹„„‹‹‹¦§¨ƒ}ƒ‹…’uztddc|„…|‚zlksmtt…‹’uztllkmttf]c\[bultekdlksultƒ||iq]b[U{u{ƒ}ƒ{u{\[[ldd{{t{{t[TT{{tlldtsl{zmlldƒ}ƒdc\sleddcd\\aWMlriƒ„„ƒƒ|{{tVTLlldtllr]gtt{Š}ƒ‘…„lddd\\tsl‚utddcztlddcb[U{||[[Tlld‹„„”››{{t]bZƒƒ|ƒ||u{{”››{||””‹““““Œ”™š¤\UZ\UZSKJkd\ekdtll{tt|‚zf]c{||lksfkktslttsb[Uf]c{||‚v{{u{{ttllktsltllaWM|‚z{tt{||ztl{tt’ŒŒj]\tsl‹‹„ƒ||dc\dc\lri{zm{{ƒ[[Tredƒ„„””‹‚|uƒƒ|ƒƒ|lldtslsre{zmtsltllcbV{ttkd\ztl{{t{ttmttldd™…D;9:97ƒƒ|š””¨©´›”›‘Œ…²««£œ¥¦§¨µ¶·‹„„šŒ””‹ƒƒ|¤¤œ››¦§¨uzt›¢››¢›‘Œ…’…‹‘Œ…{tt’ŒŒ‚v{ƒƒ|{u{””‹™š¤‹‹„™š¤‹‹„‚|uƒ„„‹‹‹“““{zm„Š„”š”|‚zƒ||{ttultlri|‚zƒƒ|¦§¨|‚zŠƒ}‘Œ…ƒƒ|ƒƒ|{zmtsldc\red{{tƒ||{||„Š„|„…sle‹„‹red{u{{ttredlldslelddlekj]\dc\SKJslelritslƒ„„b[U{||ddcƒ„„uzt{{t{{tldd{{t[TT{tt{zmSKJ|„…‚utsle{{ttll{ttztl‰ƒv[TTsle“““lrilld{ttj]\Š}|kd\tslllkztlbVZttsƒ}ƒ‹‹„{{tdc\lkslksddc{{ƒ{{ƒƒ„„llkmttƒ„„u{{ddc\[[UUYUMR{{ƒ{{ƒuztmttlddlek‹‹„dc\ddclekllkultŠŠ}lrilddlriƒ‚u””‹{ttd\\lek{{t{||ztlldd|‚zƒ„„kk]VTL{u{j]\b[U\[bd\\[TT‚|ub[Ured{||[TTllkVTLb[Uredb[Uj]\]cd{||ƒ„„j]\tlltts”››ekd{u{{||{ttVTLlri{u{ƒ||…„’tllŒ”•{||tllkd\‹’Š{||“““]cd|‚zdc\lksƒ||ddcbVUSKJztlVTL[TTlrittscbV{||sletygtts|‚zrg]‹‹‹ƒ||ƒ||{u{lddztllriƒ„„Šƒ}|‚z„Š}dc\ldd[[T|‚zttskd\[[Td\\tslb[Utzl[[T[TTkd\{||„Š}redƒƒ|ƒ||tslj]\£››SKJ*)(‹‹„””‹£œ¥£›››”›£œ¥›”›””‹”››’ŒŒ›”›¤¤››”›¢›ƒ„„‹‹„”››””‹ultŠƒ}{tt‹„‹‚|u””‹‹‹„ztlƒ||‹„‹Œ‹“{zmƒƒ|‚wl“Œ”ƒ}ƒ{{tlksŠŠ}{{t{|||‚zztlsredc\„„Šsre“““ŒŒš{ttšŒ’ŒŒŠƒ}ƒƒ|‚utŠƒ}{{tzllekd’ŒŒttslddllktll{||kk]{{t‚|uultult‹‹‹“Œ”tll\[b]bZbVU[TTtslf]c{||tsltlltllƒ}ƒlldkk]tlld\\kd\j]\ƒƒ|ƒ‚uFD;tll{ttsleVTLb[UlddVTLztlƒ||tts“Œ”ultkd\cbVdc\{zmƒ‚usletts„Š}tll‹„‹…‹‹“““‹‹„[[T]cdslelks{{ƒ{{ƒedkddc{||u{{mtt\UZ\[bJHFVZ[lkstt{ddc„„Šlksƒ}Šlks[[Td\\lekllkf]ctts“““‹‹„‘ˆ}VTLtslttsbVZ[[T[TTzllkk]ƒ||mttz‚ldc\lks‹’Šƒ||VTL\UZSKJd\\lekkd\zlllddlldddcSKJVTL[TTtslƒ}ƒ\[[dc\tslVTLVTLŒ‹“lrildd\UZlldd\\{u{llkllk{tt„„Štts„„ŠtllbVZlkslridc\uztŒ”•mttƒ}ƒlektlluztlekj]\b[Uu{{d\\{tttts[TTVTLtslVTLkk]ddc‚|uddcŠƒ}{{t’ŒŒŠƒ}tllƒ||ekdƒƒ|[TTdc\lld‚|uultttsf]cƒ„„{||kk]sre‹‹‹dc\kd\lddztlddcb[U‚utlld{ttƒ||sle£››JHF*)(Šƒ}‚|u“““š””¨©´“Œ”“Œ”’ŒŒ¦§¨£››²««”››“““›¢›Œ”•ƒ‚uŒ‹“„Š„ƒ„„ƒƒ|…‹‹‹„„{tttsl{{ƒ””‹››”tt{‹‹‹””‹{ttsle‹‹„Œ‹“tsl{{tzllztl‹‹„llk‘Œ…ƒ||UTSkk]dc\ekd{ttlddtslulttsltslkd\|‚z|‚zkk]{||d\\{||lddlri‚|uttsŠƒ}ttsSKJddctllƒ„„Œ‹“ult[[TVTLSKJllkJHFSKJ\UZdc\ldd‹„‹|„…tsllldtslb[UUTS[TT]bZVTLj]\b[UVTL{tttslVTLzllztlztfldd{u{lrilddJHFb[UVTLkd\redtslttsƒ||{ttllk{{ƒtsllldUTSttsekd{{ƒ]cdf]cllkƒ„„tts{{ƒ…„’\[bfkkVZ[ƒ}Šu{{lksddc|„…{u{“Œ”ŒŒš{tttlledkuztlek‚utuzttsltslVTLtt{\[[d\\[TTekdj]\{{tlddkk]„Š„tzl[TT\[[d\\b[Umttllkllkldddc\\UZlekbVZlldtllzllŠ}ƒtslj]\[[Tdc\lldttslldllkuztkd\edk\UZVTLb[UJHFf]cUTS…‹‹u{{Œ‹“ddcb[Ukd\…„’UTSlriuzt]bZttslddMRK„Š„„„Š{ttUMR[TT{tt„„Šllk[[TlddcbV\[[{ttlldj]\[[Ttslsreƒ||kd\ddcb[Uddctll]bZkd\ƒƒ|lldtlltslƒ||{||ultŠƒ}d\\dc\ztldc\kd\tsl{u{sle‰|vsleddc{{tlld²««[TTD;9ztl’…‹¤¤‘Œ…‘Œ…ƒ||“““‹‹‹{||››””“›…‹‹…‹‹Œ”•„Š„“““ƒƒ|„Š„{{t|‚zllk‹„„””‹|‚zƒƒ|tts{||llkd\\kd\{u{’ŒŒƒ}ƒ‹„„lrilldlldztlkk]lldtsl””‹tslu{{sleedk[[TVTLrfkf]credkd\kd\]cd|‚zsleƒ}ƒlldtts{||ekdf]ctlllld|‚zslelld‹„„tts{tt{||tllcbVzll[TTdc\d\\{u{]bZbVU{tt\[[VTL[[Tkd\\[bb[U[TTtllslekd\|‚z[TT‚utztl\[[b[Usletsl{||tts[TT[TTlld|‚z‘Œ…d\\tsl{{t{{t{||lldtllttsd\\[[Td\\{{ƒlrif]cfkklkslks|‚z{||mtttt{VZ[LKRVZ[mttmtt]cd\[[\[bd\\d\\lddlekmttedk\[[r]guztekdekdd\\lridc\{{t[TTlldd\\FD;[TTd\\kd\tslUTSlld\[[[TTkk]f]cj]\f]cf]c[TTtllf]cbVZUTSllkkd\ttslksllkd\\SKJmttUTSUMRd\\tllSKJ[TT\[br]gf]cUMRUTSztlddcslelkszlltll\UZtllVTL{||llddc\lldtt{VZTtt{„Š}‹„‹ultd\\d\\tt{mttekdlkssleVTLkd\{{tdc\dc\{{tldd[TTztl\[[dc\d\\b[Uddcd\\f]cb[UcbVlldlld{{ttslcbV[TTztlVTLkd\dc\lldtllb[Urg][TTUTSredkd\””‹[TT:97{||››”’ŒŒ²²¬“Œ”“““ƒ„„Š}|”››“““ttsllk„Š„ƒƒ|tt{mttƒƒ|…‹‹‹„„ŠŠ}{{ƒ{u{ztl‹„‹‹„„tts{u{{u{ƒ„„llk{{ƒƒ}ƒ{tt{ttkd\kd\dc\{u{tsldc\slelldƒƒ|{{ƒ{||{||ƒƒ|tllttstlldc\{ttkd\{||…‹‹{u{|‚zlld|‚zVZTSKJkd\lek|‚ztts\[[JHFf]clrildd{||sledc\ttsttsllddc\\[[JHFd\\UTSdc\ztfkd\\UZsleVTLd\\tslaWM[[Tllk{ttkd\lldlritslƒ||uztƒ„„tts{||{{tlld{u{kk]ztf„Š}{{tlridc\lddultekd]bZdc\llkSKJtlllksmttlksVZ[f]cllkUTSlks\[b\[btt{\[bult\[bVTL\[bJHFUUY[TTdc\UMR\[bd\\UTS[[T[[TVTLMRK\[[|‚ztllttsekdd\\b[USKJUTSSKJ\[[dc\lldttsllkj]\d\\leklddUMR[TT{tt\UZleklldtsld\\VTLkd\[TTuzt[[Tƒ„„ddcu{{ƒ„„{ttd\\JHFmtt[TTldddc\\UZtts{u{u{{SKJ\UZ[TTVTLUTSekdlldedkddc[TTllkddcddclridc\JHFedkttsult\[[[[Tllktslf]ccbV[TTkk][[TlldSKJSKJtlltlld\\fkkd\\sretslllkVTL{||{{t[[TVTLUTSd\\ldd[[Tdc\tllrg]]bZttskd\ldddc\d\\[TTztl²««JHF*)(‹„„ƒ||‹‹„’ŒŒ‹„„‹„„{{t„„Šƒ„„‹„„tzl{||tll|„…llkƒ„„|‚zttstllƒƒ|tt{lddƒ}ƒ„„Šb[Uƒ„„{||ddcllk[[Tultlksultu{{{ttd\\JHFdc\VTLek]lld{{t{{tlddldd…‹’ƒ||sre|„…ƒ||„„Šlriƒ||ddc{||{{t|„…u{{ddcddcedk{u{{u{tsl[[TJHF[[T\[[ddc{u{lddultkd\f]c[TTddcd\\dc\cbVlddultuztkk]b[U[TT[[TVTL\UZtllVTLb[Udc\kd\redlldVTLb[Ulldtzl{||tllekddc\lldtll{{tlddztltsl]bZlrilldlddttslld{||\[[UUY]cdedktt{mtt\[b]cd\[bUUY\[bmttlkslksUUYfkkUTS]bZUMRJHFUMR:97JHF:97UTSUTSJHFllkllkVTLSKJllk]cdcbVLKRb[Ub[U[[T\[[SKJVTL\[[dc\lriddcVTLdc\llkf]cllklddlldlddUMRUTStts\[bkd\VTLllkJHFtllbVZuztttslddddcbVU[TT[TTUTSJHFJHFddcUUYUMR\[bJHFJHF[TTdc\d\\ekd[TTUTSJHFVTL\[[]cdD;9f]clld]bZd\\VTLSKJVTLJHFllktt{‚|uekdUTS]bZdc\JHFkd\[TT[TTtll[[TVTL]cdb[U[[TSKJVTLdc\lldFD;[TTUTSSKJJHF[TT[TTdc\dc\b[Ulddd\\VTL\[[bVUd\\jcVkd\ŠŠ}JHF-1+{tt‚|u„Š„ƒ}ƒ{tttts{||{tttts„„Šdc\“Œ”uzt„„Šllkttsu{{tts|‚zJHFedkleksle\[[sleek]llk\UZf]c{{tf]cedkSKJtts{ttlddlrillddc\\[[]bZ{{ttslUTSldd{u{llklksfkkllkultkd\[[TUTS]bZ[[Td\\tllUTSddctts\[[\[[dc\VZTJHFJHFJHFFD;UTSVZTVZTtllredd\\VTLVTLdc\kd\UTSd\\kk]dc\ddcUTS[TTdc\bVUcbVJHF[[T]bZtllb[UJHFd\\tllb[Umtt[TTUTS\[[VTLb[U[TTdc\VTLb[U[[Tddc[TTUTS\[[cbVVTLddcf]cf]cUTSlksllkVZ[]cdultmtt\[[edk\UZJHFLKRUMRJHFLKRUTSJHFJHF)+2:97F=CF=CJHF:97D;9d\\d\\VTLdc\VZTLKRJHFUTSJHFFD;JHFFD;UTSMSStllMRKUTS\[[UTS\[[\[[[TTf]cSKJSKJD;9JHFUTSUMRlddVZTUTSlekdc\lks\[[[TTddcF=CSKJFD;UMR:97JHF:97:97MSS:97\[[UUY\[bllkult{||JHFJHFFD;>B9>ECJHF:97JHFLKRUTS\UZ[TTUMRMRKd\\VTLJHFekdlldlddJHFF=CFD;MRKSKJSKJlldlddSKJllkUTS[[TJHFJHFD;9D;9:97:97>B9:97>EC:97D;9:97JHF[[TSKJSKJlddJHFFD;\UZJHFJHFSKJSKJ¦§¨SKJ*)(ztl{{tƒ||{{t{tt{ttllkdc\lldldddc\[[TJHFedkdc\ddcmttlkstts]bZllklddtllultVTLMRKJHFUTS]bZ[[TUTSJHF\[[UTS\[[tslbVZllktsl[TT]bZ]bZFD;JHF>ECJHFJHFJHFVZ[UTSddc[[Td\\UTSVTLd\\SKJ\[[\[[UTSVZ[JHFJHFD;9dc\JHFJHFUTSSKJUTSJHFJHFd\\JHFJHFJHF:97UTSJHF:97FD;JHFVTLJHFJHFJHFdc\[[Tkd\JHFD;9JHFJHFJHFFD;FD;SKJ[TT[[Tldd\[[JHFddc\[[lldd\\[[Tddcllddc\VTLFD;JHF]cdllkddcldd\[[[TTd\\]cd\[[]cdJHFLKRJHF]cd*)($:97*)(*)(?;C:97:97*)()+2:97:97:97:97UUY3+**)(74,!*)(*)(*)(*)(*)(74,*)(*)(*)(JHF*)(:97*)(:97*)(74,3+**)(*)(3+**)(*)(7-2*)(:97*)(*)(*)(:97*)(,55*)(*)(*)(*)(*)(*)(*)(:97&&%&*)(>EC-1+%&FD;)+2LKRLKRUTS?;CJHF*)($*)(*)(,55*)(*)(F=C*)(*)(*)(*)(*)(74,:97-1+*)(*)(*)(:97:97JHF*)(74,-1+*)(*)(*)(74,3+**)(*)(&&*)(*)(*)(!*)(*)(*)(*)(*)(*)(*)(*)(:97*)(*)(:97*)(*)(D;9:97*)(-1+VTLSKJFD;\UZ[[TJHFSKJJHFLKRJHFSKJSKJ3+*:97:97JHFJHF74,:97LKRUTSMRKMRKJHF:97*)(:97*)(:973+*:97*)(:97:97JHFLKR>ECJHF,55:977-2*)(-1+74,:9774,-1+3+**)(*)()+2*)(*)(*)()+2:97JHF:97,55*)(*)(*)()+2*)(*)(?;C*)(74,:97*)(:977-2*)(JHF*)(&&*)(*)(3+*:97*)(3+**)(*)(*)(*)(74,3+*&&&&3+**)(*)(&&-1+*)(*)(*)(SKJ*)(*)(:97*)(D;9:97:9774,74,*)(*)(>EC*)(:97*)(*)(*)(*)(*)(*)(74,*)(-1+,55,55:97)+2*)(,55:97:97:97LKRJHF?;CUUYf]c\[b\[b\[[[TTSKJUMRJHFllkUTSllkJHFMRKVTLUTSJHFF=CVTLJHFFD;JHFJHFUTSJHFJHF>ECJHF>ECJHFJHFJHF:97LKR:97F=CJHF:97D;9:97:97:97:97FD;:97:97:97JHFF=CLKRJHF\[b\[[MRKMRKdc\]cdLKRek]UTS\[bMSSMRKJHF\UZJHFJHFVZTMRKJHFMRKJHFJHFJHF:97:97:97:97JHF>B9JHFMRKJHF:97D;9UMRVTLJHFFD;VTL[[TD;9JHFFD;>B9:97:97>B9D;9FD;JHFJHF>B9D;9:97JHFD;9FD;UTSSKJD;9FD;SKJD;9SKJJHF[TT[TTJHFJHFVTLVTL:97[[Tdc\VTLllkbVZf]cek]>B9VZ[\UZ>EC\[[VZ[UUY\[[\[bLKRVZTfkk]cd\[[[TTUTS>B9MRKMSSJHFSKJddc[TTVTLVZ[UUY\UZUMR\[[MRKllkVTLJHF:97SKJ[[TVZTJHFJHFVTL\[bJHFMSS[TTLKRJHF:97JHFD;9:97JHF:97JHF\[bf]cJHF:97VTLJHFJHF>EC:97>B9JHFSKJ:97:97SKJJHFJHFJHFJHFFD;SKJD;9MRKJHF74,JHF:97:97JHFFD;UMRD;9SKJbVUFD;MRKb[UJHF:97UMRMRKMSSLKRFD;:97FD;JHFekd:97JHFUMR]bZJHFUTS:97JHF\[[LKR\[bLKRMSSJHFLKRMSSOS`OS`JHF¦§¨¦§¨“Œ”¦§¨¦§¨™š¤¦§¨¨©´…‹‹¦§¨›”›¦§¨›¢›¦§¨«²«››”²««¦§¨›¢›µ¶·µ¶·²««²««””‹¤¤¤¤£œ¥”“›¦§¨²««””‹””‹œ¤¦ƒƒ|‹‹„ztl›¢›šŒ‚v{¦§¨²²¬²««²««£››£››š””¦§¨“Œ”¦§¨tsl’…‹¤¤£œ¥Šƒ}¤¤²««››”¤¤¦§¨¤¤››”¦§¨²¬µ¦§¨¦§¨¨©´¦§¨¦§¨¦§¨£››¦§¨£››¦§¨¦§¨œ››«²«¦§¨µ¶···Ä¤¤£››””‹’ŒŒ‘Œ…‹„„””‹””‹‰ƒv¦§¨£››¦§¨µ¶·¤¤¤¤²²¬¦§¨¦§¨¦§¨›¢›¤¤””‹””‹¤¤Šƒ}””‹²²¬¦§¨””‹ult”š”Šƒ}‚wlztl£››¦§¨²««¤¤¦§¨£››™…£››£››²««””‹²««ŠŠ}²²¬[[T\UZ²²¬²²¬¦§¨¢—š””£››¤¤¦§¨ª³·²²¬¦§¨µ¶·Ä¿¾Ƶ¶·µ¶·µ¶·¦§¨¦§¨µ¶·¦§¨¦§¨£››‘ˆ}µ¶·µ¶·ÃÄƦ§¨µ¶·²««‹‹‹¤¤µ¶·¤¤›”›µ¶·²««²««²²¬µ¶·¦§¨Ã¼¿¦§¨¦§¨’ŒŒ«²«””‹¦§¨¦§¨¦§¨²¬µ”š”¤¤‹‹‹””‹ƒ„„£œ¥£œ¥£››¦§¨²²¬µ¶·””‹¤¤¦§¨›¢›¤¤“““‹’Š”š”’ŒŒ‹„„‹‹‹£››››”²««””‹£››£››¢—””‹””‹””‹ƒ||¤¤²««£››””‹£››²²¬¦§¨²««¦§¨””‹¦§¨¦§¨£››‘ˆ}¦§¨²««¤¤ƒ„„£››””‹””‹ƒ||””‹š””””‹µ¶·¦§¨²²¬¦§¨²²¬¦§¨¤¤¦§¨¦§¨¦§¨œ¤¦¦§¨¦§¨¦§¨¦§¨µ¶·œ¤¦¨©´lks)+2?;CLKRdc\ultd\\7-2>/Att{\[[f]c]bZ!:97%lrilridc\ddc:97SKJlddlldSKJƒƒ|:97*)(JHF[[TLKRJHF\[[JHFSKJVTLldd{u{f]ckd\]cdddcred{zmSKJVTL3+*:97%JHF\UZlld7-274,%&$VZTuzttll[[TUTSMSSVZTVTLVTLtlldc\tll[[Tddc[[TJHFJHFUMRekdddcUTS74,@/7 74,73FD;VTLRP:tslredbVUVTLD;9MRKFD;FD;D;9C8.]bZ&&&&3+*FD;D;93+*3)D;9dc\VTL3)FD;%&&0FD;SKJD;9D;9VTL²²¬dc\[[TVTLjcVƒ||SKJ>R.VTLJHFGSu]cd’ˆ|‚z|‚zlrityglldsreD;9SKJsre{{t‹‹‹‚|u{tt‹„„lddf]cMRKƒ}ƒ{tttllek]f]c[[T]cdUMRD;9UUY"%VTLFD;JHF\[bf]cMRKfkktsllri[[T ,55-1+>B9VTLUMRD;9VTLVTLlldSKJ\[[sre{||VTLd\\{ttSKJfkkJHFD;9SKJsleVTLcbV>B9VTLVTLyledc\3+*"FD;FD;d\\D;9Q?@SKJ >B9*)(:97*)(]bZ7-2SKJ3+*dc\zllUTScbVJHFlldtslJHFlldf]cJHF\[[LKR%&-1+,55{{ƒVZ[llkUMRlks]bZJHFF=CLKRf]clddlek\UZf]cMSSSKJf]c>ECf]c74,[[T]bZVTLttstllƒƒ|]bZedk{u{[TT{ttUTSLKR\[bUMRJHFVZTUTSJHFJHFVTLdc\lldultVTLtlldc\uzt{ttSKJSKJSKJ74,UTSf]cf]cJHFkk]JHFD;974,*)(>B9*)(JHF3+*fkkultUTSJHF\UZUMRVZ[[TTd\\lrio€wd\\uzt]bZtsl\UZLKRultuzttts\[[lddFD;-1+FD;>B9%)*)("*)(FD;SKJFD;j]\UMR[[TFD;SKJ:97C8.D;9D;9SKJFD;JHFFD;JHFtllUMR:97SKJb[UVTLFD;JHFVTLD;9F=CPF=JHFD;9D;9SKJJHF¦§¨VTLJHF‰ƒvƒ‚u‚|u‰|v‹„„lri’ˆcbVJHFtsl‹’Š\[bSKJ7-2[TTuzt|„…lldllk…‹‹lrib[UJHFb[Uult‹‹‹„„Šult[[Tlek{{tlldSKJ\[b{{ƒ{{tj]\tllultekdSKJSKJ\UZD;9ldd\[[[[TekdF=CVZ[JHFdc\uztultlri:97]cdfkkMRKJHFttsddc\[bJHF[[Tdc\]bZlriUTSddcVTLSKJUTSf]clri[TTztlb[UVTLVTLlldVTLVTLlddd\\cbVSKJMRKVTLkd\{ttb[UUMR\UZFD;*)(:97[[TFD;[TT:97>EC:97[[TJHFFD;sle[[TMRKVZTSKJVZT\[[>EC\[[UUYUUY>EC>ECJHFJHFUUY]cdJHF\UZ]cdlksddc>ECedkJHFddcj]\UTS\UZ\[[edkbVZf]c\[b[TT:97D;9[[TMRKb[Uek]VZTUUYJHFUUYVTL]cdd\\f]c\[b\[bD;9lriMSSSKJd\\[[T[TTsle\UZ\[[UTSb[Ullk\[bSKJtll\[[SKJSKJ*)(UMRUMRSKJJHF&&3+*:97JHF74,:97JHFLKRSKJf]c]cdf]c]cdedkVTLb[UVZTmtt[[T[[T]bZ[[TUTSu{{ddc{{t{u{lksf]c]bZ]bZVTLlri&&&&SKJaWM[TT[[TVTL[TTb[UFD;3+*FD;FD;VTL74,D;9VTLSKJ[TTd\\[TTD;9SKJJHFdc\JHFJHF[[T[TTJHFbVUUTSaWM[TTVTLtll¢—llkSKJtsl{{t{zm’…‹{u{kk]]bZ|‚zMRKdc\VTLJHF%UMR{||ttsttsŒ”•\[[|„…tzlrfklddult„Š„{||ekdlddldddc\…‹‹ddcb[Umtttt{ldddc\{ttultlriUMRUUY|„…dc\lekmttVTL\[[F=CMRKVTLfkk{u{{ttMSSMRK\[b:97ekdb[Udc\ult\[[:97dc\JHF[TTMRKddcu{{dc\j]\d\\[TTllkSKJkd\j]\d\\tll[[TlddmttVTLlldVTLJHFFD;D;9SKJJHF[TTddcD;9D;9*)(FD;b[U:97SKJsle:97SKJVTLddcVTLlld{||VZTddc{||llkF=CultlrimttJHF]cd>ECLKR:97MSS\[bMSS]cdVTL\[bddc>ECSKJ\[b\[[{||ƒ}ƒ„„ŠJHFddcbVUulttts\[[FD;:97VTL3+*JHFVTL:97d\\:97]bZdc\ekdddcUMRLKRD;9[[T[[TJHFf]cbVZkk]tlldc\zllSKJb[Ukk]edkf]c{u{lek]bZUTStt{f]clddUMRUTSSKJJHFVZTFD;VTL:97FD;FD;lddJHF‚v{fkkVZ[VZ[\[[sleƒ„„lldlkslriJHF[[Tkk]\UZdc\VZTƒ„„{ttVTLlks]bZ[[TJHFJHF&& +&&3)[TTSKJbVUkd\f]csleSKJ:97FD;&&FD;PF=FD;VTL[[T[TT[TTb[Ured:97[TT[[TVTLFD;VTLJHF[TTVTLf]cVTLSKJVTLD;9lldš””bVZJHF{zmŠŠ}’ŒŒ{ttlddMRKmttiq]z‚l‹’Š|‚zUMRVZTJHFSKJƒƒ|„Š„tt{d\\lkstts[TTJHF„Š„…‹’{{tlrid\\[TT[TT]bZ[TTddclldlddlldSKJJHFedkUUYJHFlekJHFUMR[TT\[[{zmUTS\[bMSSVTL]cd{{ƒ…‹‹UTSekdSKJLKRddcSKJllkJHF[[TFD;]bZlek]bZek]\UZVZ[UMRkd\lddztluzt[TTb[Ulekd\\{u{FD;VTLmttmttllkSKJMRK74,D;9VTLVTLb[USKJbVZ[TT&&PF=VTLVTL\UZek]>B9D;9tsl\[[ekdkk]mttdc\llk{ttllkSKJ\UZ{{ƒllk\[b]cd>ECLKR:97LKR{{ƒ|‚z\[bf]ctt{MSS\[bVZ[LKRttslldj]\iWUUUYldd[TTf]cf]cJHFJHFJHFFD;JHF[TTtlldc\FD;JHFbVZlldlldddcJHFUMRSKJSKJSKJJHFSKJ{ttSKJkd\ulttll[TTSKJ{zm\[[ult{ttj]\cbV]cd\[bJHFf]c‚v‚\UZkk]jcVVTLMRKVTLsreUMRFD;UTSlek‹„„llkUMRUTS]cd{u{{{tddcu{{]bZuzt[TTsred\\b[UVTLVTL{ttVTLf]cFD;74,VTLVTL>B9 :97*)([[TD;9SKJVTLkd\d\\VTLredb[UPF=FD;sreVTLjcVek]UMRldd[TTUMRlddSKJkd\b[UFD;D;9SKJdc\JHFtll[[TSKJ74,SKJlld£››f]cLKR‘Œ…ƒ‚usle‚v{JHFVTLsreFD;ZbN‹’Šlldf]cmttUMRŒŒš{{ƒŒ”•‹’Šekd””‹ttsttstll„Š„{||‹‹„|„…{||ultsleek]llkdc\ddctlltllddcd\\\[[mtttt{\UZUTSJHFb[U\[[{{ƒJHFUMRVZ[UTStslu{{{||\UZ\[b[TT]cd>B9FD;f]ctt{:97\[[VTLdc\[[TlritslMRKFD;[TT[[Tredtts{zmdc\UTSd\\SKJSKJD;9VTL]bZrfkttsFD;!D;9VTLJHF\[[SKJUMRVTLJHFSKJj]\d\\D;9i\VJHFD;9ztlUTSlek[[TekdVZTekdlddtsllekd\\]cd{{tbVZJHF\[b>ECLKR]cdlkstsl{{ƒmtt{{ƒf]cJHFUTSultlddVTLUMRf]c\UZf]c‚v{lekUTS]cd>B9MRKVTLVZT{{t‹‹‹lek¦§¨fkktlltts{||]bZF=C74,SKJddc|„…lldlekf]cdc\zlltll‹„„‚|ubVUb[Ulekd\\tllultddcSKJSKJf]cUMRldd\UZSKJD;9JHF[[TVTLSKJVTLVTLJHFƒ}ƒŠ}ƒ{{ƒllk]cd[TTd\\sleultleku{{œ¤¦ƒƒ|tslf]cVTLFD;[[Td\\UMRD;974,MSSVTLFD;%>B974,MRKJHFj]\kd\FD;UMRcbVjcVkd\ztfcbVC8.VTLFD;VTLek]VTL[TTkd\PF=JHFVTLjcV{zmd\\PF=FD;SKJ[TTSKJbVUVTLcbV]bZtsl¤¤ek]JHF‘Œ…‘Œ…ƒ„„’ŒŒzllf]clri]bZšŒztlƒƒ|g\rq^„¬¶Ã¨©´œ¤¦µ¶·”››|„…¨©´‹‹„”“›Š~‹tllultuztddcf]c{u{{ttƒ„„“““{{tuztœ››ƒ‚utllultfkk‹‹„f]cSKJ‚v{dc\{u{ddcƒ}ŠJHF{{ƒlrid\\„Š„|‚z\[[UTSUUYlksJHFddcD;9edk…‹’VTL:97lldƒ||{||ttslldldd[TTUTSj]\b[UVTLSKJ:97{u{lddSKJrg]b[Ullkllk{{t{{ƒD;9JHFMRKVTLUTSuzt[TTddcD;9:97sle[TTdc\SKJHR>SKJrfktslmttJHFdc\ttslrilriƒ„„|‚z“Œ”ƒƒ|lek{{t†~‘MSSmtt^fsfkkŒ”•Œ‹“tt{mtt„„Š{{ƒ\[b{||[[T\[bultkd\\[bVZTmttlek“~ˆmtt{{ƒmtt{u{JHF[[Tdc\’ŒŒƒƒ|llktlltsluzt{u{ultllkJHFUMR]cdcbVVZTddcF=Cb[Uƒ||tlltlllddlld{{tdc\mtttllƒ}ƒzlldc\d\\SKJ[TTlekrfkbVZ‚wlaWM74,JHFlriD;9ddctllekdŒ‹“ttszll”“›u{{u{{VTL{zmb[U{{ƒu{{‹’Štllƒ‚utll]bZ]bZztlcbVultUMRF=CSKJiq]MRK3+**)( *)(JHFredsleb[Ub[Ukk]cbVtslVTLFD;ZbNdc\jcVztfFD;]bZbVUtslb[UVTL[TTtslŠƒ}VTLZbNkd\rg]j]\{tt‰|vcbVFD;tll|‚z¦§¨>B9SKJ‘ˆ}›”›‹‹‹Šƒ}]cdjcVmttkk]ekd‹’Šš””ult„Š„‹’Š¨©´”“›»ÂÇœ¤¦›¢›¬¶Ã‹’Š”š”{{ƒ””‹’ŒŒ{u{{||›”›ƒ}ƒztlª³·››””š”{{ƒ›”›‚|u‹„„ttsllk\[[b[U\[b]cd|‚z“Œ”{u{””‹\UZ]bZlkslld„Š}{||llkVZTMRKF=C>ECrfk[TTMRKttsJHFlddllk|„…“““mtttllj]\redUMRJHFSKJcbVVTLFD;ek]‹„„dc\j]\lldJHFlekttsuzt]bZSKJ]bZ‹„„ult‚|u[TTUTS]cdVTL[[TsleVTLD;9aWMVTLtll{{tuzttsl›¢›{||lriŒ”•“““œ¤¦™š¤‹„„¨©´|‚zzlllksOS`]bZlks]cdtts…‹‹\[b‹‹‹†~‘\[bddcUTS{||‹’Šƒ||{ttddcedkzllf]c{{ƒfkkUMRttsJHFllkVTLlddztl{ttttsdc\lri]bZddcttsVZ[JHFrfkf]cllk[[TSKJ‹„„””‹ƒ}ƒlddrfkjcVslekk]lld‹…’ƒ||‹„„|„…SKJ{{ƒUTS‚v{\[b[TTb[Uuzt[[T\UZkjVJHFD;9VTLllk‹‹‹bVZ{{ƒddc\[[\[[ƒƒ|›¢›lldddcrfktzl{||”š”…‹‹b[UFD;d\\VTL{ttd\\UTSFD;\[[FD;&&%74,>B9uzt{tt{yfztl{zmb[UaWMSKJVTLJHFVTLVTLVTL|‚zkk]VTLkd\lldbVUSKJ[TTkk]sleaWMVTLkd\SKJj]\tll‚utd\\ƒ‚ulektslª³·VZ[SKJzll£››„‰v’ŒŒŠƒ}aWMtts]bZUTSƒƒ|Šƒ}Š}ƒ]bZdc\›”›ª³·¦§¨Œ”•|„…™š¤d\\‹‹„ztlƒƒ|tts{zm“““j]\f]c“““¦§¨””‹«²«¦§¨‹„‹{ttƒ}ƒ\[[‹‹‹Œ‹“\[bf]cf]cŠŠ}ƒƒ|ŒŒšƒ||™š¤mtt“Œ”„Š„tyg””‹{||UUYtt{ttsllkUMRUMRnv‚„„Š\[[ŠŠ}ddctt{{{tƒ„„{{t\[[lddUMRredkd\lldaWMb[Urfklddsletllldddc\lld‚v‚ƒ„„UTSJHFuzt‚v{tllkd\ƒ||LKRJHF]bZb[Uƒ‚uMRKUTSkk]JHFbVU””‹dc\{{ƒsleult|‚ztts{{t{{tult…‹‹…‹‹„Š„tts]cdMSS>ECMSSldd„†™mttf]c}‡’ult{{t]bZdc\f]cSKJf]c[TTleklrif]c’ŒŒ‹„‹tts]cdD;9MRKFD;[[TSKJbVU[[T{ttlldƒƒ|\[bekd„„ŠlritslUMRlld™š¤ttsbVUttsŠƒ}›”›ƒ||‹„„‚|ulldiq]…‹‹ƒ„„{tt‹‹„‹‹‹ƒ||lkslek“Œ”tll™š¤‰|vƒ„„FD;JHF\[[dc\ultlriƒ„„ƒ}ƒllk{||tts{{ƒ{{ƒb[UztflldddcUUYiq]zllƒ‚uddctsl]bZf]cultf]ckk]\[bC8.D;9]bZJHF!FD; 74,VZTtllš””‚wlldd‚wl[TTSKJrg]C8.dc\sreaWMaWMPF=JHFFD;{ttSKJSKJ[TTVTLek]i\VSKJVTLVTLSKJ‚|ukd\VTLsrellktsl²²¬\UZ3+*Š}||‚zrr]‘Œ…tzlrg]ekd|‚zlld‹’Š‰ƒv‚ut!VTL{yf¦§¨ª³·›¢›u{{¦§¨|„…rfk[TTlri™š¤ƒ„„™š¤¦§¨””‹””‹›¢›¦§¨„Š„ƒ„„‹„„‚|uj]\”“›|‚zLKR‹‹„{||tt{|„…FD;ƒ}Šƒ||…‹‹lksƒ}ƒultlri{||lrif]cuztedklksf]ctllttsllkUUY„Š„VTLdc\dc\…‹‹SKJ[TTd\\llk{||ƒ||ƒ„„SKJsle\UZf]cylemwrg]”“›ekdddcƒ}ƒVZ[JHFVTL{{tslekk]tll\[[ekdd\\VTLb[U{ttSKJkk]kd\{u{‚|uldd{zm’ŒŒ{ttƒ‚uŒ”•|‚z{ttlldultyl„tzlddcMSS\[bMSSUUYddc\[bMSSlks{{ƒƒ„„mtt\UZlld{{ƒtsl{ttƒ||f]c]bZŒ‹““~ˆultfkkztfMRKMRKtt{SKJr]ZVTLj]\sle‹‹„{{tlkskk]ttsdc\JHF]cdlri‹„‹Œ”•tll{tt””‹“Œ”ƒ||’…‹””‹ztllldttsŠŠ}’ŒŒœ››”“›|„…f]cf]cultƒ„„‹„„i\Vfkk]bZultkk]SKJ>B9VTLƒƒ|tsl‹„‹{{ƒ…‹’Œ”•mtt]bZdc\{zm…‹‹\[b|‚ztllƒƒ|tt{f]clri‹„„Š}|tllek]JHFsleJHFaWMJHF*)(:97!JHFbVZd\\j]\sle‚|ubVUVTLsleaWMztfztfHI/VTLFD;jcVVTLVTLSKJSKJJHFkjVŠƒ}VTLd\\d\\bVUSKJztl[TTkd\VTLult{tt¦§¨>EC:97{||„‰v„‰v²««™š¤ƒ‚uƒƒ|››”‚v{{||’ŒŒƒ}ƒ*)(&&ƒ‚n¨©´‹’Šddc|„…Š}ƒƒ||VTLD;9‹„„‹‹‹tll“““…‹‹‹„„””‹‚|u””‹”š”{{ƒƒ||””‹SKJ…‹‹tzl{zm„Š„™š¤“““\[[ztfƒ}ƒ{||ƒ„„VTL[TTb[U{{t‹‹‹ztl[TTSKJUTSMRKf]cUMRllklddultlekddcztld\\VTL‚wl\[[rfkkd\Š}|{||b[Ukd\red‹„‹{u{iq]‚|u[TT|„…tslekd[TTJHFD;9[[Td\\‚|u’ŒŒsle{||JHFVZTdc\kk]VTLVTLVTLjcVd\\{{t]bZ{{t{zmƒƒ||‚z”š”›¢›Šƒ}ƒ||lek{{ƒtsl{u{{u{>EC>EC]cd\[[\[bmtt\[b{{ƒ”“›ultFD;d\\lkslld[TTlekUMR|„…¦§¨{u{ultŠ~‹mtt[[TVTLllkSKJztlredlld[[TtsluztVZTJHFFD;lriƒ}ƒf]cbVZztftzlš””’ŒŒ’…‹redƒ„„Š~‹{zmsleFD;sletsl“Œ”š””{u{ddcJHFUTSSKJf]c„Š„rfk\[[‹’Šd\\JHFJHFlldMRKƒƒ|ult{{ƒtll{u{{{ƒekdsletsl›¢›mttŠ}|‹’Šƒ||ŠŠ}„„Š|‚z|‚zz‚lƒ||lksƒ}ƒUMR\UZlekb[U\UZJHFVZT?;C3+*:97SKJ‚|uŠƒ}ztl‹‹‹rg]r]ZcbVd\\SKJi\VjcVcbVcbVVTLVTLaWMztl[TT[TTsre‘Œ…jcVredb[Utllred{ttredrg]cbV[[Tƒƒ|µ¶·\[[:97œ››””‹£››£››{u{š””ÃÄÆ””‹…‹’]bZ£››{{ƒ|„…lks’ŒŒ””‹…‹‹…‹‹‹‹‹“Œ”Š}|dc\iWUredƒ||tsl‹„‹“Œ”red””‹‹‹„’…‹cbV‹‹‹£››‹„‹f]cŒ”•fkklri››”Œ‹“Š}|lri]bZldd‹„‹…‹‹\UZj]\lddlldƒ‚uttslekSKJUTS\[[{u{rfkŒ”•bVZJHF[[TŒ‹“llduzt‹„„‚wld\\[[T\[[tll‚|uƒ||{{tlld„Š„f]c‚utb[UUMRztlŒ‹“bVZ„Š}JHF[TT\[[uztdc\‚|uŠƒ}…‹‹\[[“““‹‹„srelddkjVƒ‚nVTLaWMj]\VZTllk››”‹„‹d\\ekd‹’Š„Š}{u{{u{[[T„Š}{u{“““f]cMSSn…{{ƒ~’“…‹štts”š”tt{\UZJHF\[[|‚z|‚zœ››ultlekf]cŒ‹“‚v‚›”›ddcekdJHFmtt…‹’{ttŠ}|{tt{||SKJkd\››”|‚ztzluztkd\j]\F=C\UZSKJ{||{u{kd\‚uttlltllult{u{ztl‚wl\[[{zm‹u…ztl”“›[TT\[b\[[\[[llklriƒ}ƒUTS\[[tllŠ}|mttiq]FD;]bZ‚utƒ}ƒddcVTLddcŒ‹“kd\{tt\UZ‹‹‹ƒ„„tslš””ƒ||›¢›‹’Štyg|„…‹„„f]cUMR\[bd\\ƒƒ|VTLUTS>B9JHFUUY3)JHF‹„‹j]\‚|u‘Œ…‚|uslecbVdc\jcVŠƒ}aWMSKJb[Udc\rg]ƒ‚nrg]d\\rg]lldb[U‹„„ztfaWMSKJlldd\\‘…„ƒ||VTLdc\j]\“““Ä¿VZ[JHF£œ¥²¬µ””‹››”‘…„¢—””‹tslu{{]bZƒ}ƒ†~‘^~Y3+*’ŒŒœ¤¦Œ”•¦§¨™š¤ƒ}ƒ|‚zVTLiWUyle¦§¨£››‹„„|‚zŠ}|slesle‹‹„”š”|„…Š}ƒ“““\UZ]bZ›¢›|‚z„Š„¦§¨‹’Štzl{{ƒllkš””„Š„mttj]\dc\{{t›”›tsltts‹„‹\UZttsJHFSKJd\\lriult{u{{tt‹’Š””‹ƒ||Œ‹“UMRd\\‚ut{ttŠƒ}lddldd[TT””‹‚utš””Šƒ}ultkd\lddttstllUTSSKJUTSddc›”›’ŒŒb[Ulri|‚zƒ}ƒlriœ››””‹sresreJHFlddƒƒ|“““ƒ„„£œ¥”“›„Š„›¢›”š”œ››‹„‹{zm\[b{u{f]clrilri{||uzt{{ƒ…„’{{ƒuzt}‡’ƒ„„\[bJHFVTLfkk|‚z…‹‹{{tultƒ}Šlri‚wl{u{tsltyg›¢›mttlriVTLmw“~ˆsle|‚zŒ”•bVU{zmVTLf]cŒ”•bVZlddŠ}|‚v{zllf]cSKJ‚utultŠ}ƒzllllkcbVkd\{||b[Uƒ}ƒŠƒ}SKJSKJ“Œ”llkŒ‹“…‹‹…‹‹‹„‹]bZekdd\\f]cFD;VTLaWMcbVj]\ddc{u{\[bƒ„„Œ”•‰‘~d\\ekd„Š„„Š„‹‹„‹„„œ››„„ŠŒŒšFD;|‚zŠ}|ƒ}Šƒ}ƒtt{D;9lksJHF:C+MSSJHF MRK’ŒŒttsi\Vlld{{tkd\f]crr]‹’Šrr]ultzllkd\VTLrg]VTLrg]j]\‚|uj]\FD;sletllƒ‚u\[[{yf[TTUMRaWMŠ}|VTL‚|u‹’Š‚|u¾ÆUUYJHF£œ¥£œ¥£››“Œ”ƒ‚n£››¤¤VTLƒ}ƒJHF‹‹‹{{ƒLKRr]gšŒ‹‹„|‚zª³·”š”œ››‹„„kk]Œ‹“›¢››”››¢›Œ‹“”š”‹„„‹„„š””kk]…‹‹Œ”•ƒƒ|{||d\\lld”š”™š¤¦§¨{||{tttsl“Œ””“›ƒ}ƒ{||]bZ{{ƒred‹’Šttsƒƒ|ldd{{ƒlek]bZbVZlksƒ„„ƒƒ|{{tllk£››””‹¦§¨¦§¨”“›ƒ|||‚z‚|u{tt‹‹„i\Vredd\\ƒƒ|‹„„’ŒŒj]\\[[tslŒ”•ŠŠ}[[Tƒ||lks\UZtt{sle‚v‚ƒ}ƒ|‚z‚|uf]cuztek]ztlkk]tslSKJ\[[{zm…‹‹ztl””‹Š}ƒ{zmuzt››””››fkktt{{{ƒ‹„‹tts[TTUTSlld[TTtts”››|„…„Š„mtt]bZtt{ekdtslllk‹‹‹ŠŠ}mttd\\UMRekdtlltllleku{{MRK]bZ|„…kd\|‚zkd\‚wlcbV|‚ztslekdlddttslldyleultzll…‹‹{tt‚utSKJzll£››“Œ”‹„„¦§¨‘Œ…‹‹„ttssle{tttslldd|„…{ttultlriuzt…‹‹VTLJHF[[TUTS‹„„FD;JHFkk]rg]|‚zœ››‹„‹tsl|‚z|‚z›¢›{tt{{t”š”„„Š‹‹„£œ¥‹‹‹d\\tt{fkkVTLredtts[TT\UZ:97SKJVTLFD;:97%:97\[[dc\llk””‹ztlb[UjcV‘Œ…d\\kjVd\\aWMdc\VTLPF=SKJylelddVTLSKJVTLdc\{zmrg]{yfrg]bVZjV[zll‚wl{{t‚|uƒ||‹‹„µ¶·\[[74,¦§¨£››””‹£œ¥ldd‘ˆ}rr]b[Uƒ}ƒj]\ljƒ}Š:97SKJztl”“››¢›»ÂÇŒ”•‚wlƒ||llk‹„„£œ¥“~ˆ{||¦§¨¤¤‚v{‘…„kk]””‹›”›{{ƒƒ||œ¤¦’ŒŒ‹‹„””‹’ŒŒ{zm‘…„£œ¥“Œ”‹„„ƒ}ƒ{ttmtt[[Tf]clddƒ}ƒ‹„„{u{tllmttllkŠ}ƒtts{{ƒtsl‹’Š|„…VTL¦§¨››””››‚ut|‚z{||”š”rg]ƒ}ƒ{||sleVZTFD;red‰|vztfsle\[btslŒ‹“‹’Štts{ttldd‹…’[[Ttll””‹ƒ||œ¤¦ƒ‚u\UZultlldkd\cbVztlj]\bVU¤¤‹‹„lri‹„‹ƒ„„uzttslƒƒ|”››ƒ}ƒ‹…’{tt…‹‹‹„‹{{ƒJHFiq]llk[[T{u{{{ƒ|„…mtt{{ƒttsekdVTLddc‹‹„ƒƒ|ttsj]\Š~‹ddc{ttf]c{||]bZMRKmttu{{|‚zŠƒ}{||tsl”š”llk‚|u…‹‹tsltts{tt\UZŒ”•{tt|„…bVUllkredrg]ƒ}ƒ£œ¥‚utƒ„„‰|v¦§¨””‹{tt‚utbVUd\\VTLtllttslksƒ}ƒƒ}ƒÂ¾Æœ¤¦œ¤¦|„…f]c{ttdkVkk]jV[‹’Šllkf]c{zmfkkVTLz‚ldkVœ››œ¤¦”š”„„ŠŠƒ}|„…UTSekd:97r]gUTS:97ultedkJHFD;9dc\,553+*[[TD;9JHF[TTUTS‚|uŠŠ}{{tƒ||zll{zm‚utrg]rg]kd\SKJVTLVTL[[TVTLVTLldd[TTVTLsreƒ‚usreiq]VTLsle‚utredƒ||lld‚wlztlƒƒ|µ¶·\[b:97“““£œ¥‘Œ…‚wl{ttŠ}|‘ˆ}z‚lJHFœ¤¦š””jcV.1SKJ“Œ”µ¶·‹’ŠªÁŲ¬µ’…‹ultf]clld‚v{ƒ||‚v{™š¤ƒƒ|tll‚|u¤¤|‚z¦§¨Œ”•“““™š¤››”ƒƒ|‚wl‘…„›¢›{ttrfk}‡’ult“““œ››lritslƒ}ƒ””‹‹’Štzllrilks‹’ŠŒ‹“SKJf]c{tt””‹ŠŠ}UTS‹‹„‹„‹|‚zred{||‚v{‹„„tsl‚utb[Uztl{||[[Tzllkd\i\VlddŠŠ}ultuztƒ||”š”tllb[USKJ[[Tllk‚v{‹‹„yleldd’‘~[[TMRKkk]d\\SKJkk]j]\ŠŠ}””‹„Š„{{tultŠ}|tslu{{uzt{||¦§¨‚v{„„Š{u{{{ƒ|„…LKR\UZlddllk{{ƒ{{ƒlksnv‚mtt‹’ŠUTSVTL]bZtt{llktllƒ}ƒŒŒšŒ”•Š}|tslMRK]bZ]bZiq]]cdtzl[[Tsre{zm‹’Š{{t|„…|‚zttsƒ||rg]ƒ„„f]cƒƒ|‚v{dc\llkSKJ‚v{{tt£››ƒ}ƒllkztl|‚ztslztfƒ}ƒj]\rfkŠŠ}sle\[[ultekd„Š„Œ”•{{ƒ{{ƒlri…‹’z‚lJHFtzltslyle‹„‹ƒƒ|b[Uuztlrilrilld|‚zŒ”•„„Štt{™š¤„„Š]cdlrisreztlf]c{{ƒ“Œ”tll*)(SKJkd\VTL3+**)(D;93+*JHFJHF{{tztl‘Œ…Šƒ}ztfVTLSKJjcVVTLSKJb[UVTLkk]jcV‚wlj]\kd\i\V[[Tkk]ƒ‚u{{ttslZbNzllr]Zzllyle””‹[TTkd\{{tµ¶·LKRLKR›”›‹‹‹›¢›£œ¥f]c‘ˆ}¢—„Š}tt{““““Œ”j]\JHFUTS’…‹Œ‹“„Š„¦§¨¨©´²««™‹†ldd]bZ‚|u‹’Š|‚z{{tred[TTsle£››mttmttuztš””{{t|‚z‹‹„{{t’ŒŒ|„…¤¤›”››”›{{ƒ{{t„Š}{||{||ult¤¤‹‹‹lld\UZllk{||lddb[Ud\\‚v{uzt‚ut„„Šlri{||dc\jcV{{ƒllkƒ||ƒ„„{tt\[[kd\{ttb[Uƒƒ|tslƒƒ|ƒƒ|sleSKJ‹‹„›”›””‹r]glldf]c\UZVTLŠ}ƒƒƒ|ƒ„„{{tVTL{ttlksSKJtsl[[TJHFš””‹…’‹’Š{{tlriƒ„„…‹‹mttuztuzt|‚z|„…ultllk{{ƒ“Œ”{{ƒlks{{ƒƒ}ƒ|„…edk{{ƒœ¤¦|„…Œ”•‹„„{||sleddcddclldƒƒ|f]cŒ‹“…„’¤¤{tttslVTLVZ[tzl‹…’ƒ„„tsl“““‹‹„{ttddc…‹‹|„…|‚z””‹„Š}‚utƒƒ|‹‹‹mwUTS{{tslelek‚v{Š}ƒŠ}ƒtts‚utsre\[[b[U{ttŠƒ}‹…’“““{{tsleƒ„„‹‹‹lksd\\ldduzt„„ŠŒ”•mtt‹„‹œ¤¦„Š}[TT|‚zttsŒ‹“”š”JHFz}››”llk|„…™š¤Œ”•“Œ”{{ƒ\UZek][[Tƒ||š””tlllksƒƒ|mttSKJzllekd\[b?;CFD;"[TTƒ„„slei\Vsle‚utVTLrr]bVUPF=VTLjcVd\\lldVTLsrelddi\VVTLSKJ‚wlz‚lŠ}|lrirg]b[U{ttbVU‚ut‰|v’ŒŒ‚|ukk]|‚z¦§¨VZTUTSultƒ„„””‹‘}zrg]‘Œ…ƒ‚u–¢‹„Š„j]\j]\bVUMRKSKJ{tt¨©´œ¤¦›¢›”“›µ¶·£››‚ut””‹ztl‹„„{{t··Ä|‚zŠƒ}‚|usle‹‹‹u{{‹’Š{||{ttƒ‚u{zm{tt‹„‹””‹ƒƒ|š””{||Š}ƒ™š¤‹‹‹{ttlri¦§¨’ŒŒ™š¤‚|u‚v{d\\lek\[[]bZ[TTf]c„Š}uztƒ„„bVZ“Œ”ƒ||‚wldc\lddd\\‹’Š{zmtlltsl‹„„{ttj]\ztf„Š„kk]SKJŠ}ƒ|„…£››››”{tt{ttJHF[TTd\\ult’…‹ekdJHF[[TSKJ\UZdc\dc\SKJVTLultult‚|uµ¶·u{{{u{…‹‹|„…‹’Š››”|‚z„„Š{ttŒŒš„„Š£²‹…’\[b\UZult™š¤lksu{{ŒŒš{u{Œ”•kjVu{{\UZJHFj]\]bZ]cd\UZ{tt‹„‹‹„‹„Š}””‹…‹‹tzldc\Œ”•™š¤‹‹„››”{{t’ŒŒ{||sre|‚z‚|uredf]cSKJœ¤¦llkf]cVTLJHFSKJbVUŠ~‹yleš””bVZFD;kd\{yf””‹d\\{zmzll‹‹‹ƒƒ|rfku{{d\\r]g{{tf]cJHFultf]c„Š„]bZ]bZek]{{t‹„‹\[[{{ƒ{{ƒllkf]csleƒ„„„Š„‹‹‹tt{ŒŒš„Š„edk{{t“““ldd‚|u‹„‹|„…jcV{||ekd\[[VZT[TTF=CFD;74,lldf]ctll‚wlƒƒ|‚utVTL[[TVTLb[UVTLb[Ulrikk]bVZddcƒ„„SKJsle{ttVTL{zmƒ‚u|‚ztsllldlddtll‚v{rr]‚wlztf{{t‚wl¦§¨fkkMRKtts£››Š}|‹„„tzl’…‹‹’Š””‹ƒ}ƒjcVVTL|‚zF=C?;C¤¤›¢›„Š„…‹‹ƒ}ƒ›¢›tslsleƒƒ|ƒ„„šŒ|‚z”š”””‹Š}ƒ¦§¨‹‹„ƒ‚u]bZ‹’Š…‹‹”››ƒƒ|{{tƒ||“Œ”rfk²¬µ¤¤{u{tsl¦§¨™š¤lddekd£œ¥ƒ||Œ‹“››””“›d\\ƒ}ŠlldllkbVUzll¤¤|‚z[[Tsreultƒ‚uldd‹„„tsl‚wl‚|u{{t…‹‹tslf]cekdPF=bVUŠŠ}j]\[[T’ŒŒƒ}Šlddtt{f]c{tt:97lldUMRultekd]cdVTLbVUbVZfkk|„…ztltslSKJ{tttsllri‹‹„‚|u{{ƒlri‹‹„„Š„‹‹„œ››‹‹‹ƒ„„fkklkstt{JHFVZ[›¢›g\rmtt\[b{{ƒtt{ƒ„„œ¤¦d\\[[TVTLVTL{zmcbVtts{u{bVU{u{‹‹‹››”“““uztVZTttsuztuzt„Š„ldd””‹››”f]c„Š}„Š„[TTtsl‹’ŠMRK[[T{{ƒ‚v{d\\ƒ||tsl‘…„’ŒŒ’ŒŒf]c››”‚utrg]VTLkd\’…‹{{tlek[[TŠ}ƒtygllk””‹ljVTL[TT\[[|‚zlddƒƒ|dc\lri”››‹‹‹ƒ„„edkekd]cd{{ƒ\UZ[[TŠ}|uzt“““Œ”•{{tmttttsŒ”•lriVTLsle…‹‹lldr]ZD;93+*|‚zkd\{yfFD;JHFSKJjcVMRK‚|uƒƒ|dc\‚utkk]SKJtsl]bZbVUkjVsre[[TtllD;9aWMslesreultj]\sre””‹ƒ‚usreredtts‚ut£››ult‚wlƒ‚u{{t‘…„µ¶·]cdMRK‹„„“Œ”’ŒŒ£››£››™š¤ª³·š…Ž\[[{ttldd]bZ]bZzll‚wlƒƒ|‹„‹„Š„Š}ƒ””‹ƒ||SKJFD;š””‹‹„Šƒ}„Š„ƒ‚u“Œ”š””{tt”››tll‹’ŠŒ”•‹„„{{tŠŠ}ƒƒ|tllƒ||£››|‚zƒ„„¤¤red{||cbV]bZ{u{£œ¥›¢›¦§¨ztl\UZƒ}Š¨©´|‚zŠ}ƒ‹…’{||tslƒ„„dc\š””¤¤{tt“Œ”‹‹‹ƒ||Šƒ}‹‹„“““slekd\ultsleztlult‰|vtll{ttllktllredUMRtslVTLtts{tt…‹‹{ttekd]bZaWMred‹„„llkƒƒ|‹‹‹””‹kd\Œ”•ƒ‚uœ››¤¤”“›‚|uƒ„„”“›‹’Š„Š„{||ultlek„Š„{{ƒddc]cdf]ctslŒ”•{{ƒ“Œ”lks{{ƒ…‹’j]\VTLFD;[[Tlddƒƒ|‹‹‹ultllk{||„„Šlriƒƒ|{{t{{t{|||‚zd\\‘Œ…‹‹„tzl””‹{{t|‚zƒ‚u‹‹„Šƒ}[[T3+*lektllyfltsld\\lddŠ}|‚ut{tt‚wl{u{VTLcbVŠ}ƒƒ||‹„‹‹‹„[TTVTLVZT‚utƒ„„tsl…‹‹{u{{yfmtt\[[{u{kjVŠ}|ƒ„„“Œ”¦§¨“““™š¤tzl|„…lkslldkd\„„Šllku{{‹‹„‹‹„|‚ztt{””‹VTLƒ‚usleJHFbVUUTS:97UTSD;9VTLiq]JHF%PF=b[Ulekrg]„Š}|‚zƒ||‚|utslkk]kjVVTLdc\llkdc\JHFb[Ukd\[[Tb[U{tt‚wl‚wl‰ƒvtsl{zmš…Žred²««‰|v¤¤sleŠŠ}‘ˆ}‹‹‹¦§¨\[[JHFŒ”•¦§¨“Œ”‹„„ŠŠ}‹’Š‹’Šultdc\dc\‹„„kd\VTL’}™£›››¢›””‹«²«…‹’{{ƒ[[Tdc\b[U¦§¨””‹kd\›¢›lri’ŒŒƒ||””‹Šƒ}tzluzt|‚z™š¤sre›¢›””‹tllr]gz‚l‹‹„lri””‹¤¤››”‚|u”“›Š}ƒš””””‹ŠŠ}ƒ„„‹‹„|‚zttsVZTŠ}|{{ƒtsl[[T‚|u‘Œ…ŠŠ}‹‹„ƒ||llk“Œ”tllƒƒ|‘Œ…tslŠƒ}Šƒ}lddred‹„„aWMtllƒ„„cbVJHF[TTult{u{j]\UTSllk„Š„Œ‹“ztl|„…››”tzlkd\ultƒ„„{{tŒ”•’ŒŒ‘…„›¢›ztltslkk]‚|u‹„‹{||lkscbV””‹mttŠŠ}›”›‹…’lksJHFuztmtt|„…ulttt{ŒŒš…‹š„Š„{||mtt\[[{zmSKJMRKlek‘…„ult„Š„„„Šult[TTlritsl|‚ztsllri…‹’{tt””‹µ¶·ƒ„„Œ‹““““‹‹„ƒƒ|š””|‚zdc\b[Uedkrfkred‹‹„[TTƒ}ƒŠ}ƒ‹„„Œ‹“””‹‚v{[TTkk]‚|u‚ut‰‰w‚v{lldƒ||SKJd\\tll{||j]\mtt„Š}ƒ„„tsl{zmztl|‚zª³·¤¤“““ƒ}ƒf]c]bZu{{{ttƒ||ztlred…‹’‹‹‹u{{Œ”•Œ‹“””‹tsl‹‹„ƒ‚u|‚zƒƒ|UMR7-2SKJFD;MRKLKRtt{3+*73JHF[[T‚utsledkV[TTPF=VTLFD;bVZƒ‚u‚|u{zmtsl]bZ{||i\VztlSKJ‹‹‹edk„Š„¤¤‚wl|‚zr]Zljzll‰|vlj‚|uŠƒ}ƒƒ|‚v{¦§¨[TT:97ƒ„„tsl’ŒŒƒ‚uuzt£››Œ”•””‹„Š„\[[Š}|lld]cd“~ˆ””‹›¢›””‹””‹f]c[TTb[Uyletzl{{ƒztl„Š„””‹[TT“Œ”bVUƒƒ|’ŒŒ{{tddc”š”‹„‹lrisreVTLtllult‹‹„kd\Œ”•”š”ƒ‚uš””‹„‹|‚z™š¤””‹{zmŠƒ}›¢›lritzl{tt‹’Š¤¤‹‹‹ƒ„„{{ttslkk]ŠŠ}red‘Œ…“Œ”tsl‚ut’ŒŒztllri{zmaWMƒ‚ujcVd\\SKJVTLkd\{u{\[[lri{{tf]cSKJ{{ƒ[TTrfkttsƒ||lri’ŒŒ’ŒŒyfllek‹‹„{{tult{ttsresre{zmŠŠ}sretll‹„„{||lri‹„„kk]{||{{t“Œ”ultf]cVTLVZ[|‚z]cdmtt‹…’llk„„Šƒ}Šttsdc\MRKjcVtslztl””‹ultf]ctslult£››Š}ƒ„Š„dc\|‚zVTLttsultƒ||’…‹‹‹„››”›¢›„Š„Œ‹“‚|uztliq]lriSKJu{{UMR|‚zSKJf]cŠ}ƒ’ŒŒ‹‹‹‹…’{||ƒ}ƒf]csre{u{lddŠƒ}ultuzt\UZVTLlrilld‹‹‹{u{ddcek]lddkk]b[Usle„Š„ƒ}ƒ’…‹‹…’’ŒŒœ¤¦‹…’\[b””‹{zm…„’ztl{||‹‹‹|‚zƒ„„„Š„„Š}]bZƒ‚uƒ}ƒ|‚zttsmttlks[[TVTLFD;74,UTS3):97iq]dc\|‚z{{tVTL‘…„‚|uƒ„„cbV[TTVTL|‚zsle\[[VTL‚|uztlŠƒ}ƒƒ|edktll‚wl‚|utsllldd\\d\\Š}|ztlƒ||ƒ‚u{zmƒ‚u‚v{£››UTS*)(‹‹‹“““‘Œ…ztfVTL‰|vlriVTL”š”llkr]Zb[U:973+*‹’Šœ››¦§¨rfkyfl‚|ubVUVTLFD;redƒƒ|””‹››”ultult‹„‹”“›Œ”•‹’Š¡¡¨©´Œ‹“{{ttsl£œ¥‚v{lri¦§¨‹‹„…‹‹‹‹‹““““Œ”‹‹‹lks™š¤™š¤‹„„””‹”š”„Š„uzt›¢›”š”””‹tt{‘}zedkaWMek]‚|uztfzll‹„„ƒƒ|tll{tt‚wlkd\rg]sleŠ}|ztllrir]gSKJf]cb[Uekd‚|u{ttŒ‹“d\\UTSult‹‹‹ƒ„„‹„„tslsleƒƒ|kd\uzt‹…’„Š„lkskd\SKJlld””‹|‚zlld…‹’‹„„„Š„Œ”•{{ƒtzllldlldŠ}ƒddcf]clksJHF]bZmtt\[[tt{ƒ}Š{{ƒu{{…‹‹bVZFD;tslddclld‚|uu{{lks{{tƒ„„ƒƒ|’ŒŒ{{tuztekdUTSŠ~‹ztlŒŒštt{‹‹„£››‹„„uztŒ‹“{{tztlŠƒ}kjVuztŒ‹“ultjV[””‹‰|vjV[‚v‚ƒ||„„Š‚utf]c{{tcbVƒƒ|{||‘Œ…“Œ”ztfultb[Uttstll””‹ddcƒ„„MRKlriVTLFD;lld|„…llk{u{llkš””’ŒŒ™š¤“Œ”mttœ¤¦ƒ„„‹‹„‹…’™š¤llkŒ”•tt{ŠŠ}”š”¦§¨“Œ”lriekd]cdf]cbVUVTL>B9FD;:97FD;&&C8.{{t„Š}‹‹„kk]ultsleulttslJHFVTLVTLsre]bZVTLbVZlldlddcbVlld’ŒŒ„Š}‚wlttskk]ƒ||ƒ||Š}|‚wlbVU‚|usrei\V‚|u‘ˆ}>B9:97››”ƒ„„‘Œ…””‹jV[bVZu{{i\Vekdllkkd\aWMVTLJHF¤¤™š¤™š¤|„…tts{u{sle\[[tzlr]gtslldd|‚z’ŒŒƒ||“““£œ¥ƒ||lri|‚zƒƒ|™š¤‹‹„SKJ„Š}™š¤{|||‚zkk]tsl|„…“““ƒ„„Šƒ}VZ[™š¤‹„‹›”›’ŒŒ‹‹„‹’Š|„…{zmƒ}ƒ””‹„Š„ztflld{zm{||„Š}SKJb[Uƒ„„ƒƒ|[TTredzllztllddƒ‚uylelj{u{tllƒ||llktllƒ„„””‹ƒ„„ultb[U{{ƒJHFtsl{||lriƒ‚u‚v{]bZƒ}ƒ|„…Šƒ}u{{tts‚wlsle‚|ulld‹’Š¦§¨‹„„ƒ}ƒ„Š„ztlŠ}|ƒ‚udc\ekd’…‹rfk{{ƒmttF=C>EC]bZf]c”“›…‹’…‹šƒ„„”››dc\\[bVTLVTLUTS‚|ui\VF=Clld‹„‹‹‹„ª³·‹’Šiq]dc\[[Tƒ„„ƒ||{||šŒƒ‚u›¢›„„Šuztuzttsl””‹›¢›Œ”•]bZ™š¤redultƒƒ|rg]f]c[TT|„…‚v{Œ”•ƒ}ƒ|‚z‚|u‚v{Š}|{zmƒ||ƒ„„redbVUUTS{u{lldƒ|||„…lri|‚z‹‹‹kd\d\\kk]u{{ult\UZšŒtts\UZtt{…‹’¨©´’ŒŒ™š¤”››‹„„u{{{||‹‹‹”››ƒ„„¤¤‹„„lrilld>EC%FD;74,FD;SKJVZT3+*&&C8.yle|‚zƒƒ|ƒƒ||‚z‘Œ…Šƒ}JHFJHFlri]bZVTL:97VTL{u{tzlŠ}ƒlddrfkllk{zmlriƒƒ|VTL‘Œ…rfkŠƒ}‰|v{u{””‹Šƒ}‚utztfµ¶·MRK*)(‹’Š‚ut|‚z‘ˆ}{zmJHF|‚zllkuztlekttsi\VD;9D;9‹‹„«²«ŠŠ}Œ‹“””‹{{ƒcbV[TT‹’Šedk‹‹„ƒ||¤¤’ŒŒ™‹†‹‹‹’…‹b[Uƒ„„lri¦§¨ª³·””‹kk]Œ”•”“›ddclldVTLekdSKJj]\F=Cj]\{{ƒ„„Šƒ„„››”’ŒŒsle]bZlld{zm‹‹‹””‹‹’Šrg]ddcf]cj]\‹‹‹š””“Œ”j]\ddclddŠƒ}š””tzlztlsleƒ}ƒ‚ut{||Š~‹“Œ”fkkŠ}ƒ|„…tslmttf]ctslUMRSKJ‹„‹lksslef]clddddc{{ƒŒ”•‹„‹tslƒ„„tts’ŒŒlriuzttslz‚l{||‚utsreƒ||’ŒŒ…‹‹uztVTLtllultddcedkekdLKRu{{lkstts…‹’œ››Œ‹“”“›{tt{{ƒj]\MRKVZTrfklektsluztƒ}ƒ“Œ”“““ttstsllks‹„„…‹’„Š„ttsƒƒ|lldŒŒšŒ”•‹‹‹{||ldd“Œ”‰‘~„Š}mtt{{ƒ“Œ”£œ¥‹’Š‹„„lek‹‹‹ƒ||tts”“›‹„„ƒƒ|ƒƒ|‘Œ…‚wl››”£››b[U\UZtllrfkldd‚v{”››”››|‚zƒ}ƒ„Š„j]\‚|uSKJ{{ƒJHFddcredult„„Štt{ult‹„‹{zmµ¶·”››ultldd‹‹‹…‹‹”››‹„„¤¤‚utlldllk]bZ:97aWM3+*C8.Q?@F=C%&&&tlllri{zm‘Œ…VTLƒ||VTLƒƒ|ztl{u{JHFVTLlldJHF\UZ[TTtsllddtlld\\tts[[Tsre[[TVTLkd\kd\ŠŠ}£››£››rg]Šƒ}sle‚utµ¶·MSS:97tslƒƒ|“““‚wlekdJHF|‚ztt{uztdc\|„…rg]74,bVU…‹‹”››””‹“““UTS{||ddcekdlritsl‹‹‹’ŒŒ‹‹‹‹‹‹Šƒ}sleƒ„„””‹llkVZ[‹’Šœ››‹’Š{tt\UZ„Š„{||ƒƒ|VTLSKJ]bZ’ŒŒœ›››”›FD;[TT“Œ”¤¤¤¤‹„‹‹‹„œ¤¦””‹|‚z¤¤mttrg]tts‘…„‹‹‹d\\rg]Š}|{ttƒ„„‹„„kk]tsllldtsl‚v{{zmkd\ldd’ŒŒƒ„„mtt„Š}ƒ}Š‹„„ƒ„„{u{f]cultUMRztlult’ŒŒj]\Š}ƒkd\llkƒ||lri„„Š{||ttsf]c[[Tsreƒ„„‹‹„‹‹„{tt””‹{||ttstsl{tt{||‹‹„Šƒ}lek{ttuztMSSmtt“Œ”{u{ek]{u{{u{f]ckd\lddd\\SKJtsl’ŒŒf]cdc\{{t[[Ttllf]c\[[u{{mtt{||ekd‰|vŒ”•kd\””‹‚|u›¢›²¬µƒ„„Œ‹“‹‹„{ttVTL[[TVZTlri‚|uœ¤¦Šƒ}“Œ””››ƒƒ|{u{tsl{u{{tt‹‹„‹„„‚|u|‚zllkultlddslej]\{u{j]\‹‹‹ƒ}ƒƒ„„tzl“““‹‹„Šƒ}UMR[[Tj]\{tt‹„„ultf]c\UZ‹‹‹slerg]‹‹‹f]c{tt„‰v‹’Šfkk””‹f]ctsl\UZŠ}ƒ{u{{{ƒ:97lldmttF=CFD;>B9FD;|‚zj]\|‚z|‚z‚wlsletzlaWMrfk[[T[TTlri{zm\UZ‹’ŠlddcbVtsllldSKJttsttsVTL[[Ttllsre[[Td\\{zmrg]lldrg]ƒƒ|‰|v{zmÃÄÆJHF3+*{{t””‹”š”¢—rr][TT”“›|„…ƒƒ|llk{{t‚|uC8.JHF{{t“““uztœ››{{t”“›ƒ}ƒlksdkVŒ‹“lld‹’Š‹‹„ƒƒ|‹‹„¦§¨œ¤¦\[[|„…ƒ„„‹„„£œ¥ztl‹‹‹“““tzl””‹|‚z“Œ”lri£œ¥ƒ}ƒ{u{‚utultª³·{{t’ŒŒ‹„„‹’Š‹‹‹tslkd\””‹jcVš””‘Œ…ƒƒ|‚|usleƒ„„‘…„r]gyledc\d\\‚|ulld{{tsletllrfklddllkyleœ¤¦ekd{u{edktzl{zmlekf]c{{ƒVTLrfk‹…’””‹]bZ|‚z[TTŒ”•{u{ƒ„„tzl”š”fkk{{t””‹redlri””‹‚v{lld[[Ttslzll’ŒŒ|‚z{{tƒ}ƒ’ŒŒ…‹’lek{||Œ—££››‹…’Œ‹“{{ƒ{{ƒ{u{ttsttsfkkd\\\[[‹’Š™š¤zll{u{››”ƒ||ƒ||¤¤]cd|„……‹‹“Œ”|„…››”Œ”•‚utƒƒ|tsl“Œ”””‹Œ”•œ››””‹ƒ„„JHFmtt{{t…„’‹’Šœ¤¦«²«‘Œ…ƒ‚uult””‹“Œ”tt{kd\{zm’ŒŒ‘Œ…sre{u{\UZlekult’ŒŒ“Œ”š””‹„„|„…lrirg]””‹iq]ƒ||“““ttsldd‹„‹[TT“Œ”ultƒ||lldredlld‚v{“Œ”Œ”•ƒ||“Œ”ƒ„„¤¤kk]u{{“Œ”VTLb[U…‹‹\[bSKJ{{ƒr]gUMRƒ‚uVTL]bZJHF\[b{||‚|u“Œ”dc\kk]ultrg]\UZtsl„Š„tzlddclddu{{tts{{tVTLredUTSUTS]bZdc\]bZrg]SKJrg]{yfkd\i\VSKJsreldd¦§¨SKJ:97””‹‹„„{zm‘Œ…]bZttslri„Š„ƒ‚ukd\dc\rg]PF=bVU‚v{œ››”š”œ¤¦ztl”“›Š}ƒtsl„Š„”››ƒ||“““¦§¨‹…’‚ut{||ddc‹‹‹b[Utts””‹Œ‹“lddkd\lrilritzlŒ”•ƒ‚u„„Š‹„‹µ¶·„„Š“Œ”tts¨©´Š~‹£››d\\dc\ldd…‹‹jcVVTL{{t{ttztltslƒƒ|ztl{{t’ŒŒŠ}|Šƒ}rg]mw{zm{zmredrg]‚v{lddred”“›ult‚v{fkkd\\‹„‹kk]ƒƒ|‹‹„‹„‹lek\[[kd\ƒ}ƒtllƒ„„|‚zek]uztŠ}ƒuztlri‚|ufkkƒƒ|”š”{tttslƒƒ|{tt“““‹’Š“““lddƒƒ|”š”‹’Š™š¤ulttllb[Ukk]|„…œ¤¦™š¤Œ”•£œ¥fkk|‚z‹‹‹{tt[[Tslelri„„Š|‚zŒ”•¦§¨‹’Š{||‹…’{{tVZTdc\\UZ|„…|„…llkŒ‹“ƒ„„“Œ”‹‹„£œ¥ƒ}ƒ›¢›ƒ||ekdttstts”“›{u{””‹{{tttsztluzt£››‹„‹‚v{tlld\\sre‹’Š’ŒŒ‘Œ…{tt‹„„d\\Š}ƒ{{tldd[TT…‹‹lldbVU’ŒŒ›”›tll‚utllktzl‚|ubVZlekllkSKJlri[TTttsd\\{zm’ŒŒ¨©´„„Šƒ||ƒ„„“““›”›‹‹„tllbVZkd\„Š}]cdu{{:97{{ƒJHFD;9”š”|„…]bZ:97dc\{||rg]‚wlekdtslztlllkultsrettsŠ}|mtt{{ƒ{tt|‚zš””{||ƒ||d\\slesrett{ŠŠ}b[Ub[UcbVrg]””‹cbVjcV‚wlrg]µ¶·ddc*)(‹’Šœ››„Š„zll›¢›u{{lld„„ŠsleUTScbV{zmHI/ultult¤¤‹’Š‹’Šred™š¤f]c{zm‹‹‹tts{{t”››‹„„£››ult¦§¨ult…‹’dc\{||tts¨©´”š”„Š„„Š}…‹‹Œ”•ƒ||cbVtt{{{ƒ£œ¥tts‚ut‚v‚ddc”“›š””ƒ||f]c‹‹‹UTSkk]lldVTL{{tƒƒ|‚|ud\\ztlsreƒ||‘Œ…‰ƒvbVU‚utlrilldVTLVTLd\\kd\b[U]bZ’…‹{{ƒJHFd\\ultek]tslƒ||ƒ}ƒlri]bZdc\lek]cduzt{{ƒkd\b[UUTSult„Š}slelek””‹ek]‹„„tsl{{tred{{t{zmj]\lkscbV{{t|‚zult’…‹kd\lekUTS{{ƒekd{{ƒ”“›“Œ”{||ƒ„„œ¤¦‹‹‹‹„„›”›„Š„‹’Š{||tllƒ„„ek]tt{ƒ}ƒ{||‹’Šlldlek{{ƒŒ”•tslŒ”•‹’Š’ŒŒ›¢›“““”“›”š”ƒƒ||‚zmttf]c]cd…‹šddcztl|„…ƒ‚u|‚zuzt„„Š‹„‹{{ƒf]clksƒƒ|¤¤«²«››””š”„„Š{u{zllult‹‹‹fkk“Œ”’ŒŒ‹„‹‹„„tlllldsle‚|u£››{{ƒƒ||lrildd‚|ubVUttsultztfŠƒ}tll…‹‹rfk{{t…‹‹‹„„cbV{||mttƒƒ|UTS]bZUMRD;9\[bekdzllVTL{ttedkSKJ>B9f]c{zmredVTL„Š}Š}ƒb[U\[[{{ƒfkk‹‹‹{||lks{{ƒ[[Tllkdc\dc\‹‹‹u{{Šƒ}‹„„„Š„dc\lri‹‹„{zm””‹›¢›ljsle‰‘~²««[TT:97››”””‹¦§¨’ŒŒuztttsj]\f]cVTLbVU{{t{ttFD;JHFyfl‘Œ…zllmtttsldc\d\\kk]”š”“““‹„„”››””‹…‹‹šŒŒ‹“lks‹’ŠŠƒ}llk„Š„µ¶·œ¤¦…‹’{|||‚z|„…{||ƒ„„uzt‹„‹”“›ultšŒlrittsœ¤¦’ŒŒ{tt„Š„ult{||sleŠŠ}£››{zmslesreVTLtllsre’…‹i\V‚wlultš””lldztllldtllkd\VTLSKJƒƒ|ƒ}ƒlektslzlllriVTLd\\{ttultuzt\[[VTLrfkttsttsuztkd\b[Ulriƒ}ƒ{zmrfkJHFJHF74,b[U{{tVTLllktslsrelriƒ‚utsl|‚z‹„„ult‹…’bVU{u{ekdmttfkk£œ¥ƒ}ŠŒ‹“¦§¨{{ƒu{{f]cƒ}ƒJHFcbVllk‹’Š„Š}{||‹„„…‹‹£››{||lldŠƒ}|„…Œ”•Œ”•|‚z…‹’ƒ„„‘…„‹’ŠŠ}|{{ƒu{{JHF]bZredyl„lksllksreztf|‚z’ŒŒ’ŒŒ¤¤{{t{u{‹…šf]cd\\lldsle‹‹„|‚z„Š„Œ‹“\[[tllztlred“““{ttŠ}ƒtll…‹‹ek]bVUtsl‹‹‹²««š””‚v‚{{ƒŠ}|ultekdlek‹„„yle‹„„œ››œ››lld‹‹‹“Œ”tzl{||slemttuztMRKVTLJHFFD;FD;tzlD;9lldsre]cdJHFJHFddcaWMrg]VTLtslƒƒ|edklddlek{{ƒllkUTSddc{tttzlult{||llkultŠ}|ƒ„„‹‹„{{tSKJi\V””‹{zm””‹£››¤¤{||ŠŠ}‹‹‹VTL:97‘Œ…„Š„‹„„‰ƒv‹‹„ƒ„„‹‹‹[TTjcVkk]kk]VTLbVU%UTStslƒƒ|…‹’{{tlrid\\lksuztœ¤¦ldd””‹“Œ”{||¤¤“Œ”“““””‹ƒ}ƒ”››››”£œ¥z‚l¦§¨‹„‹ekddc\ƒ||…‹‹ƒ„„\UZultkd\‚v{VTLddc”š”lek›”›“““œ››lld›¢›ult‹„„kd\rg]‚|u{{tlddlrid\\ŠŠ}›”›‚wlred\[[sref]c‚|uVTLSKJVTL‚|uultredfkkd\\|„…dc\lldlektlllld[[T‚v{f]c{ttlri„Š„d\\zlllriultztl\[buztddclldrfkuztcbVllk‹‹„„Š„Šƒ}{||lddƒ}ƒ|‚zƒ||Š}ƒmttŒ‹“lks|„…”››tsl]bZ|„…ttsƒ}Štts\UZtts]bZultlldlks‚|uƒ||tllldd£œ¥ƒ„„llk…‹‹‰Š¡ƒ}ŠfkkŒ”•„Š„‹‹‹lld››”“Œ”‹’Š‹‹„›¢›\[b„Š„lldtt{d\\dc\„Š}ƒ„„‰|v‚|u‹’Š„„Šƒ„„‹„‹edk{||[[T‹‹„{{tƒƒ|‹„„‹’Š™š¤’ŒŒr]gŠ}|‹„‹‹„„œ››{{ƒ|‚zrg]llk‹‹„‚|uƒ}ƒƒ„„ƒ„„ƒ||rfk“Œ”‹‹‹tt{{u{zllkd\Š}|tt{sre‹’Štllƒƒ|\UZddcek]…‹‹‹„„|‚z\[b>B9\[[ddc\UZVTLJHFC8.JHFFD;ddcylecbVztllriztlllkddclek{ttttsllkllktts””‹‹„„ddclek{tt|„…tsl’ŒŒsrerfkcbV‰ƒv‰|v£››””‹‰|v“Œ”‚|u¤¤VZ[JHF‚|u{{tœ››Š}|ƒƒ|{{ƒ™š¤†~‘lldtllkk]‰ƒvsleD;9UMRultsle{{t‹‹„“““uztu{{Œ”•“““››””š”™š¤‘…„ult‚utldd[[T’ŒŒddcŒ‹“‹‹„“““Œ”•š””tts”››‹‹„Œ‹“”››œ¤¦“Œ”Š}ƒ¦§¨b[UllkŒ”•£œ¥›”›|‚ztslœ¤¦llklldlldrg]cbV‚|uVTLj]\{{tztlztl‹‹„red“Œ”d\\ƒ‚u‹’Š{ttFD;cbV{{t¤¤’ŒŒultztlSKJ]bZMRKkk]ƒ}ƒ“Œ”u{{tsl››”“Œ”‹’Š|‚zu{{Šƒ}‹‹‹ttsƒ}ƒylef]c›¢›]cdlridc\”››‹’Š{ttœ¤¦{zmultlld{||tllllk{u{ƒ„„[[Tdc\]cdlks…‹’lks‹’Š{{ƒtt{lks‹uŠbVZldd\[[{tt\[[]cd‚utƒ}Štllƒ}ƒ“““‹’Šƒƒ|Œ”•‹…’lks··Ä‹’Š‹’Š“Œ”’ŒŒkk]“Œ”›”›ttsuztllk{{t{||edkJHF“““‘Œ…”“›‚utuzt””‹›”›lek‚v{Š~‹tlltsl’ŒŒlriƒƒ|‹„„”“›ƒ||ultj]\‚|utts{ttlddƒ||b[Usleš””lri””‹“““{||Œ‹“ƒƒ|”“›“Œ”ƒƒ|‹„‹“Œ”ƒ||š””“““{{tslemttjV[tsl‹’ŠŒŒšllkmttSKJMRK]cdJHFD;9JHFSKJD;9fkkaWMedk‚v{ddcrg]{zm››”lld{zm„Š„tts„„Š{u{bVU|‚ztllƒ}ƒ“““|„…‹„‹lddttsŠƒ}lldŒ‹“tslrg]b[Uƒƒ|ztlƒƒ|‰|v‘ˆ}rg]››”µ¶·UUYLKR‰ƒv¤¤Š}ƒ™‹†ƒƒ|[TT{ttuzt‚|uƒ„„i\Vrg]FD;VTL[TT{||dc\|‚zƒ||tts]bZ\UZ››”’ŒŒŠ}ƒœ¤¦ƒ„„‹„‹‹’Š’…‹‹’Š|„…tt{dc\ƒ}ƒƒ„„„Š}jcVzll…‹‹lri¦§¨‹„‹„Š„ƒ„„lks“““›”›ekd‹…’‹‹„¦§¨¦§¨”š”d\\lks›¢›tslŠŠ}srerfksre{{t‘Œ…””‹‚ut‹„„›”›jV[Š}ƒ{||ƒ‚uƒ||tzlek]cbVmtt[[T‹„„lekSKJlld|‚z››”’ŒŒ’…‹‚ut|‚z[TT””‹…‹‹tsl|„…‹‹‹slelldFD;sreƒ||“Œ”|‚zƒ„„{{t‚|uƒ„„ƒƒ|”“›‹‹„‹‹„‹„‹£œ¥“Œ”‚v{‹’ŠŠƒ}{ttultuzt|„…MSSmttu{{ttsllklkstt{{||Š}ƒlekuztƒ‚uddcultttsƒ„„{{ƒ™š¤ldd”“›”š”™š¤··Ä„„Š|‚zfkk“““‹…’”š”tslztlƒƒ|uzt‹’ŠŒ‹“‹„‹‹…’tlllekdc\‹„„‹’Š“Œ”‘…„‹’Š›”›’…‹¨©´ƒ||VTL„Š}ƒ||ƒƒ|Œ”•{ttŒ‹“”“›””‹tts“Œ”u{{ƒ||ƒ„„’…‹‘Œ…‚wllks|‚zkk]ƒ}ƒsle“Œ”Š~‹‚v{œ¤¦redrfknƒ’…‹£››“Œ”tslŒ”•cbVztlƒ‚u{||ŒŒšƒ||UTSFD;ZbN:97:97SKJ[TTcbVsreSKJVTL[[T{u{[TTsleult‚wlcbVŒ”•dc\{ttlekƒ„„ztlnv‚mttƒ}ƒ‹‹„ƒ„„tllf]clddcbVdc\‹„‹kk]‘ˆ}ƒ||ƒ‚u””‹””‹‚wl‚|u£››“““¤¤\UZ>ECztf›¢›‹„„rg]iq][[TŠ}ƒllkztlkd\tts””‹redFD;{tt{tt‘…„|„…|‚zŒ”•ekd{{ƒ‹„„ƒƒ|ƒ||¦§¨¨©´²¬µ£››“Œ”‹’Šmttƒ„„tll{{tekd››”kk]Œ‹“‹‹„ƒ„„™š¤tt{”››‹„„Œ‹“‚ut“Œ””š”ekd’ŒŒŒ‹“‘Œ…{{t””‹tt{ƒ„„”š”‹‹„””‹Š}|‹„„{{tjcVƒƒ|ƒ||””‹‚wl{{t\[[d\\lld{||iq]rfk„‰vdc\d\\[TT\[[tts””‹llk|„…š””’ŒŒ‚v{ƒ„„f]csle{u{ƒƒ|…‹’lldSKJd\\tll‹‹‹‚|u£œ¥ztflld‹‹„””‹uzt{{t“Œ”Œ”•‹„„|„…‹„„œ››ƒ„„Œ”•ztlbVZddctsllld}‡’|‚z{{ƒddcŒ”•ƒ„„lksƒ}ƒddc“““\[[{||tt{{{ƒ””‹‹„‹„„ŠšŒ{tt“““ƒ||¨©´™š¤›¢›lkstt{ƒ„„…„’””‹{{t{u{œ››”“›Œ”•„„Š…‹‹‹„‹™š¤lriztlrfkf]czllztltsl›¢›ƒ}ƒƒ„„ultldd|‚zƒ||‹‹‹dc\‹‹„£œ¥š””b[Ukd\{zmtslŠ}|Œ‹“‹„„””‹ƒ||ƒ}ƒlriSKJrfkultf]cƒ}ƒ“““lks‚|u™š¤ƒ}ƒš””Š}|ƒ||Šƒ}‹‹„„Š„””‹{zmƒ}Š|‚z’ŒŒttsb[Ullk\[bFD;%UMR[TTtzlJHFVTL’ˆVTLlriŠ}|kd\Šƒ}ƒƒ|llkttsllkddcllkƒƒ|ult{{ƒ{u{„Š„Œ‹“u{{lksult‹‹‹‹„‹{||ƒ‚u{tt››”¤¤””‹‚|u‚v{¦§¨‰|v‹’Š›”›UMRJHF{{t””‹j]\‚|uttsb[Ub[Ured‰|v‚|u{ttztlD;9FD;{{ƒ“Œ”sle|‚z‹‹„œ¤¦llk[TT|‚z“Œ”‹„‹„Š„‚v‚µ¶·››”|„…œ¤¦mtt…‹‹|‚z”š”|„…{{tƒ„„{||”“›{||ƒ„„lkskd\f]c{u{‘Œ…{tt‹„„ƒ}ƒ¨©´{ttrg]‚|uldd{u{Š}|tllkk]tsl’…‹[[TVTLš””|‚z“Œ”‘Œ…‰‘~‰‰wtlllritsld\\JHF’ŒŒƒƒ|tslƒ||{tttts\[bekdllktsl‘Œ…‚|u‹„„lritlllek‹„‹|‚zdc\‹‹„lldttsd\\‹„„bVUtlltts[[T[TT{{ƒttsVTL{u{›¢›lridc\Š}ƒƒ||ƒ||‹‹„lddf]c{{t”š”{{ƒmttfkklldmttuzttt{lksVZ[{||ztlVZTƒƒ|llkultŒ”•’ŒŒ\[b‚v{‹’Š«²«ƒ||™š¤¦§¨¦§¨Œ‹“{{ƒu{{™š¤”“›ƒƒ|›”›ƒƒ|‹„‹|„…µ¶·›¢›™š¤„„Š™š¤‹’Šf]csre‹„‹tllllkkd\‹„‹‹„‹{||d\\llkult””‹tts‹‹„]bZ‹„„lld[[TSKJult‚v{{||’ŒŒ“““{||“Œ”tzli\V{tt„Š„Š}ƒ‹„„š””fkk\UZ{u{tllƒ||redƒ„„””‹ƒ„„„‰vuztdc\{||ekdj]\tlllddVTLMRK[[T>B9\[[kd\tsl\[[MRK*)(u{{{||redj]\‹‹„œ››ttsekd[TT[TTddc‹„„edk\[[tts|‚ztts|„…„„Šlek„Š„lddƒ}ƒ‰‘~‰ƒv‹‹„››”””‹””‹ ™‹†tll””‹µ¶·\[[,55‹‹„ƒƒ|‹’ŠjcVz‚l]bZttsztlƒƒ|‚utFD;sref]cVTL‹„‹“Œ”d\\œ¤¦››”œ¤¦„„Š™š¤lek”“›‘…„”“›tts“Œ”ª³·ª³·¨©´ÂÅÓ›¢›ª³·”››ƒ„„””‹|‚z“““{{tf]cultŒ‹“ƒƒ|{ttd\\Š}ƒŒ‹“tzl„„Š”“›ƒ}ƒtllƒƒ|redu{{zllkd\‚wlƒƒ|‹„„„Š}›”›i\V‰‰w‹„„Šƒ}{zmƒƒ|ƒ||lldbVUttsb[Uƒƒ|tygredzll‚v{\UZ[[Tkk]{{ƒlks››”kd\rr]lld‹„‹uztmwœ››ƒ||„Š„d\\ddcultzllŠ}|yle’ŒŒsle‚|ubVU{||SKJŠ}|[[TultŠƒ}ƒ||zllllktts‚utƒ„„uzt\UZMSSMSS|„…UTSUTS\[[ult\[b|„…“Œ”{||{||››”ƒ„„ultedkddc‹„„‚v{{{t”š”{||œ¤¦ŒŒš‹…š{||mttª³·Œ‹“¦§¨ª³·“Œ”‹‹‹Œ”•”š”ƒ‚u‹’Štt{llk{|||‚zf]ccbVtllmtt“““|‚z\UZ‚v{jV[sle[[Tkd\{||ttstts{tt‚|u””‹ztlkd\š””tts“Œ”„„Škd\‹‹„r]g‹‹‹tsl‹‹‹‹„‹Œ‹“sle‚ut|„…ƒ|||‚z“Œ”‚ut|‚ztts£››ƒƒ|£››¤¤“Œ”lrimtt‚utœ››|„…{ttek]JHFJHFFD;JHF{||MSSMRKƒ}ƒJHF|‚zƒ„„‹‹„‘Œ…dc\ƒ„„UTSyfllekf]c“““mttred‹…’llkŒ”•tts‹„„{tt‹’Štllœ¤¦ƒƒ|‰ƒv{zmŠƒ}››”›¢›¢—“Œ”{ttŠƒ}²««MRK:97£››{tt‚|usreSKJsrezll{{t‚|u‚|ubVZsrekk]SKJrfk’…‹Š}ƒ‹’ŠŠƒ}lks„„Š|‚zedkUTSƒ||”››™š¤š””Œ”•‘…„¦§¨œ¤¦œ¤¦››”|„…lri‘Œ…’…‹tllddcrfkf]cultš””£››{u{‹‹„{{t|‚zddc‹„‹f]c‚|u”“›…‹‹lri|‚zrfk{{t‹„„’ŒŒ„Š„{tt’ŒŒtslzllƒ‚uzll‘Œ…ƒƒ|ttsb[Ullkdc\ƒ‚uVTLd\\‹„‹f]cddcekdf]cf]c|„…£››Š}ƒtsl’ŒŒ{tt‚v‚{tt‹’Š„Š}lldSKJtllbVZztf“Œ”Š}|ultdkVƒƒ|zllƒ„„œ››‚v{{{t‰ƒv{ttred{{tƒ}ƒult{|||„…ultllk>ECMSSUTSllkddc…‹‹{{ƒmttfkkƒ„„{tt{||ekd{||f]clksddctlltll{{tœ››”››„„Š”“›ult”››ultŒ”•ƒ}ƒ›¢›ÌÖЦ§¨¦§¨™š¤”››‚|uuzt“Œ”Œ”•”“›sreœ››ƒ„„ƒ||‘Œ…{{tƒ„„ƒ„„ƒ||‹…’{{t{{t²««{tt„Š„{||ttsztl„Š„{ttkd\ƒƒ|ultƒ„„{||lld…‹‹›”›’ŒŒƒ||ƒ}ƒ{{ƒ…‹‹‚|ulddult|‚ztzlƒ„„œ››Œ‹“’ŒŒ“Œ”ztlƒ‚uztl{ttyfl…‹‹lddtll{u{VTL\[[FD;F=CUMRd\\ƒ„„[[TZbNedkUTS™š¤Œ”•µ¶·‚|u{{t{||rfkƒƒ|‹‹„|‚zƒƒ|ttstslŠ}ƒlriu{{]cd„„Š™š¤“““{{t“““{{t‹„„‘Œ…kk]‘Œ…{{t‚ut£››tll{zm²««llk7-2ŠŠ}””‹ƒ„„””‹cbVkd\‚wlƒƒ|tzlœ››yfd{||SKJPF=ƒ„„„Š„‹„‹‹’Škd\Œ”•|‚z{{ƒ]bZztld\\|‚zŒ‹“‹„‹tsl“Œ”ƒ}ƒ„Š„…‹‹„‰vœ¤¦„„Šd\\››”’ŒŒlldf]cŒ‹“{{ƒ‘Œ…rfktlllks›”›‹’Štts¦§¨{{ƒƒ}ƒtsl‹‹„MRKlks‹‹‹{tt{zmtll{||ƒƒ|””‹[TTredkd\Š}ƒƒ‚uddcƒ||ƒ||u{{lldbVZ[[Tek]\[[{u{leklekŠ}ƒ|‚zultsleekdtllkd\redllksleuztcbVlldFD;lekj]\ztl‰|v{tt‹„„ƒ||ƒƒ|“Œ””››ƒ}ƒult“““ƒ||i\Vredrfkult{ttultlrifkklld|‚z]cdmttultuzt„Š„ult^^qf]cƒ||ƒ}ƒfkk„Š}ƒ||”››uztf]c‹„„‹„„{||‹’Š“““|„…f]ctlltslddc¨©´„Š„¨©´¦§¨“Œ”˜Ž£lri„Š}ƒ}ƒ{||{tttt{ultlddzlluzt£››‹’Štzl‹‹‹{u{‰v|ƒ}ƒddc‹‹„›”›lldlldƒƒ|™š¤‚utƒƒ|‚ut‹„‹slekd\ult¦§¨ƒƒ|kd\{{t‚wl‹…’£››ƒ„„ƒ„„‚|u’…‹…‹‹lriztllekƒƒ|ƒ}ƒ£œ¥”››tll„Š}‹’Š‹„„“Œ”lld“Œ”Š}|Œ”•kd\VZTVTL:97UMR{zmekdUTSFD;MRK]bZ|‚z””‹””‹sle{{t|‚z{{t‹„„Œ‹“ztl{{tllkd\\sle|„…ttskk]llkldd‹‹„lektsl‹’Šztl{tt‹‹„{zm‹’Š‚v{Šƒ}ƒ||ŠŠ}²²¬VTL*)(œ››tzlœ››ljcbV|‚zzll””‹tzlkd\sreŠ}|74,D;9{{t”š”ƒ„„œ››tll„Š}{||ƒ}ƒ„Š„ƒ„„ultœ¤¦“““¤¤‘…„jV[yfd|‚z”››””‹ƒƒ|„Š}Š~‹ƒ||‹„‹tslƒ}ƒƒ}Šµ¶·””‹šŒµ¶·¦§¨{{ƒƒƒ|tt{œ››¨©´’ŒŒ[[Tddcek]slettsƒƒ|ª³·‹‹‹{zmultsle\[[kd\tslVTLƒƒ|{{tlddlddulttll‹‹‹JHFultred’ŒŒtsl{{ƒbVZmttlri‰v|mttkd\kd\dc\‹’Š›”›|‚z„Š}{{ttslUTS{{t{ttljtlltll{u{’…‹‹„‹tts‹‹„’ŒŒ„Š„ultredlddkd\{ttult{||edkultJHFmtt\[bfkk{tt|‚z„„Š…„’ult|„…{||‚v‚UTSdc\“““Œ‹“llkŒ”•‰|v‚v{Œ”•‹‹‹u{{mtt{{ƒ“Œ”Œ”•‹‹‹ƒƒ|‹’Š{{ƒ””‹‘…„£››‹’ŠŒ”•ƒ}ƒ‚v{{tt[[T‚|uƒƒ|¤¤ƒ||’}™„Š}|‚z“Œ”‹„‹Š}|”“›››”{zmƒ||{{tmttttsƒ„„zllƒƒ|›¢›uzt‹„„’ŒŒd\\{{ttslztf|‚ztslƒ}Šƒ}ƒtslsle””‹ƒ}ƒ{u{kd\d\\””‹››”„„Š„Š„ƒ}Š„Š„ekd”š”“Œ”rfkJHFƒ||bVUlekb[USKJJHFFD;MRKSKJVTLJHFƒƒ|\UZ|„…f]cƒƒ|‚|uŠ}|llk…‹‹ekdƒ||lri{||kd\MRKred{|||‚ztts‹‹„ƒ||ultu{{{||…‹‹{||kd\‚|u«²«„Š}ŠŠ}{{tsle‚|uŠŠ}µ¶·JHF-1+|‚z“““‘Œ…rg]kk]jcV‰ƒv”š”b[U‹‹„ƒ„„b[UVTL3+*‘Œ…„Š„‹…’ttsVTLƒ}ƒtts|‚zmtt£œ¥””‹tt{‹‹‹›”›¦§¨œ››ƒ}ƒ”“›llktt{¦§¨¨©´£››‹„‹{tttslf]clkstsl“Œ”‹…’{{ƒƒ||‚v‚”š”¦§¨„„Š‹„‹Œ‹“‹‹‹ultttsdc\f]c‚ut„„Šƒ||‹‹‹redi\Vkd\zllVTLldd{||[[Tllkƒ||ttssredc\ƒ„„bVUttsSKJƒ}ƒultllklriœ››redztltsl„Š}d\\ztlƒ„„{tt’ŒŒdc\‹’Šd\\”š”‚|uztlŠ}|cbVkk]kd\“Œ”ƒ||ƒ„„Š}|””‹’ŒŒ‚wl“Œ”kd\ult{{ƒultƒ„„lldfkk|„…JHF\[btlluzt‹„„„„Š{{ƒ}|’Œ‹“{{t{u{”š”’ŒŒƒ„„ddcƒ„„tll„„Š‹…šœ››Œ”•{||”››’ŒŒlriŒ‹“”››{tt|„…|‚zƒ||›”›””‹ƒ}ƒ”“›edk…‹‹|‚z“““‹‹„sle…‹‹lek¦§¨{||tslƒ„„ƒ}ƒŠ}ƒ{{t{{t“““{{t|‚zdc\‹‹‹rfkœ¤¦””‹’ŒŒ‹„„Š}ƒ‹„„{||‹’Š‘Œ…llkƒ„„’…‹ult|„…‹„„‹„‹›”›Œ”•{{tslett{”š”‹„‹“““{{ƒƒƒ|””‹‹‹„Š}|bVZlldlekztluztkd\D;9VTLFD;[TTsleUTSf]c&&\[b„Š„‹‹‹‹„‹‚|u‹‹‹‹’Š…‹‹Š}ƒŠ~‹””‹sleƒƒ|ƒ}ƒ‹„‹ƒ}Šlld‹‹„ztlttstts‹‹„“““‹’Š”š”‚ut‹‹„lld‹‹‹ƒƒ|‚v{yletslƒƒ|¦§¨:9774,ƒƒ|ƒ‚u{{t‚|urr]rg]‘Œ…tslyle{u{ƒƒ|ƒƒ|VTLSKJŠŠ}œ››ƒ}Š¦§¨ƒƒ|ƒ„„„Š}tt{lri‹’Š£œ¥uzt…‹‹“““””‹£››‹„„ult|‚z«²«|„…ƒ||‘Œ…™š¤›¢›…‹‹dc\Œ”•ƒ„„d\\[[TUTSrfkldd‹‹‹|„…ƒ}ƒ“Œ”Œ‹“™š¤“““„Š„j]\“Œ”b[U“Œ”{{t‹„„š””‹’Škk]{ttƒƒ|kk]uzt|‚ztts“Œ”f]c{{tsletslƒ}ƒd\\‚v{|‚z{{ƒultƒ„„’ŒŒ‹‹„{||Šƒ}Œ”•uzt‹‹„‹‹‹¦§¨{||jcV\[bƒ||{u{”š”‹„„š…Žult‚ut{{t‹‹‹‹‹‹tllŠ}|Šƒ}‹„„{u{ƒ„„Œ”•”“›f]cƒ}ƒ‹’Šlri|„…lri]cd\[[ekd…‹‹‹„‹tt{{{ƒ…„’‹‹‹tsl{u{{||ƒ||„„Šƒ„„ekdtllŒŒš†~‘llk„„Š…‹’“Œ”“Œ”„„Š„Š„Œ‹“’ŒŒ“““‚wlult‹„„µ¶·Œ‹“…„’‚wlult|‚z„Š}ƒƒ|ult“““ult{tt{{t{ttƒ„„“Œ”£››ƒ||sle’ŒŒtsldc\{||œ››lek{{t{{tŠƒ}‹„„“Œ”£œ¥¦§¨“““¦§¨ƒ„„ƒƒ|“““tll‹‹‹‹„„„„Šmwmttd\\mttztl‹‹„{u{š””’…‹{{t‹’Š|„…‹„„redlldtllŠ}|‘Œ…rg]uzttygC8.dc\[TT‹‹‹ldd\[bmtt„Š„”“›\[bkd\rfk…‹’{{t[[T‹„‹|„…š””‹‹„ttsŒ”•‚v{’ŒŒ{{tslellk”“›””‹‹„‹¦§¨‹’Š£››››”ƒƒ|‹’Š¤¤‹„‹ztl››”‚utü¿SKJ:97kd\kjVŠƒ}ztlkd\ŠŠ}d\\tsl|‚zuztƒ}ƒ{zm[TT‹„„{zmuzt”“›£œ¥ƒ‚u£œ¥ƒƒ|b[U£œ¥{||{u{Œ‹““Œ”{{ƒ{{t’ŒŒ‘Œ…››”Œ”•{||‹’Š”“›””‹£››tts\[[ek]|„…u{{ƒ‚ulksult{{t{{ƒƒ‚uu{{”“›’ŒŒ“““„„Š‚ut‹‹‹Œ”•ƒ}ƒ‘Œ…”“›“Œ”ª³·ƒ||b[Usreƒ||sreŠƒ}tt{ƒ||‚|u“““ult{ttsretzlŒ”•d\\lrir]Z|‚z‚ut“Œ”‘…„‹‹„œ¤¦tts{{t‹„‹{{ƒ{ttek]tslkd\d\\tll‹‹‹£››‹„„¦§¨››”tlllddf]cƒƒ|llkŠ}|„Š„ƒ||ldd£››sreƒ}ƒ{{ƒ“““ƒƒ|]bZ…‹‹„Š„{||…‹’{u{|‚z|„…ƒ}ƒmtt{||…‹‹|‚z‹„„ttstt{ƒ}ƒtllultƒ„„ldd£œ¥™š¤¨©´œ¤¦“Œ”“Œ”š””¦§¨«²«‹‹‹ƒ„„ƒ‚u¦§¨‹‹„‹’Š‹„‹‹…’f]c„„Štts››”””‹››”µ¶·‹…’tzl‹‹‹””‹|‚zŠ}ƒ‚ut{||ldd’ŒŒ””‹|„…{tt{{t„Š„{zmuzt””‹›”›“““£œ¥”“›œ››””‹{u{ƒ||{tt›”›ttsƒ}ƒlddldd{{t[TTllk‚|u¦§¨ƒƒ|”“›ƒ}ƒu{{‹’Šƒ„„’ŒŒ‹„‹‹„‹Š~‹ztf{{tsleŒ‹“kk]D;9ult{{ƒ|‚z…‹’mttUUYƒ„„d\\fkkzll‚|u›¢›ƒ„„uztƒ}ƒ{u{’ŒŒ‹‹‹\[[‹„„Š~‹ddc]bZ[[Tddctsl‹’ŠŒ”•Œ”•tslb[Uƒƒ|{||””‹¤¤“Œ”£››‚v{ztl¦§¨[[T74,››”„Š„{zmŠƒ}Šƒ}|‚z{zm|‚zllduztœ››‹‹„ƒ|||‚z‹„„Œ”•Œ”•“““ztlldd[TTddc|„…{u{{u{’ŒŒ‹„‹”››Šƒ}Šƒ}„„Šƒ„„VZ[u{{…‹‹¦§¨‹„„ƒƒ|ldduztdc\lksŒ”•lriŒ”•ult‘…„{tttsluzt”“›Œ‹“{{ƒd\\œ››‹’Š‹„‹ƒ}ƒ‘ˆ}ultŠ}ƒzll{ttœ››lddœ››››”Šƒ}{{t{{ƒlddtsl{||ƒ‚uƒ||kd\‚|uultj]\tllllkrfk‹‹„ƒ||{{tœ››ƒƒ|›”›{ttlld|‚zrfkj]\‚v{mttƒ}ƒlekrg]Š}ƒ‘…„‘…„ztl“Œ”›¢›‘Œ…tsllddƒ„„{tt{{ƒƒ}ƒredƒ„„„„Šuztkd\b[Utts{||{{ƒ„„Šƒ„„|„…{u{~’“mttlks[[T{||llkdc\rfkmtttt{|„…””‹ƒ}ƒ“Œ”f]c‹…’™š¤£››››”Š~‹tsl‹’Š{{ƒtt{‹‹‹{zm””‹£››ƒ„„¦§¨ƒ}ƒŒ”•‹‹‹‹’Š””‹œ››™š¤Œ‹“‚|uœ¤¦‘Œ…{||“““‚v{ƒ}ƒ‚|uŠƒ}lldƒƒ|lld‚ut¤¤‹‹„”š”‚ut‹„„›”››”›‹„„tts›”›š””‚utƒ„„“Œ”Š~‹mw„„Š{ttƒƒ|ddc“““ƒƒ|››”lks”š”{u{…‹‹|‚z”››“Œ”‹„„ƒ}ƒ‹„‹ƒ||d\\sred\\|‚z‰|v™š¤ttsŒ”•\[b>B9f]cJHFtll{||uztkd\tsl{{ƒŠ}ƒ“Œ”„„Šš””|‚z””‹„Š}›¢›{||lld{{t\UZmttƒƒ|‹„‹llktslSKJVTLkk]kk]{{tš””Š}|’ŒŒtll¦§¨VZT-1+‹‹„””‹ƒ||‘…„‚|ukd\tzlVTL[TTllkŠƒ}ƒ‚ulrilks{{t|‚zlksƒƒ|sre‹‹‹[[TUTSUUYƒ}Šzllœ››£œ¥”š”››”ƒ||‹‹‹lri|„…cbVŒ”•…‹‹‹…’slettslrikk]lddlkstts|„…”“›‚|u[[TŒ”•„Š„ttsekdldd„Š„tt{„Š„„„Š‹‹‹[TTztltts{u{‚ut|‚z”š”””‹ƒ‚uƒ‚u‘Œ…‹‹‹tll‹„„{u{lddkk]‰ƒvlddredbVUtlllldƒ}ƒtt{ƒ||ƒƒ||‚zƒƒ|b[Utts{{t{u{Œ‹“sleSKJd\\d\\„Š}sleldd[TTddc’…‹ek]‹‹‹„Š„“““‚ut‹‹„llk{u{{{t””‹„„Š[TTkd\|„…slelrimttlek|„…ƒ||‹’ŠŒ‹“{{ƒ…‹’{{ƒ{||llk{|||‚z’…‹‹…’|„…{||ƒ||{u{ƒ}ƒ‹‹‹{{ƒƒ}ƒ¦§¨›”›ƒ„„|‚z„Š„ult¦§¨”››’ŒŒ“““{||”››{{ƒ‹‹‹|‚zlld„Š„ŠŠ}‹’Š{||›”›“““„Š„¤¤“““Š}|{u{{u{ƒƒ|””‹ƒƒ|tslœ››¤¤ƒ||ƒƒ|””‹{zm””‹d\\f]c‹‹‹„Š„sle{||Š}ƒ››”“Œ”{u{”“›£œ¥””‹uztbVU|‚z‹‹‹kd\‹‹‹tsl…‹‹“““|‚z”››œ››’ŒŒ]bZ‹„„š””tll„Š}Šƒ}sletzl{{ƒlddtzltt{SKJJHFFD;llk|‚z››”tsl|‚ztt{sle“Œ”ztl{u{kd\Œ”•‹„‹ekd{u{[[TbVUtts|‚ztsltt{lldlrib[UaWMcbVdc\tslŒ‹“ƒ}ƒtsl‰|v’ŒŒJHF3+*ƒ}ƒ””‹‚|u‚wl””‹tsltslsletll„Š„lriƒƒ|u{{sle“““{||ddclri‘Œ…\[[ttsf]cUTSzll“~ˆ{u{’ŒŒ¦§¨sreƒ||’ŒŒŒ”•mtt|‚zf]cttssle¦§¨ddctsl:97ek]VTL[[T‹‹‹ttslri{||ƒƒ|{||“““”››”“›„vŒƒ|||‚z‹…’{u{zll‚v{‹„‹„Š}ult„Š„‹„„‚|u‹„„ztlœ››‹‹‹ƒ„„ult”“›‘Œ…sreyfd‹„‹sleredd\\kd\bVUtts‹‹„sreƒƒ|’ŒŒ‘Œ…]cddc\{||ttsredredUMRd\\…‹‹‚|ud\\yleŠ~‹‚|uƒ„„‹„„‹’Š{tt‹„„„Š}{u{ttsreduztƒ}ƒtll‹’Šƒ„„{u{\[b]cdyl„lksƒ„„|„…”››|„…Œ”•ƒ}ƒ’…‹llkƒ„„{{ƒ„Š„“Œ”ƒƒ|ƒ„„ƒ}ƒ›”››”›“““”“›Œ‹“››”›”›Š}|‹’Š¦§¨”››|‚ztsllld‚|uƒ„„„„Šult’ŒŒ‹‹‹|‚zš””›¢›‹‹„\[bƒ}ƒ{tt|‚zsleœ››ult‚|u‚v{Šƒ}š””tslƒ„„ŠŠ}{zmsle‹‹„ƒƒ|‚|u’ŒŒ£œ¥‹„„{u{ƒ„„‚utlldŒ”•{{t¦§¨ultƒ||ƒ}ƒ‹„‹ƒ„„ƒ||¤¤tts‚|u‹„„”š”dc\tt{”››¦§¨œ››£››Œ‹“Œ”•’ŒŒzll|‚zj]\[[TŠ}|SKJ‹„„ŠŠ}SKJVTL[TTlrimttddc‚wl{{tu{{Œ‹“tt{ƒ||{u{‚v{b[Utsl„Š„{{ƒŒ”•Šƒ}lldlekƒƒ|‹’Šultttstsl‚v{{zm¤¤tsl””‹››”‹‹‹“““{tt«²«JHF*)(ƒ}ƒuztƒ||f]c‚|udc\‚|ulritllUTS‚|ulri”š”““““Œ””š”Œ”•‘ˆ}SKJ‰ƒvlldekd\[[UMR{tt£››‹„„£›››¢›œ››Šƒ}™š¤‹’ŠlksŠƒ}ƒ„„‹’Š{{tred„Š„lldSKJ{||tslŠ~‹uztlri™š¤ƒƒ||‚z™š¤…‹’”“›”“›ƒ||¦§¨œ››ultƒ||zllztlŠŠ}£››dc\ƒƒ|Šƒ}’ŒŒrg]£œ¥ƒ„„|‚z”“›d\\tlltsl{ttƒ„„rg]ultSKJ{||ƒƒ|{{tsre{{t‹‹‹‘ˆ}ƒ||tsld\\mttƒ„„{ttƒ„„‹‹„ƒ„„slešŒldddkVbVU{||”“›{||mtt‹’Š‹„„uztllk{{ƒ‘Œ…ƒ}ƒŒ‹“lld{||[[TbVU\[bd\\\[bedkƒƒ|]bZ…‹’u{{Œ”•„„Š‹’Š|‚ztts‚|u{u{¦§¨ƒƒ|ƒ}Š{{ƒ¨©´¦§¨ƒ„„¨©´„„Šzll{u{„Š„|‚z‹‹‹”“›leklld””‹[[TlldŒŒš{{ƒ|„…„Š„|‚zztlœ¤¦‚utVZTƒ}ƒ””‹ŠŠ}››”“““£œ¥š…Ž{tt[TTkd\ek]‹’Šƒ„„‹‹„Šƒ}‹‹„‹‹„Š}|‘Œ…‹„‹ƒ}ƒŠ}|ƒ„„Œ‹“„Š„ttstslš””ƒ||„Š„››”“““‹’Š{u{‹’ŠŠ}ƒƒ||ƒ||„Š„ƒ}Šƒ||‹’Šƒ||”š”‚|uƒ„„”“›bVUƒ||rg]ztl|„…ult[TT{{tƒ„„slelrif]c{{ƒldd{|||‚z“““{{t‹‹„{||d\\f]ckd\VZTtts{u{¦§¨{tt‚v{‹’Š“““lksƒ„„”››‹’Šƒ„„šŒ¤¤›¢››¢›«²«£œ¥›¢›¦§¨‘Œ…””‹VTL*)(sreƒƒ|lriztl‚|uVTL””‹{{t‘Œ…„Š„ƒ}ƒ”š”‹‹‹{tt[[T|‚z„Š„‹‹„b[U£œ¥{tt]cd…‹‹£››’ŒŒœ¤¦‚ut“Œ”ƒ||ƒ}ƒƒƒ|ƒ}ƒ…‹‹z‚lŠ}ƒ„‰vsle[TTUTScbV‚|udc\‹„‹ŒŒš™š¤{||ƒ‚uƒ}ƒ›¢›u{{‹‹‹“““”››‚v{ƒ}ƒtsl£œ¥ƒ}ƒtll‹‹‹‚ut|‚z‹’Šek]zll{zm››”‰ƒv{{tuzttll‰|v„„Šƒ}ƒbVUztl›”›sleredƒ}ƒlddŠ}ƒsle””‹ƒƒ|llddc\””‹{ttllkd\\{ttkd\tll|‚zj]\”››Šƒ}ƒ}ƒ‘Œ…{ttŠƒ}šŒllk‹’Šllkƒ||‚v{ƒ}Š””‹tllŒ”•{{ƒ“Œ”tts„Š„tslmttf]c{{ƒmtt“““uzt{{ƒ|‚z|„…Œ‹““““{ttVZ[{ttŠƒ}uztŒ”•‚v{Š~‹…„’ƒ||tll“““”“›””‹‹„„’ŒŒœ››Œ”•{||ddc‚v{‹‹„Šƒ}”››‹‹„“Œ”™š¤Œ”•‹‹„”š”¤¤››”dc\{||£››’ŒŒ””‹’ŒŒrfkŠ}ƒš””Šƒ}ztlŠŠ}tsl„Š„œ››ztf{{t{ttkd\sle‹„„”“›‚|u|‚zultŠŠ}‹„‹‹„„‹„„··Ä‹‹„£œ¥Œ”•ƒƒ|‹„„j]\ƒ}ƒŒ‹“red„Š„™š¤¦§¨Œ‹“”“›‚|utsl¤¤{||‚utlldtzl…‹‹{{tSKJ‚utVTL{{t’‘~f]cJHFlrittsŒ”•ŠŠ}“““‹‹‹”š”ultj]\ƒ}ƒ’ŒŒllktsllksƒƒ|“““’ŒŒ”š”{zm„Š„{{tƒ}ƒƒ„„tsl››”‹’Š””‹›¢›’‘~²¬µµ¶·µ¶·¤¤¦§¨\[b)+2Šƒ}””‹ƒƒ|››”‘ˆ}dkV‹’Š‚|u‹‹„‹‹‹Š}ƒsreVTLsle‚|uŒ”•lrimttztl‹‹‹|„…\[[lrizll’ŒŒ‚|uuztVTL¤¤“Œ”šŒ“Œ”‹„‹lld“““”š”“Œ”Šƒ}‹„„lri‹‹‹f]ctsllri{{ƒ™š¤¨©´‹‹‹”š”…„’{{ƒ{u{‹„‹™š¤tllsleŠƒ}{u{‹‹‹‹’Šƒ}ƒsle{ttj]\„Š}ldd{zm‚|u””‹ƒ||‹‹‹sle‹„„„„Šdc\‰|vj]\‹‹„“““‹„‹]bZŒ‹“”››tll{{t‹’Š{zm‹„‹{u{‚|u“““Œ‹“kd\’…‹ttsedktlllddsleztf{u{ƒ||‰ƒv{tttsldc\‚v{‚|u{u{ƒ‚u›”›””‹edk{u{ƒ„„ttslldult{{t{||™š¤|‚zuzt|„…Œ”•|„…|„…|‚zlksu{{{zmƒ„„lekŠ}ƒtt{ƒ}ƒ““““““Œ‹“Œ”•‹‹‹£››ultlksƒƒ|ƒ„„„„Š{||‘Œ…”š”š””‹’Šƒ„„„„Š|„…ttsŠ}ƒ‘Œ…‹‹„‹„„{{ƒultœ››”“›¦§¨›”››”›yfl‚|u””‹‘Œ…””‹sre””‹ŠŠ}„Š„‹‹‹yfdztl‚|u‚|uƒ„„‹’Š‹‹‹‹‹‹‹„„{ttœ››’ŒŒ‹„„|‚z|‚zrfklri{ttult“Œ”¦§¨¦§¨›”›‹„‹ƒ„„|„…›¢›‹‹‹{tt‹‹„{{tš””uzt„Š}lldztfVTLSKJsleuzt[TT:97f]cmtt\[[lri”š”™š¤{{tmttƒ}ƒ“Œ”{u{¦§¨„Š„ƒƒ|“Œ”‹’Šƒƒ|‹„‹„Š}ek]tlltt{[TTƒ„„“““””‹ƒ‚uŠŠ}”š”¦§¨™š¤£œ¥››”¦§¨¦§¨JHF*)(‹‹„‹‹„lri‘Œ…ztliq]‹’Š‹‹„‹‹„lld{u{VTLtsld\\ƒƒ|ƒ„„uzt™š¤ƒ||uzt‹’Šu{{u{{tll‹„„œ¤¦ulttts{||£››¤¤œ››Œ‹“‘Œ…rfk“Œ”š””œ››‹„„ƒ„„ldd\[[{{t„Š„{ttƒ„„“Œ”tt{ƒ„„u{{|‚zultœ››red‹‹„²««ƒ||{{ƒ“““tll‹„„b[U’ŒŒ{||tts{zmslei\VŠƒ}{tt‹„„‚utddcddckd\‚|ud\\„Š}tllƒ||zll‘…„UTStll|‚z””‹ƒ‚usle“Œ”{u{ttsŠŠ}Šƒ}{||{ttƒ„„f]ctll‚wlš””lldsleƒ|||‚z‹‹‹”š”›”›‹‹„“““{u{ultttstts{ttƒ||ƒ||‹‹‹lksƒ||lriu{{|„…„„Š„„Š|„…VZT]cdu{{{{ƒ]bZ‹’ŠŠƒ}™š¤’ŒŒ{u{tll“Œ”lri‹’Š„„Š™š¤¦§¨Š}|sleƒƒ|ulttts‹‹‹£œ¥””‹‘Œ…«²«””‹Œ‹““““{{tJHFztl{{tŠƒ}ultŠ~‹tll‹„„£›››”›£››Š}|‘ˆ}lj²««lri‹‹„{zm‹’Š””‹ƒ„„Š}|zllkd\šŒ‹„„‹‹‹|‚zƒ||UTS{tt{||š””’ŒŒ‹‹„‹„„tll\[[Š}|{tt{u{’ŒŒŒ‹“‹’Šƒ„„‹„‹Œ”•œ¤¦‹’Š“““¦§¨ƒ„„œ››“Œ”|‚z]cdztlVTLSKJŠƒ}…‹‹Œ‹“MRKSKJuztd\\mtt‘Œ…„„Š‹„‹“Œ””“›“Œ”›”›œ››‹‹‹ƒƒ|tt{|„……‹’ƒ}ƒ‹’Šƒ}ƒ‹‹„ttslkstllƒ„„š””tsl›¢›{{t‚|ullkƒ||ttsƒƒ|¦§¨MSS*)(cbV„Š}Œ”•{{tƒƒ|cbV’ŒŒdc\‹‹„sreŒŒšztlekdldd‚|u‹’Š‹’Š¦§¨¦§¨¦§¨|‚zJHF¦§¨ƒƒ|[TTred[[T‹’ŠŠ}ƒœ››‹’Š²««Š~‹{zm””‹llk’ŒŒ{{t‚ut…‹‹„Š}|„…›¢›”››{{ƒlksƒ}Š|‚z„Š„…‹‹‹„„™š¤ƒ}Š‚wl””‹‚v{Œ”•yflf]clld{||‹’Š‚|uddcdc\uztb[U‹‹‹ƒ||{||²««Š}|ƒ„„tllkd\„Š„lek‚ut{ttƒ}ƒtt{ƒƒ|lektll„„Š„Š„ztlrg]”š”tts{u{lld‚v{{{tddcVTLƒ||ƒ„„‹’Šultƒƒ|sleiq]]bZlri’ŒŒ›¢›Šƒ}Œ‹“\[[‰v|sleƒ||’…‹{ttœ¤¦”“›“Œ”{{tu{{u{{fkk“Œ”ƒ}ƒmtt{{ƒ\[bŒ”•tsl„Š„{{tkd\lekultddc{u{UMRuzt‹‹„uzt›”›¦§¨ƒ‚u”š”Œ‹“…‹‹{{tllk¦§¨‘Œ…“““µ¶·ƒ„„{u{’ŒŒiq]‹‹„tllŠŠ}‹‹„‹„‹ƒ„„šŒ{{ƒ‹„„’ŒŒš””’ŒŒ²««Šƒ}{tttslƒƒ|ttsuztŠ}|ƒ||b[Utsl››”š””Œ”•„Š„uzt“Œ”„„Š{u{ƒ||ultƒ}ƒ‹„„{ttedk’ŒŒSKJsle¦§¨tt{ƒ‚u“““œ››“Œ”„Š„‹‹‹¤¤š””””‹Š}ƒ¦§¨…‹‹sle‹‹„cbVrr]SKJdkVŒ‹“Œ‹“MRKf]ctzlmwekdŠƒ}ƒ„„›”›‹’ŠŒ‹“”“›“Œ”ldd”››„Š}tts‘ˆ}…‹‹£œ¥‹‹‹ƒ„„{||Œ‹“ƒ„„‹‹‹“““tll|‚z{{ttslztlƒ„„Š}ƒƒ„„ult²¬µ[TT*)({{t¤¤„Š„’ŒŒšŒlks{zm{ttƒ||{{t„„Šuzt‹’Štslyle””‹{{t‹„‹””‹”››Œ”•|‚z¨©´²««ult‹’Šuzt{||f]c””‹{tt››”‹‹‹¦§¨›”›mtttlltzlttssle]bZ„Š„ƒ„„„Š}lri\[[™š¤\[[uzttt{tts{ttƒ„„£››ƒƒ|uzt¦§¨ttslddb[U‹‹„|‚zƒ„„ddc{{tlriztl“Œ”ŠŠ}‹‹„š””ztlttsztllddb[U‹„‹‚|uslekd\{{tŠƒ}’ŒŒ“Œ”|‚z””‹{||›¢›„Š„{{ƒ””‹‹‹„j]\ƒƒ|VTLtll“““|‚z¦§¨{u{“““š””””‹ttsllk{{tŒ‹““““œ››tllztl|‚z’ŒŒ£››ƒ}ƒ¦§¨tlledku{{ddc|‚z|„…”“›ekdmttmtt|„…ƒƒ|tll“““ztlztlultult…‹‹ttsƒ}ƒ‹‹‹‹„„Œ”•£››¦§¨‚v{ƒƒ|”“›œ››Œ”•ŠŠ}¨©´¦§¨›¢›¦§¨›¢›¦§¨‹„‹ƒƒ|ƒ„„{{t‹‹„{zmœ¤¦{{ƒlddƒ||‹„„”“›“~ˆš””œ››‹„‹‚|u‚|udc\›¢›””‹ƒ||‚|uƒ||£››Šƒ}„Š}ƒ„„‹‹‹””‹ª³·„Š„u{{ƒ}ƒš””ƒ}Š{||““““““…‹‹ƒ||tll‹„„tts£››ƒƒ|lddedklld‹‹‹””‹ztlkd\“““£œ¥¤¤ƒ„„‚|ukk]b[U{tt‘Œ…”››†~‘mttƒ}Štts{||llk‹‹„VZ[{ttƒ||“Œ”“Œ”‹…’mwmttuzt{||¦§¨ƒ„„ƒ||Œ”•Šƒ}‹’Šœ››„„Š‹’Šddcƒ||””‹[[T{u{{zm£œ¥{{ƒƒ}ƒŠ}|”š”LKR)+2ƒ‚u‹’Š“““d\\Œ”•Š}ƒ‚|usleuzt””‹tt{‹„‹VZ[VTL‹„„„Š}\UZ‚|uƒƒ|…‹‹u{{|‚z…‹‹”“›£››‹‹‹lriuztcbV‚|u’ŒŒ‹„„„Š„››”„Š„„„Š‹’Šƒƒ|ƒ}ƒƒƒ|tsl\[[|‚zu{{‚|ulks£²u{{”š”œ››tzlŒ‹“|‚z“““’ŒŒƒƒ|‹‹„ztl{u{{{tœ››lritts‰ƒvtslsleylelrirg]¤¤ztl‚|uƒ„„ultƒ}ƒztlcbVf]cš””d\\‚|u{zmŠ}|{u{lldtslddcƒ„„|‚zƒ‚u””‹ƒƒ|tsl{||d\\sle‚|u{||sre‚|u‹„‹‘Œ…d\\‰|v‹’Škk]tlltsl‹‹‹uztŠƒ}sreŠŠ}ƒƒ|‹„‹„Š„ƒ||{u{„Š„Œ”•{{ƒ”››„„Š|„…ttsŒ”•|„…‹„„‹‹‹„Š„ztlƒ„„Š}ƒƒ„„{||‹’Š¦§¨”š”œ¤¦¦§¨¦§¨£››µ¶·²««‹’Š“““‹„„Š}ƒ¤¤µ¶·ª³·””‹¨©´‹’Štt{sreŠ}ƒ’ŒŒš””ddctslult›”›{{ƒ‹‹‹ƒ}ƒ›”›‘…„‹‹„tll››”|‚z|‚z¦§¨™š¤‚|u„Š}‘ˆ}››”””‹yle‹‹‹‹‹‹{||¦§¨‹’Šllk„„Šƒ}ƒ“Œ”‹„‹£œ¥‹’Š‹’Šf]cred…‹’ldd”››ldd|‚z’ŒŒ”››¤¤ƒ‚uultdc\£››ztl”š”‹‹„|‚z‹‹„VTLš”””š”‹’Š{u{Œ”•lek{{t‚v{llk‹’Šu{{‚v{lekƒ}ƒ‚v{‹„‹ƒƒ|{tt|„…llk¦§¨Š}ƒ’ŒŒƒ„„¦§¨‹‹‹™š¤‹’ŠŒ”•‹„‹ƒ„„Šƒ}kk]ult‘…„“Œ”›”›f]c[TT¤¤JHF:97sreƒƒ|‹„‹”š”‹‹„{ttƒƒ|[[Tb[Uƒ||‹„„Œ”•lldtlllrilld[[T|‚zƒ}ƒtzl{||mttƒ„„{{t››”‰‘~ultƒƒ|‚|u‘Œ…’ŒŒƒ||ƒ}ƒtslœ¤¦|„…‹„„dc\\UZ\[[{{ƒddcztlVZ[ztlƒ}ƒŒ‹“}‡’„Š„|‚z“Œ”ƒ}ƒlriddcŠŠ}{{tœ››sreƒ}ƒ{||‹’Š|‚z{ttdc\ttsƒƒ|lldkk]ztlSKJi\V[[T{{ƒek]ƒ||‹’Š{ttzll{ttj]\ƒƒ|zll“Œ”‚utztlœ¤¦llk{tt{||ƒƒ|ztlŠƒ}zllllkdc\lldultUTS‚|ub[UsleŠƒ}sre››”‹‹‹ƒ||””‹{{t“Œ”|‚zŠƒ}‘Œ…“““{{t“Œ”{||\[[{u{{|||„…]cd|„…‹„‹{||ƒƒ|¨©´‹‹‹{{t{u{{zmŠƒ}‘…„zllƒ„„red‹‹‹‹‹„”š”Œ”•|„…“““‹‹‹£››””‹„Š„¦§¨¦§¨›¢›¤¤²««‹‹„”š”{{t‹„‹‹’Š‹„„¨©´ƒƒ|µ¶·tzl{||{{ƒŒ”•¦§¨¦§¨‹„‹£››ƒ||’ŒŒ{tt‘Œ…‚wllriŒ”•“““ƒ||‚|u‰ƒv””‹Šut“““”“›œ¤¦lri‹„‹£œ¥”››‹’Šš””{u{{tt{||{||{||ult‹„„‹„‹ƒ}ƒ„„Šƒƒ|ƒ||{tt‹‹‹‹‹„{zmyleƒƒ|‹‹„‹„‹”“›‹’Šuzt””‹]bZ“““¤¤|‚z£œ¥u{{ult]cdf]c„Š„ƒƒ|“““„Š„„„Šult“Œ”‘Œ…››”dc\ƒƒ|‹„‹ƒ„„lekredsre‚v‚{||‹„„{|||‚zbVUrfk¢—{{tlld‚|uldd{ttzll‚ut‹‹‹:97JHF‹‹„{{t|„…sleƒ||„„Šƒ||‚|uƒƒ|‹‹„‹„‹ekdlri””‹tslƒƒ|Œ”•ƒ||tllŒ”•|„…VZT‹’Š{{t””‹„Š„ƒ„„«²«‹‹„š””ƒ||ŠŠ}…‹‹’ŒŒ”“›{||b[U|„…sreŠŠ}lekttslri„„Š\[[lkssleVZ[{u{…‹‹£œ¥ƒ„„{tt{{tƒ||lri‹’Š{tttllVZ[ƒ||ƒƒ|f]cƒƒ|{||sretsllddsre{{tsre{{td\\{||ƒ„„lld””‹d\\‰|vƒ||b[Ukd\‹‹‹ldd’…‹œ¤¦‹’ŠtslŒ”•lldb[UUMRtll‹‹„‹‹‹red’ŒŒ„„Š[TTtsl{||Šƒ}‹‹„{||¦§¨¦§¨{tt‹„„œ››”š”‹‹„‚ut‚|ukd\tt{uzt›”›„„Š‹‹‹ldd{tttt{fkkmtt{ttu{{{{ƒ”“›’…‹‹’Šƒ‚uldd“Œ””“›tt{™š¤ª³·“““«²«£œ¥›”›¦§¨£››‹‹„‹‹‹{||›¢›£œ¥£››‚|utsl«²«“““‚v‚rfk“Œ”™š¤”››››”‹‹‹{||{u{“““ƒ„„tts“Œ”“Œ”{||‰|v‰ƒv””‹””‹”š”œ››‚v{‘Œ…{{t‹’Š‘Œ…š””“““{{ƒ{{t{{t“Œ”™š¤“““””‹¨©´“Œ”¦§¨¤¤Œ”•tzl“Œ”zll‹„„ƒ||lldŠŠ}“““”››”››‹‹„µ¶·²²¬‹‹‹Œ”•ƒ||„Š„\[[ƒ||ttsMRKztl“““|„…Œ”•lkslksƒ}ƒbVZ…‹‹¦§¨„Š„›”›‹’Šult›”›Œ”•‹’Š„Š}„Š}ƒ„„‚ut{u{{u{‹’Š‹„‹„„Šƒ„„SKJlrifkkred‚|u“““ƒƒ|Šƒ}‹‹‹ƒ||‚utldd””‹JHF:97rg]|‚zƒƒ|tzllri‹„‹¦§¨‘Œ…ƒ}ƒtllƒ}ƒ{{t]bZVTLƒ||‹‹„œ§²›¢›llk‹’ŠŒ”•tts|„…“““d\\“““tt{‹‹„d\\\[[£œ¥yle{tttlllks‹‹„ttslldVTL‹‹„leku{{edk‹’Šd\\UTSultŒ‹“ƒ„„{u{‹’Šslelrilldƒ‚uƒ||‹’ŠŠƒ}ƒ„„{ttztlldd|‚z‹„„tts‚v{lldŠŠ}j]\jcVkd\VTLtzlŠ~‹ult{zm‚|u[TTšŒ‘Œ…jcV¤¤ult””‹‹‹„›¢››¢›{u{{{tdc\Šƒ}bVUldddc\{{ƒ””‹“Œ”ƒ„„ztl‚|utsl‹„„rg]„Š}Œ‹“„Š„ƒ||ƒ}ƒ„Š„{{tlddztlkd\sle{|||‚zult|„…ƒƒ|”š”{u{Œ‹“…‹‹tts„„ŠlriedkUMRtll“““{{t‹‹„ƒ„„{u{ƒ„„£››¦§¨”š”œ¤¦µ¶·››”„Š„š””œ››”š”›¢›“Œ”ƒ}ƒšŒ‹’Š‹‹„„Š„“Œ”ƒƒ|¦§¨£œ¥rfkƒ„„¤¤„Š}{{t„„Šœ››ƒ}ƒœ››‹„‹ultiWUzllrg]‚utztf””‹„Š„Š}|ztl‚|ukd\‚|uŠƒ}‹’Šu{{tts‹‹‹œ››š””mttllk{||ult“Œ”tsl›¢›uzt¨©´ƒ„„“Œ”ƒ}ƒ„Š„|‚z›”›”š”œ¤¦“Œ”‹’Š‹’ŠŒ‹“ult£œ¥uztzlllddttsVTL[[Tsreœ¤¦f]cJHFultultzll{tttll””‹‹‹„‹„„Œ”•’ŒŒŒ‹“{u{|‚zƒ||Œ‹“{{tsledc\|‚z‰‰w{{ƒddcƒ||tsl{||ztltllƒƒ|‰ƒv£››lddultlddƒ‚uƒ„„D;9,55ƒƒ|UTS{||lld\[[{u{tll“““|‚z‹„„‹„„uztult‚|u{tt‹’Š…‹‹’ŒŒ‚v{lkslks]cdddc{{t‹‹‹cbVŠ~‹‹‹„d\\‚wlf]c‘Œ…ƒ||‘Œ…£œ¥ƒ‚utzl[[Tmttlld\[bttstt{lri‹‹„tts‹‹„tslŒ”•ƒƒ|ztl‹‹‹|„…zlldc\{||”››sleVZTuztlriƒƒ|”“›tts{ttŠ}ƒƒƒ|MRK£››‚wl{{tsle“““‹„„tllkd\tslsle£››{u{lri‚wltt{Šƒ}tll„Š„”š”tll…‹‹lld‹„‹‚utb[Uredllkƒ||Š}ƒ{tt“““{{tŠƒ}‘Œ…Š}|ulttzlf]c‹‹‹‹‹„‹’Š{{tsled\\‹„„‚|u{u{\[[]cdƒ}ƒŒ”•ttsƒ„„‹…’ƒ}Š‹„„{||edk{u{kd\„„Šƒ„„|‚z„Š„š””ƒ}ƒƒ}ƒkk]ª³·tts£œ¥š””‘Œ…””‹£›››¢›œ››“Œ”¨©´“Œ”‚ut²²¬²««œ¤¦œ¤¦„„Š›”›¦§¨[[Tztl”››œ››ƒƒ|ƒ}ƒƒ„„{u{{{t‹„‹š””Š}|b[Uztl‘Œ…‚|uek]¦§¨£œ¥ŠŠ}‰‘~‚utztf¤¤””‹“Œ”Œ‹“{||‹‹‹’ŒŒ{||tll£œ¥ulttt{tsl”š”™š¤ŒŒš£››””‹„Š„“Œ”‹‹„ƒƒ|™š¤œ¤¦‚|u¦§¨‹‹‹sreƒ‚u‹„„u{{lld|„…JHFdc\tsl‘Œ…[[TUMRMSSUMRultlks{{t{{t“Œ”{ttlddŒ‹“{||llkuzt{{tƒ„„ttsŒ”•››”{tt‹’Šlld[TT‚v{ƒ„„„Š„‚ut‹„„‹‹„””‹Šƒ}››”lldldd‹‹„“~ˆ£œ¥:97*)(ƒƒ|ƒ„„ƒ}ƒztlu{{ƒƒ|d\\Šƒ}‚|u|„…tts{{tUTS£››…„’”››ttsredldd{u{llkekdtt{¤¤‹‹„{{tlld{||ttstll“““‹„‹‚v{‹„„mttdc\ƒ||ekdlrikd\{ttŒ”•™š¤lriƒ„„|„…Œ”•tts„Š}|‚ztllŒ‹“‹’ŠŠŠ}tzl„Š„Š}ƒ{u{LKRd\\rr]f]cd\\ddcf]c‚utdc\kk]ztl›¢›¤¤””‹ƒ„„tt{srekd\[TT[TTj]\ultsleŠƒ}ƒ„„‚utŠ}|Œ”•tslult{{ƒƒ„„ƒ||‘…„‚|uult“““tslŠ}ƒ””‹{yf‚|u‘Œ…‘Œ…‹‹„z‚l‹‹‹uzttllrg]|„…tsl›”›{u{’ŒŒ{tt‚v‚dc\{ttƒ„„‹’Š‹‹‹„Š„{{ƒ‹‹‹‹„„{u{{{ƒ{tt‹„„red‘…„‹‹„¦§¨‹„‹”“›ƒ}ƒ‹„„”š”›¢›„Š„£›››”›¤¤ztl‚|u‹’Š{u{‚|u’…‹šŒ¤¤››”ƒƒ|‹‹„Œ”•rfk™š¤llk‚|uƒƒ|¨©´‹’Š‹‹‹ƒ„„tts‹„‹¨©´“““‚utzllrg]Šƒ}jcVsreŒ”•‚v{‹’Š””‹redŠŠ}ztlkd\„Š}VTLtsl””‹‚v{’ŒŒƒ„„››”‹„‹kk]››”lri‹’Šedktll›”›{{t™š¤¦§¨‹‹„œ››™š¤¨©´«²«”››‹„‹„Š„…‹’{{ƒmttd\\VZTƒƒ|ƒ||”š”ƒƒ|[TTJHFf]c{{ƒf]ctsl‹‹„”“›‹‹‹‚ut“Œ”lri|„…{||uzt¦§¨™š¤ƒ}ƒ””‹‚|uƒƒ|‚wlƒ„„ult{||‹‹‹““““Œ”“Œ”’…‹‚ut‹‹„‹„„Œ”•‹„„Šƒ}£œ¥JHF*)(‹‹„‹„‹ƒƒ|ƒ||mtt””‹ztl‚|u‚ut›”›¤¤{{tlri{||d\\ldd‹’Š]bZƒ}ƒƒ}Š|‚z|‚z„Š„‹‹‹‹‹„”››¦§¨™š¤‚|u””‹Œ‹“¦§¨‹„„””‹”š”uztlrillddc\{{tztl‹„‹rfk‹…’’ŒŒkk]™š¤|„…”š”[TT{||tts{||{ttlldllkmw’ŒŒ\UZƒ„„{zm‹„„{u{ƒ||‹‹‹‚v{tslsreztf‚wlkk]ddcdc\ultzll‹„‹{tt‚v{{{tkd\dc\’ŒŒƒ„„d\\›”›d\\[[Tkd\rfktslVTL‚ut£››„Š„tslb[U“Œ”{ttulttllztltll‚ut|‚zlriŒ‹“f]cŠƒ}“““{zm‹„„››”Š}ƒd\\f]clri‹„„{||‹’Š|‚zlldtt{‹„‹‹„„‹„‹{{ƒ|„…ƒ||Š}|ƒ„„ƒ„„Œ‹“‹„„’…‹ttsŠŠ}œ¤¦uztsleŠ}ƒ’…‹£››¦§¨£››‹‹„ultŠ}ƒ‚v{“““Šƒ}¦§¨„Š}ƒƒ|…‹‹zll‹‹‹“““‹‹‹dc\‘Œ…dc\{||ƒ||mtt””‹tll‚v{’ŒŒ{ttŠ}|Š}|kk]sle‹‹„‚v{‚utztfƒ}ƒ››”””‹|‚zsreSKJllk{||kk]›¢›…‹‹›¢›“Œ”‹‹‹ldd|„…Œ”•„„Š¦§¨‹‹„’…‹ƒ}ƒ””‹”š”œ››ƒ„„£œ¥|‚z{{ƒ“““‹‹‹lekttsƒ„„lrilddlri’ŒŒ„‰v{ttf]clriƒ}ƒ“Œ”‹„„›¢›ƒƒ|{u{Š}|‹„„…‹‹‹’Š|„…ƒ„„ƒ„„‘Œ…Š~‹¦§¨ztlŠŠ}‹’Š{{tŒ”•‹„‹tts|‚z{u{{u{Š}|£››™‹†¦§¨¦§¨ƒ||“““ŠŠ}£››:97*)(Šƒ}Œ”•‘…„{ttŠ}|ƒ}Š‘Œ…ƒ||{||ƒ„„Œ‹“›¢›llkkd\{u{…‹‹”“›’ŒŒ‹‹‹tts“““\[[z‚l{||‹‹‹µ¶·“““¦§¨‚|u›¢›”“›Œ‹“{{tslerfk„Š„‹‹„‹‹„›¢›{{tdc\ƒ}ƒ‹„„›¢›‹‹„ek]f]c|„…ƒƒ|‹‹„‚v{„Š„‹„‹“““zll{tt{u{[TT{{tllkzll{ttllklribVUultf]cdc\{{tVTLƒ||ƒƒ|lri{zmkk]ƒƒ|lddtllŠŠ}‹„‹VTLredƒ}ƒ“““›”›„„Š‹‹‹ƒ„„f]c|‚zsle‹„„ƒ||tllddc””‹š””‹‹‹ƒ„„‹’Š{zmbVUƒ‚u“““dc\ƒ„„[[T‹‹‹{{t‹’Š“““‘Œ…ƒ||Š}ƒztlttsultttsfkkllk|‚z\[bttsƒ„„“Œ”mttlri‹‹‹tts‹‹‹””‹ult‚ut›”›ult‚|u{{t„Š„ttstll“Œ”£››š””£››{{tƒ„„redf]cŠ}ƒ””‹‹‹„””‹¦§¨›¢›ƒƒ|\UZ”š”|‚z››”tsldc\{||‹’Šult‹‹‹{{t‚v{ztlƒ}ƒzll¦§¨b[Utzlƒ„„œ››Šƒ}dc\‘…„Šƒ}‚wl{zm{{tuzt‹‹„œ››{tttzl{ttƒ}ƒ››”{{t¤¤uzt”š”‹‹‹‹„„‹‹„“““u{{‹„„Œ”•”“›„Š}“““tsl{ttfkkŠ}|‹‹‹ƒ„„{||sle]cdtts‚|u|‚zƒƒ|Œ—£edkf]cultƒ}Š„Š}ƒƒ|¨©´š””””‹|„…ƒ‚u‹‹‹ƒ„„ƒƒ|‰|v›”›™š¤µ¶·¤¤››”›¢›“Œ”“““”š”ƒ„„lddultultredš””£››£››“Œ”’…‹‚wl¦§¨JHF)+2››”ŠŠ}ult‹„‹”“››”›£œ¥‚v{sle‹„‹‹„‹lldlek[TTlks‚v{Œ”•ƒƒ|ƒ}ƒ„„Š”››uztu{{{u{‹‹‹¦§¨„Š}¦§¨¤¤ƒƒ|¦§¨£›››”›‹’Š‚|u£œ¥”š”ƒ„„mtt[TT|‚zlek{||ƒ„„{||lldultddctsl„Š„sle™š¤’ŒŒjV[{{trfk‹„‹lek‚v{ƒ„„f]cƒ||lddd\\d\\b[Ullk””‹rg]{{tkd\|„…‹‹„Š}|ttsttsƒ||sle‘Œ…””‹ƒ‚n‚|u„„Šš””œ››””‹ƒ„„ƒ}ƒlddlddtllkd\‚utrg]f]cztlƒƒ|’…‹‹‹„ƒ‚uƒ}ƒb[Ullddc\ƒ||ƒ}ƒ{u{llk{||tsl‚|u””‹{tt‹„„ddcŠŠ}{u{ddcƒ„„‹„„“““tt{{{ttt{„„Š™š¤ƒ„„UTS‚v{lek|‚zddcd\\‹‹‹kd\ztl…‹‹“Œ”“Œ”¦§¨Â¾Æ£››””‹¤¤«²«””‹Š}ƒult‰|v“Œ”uzt„Š}‹’Šƒ„„œ››‹„‹‹‹‹ŠŠ}„Š„{||™š¤¦§¨“Œ”{ttd\\œ››š””ƒ||‹„‹“Œ”š””””‹ƒ„„‹’Š“Œ”‹’Š‹‹„²¬µsre‹‹„sretsl¦§¨Œ”•›¢›‚v{Šƒ}{{tƒ||“““‹’Š‹‹„lld|‚zƒƒ|ldd“““‹‹„“““ƒ}ƒuztƒ||{u{„„Š‹‹„ƒ„„‹„„tts£œ¥ƒƒ|…‹‹‹„„]bZ‹„„‚|u|‚zœ››‚|u\[b\[bbVU‹„‹kk]ƒ„„“““›¢›ƒƒ|ƒ„„“Œ”tsllld{u{Š}|£œ¥¦§¨dc\””‹¤¤{zm”“›œ››Œ‹“œ››„Š„“Œ”‹„„‹„„zll¦§¨‹„„£œ¥‘Œ…‹‹„²²¬\[b*)(zll[[T{tt‚|uddc{tt„Š„œ¤¦ƒ||ult{{t‚|u„Š„š””ƒ}ƒedk{||“Œ”tt{‚|uztl|‚z„Š„ult“Œ”tzl”š”‹‹„„Š„‹‹‹“Œ”ƒ||ƒ„„ztltts]cd””‹|‚z‹’Š””‹|„…u{{‹„‹…‹‹llklddtllmttƒƒ|š””ŠŠ}tts‹„„{u{ƒ}ƒ™š¤tllUMRllkttstll{ttmwSKJ[[Td\\“““’…‹cbV‚|uyle‹‹„ƒ„„š””‚|ulldŠƒ}tts‹‹„sleŠŠ}””‹£œ¥{u{™š¤“Œ”zllrfkf]ctsl{tt{tt{zmŠ}ƒ…‹‹ƒ||‹„„™š¤”››ƒƒ|‹„‹‹‹‹kd\llkƒƒ||‚z‹„‹zlltsl{zmƒƒ|’ŒŒ{ttš””„Š„‹’Štlltsl|„…{{t{||“Œ”{u{Œ”•‹‹‹‹…’”“›lri‚v{ult{||¦§¨“““ƒ||‹„„ƒƒ|£››””‹“Œ”“Œ”£²Ã¼¿¦§¨{zm¦§¨Œ‹“œ››²¬µ{{t‘…„f]c“““›¢›¦§¨ƒ||„„Š‹„‹ŠŠ}{{tœ››lri””‹ƒƒ|‹„‹‚v{lekf]c‚wl{||“Œ”šŒ””‹ƒƒ|“““›”›œ››{{t“Œ”sre””‹¦§¨‹’Š|‚z–¢‹‹‹‹ddc‹„„{{t‹„„šŒtslŠƒ}llk\[[ƒ}ƒztlƒ}ƒƒ}ƒfkk¦§¨“““Œ‹“””‹“Œ”Œ”•ultllksle‹‹‹“““|‚z{||„Š„VTL\UZ„Š}£œ¥lddedkUMRŒŒšf]c‹‹‹{{tult{||‚ut‹‹‹ttslddllk””‹Š~‹›”›’…‹uzt‘Œ…tsl””‹‹‹‹Š~‹„„Š|‚z‹‹„ƒ„„‹‹‹Š}ƒj]\‘Œ…ƒƒ|‹‹„tt{š””µ¶·f]c*)(tll‚|uš””‹…’mtt{u{Š}|{zmtslf]c|‚zlrikd\[TTtt{‚|ulri™š¤ƒ}ƒdc\„„Š„Š}ƒ„„‹„„{tt¤¤œ››Œ‹“›”›tts²««‹‹‹‹„‹‹‹„{{tƒ||”››ƒƒ|„Š„ƒ‚uŒ”•”“›tt{“Œ”Š~‹‹‹„‹’Š{{ƒVTL‚v{|‚z™š¤‹‹‹’…‹|„…ƒ}Š‹„‹‹‹‹ƒ}ƒŒ”•‚utdc\kd\\[[‚utƒ||{{t‹‹„‚|ulri‰v|ttsttsllkƒ„„|‚z’…‹j]\‹’Š{u{i\Vsreš””›”›Šƒ}ƒ||VTL‹„„ylellkztfmwlddtsl{zmƒƒ|„Š}{u{‹„„‰ƒv‚utœ››ƒ‚ullk„Š„sreƒ}ƒd\\kk]Šƒ}‚ut{tt‹„„‚ut{||ekdƒ„„”š”tslƒ}ƒƒƒ|{||{{t{{ƒ››”ŒŒš™š¤{u{‹„‹¦§¨{{t¦§¨µ¶·‹’Š‹‹‹“““£œ¥Œ”•‘Œ…£œ¥‹„„‘…„’ŒŒ™š¤ƒƒ|¨©´tll‚v‚““““Œ”{u{œ››””‹“Œ”ekdŒ‹“ƒ}ƒ‘Œ…ƒƒ|‹„„kk]ttsrfk‹‹„‚v{ƒ||zll‹„„lri›”›‘Œ…‹‹‹¦§¨”››£››‹’Š‘Œ…‚utŠƒ}{{t‹’Š‹‹„‹’Š”š”{u{tsl{{t‹‹‹u{{ddcttsƒ‚u…‹‹{||ƒ„„{{t„Š„‹’Š¦§¨{u{“““tll›¢›‹„„‹‹‹‹„„‹„‹””‹…‹‹”››lek{{ƒ|„…d\\ult{zm¤¤ultlkslks{u{rfkdc\ƒ„„ƒ}ƒlri{{t”“›ƒ}ƒ„Š„{{t‚ut{tt›”›Œ‹“‹’Šƒƒ|llk{zmƒ}ƒƒ||tts{zm{{ttllrfkŠƒ}{ttsreƒ||{yf‹’Šztl””‹JHF?;C‘Œ…‘Œ…”››‹„„ƒ}ƒtzlulttll[[T›”›‹‹„\[[ultƒ||tllƒ||Œ”•|‚zƒ||’…‹‘…„lri“Œ”‹‹„”“›“““ekdlld‹„„u{{ult‚|ukk][TT{ttkd\ddc‚|uƒ„„{{t„„Šƒ||“Œ”“Œ”tllek]‹„„ddc‰‰w„Š„[[Tllkd\\…‹‹f]c{u{llk‚utlrittstllultsle{ttj]\{||ddcsleztl[TTred‹’Šlddzllƒ||\[[‚v{{||{{t™š¤{ttlld’ŒŒ‹‹„u{{{||lek“Œ”£››tslƒ||ztl…‹’tsl„Š„”š”|‚z£œ¥š””””‹|„…{{ƒƒ‚ulriƒƒ|lld‹„„dc\{ttƒƒ|ztfultƒ||‹„„lks{{t“Œ”|„…‹‹‹›”›””‹{u{tll™š¤llk£››£œ¥‹‹‹dc\|‚z””‹œ››‹„‹¤¤’ŒŒult””‹”››tllƒ}ƒultƒƒ|‹‹„lld”š””››lriŒ”•tllƒ||””‹kk]‚ut¨©´›”›„„Š‹„„‹„„››”tts{||››”…‹‹rg]ƒ||šŒ£œ¥‹„‹ƒ„„ƒ}ƒŠ}|ƒ||‹„‹{||²¬µŒ”•Šƒ}ƒ‚ukk]‰ƒv›¢›‹’Š”š”ƒƒ|’ŒŒ‹„„¦§¨œ››ƒ„„ldd|„…|„…‰‘~]bZult‹…’ƒƒ|››”sleƒ„„llkƒ}ƒ””‹‹„‹|‚zƒ}ƒ{u{„Š„ƒ„„„„Š‹‹‹„„Š|‚z]bZŒ‹“›¢›„Š}|„…JHFlksult›”›‹’Šƒƒ|’…‹ƒƒ|tllŠ}ƒ{{ƒª³·“Œ”‚wl‘…„„vŒ‹‹‹¨©´””‹sletts””‹‚ut’ŒŒ{||ttsœ››ztl“Œ”‘…„‚|uztl‹‹‹{{tek]¤¤:97*)(‘Œ…tlltslekdult‹„„Š}|ultkd\mttƒƒ||„…u{{kd\{u{lddekd{{ƒlekVTL™š¤œ¤¦œ¤¦”š”“““ƒ„„œ¤¦{{ƒ{|||„…’ŒŒ››”¨©´lldtll|‚z›”›ƒ||tslƒ„„¦§¨”“›ult”š”|„…‹’Šƒ„„ddcƒ||ƒ}ƒ{{t\UZllk„„Š‹‹‹{u{ƒ}ƒultj]\“Œ”r]g{||ƒ||{u{j]\›”›Šƒ}tsl‰|v”››Šƒ}ª³·ult{yfšŒtzl‚utbVUllkzll’ŒŒf]cƒ||‚uttts\UZ{{tztlƒ||ƒƒ|‹‹„šŒlld{{tz‚lŒ”•tts”››””‹{{t’ŒŒtts‚ut{||‹‹„ƒ„„“““d\\‹„‹ztf’ŒŒzll‹„„’ŒŒƒ„„››”ult…‹‹ƒ||š””Œ”•{u{›”›lks‹„„”››llk“““Œ‹“””‹ztl™š¤œ››²¬µ£››{{t{{tllk‘Œ…‚v{š””””‹œ¤¦‹‹‹›¢›œ¤¦“Œ””“›{{ƒ‚utkd\lld”š”‹„‹’ŒŒ¨©´‹„„ƒ„„{{tƒ„„tzl›¢›‹‹‹‘…„¦§¨››”£œ¥¦§¨£››“Œ”£››‚|u{{tƒ„„‹„„”š”{u{“Œ”dc\‚ut{{tjcVœ››“““{u{lek›¢›””‹„Š„mtt‹’Šuzttzllrimtt\UZmtt”š”œ››{tt‹’Š‹„‹›”›¦§¨œ››ztltt{Œ”•¦§¨”“›„„Š›”›”“›‹’ŠtllŒ”•œ¤¦ƒƒ|UUYUMR\[bult‹’Š”››…‹‹uzttll“““ƒ}Š{||lks””‹ulttt{lddƒ„„“Œ”sretslƒ||‹„„tllƒ„„‹‹„{u{“Œ”‚ut‚v{ŠŠ}{{t|‚zƒ||lld¦§¨VTL74,‹’Šš””‹’Štt{“Œ”ƒ||‚v{[[T]bZlek‹„„”š”ztllri{{ƒult{||llkultkd\sle¦§¨Œ”•‹’Š¦§¨Œ‹“¦§¨‚utš””ƒ„„“““”››{{tƒ||””‹Šƒ}{||“““b[U›¢›œ§²£œ¥Œ‹“mttŒ”•‹„‹ultf]c‹„‹ldd‹„„tts‹„‹uztSKJ[TTultult„„Šllki\Vƒ}ƒ{tt‹„„””‹j]\£››ƒ||¤¤Œ”•‹„„dc\‹‹„ŠŠ}{{tVTL‚utSKJtzlb[U{ttSKJ{ttkd\ƒ„„bVU[TTŠƒ}{ttuzt‹„„zllkk]tll{||‘…„‹’Š“““lddbVU‚utkk]lri‹‹‹ttsŠŠ}…‹‹|‚z“Œ”¤¤‹„„{ttrfk‹‹„{ttŠƒ}‹…’‹‹‹”š”tts”“›tllš””{{ƒƒ„„„„Š“Œ””“›{tt›¢›kd\”››“Œ”‘…„ultttslld‹„„sle›”›ƒ}ƒ£››‹’Š“““”š”““““Œ”|„…‹…’Œ”•‹„„””‹£››“Œ”Šƒ}“Œ”“Œ”¦§¨›¢›’…‹u{{tzlƒ}ƒedk“““¦§¨‰v|red¦§¨“Œ”‚ut|„…Šƒ}‹‹„{||”“›‘Œ…£››‹’Š{zmŠƒ}„Š„¦§¨š””œ››™š¤››”‹„‹Šƒ}Œ”•{{tƒƒ||‚z|‚z’ˆllk”š”|‚zddcƒ„„…‹‹ƒ||{u{‹u…„Š}tt{‹„‹”››”š”Œ”•µ¶·œ››lri‹’ŠŒŒš¨©´‹’Šƒ}Š[TTf]clek¦§¨{||lld|‚zmtttt{{{tƒ||tt{{u{redd\\ƒ}ƒ™š¤””‹{u{‹‹„tslztlulttll‚ut„Š}‹„„Šƒ}šŒ{tt‹„„…‹‹tzlmtt{zm›¢›JHF:97{{t‘ˆ}dc\…‹‹Œ‹“š””ztlztlllk‹’Šdc\ƒƒ|cbVz‚l„„Šult››”llk{||ultŠƒ}„‰v|„…ƒƒ|ƒ}ƒ“““‹’Štt{¦§¨¦§¨{tt”››tt{‹‹„lriztl{||tllƒƒ|VZT|‚z™š¤tt{fkkllkƒ||[TTJHFf]c\[[lldultf]cf]c\UZllk‹„„ult‹‹‹lekyfllek¤¤ƒ}ƒ{zmŠŠ}‚wlSKJšŒd\\JHF{{t|‚zsre’ŒŒ{{tƒ||red{{t‚|usre{||Š}|cbVtllzll‹’Š{tt‹‹„‹„„ztl‚uttllllkƒ||‹‹„{tttzlVTLtll]bZkd\ƒ‚uƒƒ|”››‹‹„™š¤lld{ttƒƒ|‹’Š“Œ”‚v{’ŒŒŠ}|››”{|||„…„Š„tt{Œ”•“Œ”‹„„„„Š‹‹‹{ttmttultzllƒ„„¤¤ƒ}ƒlddldd£››“Œ”ddcƒƒ|ƒƒ|‘…„¤¤””‹Œ”•”››tts”š”””‹£œ¥ƒ„„Š}ƒ¦§¨ƒ‚u››”£œ¥’ŒŒ“Œ”£²‚|uredu{{ztl’‘~Š}|ƒƒ|š””£œ¥{tt‹„„b[U£››kd\Š}ƒkd\‹’Š‹„‹ƒƒ|£››£››””‹Š}|{{ttts””‹””‹£œ¥{{tlri‹’ŠŒ‹“tsllriz}‹’ŠŒ”•tsl“““ult””‹ztlzllœ¤¦Š}ƒƒ||{ttŒ”•„Š„ztl”š”…‹‹”››‹’Š”“›ƒƒ||‚z\[[›¢›lldŒ”•‹‹„’ŒŒ{u{‹…’’ŒŒŒ”•ƒ„„œ¤¦™š¤‹…’‹„‹uzt‹„‹¤¤‹„„{tttll¦§¨ƒƒ|{zm„„ŠŠ}|ulttll”››{zm{{t’ŒŒš””tll‹‹„‹‹‹”š”“““””‹¤¤JHF*)(ultcbV|‚zttsƒ„„]bZŒ”•red{ttj]\‹’Štslƒƒ|kk]ult¤¤”“›Œ”•f]ckd\bVU‹’Š…‹‹dc\d\\¤¤‹’Š|‚zŠ}|ƒ}ƒŒ‹“ƒƒ|“Œ”zll£œ¥{{t{{ƒllkuzto€wlkstt{™š¤u{{Œ”•UMRd\\ldd‚v{UMRj]\ultmwtsledkUTSƒ||ƒƒ|ƒƒ|tt{‘Œ…tll‹‹„‹‹„{{t[[T{ttredztllldlriƒ}ƒtzl{{td\\ƒ‚u‚|uƒ||ƒ‚u{||£››ldd{tt[TTd\\FD;rr]{tt{tt“““š””tll‹„‹ƒ„„‹‹‹tsllldd\\ztl{{t””‹ztltzl{{t|‚z’…‹‹‹‹…‹‹‹„„ztlƒ„„rfk”“›‹‹„{u{‹‹‹{{ƒztllddj]\mtt‹„‹{ttlek“““„Š„tt{\[bllk|‚z””‹™š¤ƒƒ|ƒ||tll{||„Š„’ŒŒ„Š„¦§¨œ››£œ¥{||”š”ª³·œ¤¦ƒ‚uŒ”•Š}ƒ··Ä£œ¥¦§¨«²«œ››f]cŒ‹“‹„„{{tƒ„„f]c‹’Š‹„„“““ldd{ttŠ}ƒtllŠ}ƒcbVddc{u{š””ƒ||ztlttsƒƒ|Šƒ}–¢‹››”””‹ƒƒ|ƒ„„š””£œ¥„„Šztl{{t‹‹„…‹‹u{{lddlriŒ”•mtt]cd]cdŠ}ƒedkj]\‚|u‹‹„¦§¨redult”š”™š¤’ŒŒ™š¤š””¦§¨uztƒ}Š|„…dc\tlllri|„…|‚ztt{u{{™š¤{{tƒ||„Š„ƒƒ|œ¤¦ƒ}ƒtslƒ}ƒ|‚zƒ}ƒ‹„„‚|umtt{u{{zm„Š„ztlddcztlult‹‹‹{ttztlƒ||kd\‚|uultf]c{{ƒƒ||”š”£››“““>EC:97tslSKJ{{tŒ‹“‹’ŠVTL‚wlŠ}|{u{d\\rg]|‚z„Š}mtt‹’Šš””™š¤{{tbVZ{u{sre|„…‹‹‹ƒƒ|{||zll|‚z{u{””‹”š”uzt”››ulttll{{tlddƒ}Š{tt|‚z‹’ŠUTSŒ‹“ult\[blrilldf]ctll£œ¥mwtsllek‹„‹””‹…‹‹JHFuzt¦§¨{tt[[T›”›{||kk]’ŒŒ‚utSKJred‚v{‹’Šllk|‚z‹’Š‰ƒv‹„„d\\tslultedkƒ}ƒ“““ƒƒ||„…b[Uztl‘Œ…„Š}kjV‚|utllƒ„„{{t{tt›”›dc\ƒƒ|ƒƒ|{||lldƒ‚u””‹‘Œ…””‹‹„„‹„‹”š”ƒ}ƒƒ}ƒtts{tt‹‹„{{t‹„„ƒ}ƒƒƒ|{||Œ”•‹„‹”“›|„…{||Œ”•ttslektt{{tt{||Œ”•‹„„œ››‹‹‹¦§¨ƒ}ƒ{{t’ŒŒ‚v{tslŒ”•š””‘Œ…“Œ”¦§¨››”’ŒŒµ¶·œ¤¦‹’Štslœ››{tt…‹‹¦§¨›¢›¦§¨“““‹…’ƒ}ƒš””¤¤¦§¨£››š””›¢›¦§¨ª³·œ››‹„‹‹„„{tttts{zm‹„„£››{tt{{t{ttŒ‹“\UZred‹’Š{u{uztš””Šƒ}œ››‹„‹{ttbVU{|||„…]bZŒ”•‹’Š›¢›Œ”•…‹‹‹‹„ult””‹‹’Š“““„„Šult“““š””‹„‹“““|‚zultdc\llkkd\tlledkttsultfkklks\[blekllk{{ƒkk]‹’Šœ¤¦¤¤Œ”•œ››¦§¨ekdttsƒ}Š{||‹‹„“Œ”{u{uzt{{tdc\|‚z‘Œ…“Œ”ƒ„„Œ”•{{tztf‘…„ƒ„„›”›llkšŒ””‹“““’…‹‹’Š:977-2”››‹‹„ŠŠ}”š”llk{u{ƒƒ|‹„„„„Š{u{tzllld|‚zlldu{{ttstt{lriultŠŠ}]bZkd\{ttƒ||tll””‹lld’ŒŒŠƒ}‘Œ…|‚zƒ}ƒ”“›rfk¤¤‹’Š“““|‚zƒƒ|{||™š¤llktt{„Š„lksf]c{u{SKJƒ}Š{ttlldŒ‹“tll{tt‚v{…‹‹|‚z|‚zuzt[TTƒ||llk‚wlrfkVTLsleƒ||slettslld‹‹„tts|‚zsleƒ||aWMSKJFD;ztlultu{{“Œ”[TT””‹slelldkd\‚|utsltts„Š„‹„‹uzttllb[Utyg{{ƒ””‹ztlsrekk]‹„‹{{t™š¤¦§¨››”“Œ”ddc””‹‹„„sle‹…’ƒ„„”š”‹‹‹|‚ztts…‹‹ƒ}Š{tttt{{||“““ddc‹…’{||{{ƒtts„„Š‹„‹¤¤Š~‹“““‘…„ƒ}ƒ›¢›‹’Š››”{{t£œ¥™š¤’ŒŒµ¶·œ¤¦œ¤¦¤¤””‹¨©´µ¶·™š¤œ››µ¶·¦§¨“Œ”£œ¥“Œ”f]cƒ„„mw‹„‹‚wl‚|u””‹””‹””‹„Š„„„Š“Œ”uztbVU››”“Œ”lld‹‹„ddctsl‹„‹{ttsle‚|uƒ„„ult“Œ”{||“Œ”rg]ƒƒ|Šƒ}ƒ„„lri{||œ››mtt|‚z„„Štt{ddc’…‹“““›¢›{||rfk››”£œ¥‹‹‹„Š}ztlŒ”•zll‹’Šƒ||lddŒ”•ƒƒ|‚v{uztVTLultSKJtslŒ‹“[[Ttzl‹’Š‹‹„{||{||„Š„{tt””‹„Š„““““““Œ”•{{ƒ‹’Šultƒƒ|ƒ„„{{t‹„„{u{“““”š”‹„„Š}|ƒ||tsl{u{‚|u{tt|„…uzt”š”>B9*)(zllƒ|||„…“Œ”{{tllklddbVUd\\lddek]UTSlri[[T{{ƒtslult{{td\\„Š}u{{cbVbVZ››”ƒ}ƒsleb[U{||zll‹„„{||”“›ƒ}ƒtsl{ttƒ‚u|‚z„„Šuzt|„…|„…{{ƒ\[bJHFJHF\[[f]cd\\\UZb[Ud\\ƒ„„ttsd\\VTLƒ}ƒ‹„‹{zmtsl{||‚|u{{tƒƒ|„„Šf]c]bZsleldd£››ddclld|‚ztzl‚|utllaWMsre{{ƒ{zmŒ‹“j]\tllƒ||‹„„tslztlf]cb[U|‚z{||Šƒ}Œ‹“dc\|„…zll‹‹„Œ”•ek]tsl‚ut‘Œ…{ttƒƒ|lri‚v‚‹‹„ƒ}ƒ¤¤tlliq]tsld\\{||{{t‹„‹|‚z›”›{{ƒƒ}ƒš””Œ‹“›”›ƒ}ƒ{{ƒ{||ƒ}ƒ”š”{u{ƒ||‹„„Œ”•Š}ƒ‹„„¦§¨’ŒŒ‹’Š”“›”››“Œ”™š¤‹‹‹””‹¦§¨‹’Š¨©´{{ƒ”“›ƒ}ƒŠ}ƒ“Œ”¤¤œ¤¦sle“““Š~‹£œ¥’ŒŒ“““œ›››¢›‹’Šƒ||‚|u{{tƒ|||‚z“Œ”ŒŒš\[[‚v{„Š}ztl{||“““‹„‹tsllldj]\ttstzl{||‚wl“Œ”ƒ}ƒƒ„„lldƒ||››”„Š„„„Šlldmttlks|„…lksuzt„„Š“Œ”››”‹‹‹{{ttts“Œ”ƒ}ƒ‹‹‹“““””‹Œ”•{{tƒƒ|ƒƒ|’ŒŒ‹‹‹lriƒ„„œ¤¦”“›Œ”•r]glldƒ„„mtt|‚z„Š„lddœ§²‚v{‹’Š’ŒŒƒ„„‹‹‹‘…„‘Œ…tt{{{ƒƒƒ|‹„‹š””Š~‹’ŒŒ‹‹‹‹„‹‹’Š{{t…‹‹{{t’ŒŒ“Œ”dc\VTLtllVTL]bZ’ŒŒJHFJHF“““‹‹‹|‚z|„…]bZSKJd\\ultddcd\\b[U|„…|‚zlekttssleultuzt‹‹‹‹„„{{t{{ƒ‹„‹“““ƒƒ|‘Œ…‹’Š|‚zllkldd|‚ztts{u{lddƒ}ƒ|‚z|‚zMRKddcult]bZlddultf]cmtt„„Štsl[TTultd\\lddu{{Š}ƒtllj]\„„Šf]c‚|ukd\{||{u{[TTŠ}|{u{sreztl‹„„{zmcbVƒ||„Š„tzltzlultkd\{||’ŒŒllk…‹‹zll‚utult‹‹„¦§¨kd\VTLsle””‹|‚zdc\“Œ”ƒ||ztl’ŒŒsresre”š”kk]tsl‚utsleldd‹‹‹‹…’ulttlllddllkSKJiq]tsl‹„„ƒ}ƒ‹‹‹Œ”•{tt{{ƒ{||llk‹’Š{{ƒ™š¤’ŒŒ™š¤|‚zŒ‹“™š¤ƒ||tts“““{{tkd\””‹ƒ||¦§¨Œ”•{||ƒ}ƒ””‹£œ¥‹„‹”š”›¢›”››™š¤ult‹‹‹|‚z™š¤£œ¥uzt‹’Šœ››¨©´Œ‹““Œ”tsl|„…{{tœ››‚|u¦§¨“““œ¤¦Šƒ}™š¤ldd¦§¨Œ”•“Œ”‹„„’ŒŒ‹„„£œ¥Œ‹“ƒ„„dc\ldd‹„‹””‹‹‹„‹„‹‚|utt{ƒ„„›”›‹‹‹…‹‹tt{œ¤¦tsl|„…|„…{{t¨©´”š”„„ŠŒ”•{{ƒ|„…tts’ŒŒ””‹‚utŠƒ}Œ‹“sle™š¤””‹”››‚ut{||ª³·Œ”•£œ¥ekdœ¤¦£››…‹’Œ”•œ§²|‚z‹‹‹”››”š”¦§¨™š¤œ›››¢›tsl”š”ƒ}ƒztl{u{llkƒ||¦§¨‘…„ƒ}ƒ‘Œ…‚v{ƒ„„””‹{{t{||{ttj]\ttsŠ}ƒ|‚zttsddc„Š„‹„„SKJ*)({||dc\lddtllVTLf]c‹‹‹{u{uztttstslu{{””‹lriu{{f]c‹‹‹ƒ„„u{{lld‹‹„Œ‹“‹„„ƒ„„…‹‹’ŒŒƒ||ƒ||²¬µdc\b[U¦§¨‹„„„„Šllk“““‹„„uzttzlddcu{{d\\ddcJHFVZTSKJ“““’ŒŒ‚v{tt{[TTlksƒ||tsld\\[TTddc””‹‚|utts’…‹{||red{ttd\\sle””‹d\\ƒ}ƒ\[[z‚lŒ”•ƒ„„bVZŠ}|’ŒŒƒ||ƒ||{||‚v{rg]rfkkd\‹„‹ƒƒ|kd\{{tslesrelld‹„„red|‚zsletslztl…‹‹{tt‚|uš…ŽŠ}|“Œ”‹’ŠŠ}ƒ{{t‚|u{tttslƒƒ|sleƒƒ|‚v{tsl{tt”››ƒ„„£››tts|„…ƒƒ|{u{ttstt{ƒ„„mtt“Œ”™š¤‚v{llk{ttŠŠ}™š¤ztl£œ¥‹„„‹‹‹¨©´’ŒŒ™š¤“Œ”“Œ”„Š}‹‹‹|‚z¦§¨ƒ„„„Š}¦§¨“Œ”‹„„„Š„µ¶·Â¾Æ£››£››Š~‹›¢›”š”„„Š›¢›Šƒ}¦§¨‹‹‹{tt¦§¨””‹‹’Š›”›{||“Œ”tts‚ut£››’ŒŒ‹„„‘Œ…{||Š}ƒŠƒ}ƒ}Š”š”‘Œ…‘Œ…”“›ultœ››››”|„…lriš”””››|„…’ˆŒ‹“…‹’|„…|‚z”“›ult|„…dc\“““²¬µ’ŒŒœ››{u{ƒ}ƒ”“›‚|u{zm{tt‹‹„™š¤Œ‹“‹„‹„Š„Œ‹“ƒ}ƒ{ttttsu{{ª³·¦§¨ƒ„„Œ”•Œ‹“j]\””‹””‹uzt‹„„tsl‚v{ƒ}ƒuzt‹‹‹‹‹‹bVUƒ||ztl‹„‹Œ‹“{{t{tt{{t‚ut{ttllk‚|u{{t|‚z\[[dc\‹‹‹:97&&UTSd\\d\\u{{ztl|„…š””™š¤{{tƒ„„œ¤¦””‹|‚z|„…“““”š”“Œ”mtt‹‹„„Š„sle”››£œ¥‹’Š‹’Š‹‹„{{tlld›”›sletts‹‹„£œ¥ª³·{tt“““ekd…‹’ekdsrelrif]c‹„‹{{ƒmttsle{zmzllƒ||Œ‹“¦§¨ldd››”lektlledkult{{t\[[|„…£œ¥f]cttslddtslkd\sleSKJ‹‹‹\[[leklldtts{u{tll””‹{{tƒ}ƒš””ztlrfkttssle””‹VTLtllsleztf{u{uztŠ}ƒf]csredc\Šƒ}sre{u{{zm{||£››Š}|‹‹„“““lldkd\‹„‹{tttlld\\„Š„sreœ››„Š„{{t™š¤Œ‹“ƒ||ttstll{u{mtt””‹{tt”“›‹‹‹{{ƒ{{ƒ{tt{{ƒf]c”››”“›‹‹„Š~‹£œ¥ttsŒ—£››”tts’…‹ƒ}ŠŒ”•‹’ŠŒ”•ƒƒ|tsllri…‹’¦§¨‹‹‹“““»ÂÇ”š”“Œ”²¬µ›”›””‹tsltsl›¢›š””Š}|ult”š”””‹‹„‹‚|u{u{{{t{u{š””›”›ƒ„„tts‹‹‹ƒ}ƒ{{ƒ“Œ”llk›”›‹’Šƒ||š””|‚z‹„‹{{ƒ‹‹„|„…mtt\[[‹„„ƒ„„|„…|„…Œ‹“mttŒ”•f]cd\\|‚zƒƒ|‚ut‹…’‹…’‹„‹„Š„tllmtt‹„‹tll”š”ƒƒ|›¢›…‹‹™š¤mtt™š¤¨©´ztl{ttŒ”•Ž¡›”››u{{œ¤¦ttsƒ}ƒ¦§¨‹‹„Œ”•”››ƒƒ|lrilekttsŠ}|{||{tt{{tƒƒ|‹‹„š””ƒ‚uuzt‹„„‚ut‚v{lks‘…„‹„„{||{{ƒJHF£››:97*)([[TSKJJHF\[[lri“Œ”{||‹„‹tsl{ttlri‹’Š|‚zŠŠ}ƒ„„u{{™š¤kd\„Š„ƒ„„£››…‹’‚v‚›¢›Œ”•|‚z‹„‹œ¤¦“Œ”¦§¨„Š„Œ”•¦§¨“Œ””š”¦§¨f]cf]cVTLek]kk]Œ”•ultd\\VTLŠ}ƒ{||„Š„f]ctt{Œ”•edkš””lddedk„„ŠuztVTLmtt…‹’ldd„Š„‹‹‹ƒ||kd\lddzlllksƒ||š””|„…{||{u{ƒ||lddtlld\\u{{ƒƒ|f]c[TTtllƒ||‚|u{zmj]\zllj]\{{t”“›tllŒ‹“{{tSKJ…‹‹¤¤|‚z„„ŠŠ}|ldd‹„„‹‹„ƒ}ƒ{ttƒ‚u‹‹‹„Š„“““ldd‹‹„‹’Š“““|‚z…‹‹{{ƒ{tt{{t{{ƒ‹‹„sle{||„Š„uzttts{u{ƒ||{{ƒ{tt{u{‹’ŠtslŒ‹“‹„„Œ‹“£œ¥tslŒ”•llktt{“Œ”lek„Š„”š”|„…›¢›œ››„‰vŒ”•œ››¨©´ª³·…‹’œ¤¦tt{‚v{²¬µ””‹œ¤¦Š}|‹‹„‹‹„ƒƒ|Œ”•””‹œ››ƒ}ƒ‘Œ…™š¤ƒƒ|‹„‹{||£››’…‹Œ‹“””‹›”›£››£››{{ƒ›”››¢›¦§¨œ››ƒƒ|Œ‹“{tt‚v{ƒ}ƒƒ„„‹„„zllmtt™š¤|„…ŒŒšJHFlldlks{ttsleldd“““™š¤‹„„‘…„‹’Šš””™š¤‹‹„‹‹„””‹Œ”•œ¤¦”››Œ‹“dc\…„’ƒ}ƒttsƒ„„{u{lld’…‹„„Š¦§¨llk“Œ”“““{||tts|‚z“Œ”lek{{ƒult‚|uztl‚v{‚|u‹‹„š””‹„„„„Štzlœ››‰|vtlluzt”š”ttsllklld{{t››”SKJ*)(lkslldVTLUTSsref]ctllbVZtzllldmtt|‚z{{tƒƒ||‚zƒ„„Œ”•‹’Š‹’Šlld›¢›Œ”•šŒ¦§¨{||\[[‹’Š‹‹„””‹ƒ}Š{||…‹‹tll››”|‚z›¢›ŒŒšult”››lld{||mtt£››dc\MSS“““…‹‹”››’…‹{{ƒ„Š}lriztlsrezllŒ”•ttslddztl{||‹„„llkf]cllkultVTLsre{zmzllƒƒ|f]ctsl{||{u{dc\SKJ‹„‹ultlldƒ„„nƒf]c{||ŠŠ}””‹‰ƒvŠƒ}ult{||ƒƒ|‹„‹tts{zm{tt””‹‹‹‹“““{||{tt{tt‘…„tslŠ}ƒ£››ƒƒ|‹‹‹kd\sleulttllƒƒ|£››{{tŠƒ}ƒ„„”››‚ut…‹‹“Œ”llkllkttsllk™š¤{u{ddc…‹’Œ‹““““‚|uƒ||”››”š”’ŒŒ¦§¨œ¤¦|‚z‹’Š{{ƒ{u{ƒ}ŠŒ”•‹‹„|‚z‹„‹¦§¨›¢›«²«™š¤”“›„„Šš””‹‹‹ƒ}ƒ‹„„]cdƒ„„|„…š””uztkd\’ŒŒ{tttsl”š”Œ‹“{tt›”›ƒƒ|‹„„lek›”›¦§¨Œ”•{tt¤¤‹„„’ŒŒ£œ¥ŠŠ}tzlš””ƒƒ|”š”‹‹‹tllƒ}ƒ|„…redUMRtt{…‹‹UTS„„Š…„’ƒ„„…‹‹ƒ}ƒ“Œ”‹‹„ŠŠ}Š}|¦§¨µ¶·“Œ”‹‹‹“““tll“Œ”””‹››”›¢›Œ”•…‹‹lri„Š„{u{¨©´ŒŒš…‹‹u{{’ŒŒŒ”•”š”‹‹‹tt{™š¤uzt™š¤tts„„Š›”›¦§¨ƒ„„ƒƒ|tslš”””“›‰v|ƒƒ|Š}ƒkk]|„…ldd¦§¨š””’ŒŒ”š”‹‹„””‹{u{“““{||²««JHF3+*”››ƒƒ||„…UTSdc\Š}|‚ut[TT{||lkstsl|‚zƒƒ||‚z|‚zƒ}ƒ“Œ”lri’ŒŒ{{ƒ””‹|‚z›”›{||‹’Šƒ||ekd…‹‹rfkkd\ƒ‚uttsƒ||“Œ”‹‹‹›¢›ª³·‹„„mtt>B9JHFlksƒƒ|tsl””‹\UZ{{ƒ…‹’Œ‹“\UZfkk››”VTLult‚|u‹„‹¦§¨…‹‹d\\\[[ult‹‹„ek]llkbVUj]\tzlztlslekd\ult¦§¨‹’ŠŠƒ}ldd{tt{u{tt{b[USKJiWU{u{”“›ƒ„„{zmVTLrg]sreedkƒ||{ttttsƒ„„„Š„‹„„Š}|‹‹‹zlltllƒ||rg]ztlƒ||ztlbVUlddu{{Šƒ}kd\lldtsl‹’Štllsle{{t‹‹„{ttllkedk{ttttslldedk{u{tt{llklks|„…sre„Š}Œ”•Œ”•¦§¨ÂÅÓ”“›¦§¨…‹’”š”œ¤¦”“›“Œ”‹‹„|‚z¦§¨ƒ„„ƒ‚u›¢›œ¤¦™š¤£››{u{{{ƒ””‹‚v{lrif]cdc\”“›œ¤¦ƒƒ|ƒ‚u“““„„Š‹‹„‰‰wsretts{tt””‹£œ¥„Š„š””‹„‹”“›‹‹‹„Š„ult‚v‚tllult|‚z„Š„{{tœ¤¦‹„‹’ŒŒ‚v{ƒ„„ldd{tt{||œ¤¦…‹’…‹‹{{ƒ›¢›lkslek‹„„‹„„ƒƒ|‹‹„‹u…’…‹‹„‹‹‹„’ŒŒ{{ƒ››”{{t¦§¨ŠŠ}¦§¨™š¤…„’{{tult„„Š|‚zŒ”•llktslmtt£œ¥|„…llklddlek{{ƒ{{tƒ„„‹„„ƒƒ|‚v{’ŒŒ¨©´¦§¨š””ƒ||””‹“Œ”‹„‹œ››‰ƒvkd\redulttsldc\sleƒ}ƒlekƒ„„””‹JHF{{tlldkd\UMRUTSlksSKJUTS]bZƒ||lritslkk]tslllk{tt{||ƒ||Š}|‚ut|‚z¦§¨‚v‚œ¤¦|‚z‹‹„|‚ztsl‹‹‹‹‹„…‹‹llkj]\Œ‹“|‚z£œ¥{u{tt{\[[|‚zlldŒŒš“Œ”uztkk]ƒ||tt{lek{u{“““dc\f]cuzt‚|ucbVu{{tzlddcƒƒ|dc\sleƒƒ|””‹‹‹„VTLb[Ulri{zm‚v‚ek]lldsle{||’ŒŒllkd\\›”›JHFttsb[UbVUztl{zmtzlŠŠ}SKJ]bZfkk|‚z‹„‹tll“Œ”[[TtslultŠ}|ƒ}ƒllkyle‚|u’…‹tllƒ||‚v{ztld\\{||yletlllri‚wlj]\‹„‹uzt‹‹‹ldduztult“Œ”‹„„{{ƒ{u{{{ƒŒ‹“lekmttddc„„Š™š¤{||¦§¨Œ”•{||··Ä¨©´œ¤¦Œ”•|‚z™š¤‹‹„u{{”“›ƒ„„ª³·¨©´ª³·Œ‹“¦§¨Œ”•‹„‹tsl™š¤œ››’ŒŒ‹„‹’ŒŒ¤¤”››“Œ”“““‹’Šƒ||‹‹‹¦§¨tsl“Œ”‹‹„ƒ}ƒtll£œ¥ƒ„„£››‹„‹‹„‹ƒ„„‹’Š‹‹‹Š}ƒttsš””‹‹‹{{tƒƒ|ƒƒ|[[T“““{|||‚ztllƒ}ƒƒ„„œ¤¦mtt|„…fkk£œ¥”“›“Œ”‚v{‹„‹„Š„|‚z“Œ”‹„„tlllri‹‹‹‹„‹£œ¥ldd‹‹„‰‰w”š”|„…{{ƒu{{¨©´Œ‹“lri„„Šllk{{tlks‹’ŠŒ”•‹’Šylelks{{ƒtslƒƒ|‹„„lks‚v{‹‹‹{{ƒŠ}ƒ‹„‹ztlztlbVZƒ}ƒ™š¤ztld\\Šƒ}{u{„Š„ƒ}ƒsrelekedkƒ„„£››JHF:97llklldj]\lek[[T„„Štslldd{||lekdc\dc\{ttb[UŒ‹“lkstsl‚|uŠƒ}ŠŠ}ƒƒ|Œ”•{{ƒœ¤¦””‹“““‹‹‹sleœ››{u{ttsŠ}ƒ›”›‹’Šlldƒ}ƒlddmtt|„…mtttll{{ƒ¨©´“““sle‹‹‹ƒ„„f]cJHFlks|„…b[UJHF{{tD;9u{{ƒƒ|‹‹‹œ››tts{||b[U]bZ[TTƒ||‹’Šƒ„„dc\ƒ||ttstsllldllkztl{{ƒ‹’ŠlekbVZf]cƒ||‚v{Š}|ƒ||ztfrg]VTLd\\lldllkttsf]cƒ„„ƒ‚u|‚z‚|uŠ}ƒlld‚|utll‘ˆ}zll’ŒŒrg]j]\{{td\\|‚z‹„„ztltt{‹‹‹uzt‚v{„Š„lldlldƒ„„mtt…‹’ƒ}ƒ„„Š{u{Œ”•|„…mttllk\[[›”›‹’Š{{ƒŒ”•|‚zƒ„„£²”››|„…œ§²›¢›Œ”•„„Š£œ¥“““Œ”•‹„‹{{ƒª³·››”lks™š¤£››ƒ||{{t¨©´“““œ››Œ‹“„Š„”››¨©´‹’Š¦§¨¦§¨„Š„uzt¦§¨“Œ”{u{›”›‹„„’ŒŒƒ||””‹ultddc“““slerfk{u{{tt‹‹‹œ¤¦{{ttzl]bZmttƒ„„Œ‹“lri{ttŒŒš{tt\[[mttŒ”•{{ƒƒ}ŠŒ”•tt{‹‹„fkk{{tƒ„„ƒ}Šztlœ››uzt’ŒŒ“Œ”{{ƒ‘Œ…‘Œ…ƒ‚u„„Šedkƒ}ƒ‹‹‹¨©´{u{lriultnƒ|„…{{ƒ”“›lri‚utš””“““‹‹‹{{ƒ››”¦§¨”“›ƒ„„‹’Š£œ¥fkk‹„„‚|u””‹{tttzl£›››”›{{t‚v{{u{tsllddcbVSKJlddf]c£››JHF*)(\[[[TTSKJ‹’Šdc\ƒ}ƒ[TT‹’Š{{tlddSKJtsliq]b[U{{tek]‹‹‹sle””‹lldlrittsultlld]bZ”š”ddc£››ttsf]cttsu{{ultUMR‚|ulddultŒ‹“}‡’|‚z{tt”“›yfl{||‚|utsltt{edkSKJlksuzt{{tJHFtll\[[‹’Škk]›¢›ƒ„„‹‹‹ƒ||lldœ››Šƒ}{zm{ttddcb[U{||z‚l‹’Š”“›{||b[Ud\\VTLf]c\[[b[UUMRj]\‚|u{tt‘Œ…‚|uredsreƒƒ|…„’„Š„{||„Š„uzt”š”kd\kd\ƒ„„™š¤Šƒ}{{tƒƒ|tsl{u{‘Œ…lritlllld{ttzllyleƒƒ|tslttsŒ”•lldekd‹‹„{{ƒŒ‹“yl„]cdultuztult{{ƒ{||tt{¦§¨…‹‹”››uzt…‹‹¦§¨Œ‹“¨©´œ¤¦lrimtt…‹’Œ‹“‹‹‹ƒ„„‹‹‹|„…“Œ””››|„…£œ¥¨©´¤¤‹„„œ¤¦“““¦§¨··Ä‹…’ŠŠ}{{ƒ{u{{{ƒƒƒ|…‹‹”››“““µ¶·Š}ƒ{ttƒ}ƒƒ||“Œ”ƒ}ƒ{ttƒ}ƒ„„Š“Œ”‹‹„‹‹‹“Œ”‹…’…‹‹|‚zœ¤¦mttddctzl{{ƒultf]cƒ||UUYlddœ¤¦|„……‹‹rfk‹…’mttf]cd\\edk£››”››{u{ƒ||ƒ||››”“““lld“Œ”’ŒŒµ¶·’ŒŒƒ„„™š¤‚|u£œ¥Œ‹“‹„„”››„„Šmtt„Š„f]c‹…’Œ‹“’ŒŒ’…‹„Š}„„Š‹‹„‹‹„²¬µ‹„„ttslri„„Šƒ||llkƒƒ|ttsred{{tŠ}ƒ{{tƒƒ|tll‹„„\[[{{tkd\‹„‹ek]fkk¢—FD;3+*Œ”•VTLb[Ulrisrelddƒ||[TTJHFd\\\[[ƒ||sre{zmƒƒ|ztl‚utztlztllld””‹…‹‹“Œ””››ult|„…uzt‹‹„{u{uztultƒ||tt{llk„Š„lektlld\\[TT\[[[[TŒ”•œ››„„ŠbVUztlb[Uttsf]cf]c{||Šƒ}[[TVZTŒ”•|‚z…‹‹tzl|‚z{tt{u{{zmrg]“Œ”ztfkd\dc\{{tultlrikk][TT„Š„’ŒŒttsƒƒ|„„Šdc\ek]\[[mwiWUzlltsl’ŒŒlldldd|„…Œ”•lri””‹|„…tsl‹’Š‚utŠ}|‹„‹£››srekk]kd\ekd‚v{bVZdc\ƒ}ƒtygb[Uƒ||redlldlekult|‚ztts{{t{{tƒ}ƒ„„Š”“›{{ƒ{{ƒ]cd{{ƒ”“›tt{{||™š¤|‚z{{ƒ›¢›Œ”•tt{‹…’£œ¥…‹‹{{ƒª³·…‹š‹‹„‹‹„”››Œ‹“Š}|“Œ”¨©´…‹‹™š¤‹„‹š””‹‹‹{||‹’ŠedkUUY{{ƒ¦§¨tt{š””ultŒ”•‹‹‹¦§¨£œ¥¤¤uzt’ŒŒult£œ¥‹…’’ŒŒ{||{{tldd„Š}{{tred’…‹ztl”››”š”…‹‹š””tsltts{tt{u{ƒ}Štslu{{ƒ„„‹’Šlksƒ„„mttƒ}Š]cdtts‚ut{{ƒƒ„„|‚z”“›£››rfk‹‹‹’…‹œ››‚|u’ŒŒ“““¤¤™š¤„„Š‹’Š™š¤tt{‹„‹“““{u{„„ŠŒ”•lks‹…’Œ‹“£››”š”ƒ„„‹‹„Œ‹“’ŒŒ£œ¥ttstllulttts’…‹f]cz‚llri{u{‹„„œ››‹‹„‚uttts’ŒŒ|„…]cd‹‹‹{u{{{tllk””‹SKJ*)(|‚zd\\\UZ[[TJHFƒ„„ultddc|‚zsle‚ut‹’Š|‚z””‹“““‚v{ultlldzll|‚z“““kd\ƒ„„™š¤‹‹‹œ››Œ”•{{t‚v{ƒ}ƒ…„’kk]f]czll¦§¨ddcnƒult…‹’›¢›ult“Œ”£œ¥”š”tt{kd\{{ƒf]cult\[b{||\[[„Š„llk“““œ¤¦tt{dkV]bZ{u{|‚zslesleztl‘Œ…ekdlri{||[TT{zmsle‚wlƒ}ƒŠ}|”“›{||“Œ”‚wlƒ||dc\Š~‹‚wlŠŠ}ƒ‚nŠŠ}kk]›¢›tslƒ„„lri‰ƒv…‹’|‚ztsl‘ˆ}Šƒ}ztlcbV|‚zd\\‚utultŠ}ƒedk{{ttlltslb[Utlltllƒ||mtt{{tuztkk]lld{{tlks{{ƒ‹‹‹ƒ}Š…‹‹{{ƒ{{ƒtt{ƒ„„ƒ||Œ‹“™š¤™š¤„„ŠŒ”•‹‹‹‹‹‹¨©´™š¤Œ”•…‹’¨©´¨©´¦§¨›¢›…‹štll‹‹„™š¤£œ¥¦§¨£œ¥¦§¨Œ”•ƒ„„{{tš”””“›{{ƒ«²«mttƒƒ|¨©´{{ƒƒ}ƒ™š¤”š”ztl{u{‹„„£œ¥¦§¨›”›µ¶·£››Šƒ}‹„„„„Šttstsl{ttƒ||…„’ƒ„„|‚z‹„„{||Œ‹“ztlult„„Š‹‹‹nv‚{||lri‹„‹„„Š[[T{||{{ƒŒŒšf]c„Š„[[Tƒ„„{{t²¬µlritsl‹‹‹tt{”“›‚|uš””‹‹„“Œ”ƒ}Š›¢›””‹…‹‹™š¤„„Š”“›‹‹‹|‚z“““™š¤{{ƒ“Œ”ƒ||{||{||sle{u{{u{j]\j]\¨©´Œ‹“œ››‚v{{{t””‹‹„‹”“›¤¤Šƒ}’ŒŒ“Œ”tllƒƒ|uztuzt‹„‹„Š„{||””‹D;9*)(f]cVTLlriu{{sre{u{ztlVTLttsddc[TTuztlri‹’Štzl‹„‹£œ¥uzt””‹lriult|‚z{tt¦§¨“Œ”ƒ„„”š”{{t’ŒŒ”››{||d\\llklriƒƒ|tts‚v{{tt‹…’Œ”•‹‹„ƒ||›”›ultultŠƒ}„Š„uzt”“›JHF[[T‚utlritlldc\”“›tt{]bZkd\tsl{u{red‹„„slelddtslŠƒ}sle\[[{{t‹’ŠbVU{{tztfŒ‹“‘…„rfkldd‹‹„sreŠ~‹r]g{||ƒƒ|{u{lri›¢›ƒ„„|„…lek[TTb[Utsl[[Tsle‘…„dc\tllrg]|‚z‚|u{tt{u{kd\{zm[TTƒƒ|ƒƒ|‹„„’ŒŒztltt{uztƒ„„lri“Œ”ƒ„„ƒ}ƒtt{‹„‹}‡’“““…‹’Œ”•{{ƒ…„’|„…”“›|„…edkƒ„„Œ—£œ¤¦{{ƒ{{ƒ„„Š|„……‹’‹‹‹œ¤¦“““…‹’‹’Š”š”¦§¨¨©´ƒ}Š£œ¥·¶Ñœ¤¦Œ”•„„Š”››ƒ}ƒtzl„„Š{{ƒlks{u{Œ”•Š}ƒ¦§¨‹‹‹tts„Š„{u{llk‹„‹‚v{µ¶·¦§¨{u{tll{u{tllƒƒ|{ttultllkttsu{{‹’Š¦§¨””‹¨©´|„…{u{lks†~‘edk›”›„Š„“““„„Š„„Šlks{{ƒlksb[Uyle’ŒŒ””‹“““››”ƒƒ|››”¦§¨“““{tt’ŒŒ‚ut„Š„Œ‹“ƒ|||‚z“““‹‹‹ª³·…‹‹ƒ„„tt{|„…”“›‹„‹™š¤tll‹„„tts{{ttsl‹„„‹’Š‹„„“““Œ”•œ››š…Žƒ‚u’ŒŒŠƒ}ƒ}ƒ|„…ƒƒ|’ŒŒ{tt’ŒŒƒ||ttsƒ„„{||{tttslfkk””‹MRK*)(leksre]bZ{tt„Š„lddkd\d\\UTSUMR{{tuztmttdc\{zm‚v‚tll“““ldd|„…SKJu{{|„…|„…‚|uª³·Œ”•ƒ‚u‹‹„™š¤‹„‹Œ‹“ƒ„„¦§¨kk]\[blksŒ”•edkldd…‹’bVU„„Š””‹{tt‹‹„{zm{{ƒ{u{{u{tllƒƒ|tzl””‹|„…””‹[[TbVUlri“Œ”£››FD;ttsredkd\b[Ud\\{zmVTL›¢›ƒƒ|[TTllkƒ||{||b[U{ttŠ}|sle’ŒŒƒ||kd\lldƒ‚n{{tlld‹‹„{||Œ‹“|„…“““ƒ}ƒlriƒƒ|‹„‹’ŒŒttsb[U‹’Šek]ztlrg]‹„„ƒ‚uztf[TTtts‹‹„‚v‚zllkd\Œ”•llkuztddc‚|u{tttt{tsl™š¤œ››“““™š¤™š¤…‹š|„…Œ”•ŒŒšttsfkkƒ}ƒ{u{{{ƒ›”›{{ƒ}‡’Œ”•|„…|„……‹’}‡’mtt|„…¨©´tts··Ä™š¤…‹’›¢›‹„„‹‹‹‹„‹“““œ››¨©´ttsrfk£œ¥£››‹„„“Œ”“Œ””š”‹‹„‹‹„{u{zll{||‹’Š‚wlœ¤¦|‚zƒ„„uztlkslri|‚zttsf]clekekd„Š„|‚zŒ”•™š¤|„…lkslriultlksdc\tsl|„…‹‹„Š}ƒUUY{{ƒƒ}Š›”›š””kd\””‹›”›œ››‹„‹‹„„¦§¨“Œ”sle””‹ult{{t{{ƒƒ||‹‹„””‹‹‹‹{u{{{ƒ™š¤„„Š{||Œ”•“Œ”f]crfkŠ}|lriztl‹„„‹„‹›¢›‹‹„tt{Š~‹ƒƒ|ddcŠŠ}””‹ƒ||{u{ttsŒ”•‹„‹”š”‹„„ultddcƒ„„{ttultsre\[[ƒ||JHF*)(llklldkd\lldƒ‚u‹„‹ddcd\\UTS{u{ddcttszllddc{zmtll{||tts‚|u„Š„„Š„”š”œ¤¦‹’Šƒ}ƒlkssretsl’ŒŒlri“Œ”j]\j]\¤¤”š”{||lekƒ}ŠŠŠ}{||[[Tf]c“Œ”|‚zzllkd\ttstslƒ„„‹‹‹lri’ŒŒ>EC|‚zŒ”•{u{uztztlŠ}ƒ’ŒŒ{{t{{tsle‹„„bVZu{{ldd{{tlld|‚zlriVTL£œ¥VTLultkd\ƒ||j]\ƒ||]cd‚v{VTLdc\dc\ƒ„„tzl{ttuzt’ŒŒ…‹’‹„‹yle{{tllk‚utƒ||ŠŠ}llktsl‹‹‹tllztl“Œ”{{tek]sleƒƒ|‚utƒ}ƒldd‹„„‹’Šƒƒ|‹‹‹lldƒ}ƒ“““‹„‹{||“Œ”mtt{{ƒ{{ƒlks…‹’|„…tt{”“›{||„„Š{{ƒ™š¤Œ”•ŒŒš|„…}‡’}‡’|‚z…‹’Œ”•tts™š¤“““œ¤¦Œ”•”››lksnv‚mtt“““|‚z{{ƒ™š¤ƒ}ƒƒƒ|ƒ}ƒ‹‹‹mttztl’ŒŒult“Œ”Œ”•{u{ƒƒ|¨©´“““ƒ||{{t“Œ”ƒ||llkddcttsƒƒ|Œ”•’ŒŒ‚v{lks{u{{{tƒ„„Œ”•{u{{{ƒ…‹’ultlksUMR™š¤”››‹’Š|„…lri|‚z]bZUMRd\\b[U‹‹‹llk‹„„”š”|‚z{zm‹„„›”›ƒ}ƒldd’ŒŒŠ}|ƒ„„{tt£œ¥›¢›sre›”›“Œ”¦§¨‚v{Œ—£‹‹„“““ƒ||llkd\\{ttsreƒƒ|›”›œ››“““‹„„ƒ}ƒ{{ƒkd\lddƒ„„›¢›ƒ||›”›“Œ”‰|vŠƒ}œ››ƒƒ|ddc\[[d\\[TT\UZ[[Tƒ}ƒ¤¤74,74,lddVTLb[U‹‹„uztdc\ddc{u{u{{dc\d\\tsl]bZddcredlritllsleƒƒ|ekd™š¤ƒƒ|lekª³·”“›lek„„Š²²¬ultu{{b[U¦§¨tlllri‹‹„{{ƒtt{Œ”•‹‹„SKJUTS{u{{tt””‹’ŒŒtsllldtt{yl„ttsztltllƒƒ|kk]\[[ddc„Š}¦§¨ƒ}ŠultttsŠƒ}|‚zj]\‚|uztlu{{tllƒƒ|ttsƒ„„d\\fkk{tt“Œ”ult{||Œ‹“ƒ„„ƒƒ|“Œ”{zm|„…lksdc\Š}|Œ”•ztf{u{“Œ”“Œ”¦§¨tts‚utult[TTek]ƒ||ztl{ttkd\ztlƒ„„”š”››”{tt{zm‚|uultldduztŒ”•{{ƒƒƒ|{{t‹„‹uztllk‹‹‹…„’ultf]c|„…nv‚fkk{||Œ—£ŒŒš{{ƒ£œ¥“Œ”œ¤¦u{{Œ‹“Œ”•…‹‹|„…|„…|„…ƒ}Š”››tts„„Š™š¤‹„‹ƒ||{{ƒŒ—£mtt””‹„Š„™š¤”››™š¤dc\{{ƒƒƒ|{tt¤¤“““„„Šµ¶·ult¨©´œ››£œ¥zlltllllk”“›ttsu{{‹‹‹”“›”››ekd”“›ƒ}ƒtzlƒ}ƒlldtts…‹‹f]crfkŒ‹“\UZd\\\UZ‹…’|‚ztsl‹’Š‹„„uzt]cd|„…lks[[Tš””{u{‹„„„Š„¦§¨µ¶·”“›‹„„ƒƒ|uzt²²¬{tttts{||{tt‹‹„Šƒ}¦§¨Œ‹“”››‹„„Œ”•”››„„Š›”›{u{bVUƒƒ|”š”‰ƒv{||™š¤“““‚|u”“›ult¦§¨ŠŠ}„Š„|‚z…‹‹ult”“›{||ƒ}ƒkd\‚|uƒ„„|„…Œ”•lrif]c|„…tt{²««JHF3+*bVZllkj]\tll]cdlld]cdult{{tUTS“““[[TlriVTL‚|u„„Šlksd\\j]\ttsœ¤¦‹‹„›¢›™š¤lddldd”››‹‹‹ldd…‹‹‚ut””‹“Œ”››”d\\uztttsedk‘Œ…lekƒ„„“Œ”{u{ƒƒ|‚v{‹’Š|„…{{tslellkVZTlri|‚zz‚lddc™š¤ttstll|„…š””u{{‘Œ…sreb[U{ttŠ}ƒsled\\tts„Š„{ttldd\[b››”ldd{zmtt{„vŒ™š¤tzl‹„‹f]cdc\lri‚|ukk]{yfd\\llkf]c{{tŠƒ}‹’Štlltll{u{‹‹„…‹‹‘Œ…””‹‚utj]\zll|„…‹’Šsle{{t””‹›”›‚v{œ››{{ƒƒ„„‹„„tsl„Š„‹‹‹‹„„”š”{{ƒƒ„„“Œ”¨©´Œ”•Œ—£Œ‹“‹„‹”“›‹‹‹¨©´™š¤ª³·”“›ŒŒš|„…œ¤¦|„…Œ‹“|‚zŒ—£¦§¨…‹‹£œ¥™š¤ƒ||œ››„„Šlks™š¤››”„Š„œ§²{||redƒ}Š‹„‹ƒ„„‹‹‹{tt”››‹‹‹ultŒ‹“··Äƒƒ|ldd‹„„Œ‹“tt{sleuzt‹„‹ƒƒ|fkkƒ}ƒ…‹‹ƒ}ƒlld{||{{ƒ‹’Š…‹‹ƒ„„{u{MSSf]cUTS”“›f]cmtt{{ƒƒƒ|™š¤Œ”•‹‹‹u{{edkedktslƒ||ƒ}ƒ“Œ”””‹ŠŠ}‚wl“““›”›{||”š”‹„„‹‹„„Š„ultƒ}ƒbVU[[Tƒ}ƒtts]bZŒ‹“ƒ„„Š}|{||“Œ”‚v{{tt¦§¨«²«‹’Štsl¨©´…‹‹“Œ”Œ”•Œ‹“{tt[[Ttsl‹‹‹„„ŠŠ}|sle‰ƒvƒ||ultuztŒ”•uztƒƒ|tllUUYddc\[[£››:97&&red{zmJHFVTLMRKƒ‚u\[[[TTVTLJHFVTLtslsle[TTllddc\””‹i\Vtsltts“““ƒ„„lriœ¤¦£››\[bddcƒ||ultœ››{ttƒ||“““ƒƒ|Š}ƒ™š¤{{ƒlksSKJedk{{ƒƒ}Šlld‹‹‹sleƒ„„]cd‹’ŠbVZUTSVTLdkVfkkFD;„Š„aWM]bZVTLSKJƒ||uzt‹„„lri’ŒŒldd’ŒŒ“Œ”lddƒ}ƒtts{ttddctllƒ||redf]cŠ}ƒzlld\\tzlƒ„„{ttuztdkVVTLŠŠ}JHFredf]cult{||tll“Œ”{u{’…‹lekƒ„„{tt{||‚|u‹„„tllƒ||ldd|‚zŠƒ}tts‚ut{ttf]c‚|u‹’Š››”{|||‚zŠƒ}ƒƒ||„…‚v{™š¤…„’‹…’…„’}‡’lks{u{ŒŒš™š¤™š¤|„…Œ‹“›²¦§¨…„’tt{œ¤¦}‡’ª³·…‹’‹„‹{||œ¤¦›²›²œ¤¦›¢›¨©´Œ”•Œ”•£››«²«…‹‹‹‹‹‹…š{{ƒ‚v{‹‹‹ult«²«œ¤¦™š¤“Œ”ƒƒ|¨©´£œ¥rfk”“›£œ¥„„Šƒ}Š„„Š…‹’‚|u{||{{ƒƒ}ƒ{tt{{ƒ››”£œ¥›¢›œ¤¦”››¨©´|„…|‚zd\\“““{{ƒ]bZƒ}ƒlldƒ}ƒœ¤¦ƒƒ|{{ƒJHFult”š”‹‹‹tt{…„’‹„‹””‹tzl{||{tt¦§¨”š”’…‹ƒƒ|„„ŠŒ”•“Œ”|„…lldldd|„…›”›ƒ||Œ”•|‚z„„Š‹„‹™š¤š””sreƒƒ|{yff]c‹’ŠŒ”•|„…ƒ}ƒ{{ƒ‹„„lriVTLek]ƒ}ƒ‹„‹llkcbVldd[[Ttlledk\[buztztl[TTUTSedk””‹:97&&\[[SKJVTLz‚lVZTek]FD;ultd\\|‚z‹‹‹lldsre’ŒŒsle…‹‹kd\jcV‹’Šƒƒ|llk‹’Šlld\[[„Š}uztƒ„„„Š„“Œ””š”‹…’‹…’ª³·£››{tttsl{||›”›tllf]ctlllldŒ”•Œ‹“‚ut”š””››\[[ultSKJ{{ƒ{zm[[TVZTlddJHFu{{lddVTLtlllldd\\tsltsl‚v{‹’Šztllrillkttsj]\lriUTSb[UlddŠƒ}lddƒ}ƒultzllf]ckd\lritzluzt››”‚wllddttsƒƒ|‚utreddc\‚uttts{{ƒ“““Œ”•‹’Šƒ||Šƒ}‚wl{{t{{tddctlllriŠŠ}redddc{{tztltsluzt|„…‹„‹”š”u{{„Š„ƒ}Š„Š„’ŒŒ…„’{{ƒ{{ƒ‹…’™š¤u{{ŒŒš{{ƒ”››…‹’Œ—£{{ƒ{{ƒŒ”•…‹’“Œ”Œ”•¨©´™š¤…‹‹Œ”•™š¤£››‹‹‹™š¤edkœ¤¦›¢›¦§¨™š¤”››‹„„›”›”››œ›››¢›¦§¨‰‘~ŒŒš£œ¥µ¶·¨©´‹„„¦§¨¦§¨™š¤‹…’„Š„|„…ƒ||“Œ”tt{Œ‹“‘Œ…“Œ”Œ”•‹‹„‹…’”››lrimttŒ”•‹’Šekd{u{rfklks\[buzt’ŒŒ“Œ”u{{Œ”•…‹‹f]c[TT„Š}“Œ”ult”“›œ¤¦‹’Š‹’Š‘…„{|||‚ztts“Œ”ult‹’Š“Œ”ƒ}ƒ‹„‹|‚zb[Utts£œ¥‹„„{||{tt‹‹‹ƒ}ƒƒ}ƒ”“›‚|u|‚z„Š„Œ”•‹„‹«²«“Œ”ldd\[[‚|u]bZkk]sleŠ}ƒldd{||„Š„{{t{tt››”‹‹‹|„…|‚ztlllek{||JHF£››JHF3+*edkek]lldb[Udc\lld\UZVTLVTL[TTlddlld{{ttlllddƒƒ|Šƒ}yle¤¤‹‹‹{||{{t„„Š|„…{u{‹’Š”“›ƒ„„‹„‹›¢›”››{u{{{ƒšŒ›¢›fkkr]Z{{ƒs_q‹…’rfklek™š¤lld”››‹‹„uzt‚v{ƒ‚uldd‹’Šƒƒ|MRK]bZVZ[llklld‚utekd‹„„ddcztl]bZUMRztfdc\Šƒ}JHF\[[f]cƒƒ|Š}ƒ{||j]\tllkd\d\\…‹’ƒ||{ttttslks„„Šƒƒ|œ¤¦Šƒ}£œ¥Š}|lldllkultlddlld””‹{tt‚v{››”‹‹„“““rg]’…‹’ŒŒ{tt{ttlldf]c{{ttllllklddredƒƒ|{{t›¢›¤¤œ¤¦“““”š”””‹™š¤u{{…‹‹Œ”•…‹’„„Š…‹’™š¤œ¤¦Œ—£mtt™š¤‹…’”“›{{ƒlks›²œ§²œ§²œ¤¦”››£²{{ƒ{||lri‹‹„sre…‹’u{{…‹‹|„…|‚z|‚zŒ”•””‹‹…’ultœ¤¦“““ª³·”››ŒŒštts“Œ”™š¤„Š}„„Šƒ}ƒ‹„‹“Œ”Š}ƒu{{ztl{{t”“›ttsj]\š””uzt‚|ubVZmttŒ”•VZ[|‚z…‹‹tts{{ƒ‚|uf]c‹…’”“›””‹ŒŒštllekdUTSlks†~‘[[T{{tlks{{t¦§¨””‹¦§¨’ŒŒtllƒƒ|£››‘…„ldd„Š„tt{Œ”•‹‹‹£²‹„‹ƒ}ƒ›”›ult…‹‹“Œ”edk›”›tt{{{t‚|uƒƒ|„Š„|„…‹„„{||lldlksultb[Ulld{{t[[Trfkult’…‹ƒƒ|lld””‹”š”„Š„‹‹‹ekd‹‹„[TTtslddc²²¬FD;*)(ultddcSKJD;9JHFcbVf]cSKJ[TTldd\[[tslŒ”•[[Trfk„Š„Š}|lld{zm‹’Šuzt{{tlri„Š„ƒ„„’ŒŒŒ‹“„Š„{tt’ŒŒ\[[‹„„{{ƒf]c«²«„Š„…‹‹{||Š}ƒƒ„„‹‹‹ultŠ}ƒbVZ„„ŠbVU…‹’š””””‹{{t›¢›Ž¡›ult]bZultldd[[Tlddlld“““[TT‚|ub[Ulld‚|u{ttek]ddcddcVTLSKJFD;kk]ult{{tddcuztVTLtllbVZ{||[TTtslldd¦§¨lritllŠ}|ƒ„„{{tƒ||bVUttsredredzll‹‹‹{{t|‚z{{tztl|„…|‚z‚utœ¤¦kd\…‹‹ztl‹„‹edk|‚z…‹‹lld‹„„‹„‹‹„„”››Œ‹“uzt|„…{{ƒŒ”•}‡’¨©´œ¤¦™š¤›²œ¤¦™š¤ƒ}Š‹„‹„†™}|’{{ƒ{{ƒŒ—£œ¤¦|„……‹šf]ctt{ultŒ”•…‹’‹‹„‹’Š„„Š{||¨©´«²«‹’Š…‹‹mttŠ~‹…„’{{ƒŠƒ}””‹œ¤¦|„…Œ‹““Œ”‹„„Œ”•„Š}ƒ||„Š„…‹’{tt‹’Š{{ƒŒ‹“d\\{||f]c‚v{r]g{{ƒ‚wl{|||‚z]cd|‚z|‚z„Š„{{ƒ|‚z{||f]c™š¤tslƒƒ||„…lld‹‹„†~‘‹’Š£œ¥„Š„ƒ||{{ƒlld…‹‹‹„‹‹‹„ƒ||“““Šƒ}ƒ||Œ‹“tsl‹‹‹™š¤ldd„„Š’ŒŒrfk“Œ”ƒ}ƒldd…‹‹{u{|„…›”›ƒ„„tt{ƒ||«²«lriƒ}Š™š¤Œ”•{||{||Œ‹“d\\kd\tsl\UZlddultu{{uzt|‚z’…‹’…‹‹’Šƒ„„‹’ŠŠ}|f]cVZT\UZ¦§¨UMRlddVTLFD;FD;‹‹„[[T‚ut[TTfkkƒ}ƒ[TT[[T‹‹„lek[[Tƒ„„ztfVTLcbVdc\‹‹„tslfkk“““|‚zmttek]’…‹ƒ||tzl“““{{tttsœ››¤¤’…‹tt{ddc‹‹„ƒ}ƒš””’…‹‹„„Œ”•¦§¨VTL\UZ””‹”š”|„…‹‹‹”š”ª³·lriedkdc\|‚zztlttstllekd‹„„SKJ‹‹„ttskk]ƒƒ|uztlldSKJ‚|utsltlld\\f]ckjVƒƒ|SKJb[Uztluztulttsl‘Œ…‹’Š|‚zsle{tt‹‹‹‹‹„Š}ƒlks[[Tkd\red‹„„ƒƒ|kk]u{{‘Œ…lddllk{{ƒsledc\f]cƒ„„š””Š}ƒult”››‹’Štllztlƒ||llk{||{{ƒƒ„„ƒ}Šmtt™š¤}|’{{ƒŒŒš™š¤‹…’nv‚˜Ž£}‡’ult{{ƒ™š¤›²}|’{{ƒ}‡’Œ”•|„…Œ‹“Œ‹“™š¤|„…ŒŒš¦§¨”š”…‹‹Œ—£”š”|„…tzl|„…Œ”•|‚zultƒ||‹’Š””‹“Œ”„Š„¦§¨lks{tt…‹‹„Š„{||›”›Œ‹““Œ”o€w|„…{ttsle|„…‹’Š‹‹‹ult¦§¨‹’Šredekd…‹‹œ¤¦|‚z]cd|„…mtttslmttedkŒ‹“‹‹„uztcbV\[[››”œ§²|„…™š¤‹„„ƒ||f]cŠ}|œ››œ¤¦š””‚v{š””[TT{{ƒ””‹”››Œ”•tllŠƒ}{{ƒd\\ƒ}ƒŠƒ}{{t{||ddcddc…‹’“Œ”rfktsluztddcult¦§¨llk‹‹‹”š””“›‹‹‹dc\››”‚|uUMRƒ}ƒtsl{||tsld\\ttsddcu{{{u{{ttlekVZTddc²««D;9*)(dc\VTLFD;D;9ek]kk]bVUult{{tlksd\\lrilriVTLlks‚|uj]\cbVlldVZTuztMRKƒ„„u{{{ttŒ”•lriœ¤¦u{{ƒ‚u{tt“““‹‹‹mtt²²¬ttsƒƒ|mttf]c™š¤tsl‹„„ult„Š„Œ”•ŠŠ}”“›ƒƒ|ulttts]bZ„„Šƒ„„{ttultztl{{tztl]bZ“Œ”{zmlri\UZ„Š}{u{Š}|d\\uztƒ}Šƒƒ|Š}|sreœ››‘ˆ}f]c‚v‚{{tlddSKJ‹„„ddc‚v‚ek]VTL[TTdc\llkddc\[bƒ„„ƒ||”š”tsllldredUTSlldkd\ƒ„„redVTL{||[[TFD;llklddtsltsl{{ƒf]cfkktsl‹„‹ƒ||llkultlrifkk„„Šmtt|„…‹’Š|„…{{ƒ…„’Œ”•”“›œ§²¡¡mk…}|’Œ—£{{ƒlks{tt‹…š|„…¨©´Œ”•…‹‹”“›™š¤Œ—£¨©´‹„‹Œ”•‹„‹Œ‹“¦§¨|‚z‹‹‹lri|„…Œ‹“{u{}‡’’ŒŒ{{tƒƒ||‚z™š¤]cdlks…‹‹Šƒ}œ››{tt™š¤Œ‹“ŒŒš…‹‹lek››”…„’ª³·‹’Š¤¤{{ƒ{u{ƒ„„›¢›mtt™š¤{||VTL|‚z]bZtsl„„Šult‹’Šdc\‹‹„”š”™š¤™š¤|„…‹…’”š”’ŒŒ‚v‚{{ƒult¦§¨‹’Šœ››{u{ƒ||tsllek¦§¨Šƒ}ƒ„„“Œ”{u{{ttƒ}ƒ„„Š{u{sle“Œ”‚v{f]c{{tƒ}ƒƒ„„ƒ||lriztledk{{ƒ|„…››”™š¤“““¦§¨sle‘Œ…{u{d\\{||‹‹„mtttslultdc\|‚z{{ƒkd\ldd\[[tt{\[[¦§¨SKJ&&j]\Šƒ}f]cVTLJHF]bZzlltll]bZllklld››”tzlsleuztultVTLtll]bZ[[Tu{{tzl”š”llk|‚z‹’Š|‚zŒ”•{{td\\²²¬{||Œ”•ekd‹’Šlld{{ƒf]cedkš””lldbVU“Œ”lddult[[Ttt{SKJ{ttlddu{{lriUTSdc\rfkƒƒ|tsl{{ttslzll|‚zƒ||{ttttslldddcMRKf]clkstsl‘Œ…ekdƒƒ|‘…„{{ƒldddc\{u{FD;Q?@ultƒ}Šdc\ƒƒ||‚z{{t†~‘„Š„mttlldultŠƒ}|‚z{zmf]cuztŠŠ}{||UTSylerfk{ttdc\sle{||VTLtzlbVUlddllkdc\lddƒ||ztfllklddƒ}ƒu{{mtttt{uzt…‹’nv‚ŒŒšedklkstt{¨©´œ¤¦Œ”•›²œ§²“Œ”¨©´lks}‡’}‡’|„…u{{¦§¨„„Š£œ¥™š¤™š¤£œ¥œ››|„…|„…œ››œ››œ¤¦›¢›{{ƒu{{ultyl„ttsµ¶·‹„‹Œ”•\[[lkstsl…‹‹llk‹‹‹lri…‹‹{{ƒ””‹{||›”›„Š„„„Š{{ƒ¦§¨“Œ”£œ¥„Š„ldd|‚zlksƒ}ƒmttlrirfk\UZd\\\[b‹’Š{{ƒ‹‹„››”tslmttlkslksƒ„„{tt{tt|„…¦§¨’ŒŒ’ŒŒœ¤¦Šƒ}Œ‹“””‹ƒ||™š¤£››””‹{||’…‹{{ƒultult{{ƒ|‚z‹„„œ››|‚z™š¤{{t{{ƒƒ||””‹|‚zƒ||{||œ››‹’Šœ¤¦‹’Šƒ}Š„„Š’ŒŒ{{tddc{tt{{ƒkd\lriƒƒ|lld{ttƒ„„ttsƒ„„ztlfkk]cdllk””‹bVU-1+ldd{{tF=CsletllSKJ{zmzllldd\UZslelldddcd\\ƒ„„‹„„r]ZŠƒ}„Š}|„…JHF{zmfkku{{‹’Š„Š}lriuztƒ}ƒƒƒ|“““”š”tt{kd\{||VZTlksllk“““‹’Š›¢›[TTƒƒ|uzt„Š„Šƒ}›”›lddtlllriUUYVZTVZTUTS‹‹„‹‹‹{{tslettskd\ƒ„„VTLkd\tsl‹’Š…‹‹[[T\UZ‹’Š‰|vkd\ƒƒ|{{tsleƒ||SKJ””‹f]csre{tt{{ƒultƒƒ|rg]‹’Š„Š}lddtslbVUlri‹„„‚v{d\\UTSslekk]ƒ||”š”‹‹‹{{tŠ}|{ttttsek]{||ztlttslddjV[\[[\UZ{ttult‹‹‹ƒƒ|{{ƒ{||fkk“““£²„„Š…‹’{{ƒnv‚{||u{{{{ƒ„†™Œ—£œ¤¦}‡’Œ—£{{ƒ{{ƒyl„{{ƒ…‹’Œ”•™š¤™š¤ttsŠ~‹œ§²ŒŒšª³·™š¤£››‹’Štzl›¢›lldª³·ª³·lrimtt™š¤tll¦§¨ztlŒ‹“Œ”•ƒ}ƒ‹‹‹zllƒƒ|‹‹‹“Œ”™š¤{{ƒ””‹”“›‹‹‹bVZ|„…‹‹„‹„„{tt{{ƒ[[Ttll…‹’|‚zŒŒš„Š„[[Tƒ„„„„Š‹‹„ttsŒ”•|‚z]cduzt{{t{{ƒUMR|„…d\\{zmƒ}ƒ‹„„…‹‹ƒƒ|‹„„ƒ„„sleldd‹„„”“››”›””‹¦§¨ƒ}ƒ“Œ”¦§¨{u{{u{…‹‹Œ”•””‹ƒ}ƒ„Š„|‚z‹‹‹”“›‹„„ddc{||„Š„{{ƒult‹’Š’ŒŒ|‚z“““kd\“““››”„„Šš””redŠ}|tzl“““sle[[T|‚z]bZb[U[TT\[[UTSf]c¦§¨FD;*)(f]c‚|uSKJ]bZlddJHFddclldddc\[[“~ˆtzlekd{||ult“Œ”“Œ”tzlu{{Œ‹“llklldtt{ekd›¢›lkszlltt{uztƒ‚u‹’Š}|’””‹‹’ŠtsltllVTL{tt‹’Šztl…‹‹uztVTLlri‹‹„ƒƒ|‹‹‹‹„‹{tt]bZJHFb[U]cd]bZmtt{tt{zm‹‹‹[[Tlld{u{sreult{||]bZttslld[TTcbVVTLb[U””‹[TT{zmi\VbVZtllƒ}ƒsletlledkUMRek]kk]””‹VTLlddUTS“Œ”‹„‹‚utultkd\{||“Œ”cbV{tt|‚z‹‹‹””‹tllbVZuzttsl{||ƒƒ|lld‰ƒvtsllksbVZ{||ulttll{{ƒultmttfkk„Š„™š¤‹‹‹“““Œ—£{{ƒlksŽ¡›mtt‹…š…„’Œ”•…‹šŒ—£|„…„„Š…„’…‹š~’“ekdŒ”•ƒ}Š›”›ŒŒš…„’£››‹„‹™š¤›¢›“““›”›”š”ƒ||””‹ª³·ª³·‹‹‹{{ƒ‹’Š‹‹‹‘…„™š¤Œ”•{{ƒš””¦§¨“Œ”››”ldd‹‹‹£œ¥ŒŒš{{ƒ™š¤Šƒ}|‚zŒ”•ztlƒ„„{u{{||’…‹{{ƒŒ”•›”›‹’Š‚utf]c™š¤“Œ”ƒ„„lriUUYmttUTSdc\]cdtts{{ƒekdlek‹„‹lekŒ”•››”ttstzl‚wlŠ~‹›”›‹‹‹”“›lksœ§²|„…£œ¥{{ƒtsl{{ƒ™š¤‹‹„¦§¨Š~‹‹‹„u{{‹‹„ƒ}ƒƒ}ƒ‹‹‹ƒƒ|‚|u{||tt{fkk„Š„Š}|ultlri{{t‚|uƒ}ƒƒ„„ƒ}ƒƒƒ|ƒƒ|””‹‘Œ…ztlƒ„„tslVTL{ttultfkkUTS¦§¨MRK*)({tti\Vkd\FD;bVUPF=dc\UMRdc\sle„Š}tsl{u{ttstll›¢›jcV‚|utygƒ„„ƒƒ|u{{d\\mttekd„Š„ƒ}ƒŠƒ}|„…ƒ}Šuzt|„…|‚z””‹b[UddctllŠ}ƒŠŠ}\[[‹…’{zmj]\„Š„’ŒŒ‹„„[TT’ŒŒtlltts…‹‹Œ”•u{{lrillk›”›tllztld\\‚v{|„…ztlVTLttstzl{{ƒ{||„„Š[[Tb[U{{tŠŠ}\[[VTLJHFlddiq]d\\VTLlld]bZSKJJHFƒƒ|ƒƒ|ƒ||f]c„Š}ƒ}ƒddcd\\tll‚|u”“›“““lld£››‹’Š{u{’ŒŒŒ‹“ƒƒ|mtttsl{||Œ”•mttƒƒ|mwtts‹„‹[TTtll|‚z„Š„ƒƒ|ddcMSSlek™š¤Œ‹“lks|„…}‡’…„’|„…{{ƒ‹‹‹Œ”•Œ”•™š¤ƒ„„…‹’¨©´{{ƒŒ—£nv‚Œ”•…‹‹“““£²”››ŒŒš””‹{u{{{ƒ¦§¨ƒ}ƒ‹„„‹‹‹|‚zœ¤¦œ¤¦»ÂÇ‹„‹lks\[b›”›{tt„„ŠŒ”•Œ”•]bZ‹„‹‹„„””‹ult’ŒŒ„†™{{tœ¤¦””‹Œ”•„Š}tts„„Šultœ¤¦‹„„{||¦§¨”š”ª³·„„Šƒ„„£œ¥{{ƒ{{tŒ‹“JHF\[[LKRMRKVTL\[bJHFu{{u{{red£œ¥Š~‹|‚z“Œ”tts¦§¨›”›¨©´²««”“›””‹”“›Œ”•Œ”•‰v|ƒƒ|ª³·ttstt{…‹‹‹…’ultœ››“““ƒ}ƒ“““™š¤ƒ||ekd…‹‹ddcedk‹„‹ldd{zmmttultdc\ƒƒ|llk‹„‹‹„‹‹„„{{ƒ››”‹„„sle‹’Šdc\ƒ„„{tt]bZ]bZVZT£››b[U*)(f]ckk]Š}|FD;UMR{tt[[TVTLSKJVTLj]\VTL{u{ƒ||tlllldkk]ztl‹‹„‹‹‹”š”tslmtt\UZ„Š„Œ”•{u{‹‹‹™š¤{{ƒ«²«›¢›{||‹‹„{{tƒ„„‚utekdbVZUMR™š¤‹‹„{u{{||‚|u‹‹„lek‘Œ…””‹{{ƒuzt{{tekdJHFUMRldd|‚z‰|vf]c‹‹„{||ztl{ttVZ[‰‘~”››{{ttll{tt[[Tkd\ƒ}ƒFD;VZTd\\lddb[UtlllldlddJHFultekdƒ‚u””‹ƒ„„dc\tslƒ||dc\“Œ”¦§¨{{tkk]{ttƒƒ|‘Œ…››”ultredtt{|‚ztsl‹‹„Œ‹“š””{{tzllLKRmttƒ}ƒbVU{{ƒlri“““uztmtt{{ƒtt{}|’{||Œ”•{{ƒ|„……‹šŒ—£™š¤{{ƒ|„……‹’œ§²·¶Ñ¨©´”“›{{ƒœ¤¦œ¤¦|„…}‡’“““¦§¨œ¤¦Œ‹“¦§¨‹‹‹¨©´£›››¢›Œ”•™š¤””‹‹‹‹|‚zfkkf]clksŒ—£zll‹„‹‚v‚¬¶Ãš””lldredƒƒ|ƒ||„„Šœ››Œ‹“Œ”•Œ”•œ››Œ”•¦§¨lld|„…{tt”››‹’Š{u{„„Š„Š„{||uzt|‚z{tttt{JHF„„Š†~‘ƒ}ŠŒ”•…‹’zlluztlriVZTlrillkŠ}|llk„„Š{u{›”›‚|uztlƒ}ƒultƒƒ|™š¤¦§¨¦§¨‘Œ…”››™š¤”“›ƒ}Šf]clldƒ}ƒ{{ƒ‹„„‹‹‹„Š„ldd|„…llktts…‹’ekd£œ¥‚v‚tll‹„„ƒ||{ttleksletll‹„„‹„„ƒ||JHF{||zllkd\JHFUTSlek‚utfkk\[[ddc‘ˆ}JHFSKJbVZkk]b[UPF=3+*FD;[TTD;9JHFlddtsldc\{ttdc\‚ut{u{{||ƒƒ|¤¤ƒƒ|ttslddddcult[TT|„…™š¤“Œ”¬¶Ã¨©´œ¤¦Œ”•‰‘~iq]„Š„tllb[UddcUUYf]c{tt|‚zddc{u{dc\‚v{tslultƒ„„rg]Œ”•|‚zekd[TTlks‘…„{||lek”“›ƒ||b[Uš””›”›[[TŒ”•UTS{ttrfksresle”››j]\ttsUUYuzttllVTLleksre‚ut‚wl\[bƒƒ|“““ddcultlld‹‹„ƒ||\[[{{ƒ£œ¥””‹‹‹„‹„‹{{tš””{{tlksredultœ››Œ”•£››{||tllmttrg]ttstt{{u{ult{u{””‹…‹‹{{ƒ…‹‹…‹‹Œ—£Œ”•u{{{{ƒŒ”•Œ—£Œ‹“…‹šŒŒšŒ”•…‹šŒ”•™š¤Œ—£»ÂÇ”››™š¤œ¤¦…‹‹Œ”•‹„‹™š¤¦§¨š””™š¤¦§¨™š¤›¢››”›‹„‹tzlŒ”•”›››¢›Œ”•u{{yl„MSSuzt{{t”“›“““Œ”•„Š„ƒ}ƒƒ}ƒ‹’Š„Š}”“›™š¤tts™š¤”“››¢›|„…‹„‹|‚z\[b›”›u{{{{t“Œ”Œ—£|„…[TT„„Šmtt\[[{{ƒUTSultŒ”•“Œ”™š¤|‚zlddllk{{ƒŒ”•llk‚|u‚v{Œ”•ttstt{ultztl‚v{“Œ”ƒ„„›”›”››ª³·¦§¨‹…’›¢›ƒ„„|„…\UZƒ}Šrfk’ŒŒ‹„„ldd’ŒŒŒ”•„Š„‹„‹ƒ||”››llkmttƒ}ƒ„„Šmttu{{ultttsŒŒš‰|v{{ƒ‹„‹zllSKJd\\lriu{{ek]„Š„|‚zsleztl[TTVZTllk¦§¨:97*)(u{{SKJJHFSKJ3+*SKJD;9F=Cf]crfkVTLƒƒ|{tt‹„‹“~ˆddcsrejcVlldlld”››edk[TTƒ„„mttƒ„„‹u…‹„‹lriƒ„„ek]lri”š”«²«ƒƒ|ƒ„„ztl‹„„{ttƒ}ƒƒƒ|u{{[TTd\\VTL{{tult››”‹„„Œ‹“u{{u{{ttsfkkUMRb[Ulld{tt\UZŠŠ}VTL’ŒŒ‚v{„Š„‹‹„ultƒ||redlks”š”‹’Ši\V[[T‹’Štyg‹’Šlddult‚|uƒ‚uƒ„„f]c|‚ztlltslVZ[„Š„tzl[[T{u{ult‹„‹“““‚|u¦§¨ƒƒ|tts””‹£œ¥£œ¥”››””‹”››{{t{u{VTLlri“Œ”{u{“Œ”…‹‹›”›ddc’ŒŒultkd\u{{Œ”•™š¤ŒŒš‹‹‹…‹š…‹šmtt{{ƒ|„…„„Š|„…ŒŒš{{ƒŒ”•™š¤œ§²…‹‹‹‹‹|„…¨©´™š¤™š¤Œ‹“{{tŠ}ƒ†~‘“Œ”‹‹‹|„…’ŒŒª³·š””œ¤¦œ¤¦‹‹‹‹’Š”››\[[tt{{||ƒ}Šƒƒ|Œ”•‹’ŠŒ”•Œ”•œ››™š¤‹‹‹‹„‹ddcƒ}Š›¢›}‡’™š¤Œ”•ƒ}ƒ„Š„‹’Š„„ŠUTSVTLb[UŒ”•lriuzttt{lri[TTultultult{{ƒ™š¤Œ”•tlllrilks|‚zlks“Œ”‚utf]c{{ƒultŠŠ}tts{||{ttŠ~‹ƒ||‚v{£››tzllkssreUTSddcnƒVZ[lksŒ‹“ƒ||lddƒ„„ƒ||ƒƒ|uztƒ„„›”›{{ƒ{u{Œ”•ƒ„„…„’”››ƒ„„ƒ}ƒ{||œ››‹’Š‹‹„‹‹‹sle[TT\[b]bZsletslVTLekdztl‹u…[TTu{{llk²««UMR*)(\[[rg]bVUVTLVTLkd\ttsƒƒ|rfkŠ~‹ƒ„„tzlƒƒ|ƒ||[TTtt{‹‹‹kd\VTL{{ƒ„Š„tsl‚|uƒ„„f]c[[T{{ƒ”“›ttsmttek]{{tuztlriVTLlek‹„„ttssle‹„‹„„Šttsuztkk]r]Z“Œ”¦§¨Š}|kd\f]cJHFddcfkkf]cUMR{u{lldult[TT””‹[TTrfk{{td\\‹‹‹ƒƒ|™‹†ult¨©´”š”lks‚|u“““|„…tlllldkd\{u{|‚z‚ut‹‹„‹…štslb[Uddctsluzt”š”‚|uƒ}Š‚v‚{{ƒš””tllœ››‹„„””‹tts“Œ”’ŒŒª³·››”{||‹„„tts‚ut‹’Šzllƒ}Š{{ƒldd{u{‹„‹‹‹‹ƒ}Šllk‚|u|„…Œ—£œ¤¦Œ”•™š¤}‡’{{ƒ{{ƒ}‡’|„…mtt…„’Œ”•}‡’™š¤ƒ„„”“›„„Š|„…Œ”•Œ”•Œ”•™š¤ddcŒ”•ttsŒ‹“ult¦§¨œ››‹…’‹‹‹|‚z””‹ƒƒ|”“›Œ”•£œ¥™š¤lkslks”››Œ”•‹’ŠŒ”•{{ƒ‹‹‹‹u…uzttll‹‹‹…„’Œ”•mtt\[b„„Šmttmtttt{ultlks‹’Š[TTuztVTLddcƒ„„fkk{tt†~‘™š¤„„Šlddyl„{{ƒttslri{{ƒ‹‹‹|„…œ¤¦ztlš””ult|‚zŠ}|£œ¥”š”{{t{u{{u{‹‹„Œ”•tts{||lriƒ„„tt{ddcu{{\UZ‹„‹tsl{ttŠŠ}ultƒ}ƒ¨©´ƒ}ƒ{ttŒ”•{{ƒtt{…‹‹llk{||ddcf]crfkƒ||’ŒŒ››”Š}|tslbVUf]c‚|u\UZ{zmƒƒ|tts[[Ttsld\\|„…{||¤¤MRK:97{ttdc\D;9SKJVTLVTLf]c\UZbVZ‚v{uzt{||slekd\ekdlkstzlŠƒ}uztlrifkkƒ„„ƒ||ttsƒ||\[[ekdtll\[[\[[mtt‰ƒv{ttVTLdc\rfklddtll‹„„{u{|„…ttsƒƒ|UTS{{t‚v{¤¤tllbVUVTL\[bttsult\[bllkŠ}ƒ{{ttllddc“““ƒƒ|UTS|‚zVTL|‚zultrfkult¦§¨„Š}¦§¨i\VŒ”•|„…{{ttt{‚utlriztllriu{{lddœ¤¦lj|„…‹„‹„Š„{||{ttƒ„„‹„‹{u{‹‹‹Šƒ}„Š}lddŠƒ}{{t‹…’ƒ}ƒƒ„„‚|uttskd\tts‹„‹Œ”•‹‹‹ƒ}ƒtts|‚z‹‹‹lks…‹‹{{ƒ|‚zƒƒ|edklri|„…„Š„…‹’|„……„’ŒŒš}‡’ŒŒš|„…Œ—£|„…”››œ¤¦”“›¬¶Ã¦§¨…‹š¦§¨œ§²œ§²›”›µ¶·¦§¨Œ”•œ¤¦“Œ”™š¤ƒ}Š£œ¥’ŒŒ›¢›”š”œ››“““lri“““ultttsd\\{||„„Š‹’Šœ¤¦¤¤f]c’ŒŒ|„…tt{¨©´ƒ}ƒœ¤¦Œ”•u{{Œ”•…‹’œ¤¦lks|„…mttlld[TTekd|„…”››ƒ||{{ƒ“““‹’Š“““{{tekd£›››”›„„Š‹‹„…‹šek]ddckd\ult›”›{u{ttsldd›”›¦§¨ƒƒ|“Œ”tlllek|‚zuzt|„…sre‹„‹{u{[TTtslultult{{tƒ|||‚z’ŒŒ“Œ”Œ”•ƒ}ƒ‹‹‹tt{lksmtt{{ƒ{{ƒ„„Šllk{{ƒtts‹‹„œ››””‹tsl{{tŠ}ƒrfkVTLtllVTL]bZ{||ƒ||tllf]c[[Tddcƒ„„MSS*)(tslb[U[[TaWMJHFSKJuztVTL[TTultddcdc\{zmlld„„ŠŒ”•cbVUTScbVŠ}|\UZ{ttultš””œ¤¦„Š}u{{tll|„…tts„Š„ztl{{tdc\tt{{tt{{tekd““““Œ”Œ‹“\[[srekd\ƒƒ|‰|v’ŒŒšŒ{u{r]g|‚zddc„„Šlks‹„‹‹„„lldyl„d\\tts„Š„tlltll[[T[[TŠ}|{ttlri|‚zVTLrfk‘Œ…tllŒ‹“sreldd{ttUTSkd\…‹‹UTS]bZ›¢›’ŒŒu{{‹„‹uzttlllld{{ƒsle\[[ƒƒ|„Š„‹’Šuzt””‹”š”‹‹‹f]c|„…ttsddclekœ››”››|„…‹„„{u{ttsttskd\edklldŒ‹“‹‹‹{||{{ƒ\[b|„……‹‹…‹’{{ƒtt{Œ—£Œ”•œ¤¦›²{{ƒŒ”•{{ƒŒ—£Œ—£™š¤lksœ§²…‹‹£œ¥›¢›Œ”•œ››ƒ„„Œ”•„Š„”“›Œ”•œ››ƒ}ƒ…‹‹Œ”•…‹‹¦§¨œ››™š¤“Œ”\UZ]cdldd|‚zŒ‹“ƒƒ|”š”tt{‹…’¦§¨ƒ||™š¤‹’Š›²¦§¨lriedk\UZ‹‹‹ttsttsmtt]bZlriƒƒ|u{{\[[›”›“Œ”|‚zkd\lddƒ‚u”š”ƒ||SKJtt{Œ”•u{{‹„‹“Œ”ult“““£œ¥ulttt{Œ”•ƒƒ|‹„„“““¦§¨¦§¨¤¤š””{|||„…ult]bZƒ}ƒUUY]cdldd{{ƒœ››{{t|‚z‹‹‹””‹‹…’”››„„Šlek…‹‹{{ƒ|„…lks|‚zuztulttt{ttsƒ}ƒ‚utƒ||dc\‚|urfk‚v{{||{tt|‚z]bZUTSsle[TTllkUTStt{£››LKRD;9lldkd\[TTVTLPF=VTLVTLf]cultf]cddc{{tdc\{u{kd\‹’Šlrilldtslkd\VZTred“Œ”{u{«²«uztu{{ƒƒ|lddŒ”•ldd{tt…‹‹]bZMSSlddkd\‹‹„ƒƒ|{u{…‹’lks|‚zdc\Šƒ}lddŠƒ}‹„‹Šƒ}lriUUY|‚z{{ƒ:97lksult|‚zultƒ„„››”{{td\\mtt{{tllk“Œ”rfk[[Tdc\Š}|‹„„Š}|‹‹‹{||ƒ„„‹‹„ƒ‚u{{tsle|„…|„…lek›¢›”š”””‹œ¤¦¦§¨ƒ||Œ”•ƒ}ƒtll{{t|‚z‚|u‹‹‹{{tlld|‚zuztlddŒ‹“„Š}‹‹„‹„„¨©´’ŒŒŒ”•‹‹„lks|„…]bZUTS{u{{||ttsƒ„„{||mtt\[b|„……‹’…‹‹|„……‹’Œ—£Œ—£™š¤¬¶Ã™š¤|„…~’“„†™|„…{u{{{ƒŒ—£”››¨©´|„…™š¤Œ”•™š¤¨©´|„…™š¤u{{‹…’’ŒŒekd|„…œ¤¦‹‹‹tllmttd\\lksŒ”•‹‹„£²rfk„Š„Œ”•ƒ„„‹„„“Œ”ƒ„„œ¤¦ƒ}ƒ…‹‹Œ”•{{ƒrfku{{llkekdldd‹‹‹¦§¨””‹ztltt{ekd„„Š{{tŠ}|tll|‚z|‚zmttrfkƒƒ||„…fkk{||ddcultult‹‹‹™š¤rfk™š¤{{ƒŠ}ƒƒ„„”š”””‹“Œ”„Š„Œ”•œ››‹’ŠŒ‹“ƒ„„”“›{{ƒƒ}Š[[T…‹’‹„„{u{ƒ‚u{||””‹edktzlult{tt|„…{{ƒtts{{ƒu{{|„…‹’Š“Œ”lldŠ}|{{tddc‚|uJHFJHFlddttsult‹‹„{{tlritsl[TTllkdc\ddc””‹FD;:97UTS]bZd\\VTLSKJrg]lriyle{{tekdlrilldkk]]bZ‹„„edktsl””‹uzt{||edkŠ}ƒ{u{ƒƒ|{tttslŒ”•ƒƒ|lld…‹‹‹‹‹{ttƒƒ|mtt{{t{||[[T››”tts‹‹‹\[[Œ”•|‚z£››‹’Š“““š”””››{{ƒœ››\[[”“›ekdUTSf]cUTS”š”|„…‚v‚[[Tlks{ttlks[[Tƒ}ŠSKJr]gSKJUMRkd\ŠŠ}b[Uultekdllk”š”aWMŠƒ}ƒ||›¢›…‹‹{{ƒŠƒ}¨©´œ¤¦¦§¨‹’Šœ››“Œ”{u{zll‹„„uztƒ}ƒ|‚zldd‹‹„tsl“““lddlekƒ||‹‹‹{ttuztƒ||uztƒ„„llktt{|‚z{{ƒ”“›ƒ„„…‹’{{t‹„‹mtt|„…œ§²”››œ§²Œ”•lks|„…œ§²™š¤··Äª³·…„’{{ƒŒ”•…‹’{{ƒ{{ƒ‰Š¡tts“Œ”{{ƒŠ~‹…‹’¦§¨Œ”•··Ä‹‹„\[[”“›tllf]cekd|„…››”|„…™š¤‹…’ƒ}Šu{{tt{{u{{{ƒtts{u{lritts“Œ”tt{mtt{{ƒmtt‹‹„™š¤lekrfk“““u{{\[[ƒƒ|ŒŒšztl‹’Šdc\lldkd\ƒƒ|lldu{{‹‹„d\\ƒ||“Œ”ult{{ƒŒ”•tllF=CŠ}ƒ‹…’’…‹‘}zŠ~‹ƒ}ƒ{tt‹‹‹‘Œ…ƒƒ|Šƒ}œ››„Š„{{ƒllk|‚zŒ‹“uzt{u{‹„‹œ¤¦‹‹„|„……‹‹‹„‹mtt…‹‹|„…”“›”››ƒ}Šllk{{ƒŒ‹“œ¤¦”››™š¤…‹’…‹‹ƒƒ|”››’ŒŒ“““rg]VTLFD;[TTUTSekdlddztlllkllkdc\[[TUMRztlUTS””‹:97:97sreb[UlddSKJsreD;9lddSKJldd{||lld‹‹„srezllf]cŒ”•sle‚utƒ‚uultlld{tt‹„„””‹ƒ||]bZlriƒ||tsl|„…Œ”•’ŒŒ‚ut‹’Š[[T[[T[[Ttsltsl™š¤Œ”•‹’Šœ››{{tlddƒ}ƒttsttsŠ~‹uzt|„…‹‹„MSS\[[[TT‹„‹]bZ[TTi\Vƒƒ|{u{{{tƒ„„ƒ||{ttsrej]\leklddcbV‹’Šrg]{{t{tttllƒ„„tyg‚|uttslldƒ„„mttdc\UTS‹‹‹›¢›²²¬‘Œ…£œ¥œ¤¦‹„‹‹’Š‹’Š””‹“““f]c‚ut|‚zƒ„„{tt‚|u„„Š“““{||{||ddcƒ„„ultedk{{ƒ|‚zlksŒŒš‹‹‹œ››|„…}‡’œ¤¦|„…™š¤|„…|„…Œ”•…„’œ§²^fs…„’·¶Ñ…‹’Œ‹“œ§²”“›„Š„ƒ„„{{ƒ{{ƒŒ”•”››{{ƒŒ”•›¢›™š¤£››¨©´ƒƒ|ultŠ}ƒ“Œ”™š¤tsllks…‹’”š”‹’ŠŒŒš„„Šu{{mttmttlksŒ”•Œ‹“ddc{||ƒ}ƒmttlks…‹’™š¤Œ”•‹‹‹lrimttŠ}|lritsl‹‹„lriƒƒ|‹„‹”“›Œ”•{{t›”›“““ƒ„„ƒ„„sre¦§¨{{tred„Š„lld]bZ\[bUMR{{ƒ{{ƒred‚v{“Œ”™š¤Šƒ}{u{‘Œ…ƒ||‹„‹uzt‹‹‹™š¤tsl|„…]bZŒ‹“ƒ||…‹‹tll¨©´‹’Š™š¤tt{‹’Šmtt‚v{uztƒ„„ƒ}ƒ›¢›lksƒ„„mttuztekd…‹‹llk‹‹„tlltzlek][[Tlldsletts„Š„‚v{ƒƒ|ddcekdtslztlultdc\,55ƒ||FD;74,{{tlrif]c{zmlriFD;\[[VTL{||‹„‹|‚zsle|‚zttsjV[tslrg]tslslej]\sleƒ||lekllk{{ttzl“““llddc\|„…{||“““ek]”››b[U{ttlri‰ƒvlri\[[¦§¨Œ”•ekd…‹‹uzt‚|u‹‹„tt{{{ƒƒ„„lri|„…kd\UTS\UZdc\[TTlldbVU{{t\[[„„ŠlldVZTultyle‹„„ƒ}ƒ„„ŠcbVkk]lri{zm‹„„zll[TTsreztlf]c]bZ|„…UTSlri„Š„]bZ‹„„‹‹„ztl{||«²«“Œ”““““““‹’Štslƒ||‹‹„d\\‹‹‹{ttmtt{u{””‹’…‹tt{‹‹‹œ››‹„‹ƒ}Š]cdtts{{ƒlksƒ||ƒ}ƒ{tt™š¤‰Š¡…‹‹Œ”•}‡’|„…}‡’Œ—£{{ƒ|„…Œ”•}‡’¨©´™š¤Œ—£›²‹‹‹‹„‹ƒ}Š…‹šÀ¶œ¤¦™š¤Œ‹“™š¤µ¶·{{ƒ›”›|‚zŒŒš“Œ”ult”š”mtttts“““uzt„Š„}‡’edk|‚zmttUTS\[b]bZŒ”•dc\tsl{{ƒnv‚]cdŒ—£“““…‹’‹„„d\\\[[|‚z“““‹‹„„„Š{u{tllj]\”“›|„…£››ldddc\|„…mtt|‚zƒ}ƒ‚v{£œ¥lks™š¤Š}ƒ‚v‚{{ƒ‚wltt{‹‹‹yl„“Œ”‚v{ŠŠ}‚utŠƒ}ƒ„„œ¤¦‹’Š„Š„™š¤Œ”•™š¤””‹llktll…„’ulttt{‹‹„…‹’“~ˆtzlŠƒ}™š¤„Š„|„…ƒ}Šnv‚œ§²„Š„“Œ”ddcmttlksd\\lrilddd\\ekd{tt{{t‹„„ddc{||Š}ƒ{tttzltts{zmj]\\UZUTSUTS””‹JHF74,lridkVSKJVTLJHFbVZVTLbVUtllŒ‹“u{{d\\srelksztlƒ„„kk]tslztlddclri{ttƒ||””‹‹‹‹”š”Œ‹“ztlfkk{||tzlƒ}ƒ]bZmtt{u{llk|‚z‹’ŠFD;MSSlriœ››lri]bZ{{ƒtll‹„‹”››lkslddllkƒ„„ddctll\[bultuzt\[bƒ}ƒtslŠƒ}‹’Šlks]bZ„„ŠUMRƒ„„ƒ||ƒ„„b[Uƒ„„ult£››rg]LKR{ttkk]UTSlddVTL[TTUMR‹„‹lriœ››œ››ƒ‚u{u{”“›lld‹„‹Œ”•„Š„‹’Š‘Œ…{||{tt‹„„ª³·š””™š¤ƒƒ|‘Œ…‹„„kd\tzl…‹‹ƒ„„…„’\[bek]tt{“Œ”Œ‹“{{ƒu{{™š¤|„…ŒŒšmttŒ—£…‹’¬¶Ã™š¤Œ—£Œ—£Œ”•…‹‹™š¤ƒ}ŠŒ—£”“›ª³·”››ƒ}ƒ™š¤™š¤™š¤Œ‹“Œ‹“ª³·“Œ”“Œ”{{ƒ|‚z£œ¥‹…’ulttt{tt{Œ”•ƒ„„‹„„UTSultlksu{{}‡’|„…lksekd]bZ]bZtslƒ}ƒ””‹|„…mk…Œ”•”“›”“›\[b\[[kk]|‚zultztl‘…„tlllri|‚zddcultttsek]]cdMRK‹‹‹ƒ}ŠUMR‚v{œ¤¦Œ”•‹‹‹Š~‹{{ƒ‹„‹ult””‹£²‚v{llk‹„„£œ¥š””œ››„„Š¦§¨‹‹‹¦§¨Œ”•Œ”•Œ”•|‚zmttmttf]c|„…ek]\[bultllktts£œ¥‹‹‹|„…{{ƒ…‹‹}‡’ƒ„„Œ”•{{ƒlksVZTJHF{ttultUTSu{{tlllld{{tedkŒ‹“ƒ||sletsl{||kk]SKJSKJaWM|„…š””ekd*)(kd\kk]bVUVTL:97D;9\UZbVU‹„„llk]bZtsl„Š}f]ckd\mttcbV‹„‹ldd\[[‹’Šztlztllldmtt’ŒŒŒ”•‹‹„cbVƒƒ|dc\„„Šb[Ulld‹‹„‹„„|„…]bZ]cdekdJHFu{{MRKVZ[llkkd\edk{||{{ƒŒ”•|„…„Š„lddldd{{ƒlks|‚zllk‘Œ…tslztl‚utUMRjcVƒ„„j]\lddbVZ{|||‚z‹‹„‹‹‹››”‚|uf]crfkrg]\[[ldddc\{||mtt”“›|‚z{{t‹„„[TT\[[\[btslttsƒƒ|ƒ||{||”š”lekƒƒ|‹„„™š¤red¦§¨‹„„lld£››mttu{{uzt{u{{{ƒlkstslƒ}Š{{ƒ”››u{{{{ƒfkkmttu{{|„…mttmtt}‡’†~‘œ§²Œ—£›²{||“Œ”†~‘†~‘‹’Š”››µ¶·{u{|„…nv‚{u{|„…“““{|||„…¨©´š””u{{²¬µ£œ¥›”›|„…Œ”•ttsult{u{mtt}|’mttfkkŒ”•|„…mtt|‚z|„…Œ”•“““ult”››œ¤¦mtt…‹‹„„ŠŒŒšleklldllk{||VTLŠƒ}UTS[TTlldVTL{||‚utJHFtllJHFtslkd\¦§¨lks¦§¨›¢›tslƒ‚uƒ}ŠJHFleksleŒ”•™š¤ƒ}ŠŒŒš“Œ”’…‹‹„‹‘Œ…“““”š”‹„‹Œ”•¨©´ttsuztŒ”•lri\[blksu{{tsl\[bƒ}ƒf]cƒ||Š~‹tt{{||˜Ž£|„…”“›tts{tt{||mtt|„…uztlldf]clri‹’Šlld{{tztl]cd\[[redVTL[[T|‚zrg]FD;[[Tdc\SKJ””‹:97*)(UTSVTLaWMVTLSKJJHFf]ckk]‹„‹‹„‹llkSKJlrikd\zllrfkd\\lrilriVTLƒ}Šyle‚|ubVUmtt{zmŒ”•{{tkd\tts{{t{ttƒƒ||‚zƒ||ldd‹’Š‹‹‹„Š„lrilksekdmtttzlultƒ||{{ƒlri‹„‹mtt›”›…‹’ƒ„„‹‹‹ƒ}ƒtt{|‚z„Š„redrg]››”lrifkk{{t„„Šlddsle‚|utsllriŒ”•Š}|ƒ„„Š}|D;9ƒ||…‹‹lldulttt{[[TŒ‹“lddttslrid\\b[UJHFd\\lldtt{ƒ„„“““ƒ„„ƒ„„”››{tt”“›uztkd\{{ƒf]ctsl”“›{{t{u{{ttult{{ƒmttƒ||{{ƒtt{]bZ]cd{{ƒmttmttŒ”•mtt{{ƒnv‚…‹’…„’œ§²™š¤™š¤™š¤mtt{{ƒŒ—£|„…”››¨©´lksƒ„„{{ƒ”“›“Œ”¨©´„„Š”“›œ¤¦ƒ}ƒlrif]c‹„‹{u{[TT¨©´edklekuzt…‹‹lks]bZlrimttmttmtt~’“‹’ŠŒ”•Œ‹“u{{„„Šmtt„„ŠŒŒš{{ƒ{u{„„Šƒƒ||‚z‹’Štllkk]lddb[Uƒ||”š”{{tultlekdc\MRKllkrfkf]c’ŒŒ‹’Š“““‹‹‹œ››’ŒŒf]cUMRtll{{ƒ”“›™š¤¦§¨„Š„ƒ||‹„„Œ”•‹„„‹‹„‘…„¨©´”“›ultuztŒ”•ƒ||””‹ƒ}ƒmtt‹’ŠlksVTL\[[u{{tslultttsult{{ƒ{{ƒedkƒ}ƒmttVZ[„„Štts‹‹‹™š¤{{ƒuzt\[[tlltsl\[btts[TTztlVZTkd\VTLb[UyleUTS[TTµ¶·JHF>ECSKJVTLJHF74,[TTrfkŠƒ}b[Uƒ}ƒf]cllklld{||UMR\[[VZTi\V]bZlriekdVTL””‹|‚ztll|‚z‹’Šfkk‹‹„tzl‹‹„‹’Š¦§¨””‹fkk[[Trg]ekd{{ƒ™š¤tll…‹’‹’Š¦§¨ƒ„„ƒ||{u{g\rUTSedkkd\u{{Œ”•Œ”•‹‹„mttŒ‹“‹’ŠmttSKJult|‚z{u{£››ddcd\\{u{lddsleldd|‚z]cdred|„…cbVd\\f]c”“›Œ”•š””„Š„|‚zmttd\\\[[ƒ„„‚utttsu{{uztuzt“Œ”‹‹„‹’Š¦§¨”š”Œ”•””‹Œ‹“ƒ„„Œ‹“ttsult|‚z{{t„„Šƒ||ƒƒ|lriƒ}ƒmtt|‚z“Œ”lkskd\{{ƒ‹„‹¨©´Œ”•Œ—£¬¶Ã…‹’|„…{{ƒœ§²Œ—£lks…„’„Š„™š¤¦§¨Œ”•|„…™š¤”“›ƒ}Š‹…’{{ƒœ§²™š¤”“›‹’Š{{ƒuztš””“““™š¤”“›£››tsl|„…Œ‹“llktt{„„Š|‚z[[Tmttu{{|„…Œ—£|„…Œ”•|„…‹‹„”“›…‹’Œ”•u{{lek|„…lkslrimttu{{lld‹„‹|‚z¨©´„Š}lrib[Uekdr]g\[[VTLf]cŠƒ}{||f]cmttult“““ƒƒ|{u{f]c™š¤Œ‹“ƒ||tyg{tt’…‹„Š}”š”lekrfk“Œ”’ŒŒœ››¦§¨{ttƒ}ƒ„„Š|‚zŒ”•„Š„¨©´“““|‚z„Š„”››{||llkllk{u{”“›tts{{ƒ{{ƒlksŒ”•ttstllŒ”•}‡’uzt{{ƒ’ŒŒ…‹‹\[[d\\ek]d\\edkllklddtsllri[[TVTLb[Uultlddu{{¦§¨UMR*)(aWMVTLd\\VTL[[TD;9[TTb[U{u{]bZ{{tttsztlSKJlld’ŒŒƒ||tsltsluztddc‚|u{zm‹‹‹ekdkd\ddc‹‹„\[[lldtts‹„„tygŒ”•b[UŠŠ}sle\[[|‚z”“›™š¤…‹‹¸Á¹lri››”Œ‹“|„…uzt]cdlri{{ƒ|‚z]bZf]c{{ƒlrimttŒ‹“b[Ud\\\[[ƒ||lldlld{{ƒlldtslsleekd|‚zldddc\tslj]\VTL‚v{u{{ƒ„„‘Œ……‹‹MRKVZTƒƒ|uztsreŠƒ}ƒ„„|‚z¦§¨‹’ŠŒ‹“‹„„¦§¨Œ”•ƒ„„|‚z””‹£œ¥{||ƒ||{{t‹„„tslƒƒ|œ››{{ƒ››”‹…’ultmttVZTtt{{{ƒ|„…™š¤ƒ}Š…‹‹}‡’™š¤Œ”•}‡’œ¤¦Œ—£‹…š}‡’†~‘|„…lri‹‹‹Œ—£¨©´‹‹‹œ§²|‚z“Œ”Œ”•ŒŒšƒ}Šƒ„„Œ‹“¤¤‹‹‹ª³·™š¤ultult|„…‹…’{{ƒ‹…’…‹‹‹„‹Œ”•lldu{{uzttsl}‡’|„…œ››™š¤œ¤¦nv‚Œ”•‹‹‹œ¤¦œ¤¦{{ƒ„„Šmtt{u{„Š„ttsekdƒ„„Šƒ}ldd„„Š“““””‹‹‹„ddckd\Œ”•uzt{{ƒSKJttsUMRdc\D;9{ttMRKsle{{ƒƒ}Š{{ƒtll{{tƒ}ƒ™š¤”š”lrid\\kd\ƒ„„{ttƒƒ|œ››…‹‹ƒ}Šƒ}ƒ‹„‹{{t“““¨©´™š¤{u{ª³·ƒ}Šƒƒ|u{{mttu{{tll…‹‹lks|„…ŒŒš{{ƒf]c{||{tt{{ƒ{{ƒlrilksƒ„„tsl{ttlld{{tmttultkd\rfk{{ƒ]bZkk]tllVTLUTS]bZ²²¬]bZ:97Šƒ}VTLtzli\VJHFi\VUMRVTL‹…’\[[\[[mttnƒ‰v|uzttll“Œ”Š}|bVU„Š„‹‹„¤¤ultlld]bZedk|„…sre{ttkd\bVUf]cŠƒ}œ¤¦”š”|‚z[TTtll‹„„œ¤¦‹’Š[[Tllkd\\ƒ||ƒ}ƒœ¤¦”š”u{{edk„Š„‹’ŠVTL\[b\[bVTLdc\{||ƒ||ztlttsred]bZek]cbV…‹’››”’ŒŒllk]cdedkd\\lld]bZkk]tslUTS[[Tedk{||lriddcu{{mttsrei\Vƒ„„„„ŠŒ‹“Œ‹“”››²²¬¦§¨{||uzt„„Š{||{{ƒ{{ƒ‹‹„‹’ŠŒ‹“UTSƒ||‹‹‹|„…|„…ttstt{tt{œ››…‹’ƒ}ƒtllŒ—£|„…u{{}‡’{{ƒ™š¤œ§²Œ—£Œ—£¨©´¬¶Ãœ§²…‹š‹„„mtt“Œ”Œ”•‹‹‹œ§²]cdœ¤¦‹…’|„…Š~‹‹‹‹{||™š¤„Š„™š¤µ¶·™š¤™š¤™š¤„„Šœ¤¦™š¤…‹š‹…’‹’Š”“›ŒŒšlriª³·]cdu{{]cd…‹š~’“|„…‹‹„„Š„u{{mttƒ}ƒ…„’mtt{u{“““cbV]cdf]cSKJtts‹’Š‹’Štllztlddcƒ„„ttsekdlrilksSKJ]cd|„…[TTlriddc[[T{u{lksyl„‹‹‹Œ”•Œ”•tts“““ƒ„„‹„„zll‹„‹“Œ”›¢›{||””‹|‚z™š¤¦§¨„Š„tslœ¤¦›¢›{{ƒ‹‹‹{{ƒ„Š„|„…‹„„ŒŒš{tt…‹‹}‡’“Œ”tt{ŒŒš‹‹‹›”›lri|„…]bZmtttt{tllƒ„„ddcuztbVU\[[…‹‹tsl|‚z‹‹‹srecbVyfdlddred[[T¦§¨JHF*)(kd\VTLek]VTLMRKD;9{{t[TTlddJHFVTL\[[tt{{u{{||zll‹‹„Šƒ}›”›”››ekd‹’Šƒƒ|“““””‹ttsƒ}ƒtsllekkd\VZT\[[{ttSKJ{{tzll’ŒŒ‚|u|‚ztsltlluzt{tt„Š}ƒ‚uƒ||Œ”•””‹Œ”•\[bcbVn…fkkbVZSKJz‚l„„Šttstllkd\Š}ƒVTL|‚zƒ„„lek[TTtsld\\]bZ‹’Š¨©´ult¤¤”“›[TT„„ŠUMRultrfklri]bZUMR|„…lriVZT{tt‹‹‹‹‹‹{{ƒ|‚z™š¤›¢›‘Œ…Œ‹“|‚ztsl’ŒŒult…‹‹ƒ||[[Tfkkuztƒ}Štts„Š„‹„„ƒ„„{||Œ‹“”š”Œ‹“’ŒŒ‹‹‹…‹’{{ƒmtt{{ƒŒ‹“nv‚Œ”•…‹’…‹šœ§²|„…›²{{ƒ“““™š¤¦§¨u{{f]cŒ—£‹‹‹{u{”“›…‹‹£œ¥‹„„ƒ}Š‹„‹™š¤uzt™š¤edkŒ”•™š¤œ¤¦¦§¨…„’œ¤¦µ¶·Œ”•’ŒŒ…‹‹]cd|‚zVZ[mtt]cdœ§²‹’ŠŒ”•ddcuztŒ”•fkklksŒ”•Œ”•lksUTSSKJtsl‹’Š{{t]cd{{tuztŒ‹“’…‹|‚z’ŒŒŒ‹“Œ”•ttsƒ||fkktt{lrif]cttsƒ„„[TT[[TVTL{u{ttsmttœ¤¦Œ”•”š”tzl{ttƒ||‹„„Šƒ}”››„Š„‹‹‹Œ”•‹‹‹¦§¨“““‹’Š™š¤„Š„‹‹‹‹„‹‹„„™š¤Œ”•‹„‹{u{{u{{||u{{{{ƒlkslksttsf]c]cdlks|„…\[b|„…ttstsl{ttƒƒ|tll{||uztlld|‚z[[TVTLJHFlld[[T]bZult²²¬UTS*)(dc\[[TJHFaWMD;9D;9jV[FD;JHF\[[b[Uf]cult‹‹„d\\lekƒ}ƒtt{ultiq][[TŠŠ}z‚lŒ”•ƒƒ|ek]‹‹„u{{ƒ}ƒ‚uttzlƒƒ|Šƒ}rg]j]\Š}ƒ‘…„zlllddek]mtt{{t‹‹„ttslri{u{œ¤¦ƒƒ|tll{{ƒƒ||lldMRKSKJF=C„Š„{{trfk””‹r]Z’ŒŒtllbVU]bZekdsle{tttllƒ‚uekdtlltll››”…‹‹‚v{ult{u{\[[ultfkk>B9tll|„…‹’ŠcbVekd””‹u{{‹„„ƒ||{{ƒœ››ƒƒ|„Š„™š¤ttszlllddmtttslttstt{ƒ„„œ››››”{{t…‹‹tts|„…{tt™š¤mttlriuzt|„…\[b}‡’…‹’…„’…„’Œ”•Œ”•}‡’Œ—£…‹šœ¤¦™š¤{{ƒ¦§¨Œ—£…‹‹ƒ„„Œ”•ª³·‹‹‹™š¤Œ”•Œ‹““Œ”™š¤™š¤”››”››“Œ”™š¤›”›™š¤†~‘™š¤u{{lks“Œ”…‹‹‹’Škd\f]c|‚z|„…mttVZTnv‚|„……‹’llkƒ„„u{{…‹‹Œ”•ult…‹šƒ}ƒf]c¤¤{|||‚zllk|‚z{{t]bZsleƒ||ƒ„„””‹”“›dc\ƒ||\[[{tt\[b[TTŠ}ƒtzl|„…VTLek]JHF{u{”››Œ”•Œ”•¨©´{{ƒ¦§¨ƒ„„š””{ttœ››‹’Šuzt‹‹‹tslŠ}ƒŠ~‹tll|„…ztl|„…]bZ{||„„Š|„…‹’ŠŒ”•u{{‹„‹{{ƒŒ”•…‹’ŒŒš…„’“““{ttu{{mtt]cd…‹‹{{ƒƒ||‹’Šb[Uekd{ttfkkZbN|‚z\UZekdSKJVTLldd[[Tdc\VTL¦§¨:97*)(slejcVD;93+*JHF74,JHF[TTultƒ}ƒ‚|ulldttsŒ”•ult“Œ”ƒ||ult[[TttsUTS[[Tek]””‹„Š„„Š„Œ‹“„„Š“““š””ddc{{ƒ…‹‹|‚z‚|uult‹„‹‹„‹ultƒ„„”››ultlks“Œ”uzt\UZlritslek]{u{tsllri]cd?;C{tt[[T‹’Šsle{tt‚|ulriJHFddcdc\ddcd\\tllƒ‚uVTL[TTttsd\\ultttsb[Uult[TTUMR[TT‹’Šlri{||ttsekdfkk›¢›Š}|ƒ}ƒ““““““ƒ}ƒtll›¢›llk··Ä“““„„Š“Œ”mtt”š”uzt¦§¨‹‹‹ztl{|||‚zƒ‚uŒ”•{{ƒ‹„„…‹‹tslœ››™š¤mtt{{ƒ|„……‹’Œ—£™š¤ª³·Œ”•}‡’|„…œ§²ª³·¡¡ƒ}ƒƒ}ƒ‹…’™š¤„„Š¬¶Ã£œ¥¦§¨ª³·œ¤¦œ§²›¢›™š¤Œ‹“œ§²|„…£œ¥‚v‚¦§¨™š¤™š¤lks…„’œ¤¦]cduztmttu{{{{ƒtts|„…Œ”•fkkmtt|„…Œ”•{{ƒ‹‹‹edk]bZlks}|’‹‹„ƒ}Šrfk{{t…‹’’ˆtsl‹’Š]bZ[[TUTSŠ~‹u{{‚|u„„Šekd[[Tdc\u{{VZ[lrilekuztuzttsllrilriultd\\|„…‹’Štt{”“›”››¦§¨Œ”•¦§¨mw””‹‹‹„tslVTL{{ƒ™š¤{||”››‹‹‹ƒ„„”“›ƒ}ƒtslllk„Š„“““”“›ƒ„„lriult™š¤{{ƒ‹„‹ƒ}ƒtt{ƒ„„lks]bZ{{ƒ{u{{||‹‹„f]cdc\SKJ„„Štslƒƒ|llk[TT[[TztlVTLsrett{d\\¤¤JHF*)(j]\cbVJHFSKJF=CF=C[[T[[TbVUƒ}ƒ{{tƒ||²««’ŒŒ{u{tlllekllktll{zmdc\kd\{{t{{tlri]bZ”“›‹‹‹™š¤ƒ„„“““‚wl””‹…‹’ƒ}ƒƒ||red|„…ƒ}Šsle‹’Š„„Š£œ¥…„’Œ”•œ¤¦”››SKJlektllŠ~‹‹’ŠŠƒ}\[bultleklritsld\\’ŒŒ{ttddc‚v{mttƒ„„“““tllb[U“Œ”d\\‹‹‹kd\b[UbVZdc\lddF=Cf]clekŒ”•mttf]cmttttsu{{…‹‹lri“Œ”Šƒ}ƒƒ|ƒ„„lldtsl…‹‹“Œ”„Š„Œ”•‹…š{u{²²¬fkkŒ‹“uzt››”ƒ„„‹’Š”š””š”f]cƒƒ|{ttlld”››„Š„…‹’{{ƒ|„…{{ƒ…‹šœ¤¦œ§²œ§²}‡’}‡’|„…Œ—£œ§²tt{™š¤{{t“““„Š„…‹‹¬¶Ãœ››‹‹„…„’£œ¥¨©´“Œ”lks„„Š…‹’lek£››™š¤Œ‹“Š~‹„„Šmttœ§²Œ”•“Œ”lddmttUTS”š”|„…mtt”“›|‚zœ¤¦Œ—£tt{{||…‹‹…‹‹{{ƒlks{{t‹…’tll‹‹‹“““¤¤kk]uztVZTddclekbVZtslkd\lksŒ”•VTL]bZtlluzt[TTtll‹’Š]bZekdu{{{{ƒ{{ƒ“““|‚zlri{{ƒ{u{lld››”{u{‚v{’ŒŒekd{{tzll„Š„ƒ||Š}|{{ƒœ››„Š„ttsŒ‹“}‡’f]cmttŒ”•f]clri{{ƒmtt]bZedk„†™ŒŒš‹…’mtt‹‹„tt{dc\]cdu{{tts‹’Š‹’Šllk{tt|‚zztl]cdlek[[T{{trg]VTL[[TSKJldd¦§¨\[[*)(sleJHFbVZJHFJHFVTLVTLkd\[TT’ŒŒ{{t„Š„ƒ||ttsrfk{{ƒ’…‹{{ttslllklri“““””‹llkttsu{{f]cŠŠ}ƒ}ƒ{{t””‹ek]lksfkkŠ}ƒƒ„„ttstzlƒ„„d\\uzt”“›]cdultttsœ››Œ”•d\\…‹‹UUYƒ|||‚zddcdc\UMRdc\mtt‹‹‹rg]lek““““Œ”lddlri{ttjcV¦§¨‹‹„[TTj]\ek][TT{ttƒ}Š|„…llk{tt‚v{ƒ}Š|‚ztt{\[[]cd\[[…‹’™š¤„„Šƒ||”“›{||Œ‹“{||tsl|‚ztt{{||ekd“Œ”ƒ}ƒœ››|‚z”››sle”“›“““ƒ„„„Š„›¢›|„…ekd]bZ|‚zƒ„„dc\…‹‹…‹š…‹’„†™™š¤œ¤¦™š¤Œ—£…‹šŒ—£Œ—£}|’|„…Œ”•{{ƒœ››{{ƒ{||‹‹‹{{ƒƒ„„œ››Œ”•Œ”•Œ”•™š¤œ§²œ¤¦|„…™š¤‹…š‹„„ultŒŒš··ÄŒ—£™š¤œ¤¦œ¤¦lks]cdlksmttlri\[b…‹šmttŒ”•mttƒ„„ult…‹‹œ§²{{t{{ƒ{{tƒ}ƒ‹„‹“Œ”tts{{t]bZ[[T|‚zuzt“Œ”“Œ”llk””‹f]c{{ƒ]bZek]tsl\[[JHFmttmtt”››|„…{||ddcztl[[T\[[’ŒŒ™š¤”“›Œ‹“¦§¨ƒ}ƒlld’ŒŒ„Š„¦§¨{{tlld‘…„›”›”››uztŠŠ}lkslld\[[tsl}‡’uzt|„…{{ƒlks{||VZ[{{ƒƒ||lekŒ‹“lddlri{{ƒ[[T{{ƒƒ„„tsl…‹‹{{t]bZƒƒ|{u{‹‹‹{zmedkddc[[Tdc\VTLztl\UZldd¦§¨LKR*)(ztf{{t{ttUMRVTLj]\|‚zrg]‚v{f]ckd\tts{u{fkk‚v{„„Štt{slekd\dc\ttsuzt””‹lks”š”{u{tt{’…‹‹‹‹‹„‹{||’ŒŒ”š”Œ”•{ttƒ„„\UZ‚|uf]ckk]{{t””‹{{ƒ\[buztœ¤¦”š”tslmttlkstsl‹’Š{||SKJ\[[[TT|„…[[Tdc\’ŒŒtllkd\lkskd\‚uttzl‚|u{zm¦§¨tsld\\š””kk]lld{{ƒultf]cƒ||ult]cdlkslks{||lek›¢›‘Œ……‹’ƒ}Šœ¤¦ƒ‚u··Ä‹‹‹¦§¨ekd‘…„{||ult£œ¥’ŒŒ””‹Œ”•‹‹‹””‹{{ƒƒ„„”››„„Š“Œ”|‚ztts‹‹‹™š¤{||{||Œ”•{tt„„Šlksœ¤¦}|’„„Š…‹’|„…Œ”•}|’…‹šŒ—£{{ƒ‹’ŠŒ”•™š¤ŒŒš|„…£œ¥{u{\[b“““·¶Ñ£œ¥¨©´Œ”•¦§¨ªÁÅ™š¤¨©´{||‹…’¨©´œ¤¦œ§²Œ—£œ¤¦Œ”•u{{|„…mtt\[[tts}‡’|„…mtt]cdfkkddcŒ”•ƒ„„|„…‹‹„ultlri‚v‚{||d\\[TT”š”kd\kd\fkksre\UZJHFmtttts{{ƒ„„ŠVTLb[U‚utmtt\[b\[b|„…{||u{{ƒƒ|[[Tlldƒ}ƒ}‡’{{ƒŒ‹“”“›‹„‹‚|u{ttœ››{u{|„…‹‹„{tt’ŒŒœ››{ttmtt“Œ”ƒ‚u”š”ŒŒšnv‚mttmtttsl‚v‚Œ”•ultmtttt{…‹‹”“›‹„‹ƒ||uztu{{ultmttUUYult{{t{||œ››]bZsle\[[UTS[[Tllkdc\VTLVTLVTLd\\jV[SKJ¦§¨\[b74,red]bZlddekd[TTSKJ]bZSKJf]cb[Utslddcztl{{ƒrfk‚v‚ult‹’Šdc\kk]{{tkk]dc\ult„Š„{{t‚|ud\\ƒ}Š[TTtzllri[[Tekdtsl¦§¨tll„„Štts|‚z|‚zŒ”•fkkƒ}ƒu{{{||uzt]cdJHFlksdc\[[TtllSKJ“Œ”tsl|‚zmtt‘Œ…tll‹„‹VTLsretllƒƒ|{zmf]cllk{{t{ttUTS‹„„ztl{ttllkf]ctllf]cSKJJHFult„„Šu{{JHFtt{„Š}”››Œ‹“œ¤¦{tt{u{’…‹›”›mtt‚v‚ª³·dc\lek„Š„””‹lldkk]{||edk{{t|„…„Š„™š¤|„…ª³·ult{{ƒmtttts|‚ztt{uzt{{ƒª³·™š¤Œ”•mk…{{ƒ{{ƒ™š¤™š¤ƒ}Šœ¤¦lekƒ„„d\\‹’Š|„…ƒ}ƒ‹„„f]clksª³·‹…’‹„‹|‚zŒ”•”“›»ÂÇ|‚z{{t“Œ”„„Šœ››Œ”•¨©´ª³·œ¤¦Œ”•fkkVZ[„„Š|„…{{ƒ^fs]cdmtt\[b”“›Œ”•”š”ultœ¤¦{{ƒ™š¤f]cƒ||tsl‹’Šddc’…‹JHF|„…ƒ‚u‚utf]cult\[[lkstt{{ttult‹‹‹™š¤Œ—£nv‚\[[]bZekd]bZJHFddcult‹„‹™š¤…‹’…‹‹¨©´„Š„“Œ”‹„‹kk]|„…{||tllƒ||tslult\[[Œ‹“ƒƒ|SKJf]cŒ—£|„…Œ”•{||tslŒ”•”š”…‹‹mttlks{{ƒ“Œ”“““mtttslult”š”yl„\UZtsluztultuztƒ||ddcd\\kd\UTStslVTL[TTlld]bZrg]d\\œ¤¦LKR*)(bVUVTL74,JHFJHFf]clldUMR{tt|‚zƒƒ|uztb[Uƒ}Š“Œ”‹„‹{u{ztl{{tkk]b[U„Š„[[T{{tdc\‚v{Œ”•‚ut{{ƒ{tt{{tlricbV|‚zlekƒ||tts{tttslultƒ„„…‹‹{u{{u{tts|‚zmttUTS\[bUMRd\\ekdVTL[[TbVZult‹‹„{{ƒsrered[TTbVUf]cSKJ‘Œ…””‹sletsl{zm¦§¨u{{ƒ}ƒ[TTSKJƒ||bVZlddllk{u{SKJf]clkstt{MSS“““‹‹‹‹‹‹{u{„„Šƒƒ|”“›™š¤‚|u‹’Šddc”››lksƒ„„‹…’¦§¨tslult{{t£œ¥‹’Š“““…‹‹›¢›Œ‹“{||{{ƒ{{ƒ\[btt{Œ”•{{ƒ‹„‹™š¤™š¤™š¤Œ‹“mtt}‡’}‡’lksmk…†~‘tts„„Š{{tƒ}ƒttsu{{“Œ”‹…’™š¤œ¤¦|„…tsl‹„„]cdu{{œ¤¦…‹’{tt‹‹‹lks‹„‹™š¤…‹‹œ§²Œ”•‹…šœ¤¦]cdUTSƒ}Šnv‚mttVZ[\[b\[b|„…ƒ}ƒ\[[|„…ƒ}ŠŒ”•|„…‹…’{{ƒ{u{””‹MRK{{ƒ™š¤f]cllkkd\{{ƒlksŒ‹“ƒ„„lksmtt|‚z…‹’‹…’^fs\[[mttu{{{{t|‚zVTLtsltslVTLfkk…‹‹{{ƒœ››‹…’›”›ult‹‹„ƒ‚u¤¤‹’Š“Œ”„„Š‹„„j]\…‹‹u{{ƒƒ|Œ”•f]cultLKRƒ„„…‹‹ƒ}ƒlddttsŒ”•ƒ}ŠŒ‹“…‹’™š¤…‹‹lekuzt{u{|„…lksmttlri|„…lriuztlekultd\\dc\UMRek]sle[TT]bZSKJ\[b[TT¦§¨MSS-1+VTL[TTPF=UTSddc\[[lld‚utred|‚z|‚zƒ„„ƒ||u{{{ttbVZlek{zmj]\VTLmttdc\tzl|„…‹‹„{||lekƒ}ƒ‹…’{{t’ŒŒ{{t\[[Šƒ}UMRƒ}ƒtt{|‚z{{ƒfkkš””ƒ„„™š¤‹…’{{ƒ™š¤|‚z“““ŒŒš‚wlVTLtsl[TTlks„vŒSKJ|‚z„„Šddc{||ƒ}ƒlddj]\tts‰|vJHF[TT‹‹„‚|urfk{{tult’ŒŒsleƒ„„ttstll{tt…„’MSSf]cult„„Š\[bldd{ttŒ‹“ultf]clekœ¤¦Œ‹“‹’Š|‚z™š¤”››‹…’{||Œ‹“‹‹„„Š„ƒ||™š¤ƒ}ƒŒ”•…‹‹lld|„……„’uzt{||mttedk|‚zœ§²™š¤œ¤¦™š¤™š¤¦§¨¦§¨›²‰Š¡|„…‰Š¡{{ƒmttŒ”•‹„„uztŒ”•“““›”›œ››£œ¥Œ—£‹‹„llk‹‹„”š”ult|„…™š¤œ¤¦|‚zf]cf]c{{ƒ™š¤}‡’¨©´”››ŒŒšmtt]cd\[[ldd|„…Œ”•mtt{{ƒVZ[lks{{ƒlksmtt{{ƒlek\[blks{u{Œ‹“{ttSKJ{u{tll{u{VZ[‹‹„tt{llkddclddrfk|„…ƒ„„{{ƒtt{edk|„……‹šmtt‹‹‹]cd]cdlld{||{ttultŒ”•„„Š„Š„{{ƒ]cd{{t{tt¤¤ƒ„„‹‹„œ››u{{u{{‹„‹Œ‹“|‚z[TTtt{{{ƒ|„…u{{‹‹‹ekd{{t{||tllfkk{u{VZT|„…‹…š{||ddc|„…ult…‹‹ldd{tt|‚zekdddcUMRztlfkk‘Œ…‹„„SKJVTLdc\D;9JHFlldVTLldd¦§¨JHF,55sled\\:97JHFredbVUlri{u{tllUTSVTLlriultf]cult‹„‹ult‹‹„“Œ”]bZ{{ƒ„Š„tsl]bZ„Š„‚|uf]clekultdc\””‹llk…‹‹VTLVZTlek{{ƒ¦§¨›”›UTSd\\…‹‹{||tt{ƒ}Š™š¤”š”‹„„Œ”•ult‘Œ…‹‹„{{tJHFƒ„„f]c„Š„ult{tt›”›sleztl‹„„rfk£››redrr]slettsšŒ›¢›“Œ”™š¤{||‘Œ…{{ƒrfk{zm\UZJHFddc{{ƒ\UZLKRŠ}ƒƒ„„£œ¥‹„‹{u{ldd’…‹Œ”•‹’Š|‚zmtt‹‹‹ƒ||™š¤lks”››‹‹‹‚ut‚|u‹„„{||{ttŒ”•‹’ŠŒ”•“““[[Tmk…uzt“Œ”lks{{ƒ…‹šœ§²··ÄŒ—£¨©´™š¤™š¤™š¤}‡’†~‘mtt‹„‹{{t{{tŒ”•{{ƒ“““¨©´¨©´™š¤µ¶·ƒ}Šš””™š¤]cd{||Œ”•{{ƒ„„Šult{{ƒ‹…’Œ”•…‹‹{{ƒttstt{{||]cd…‹‹tts]cd|‚zŒ”•n…mttlkslks™š¤”››ŒŒšultu{{ƒ}ƒƒ}ŠŠ}ƒ‹‹„‹„‹uztg\rŒ”•Œ”•š””ƒ}ƒ”“›edkƒ||f]c|„…{{ƒ|„…lks\[blksŒ—£nv‚›¢›|‚z{{ƒ“Œ”‹„‹Š}|tll…‹’“Œ””“›”“›…„’tsl‘…„tslult…‹‹œ¤¦’ŒŒtt{ƒ}ŠŒ”•mtt„Š„…‹’“~ˆ™š¤mttfkk‹„‹ƒ}ƒ‹…’ttsfkkttsu{{{{ƒ{{ƒ\[[mttmttUMRllkƒ}ŠmttuztUTSfkkUTSSKJ|‚ztsl[TTSKJ[[Trg]aWMlrilddcbVult¦§¨LKR,55‚wl[TT\UZddcJHFtll[[Tultllk]bZtzl{ttult[TT”“›tsl„„Š‹’Šƒ||SKJmttŒ”•|‚zttsek]Œ”•lddœ››llkd\\{||d\\mttJHFVZTbVZlks’…‹mtt|„…„Š}Œ‹“„„Šƒ}Š{{ƒ‹’Šu{{lks™š¤{ttsle[[TUMR?;Cf]cSKJ„Š}lekttstt{„„Šf]cƒƒ|UMRkk]ztlŠ}|VTLuzt…„’”š”f]cƒ||VTL‹„„…‹‹lddldd[[Tekdd\\mttlks\[b{|||„…lksldd{{ƒ‹„‹ttsŠ}ƒ|‚zu{{{{ƒ‹’Š‹„‹ƒ||…‹‹››”|„…ƒƒ|ƒ}ƒtll‹‹„Šƒ}Œ”•‹’Šƒ||„Š„tll{{ƒ‹„‹”“›{{ƒœ¤¦…‹‹Œ‹“…„’œ§²¨©´Œ—£·¶Ñ™š¤…„’‰Š¡„†™u{{b[Ulld{{ƒƒ||£››£œ¥”››‹„‹¦§¨ultŠ~‹¦§¨|‚z|„…™š¤¦§¨œ¤¦ƒ„„¨©´£²mtt™š¤lks”“›lddŒ”•mttœ¤¦“““Œ—£|„…{{ƒnv‚œ¤¦]cd|„…\[b|‚zlek\UZlks‹„‹ŒŒšlek‹’Šƒ„„’‘~ƒ}ƒƒ„„…‹‹Š}ƒlks„„Š„„ŠŠ}ƒ…„’lks{||{{ƒLKR…‹š{{ƒ\[b~’“|„…Œ”•mtt„„Šd\\…‹‹£œ¥Œ”•”“›”š”‹…’Œ”•lriŠŠ}‹‹„”“›’ŒŒ¦§¨š””{{t‹…’|„…|„…lks{u{™š¤œ¤¦Œ—£|„…tllf]cfkk“Œ”lriu{{ultu{{{{ƒƒ|||„…mttlksŒ‹“lks…‹’ƒ„„…‹‹lks]cddc\\[[dc\[TTultddcsre{ttlrikd\ztlVTL¦§¨MSS:97tzlŠŠ}ultSKJVTLVZTVTL[TT[[Tf]c‚utllkŒ‹“dc\lekb[Uttsƒ}ƒtt{ƒ|||„…mtt|‚zuztlldƒƒ|f]clksult‹„„ultœ››œ¤¦|‚zddc“Œ”Œ”•{ttJHFtsl‚|u|„…u{{ƒ„„|„…ttstt{…‹’ƒ}ƒtlld\\iq]lriUMR|„…d\\llktlllri\UZ[TTsleŠƒ}\[[ultŠƒ}’ŒŒztl¦§¨‹„„”š”\[[ƒ||]cdJHF[TTVZTVTL\[[ekdSKJ^fsmttSKJdc\ldd„„Š“Œ”„„Š™š¤ult‹‹‹“Œ””š”ƒ}ƒƒƒ|ƒ}ƒ„„Šƒ„„{||’ŒŒ…‹‹uztllklldtll›¢›{||{{tzlltts\[bƒ}ƒult˜Ž£u{{Œ”•ulttt{™š¤„†™„„Š‹…š…‹’ŒŒš™š¤Œ—£“Œ”lek{u{›”›ƒ}ƒ“Œ”{u{µ¶·›¢›‹„„“Œ”™š¤¨©´ª³·œ§²›¢›|„…œ¤¦‚v{£œ¥ƒ}ƒŒ—£Œ”•…„’…‹‹”“›|„…œ¤¦lri¨©´{{ƒ|„…Œ—£œ¤¦}‡’mttlektt{‹’Š‚v‚”››ŒŒš„„Š„„Š[TT„Š„{{t‹‹‹{{t{{t„Š„ztl]bZ‹…’{{ƒƒ||ŒŒštts{||JHFVZ[lksn…MSSmttmtt{||fkk\[[™š¤œ¤¦Œ‹“‹‹‹›”›|„…“Œ”‹’Šlddƒ„„‹‹‹‹…’Œ”•””‹“““Š}|‹„‹nv‚ultdc\™š¤tt{edkUUY{||ƒ„„ŒŒš{{ƒmtt]cd\[b^fs‹’Š…„’mttmttmttf]cmtttsl„Š„ekduztUTSƒƒ|‚utleklrid\\f]ccbVlddSKJlldUMRr]ZVTLµ¶·OS`)+2‹’Šƒƒ|llkFD;[[TSKJFD;SKJVZTUMRJHFJHFtsllldredSKJ{||‹„‹UTS\[b¨©´ekd›¢›|‚z|„…tts{||ƒ„„mtt‹…’{||lri™š¤œ››]cd‚v‚uzt‹’Šztl[TTztltts™š¤\[btsl{{ƒ…‹‹{u{UTS‹‹„ƒ„„|„…]bZ{{ƒJHFddcultŠ}|\[[d\\srelri{ttŠ}|rfksrebVZdc\edksleddcu{{\[[ekdf]c\UZ|„…d\\|‚z[[T\[[\[b™š¤d\\{{td\\£œ¥‹„‹¨©´Œ”•¦§¨ƒ||lritts‹„‹…‹‹ƒ}ƒ‹‹‹ƒ„„{tt¦§¨œ¤¦ƒ||ƒƒ||„…””‹›¢›‹‹‹…‹’’ŒŒttsUUY{{ƒŒŒš™š¤œ¤¦Œ”•}‡’ŒŒš¬¶Ã†~‘„„ŠŒ—£œ››¨©´…„’Œ—£uzt¦§¨…‹’›”›tt{†~‘‹„‹{tt{||‹„‹™š¤™š¤{tt…‹‹}‡’Œ”•ƒ„„’ŒŒ“““‹…’™š¤˜Ž£Œ”•lksœ¤¦Œ”•…‹‹]cdlriddcult|„…uztŒ”•|„…¬¶ÃŒ‹“™š¤ƒ„„“““‹„‹ddcultult[TTtllekdiq]]bZ„Š„ekdkd\{{ƒ\[[ekdf]c™š¤ƒ„„{u{lksmtttt{|„…|„…n…Ž¡›ek]|„…„Š„lksuzt“Œ””››“Œ”mtt{{ƒlks{{ƒš””œ››†~‘‘Œ…“““‹‹„“““tllŒ”•„„Š’ŒŒƒ}Š|„…{{ƒlksŒ”•ddc{u{{{tult|„…mtt|„…{{ƒlksfkk\[b]cd\[b]cdfkkddcuzt]cdlri|‚z{||[TTb[Ukd\sleb[UyleyfdllkJHFaWMlriœ¤¦OS`*)(ttsƒ}ƒ{ttd\\sre{{tb[UVTL74,JHFFD;UTSVZTkd\redjV[{u{ekdmtt{{tult{{t‹’Š|‚zu{{lkslri\UZuztƒ}ƒ[TTƒ„„Œ‹“lri]cdddc{||UTStt{„„Š›¢›|„…tts{u{|„…››”uztultUTSlddztl|‚zek]{{ƒ:97f]c\[[{ttlld”“›{u{|‚z“Œ”{ttƒ„„rfk{tt‹„„sref]cUMR[[TlriJHFƒ||\[b{{ƒƒ„„™š¤Œ”•ult]bZultƒ}ƒƒ||mtt’ŒŒ„„ŠŒŒšekdtt{£œ¥”“›ª³·“Œ”„Š„{||{||œ¤¦‹„„ŠŠ}{{tª³·‹„‹”š”ƒ}ƒu{{„„Š|„…’ŒŒ{{ƒultmk…ƒ}Šœ§²œ¤¦~’“œ¤¦ult›²œ¤¦Œ—£Œ—£…‹šŒ—£„„Š|„…“Œ”tllœ¤¦œ››ŒŒš}‡’š””µ¶·“Œ”“““›”›‹…’›”›œ¤¦|„…«²«Œ—£Œ‹“¦§¨™š¤lks™š¤™š¤Œ—£Œ”•…‹’¨©´¡¡…‹‹“““{ttŸ±¯VZ[{{ƒ]cdmttUUY…‹‹„Š„ult”“›yl„Œ‹“f]cf]c‚wlddcJHF[[Tƒƒ|edk’ŒŒ„Š„ulttt{š””edkmttŠƒ}]cdMRK{{ƒ|„…OS`lriŒ”•]bZLKR{{ƒlksuztyl„™š¤“Œ”“Œ”™š¤…‹‹…‹‹‘Œ…‹‹‹ƒ}ƒ‹’Šš””››”‹„„Œ‹“…‹’edkttslekmttfkkƒ„„Œ‹“{||…‹’|„…ƒ„„\[[f]c\[b]cd{{ƒlks|„…Œ”•}‡’‹„„…‹‹ƒƒ||„…lksVZT…‹‹‹’Šf]ckd\b[Uf]c[[Trg]red{{tekd]bZtsl¨©´JHF,55mttlldbVUFD;b[Uz‚lekd[[Tekdlri›¢›SKJlld„Š„ƒ}ƒ{u{{u{d\\UTS…„’lks|‚zlrimttu{{mttllk\[[llk\[[ldd{tt{||lri{{ƒ„„Šulttsl{{ƒmttƒƒ|{||ƒ}ƒƒ}ƒult„„Š{{ƒttsdc\{{t{{t„Š„[[TlksJHFJHFd\\„„Š|‚z{{ƒ‚|uŒ‹“tsl[TTrfkVTLrfkdc\FD;sleekd[TTkk]|„…lldƒ}ƒ{u{JHF{{ƒ\[[UUY]bZ{u{SKJllk„Š„zlllek{||„„Š‹‹‹ƒƒ||„……‹‹…„’‹’Šƒ}ƒ‹„„Œ”•lld›”›‹‹„“Œ”lriŠƒ}ldd|‚z{{ƒŒ”•llk“Œ”lks‹’Šlekmtt“Œ”œ¤¦Œ‹“{{ƒ|„…Œ—£Œ”•œ§²‰Š¡™š¤{{ƒ™š¤
\ No newline at end of file diff --git a/libs/ode-0.16.1/drawstuff/textures/sky.ppm b/libs/ode-0.16.1/drawstuff/textures/sky.ppm new file mode 100644 index 0000000..8b541b1 --- /dev/null +++ b/libs/ode-0.16.1/drawstuff/textures/sky.ppm @@ -0,0 +1,5 @@ +P6 +# Created by Paint Shop Pro +128 128 +255 +¾çýÃéþËîÿÎïÿÆéÿÂçÿºçÿ·åÿ²àÿ°Ýþµàÿ¹åþÃëÿÍðÿÏðÿÐíûÑîüÏïþÇìÿ½æü´àù´âü¹åÿºæÿ¹åÿµâÿ±Þý«Ùú¦×ø§ÙüªÜÿ¶âýÉîÿÐñÿÚõüâúþëýýíýüïÿþìþÿìþÿãüÿÛøÿÊíÿÄéÿÛÿ£Ôü£Øÿ¤Úþ§Üü±ãþ°ãÿ¤Ûÿ ÕýŸÔþ ÕÿŸÔþŸÕÿ›ÔÿšÕÿ™×þ˜×ÿ”Ñý™ÒÿšÓþ›Õý¡Ùþ¥ÚüÞü°ßù»åû½èû½æü»çÿ¸åÿ®Þÿ§ÛÿÓÿšÓÿ•Ðü•Ðü—Òþ“Òþ‘Ðû›Óø§Ùú¾èÿÄêÿÌðÿÆîÿºæÿ¦×ø Öú“Óÿ‹Íý„Çü€Äÿ}Ãÿ}Ãÿ~ÄÿÆþ€ÇýƒÉýƒÈÿÆÿƒÈÿÆÿ€ÄÿÅÿÅÿÆÿ€Åþ~Äÿ}ÄÿÆÿ…ÈÿŒËÿÌÿ„Çü…ÊÿˆÍÿ‹ÌÿŽÍÿ‘ÐÿÎÿ™Ôÿ ×þ±âÿ´áþ¸äÿÂêÿÃèÿ»ãý·àü®Üý©Ùý¥Ö÷©Ö÷¯ÛøÂëÿÊðÿÇëÿÆéýËîÿÉîÿÌðÿÆïÿ¿éÿºæÿ»çÿ¼èÿ»çÿ¹åÿµäÿ²àÿ¨Ùú£Õø Ôù¢Öý²ßüÄêÿËðÿØöÿÞùÿéþÿêþýìþþíÿÿêþÿ×õÿÎðü½ãö·áù®Ûú¬Ùú³àÿ½çÿÂëÿÐôÿÏôÿ¼éÿ³àÿÛü®Üþ¨Úÿ£ØÿŸÕÿ‘ÎúŽÍùÏû‘Îû•Ïý–Ñý˜Óý×ý ØýªÜý¬Ýû¸æÿ»çÿ¶âý²áÿ¬Ýþ ÔûÒü˜Ðÿ•ÏýÍú‘Îû”Ñþ‘Ñÿ‘Ñý˜Òø Ôù·äÿÀéÿÇïÿÀìÿ¸æÿ¥ÙþŸÖý‘ÑÿŠÌþ…Èÿ}Áþy¿ý{Àÿ}Ãÿ€ÆÿÈÿÆý‚ÉÿÇÿ}ÃÿzÀüÅÿÅÿÅÿ~Äÿ|ÂýzÀûzÂýÆÿ…ÈÿŠÉþŠÉþ…Æþ†ÉÿŒÏÿÎÿÍþÍþÍþ”Ïû˜Òú¨Ýÿ°Þÿ²àÿ·ãÿ¸áý±Ýú®Ûú¤Öù Òõ¤Ö÷Ûü³ßüÃéÿÆìÿ¼âùºà÷ÃéÿÅíÿÈðÿÃíÿ¼æÿºäý½çÿ½çÿ¼æÿ·ãþ³âÿ®ßÿ¨Úý¢ÖûŸÕûŸÔü±ÞýÀèÿÇíÿÔôÿÛøÿåýÿèþüìÿÿíÿÿëÿþ×øÿÍóÿ¾ä÷¹ãùµáüµáüÁëÿÍòÿÒóÿÚ÷ýØöÿÆïÿÁéÿ¸âû³ßü®Üþ¥Ùÿ ×ÿ‘ÎûËúŽÎþÎý”Ñÿ•Òÿ–Óÿ›ÖÿœÖü¥Ûÿ¨Ýý³äÿ·æÿ³âÿªÛü¦ØûŸÔü˜Ñü•Ïý’ÏþŽÌû‘Ïþ”Òÿ‘Ñÿ’Òÿ˜ÒúÓù²àÿºçÿ½éÿ¸æÿ³ãÿ¥Ùÿ ×ÿŽÎþ‰Ëý…Èÿ~ÂÿzÀþz¿ÿ|ÂÿÅÿÆþ€Åþ€Çÿ~Äÿ{Áÿy¿ý~Äÿ~Äÿ~Äÿ~Äÿ|Âý{ÁüxÀûÆÿ…Èÿ‰ÈýŠÉþŠËÿŠÍÿŒÏÿÎÿÌûÍü‘Îý“Îú—Ðû¤Úÿ£Øÿ¥Úÿ®àÿ±ßÿªÚÿ¥ÙþšÑø—Îõ¢Öû´âÿ»çÿÉíÿÈîÿ¹áû³Üø³àý·äÿºçÿ·ãÿ²Þû¹ãü»ãý¼æÿ½çÿ¶ãÿ®ßÿªÜÿ¡×ýÔûšÔü›Õý«Ýÿ¸åÿÀêÿÍòÿÓõÿÚ÷ýßûþéÿÿçÿýéÿýáÿÿØúÿÉíûÆëûÉîÿÊïÿÔõÿÚ÷ÿÙõùàõöß÷÷Úöÿ×õÿÏðÿÉìÿ¹âþªÜÿ¡Öÿ’ÐÿÎÿ‹ÌÿŽÍÿÏÿÏÿÐþ”Óÿ‘Ðû›ÖþžØþ¨Þÿªßÿ¥Ùþ¡×ýŸÖý˜Óÿ“ÐýÍþŽÍÿŽÍÿÎÿÎÿÏÿÏÿ’Ïü–Ïú£×þ¨Úÿ¨Øü¤Øý¥ÙÿžÕþ—Òþ‹Êý†ÈüƒÅÿÃÿ|Âÿy¾ÿz¿ÿ}Ãÿ~Äÿ‚ÇÿÇÿx¿ýv½ýu¼üw¾þzÁÿzÁÿzÁÿzÂýyÁüw¿ù€Åþ„ÇüˆÇüŠËÿŒÏÿŠÍÿˆÊþ‘Îû•Îù”Íø–Ïú“Éõ“ÊóÔý›ÑÿžÔÿ©Ýÿ¬Ýÿ£×ÿ Õý˜Ñü•ÐúŸÕû±âÿ¼éÿÌðÿËðÿ¼åÿ´àý°ßý±ßÿ´âÿ´ßÿ±Ýúºäý¹áû»åþºæÿ´ãÿ¬Þÿ¨ÜÿžÕü˜Òú˜Ñü›Ôÿ¥Ùþ²áÿ¸åÿÆìÿËïÿÕóýÜùÿçÿÿäþýæÿüæÿÿßþÿÐñúÎîùÐòþÒóÿÚúÿÝøÿÝöúåûùæûüßøýÚõüÚøÿÕöÿÂêÿ¯ßÿ£Øÿ‘Ïÿ‹Íÿ…Èý‹ÍÿŽÍÿÌÿÍýÐþÍü—ÔÿšÕý¡Ûÿ¤ÜÿžÕü¡Øÿ×ÿ“Ðý‘ÏþÏÿÏÿÏÿÎÿŽÍÿŒÎÿŒÎÿÍü”ÏûžÓý Õý¡ÕüŸÔü¡Öÿ™Òý”ÏûŒËÿ…Æü‚Äþ~Âÿ{Áÿz¿ÿz¿ÿ}ÃÿÅÿ‚ÈÿƒÉÿw¾üu¼üt»ût»ûyÀÿzÁÿyÀÿx¿ýw¿ú{Ãý‚Çþ„Çü†ÅúˆÉÿŒÏÿ‰Ìÿ‡Éû•ÐúœÓúÒúŸÔü™Îö™Îö¡Øÿ”Ìû–ÏüšÐüžÓý™Òý“Îú“Óÿ”ÒÿšÕÿªÞÿ²ãÿÃèÿÅíÿ¾êÿ¸äÿ®Üý¬Úû®Üý²Þû±Ýú³Üø·ßù¸äÿ´áþ®ßÿ£Ùÿ ×ÿœÕÿ›Ôÿ›ÖÿÖÿŸÔü¨ÚýÞÿµáü½åþËïÿÐòþÚ÷ýÛ÷ûàúûíÿÿíÿÿæûüåýÿãþÿßüÿÛùÿÛøþßûÿäÿÿäþÿãøûàøüÞùÿÚøÿÍóÿ±âÿ¡ÕüÎýÎÿ†Éÿ‡ÉýŒÎÿŠÌÿ‰ËÿŠÌÿ‹ÍÿÏÿ‘Ïþ“Ðü’Ïû•Ðü”Ïû’ÏüÏýÏÿŒÎÿŒÎÿŒÎÿŒÎÿŽÍÿÏÿÏÿÏÿ‘Ïÿ”Îü•Îû–Ïü•Îû—Ðý˜Óÿ•ÒÿŽÍÿŠËÿ‚Äþ~Âÿ~ÄÿzÀþy¿ý~Äÿ|Âÿ|ÀýÅÿ{Âÿx¿ÿw¾þv½ýw¾þv½ýw¾üzÂýÇÿÈÿ†Éþ…Èý…Äù„ÅûŠÍÿŠÍÿÐÿ¢Ùÿªßÿµãÿ¸çÿ²ãÿ¬Þÿ Ôû•Îû•Îû–Ìø™Ïû—Òþ‘ÎûÒÿ’Òÿ–Óÿ£Øÿ©Ûþ¸âû¿èÿ»çÿµáþ®Ûú±Þû³àý³ßú²Þùµáü´Ýùµáþ²ßþªÜÿÔû×ÿ™Ôÿ›ÖÿŸØÿž×ÿÔû¢Øü§Üþ¯Þü¶âýÈìÿÌïÿ×õÿÛøÿÝùüêýûîþûëþüêÿÿèÿÿãÿÿÞûÿÚ÷ýÞûÿæÿÿåÿÿãøýß÷ûÜ÷ÿÚøÿÎôÿ³äÿ¢ÖýÍüŽÍÿ†ÉþˆÊþ‰Ëÿ‡Êþ†Éý„ÇûŠÍÿÏÿŽÎþÍüÍüÍúÍúÍüÏÿÎÿ‹Íÿ‰Ìÿ‰Ëÿ‹ÌÿÎÿÏÿÏÿÏÿÎÿ‘Îý“Íý’Ìú‘Ëù”ÎüšÔÿš×ÿÎÿ‹ÌÿƒÅÿÄÿ~Äÿ|Âþ{Áý~Äÿ}Ãÿ}ÁþÅÿ~Äÿ|ÂÿzÀþw½ûy¿ýx¾üx¾ü|ÂþÇÿÈþˆËÿ†Éþ‚Ãù„Åý‹ÎÿŠÍÿ‘Ïþ¨Þÿ´çÿÁíÿÄðÿ¾ëÿµäÿ¤Öû§Ýÿ¦ÝÿœÑû˜Ïø”ÑþÐÿŠÐÿŒÏÿÌÿ“Ìù˜Íõ¬Ýý¸çÿ½éÿ¼æÿ¼äý¿åüÂêÿ½çÿ½çÿ¸äÿ¸äÿ°Þÿ«Üý¢ØþšÓþ–Ñý•Ðü˜ÓÿŸØÿŸÕÿ×ÿ ×þ¤Úÿ©Ûþ¯Ýÿ¾çÿÃèÿÒóÿÙöÿÝøÿãøûçûúéþÿéþÿäýÿáúþÝùýÞúþàüÿáýÿßøÿÚõþÛöÿÛùÿÕöÿÅîÿµäÿ«ßÿ“ÐýŒÌüŒÍÿÎÿ‰ËýŠÍÿ‰Ìÿ„ÇüƒÆû†Çý…Çû‡ÆùŠÉüÍÿÎÿÎÿÏÿŒÎÿ…Çù†Èú‰ËÿÌÿŽËÿÌÿÍÿÎÿÎÿ‘Ïÿ‘Ïÿ‘Ïÿ“Ðÿ–Ðÿ™Ñÿ™ÓÿÎÿŒÎÿ…ÈýÆÿ€Çÿ~Äÿ~ÄÿÇÿÅÿ‚Çÿ‚ÈÿÅÿ|Âþ{Áý|Âÿ|ÂÿzÀüzÀü~ÄÿƒÊÿ†ÍÿŽÑÿÐÿ‹ÌÿŒÍÿÐÿÎÿ’Ïü«Ýÿ¸çÿÌñÿÒøÿÏøÿÈðÿµâÿ©Þÿ¨Þÿ›Ðø—Î÷“ÐýÐÿˆÍÿ†ÍÿˆÉÿÌþ•Îû£Ùû¬ßþºæÿ¿èþÇêýËïÿÌïÿÃìÿÅïÿºèÿ¹æÿ«Üý§ÛÿÔý”ÏûÍú”Ïû–ÑýÓÿžÓýœÖþ×ÿ¢Ùÿ¤Øÿ§×ÿ®ÙûµÞüÇêÿÎíÿ×óÿÛöÿÞùÿÜ÷þÛ÷ûÛ÷ûÛ÷ûßøüäüþéþÿåúýÝôú×ôÿÖóÿÒóÿËïÿ»æù«Üú¥Úü•ÐüÎý‘ÐÿÎÿŽÍÿÏÿÏÿŒÏÿ‡Êÿ†Éþ‡ÊÿŠÌÿŒËÿÍÿÏÿÏÿÏÿŒÎÿ‹Íÿ‹ÍÿŽÍÿÌÿÌÿÌÿÌþÍÿÎÿÎÿÎÿ‘Ïÿ“Ïÿ”Îþ—Ïþ˜ÒÿÏÿŽÐÿˆËÿ‚ÇþÈþ~Åý~Äÿ}Ãþy¿ú}Âý‚ÇÿÆÿÆÿÆÿ€Äÿ~ÂÿÃÿÄÿÆÿ‚Çþ„Ëÿ‡ÊþˆËÿ‰Êÿ‡Èÿ†Èÿ‡Èþ“Îú©Úú´àùÆèòÍîõÒôÿÌñÿ¼äþªàÿ©ßÿ›Òù–Íö‘ÎýŽÎþ†Ëÿ…Êÿ†ÇýËý•Îû£ØúªÝü¹åþÀéýÈìüËïÿÉìÿ¿èþÂìÿ¹çÿ¸çÿ«Ýÿ©ÝÿœÕÿ‘ÎúÌù”Îü–Ñý›ÑýžÓý×ýžØÿ¤Ûÿ¤Ùÿ¦×ÿªÖù±ÜüÄèÿÊêÿÖóÿÛ÷ÿÝùÿÙ÷ÿØöþÛøÿÛøþÛ÷ûâúþçüÿåúûÞöúÓòÿÐñÿÉîÿÄêýµâù¨ÙùŸÔö•Îù”Îü’ÏþÍüÍþŽÍÿÏÿÐÿ…Èý…Èý‡ÊÿŽÏÿÏÿŒËþÎÿÏÿÏÿŒÎÿÒÿÑÿŽÍÿÍÿ‘ÎÿÎÿÎÿŽÍÿŽÍÿŽÍÿŽÍÿÎÿÌþ’Ìü™Ñÿ›ÕÿÏÿŽÐÿˆËÿƒÈÿ‚Éÿ€Æÿ€Æÿ}Ãþz¿ú{Àù€ÅþƒÈÿ„Éÿ…ÇÿƒÅÿÃÿ‚ÄþÆÿÆÿÆý…Ëÿ†ÉýˆËÿŒÏÿŠÌÿ„Æÿ…ÈýÌù¡ÖøªÛù½ãðÆèòÍòÿÌòÿ¿çÿ°äÿ©Þÿ˜Ñü”ÎüŽÍÿÌÿ‡ÉýŠÉü‹Éú–ÐÿžÔÿ°Þÿ´áÿºäú¿êûÇîÿÄíÿÃëÿ¾èÿ¾èÿ»éÿ³äÿ¥Ùþ¢Øþ—Òü“Òþ’Ñý™Öÿ›ÖÿœÒþÔý¡×ý¤Úÿ¤Üÿ£Ùý£×üªÛü°ßý¼äþÀåÿÉìÿÔôÿÓóþÐòþÎïþÍîÿÍîýÔôÿÜùÿßúÿäüþÞúþÍóÿÅîÿ¸âû²ßü¬Üÿ¥ÖþÑùžÓû¡Öþ¢×ÿœÒÿ•Íü’Ïþ‘ÏÿÌÿ‰Èû‡Éý‰Ëý‹ÏÿŠÍÿŽÎþÏÿÏÿÏÿÎÿÌÿŽÍÿÎÿÎÿÎÿŽÐÿŽÐÿÑÿ‘Ðÿ‘ÎÿÍÿ•Îÿ•Íþ–Ïü›Ôÿ™ÔÿŽÍÿŠÉþˆËÿÆÿ€ÄÿÇÿ‚Çÿ€ÂüÂù‚Åü„Éÿ‡Éÿ…Æþ…ÆüŠÉþŠÉþ…ÆüƒÆý‚ÇÿƒÈÿ„Åû‡Èþ…Èý‡Ìÿ‡Îÿ€Çý„ÊþÏÿ–Õÿ›Øÿ©Ûü°ßýµäÿ´ãÿ·æÿªßÿ¤Ùÿ•Ðü“ÐýÌÿˆÊþ‰ËÿŒËÿŽÌý˜ÒÿžÔÿ²àÿ¶ãÿ¹æû¿êûÂëýÆïÿÆîÿ¿éÿ»çÿ»éÿ´âÿ¦Øý¢Öý™Óû—Ôÿ•Òþœ×ÿž×ÿžÕü Öü¤Øý§Ûÿ¦Üÿ¤Øý¤Øý®ßÿ³àÿ¼äþ¿äþÆéÿÑñÿÑñþÍîÿÌíÿÈëþÈëþÑñÿÚöÿÜ÷ÿàùþÜùÿËñÿ¿èü³Ýö¯Üù¬Üÿ©Úÿ¤Øÿ¥Ùÿ¦Úÿ¦Ûÿ Öÿ—Ïþ”Îþ“ÐÿÍþËü‹ÊýÍýÏÿŽÍÿÍüŽÎüŽÎüŽÎþ‹ÍÿŽÍÿŽÍÿÎÿ‘ÏÿÎÿÌÿŽÍÿ‘Ðÿ’Ðÿ‘Íÿ‘Íÿ”Îþ–Ìú™ÏûŸÖýœÖþÍþŽÌÿÎÿ„ÆÿÆÿ‚Çÿ‚ÇÿÃýÄûƒÆý†Ëÿ†Èÿ„Åý†ÇýŽÍÿŽÍÿ‰Êÿ†ÉÿƒÈÿ„Éÿ…Æü†ÈüƒÆúˆËÿ‡Íÿ‚Èü†ÉýÍý’Ïû–Ñý¢Øü¤Ùû¥Úü¥Úü«àÿ•Îû•Ïý‘ÎýŒÊû‡Éý‡Êÿ‡Êÿ‹ÍÿÎÿ–Óÿ›ÔÿÝÿ±âÿºêÿ¾ìÿ¼éÿ¼èÿ¾êÿ¶âý³ßø³ßø·äÿªØü¦ÖüŸÓúŸÖýžÕü¢Øþ£Ùý§Ùú¨Ûú¨ÙúªÛüªÛü«ÜýÞÿ±ßÿµâÿ¿èÿÂêÿÃèÿÈëÿÇêþÅèþÅçÿÃçÿÃçÿÉéÿÑðÿÒïÿÕñýÕõÿÄêý¹âø²Üõ±Þû¯Ýÿßÿ¯áÿßÿ¬Þÿ«ßÿ Õÿ™Íü›ÑÿžÔÿ Öÿ ÖÿŸÕÿŸÕÿ›Ñý˜Îú“Íû‘Ïþ‘ÏþÐÿŽÐÿ‹Íÿ‹ÍÿŽÍÿÍþÌþÎÿÎý‘ÎýÍü™ÑÿžÔÿ Õÿ¤ØÿªÜÿ«Üý¥×úœÓü—Ðû”ÎþÊÿŒËÿ…Èÿ…Èÿ…Èÿ…Èý„Çü†Éþ‡Êÿ†Çý‡ÉýÌÿÌÿÎÿŒÍÿ„Æÿ‚ÄþƒÄúŠÉþŠÉþˆÊþ‰ÈýŒËþŽÌý‘Îý”Íú•Îù™Ôÿ—Ôÿ”Ñý’Ïû’ÏûÉùÍüÍþŠÉü†Éþ‰Ìÿ‡ÊÿŒÎÿÎÿ“Ðÿ—Ñÿ¦×ÿ¬Þÿ·éÿ¼ìÿ¸æþ¶âý·ãÿ´àû²Þ÷³ßø¹äÿ®Úý«Ùý¤Öù£×ü£×ü§Ùú¨Ûú«Üú®Ýù°Ýü±Þý±Þý²ßÿ´áÿ²ßþµáþ¾çÿÁèÿÁæÿÇëÿÇêÿÆèÿÅéÿÅéÿÅéÿÅèþÎïÿÏîÿÑîþÑòÿÅëÿ»äú²Üõ¯Ûø«Ùû®Þÿ®Þÿ¬Üÿ«Ýÿ«Ýÿ¦ÚÿŸÒý¢Öþ¥Ùÿ¦Úÿ«Üÿ¬ÝÿªÞÿ¥Ùÿ¡Òú“Ì÷‘ÎûÎýÏÿŒÎÿ‹Íÿ‹ÍÿŽÍÿÍþÌþ‘Îý’Ïþ’Ìú’ÌúÓÿ£Øÿ§Øÿ®ßÿ³áÿ³àýÜú£×üŸÓú—ÍûËýÎÿŠËÿ‰Êÿ‰Ìÿ‰Ìÿ†ÉþˆËÿŠÍÿŠÌÿ‰ËÿÌÿŒËÿÎÿ‹ÌÿƒÅÿƒÄþ‚Ãù‹ÊÿÌÿÎÿŽÍÿŽÌýÍþ‘Îý”Íú•Îû‘ÏþÐÿ‘ÑÿÐÿŽÎþ‡Æû†Åú…Æü†Çý…Èý…Èý‹ÎÿÑÿÏÿŒÊùÊ÷™Îø Öü®ãÿ±æÿ¬ÝýÛý®Üþ¶âÿ¹åÿ»çÿ½æÿ¶ßÿ´ßÿ±Þý°ßýµäÿ¶äþ¸æþ½êÿ½êÿÁëÿÁéÿ¿çÿ½äÿ¿æÿ¿çÿ½çÿ¼äþ½äÿ¿çÿÃéþÄèþÄèþÅéÿÆêÿÇëÿÆêÿÍðÿÏóÿÎïþÎòÿÅîÿÀèÿ³ßú²Þû´áÿµãÿ±ßÿ¯Ýþ°ßý°ßý±ßÿ¯Üûµáþ¸äÿ»åý¼æþÁëÿÃíÿ½çÿ¶àøŸÕûšÕÿ–Óÿ‘ÑÿÏÿŒÎÿŒÎÿÎÿÎÿ‘Îý”Îü—ÒþœÒþœÓü¦×ÿ«Ûÿµâÿ½çÿÂèÿÈìÿÆìÿ¹åþ´àý¨ÙúÒü›ÔÿÍþŽÌÿŽÍÿ‹Íÿ†ÈúŠÎÿ‰ÍþˆÊþˆÊþ‹ÍÿŒÍÿ‹Ìÿ‡ÈÿƒÄüŠËÿ†Éÿ‰Ìÿ‰ÌÿÏÿÏÿ‘Ïÿ’Ðÿ’ÎÿÍþÎÿÏÿŒÏÿŒÏÿŒÏÿ‰Ìÿ†Çý‡Èþ…Èÿ„Çþ‰ÌÿÐÿŒÎÿÌÿÍþŠÈ÷ˆÅò˜ÎúžÕþ¦Üÿ¦Üþ¤Ùû¦ÖúªØü¹æÿ»éÿ¾êÿ¿èÿ¹âÿ¶ßý³ßü·ãþ¼èÿÀíÿ¼éþÄïÿÆñÿÃìÿÂçÿÀåÿÀåÿÅêÿÂçÿ¿çÿ¾æÿ¾æÿ¿çÿÉïÿÈîÿÇíÿÈíÿÉíÿÈíÿÉîÿËðÿÍòÿÎòÿÌòÿÃìÿÀèÿ´àû²Þû´áÿ±Þÿ±Þÿ¶ãÿ¹æÿ»éÿ»éÿ¼éÿ¼åû¾çûÊïÿÉîÿÏôÿÐõÿÇìüÁèù«àÿ›Öÿ˜Õÿ‘ÑÿŠÌþŒÏÿŒÏÿÏÿ’Ðÿ’Ïþ–ÎýœÕÿžÕþŸÕû«Ûÿ¯Ýþ¹ãüÈîÿÎñÿÎïÿÊíÿÆìÿÂëÿ²Þû£ÕúŸÔü“ÍûŽÌýŽÍÿÌÿŽÐÿ‹ÍÿŠÎÿˆÌý‡Ëü†Èü‡Èþ‹Êÿ‰Èþ‡ÆüŒÍÿŠÍÿŒÏÿÐÿÏÿÎÿÌþ’Îÿ‘ÏÿŽÍÿÏÿÏÿ‹Íÿ‹ÍÿŽÐÿÎÿˆÍÿ„Éÿ‚Çÿ‰ÌÿŽÏÿŒÍÿÎÿ‘Ïÿ“ÐÿÍúÌù‘Îû•Ðü˜ÓûšÔúœÓú Ôü§×ÿµâÿ¸åÿÁîÿ¾æÿÁéÿÂêÿÄìÿÇðÿÉïÿËñÿÆìÿÉðÿÊïÿÇìÿÄèþÅèüÈëÿÉìÿÍðÿÉîÿÁåûÁåûÆìÿÆíþÆíüÇîýÊïÿÊíÿÈìüÊîüËñþËóÿÆîøÄìøÃìÿÃíÿºæÿ¶âý³àÿ´áÿ²Þû¶âý»åþ¼åûÅïÿÎóÿÑóýÐòûÕôùØõûÝüÿÞýÿÕöýÎðù²ãÿ™Óû•ÐúÍýŒËþ†Éþ‡Êþ‹Íÿ‘Ïÿ”Îþ˜ÑþšÓþ Õý¥Ùþ·äÿ¹åþÄêýÖöÿÙ÷ÿÜ÷ÿÝøÿÛøÿ×÷ÿÇìÿ±Þû«ÜýšÐü“ÍûÍþÍýÏÿŽÐÿŠÌþˆËÿ‰Ìÿ‹Îÿ†ÇýˆÇü‰ÈýÎÿ’Ðÿ‘ÓÿÎÿŽÌý’Ìú–Ïü•Îû”ÎüÎÿ‹Íÿ‹ÎÿÏÿ‹Êý‡ÆùˆÇüŠÉþ‚ÈÿÇÿƒÈÿ†Éÿ‹ÌÿŽÍÿ‘Ïþ”Ñÿ˜Óÿ—Òü•ÒþÏÿÍüŽÍù‘Îú–ÑýÓÿ¢Õÿ®Üþ°ÝúºçüÁêÿÄíÿÃìÿÄêýÊïÿÍòÿÊïÿÉìÿÉìÿÇìþÉîÿÈëþÊîþÏðÿÏïþÍíüÍîýËïýÉíýÆëýÆìÿÆíþÊïÿÌïÿÍîÿËìýËïÿÎóÿÎõÿÅïýÂìü¿èþ½çÿµáü¶âý¼èÿµáþ´Ýùºâû¿èþÃéüÈìüÖöÿßüÿàûÿåþÿäýÿæÿÿäÿÿÛùÿÒóü°ßý˜Ïö’ËöŠÊú†Èú…Èý‡ÊÿŽÍÿ‘Îý”Îþ›Ôÿ›Ôÿ¤Øÿ¬ÞÿºèÿÀêÿÎòÿÝúÿàùÿâúþæûþéÿýçÿÿØøÿÀæýµáþ¡Õü˜ÏøÍüÍûŠÌü‰ËýŠÌÿŠÍÿŠÍÿ‰ÌÿŒÎÿŠÉþŒËþ˜Õÿ™Ôÿ˜ÑüÔû Öú¦Öú¦×ø£Ó÷ Ò÷–ÏúÎÿÏÿŽÐÿŠÍÿƒÆúƒÄú…Æü€Æÿ‚Èÿ„Éÿ…Çÿ‹ÊÿÎÿ’Ñý–Óÿ™Ôþ™Ôþ—ÔÿÏÿŽÎþŽÌûÏû–ÓÿžÔÿ¢Õÿ«Ûÿ®Ýù·äù¿èüÄíÿÃìþÅëþÍòÿÍòÿÊíÿÊíÿËîÿÉîÿÉîÿËïÿÌðþÐòþÑñþÖöÿÖöÿÐòþÌíüËïÿÆìÿÆìÿÉîÿËîÿÌíÿËìÿÌíÿÌñÿÌñÿÃìþÀéû¿çÿ¾èÿ·ãþµáü¶âÿ·ãþ¸âû½æüÁêþÉîÿÌíþØõÿÞùÿâûÿèÿÿàøüßøýÞùÿÚøÿÔòü·äÿÒú•ÎùŠÊú…Çù†Ìÿ‰ÏÿÏÿÍü•Íü™Òÿ™Òÿ¦Úÿßÿ¹çÿÀëþÑóÿßúÿãüÿéþÿìÿÿíÿüìÿÿàüÿÇëÿ¼æÿ£×üšÑú“ÐýÏý‹ÍýˆÊü‹Íÿ‹ÎÿŠÍÿ‡ÊÿÏÿŠÉüËüšÔÿžÕþžÔú¬Þÿ³äÿ¹åÿ·ãÿ¯ÛøªØùœÑù’ÏüÏÿÐÿ‰Ïÿ„Êþ„Çü‚Åü~ÄÿÅÿ€ÅÿÃý„ÅûˆÇü•Óÿš×ÿœ×ÿÖÿØÿÏÿŒÎÿŽÎþ‘Ñÿ™ÖÿŸÕÿ¡Ôÿ¯Ýÿ²ßü¸âøºã÷ÅîÿÉïÿÅêúÊîþÊîþÆéüÉìÿÐñÿÎïÿÑóÿÔöÿÖöÿ×õÿÙ÷ÿÞûÿáþÿàþÿ×÷ÿÇëùÈìÿÅëÿÅéÿÇêÿÉéþÉéþÌïÿËîÿÉîÿÁçú¾äù½çÿ»åþ¶ßûµáü½éÿÁëÿÄìÿÇíÿÈîÿÒöÿÖöÿ×ôÿÔðüÖñüàøÿáøÿÝõÿÛöÿÚöÿÕòÿ»èÿžÒù–ÍôÎúÐÿÓÿ’Õÿ•Ôÿ‘Îý“Íý‘Éø”Íú¦Ûÿßÿ¸äýÂëÿÒôÿÞúþäýÿëÿÿìÿýîÿùìÿýåþÿÎïÿÃéÿ«Üü¡Õúš×ÿ–ÕÿÏÿÎÿŽÍÿ‹Íÿ‹Íÿ‹ÎÿÐÿŒËþŽÌûœÖþ¨Üÿ©Øô½çýÊðÿÔõÿÓóÿÏðÿÆêÿ°ßýŸÖÿ–ÓÿŠÍÿ‰Ïÿ‡Ìÿ„Éÿ|Ãû|Äÿ}ÅÿÅÿ}Ãþ~Ãü€ÅüÐÿ—Öÿ™×ÿ™Óÿ’ÏþŠÎÿŠÎÿŽÎþŽÎü™Óÿ£Øÿ¨Ùÿ´àýºäý¼åû½åþÄêÿÆëþÊëúÎïÿÍñÿÄéüÇêþÑðÿÓðÿÚõþÜ÷þØõûÛøþÜùýçÿÿçÿÿàýÿÛùÿÉíýÃçÿÄèÿÁçþÀäúÇìÿÌñÿÍòÿËïÿÊîüËìûÆéü¾åÿ¾åÿºâüºäýÁëÿÈñÿÆïÿÆíþÊñÿÎòÿÖ÷ÿÏïúÐñÿÏóÿ×÷ÿàüÿÞùÿÞùÿÚöÿÖôþ¹åÿ£Õú™Íô’Í÷‘Îú’ÒÿŽÐÿ‘ÑÿŽÌýŽÌý’Ìü”Îü¡Øÿ¥Ùþ¶ãÿÂìÿÔõÿßúÿåýÿìÿÿéüúðÿüðÿÿèýÿØôÿÑòÿ»äÿ«Üü›Õýš×ÿÐÿÎÿÍþÎÿÏÿŽÑÿŠÐÿ‹ÍÿÏûŸÕû·æÿ¶âûÇîÿÓ÷ÿâýÿãüÿÝøÿÓðþ·áù¦ÜÿšÕÿŒÌü‹ÍÿˆËÿ„Çü~Ãü|Äÿ|Äÿ|Äÿ|ÃÿyÁüw¿ùÄýƒÆý†Åû‹Èþ‹Éü‰ÍüŒÎþÐÿÎý—Ðý¥ÙÿÞÿ¶âý»åýÅëÿÉïÿÈëÿËìýÒðûÒòÿÎïÿËîÿÌïÿÓòÿ×ôÿÞõûåýÿãÿÿåÿÿæÿÿèÿÿçÿÿäýÿÞûÿÎïÿ¿äþ½äÿ¾èÿ¿éÿ¿éÿ¾èþÄíÿÃéüÅêüÌðþËðÿÅêÿÄéÿÁçþÂèÿÉïÿÆìÿÂèûÃìþÈòÿÉðÿÐòþËïÿÃìÿÁêÿÊïÿÎïÿ×óþÛöÿÛøþÙöþÊóÿµâÿªÛûŸÕùœÔù‘ÏøŽÍø‘ÏþÍþËýÍü’ÏüœÕÿ¡Öþ²áÿ»çÿÎòÿÖóûÝöûéþÿëÿþíÿÿíÿÿéüÿÞöÿØõÿÇíÿ¹åÿ£Ùý×ÿŽÍù“Ðÿ‘Ëù–Ðþ—ÑÿŽÎüÌÿ‘Ñÿ”ÑýŸÓø»çÿÇíÿØúÿàþÿæÿÿèÿÿäýÿÛ÷ÿÄêÿ¬Þÿ¢Øþ“ÑÿÏÿ‡Éý†ÉþƒÈÿ|Äÿ{Ãþ{Ãþ|Ãÿw¿út¼÷zÀû}ÂûÂúˆÇý‰ÈýˆÌûŠÌüŽÎþÍü˜Ñþ§Ûÿ°áÿ»äÿ¿çÿÊðÿÊðÿÍîÿÐðýÙõÿ×õÿÎîýÎïÿËïÿÏïþÔñÿãúÿèÿÿæÿÿâÿÿâþÿêÿÿêÿÿæþÿßúÿÐðÿ¾æÿ¹åÿ¹åÿ¼èÿ»çÿ·ãþ¼æÿ¿èüÄêýËðÿÊïÿÇëÿÇëÿÃèûÃéüÉïÿÅëþÀæùÂëýÈñÿÅïÿÈíýÇíÿ¾èÿ»åþÆêÿËìÿÖòýÜ÷ÿßúÿÝøÿÎóÿ¾èÿ¶äþ«Þý¥ÚúœÖü™Ôü—Ôÿ‘ÍÿŽÊüËýÌû™ÒýžÓû¯Ýþ¹åÿÊïÿÔòüÙôûæþÿêÿÿìÿÿíÿÿèýÿß÷ÿÛ÷ÿÊïÿ¾èÿ©Þþ¢Úý”Ïù”Ñþ“ÎúÓÿŸÕÿ•Ðü‘Îû—Ôÿ™ÔþžÒ÷½éÿËðÿÝûÿàýÿâûÿäýÿÜøÿÕõÿÄìÿ²ãÿªÞÿ˜ÖÿÑÿ‡ÉýˆËÿ…Êÿ|Àý|Âþ~Äÿ~Äÿv½ûsºøu¼úzÀþ€ÄÿÃÿ„ÇþŠÌü‹ËûËúÌùžÔÿ©Ûþ±ßÿ½åÿÃéÿÌïÿËïÿÚöÿáüÿèÿÿâûÿÞúÿÖöÿÐòþÎîûÔòýàùþæÿÿåÿÿÝùüßøüìÿÿëÿþêþÿäûÿÕñýÀéýµãûÚ÷°Ýü°ÜÿÙü¶áÿÂìÿÈñÿÍôÿÌòÿÔôÿÕõÿÐñÿÌðÿÌñÿÆìÿ¾çû¼åû¿éÿ½çÿ·ãþ³àÿ®ßÿ¯Ýþ½åÿÃçýÓïûÛöÿáúÿÜøüÏí÷ÎðüÌòÿÄïÿ»èÿ¯àþ§ÜþŸÖÿ•Ïý‘ËûŽÍÿŒÌü“ÐüšÔüªÜÿ´ãÿÀéýÒôÿØöÿßûÿåþÿèÿÿêÿÿæþÿßøýÚ÷ÿÊîüÅëþ»éÿ²äÿ¦ÜþŸÙÿ Õý«Ýÿ®ÞÿªÜÿ¥Ùþ¤Ûÿ¡ØÿŸÓø½éÿÑòÿÙ÷ÿÓñüÐðýÏðÿÆìÿÀéÿµâÿ¯ßÿ«Ýÿ”ÒÿŒÍÿƒÄú„Çþ€Åþ}¿û€ÂþƒÇÿÅÿx¿ÿw¾þv½ýw¾ü}Ãÿ~ÄÿƒÈÿŽÎþÏý”Ñþ–ÑýŸÖÿÞÿ³àÿÄêÿÉîÿÏðÿÖôþäýÿèÿÿìÿÿìÿÿëÿÿÚöÿÓñûÓñûØöþÚóøàùþáýÿÛ÷úàøüêþýìÿýìÿÿëþÿß÷ÿÎóÿÅîÿ½åþ¼åÿ¹âÿ¶ßÿ»âÿÅéÿÊîþÓõÿÓôýÚ÷ÿÛùÿÕõÿÐòþÊîþÇíÿÁçþ³Ýö´Þ÷²ßü¯Ýÿ Ôû¡Õü£×ü±Þý¿äþÑíûÙôÿâûÿàùþÛ÷ûÚ÷ûÚùþÔöÿÍñÿ¾èþ³áû¥×üšÐþ”Ìû“ÓÿÐÿ“Ðý—Òü¤ÙûÞþºäüÌðÿÑóÿÚøÿâÿÿæÿÿèÿÿæþÿÝöúÚóøÔòüÐòþÉïÿ¾èþ³âþ¬àÿ®Þÿ²Þû³ßúµáþ´âÿ©Ûÿ¡ÕüœÒø¸æÿÆìÿÅèþºà÷µãû²áýªßÿ¢Øü›Óø¡ØÿžÕþÊÿˆÉÿ„Åý„Æÿ‚Çÿ…Æÿ„Æÿ€Åÿ~ÄÿzÁÿx¿ýw¾üzÁÿÅÿÅÿƒÈÿ‘Ïþ”Òÿ•Òÿ—Òþ¡Öþ°Þÿ¶áÿÄêÿÊïÿÖøÿÖôüæþÿéþÿîÿÿëÿÿçüÿÛöÿÖóûÕòø×ôúßøüÛôùÜøüäÿÿçÿÿëÿþìÿýìÿÿìÿÿàøÿÎðüËïÿÆëþÄèÿÂåÿÁäÿÆèÿËìÿÑñþÖôüÑï÷ÙöüÛùÿÑñüÏñýÊîþÇíÿÅëÿ¹ãüµÞú±ÞýªÚþ¡ÕüŸÔü Ôû°Ýþ½âýÒïÿ×óÿÛöýÝøÿÝöúâþÿßûÿÙ÷ÿÖöÿÉïÿÁëÿ¬ÝþÓÿ–Îý‘Ïÿ“Óÿ˜Õÿ˜Óû¢×ù©ÚúºäüÉíýÎïþØöÿÜùÿäÿÿèÿÿèÿÿáùûÝöúÚ÷ÿÓóþÈíýÆìÿ²àø¨Úû®Üþ¼åÿ¹ãü¶ßû¼éÿ¥×üžÒùÓù¯áÿ½æÿ¹âþ±Þû¨Ýý¡ÙüžÙÿšØÿ’Ïû•Òÿ—Ñÿ‰Èþ†Çÿ‰ÊÿˆËÿ†Éÿ„Åý„Åý‚ÄþÄý}Ãþ}Ãþ€Æÿ‚Èÿ…ÊÿƒÈÿ‰Êÿ’Ïþ•Òÿ˜Òÿ™Òý Ôû¯Üý¶ßûÃèûÉíýÔõþÛúÿëÿÿíÿÿóÿýîüýìûÿâùÿßøýáúþäþÿçÿÿåþÿáýÿàüÿäýÿéýüêþýëÿÿåüÿÙõÿ×õÿ×õÿÖóÿÔôÿÔóÿÔôÿÖóÿÚôÿÝõÿßöþÜõüÔòüÔòüÊê÷ÈéøÄçúÇíÿÅîÿÀéÿºæÿ¶ãÿ¶äÿ«Ýÿ£×þ¢Öý°Ýþ¿çÿÑòÿÙöÿÛùÿÜúÿÞùÿáúÿàùþàûÿÝúÿÒóÿÉïÿ´ãÿ¢×ÿ›Ôÿ‘Îû”Ñý˜Óû›Òù¨Úû°ßû½æüÉíýÎðüØöÿÜùÿàüýãýþæþþêÿÿèÿÿäÿÿàýÿÔöÿÌðÿºàõ±Ýø¯Ûö·ßø¸àú¶ãÿ®ßÿ ÕýŸÖýŸÔüÑø¡Õü¢Ùÿž×ÿ•Ôÿ‘ÑÿŒÐÿÓÿŽÑÿ‹Íÿ‹Êÿ„Åý…Æÿ‹ÌÿŠÍÿ„Çü†Çý†ÇýƒÆý‚Åü€ÅþÆþÈÿƒÊÿ†Ëÿ‡Êÿ‹Ìÿ“Ðÿ–ÓÿšÓÿ›Ñý Ôû°Ýü·áúÅèûËìûÖôþÝúÿëÿÿîÿÿôÿþòüýïýÿéüÿåýÿçÿÿéÿÿèÿÿçÿÿâþÿÝúþáýÿéþÿëÿþèýÿàùþÕòÿÚöÿÚöÿÚöÿØöÿ×õÿ×õÿÚöÿÜ÷ÿßöþáõþÝôüÔôÿÓóÿÊëúÆêúÅêýÃìÿÂìÿ½éÿ»çÿºæÿ¹æÿ¯àÿªÜÿªÜÿµâÿ¿çÿÐñÿÖõÿ×÷ÿ×÷ÿÜøÿÜ÷þßøÿàûÿÞùÿÒóÿËðÿ¶ãÿ¢×ÿ›Ôÿ™ÔÿšÕÿ›ÕûžÔø«Üü²áû¾çûËìýÎîûØôÿÛøþàüýáûüãûûèýþéþÿåþÿàûÿÕõÿÏðÿÁæù¹ãû¶àù¸âú¸âû³áÿ¨ÜÿœÖþ×ÿŸÖý˜Íõ™Ïû™Óÿ•ÒÿÏÿÏÿ‡Íÿ‹ÑÿŠÐÿ‡Êÿ†Çý…Æþ…Æþ‹ÌÿŠÍÿ„ÇüÏÿÏÿˆÊþ„ÇüƒÉý…ËÿƒÉý†ÉþŠÌÿÌÿ‘Ïÿ•Ïý˜ÒÿÓÿŸÔÿ§Øÿ·ãÿ½åÿÈìüÎðüÙ÷ÿÛøþêÿÿíÿÿ÷ÿÿøÿÿöÿÿòÿÿïÿÿìÿÿìÿþèýþæþÿàüÿÛøüàüÿèÿÿçÿÿßøý×ôüÍîÿÓðÿÕñÿÙ÷ÿÛùÿÝüÿÝüþÜúüÞúþàùÿã÷ÿÝôÿÒöÿÑòÿÊíÿÄéûÂèûÃìÿÀêÿ¹åþºæÿ¾ëÿ½çý¸äý²áÿÞü´áþ»ãýÄçûÉêýÊíÿÉîÿÐðÿÓñüØôÿÚõþØóüÒòÿËîÿ´áþ¢×ÿž×ÿœÖþžÕü¡×û§Ùú¶ãÿ»çÿÇìÿÐðýÔðüÛöýáúÿäþÿåýÿçüýéýþêþÿäûÿßøÿ×õÿÒòÿÐóÿÈîÿÄíÿºæÿµâÿ¢ØüŸÙÿ–Õÿ”Óÿ ×ÿœÓü“Ñÿ‹Êÿ‰Èý†Èú‰ËýŒÎÿŒÎÿ‡ÊþˆËÿ†Éÿ‡Èÿ†ÇÿˆËÿ‰ÌÿˆÌýÏÿÏÿˆÊþ„Çû†ÉýŠÍÿˆËÿŠÌÿÍýÍþ“Ðÿ–Ðþ™ÑÿÓÿ Õÿ¬Üÿ¸äÿ¿çÿÉíýÏñýÙ÷ÿÚùþèÿÿíÿÿ÷ÿÿøÿÿöÿÿóÿÿïÿÿíÿÿëþúêþÿåýÿßûþÛøüßûþçÿÿäüþÚõüÕóýÌïÿÏîÿÓðÿÙ÷ÿÛùÿÛýþÜþýÚúùÜøüáùÿâøÿÛõÿÎóÿÍðÿÈíÿÁçú¾äùÁêÿ¿éÿ¸åü¸åü¼æü½æø»åû¶åÿ²áý¶âý¸âû¿âøÁäøÄéüÅêýËìÿÒïÿØôÿÖñüÕðûÒïýÉìÿ±Þû ÖüÖÿ¡Øÿ£Ùÿ§Üþ¬ßþ¼èÿÁëÿÌïÿÕóþ×óþàùÿåüÿéÿÿëÿÿéýþåùúäøùÞõûÜõüÙ÷ÿÕõÿ×úÿÌñÿÈîÿ¸äý±àþšÔú—Ôÿ“ÓÿÐþœÖþžÕþ—ÕÿŠËÿ‰Ëÿ‰Èû‹ËûÏÿŽÎþˆÊüÏÿ‰Êÿ„Çþ„ÇþŠÍÿŒÏÿŠÎÿ‘ÏÿÎÿŽÎþŽÍÿŒÎÿŒÎÿÏÿŒÎÿŽÍÿÏÿ‘Ïÿ•Ðú˜ÑüŸÖý Öü«Üý¾çÿÇíÿÒñÿÕòÿÛöÿáúÿëÿÿïÿÿ÷ÿÿöÿüôÿûñÿÿîÿÿèÿÿçÿÿâþÿÞúûÜøùßùúãûýâúþÞ÷üØôÿÒñÿÉìÿÐñÿÑóÿÒôÿÕ÷ÿØúÿÕ÷ÿÕöÿ×õÿØöþÜùÿÛùÿÎóÿÈïÿÁçú¼åùÁëÿ¼èÿºæÿ·äÿµâÿ°ßý«Þû¶éÿ´åÿ²áý´àûºãÿºâüºâü»åþ»äÿÈìÿÍðÿÐóÿÎõÿÉòÿÀïÿ¹éÿªÜý¡Öþ¤Ùÿ©ÝÿªÝü°ßû·ãüÇíÿÌðÿØöÿÜõüßøýèÿÿéþÿèýþéþÿêÿÿæûþáùýÝöýÛöÿÛ÷ÿÚöÿÒòÿÏñýÃêû¶âý¯ÝþŸÔþšÐþ”Îü•ÏýžÕþžÕü™Òÿ•Ïý’ÏþÎÿÌÿÌÿÌÿÌÿÎÿ‘ÍÿŠÊú‰ËûÏÿŽÐÿÏÿ’Îÿ‘ÍÿÍþÍý‹Íÿ‹ÍÿÏÿŒÎÿÌÿÎÿÎÿ”Ïù—ÐûžÓû Ôù°Þÿ¼æÿÆêÿÐïÿÕòÿÞöÿåýÿìþþïÿþöÿÿøÿüõÿüñÿÿíÿþæþþäýÿáÿÿßûüÝúøâúúçüýåýÿàùÿ×ôÿÑðÿÆéÿÊëúÍïûÑòÿÔõÿÑòÿÉíýËïÿÎðüÒòýÖ÷ÿÕ÷ÿËòÿÆìÿ¾çû»åû½éÿºçÿ¸åÿµáÿ´àÿ®ßÿ©ßÿ¬âÿ¬ßþ¬Ýý´àýµÞü¶ßý¸áý¹åÿ»çÿÅéÿËîÿËñÿÃðÿÀïÿ¸êÿ±äÿ¥Úü¢×ÿ¤ÙÿªÜÿ«Þýµãý½çÿÊïÿÏðÿÚõþÝöúáùûêÿÿéþÿêþÿêþÿêÿÿæþÿäýÿÙôýØóüÙõÿØöÿÒòÿÎòþÄêý¶ãÿ±ßÿ£Öÿ›Ïþ”Ìû•ÎûžÕþ ÖüŸÔüšÐü–Ïü’ÎÿÌÿÎÿÎÿÍÿ‘Îý“ÍûÌøÎú’Òÿ‘ÑÿÎÿ’Îÿ’ÎÿÎÿÎÿÏÿŽÐÿÏÿŒÎÿÌÿÌÿÎÿ•Ðü™ÒÿŸÔþ¢ÖýµãÿÀêÿÈìÿÒòÿ×õÿãüÿìÿÿîþþïýýôþýøÿþ÷ÿýôÿÿïÿþçüýãûÿàüÿßûüâüýçÿÿéþÿãûÿÞ÷üÕóþÏïþÆéýÐñÿÏñýÉíýÈíÿÇíÿÃéÿ»äú¿åüÃéþÈîÿÆïÿ¾èÿ¸äý³ßú¯Ý÷¯Þü¯àÿ¬ÝþªÚþ©Ùý£×üžÔøÕú£Ùÿ¥Ùÿ¤Öû£Ó÷¬Ùú±Üüºãÿ½çÿÊëþÎïÿÈíÿ»åû¹åþ¯àþ¥×øœÐõ£×ÿ¤×ÿ¦Ûý«Ýþ»èÿÁíÿÍòÿÒóÿÛöÿäüþèýÿëÿþêþýíÿÿìþÿëÿÿåþÿáüÿÕñýÐíûÍîÿÎïÿÇìÿÁêþ¶âýÞÿªÜÿ ÕÿžÔÿšÐüÒú©Þÿ¯áÿ¬Ýþ¤Øý ÕýšÓÿ–ÐÿËýËýÍü•Îû˜Ñþ›Õý×ÿØÿšÕÿ“Ðÿ”Îÿ”Îÿ’Îÿ’Ðÿ“Óÿ”ÔÿŽÐÿÎÿÎÿ’Ðÿ“Ñÿ˜ÒÿÕÿ¨Ýÿ©Ýÿ³áÿ¿éÿÈíÿÑñüÖôüãüÿêýÿñÿÿõÿÿöÿÿöÿü÷ÿÿõÿÿñÿÿìÿÿêÿÿâûÿßøüáúþçÿÿéþÿäüÿßøýÖóûÒðûÊëúÍïûÍîýÈíÿÄíÿºæÿ³àÿ¬Úü©Úû«Üý¯Ýþ¯Ýþ¬ÝþªÛüÞÿªÜý¨Úýªßÿ©Þÿ§Ýÿ¥ÛÿžÖûÔû•Ï÷—ÒþšÔÿœÖÿÓÿ«Ýÿ³áÿ¾èÿÅêÿÏðÿÍðÿÇíÿ·ãÿ´áÿ¦×ÿÑùšÏùŸÖÿœÓú Öú¥Úü´ãÿºæÿÌñÿÔõÿÜ÷ÿèýÿëÿÿëþüíÿþïÿþîÿÿëÿÿÜ÷ÿ×óþÍîÿÄçû½åþ»åþ°Üù®Üý£×ü¡Öþ ×ÿÓÿ Öÿ¢Öý¨Úý¸çÿ½ëÿºæÿ´áþ®ßÿ¨Üÿ¤ÙÿÖÿÖÿÓÿžÓû£Øÿ«Ýÿ¬Üÿ¨Üÿ¤ÙÿœÒþ”Îþ”Îþ’Ïþ‘Ïÿ‘Ñÿ’ÒÿÏÿŽÍÿÎÿ“Ñÿ“Ñÿ–Ðþ™Ñÿ§ÜÿªÞÿ³áÿ½çÿÆëþÒòýØöþåþÿêþÿñÿÿõÿÿöÿÿ÷ÿÿ÷ÿÿõÿÿòÿÿìÿÿêÿÿäüÿàøüáùýéþÿéþÿåýÿàùþØõýÕóûÎðúÐòþÐñÿÇíÿÃíÿ¶åÿ®ßÿ¤Õý Öü¡×ý£×þ£×þ¢Öý¢ÖýªÞÿ«ßÿ©Ýÿ©ßÿªàÿ¨àÿ¥ÝÿÔûžÕþ—Ðý“Ðÿ”Ðÿ•Óÿ—Ñÿ§Üÿ±áÿ¾èÿÆìÿÎòÿÊðÿÄìÿ¶âÿ±ÞÿŸÒÿ˜Îü˜ÑþšÕÿ—ÒúœÔù¢×ù±âÿ¸æÿÊïÿÒóÿÜ÷ÿèýÿëÿÿëþüîÿÿïÿþíÿÿêÿÿÛ÷ÿ×ôÿÊíÿÁçþ¹åÿ¶ãÿ©Úû¤ØýÔûžÔÿž×ÿžÔÿ ×ÿ§ÙüÞþ¿ìÿÄïÿÄíÿ½çÿ¶äþ®ßÿªÜÿ Õÿ ×ÿŸÔü£×ü¨Üÿ´âÿ³àÿÞÿ«Ýÿ Õý–Ðÿ•Ïÿ‘ÎýÍüÏÿÏÿŽÎþÍýŽÌÿÎÿ‘Ïÿ“Íý—ÏþŸÔþ¥Ùÿ²àÿºäúÃèúÑòûÙøýëÿÿîÿÿôÿÿôÿÿöÿÿ÷ÿÿ÷ÿÿòÿÿðÿÿëÿÿêþÿãøýãøýåúÿèýÿçüÿåýÿãüÿÜøüÙöüÚøÿÔöÿÎòÿÀéý¹åþªÜÿ¤Øÿž×ÿ˜Òÿ—Ñÿ”Ïû‘Ìø˜Ñþ›Ôÿ£Úÿ¨Ýÿãÿ¦Üÿ¡Øÿ¡Ûÿ¡Ýÿ“ÎöÓÿÓÿÌÿÊÿÏÿÍÿšÓþ¥Ùÿ´áþ½åÿ¿éÿ¶ãÿ³áÿ§Ûÿ Ôÿ–Ðÿ“Ïÿ’Ðÿ•Ôÿ”ÓþœÔù¡Öø²àÿ¹åÿÈíÿÎïÿÜ÷ÿèýÿéüÿîÿÿðÿÿíÿÿíÿÿãüÿÚ÷ÿÔõÿÁéÿ¹åÿ±ãÿªÞÿ—Íù”Ìû•Ïÿ—Ñÿ™Óÿ¡Øÿ¥Ûÿ¬Û÷³áùÈïþÌðüÎðüÊîþÄêý´àû¯Þü¤Öù Ôù¥×ü«Ýÿ²âÿºæÿ¼èÿ´áÿ°Þÿ¨Üÿ•Ïÿ•Ïÿ‘ÎýÍüÎÿÏÿŽÎþŽÎþÍÿÎÿ‘Íÿ“Íû–ÏüÒü¢Öý®Ýû¹ãùÂçùÐñúØ÷üéÿÿíÿÿôÿÿôÿÿõÿÿôÿÿõÿÿñÿÿïÿÿëÿÿêÿÿäùüäùþåúýçüÿæûþäýÿäýÿßûÿÜùÿÛøÿØøÿÑõÿÀéÿ·ãþ¦ØýžÓý”Ñþ’Ïþ“ÐÿÍúÊ÷”Îü—Ðý Öÿ¢Ùÿ¦Ûÿ¥Ûÿ¢Ùÿ×ýœØý”Ï÷šÐüžÔÿ”ÐÿÎÿÏÿÍÿšÓÿ£Øÿ¯Ýþµáþµãý±ßÿÝÿ£ØÿÓÿšÓÿ—Óÿ“Ñÿ“Óÿ“ÒýžÔú¥×ú³âÿºæÿÈíÿÎïÿÛöÿâùÿçüÿìÿÿíÿÿìÿÿêýÿßøÿÔôÿÌñÿºæÿ²àÿ©Þÿ¤Ûÿ“ËúÍü’Îÿ”Ñÿ–Óÿ ×þ§Ýÿ°ßùºäúÌòÿÒóüÑòûÎïþÉîþ½çÿ¶äþ§Øù¤Öù§Ùü¬Þÿ±âÿ¼èÿ½éÿµâÿ°Þÿ§Ùþ”Ìý”Ìý’ÌüÍüÍüÍüŽÎþÍþÍþÌþÍü–Ñû™Òý Õý¤Øý¯Þü½çýÆëýÑñü×õýåþÿëýýñÿÿòÿÿñÿÿîüüïýþëýýêþýêÿþêÿþíÿÿìÿÿíÿÿíÿÿêÿÿçÿÿçÿÿäÿÿãþÿÝúÿØõÿÑòÿÀåÿ¶âÿ¢ØþšÓþ’Ïþ–Ôÿ˜Öÿ—Ôÿ”ÑþÍú’ÍùÔý¡ÖþŸÓú ÖüŸÔü˜Òú˜Óû—Òü˜ÏøÓÿ™Ñÿ–Ðþ“Íý“Íû–ÏüœÓüžÒùžÒ÷¦Öú¦Öú¥×üžÓý™ÏûšÕÿ™Ôÿ—Òþ˜Óÿ˜Óý¡Õú§Øù³àý»äÿÈíÿÎïÿÚöÿÞ÷þâùÿèýÿèýÿçüÿÞöúÓïúÈëþ¿èþ¯Ýþ¥×ü›Ôÿ™ÓÿÌÿ‘Ïÿ’Ðÿ”Ñÿ˜Óÿ¡Ùþ©Þþ¹æûÇîÿØøÿÛøþÜ÷þ×õÿÓõÿÇíÿ¼æÿÚû«ÙûÝÿ¯àÿ¯àÿµâÿ¶ãÿ³áÿ®Þÿ¤Øÿ”Ìû”Ìû“ÍýÍüÍüŽÌûŽÎüÍþÎÿ’Îÿ’Ïþ—Òü›Ôÿ£Ùÿ¨Üÿ³âÿ¾èþÇìÿÑñüÖôüãüÿëýýðÿÿñÿÿïÿþìüüíýýëýýêþýêÿþëÿÿëÿþëýýëÿþìÿÿéÿÿåþÿãüÿßøýÞùÿÝøÿ×ôÿÏðÿÀåÿ¶âÿ£Ùÿ›Ôÿ“Ðý–Õÿ™Öÿ—Òü”ÏùÍú“ÎúŸÖÿ£Øÿ£Õú ÔùžÒù›ÕýØÿ™ÔüŸÖýŸÖýÓÿšÓþ™Òÿ•Îû—ÍùšÐü™Ðù™Ðù£Óù¦Öú¥×úžÒ÷›ÏöžÕüžÕüœÓúÒúžÓû§×û¬Úû¶âý½åÿÊíÿÏðÿÚöÿßøÿßøÿæýÿèÿÿãûÿÝöýÒðûÇëÿ¾èÿªÚþ Ôû–Ðþ“ÏÿÍÿÎÿ‘Ïÿ“Ðý—Òü¢Øü¬ßþ¾èþÊïÿÚøÿÜøüßøýØöþÕõÿÉíÿ½åÿ®Ûü¬Úü®Þÿ®Þÿ¯ßÿ²àÿ±ßÿ¯ßÿ«Ýÿ¡×ýšÒÿšÒÿ˜Òÿ•Òÿ‘ÏþÎýÍüÍþ‘Íÿ–Òÿ˜Õÿ™ÔüžØÿ¨Þÿ¬áÿ·æÿÀêÿÈíÿÏïüÔòüÞ÷üêþýìÿûíÿüíÿþíÿÿëýýêþýéÿýèÿþéÿÿïÿÿíÿþìÿýéþÿçüÿâûÿÞ÷üÛôûÞ÷þâûÿÚöÿÒñÿÁæÿ¶âÿ£×þœÓü˜Õÿ™×ÿØÿ™Óø•Ñö—Òþ›Ôÿ¥Úÿ§ÛÿªÚþ¨Úÿ¨Ùÿ¢×ÿ ÚÿÖÿ¢Úÿ¡×û Öü¢Öý¢Öý¤ØÿœÒþ›Ôÿ—Ôÿ—Ôÿ¨Øÿ²Þÿ³áÿ®ßý¬Þù°âý±ãþ´ãÿ±Þÿ²Ýÿ¸åÿ¹æÿ¾èÿ¿çÿÇêþËìýÑïú×ôüÚõþÞùÿßúÿßúÿÞùÿÓóÿÆìÿ¼èÿ¦ØýÒü“ÍÿÌÿŽËÿ‘Ïÿ‘Îý”Ïû˜Òú£Øú³äÿÄíÿÎòÿÚ÷ÿß÷ûàøüÞùÿÛùÿÌñÿÃëÿ¶ãÿ±ßÿªÚÿ¨ØþªÚþ¬Üÿ¨Úÿ¤Øÿ¢Öý›ÒùŸÔüÔûœÖþÖÿ–Ñý‘ÎúÍùÍù•ÐüšÕÿœÕÿ ×ÿ¥Úÿßÿ±ßÿ¿èÿÈîÿËðÿÐñÿÕõÿÙ÷ÿåþÿéþÿéþÿêÿþéÿýèþüêþüëÿýëÿýëÿýðÿÿíÿÿéýþàøüÜøüÔòüÒðúÍíúÏïüÐðÿÍðÿÉîÿ½çÿ·ãþªÝü¥Úü¡×ýŸ×ü£Ùÿ¡×ûžÔøŸ×ú¢Úý©ßÿ©ßÿ¨Üÿ¦Úÿ¤Øÿ£×ü£Ùý¥Úú©Ûü²áÿ³áû´àû»çÿµáüªÛû¦Øû£Ûÿ¤Þÿ³áÿÄìÿÈîÿÊîþÊëüÅêúÆëûÉîþÍîýËëøÉðÿÆïÿÆïÿÅîÿ¿èþ¿åüÃçýÍîÿÒòÿØöÿØöÿÓõÿÓóÿÑðÿÁéÿ¸åÿ¡Ýÿ™ØÿÏÿÍþ“Íý’Ïü•ÐüšÑøŸÕû¯Þü¹åÿÉîÿÏðÿÚ÷ÿÚöúÝøÿÚöÿÙ÷ÿÑòÿÈíÿ½æÿ¶áÿ¦Öü¡Ôÿ£ÖÿŸÕÿ ÖÿŸÕÿÓÿšÓþ Öü ÖüŸÖý×ÿ–Ñû”ÏùÍù“Îø–ÑûœÖþ×ÿ¡Øÿ¦ÚÿÝÿ°Ýþ½çÿÅëþÉìÿÎïþÒóÿ×÷ÿßûÿäüÿåýÿçÿÿèÿþæÿüéÿýêþýëÿþìþþïÿÿíÿÿéüÿÞ÷üÛöýÖöÿÓóþÎïþÌðÿÍîÿÌñÿÈîÿ½çý·ãüÞü©Üû©Ûü¦ÛýªÜÿ©Ûþ¤Ùûž×õ¢Øú¨Þÿ©Þÿ¨Ýÿ¤Øÿ£×þ¤Øý¥ÚüªÝü¯Þüµãýºäü½æüÂëÿ½æü°Þø«Úø¥Ûý¨àÿµâÿÈîÿÌïÿÕóþÕóþÏïüÍïûÐòüÔòúÒï÷ÎðúÊðûÈïÿÉïÿÁêÿ¾æÿ½æüÆëþÊîþÏñýÏñýÍóÿÐñÿÍìÿ»âÿ±ßÿ›Ùÿ“ÖÿŽÎþÍþ•Íþ”Îü•ÐúœÓú¢Öû²ßþ»åþÉìÿÏðÿÚùþÚõüÜøÿÛ÷ÿÙ÷ÿÏðÿÈëþ¾æÿ¶âÿ¨Øþ¡Ôÿ¡Õÿ¡×ÿŸØÿ›Ôÿ›ÑÿœÒÿ¢Øþ¢Øþ ×þžØÿšÕÿ™Ôþ–Óÿ™Ôþ›Öÿ×ÿ×ÿ¥Úÿ§ÛÿÞÿ±Þý¾èÿÇíÿÉìÿÉêûÌíüÏïüÖóûÚõüÝùýáýÿãÿÿçÿÿæÿÿåÿÿçÿÿèÿÿåøþéüÿçûÿÞùÿÚøÿÕ÷ÿÓõÿÎïþËïÿÍîÿËîÿÆëý¾äùºãù¶ãúµáú¸æÿ½éÿ¾êÿºãÿ´âü¬ÞÿªÜÿ¨Üÿ¨Ûÿ¤×ÿ¡Ôÿ¡Ôÿ¥Öþ©Ûÿ¯àÿ¶âÿ¼æþÈîÿÌñÿÎñÿËðÿÀéÿºäý°áÿ°áÿ¼èÿÍòÿÓôÿÛùÿÜøÿÛùÿ×÷ÿ×ùÿßýÿÞùÿÞúþÛ÷û×õÿÖöÿÎñÿÉíÿ¿èþÁêÿÄíÿÆïÿÆðÿÄëüÆëýÃçÿ°Ûû§Ùú™×ÿ‘ÔÿÍýŽÌý’Ìü•ÏýšÔü¢Øþ¨Üÿ·äÿ¼æÿÊíÿÐðÿÚ÷ýÛ÷ûÚõþÜøÿÙõÿÎîûÌíþÁçþ¹ãüªØú ÔüžÑþšÏû›Ðü›ÐúœÑû¡Öÿ¡Öþ¡Öþ ×ÿÖÿœ×ÿœ×ÿš×ÿ›Öÿ›ÖÿœÖþœÖþ¤Ùÿ§Ûÿ®ßÿ²ßþ¿éÿÉïÿËîÿÊëüÌíþÏïüÔòýØõýÚ÷ÿÞûÿßüÿåÿÿâþÿáýÿâýÿåþÿÞõûáøÿàùÿØôÿÕóýÔöÿÒôÿËïýÉíýÊíÿÍñÿËîÿÄéüÃèûÀéýÀéÿÂëÿÌòÿÍóÿÄèþ½åþ±âÿÝÿ©Úÿ¨Ùÿ¡Ôÿ¡Ôÿ¢Óþ¦Öþ©Ùÿ±ßÿ»äÿÃéþÏòÿÓôÿÔôÿÐñÿÉîÿÂëÿ¸æÿµâÿºäüÌïÿÒóÿÜøÿÛöÿÚøÿÖöÿ×ùÿàþÿáüÿäüÿâúüÛöýÚöÿÑòÿËîÿÃéþ¿èþ¿èþ¾éü¾éü¾çù¿èü»ãýÛü¥Úü—Öÿ“ÔþÏÿÍþ”Îÿ—ÒþœÖþ¥Ûÿ¬Þÿ¸äÿ¿éÿÌïÿÑñþÚ÷ýÚöúÙôýÛøÿÙõÿÑñüÐñÿÊîÿÀèÿ¬Úû¤Øÿ¢Õÿ˜ËöšÍøžÒúŸÓû¢ÖþŸÔü ÕýžÕþšÓþœ×ÿžÙÿ™Öÿ™Ôÿ—Òü›Ôÿ×ÿ¡×ý¦ÚÿÞþ¯Üù¹ãûÅëÿÉîÿÉìÿËîÿÊîþÌíþÏðÿÑòÿÖöÿØùÿÚøÿÓóþÑñüÒòÿÓôÿÙöÿÚ÷ÿØõÿÒòÿÑñþÒóÿÑòÿÉíýÆéüÈëþÏðÿÎïþÍîýÎïþÏðÿÏðÿÕõÿÝûÿÝùÿ×óÿÒòÿ½æÿ³ßüªÚþ¨Ùÿ ÓÿŸÒÿ¡Òý§×ý¯Ýÿ¹åÿÁêÿÏóÿÙöÿÛ÷ÿÝøÿÛöÿØõÿÒóÿÇíÿÃéþ¾äùÉêûÎîûÛöÿÛöÿ×óÿ×ôÿÕõÿØöÿÜ÷ÿß÷ûàøüÝöûØóüÔòýÒòÿÍñÿÇìÿÆëþÅëÿÃìÿ½êÿ¹æýÚù£Õú Öü”Òù’Ñú‘Ïþ“Ñÿ–Òÿ–Ñý ×þªÞÿ±âÿ»çÿÁéÿÍñÿÒòÿÝúÿßûÿàùÿÝöýÛöýÚ÷ÿÙ÷ÿÏóÿÆíþ³ßúªÜý¥ÙþÒúÔýžÕþÒüœÑûŸÔü ÕýÔý™ÒýšÕÿœ×ÿ–Óÿ–Ñý•Ðú›ÔÿŸÖÿ¤ØýªÜÿ°Þÿ¯Üù·áùÆìÿÉíÿÈëþÉìÿÆéüÆëþÉîÿÍñÿÔöÿÖøÿÓóÿÍïûÉíûÊîþÌïÿÎïÿÏðÿÏðÿÎïþÎïþÎïþÎïþÉíýÇêýÌïÿÔôÿÔôÿÔôÿÖöÿÙ÷ÿØöÿÚöÿÝøÿÞ÷þÜõüÙõÿÄíÿºäý®ÜþªÚÿŸÒýŸÒý¡Òû«Ùû±ßÿ¼èÿÂèûÒóÿÙõÿÚõþÞ÷þàùÿÚöÿ×õÿÌðþÈíÿÅëþËìýÏìúÙôÿÚõþÖôÿÕõÿÕõÿÕóþÙõÿÜõüÞ÷þÜ÷þØóüÕóý×õÿÎîýÊëüÊíÿÎñÿÌóÿÂïÿ¼èÿªØúŸÓúžÖû—Óø“Ñø’Ïû’Ïþ–Ðÿ–Ïú¡×ýßÿ²ãÿ½éÿÀèÿÎïÿÒòÿßüÿâþÿãüÿÞ÷üÝöûÝùýÛøþÕõÿÌðÿ¼æþ²ãÿ¬ÞÿÔûÔýœÓü›ÒûÔýœÑù›ÐøœÓü›ÔÿšÕÿ™Ôÿ•Òÿ–Ñý•ÐüšÓþ¡Øÿªßÿßÿ±àþ¶ãÿ»åýÄêÿÇëÿËîÿÉìÿÂæü¾äûÀæýÂèýÉîÿÍñÿÍñÿÇìþÂèû¼åû¼äþ¾æÿ¿èþÀéýÅêüÇìþËïÿËïÿËïÿËîÿÎñÿÐñÿÓóÿÕõÿØôÿÙôýÙôûåþÿèÿÿèýÿæûþâûÿÍñýÄëü´âü¬ÝýžÔú¦Üÿ©Ýÿ³äÿ½ëÿÃîÿÊïÿÏïüÔñùÙò÷ãøýäùþáøþßøÿÖôþÑñüÊïÿÎïÿÑñþÚõÿÚõÿÖóÿÐñÿÌíþÑñÿÕòÿÑñþÑóÿÕõÿÖöÿØöÿÙ÷ÿ×óþÖòþÔðüÒîüÒòÿÄîÿ»çÿ¬Üÿ¤Ùÿ¤ÚÿŸÕ÷Óõ™Ð÷—Ðû—ÐýÔû¤ØýÞÿ²àÿ½æÿÂèÿÎïÿÓóÿÜùÿçÿÿçÿÿéþÿêýÿéþÿçÿÿÝøÿØöÿÉïÿºèÿ²áÿ¦Üÿ¥ßÿ¡ÛÿœÕÿ—Òü˜Í÷›ÐúžÔÿ›Ôÿ—Ñÿ–Ðþ”Ñþ•Ïý”Ïû™ÒýŸÖÿªßÿßÿ³âÿ¸åÿ¼æþÄêÿÆêÿÈìÿÇëÿÀæý½åþ½åþ¾çýÄêýÉîþÍòÿÅëÿÀéÿ·ãüµáþ²Þûµßø·áù¿èüÄêýÈíÿÊïÿÌïÿÌïÿÌïÿÍîÿÏñýÓóþ×óþÙôýÜõüèÿÿêÿÿèýÿçÿÿæÿÿÔöÿËðÿ¶äü¬ÝûÓù£Ûÿ§Ýÿ²äÿ»éÿÅîÿÉîþÐðýÒï÷ØñöæûþéüÿæþÿäýÿÚ÷ÿÕóýÊïÿÐñÿÔôÿÚöÿØôÿÑñÿÍîÿÆéüÍìþÏïþÍñÿÎòÿÒóÿÕõÿÙ÷ÿÚøÿÚõþØóþÕðûÑëøÒïýÅîÿ¼èÿ®àÿ©ßÿ©ßÿ¥Úù¦Ùø ÔùÒú™ÏûŸÔü©Ýÿ¬Ýþ°ßýÁéÿÂèÿÍîýÑñüÚ÷ýçÿÿêÿÿëþÿìþÿìþþëÿÿåýÿßúÿÎòÿ¾èÿ³àý¦Üÿ§Þÿ¥Üÿ¢ÙÿœÖþÒüŸÔþÓÿ˜Ñþ”Îü•Ïý‘Îû’Ìú“Îú™Òÿ ×ÿ«ÝþÞþ¶ãÿ»éÿ¼æþÃéÿÄèþÅéÿÅéÿÀåÿ½æÿ¼åÿ½åÿÃéþÉîÿÊïÿÅëÿÀêÿ¸åÿ±ßÿ©ÛüªÛû¯Þú»èÿÁêþÇìþÊïÿÏòÿÍðÿÊíÿÌïÿÍñÿÔôÿØöÿÞùÿàüÿãüÿâûÿáúþæÿÿåÿÿÙúÿÎòÿ´àû©Úû›ÔÿœÕÿ ×þªÝü²áûÂíÿÌóÿÒôÿÓðøÖòöçÿÿêÿÿéÿÿçÿÿÚ÷ýÕòúÄéûÌïÿÔôÿØöÿÕòÿÎïÿÊíÿÃçýÆéýËëÿÕöÿÔõÿÖôÿØöÿÚ÷ÿÙöü×ôüÖôÿÒòÿÍîÿÏðÿÆìÿ¼æÿ¨Úÿ¬àÿ²äÿ¾ìÿÀìÿ¶ãÿÞÿ£×ÿ§ÛÿªÚþ°Þÿ´áþ¾æÿÃéþÌíüÏïúÙöúèÿÿíÿÿòÿÿòÿÿôÿþôÿþìþÿçüÿÔñÿ¿åüµßøÛü¬Ýý¬Ýþ¨ÚûŸÔö§Üÿ¥ÚÿŸÕÿ›Ôÿ–Ðþ”Îü’Ïü“Íû“Îú˜ÑþŸÖÿ¨ÛúÞþ´áþ¸æÿ½çÿÂèÿÁçþÅéÿÅéÿÃèÿ¼èÿ½æÿ½çÿÁçüÃèûÂæüÀèÿ½æÿ±ßÿ®Üþ¦Üÿ¨Ýÿ®áÿ»éÿ¾èÿÄéüÈíÿÌïÿÈëÿÅèþÉîÿÊïÿÏñýÑñüØõýÚ÷ýÙõùÙõùÙõùÞûÿßüÿÔñÿÊëþ´áÿªÜÿ•Íþ–Ðÿ˜Ðÿ£Õú©×ø½çÿÆïÿÏóÿØöÿÝøÿæþÿêÿÿèÿÿäýÿØõûÓðøÅêüÉîÿÐñÿÕòÿÑñÿÎñÿÌðÿÂêÿÅéÿËîÿÕñÿÕðûÚõüÞùÿáýÿÞûÿÚøÿÏóÿÈîÿ¿éÿÂêÿÅèû»ãü¨Øü®ÞÿµãÿÁêÿÅëþ¼æÿ´áþ¬ÞÿßÿªÛü´áÿºæÿ¾æÿÄèþÎïþÑñüÛøüéÿÿïþÿõÿÿ÷ÿÿøÿü÷ÿûñÿÿìþÿÛõÿÇêþÀåÿ¸âû¹ãû½çÿ»çÿµáþªÞÿ¦Ûÿ¡×ÿž×ÿ–Ðþ‘Îû”Ñþ’Ïþ“Íû—ÐýÔý§ÙúÞþ³àý¶äþ½çÿÂèÿÁçþÄêÿÅëÿÅêÿÀéÿÀêÿÀèÿÁçþÁçüÀæýÀêÿ¼èÿ±ÞÿÛý¨Ýÿ©Þþ°ãÿ½ëÿ¿éÿÁçúÆëþÈíÿÅèþÃæüÈîÿÉðÿËðÿÍñÿÔôÿØöÿÙöþÛøþÚ÷ýàýÿàÿÿÐñÿÃçýÝÿ¦Ûÿ˜Òÿ—Ñÿ™Ñÿ£Õú¦×ø»çÿÄïÿÏóÿÜúÿáüÿêÿÿëÿÿèÿÿäýÿØõûÒðøÅêüÇìþÍîÿÏïþÎîýÌïÿÊîÿÀèÿÂçÿÇíÿÒîüÓîùÞ÷þåüÿéÿÿæÿÿÛùÿËðÿÂëÿµäÿ·äÿ·ßù°Ûû¡Òú¥ÖþªÛü¸äý¿èþ¹ãü³ßü¯Ýÿ®Þÿ®Üþ´áÿºæÿÃéÿÆéýÐðýÕóýÝùýìÿÿðþÿõÿþøÿÿøÿü÷ÿûõÿÿðÿÿàøÿÍîÿÇêþÆìÿÇíÿÆïÿÄìÿ¹ãü²äÿ«ÝÿŸÔüÔý–Ðþ”Ñþ“Ñÿ’ÐÿÍü”Îü˜Ñþ£Ôü¨Øþ²àÿ³àý¹æý¾çý¿èüÁêÿÂëÿÂëÿÆìÿÃéþÂèýÀéÿ¾èÿ¾êÿ»éÿ¹çÿ±ßù®Ýù¨Ù÷´ãÿ»éÿ¾èÿ¿çÿÀæýÂèÿÀæýÀæýÁæÿÃîÿÃîÿÅîÿÄíÿÉíÿÎñÿÑòÿÖôþÛøþßûüÚùþ¸åú«Ýøœ×ÿ•ÓÿÌÿ–Îÿ™Íü¡Óø§ÙúµäÿÀêÿÌïÿÞùÿâùÿëÿþíÿþëÿÿåþÿÜúÿÔôÿÁåûÉìÿËîÿÈëÿÇêþÉìÿÉîÿÁêÿ·ãü»çÿÍîÿÕòÿçýÿíÿÿîþþíýýà÷ýÎñÿÃíÿ¥ÙþŸÖÿ—Ñÿ–Ðÿ•Ïý—Ðû—Ñùãÿ²æÿ²âÿ°Þÿ°Ýþ°Ýþ´ßÿ»äÿ¿çÿÅêýÌíþÓðøÛôùèýþïÿþôþýöüü÷ýýøÿþøÿÿöÿÿïÿÿèýÿÜõüØóüÏïüÐñÿËïÿÊíÿÈîÿ¶èÿßÿŸÔüžÕþ–Ðþ’Ïü‘Ïÿ‘ÏÿÍü•Ïý˜Ñþ Ôû¦Øý²àÿ³àýºçþ¾çý¿èüÅëÿÆìÿÇíÿÅëÿÅëÿÄêÿ¿èþ¿éÿÀìÿ¹çÿ¶äþ²áý±àþ¬Û÷¶ãÿ»éÿ½çÿ¿çÿÃéÿÃéþÃçýÄêÿÄêÿÀéû¿èúÃéüÂèûÇìÿÍðÿÎïÿÑòûÖôüÙöúÒóú²àø§Øø—Òþ‘ÏÿÌÿ–ÐÿšÐþŸÓú¤Ùû³âÿÀêÿÉìÿØôÿÞ÷üëÿþíÿþíÿÿçÿÿÝúÿÖôÿÄéüÉíÿÊîÿÆêÿÃçýÅéÿÆìÿ½åþ²Þù¹åÿÈëþÓðþåýÿìÿÿðÿÿïÿÿâùÿÍðÿÂêÿ¤ØýžÕþ”Îÿ‘ÍÿÍú“Îø–Ðø§Þÿ¬ãÿ¬àÿ«Ýÿ«Ûÿ¬Úü±Þÿ¹åÿ¾èÿÅéÿÊëüÕñüÞ÷þëÿÿðÿÿóÿýôýüõþýøÿÿøÿÿôÿÿïÿÿéþÿàùÿÜ÷þÕñÿÖóÿÍîÿÊëþËðÿ³åÿ¯áÿ§Üÿ¢Ùÿ”Îü‘ÎûÍþÍþ’Ïþ—Ñÿ™Òÿ Õý¥Ùÿ°áÿ³âÿ¼éÿÀéÿÃéþÆìÿÆìÿÇíÿÃéþÆìÿÅëÿÀéÿÂìÿ»çÿ¶ãÿ´ãÿ²ãÿ¯àþµäÿÂîÿÆòÿÁêÿÃéþÈíÿÉìÿÉíýÌðÿÊïÿÅèûÀãöÄèøÊîüÉë÷ÇéõÔôÿÔõþÕöÿÏïúÆêúªÜý Öü’ÒÿŒÐÿŽÑÿÎý•Îû›Ðú Õý¬Þÿ¹åÿÈíÿ×õÿÛ÷ûêþýëþüîÿÿëÿÿâùÿÛóýÈíÿÃéÿÁçþÀæýÁçþ¼äþ¸áý¬Øõ®Üý´âÿÁåûÌìûßúÿåýÿìþþîÿÿæýÿÏóÿÃìÿªÛûŸÕû“Ïÿ’ÎÿŽÌýËúÌø’Ïü–Ñý•Îù•ÎùŸÔþ¥Öþ«ÛÿµäÿºçÿÅëÿÈëþÚöÿäýÿîÿÿðÿýòÿÿóÿÿóÿÿôÿÿôÿÿñÿÿïÿÿéüÿâúþÝõùØòÿÖòÿÐíýÏîÿËîÿ¯áÿßÿ¦Ûÿ¡Øÿ”Îü’ÏüÍþÍþ“Ðÿ—Ñÿ—ÒþžÕþ¢×ÿßÿ±àþºæÿÀéÿÃéþÅëÿÅëÿÅëÿÅëÿÆìÿÅëÿ¿çÿ»çÿ¹åÿ·æÿ·æÿ³äÿ°áÿ³àýÀìÿÆðÿÃéþÄêýÊîþËïýËïûÏñýÍñýÍîÿÉèúÍíüÓóÿÎïøÊëôÙúÿÙúÿÙùÿÐðýÄéü¦ÚÿœÓúŽÐÿŠÐÿŠÐÿŽÍù’Íù™ÏûÒþ§Ûÿ³áûÅìý×õÿÙõùèüûëþüñÿÿíÿÿæûÿÞõýÉîÿÀæý½ãú¾æÿÀèÿ¹âþ²Þû©Ö÷«Ûÿ¯ßÿ¿åúÊëúÜùÿâùÿéýþìÿÿåþÿÐôÿÅîÿ¬Ýû Ôù’ÐÿÎÿÍýŠÊúˆÈøÍûÎýŽËøÌùšÓÿ¡Öþ¨Úÿ²ãÿ¹æÿÃéÿÈëÿÛ÷ÿåþÿîÿÿðÿýñÿÿðþþïÿþðÿÿðþþîþýìþþêþÿéþÿâúüÖñüÔðþÑîþÒñÿÉìÿ®àÿ¦Øû›Ðø›Òû•Ïý’ÏüÍþŽÌý“Ðÿ—Ñÿ–Ñý ×ÿ¤Ùÿßÿ¯àÿ¹çÿ½çý¿èüÄêýÄêýÅëÿÁçþ½æü¾çý¿çÿ¹ãü¹åÿºèÿ·æÿ²áý²áýÀêÿÇíÿÈîÿÄèøËìûØöÿÚøÿÙøýØ÷üÜûÿÜøÿÛ÷ÿÜøÿÚ÷ÿØõùÚùüØúüÙùÿØøÿÌíÿÁåÿ¢Öþ–ÌøŒÎþ‰Ïÿ†ÍûÏû‘Îú•ÎûšÐþ¡Öÿ¯ÞüÁêþÒòý×ôúêÿÿíÿÿõÿÿõÿÿðÿÿèùÿÌíþ¾çû½æü¿çÿ¾èÿµâÿ´áÿÛÿ¦Öþ¨Ùÿ¾æÿÈíýÙúÿÞùÿçüÿéþÿâûÿÒóÿÈîÿ¯ÞøŸÔô“ÑÿÍþ‘ÐÿŠÌÿ„ÇûˆËÿŽÐÿŽÐÿŒÎÿ“ÑÿšÓþ¢Øþßÿ³áÿ½åþÃèûÙõÿãüÿðÿÿóÿÿîÿÿìþþëÿþëÿþêþýéýþêÿÿêÿÿìÿÿçüýÓïúÒòÿÐôÿÏòÿÇíÿßÿ§ÙüœÑùšÑú’ÌúÍú‘Ïÿ‘Ïÿ’Ïþ•Ïý–Ïü ×ÿ¥Úÿßÿ°áÿ·åý»åû¾çýÀéÿÁêÿÂêÿ¿çÿ¼æþ»åý¸âú·áùºäü¹ãû¹ãû½çÿÀêÿËðÿÒóÿÍïûÍëõÖóûæÿÿåþÿáûüãýþãýþâûÿâúÿãüÿäýÿßûüÞúûØõùÚøÿÚ÷ÿËêþÄæÿ§ÙþžÓûÐþŒÐÿŠÐÿÏýÏû”Îü—ÏþŸÔÿ®ßÿÁëÿÌíüÖôþåýÿëÿÿñÿÿóÿÿðÿÿìûÿØõÿÈíÿÂèû¿èþÀêÿºæÿ´áÿ®ÜþªÚþÝÿ¾èÿÆìÿÓõÿ×õÿàùþãüÿÝøÿÓôÿÎôÿºæÿ«Üü–Óÿ“Ðý‘ÏÿÌÿ‹ÍÿÏÿŽÐÿŒÎÿŽÍÿ–Ôÿ×ÿ¢ØþªÛü°ßýºäúÁæùØóþâùÿïÿÿñÿýìþþèýþéþÿçÿÿåýÿÞöúßùúèÿÿçÿÿãûÿÕ÷ÿÍõÿÅïÿ¾éúµâù®àÿ¨ÚýžÓû›Òû’ÌúÌùÎÿÎÿ‘Îý”Îü•Îû¡Öÿ¦Úÿ®àÿ±âÿ¸æþ¹æý¼æþ¾èÿ¾èÿ¿éÿ¿éÿ»åþ¹ãü¸âú¹áú¼äý½æü¼åû¿èþÆìÿÕöÿ×ôÿÓñûÕð÷Þ÷üçÿÿçÿÿçüýæþþåýýâúþâùÿäûÿåýÿãüÿßûþÙöúÙ÷ÿÚøÿÏìüÉéþ¬Úû£Õú‘ÐüÏÿ‹ÏÿÏý‘Ðü“Îú”Ïû›ÑýªÛü¼æÿÊíÿÓóÿÞ÷üçüÿíÿÿñÿÿîþþìûþÜøÿÍîÿÆéüÂèýÀêÿ¾êÿ¸åÿ°Þÿ®Üþ±ßÿÀêÿÄíÿÎòÿÓóþÞùÿáýÿÜùÿÒóÿÏôÿÁëÿµäÿšÕÿ–Ñý‘ÏþÎÿ‘ÐÿÎÿÎÿŽÎþ‘Ïþš×ÿÔû¡Õú§Øø¬Û÷ºãùÄçûÙôÿãúÿïÿÿñÿýíÿÿçüýèýþèÿÿäüÿÜõúÛ÷úãüÿäýÿáúÿÕùÿÌöÿÀëû·ä÷°Þõ¨Úý¥×úžÓûœÓü–Ðþ–ÓÿÎÿÎÿ‘Îý”Îü•Îû¥Öþ©Ûÿ¯àÿ³âÿ¸æÿ»çÿ¹åþ¶âûµãýµãý·åÿµáüµáú¼æþÃéÿÃéþÈëþÇêýËìýÒòÿÜøÿßøÿâùÿèýÿêþÿíýýïÿþîþýïÿþìÿýéýüèýþéþÿçÿÿáøþÞ÷þÜ÷ÿÞùÿàûÿÚõþÒðûÀéÿ²ßü—Î÷ÌûÎÿ‘Ïÿ“Ðÿ—Òþ˜ÓýŸÖý¨Øü·àþÌðÿÔõÿÛöýãúÿëÿÿíÿÿíÿÿíÿÿäüÿÓñüÎîûÃæù¿åøÆðÿÅïÿ½éÿ·ãü¶âûµáú»åýÈïÿÑòÿÛ÷ÿÜùÿÚöÿÎïÿÊíÿÀèÿ¶ãÿ¡ÛÿžØþšÕÿ•Ïÿ“Ðÿ‘Îý•Ïÿ˜ÑþšÓþ Õý¢Öû¬Þÿ´ãÿ·åÿÃéþÏðÿÞùÿæýÿïÿÿðþþíÿÿëÿÿêÿÿâûÿÞùÿ×ôü×ôüÚ÷ÿÝøÿÛöÿÏóÿÇðÿ¿êý¸åú°Þö¨Úý¤ÖùÒú›Òû—Ñÿ˜ÕÿÎÿÎÿ’Ïþ•Ïý—Ðý¤Öû©Ùý±ßÿ³âþ¸æÿ»çÿ¸äý²àú²àú³àý²ßü´àûµáú¼æþÇíÿÉîÿÎïÿÏïþÓðþ×óÿáúÿåüÿéþÿîÿÿîÿÿñÿÿóÿÿòÿÿòÿÿòÿÿëÿýéÿýéþÿæþÿßöþÜòýÞöÿÜ÷ÿàûÿÞùÿØõýËðÿ¼æþœÑù“ÍûÍÿ’Îÿ•Ïÿ—ÒþšÕý¢Úÿ¬Üÿ¸áÿÊîÿÐñÿÙöþáúÿéþÿìÿÿîÿÿíÿÿæÿÿ×óþÕóþÅéùÂçùÇðÿÆðÿÀêÿ»åû¸âø±Ýø´àùÅëþÌðÿ×õÿÙõÿÙ÷ÿÏðÿÊíÿÀåÿ´àý¢Úÿ ØýœÕÿ–Îý•Ïý—Ïþ™Ñÿ Õÿ¡Öÿ£×ü§Ùú±âÿµãý¶âûÀæûÍîÿÝøÿåüÿðÿÿòÿÿìþþëÿÿæþÿÝùýÜ÷ÿÖôþÖôþÙõÿÛ÷ÿÚõÿÎñÿÇíÿÀéÿ½çÿ²Þùºçÿ³âÿ§Ùü Ôû›ÔÿžØÿ’Îÿ’Îÿ–ÐÿšÒÿÓÿ¥Õû¨Øü®ßÿ²áÿ¶åÿ¶åÿ´áþ¯Þü°ßý±âÿ°ßû»éÿ¼èÿÃéþÑôÿØ÷ÿÚöÿÛ÷ÿÞùÿß÷ÿéþÿêþÿëýÿíýýïýþôÿÿöÿÿõÿþôþÿ÷ÿÿòÿýïÿýïÿÿíÿÿãùÿàöÿÝõÿÔïøÙôûäÿÿàýÿÔöÿÊðÿ¬ÞÿžÔÿÌÿÍÿ‘Íÿ’Ïû•ÓüŸÙþ¨Úÿ°Ûý¿çÿÅêýÖöÿÙöþáúÿåýÿêÿÿêÿÿâûÿÙôýÚöÿÍíúÈéøÌïÿÌñÿÃéüÁêüÂëý±Ýö²Þù»äúÂèûÐñÿÕóþÚöÿÒòÿÍîÿ½âü°Ü÷¡×ûŸÕû¡Öþ Õÿ¡Öÿ¤Øÿ¤Õý¨ØüªÛü°ßýµâÿ½éÿ¾èÿÀéÿÎòÿÕõÿåüÿëþÿðÿÿñÿÿïÿÿáùûÞõûÛöÿ×óÿ×õÿ×õÿØùÿ×÷ÿÖóÿÇêþ¾âú¼âùÂçÿ¿çÿÍòÿÇíÿ³Üø«Øù¤Õÿ¢ÕÿšÏÿ›ÐÿœÔÿžÔÿÒþ£Ôü¥Öþ©Ûþ¬Ýþ°áÿ±âÿ³áÿ¬Ýþ«Ûÿ°Þÿ³àýÀêÿÅîÿÍñÿÔòýÜøÿÜôþÞ÷þäýÿäýÿçüÿëýÿìþÿðÿÿòÿÿõÿÿõÿÿöÿÿöÿÿõýÿöÿþòÿüðÿÿïÿÿçûÿáøÿÖñüÏëöÐîöÚûÿàÿÿ×õÿÊïÿ¬ÞÿÖÿŽÍÿŽÍÿÍÿÍüÏûØÿ£×þÛý¸äýÀêÿÍóÿÕ÷ÿßüÿâýÿçþÿçÿÿÞúþÝúÿÝúÿ×õÿÓñüÍíüËìýÃèûÄíÿÀëþ¶àöµß÷µâù»åýÌñÿÖøÿÚõüÙöþÕõÿ¼åûÛõ¡×ý£Ùÿ£×ü¨Úý¬Ýþ²áÿ¶ãÿ²àú°ÞøµáúÁçþÄêÿÊðÿÍòÿÕóýßúÿêüþðþÿòÿÿñÿÿæþþÛöýÖðýÓîÿÕðÿ×õýÙøûØûýÓõÿÍñÿ½ãú»äúÀæûÂèûÈíýÙ÷ÿÒòýÉìÿÈîÿ¹äÿ²Þÿ©Úÿ¦×ÿ¢Öþ¢Öþ¢Öþ ÕýŸÔü¡Õü£×ü¦Ûûßÿ®ßÿ§×û§×û²àÿ¼èÿÈñÿÐõÿ×÷ÿÜ÷ÿàùþàøüâúþéÿÿèÿÿèýÿêþÿêþÿíÿÿïÿÿòþþóÿÿõÿÿ÷ÿÿ÷ÿÿ÷ÿýõÿúôÿÿóÿÿìýÿéüÿÜóûÓîõÔïøÚ÷ýÜùÿÔòúÉíýªÜý›ÕýŠÉü†Èü‹Êÿ‘ÏÿÍü“ÐüžÕþ¢ÖûÜú³áû¿êýÇîÿÒôÿÕõÿØôÿÙôÿÚøÿÚ÷ýÜùÿáüÿáüÿÙ÷ÿÒòýÂæöÃìþÃîÿ¾èÿ·àü±Þû¸åÿÈñÿÏòÿÞùÿÖòþÎíÿ»åþ²áÿ¬Þÿ®àÿ±ßÿ¹åÿ¾èÿÄíÿÅîÿÃìÿÂëÿÂèûÈéüÊíÿÐóÿÕöÿÝúÿåýÿïýýóÿýôÿÿîÿÿäþûØõýÓîÿÐêÿÐìÿÙ÷ÿÚùüØüüÏóÿËîÿÆëþÇìþÍñÿÒôÿÛùÿßüÿÚøÿÐòþÎòÿÆïÿÁíÿ´âÿÞÿ¦Øû¤Öû¢ÖýŸÔþžÓýžÓûŸÕû¤ÙûªÜÿªÜý¤Ôø§Õù´áÿ¿éÿÌòÿÒ÷ÿÛùÿßøÿäüÿãûÿäüþçÿÿæÿÿéþÿêþÿëÿÿíÿÿïÿÿðþþòþþõÿÿ÷ÿÿ÷ÿÿöÿüöÿüöÿÿöÿÿðÿÿìþÿèûÿà÷ýà÷ýâûÿãüÿ×õýÉíý¨Úû™ÓûŠÉü†Èü‹Êÿ‘ÏÿÎý“ÐýœÕÿ Õý¨Ùú®Ýû¹æý¿èüÉîþÍñÿÐðýÒïý×õÿÚ÷ÿÝúÿäÿÿäÿÿÜùÿÖôþÃç÷ÅëÿÃìÿ¼åÿ´ßÿ±Þÿ¶ãÿÃëÿÊîÿÚ÷ÿÔñÿÈëÿ¸äÿ²áÿ°áÿ³áÿµâÿ¿éÿÄíÿÉïÿÊïÿËðÿÊïÿÇëûËìýÍîÿÐôÿÕ÷ÿÞúþéþÿñÿÿôÿþòÿÿíÿÿæÿýÚ÷ÿÕñÿÐêÿÏëÿ×õÿØ÷üÙûýÓõÿÎñÿÏðÿÐñÿÔôÿÙ÷ÿàûÿáùýäýÿäÿÿßþÿÖøÿÓùÿÅðÿ¾éü°Þö¬Ùø©ÚûžÔÿ›Ñý—Ðû™Óû ×þ Öü¡Õú¦Ôö«ØùºãÿÁçüÎòÿÖøÿÝúÿâúüäùúæûüèýþçÿÿçÿÿæþþéþÿêÿÿìÿÿîÿÿïÿþñÿÿôÿþõÿþôþýöÿüöÿü÷ÿÿ÷ÿÿöÿÿöÿÿõÿÿòÿÿñÿÿîþýêþÿÜúÿÌïÿ§Ùú›ÒûŽÍÿŒËÿŒÊýÍþÍþ“Ñÿ”Ñÿ™ÒÿžÓý¡ÕüªÛû¯Þú¹ãü½åþÃéþÇëÿÑîÿÙõÿÞúÿäÿÿâþÿÚøú×öûÉíûÄêÿ¿äÿ¯Úý®Úÿ²àÿ²àÿ¶âÿ½åÿÇëÿÅéÿ½äÿ´áÿ±ßÿ·ãü¼æÿ¿èþÈíÿÌðþÓóÿÕõÿ×øÿÖ÷ÿÔõþ×õÿÔôÿÔöÿÖöÿÜøüêÿÿðÿýòÿüðÿÿêÿÿèÿÿÝúÿØôÿÑíÿÐíÿÔôÿÕöÿ×øÿÒôÿÏðÿÐíûÒîùÙôûÞ÷þèýÿéýÿæûÿàøüßùúÚùû×ùûÎóûÈîû½æüºáþµâÿž×ÿ™Òý‘Îú’Ïû˜ÓÿžÕþŸÕûÛýµàÿ¿çÿÆêúÖ÷ÿÞüÿçÿÿêÿÿèüûêÿþêÿþæþþäþýâüýãýþåýÿéþÿêÿÿëýýëþüñÿýòÿþõÿýõÿþ÷ÿÿ÷ÿÿøþþøþþùÿÿûÿÿùÿÿùÿÿ÷ÿþñÿÿÖöÿËðÿßÿ¡Øÿ‘ÏÿŽÍÿŽÌÿ’ÐÿÏÿÏÿÍÿ”Ðÿ™Óÿ›Ôÿ Õý¦ÚÿÛýÜú³àý¸äÿËëÿÒïÿØôÿÞûÿàüÿÜúüÙøýËïýÄéÿ¼ãÿ²Þÿ«Ùý¬Úü±Þÿµáþ¶âý¶âû±Ýú°Ýü²ãÿ³âÿÃéþÇíÿÌðÿÒòÿÖôþÜùÿàýÿÝúÿÚ÷ýÛøþÖôüÓôýÓôýÖôüÜõùèýþíÿþîÿÿìÿÿæÿÿãÿÿÚ÷ýÔòüÍìþÌëÿÌìûÍíúÑñüÑñÿÐïÿØõÿÙõÿÚõþÝöýà÷ýáõþáõþßöüÞ÷ûÛ÷úÙöúÔõüÏñýÅéÿÁæÿ½æÿ¡Øÿ—Ðû‘ÎúÌùš×ÿ™ÒýŸÔü¯Üý·âÿÉïÿÊëüÙúÿßþÿèÿÿèýþêþýêÿþêÿþåýýâüýÜøûßûþãýþçÿÿêÿÿêþýíÿþñÿÿðÿýñÿýôþÿôþÿ÷ÿÿúÿÿüÿÿüÿÿüÿýûÿýûÿýõþùðþþÏïüÀåø¨Úû ×ÿÎÿÍÿÍÿŽÍÿŽÍÿÌÿŽÌÿ‘ÏÿšÔÿœÔÿÓÿŸÔþ¥×ü«Üý°Þÿ´áÿÁåÿÌëÿÒòÿÛúÿÜùýØ÷úÓôûÉíýÁæÿºáÿ¯ÝÿÝÿ°ßý²ßü³áû³áû°Þø®Ýù°ßý´åÿ¸çÿÄêÿÉîÿËïÿÔôÿÚøÿÜ÷þÞùÿÞúþÝùýÜùýÙøýÕöÿÔõþ×õýÝöûçüÿîÿÿíÿÿéÿÿâþÿÛùûÚøÿ×õÿÌíþËìÿÊëþÍîÿÔõÿ×÷ÿ×öÿÚúÿÛùÿÚøÿÙõÿÜôþÜóÿÝõÿÞöÿÞöÿÞ÷þÜ÷þÛ÷ÿÛ÷ÿÕôÿÐðÿÊïÿ®àÿ¢Øþ–ÑýÍú”Òÿ–Ñý™Ðù°Ýþ½æÿÍðÿÏðÿÛùÿÝúÿäýÿçüýéþÿéþÿçÿÿáýÿßûþÛøþÛøþÛøüáúþâûÿæûþèýþìÿþíÿþíÿþñÿÿóÿÿõÿÿ÷ÿÿûÿþûÿþûÿüûÿýøÿþôÿûîþýÓôÿÆëþªÜÿ ×ÿ“ÏÿÍÿ‘ÏÿŒËÿ‹ÊÿŒÎÿÎÿ’Îÿ–Ðÿ—Ñÿ™ÒÿžÔÿ£×ÿ¦ÚÿªÜý¬Þÿ¸áýÂæþÇìÿÐôÿÒôÿÏóÿÌñÿÃìÿ»æÿ·ãÿ²ãÿ²ãÿ·äÿ¸äý·åü¶æý¬âþªßþ«àÿ´åÿ¹çÿÁçþÄêÿËîÿÑñþÓñü×ôüÙöþÚ÷ýÚ÷ýÛøþØöþÔõþÓóþÖôÿÚõþáøþëÿÿêÿÿßüÿÓõþÕöÿÒòÿÒóÿÍòÿÉíÿÅéÿÆêÿÌïÿÑòÿÒòÿÏóÿÎòÿÓôÿÒóÿÔñÿÕñýÖòþÚõÿÛöÿÞöÿÞöÿÜ÷ÿÜøÿÙöÿÒñÿÌðÿ±âÿ¨Úý˜Ñü”Îü“Ñÿ˜ÒÿšÑú°Ýþ¼åÿÉìÿÏðÿÛ÷ÿÜùÿåþÿêÿÿéþÿçÿÿåþÿßüÿÝúþÚ÷ÿÙöþÙöüÜøüßøýâúþæûþëÿþìþþìÿýðÿÿñÿÿôÿÿõÿÿùÿÿùÿýùÿûøÿþöÿýðÿüìþþ×øÿÉïÿ©ÛþÔýÌþÍÿ‘ÏÿŠÉþ‡ÉýŠÌÿŽÎþ’Îÿ”Îþ•Ïÿ™ÒÿŸÕÿ£×ÿ¦Úÿ¨ÚýªÜý¶âý¾æÿÂëÿÊðÿÊïÿÈíÿÅëþ½çÿµâÿ³áÿ±áÿ²ãÿ¸äÿºäý¸åü¶åÿ¬ãÿ¨Þÿ©àÿ²ãÿ¸åÿ¾æÿÁêÿÊïÿÏðÿÐðýÔòü×óþ×ôü×õýØöþÖôüÒôþÒòÿÓóÿ×óþßøÿéÿÿæÿÿ×øÿËïûÎðüÎïþÍñÿÈîÿÄêÿÀèÿÃéÿÈìÿÏðÿÐðýÍñÿËðÿÏóÿÑòÿÐðÿÑóýÑóýÕõÿÙ÷ÿÛ÷ÿÜ÷ÿÝøÿÞùÿÝúÿ×ôüÑóÿ·ãþ¬ÛùšÏ÷•Ðü”ÒÿšÔÿŸÕÿµâÿÀéÿÌïÿÒóÿÛ÷ÿÚöÿàùÿãûÿåýÿâûÿÞùÿÙ÷ÿØöÿÕóþÖôÿ×õÿÙöþÛöÿÞ÷üáùýéþÿëþÿìþÿíÿÿîÿÿðÿÿñÿÿôþýõþýôÿûòÿÿñÿÿëÿþçÿÿÏóÿÂèý§×ûŸÔþ–ÐÿÌÿŽÊþŠÇý†Èü‡ÉýŽÌû–Ðþ–Ðþ–ÐþžÔÿ Õÿ£×ÿ¥Ùþ¥Úú©Üû°âýµãý¹åÿ¿èÿ¾èÿºãÿ·ãÿ²ßþ©Ûü©Ûþ¬Üÿ°Ýÿ¸áÿºáþ¹âþµäÿ¨àÿ Úÿ¡ÙþÛý°Ýü·ãÿ»äÿÂêÿÊïÿÌïÿÏïþÐðÿÐðýÑñþÓóÿÕõÿÓôÿÓôÿÓôÿØôÿÛöÿáüÿÜøÿÉïüÁçúÂåùÈíÿÇíÿ½çýºæÿ¹åÿºãÿ¿èþÌðþÏñûÍñÿËïÿÏðÿÐñÿÏîÿÑöþÒ÷ÿÔöÿÕõÿØôÿØôÿÜ÷ÿÞùÿßûÿÚøúÕöý¾èÿ°Ýú™Îö•Îù’Ðÿ—Ôÿ Öÿ´áÿ½æÿÉìÿÏðÿÙõÿØôÿÞ÷þà÷ýáøþÞ÷þÚõüÕóýÔòüÐðýÕòÿ×õÿÛøÿÜ÷ÿÝöûàùýçÿÿêÿÿëÿÿìÿÿìÿÿðÿÿñÿÿôþýôþýòþüñÿÿîÿÿêÿÿæÿÿÌðÿ½ãø¦Öú Õÿ™ÓÿËÿ‹ÇûŒÉÿŠÌÿ‰ËÿÎú™Òÿ™Òÿ˜ÑþžÔÿ Õÿ£×ÿ¥Ùþ§Ùú©Üû©Ü÷ßú²áýºæÿºåÿ´ßÿ²ßÿÛý¢×ù£Øú¦×ÿ«ØÿµÞþ·Þý·àÿ³áÿ¤Ûÿ›ÔÿœÓü§ÕùªÖù²ßþµáþ¼äþÆêÿËîÿÎïÿÏðÿÎïþÎïþÑòÿÒôÿÑòÿÏòÿÑòÿÖñÿÙóÿÞøÿÕóþÂéø½æú¾âøÂæüÂèÿ½çýºæÿµâÿµáþ¼åûËïýÏñûÎðüËìûÍíüÐðÿÓðÿÌíþÏðÿÒóÿÐñÿÊíÿÊîþÐñÿÕõÿÛùÿÚ÷ÿÙ÷ÿÅëÿ³ßøžÓõ˜ÒøÒý”Ôÿ—Öÿ©Þþ±âÿ¾èÿÂëÿÎñÿÕöÿÛùÿÛöýÝõÿÓïúÑïúËïýÉîþÍðÿÐñÿÒóÿÙõÿÜ÷ÿÝöýâùÿëÿÿëþÿìÿÿìÿÿìÿÿíÿÿíÿÿïÿÿðþþïýýñÿÿòÿÿïýýéýþÐñÿ¿åú¥×ú¡Øÿ–ÔÿËþŠÈûˆÇúŠÉþŽÐÿ’Ðÿ–Óÿ—Ôÿ˜Õÿœ×ÿ›Õû¤Úþ¨ÝÿÞÿ¬Ýþ§Ûÿ¥Ùÿ¥ÙÿªÜÿªÜÿªÚþ¨Úÿ¢ÖýÒúšÏù™Òý™Òý¢Öý©Ûÿ§Ûÿ¤Ùÿ˜Õÿ”Ñÿ–ÐþŸÔÿ¢Õÿ¦×ÿ¨Øü±Þý¿éÿÂëÿÌñÿÍñÿÎïþÎðüÏðÿÎïÿÌïÿÌðÿÎïÿÐíûÖôÿÐðÿÈëÿ´áþÞÿ¯Üû·ãÿ¸äÿµãý¶ãÿ°Ýú°Þø·ãüºçþ½çýÄçûÇçüÎïÿÎïÿÎïÿÂäýÁåýÁçþÂçÿ¾æÿ½åþºãùÁçüÐóÿÑòÿÌïÿ¾çÿ±Þý¡ÕúŸÖý™×ÿ—ÕþšÕý¥Úü¬ÝýµâÿÀêÿÅëÿÈíÿÒòÿÙõÿÓïûÏìúËìûÅêýÁçüÄéüÎïÿÓóÿÚöÿÚõþáøþæûÿìÿÿìþÿíÿÿìÿÿìÿÿíÿÿíÿÿïÿÿïÿÿðÿÿòÿÿóÿÿñÿÿíÿÿÝûÿÌñÿ¦×ø›Òù’ÐÿÎÿŽÌÿŠÉþŠÉþ‰ËÿÌÿÎÿÎýÏú•Ðø›Õû£Ùý§Üþ®Þÿ°Þÿ§Ûÿ ÕÿŸÔü£×ü¥Ùþ«ßÿªÞÿ£ØÿœÒþšÐþ“Ðý’Ïû˜ÒúžÓûŸÖÿœÕÿš×ÿ–Óÿ™ÒÿœÑûžÒú§×ÿªÚÿ³àÿÀèÿÂèÿÇìþÊíÿÌðÿËïÿÇêýÈëÿÉìÿÊïÿÌïÿÏñýÑñþÌíÿÄèÿ®Üþ£Ùÿ¦ØûÛý®ßÿ³áÿ²àÿ±àþ¯Þü±àü²áýµäÿ½æÿ»åþ¾èÿ¾èÿ»åþºßú·ßù¸áý»äÿ¹åÿ¸äÿ°ÜõµßøÃìÿÇíÿÄéÿ¶ãÿ®Üþ¢Öý Õý×ÿžØÿ£ØÿªÜÿÞÿ²ßü¹åþ¿èþÅëÿÐñÿØôÿÖòÿÎîýÊëüÂèý¾çýÅèûÏïüÖôÿÜ÷ÿÞ÷þåúÿèûÿíÿÿìþÿìþÿìþþëÿþìþþìþþîþþîþþðÿÿòÿÿóÿÿòÿÿîÿÿÝùÿÍðÿ©ÚúŸÕû“Ðÿ‘ÏÿÎÿŒËÿ‰ËÿˆÊþÌÿÎÿÎý‘Ðü—Òü›Õý£Ùÿ©Ûÿ°Þÿ±Ýÿ©Ýÿ ÕýŸÓú£×ü¥Úü¦Úÿ¦Úÿ ×þ›Ôÿ›Ôÿ‘ÎûÍú’Ìô—Ìô˜Ïö—Î÷›ÖÿšÕÿÓÿŸÓú¡Òú«Ùý¯ÛÿµáþÂçÿÁçþÆëþÈëÿÊíÿÊíÿÅéÿÅèþÅéÿÈìÿÉîÿÎïþÏðÿÉìÿÁçþªÛü Õý¡Õú¦Øû©Ûþ¯ßÿÞÿ¯àÿÞþ¯àÿ¯àÿ²àÿ¶åÿ³âÿ´ãÿ¶åÿ±àþ¬Úü¬Úü¬ÜÿÝÿ«ÝÿªÜÿ¤Öù£Õø¨Ùú¬Ýþ¬Üÿ£Öÿ¢Õÿ¥Öÿ¦×ÿªÚþ²àÿµáÿ·äÿ´áÿ¯ÜûÙö»ãýÄêÿÍðÿÐðÿ×ôÿÌíÿÄçû¾äû¿çÿÏïü×ôüÜ÷þåýÿéþÿìþÿìþÿïÿÿïÿÿîþþìþþìþþìþþìþþîþþîþþïÿÿðÿÿïÿÿðÿÿïÿÿåýÿÔôÿµâÿ©Ýÿ‘ÎûÍþÍÿ‹Íÿ‹Íÿ‰Ëÿ‹ÊýÍþ‘Ïþ”Óÿœ×ÿ Öÿ¥Ùÿ©Úÿ¯Üÿ±ÝÿªÚÿ¥×ü¤Öù¨Úû©Ûþ¨Úý¦ÚÿžÕü˜Ñü™ÔÿžÛÿÚÿŸÖÿ Öü¡Õú¡×ýŸÖý£Ûþ§Üþ²áÿµáþ¼ãÿ¿äÿÁåÿÇëÿÇêÿÉìÿÅéÿÆêÿÆìÿÁéÿÀåÿ¾æÿ¾èÿÀéÿÅëþÉîÿÃéÿºäý£×ü™ÒýšÑú›ÒûÔý¢×ÿ¢×ÿ¢Øþ¢Öý¨Üÿ¥Ùþ¥×ü£ÛÿžØýŸÙÿŸÙÿœÖü Ò÷£Õú¦Úÿ§Ûÿ¦Ûÿ¦Ûÿ ÕýŸÔüŸÕû¡×ý¢×ÿÓÿŸÕÿ¨Ùÿ¬Üÿ´áÿ½æÿ¾çÿ»çÿ¸äÿ´àý¬Øó¹áûÂèÿÊíÿÍîÿÐïÿÊëþÄçûÀæýÁéÿÐðûÛ÷ûâûÿêÿÿëÿÿîÿÿïÿÿðþÿðþÿïýþìÿýìÿýìþþìþþìþþìþþìþÿíÿÿìþÿíÿÿîÿÿæýÿØõÿ¶ãÿ¨Ýÿ‘ÎûÍþŽÍÿ‹ÍÿŠËÿˆËÿ‹ÊýÍü‘Ïþ“Òþœ×ÿ¡×ÿ¦ÚÿªÛÿ°Üÿ±ÛÿÛÿªÛü«Üý®ßÿ®ßÿ¬Þÿªßÿ ×þ˜Ñü™Ôÿ—Ôÿ—ÔÿœÓúžÒ÷ ÒõŸÔö¤Úþ©Þþ°áÿ»çÿ¿éÿÈêÿÇéÿÇêþÌïÿÌïÿÊíÿÇìÿÇíÿÄìÿ½çÿ½åÿ»åþ¹åþºæÿ¿èþÅëÿ¾æÿ¶âÿ¡Õü–Ñý•Îû–Ïü–ÏüšÐüÓÿŸÖÿŸÔþ£Øÿ Öü Ôû×ýšÖû›Öþ™Ôü–ÑùŸÔþŸÔþ ×ÿ¡ØÿŸÕÿÓÿšÓÿ™Òÿ—Ñÿ‘Îý’Ïþš×ÿ¡Ûÿ«Ýÿ´áÿÀæýÆëþÆëþÀæû¼åùºäü¾èÿÀéÿÅëÿÌïÿÍîÿÎíÿÍîÿÊíÿÈìÿÊîÿÖôüáúþåÿÿëÿÿìþþïÿþïÿþðþÿïýþîýÿìþþëÿþêþýëÿÿëÿÿêÿÿëÿÿëÿÿèýÿèüÿëÿÿàùÿ×ôÿ¹æÿ¦Úÿ‘ÎûÍÿŽÍÿ‰Êÿ†Éþ‰ÌÿŒÎÿÎý—Õÿ™×ÿ›Ôÿ¢ØÿªÛÿÝÿ®Úý³Þÿµàÿ·ãÿ¹åÿºæÿºæÿ´áþ³âÿ®àÿ£ÙÿÔû™ÓûŸÖýßÿ³áÿ±àü°ßû²ãÿ¶åÿ»èÿÊðÿÎóÿÔôÿÖôÿ×õÿÔôÿÒôþÊðýËðÿÄîÿ½êÿ´âü´àý±àþ®ßý®ßý±Þû¸äÿ³àý¯ÝþžÕþ’ÏüËý‘Íÿ‘ÍÿÌû‘Îý›ÕÿœÕÿœÕÿÔýŸÕÿœ×ÿœ×ÿšÕý™ÔüšÕý Õý Õý¢Ùÿ¤Ùÿ¡Øÿ Öÿ™Òÿ—Òþ•ÒÿÎÿ’Ðÿ™ÖÿžÙÿ©Ûü³àýÃéþÇëûÈìüÅêüÃêûÂëÿÁêÿÆêÿÉîÿÑòÿÐðÿÑñÿÐïÿÎïÿËîÿÌïÿÛøÿãüÿæÿÿêÿÿêþÿðÿÿðÿÿðÿÿñÿÿðÿÿìÿÿìÿÿìÿÿíÿÿëÿÿèÿÿæýÿãüÿáúÿáùÿãüÿÜõüÓóÿ»èÿ©Ýÿ”ÑÿÍÿŽÍÿ‡Èþ…Èý†ÉþŒÎÿÎý–Ôÿ˜Öÿ›ÔÿžÔÿ¨Ùÿ¯Ýÿ±Üü¶ßÿ»äÿ¾æÿ¿çÿ¿çÿ¾èÿºæÿ¹çÿ³äÿ«Ýÿ¦Úÿ¢Øü¦Ûý¶åÿºçÿ»çÿ¹åþ¸æÿ¹çþ¿êýÌñÿÒôÿÙ÷ÿØöþÙ÷ÿÖ÷þÓõþÏõÿÍôÿÃíÿ»éÿ²áû±Þý®ßÿ¬Þÿßÿ°ßý´ãÿ°ßý«ÜýÔý‘ÏþŽÌÿÎÿÍÿÍþ‘Íÿ–Ðÿ–Ðþ—Ðý—ÐûšÐüœÖþœÖþ›Õý™ÓûœÓü©Ûþ©Ûþ¬ÞÿßÿªÞÿ©ÝÿžÕþšÓþ•ÒÿÎÿ‘Ïÿ˜ÓýœÖþ§Ùú³âÿÆïÿÎóÿÐôÿÌòÿËñþÌñÿÌðÿÑñÿÔôÿÙöÿÚöÿÛ÷ÿÙõÿ×õÿÖôÿØõÿØôÿÞùÿáýÿçÿÿéþÿìÿÿìÿÿìÿÿíÿÿìÿÿêÿÿêÿÿéÿÿêÿÿäýÿàûÿ×ôüÑïúÔòýÖóÿÕóþÓïûÊíÿµæÿ¤Üÿ’ÐÿŠÉüŠÉþ‡Êÿ‡Êÿ‰ÌÿŒÎÿÎÿ”Òÿ–ÓÿšÓÿÔý§Ùü°ßý¸âû½åþÃéÿÄèþÆéýÆéüÆéüÆëþÅêý½æüµáü´àû¶äþºæÿÄíÿÉîÿÉîÿÇíÿÅîÿÅîÿÊïÿÔôÿØöÿÚ÷ýÚ÷ýØ÷üÓôûÐòûÊñÿÃìþµáú®Ý÷¦×÷¥Ö÷£×ü¢Úÿ£Ûÿ¦Ûý¨Úû§Ùü£×ü™ÒÿÎÿ‹Íÿ‹Íÿ‹ÍÿŽÍÿÎÿ”Ñÿ•Òÿ™ÔÿšÓþœÕÿÔýÔûŸÔüžÓû£×þ®ßÿ®ßÿ°áÿ±âÿ¯àÿ®Þÿ¤Øÿ Õý—ÒþÍü‘Îý™ÒýŸÖÿ©Ûþ³áÿÁëÿËñÿÍòÿËðÿÊïÿÌðþÐòþÖôÿØöÿÛ÷ÿÝøÿÜ÷ÿÜ÷ÿÚ÷ÿÙöþÛ÷ÿØôÿÛøÿßúÿäýÿæþÿêÿÿêÿÿêÿÿëÿÿêÿÿéÿÿèÿÿèÿÿèÿÿàûÿÝúÿÑïúËëøÏïüÓôÿÓõÿÌìùÄéüßÿ×ýÏÿˆÊþ‡Éý‡Êÿ‰Ìÿ‹ÎÿŒÎÿÐÿ“Ñÿ•ÒÿšÓþžÕü¨Ùú¯Þúºäú¿èüÈëÿÈëþËìýÍîÿÎïþÏðÿÍîÿÅêý¿åü¾ãý¼çúÀéûÉîþÎïþÏðÿÍñÿÊðÿÊïÿÌïÿÖóÿ×õÿØöþØöþ×õýÑñüÎðüÆíþÀéÿ²ßüÜú§Øù¤Öù Öü×ýŸÙÿ£Ûÿ¢Øü¢Öû Öü—ÑÿÎÿ‹ÍÿŠÍÿŠÍÿŒÎÿÏÿ‘Ïþ“Òþ–Óÿ™ÔþœÖþÔýŸÔþ¡Öÿ£×ÿªÛÿ¶âý¶âý¹åÿºæÿ¸äÿµâÿ«Üý¤Øý›Òû“Îú”ÎüœÒÿ¡Õÿ¥ÖÿªÚÿ²ßÿ¼åÿÂçÿÉíÿËðÿÓôÿÕóýÜ÷þÞùÿàùþãûÿáøþäûÿâûÿßøýßöü×õÿ×õÿ×õÿÛöýÞ÷üÞ÷ûßùúâüýåýÿçÿÿæÿÿåþÿàüÿßúÿÚ÷ÿ×õÿÌìùÄèøÇëûÏôÿÒõÿÎïÿÄíÿ«áÿœ×ÿ‹Íÿ‡Êÿ†Çý†ÉþˆËÿ‰ÌÿŒÎÿÐÿ‘Îý’Ïü›Ñý ÖüÞü¹çÿÆñÿÊñÿÏðÿÐïÿÒïÿÔòýÖòý×óþÖôþÔñÿÏïþÍîÿÌðþÍòû×õýÚ÷ÿÜùÿÛùÿÎòÿÌðÿÍîÿÒïýÓïûÔñÿÒòÿÒòÿÍîÿÈëÿ¼äý¹âþ°ÜÿÚÿ¨Ùÿ§ÛÿÔû–Ñû–ÔûŸÙÿŸ×ü ÕýžÕþ•ÒÿÏÿŒÍÿˆËÿ‰ÌÿÏÿŽÎþÎý’Ñý—ÕþšÕýœÖþžÔÿŸÕÿ£Øÿ¤ÙÿªÞÿ´áø¶ãú½çÿ¾æÿ¾æÿ½çÿµãý¬Ýý›Òû‘Ïÿ‘Íÿ™Òÿ›ÓÿšÓÿ›Ôÿ¢Ùÿ¨Úû¯ÞúºäúÃìþÍïû×ôúÝöúßøüäüþçùùëþüæøøåúýÞúÿÕõÿÅëþÆïÿÈñÿÈñÿÉïÿÊïÿËïÿÒòýØöÿÛøÿÕ÷ÿÒ÷ÿÍôÿÊñÿÈîÿÈîÿÅëÿÆéÿÇêþÏðÿÕòÿãüÿáýÿÆïÿµãý—ÏôÎúŽÌûŒËþÌÿŽÍÿÏÿÎÿ”Ñÿ•ÐüŸÕûÞÿ¿çÿÌïÿÝùÿáúÿæýÿæþÿæþÿèýÿèýÿçüÿæûÿâùÿàùÿÞùÿÞúþâþÿÝùýÚõü×÷ÿÔöÿËðÿÁêÿ¼æþ½çÿÀêÿÉïÿÉïÿÉíÿÂæÿ¾äû¾äù¼åû»åþ¸äÿ±ßÿ¬ÞÿœÔù’ÍùŽËø—Öÿ˜×ÿ™×ÿ—Õþ“Îú‘Ëû’ÐÿÎÿÌÿŒËþÌÿÍþÍü•Ðü™ÒýœÒþœÑûžÓý¡Õü£×þ®Þÿµâù·äû½çÿ¾æÿ¾æÿ¾èÿ¸æþ°âýŸÖý’Ðÿ‘Ïÿ•Îû—Ïþ—Ñÿ–ÓÿžØÿ¢Øú§Ú÷²ßö¾çùÍïûØõûÞ÷üáúþäüþçúøîþûèúúæûÿÚúÿÏòÿ»åý¼èÿ¼êÿ½éÿ¼èÿ¿éÿÁêþËïÿÒôÿÖôÿÍòÿÉòÿÃîÿÀêÿÀêÿÂëÿÄêÿÆéÿÊêÿÑðÿÖòÿæûþæÿÿÔøÿÅîÿ¥Ø÷–Ñù’ÏûŽÌýŽÌÿÎÿÏÿÎÿ”Ñþ–Ñý¡×ý®ßÿÃéÿÏðÿâúÿèûÿéþÿéÿýéÿýêþýêþýìÿÿìÿÿéþÿæþÿæýÿäüþçÿÿâûÿÝøÿÖöÿÒóÿÉîÿ½çÿ·ãþµâÿ¶äþ½çÿ½çÿÁèÿ¿çÿ½åþ»äø»äø¼æþ¹åþ´áÿàÿœÔù“ÍûËü’Òÿ–Öÿ™Øÿ˜×ÿ—Òþ•Ïÿ‘ÏÿÎÿÌÿŒËþŽÍÿŽÌÿÍþ”Îü—ÐýšÐüÒüžÓûŸÓú¤Öû¬Ýþµäÿ·äÿºæÿ¼åÿ¾æÿ¿çÿ¸æýµåü¦Üþ—Òþ”Îü–Ìú–Ïü˜ÑþšÓþžÕþ¦Ûý°áÿ¼éÿÃìÿÌðÿ×õÿÝúÿßüÿßûÿáùûéýþåúÿàøÿËîÿ¿äþ¦Õñ§ØöªÛù¯Þü±àü³ßø¹ãûÈîÿÍðÿÍîýÄçúÂçú¼âõ»áôÂçúÅêýÇêýÍîýÑñÿÙõÿÜôþçüýèÿÿãÿÿÙúÿµáú©Þÿ¡Øÿ’ÏþÎÿÎÿÎÿÎý”Ñþ˜Óÿ¥Ûÿ«Üý¾æÿÇêþÖòþàøÿêÿÿëÿÿìÿÿíÿÿíÿÿìþþìþþêþÿéþÿéþÿêÿÿèýþáùýßøýÕóýÐðûÅéù¾äû¼äýºäý·ãü³áû±Þû³Þþ¶áÿ¶âý·äû·äû·åÿµäÿ®àÿ«àÿšÔü’ÎÿŽÍÿ†Èü‡ÉûÐý‘Ñÿ“Ðÿ“ÏÿŽÍÿ‹ÍÿŠÌÿ‰ËÿŒÎÿŽÍÿŽÍÿ‘Îý•Îû—ÍûŸÕÿ ×ÿŸÔü¢ÖýÝÿ²ãÿ³äÿ·äÿ¸ãÿ¾æÿ¿çÿ»èý¹çþâÿ¡ØÿœÕÿšÐþ›ÑÿÓÿÓÿÔû¨Ýÿ±âÿ¿éÿÂëÿÍñÿÖöÿÝûÿÞüÿÜúÿßûÿåýÿàùÿÚöÿÃéþ¶ßû£Ôõ£Õø¥×ú©ÚûªÛû²ßü¸äýÉïÿÌñÿÉìÿÄåöÁä÷¿äöÀå÷ÉìÿÌðÿÎïþÔòýÙõÿÞùÿàùþéþÿçÿÿäÿÿÞüÿÁçü²ãÿ¨Üÿ“ÐýÏÿÏÿ‘Ïÿ‘Îý˜Òÿ™Ôþ¦Üÿ¬Þÿ½çÿÅéÿÒïýÚöÿæþÿêÿÿìÿÿíÿÿîÿÿðÿÿîÿÿîÿÿìÿÿìÿÿìÿÿçüýß÷ùßöüØõýÖôþÊëúÃèûÃéþ¾æÿ¼æÿ´ãý±àü°Ýþ³àÿ´áþ´âú´âú²áý®ßÿ¥Ùþ¦Üÿ™Òý‘ÏÿÎÿ†ÇýƒÆúŠÎýŽÐÿ‘Ïÿ‘ÎÿŠËÿ‰Ìÿ‡ÊÿˆËÿŠÍÿÏÿÎÿ’Ïþ•Ðü–ÏüÓÿŸÖÿ Õý£×ÿ®àÿ«àÿ«àÿ±ßÿ³àÿ¼äþ¿èþ½èù½èùµäþªÜý¥Ùþ¢×ÿ¡Öÿ£Øÿ¢×ÿ Ôû©Úû®Ûú´Þ÷·àöËîÿÑòÿÔõÿÑõÿÐôÿÙûÿÙùÿÐñÿÈëþ³àýªÛüŸÖÿÔýÔýŸÕû¢ÖûÛü´áÿÆîÿÉïÿÆêÿÈéúËëúÑñÿÓóÿÙ÷ÿÛùÿßüÿàùþäýÿéÿÿèÿÿèÿÿèÿÿçÿÿåþÿÒòÿÀêÿ¯àÿ•ÐúŽÎüÏÿÎý–ÐþœÕÿœÕÿ¥Ùÿ«ÝÿµáþºäüÇêþÍîÿÜ÷þäüþèýþìÿÿíÿÿíýüîþýïÿþïÿÿîþþðÿÿìÿýëÿÿçüÿÞ÷þÞùÿÚøÿÓôÿÍðÿÇìÿÅëÿ¸æý¶âû¶âÿ½æÿ¼èÿ·åü¸æý¶åÿ¯àÿ¢ÖûžÕü˜ÒÿÊÿŽÍÿ‰Êÿ…ÈýˆËÿˆËÿ‡ÈþˆÉÿ…ÈÿƒÈÿ‚Çþ„Éÿ‰ÌÿÏÿÏÿ‘Ïÿ”Ñþ–Ðþ™ÒÿœÕÿ¡Öÿ¤Øÿ¬Ýÿ¨ÞÿªÞÿ°Þÿ²ßÿ¼äþ¾çûÁëûÁëûºçþ®ßý«Ûÿ¥Ùÿ¤×ÿ§Ûÿ¦Úÿ¤ÖûÛü³ßüºâü»áøÉîÿËïÿÍñÿÊïÿÉðÿÓøÿÒöÿÈíÿÀæý«Üü¤ØýšÕÿ™ÔÿšÓþ¡Øÿ¤ÚÿªÛü³àÿÅïÿÉîÿÇëÿÍîÿÑñÿ×÷ÿÛøÿÞúÿßüÿãþÿâûÿæþÿêÿÿéÿÿæÿÿçÿÿåüÿáúÿÎîûÁëÿ²áÿ•ÐúŽÎüŒÐÿ‘Îý—ÑÿÖÿžÕþ¤Øÿ¬Þÿ´áþ»åþÉíÿÌïÿÙöþáúþåýÿëÿÿíÿÿîþýîþýñÿÿðÿÿðþÿîþýîþýðÿÿëÿÿÝôúÞ÷þÝùÿØøÿÓôÿÏðÿÍòÿ¾éü»åý¼ãÿÁéÿÁëÿ½êÿ¿ìÿ½ëÿ·æÿ¨ÚÿÔû™ÓÿŒÉÿŒËÿ‰Êÿ‹ÌÿŒÏÿ‹ÎÿˆËÿ‰Êÿ„Çþ‚ÇþÆýƒÈÿˆËÿŒÎÿÏÿÐÿ“Ðÿ–Ðþ›Ôÿž×ÿ£Øÿ¦Úÿ¬Ýÿ¡Öö¤Ùù°ÞÿµàÿÃéÿÇìþÑõÿÓ÷ÿÅïÿ»åþµàÿ§Ùþ¥×ü§ÙþÝÿ·åÿ·ãÿ»äÿÁçþ¿åüÄéüÉìÿÅëþ¾çû¿éÿÁëÿ¿éÿ´àù°Ýú£ÙÿšÓþ‘ÏÿÎÿ”Ñþ ×ÿªÞÿ¶äÿ¶ãÿÁéÿÆìÿÇëÿÒòÿÙöÿÚøÿÛ÷ÿãþÿãÿÿáúþæþÿëÿÿåúûãûýÚ÷ýÚ÷ÿÕñüÐîùÄçú½éÿ²ãÿ‘Ìø‡Çõ‹ÍÿÍü—ÐýŸÖÿ Õý¨Úÿ¯àÿ¼èÿ»åþÅëÿËïÿÓóÿÛøÿÜ÷þæþÿëþÿðÿÿïÿþïýýòþþóÿÿïýýïÿþðÿÿíÿÿäùþßöüÛöÿÚöÿØöÿÓóÿÒóÿÌñÿÊïÿÅéÿÊîÿÉîÿÊðÿÉïÿÁëÿ¹åÿ«Ùû¡×ý—Ðý“Íÿ’ÎÿÏÿ‘ÐÿÏÿŒÐÿ…Èÿ†ÈÿƒÆý…Êÿ‚Çþ‚Çþ…Èý‰Ëÿ‹Íÿ‘Ïÿ’Ïü•ÏýšÐüšÑú Õý¤Øÿ§Ùþ°âý±ãþ·ãþ¼äþÊëþÎîûÖ÷ÿÖ÷ÿÏóÿÇëÿÀçÿÞþ«Üü³áÿ¸åÿ¸äÿ¿éÿÁéÿÃéþÃéþÆëþÉìÿÁçþ»åýµãû²áû²àúªÛû¥ÚüšÕÿ”ÑÿŽÍÿŽÌý”Ñÿ¤Ùÿßÿ»çÿ¾èÿÄêÿÆëþÈëþÐòþÔôÿÚøÿÙ÷ÿÝùýàùþàøüäüþåýÿáùýÝøÿÑòÿÌíþ¿ä÷»áø³àý¬áÿ£Úÿ‘ÎûÍýŽÎþ”Ñÿ˜Ñþ¡Öÿ£×þ®Þÿ³áÿ¾çÿ¿çÿÇíÿÊîÿÎòÿÕõÿÕóýÛöýäüÿìþÿîþþðþþóÿÿôÿÿõÿÿóÿÿíÿÿêüþáöûÝõùÝöýÜ÷ÿÜøÿÙ÷ÿÖöÿÍñýÌðþËîÿËîÿÉîÿÅìýÃêûºäü´àû¬Úû¦Øû ÕýœÒÿšÒÿ™Óÿ—Ôÿ’ÑýÏý„Æú…ÆþŠËÿˆËÿ†Éþ…Èý‡ÊÿÏÿÎÿÍü”Ïû™ÒÿÒúžÔú¥Ùþ«Ýÿ±âÿ¹éÿ¹çÿ»åý¿åüÎíÿÔòýØöþ×õýÒóÿÊìÿÆëÿ²áÿ®Ýû³àý¶âý·áùÂëÿÆìÿÆêÿÆëþÇìÿÉìÿÁçþ¼æþµäþ¯áü¬Û÷¥×øŸÕù“ÐýÍþÎÿÍþ•ÏýŸÓú§×û»äÿÀèÿÉîÿÊîþÊëúÎðüÐòüÖ÷ÿ×õýÚöúÜøüàùýäýÿáúþßøýÛøÿËðÿÅéÿµßø°ÜùªÜÿ¥Üÿœ×ÿÎýÍþÏÿ”Ñÿ˜Ñþ Õÿ¢ÖýÞÿ³àÿ½çÿÀèÿÈìÿËîÿËïÿÒóÿÑñþÙôýâùÿêüÿíüÿñÿÿóÿÿôÿÿõÿÿòÿÿìþÿéûÿâ÷üß÷ûáúÿÞùÿÜøÿ×õÿÓóþÊðûÈîûËðÿÌðÿÍòÿÅëþÁêü¶âû±Þû«Ùû¨Úû§Ûÿ¥Øÿ¡ÖÿÓÿ×ÿ–Ñû‘ÎúˆÈøŠËÿŒÎÿ‹ÍÿŠÌÿˆÊþŠÌÿÏÿÏÿÍü–ÏüœÒÿ Öü£×üªÜÿ®ßÿ¶äÿ¼éü½êýÄêýÉìÿØõÿÝùÿÚ÷ûÙöüÏïþÅçÿÆëÿºéÿµãý°Üõ³à÷¼åûÄêýÊïÿÊïÿËðÿÆëýÈëÿÁçþÀêÿºéÿ³äÿ°áÿ§ÙüŸÕû‘ÏþÏÿŽÍÿ•Òÿ˜ÓÿœÎó¥Óô¼äýÇíÿÕöÿÔöÿÓóþÏôýÎôýÔ÷ýÓôûÖó÷Ú÷ûãÿÿâþÿáüÿÛöÿÓðþÁéÿ¸áý¥Ö÷ŸÓú˜Õÿ“Óÿ‘ÑÿŠÉüŠÉüŽÌûÍü—Ðý¡Öþ¤Øý±àþ¹åÿ¿çÿÅëÿÉìÿÊêÿÄëüËðÿÍñÿÙ÷ÿÞùÿåøþéûýðþÿñýýóÿÿóÿÿðÿÿëýÿêýÿêÿÿéÿÿâûÿÜ÷ÿÛ÷ÿÔòüÎîùÄîúÅìýÉïÿÂêÿÁëÿ¼éþºèÿ°ßû©Úú¥×ú«Üü°áÿ®ÞÿªÛÿ¥Ùÿ¢ØþœÖûšÖû‘Îû‘Ïÿ‘ÐÿÎÿÏÿ‰Èû‰ÈûÍÿÎÿ“Íû™Òÿ Öÿ§ÛÿªÜý¬Ýý¯Ýþµâÿ¿éùÃêûÊîüÏðÿÙõÿÜùÿÚ÷ÿØôÿËêüÀâûÂçÿ¾ìÿ¼èÿ·äû¹ãù¾çûÄêýÉïÿËðÿËñÿÆëþÆêÿ¾çýÁëÿ¼ëÿ·æÿ°áÿ¦ØûÓùÍúŽÎþŒËþ—ÔÿœÕÿŸÑô¨×õÀæýËîÿØøÿÙ÷ÿÚ÷ÿÖ÷þÓöüÕöýÓôûÕòøÚ÷ýàüÿÞúþâýÿÜøÿÏïþ¼åÿ³àÿ¢ÖûžÕþ™ØÿŽÐÿÏÿˆÇú‡ÆùËþÍü˜Ñþ¥ÚÿªÜÿ¶ãÿ¾çÿÃèÿÈìÿÉìÿÉêýÃéüÊïÿÍñÿÛùÿÞùÿãøûçûüïÿÿîþþðÿÿóÿÿñÿÿëýÿêüþêýÿêÿÿÞ÷þØôÿØôÿÒðûËíùÃíýÁêþÄîÿ¸äý¶âûµâùµãû¬Ýû§Ùú¤Øý«Üü±ßÿÝÿ«Ûÿ«Ûÿ¯ßÿ«àÿªÞÿœÒþ–Ðÿ“ÑÿÐÿÏÿˆÇú„ÆúÌÿÍþ”ÎüšÓþ¡×ÿªÞÿ¬ÞÿÞþ¯Þü¶âýÎêöÏëöÖó÷ÚöúÜ÷þÚ÷ÿÔóÿÍíÿÂçÿ½çÿ»èÿÂìÿÂêÿ½æü½æüÂëÿÆìÿÆïÿÃëÿÆîÿ¾èÿ·ãü·ãü¸æþ¹çÿ¶ãÿ´âÿ©Ýÿ£Ùÿ•Ðú’Íù‘Ëû—Ïþ™ÐùÛü¹åÿÏòÿÕõÿãûÿäûÿâõûàøüÞ÷ûÔïøÑëøÑíùÔðüÛøþÛøþÜùÿÖòþËìý²ãÿ«ÛÿŸÔþ›Ôÿ”ÓþŽÏù‹ÎùŒÌüÌÿÍÿ’Îÿ™Òÿ¤ØÿªÜÿ·ãÿ¿æÿÈìÿÌïÿÎïÿÌíþÆìÿËïÿÐòþÛøþáúþãù÷äú÷çýûæÿÿäÿÿëÿþìÿýìþþìþþçûüäùüßøÿÙ÷ÿØõÿÍîÿÇìÿ¿éÿ½æÿ´áÿ²áÿ³àý¶âý¸äÿ©Úú£Øø¦ÜÿÞÿ±ßÿ¯Ýþ³àÿ¶Ýú¾áýÌðÿÇìÿ²Ýý¤ØýžÕþ‘ÎûÍþ†Éý„ÇþŠÍÿ‹Îÿ‘Ïþ™ÓûŸÖýªàÿªßÿ±âÿ¶ãÿÀåÿÒðûÓñûÙøûÝúþÝúÿÜøÿÑðÿÅèþ¾æÿ»éÿ¹çÿÀêÿÁëÿ¿èþ¾çýÀæûÄêÿÅëÿ¿çÿÂêÿ»åþ±ßù±Þû²áý´ãÿ²àÿ°áÿ§Ûÿ¡Øÿ—Òü”Ïû’ÍùÔýŸÕû³àý¾èÿÎòÿÕõÿåþÿçþÿåøþäýÿàûÿÖòýÓïýÒïýÔòýÙ÷ÿÙ÷ÿÙ÷ÿÑîüÇèû°áÿ¨Øü›Ðü—Ðý‘ÐüŽÎúÍùŽÌûÍÿ‘Íÿ•ÏÿœÒþ§ØÿÝÿºæÿÁéÿÊïÿÏòÿÐñÿÏïþÅêüÊîüÐòüÝúþäþÿåûùæüùéÿýåÿÿâþÿéÿÿêÿÿëÿÿìÿÿèýÿäüÿÝøÿ×õÿÔñÿÌíþÇìþ¼æÿ¹âþ²ßþ³àÿµáþºäý¼æÿ¯Þü¨Ûú©Þÿ¯Ýþ´ãÿ²ßþµâÿ½åþÄèþÐóÿÎòÿ¿éÿÞÿ¡Øÿ‘ÎûÎýˆËÿ„Çþ‡ÊÿˆËÿÎÿšÓþŸÖÿªàÿªßÿ´ãÿ¹åÿÄèÿÙ÷ÿÚøÿâÿÿäÿÿàÿÿÞüÿÊíÿ¿åü±Ýø³âü´ãý²Þù¸áýÀèÿÁêÿÁçüÆëþÃéþ½âüºßù¯Ûø©Úû¥×ü¥×ü§Ùþ¥ÙþŸÕû›ÕýšÕÿ™Öÿ™Öÿ©ßÿ´åÿ¶åÿ¾èþÄëüÌîøÒóúâþÿäÿÿåþÿÝûÿÙùÿÓóÿÑðÿÓòÿÓóÿ×øÿØùÿÖöÿÍìþÄçûªÜ÷¢ÔõšÏû™Ñÿ™Öÿ”Óÿ•Òþ—Òü—Òü›ÑýŸÔü¤Øý¯Ýþ´áþÁêÿËïÿÓôÿ×÷ÿÖôÿÓñüÌìùÍíøÓñûãüÿçÿÿêÿþêÿþçÿÿáúþÛ÷ûÛøÿÚ÷ÿÚ÷ÿÛöýÚõüÙôýÙõÿÔòýÏïüÌíüËïÿÀéÿºäý´àû·áú·áùÂèÿÅëÿºæÿ´áþ¯àÿ°ßû´ãýµãý¹æýÊïÿÒóÿØöÿÕõÿÏõÿ½êÿáÿ“ÎúŽÍùŒÎÿŠÍÿ„Çþ†ÉþÎÿ™Ôÿž×ÿ§Ýÿ©Ûüµâÿ½çÿÎîÿÙöþÚ÷ýâþÿåÿÿäÿÿáÿÿÍîÿÄèþ²Þ÷²âù´ãý±Ýú¶ßûÀèÿÅëÿÆëþÈíÿÆêÿ¾äûºßù®Ú÷©Ùÿ¡Õý Ôû ÔûŸÔüžÕü›ÖÿšÕÿ—Ôÿ—Öÿâÿºéÿ¼êÿÄíÿÊïÿÒôýÕöýÞûÿÞûÿÝúÿÕõÿÓóÿÐïÿÑðÿÒñÿÒòÿ×÷ÿØùÿÖöÿÎíÿÅêý¬Þ÷¤×öœÑýÓÿœÖÿšÔÿ›ÖÿžØþ ×þ¢Øþ¥Úü¬Ýý³àýºäýÄéüËîÿÔôÿÙ÷ÿÚøÿÙõÿÔòýÓïúÖóûäýÿèÿÿéÿýçÿÿæÿÿàüÿÞùÿ×õÿÔôÿÓóþÕóýÔòüÔðûÖòýÓñüÑñþÐñÿÐñÿÆìÿ¾æÿ¹ãü¹ãû¹âøÆëþÊíÿÁéÿ¸äý±àþ°ßû±àüµãý¹æýËðÿÖöÿÛøÿÚ÷ÿÖøÿÅðÿ³åÿ”ÏùÊ÷ŠÌÿ‹Ìÿ„Çþ†ÉþÍý–Óÿœ×ÿ¥Ûÿ§Ùú´áþ¾æÿÐðÿçÿÿçÿÿêÿþëÿþçÿýåÿÿ×õÿÏîÿÄêÿ¼éüºéý¹åÿ¹ãüÃéþÉîÿÐñÿÔõÿÔõÿÎñÿÇëÿ¼åÿ²âÿ¥Úÿ¢×ÿžÓý›ÒûŸÖÿ Úÿœ×ÿ—Òú›Ùÿ²áÿ¿çÿÀéÿÊîþÐñÿÕõÿÔôÿÎïþËìýÉìÿËïÿÊîþÍíÿÏïÿÐìÿÏìü×õÿØöÿ×ôÿÑðÿÊïÿ¶êÿàýÒþšÎþ“ËþŸÕÿ¢Ùÿ«àÿ°ãÿ¶åÿ¸æþÀêÿÆìÿÉìÿÎîùÔòýÙôýÚõüÜøüÞ÷üåþÿßøýáùýèÿÿëÿÿèÿÿæÿÿàüÿÛøÿÚöÿÏôÿÍôÿËðÿÌðÿÌîúÌì÷ÏíøÓñüÖöÿØøÿÕõÿÊíÿÄéüÁçþÀæû¿ä÷ÌíÿÏðÿÇëÿ¾æÿ±Þû°ßýªØù´áþ¸äýÊîþÕóþàùÿáúÿÚ÷ÿÈíÿ¸çÿ—ÑùÊö†Åø„Åû‚ÇþƒÈÿ‡ÉûÍü•Òÿ¡×ý¤Öù±Þû½åþÒñÿèüýìÿÿíÿüíÿúìÿüêþüâûÿÚöÿÍîýÉðÿÈòÿ½çÿ½åþÈëþÎïþÖôÿÙ÷ÿÚ÷ÿÔóÿÍîÿ¿äþ±Ýÿ§Ùþ¦Øý¨Ùÿ¨Üÿ§Ûÿ¥Ûÿ£Ùý¡Öø¢×ù´ÜöÆéÿÈëÿÐïÿÒòÿÔóÿÐñÿÃèÿ½äÿ±Þÿ´Þö¸á÷ÄêÿÉíÿÏîÿÏîÿÔòýÖôÿÕòÿÍìÿËïÿ¶êÿ©ÞýœÑû˜ÌûšÎþ¥Ùÿ¬Þÿ¶äüºçþÅîÿËñÿÍñÿÒòÿ×õÿÜ÷þÝöûäüÿåýÿæþÿêÿÿêÿÿéþÿéþÿçÿÿèÿÿâûÿâþÿØöþÏïüÌìûÄêýÁìÿÆíþÈíÿÍïûÎîùÒðúÕóû×óþÚöÿÚøÿÓóÿÍîÿÆëýÎñÿÑõÿÓóÿÒñÿÊíÿÁçþ°ÝüªÚþ§×ÿ°Þÿ¶áÿÊíÿÓðÿÝõÿß÷ÿÚöÿÆëþ²áýœÓú–ÑûŽÎþŒÎÿƒÈÿ„ÉÿŠÍÿÐÿ’ÐÿœÓü Ôù´áÿ¾èÿÐñÿèûÿëÿÿëÿûëþøìÿûêþüåüÿÝøÿÐðÿÌðþÊñÿ½çÿÁçüÍîýÓóþÛøÿÞùÿßúÿÙöÿÒòÿÄèþ´Ýû¬Úû¬Úû¯àÿ²ãÿ¯àÿ¯àÿ®ßÿ®Ýû®Ýû½áùÏïÿÔóÿØõÿØõÿÔóÿÎñÿ¿èÿ¶ãÿ§Øÿ©ØöÛõºãÿÀçÿËíÿÌïÿÏïþÎïþÍîÿÆéÿÅêÿ±äÿ©ÞþœÑû˜ÍùÐýªÜÿ°Þÿºäü¿èüËðÿÍñÿÑñüØôÿÛöýáùýãûÿèýÿéþÿéþÿëÿÿíÿÿéýþæûüæþÿèÿÿÝøÿÝúÿÑñüÇëûÅèûÁçü¾çûÂéúÈíÿÐòþÑñüØõýØõûÙôýÜ÷ÿÜùÿØöÿÓóÿÍñÿÑõÿÓ÷ÿÓóÿÒñÿÈìÿÀèÿ¯Þü¬Þÿ¥ÖÿÝÿµâÿÇëÿÐïÿÛóÿÝõÿÚöÿÃèû¯ÞúÓù™ÓûÐþŽÐÿ„Éÿ…ÊÿŠÍÿÏÿ’Ðÿ—ÐûžÔúµãÿ¼èÿÎñÿÛöÿàûÿåÿÿåýýêÿÿéÿÿáùÿÜöÿÑðÿËïÿÊïÿÆìÿÉîÿØöÿÝúÿåýÿêÿÿëÿÿáüÿÚ÷ÿÎîûÅèû¿åü¼åû¾æÿ¾èÿÁéÿÃëÿÇíÿÊîÿÈìÿËìýÖóÿ×ôÿØôÿÖôÿÍðÿÅëÿ¯Ýþ¦Úÿ™Óÿ–Ñù—Óø¡Öþ¨Ùÿ¶ãÿºæÿ½çÿ½êÿ»çÿ´áÿ°Þÿ§Üü§Ûÿ¤×ÿ¢Õÿ«Ýÿ²áý·äûÃéüÈëÿÏîÿØôÿÝøÿåüÿéþÿìÿÿëÿÿìþþìþþìþþìþÿîÿÿêþÿçüýáúþÝùýØöÿÔôÿÈíý½ãø¼âùÀæûÀåøÆéüÎïþÚøÿÜøÿÜ÷þàùýàùþÝöûÛôùÜ÷þÚøÿÔöÿÏðÿÎïþÏïþÊëü½ãú·ãü¬Ýþ¨Üÿ¥Úÿ¨Úÿ¬ÝýÄêÿÈëþÕóþÙ÷ÿÖöÿÀæù³áû¤ØýŸÖýÎý‹ÍÿÆÿ‚Çÿ…Èÿ‰ËÿŒËþ”ÎüšÓþ±ãÿ·æÿÈîÿÖôÿÜúÿáþÿáýÿåþÿåþÿÝ÷ÿÙôÿÐñÿËîÿÉîÿËðÿÏóÿÝûÿãÿÿêÿþëÿþëÿÿãüÿÜ÷þÔòýÐðÿÈëþÆëýÆëþÅëÿÉíÿÍðÿÎñÿÏðÿÏîÿÑñþ×õÿÖôþ×óþÔòüÈìü½æú§Øù¡×ý–ÓÿÐüÐü•ÒþÓÿªÛÿÞÿ®Ýù°âý°áÿßÿ©Ûÿ¥Úü¥Ùÿ¥Ùÿ¤Øÿ¬Ýþ³áùºäúÅêüËìÿÐíÿÚõÿáúÿéþÿìÿÿíÿÿíÿÿíýýíýýïÿÿíÿÿíÿÿìÿÿéþÿàùýÚõüÕõÿÒôÿÈïÿ¼åûºâûÂæüÃèúËìýÐðýÛ÷ÿÞùÿâûÿæÿÿæÿÿáúþßøüÜøüÛøÿÔôÿÌíüÊëúÍîÿÈéü¸àù·ãþ«Ýþ¦Úÿ¦Ûÿ¥Úü©Úú¿èþÆêúÕõÿØùÿÕ÷ÿÀêú´âü¥Úü Øý‘ÏþÏÿÆÿ€ÅþÆý‡Èþ‹Êÿ‘Îý–Ñý§ÛÿÞþ¿éÿÇêýÏóÿÖøÿÔõþÑòûÑñüÑðÿÎïÿÈìÿÄêÿÄêýÊîúÐòüàüÿçÿÿìÿüíÿüìÿþéþÿçÿÿãÿÿÚ÷ýÖôþÔôÿÔöÿÔõÿÍîÿÖöÿ×÷ÿØôÿÛõÿÜùÿßüÿÞûÿÛùÿÖôþ¾ãõ´Þô¢×÷×ý‘Ñÿ‡Íÿ‡Íÿ‹ÍÿÎÿ˜Òÿ›ÔÿšÒ÷˜Ðõ™Ð÷Öÿ›Ôÿ ÔûŸÓú©Ýÿ®àÿµäÿ½çý¾çùÊëüÏîÿØóÿÜ÷ÿäüÿíÿÿîÿÿïÿþñÿÿîüýïýþòÿÿòÿÿñÿÿíÿÿêþÿâùÿÝøÿÑñüÎïþÍòÿÄêÿÀéÿÊíÿÐñÿ×÷ÿØöÿÞùÿâþÿãüÿåÿÿçÿÿéþÿéþÿÝöûÛöýÔôÿÌíþÊëüËïÿÊíÿ¾æÿ»çÿªÛü§Üþ¡×û§ÜüªÝúµàóÁæöØùÿÛüÿÕ÷ÿÅïý¼éÿßÿ£Ûÿ‘ÑÿŽÐÿƒÈÿ‚Çÿ„ÇþˆÊþŒËÿ’ÐÿÍú˜ÏöŸÔö²àúÃèûËðÿÐôÿÍñÿÎòþËñüÅêúÅêüÂèû¿èüÆìÿÑñü×õÿãÿÿéÿÿêþýîÿÿîÿÿìÿÿêÿÿåÿþÞ÷ûÚõüØõýÔôÿÔõÿÔõÿÕõÿÖöÿÙ÷ÿÛøÿàûÿßúÿÝúÿÚøÿÒóÿ·ßø®Ûø¢Øþ›ÔÿÌÿ‡ÉýˆÊþÎÿ’Ðÿ”Îþ”Îü–Ïú–Ïú–Ïú™ÔÿœÕÿ Öü¡×ý©Þÿ¯âÿºèÿÁçüÅêüÎîûÑîüØôÿÛöýçÿÿíÿÿñÿÿñÿýõÿÿîüüïýýóÿÿðÿÿðÿÿíÿÿëÿÿäøÿßõÿÚôÿÖòÿÎïþÅéùÆìùÎðüÔòýÜùÿÞúýàúûÞúûåÿÿâþÿæÿÿíÿÿêþÿÜ÷þÛ÷ÿ×ôÿÈéüÂãöÌðÿÊïÿÃìÿÁëÿ¶âÿ¯Ýÿ«Ýÿ§ÙüªÛü´ÞöÀåøØöÿßûÿÝûÿÌîúÄêÿ«ÜüÓ÷ÏÿŒÏÿ…Êÿ‚Çþ…ÇûÎÿÎÿËý”Ìý›ÒûŸÓúÞþ¼áü¼äý¿èþÃéþÁêü½æø¹âô·àô½æü¾æÿÁçþÎðüÑóÿÒîùÔïøà÷ýçüÿèýÿæþþçÿÿâþÿÝùý×óþÔòýÑòÿÑôÿÊíÿÍîÿÐðÿ×õÿÛøÿßøýÛöýØõýÑñþÉêûÀêÿ²ßÿ™Ðù•ÏýŠÌÿ‡Èþ‰ËÿÌÿÌÿ’Îÿ•Òÿ—Ñÿ”Íú”Íø˜Ñü›Õý Öú¤Øý®àÿ²ãÿ¼æÿÂçúÅèûÎîûÏïúÙõÿÞùÿçÿÿíÿÿðÿÿñÿÿðÿüïýýïýýïþÿíÿÿëÿþëÿþêþÿèûÿæúÿá÷ÿÜ÷ÿØöÿÐòüÎòþ×÷ÿÚøÿÛ÷úÝ÷øàúûßûüáþÿãÿÿæÿÿëýýæúûàûÿÞùÿØóÿÌëýÈéúÌðþÌòÿÉðÿÉïÿÀèÿ¶ãÿ®ßÿ¥Ö÷¨×õ·á÷ÈíÿÝúÿâþÿãÿÿØöÿÎóÿ®ÜýÓù‹ÍÿˆÍÿ…Êÿ‚ÇþƒÅùŒËþŽÍÿ‘Ïÿ“Ñÿ™Ôþ›Õý¦Üÿ¬×ù¯Úüµàÿ¶ßý·àüºãÿ¹ãü·ßù¾åÿÄéÿÂçÿÁçúÅêýËîÿÏðÿÏïü×õÿÙõÿÝúÿáþÿâÿÿ×÷ÿÍñÿÈëþÂèýÃéÿÈîÿÊíÿÌíÿÓðþÖòýÞ÷þÜ÷þÙöþÓóþÌíþ»åþ³áÿ›ÒûÌù†ÉþƒÈÿ†Éÿ…Èý†ÈüŽÍÿ“Ñÿ•Ïý›ÔÿžÔÿŸÖÿ¡×ý§Ùú«Ýþµäÿ¸åÿ¼æþÄêýÇêýÏðÿÐòþÛùÿàûÿåýÿíÿÿîÿÿðÿÿðÿüðÿÿðÿÿìþÿìþÿêýÿéþÿéþÿèýþèýþçÿÿäýÿÙöüÖöÿ×ùÿØöÿÜùÿãüÿäüþâüýàüÿÙøýßüÿäýÿåùúäøùÞ÷ûÝöý×ñþÔðþÓñüÒôþÐõþËðÿÊïÿ¾æÿ·åÿ«Üú©Úø¯ÞøÉòÿÑõÿâþÿæÿÿçÿÿÛùÿÍóÿ¥×ü—Î÷„Åû‚Äþ‚ÄþƒÆý‹ÊÿÎÿÏÿÑÿ‘Ôÿ”Õÿ”Óü×ý¦Òõ©Õø°Ûý¯Úü³Üü¸áÿ½æÿ½äÿ½äÿÄèÿÄéÿ¾çý½æüÄêÿÉíÿÍðÿÒóÿÓóÿÔôÿ×÷ÿØøÿÕöÿËðÿÅëÿ¾æÿ½åþÀèÿÆêÿÉìÿÒòÿÖôÿØóúÛöýÛöýÖöÿÐñÿ¼äþ·äÿœÖþÍú†Éþ„ÉÿƒÈÿƒÆý†ÇýŽÍÿÐÿ“ÐýÖÿ ×ÿ£Øÿ¥Ùþ¬Ýý¯àÿ¸åÿºæÿ¾æÿÅëþÇìÿÏðÿÐñÿÛùÿßúÿäüÿìÿÿìÿÿñÿÿñÿýðÿÿðÿÿìÿÿëþÿëÿÿêÿÿéþÿêÿþêÿþèÿÿåÿþÙõùÚøÿÙùÿØôÿÜ÷þåþÿæþÿáûüÝùüØöþÛùÿßûÿáôøáõöß÷ùßöüÛóÿØôÿØöÿÖøÿÕ÷ÿÌòÿÊïÿ½åþ°Ýú¨Ûø¯àþ´ãýÈòÿ×ùÿæÿÿéÿÿçÿÿ×øÿÄìÿžÒù“Ì÷„ÅûÃýÃýƒÆýŒËÿÏÿÏÿÒÿÔÿ”Õÿ”Óü›Õý±ßÿ®Üý³áÿ¸åÿºæÿ¼èÿÂìÿÅíÿ»àúÁæÿÂêÿ»çÿ½éÿºæÿ¸äÿ»çÿÁëÿÃèÿÄèþÇìÿÊïÿÈîÿÂêÿ½çÿ·ãÿµáþ¹âÿÀèÿÆìÿÐñÿÓóÿÔñùÛöýÞùÿâþÿÛûÿËðÿÁíÿŸÖý“Ðý‰Ìÿ‡ÌÿƒÈÿ‚Èü‰ÌÿÎÿŽÎþ–ÓÿœÓüžÓû§Ûÿßÿµâÿ¶ãÿºæÿ¾èÿÀéÿÅëþÆëýÍîÿÍîÿÖöÿÝøÿáùýëÿÿêþýñÿÿòÿÿíýýìþÿëÿÿèýÿÞöÿÞ÷þÞ÷ûâûøãüøåÿûæÿýÞúýÞúÿÚøÿÙõÿÝøÿãüÿâùÿÜõúØóúÍíøÓóþÚöÿà÷ýåúýäùúâúþÞöÿÚöÿÚøÿ×ùÿÓøÿËðÿÇíÿºãÿ²àÿžÐó¨Úû°ÞÿÅîÿÎòÿáüÿâýÿÛöÿÄèø³ßü–Ëõ“ÍûŠÍÿ†Ëÿ‡ÉÿˆÉÿˆÇü‹ÉüŽÍÿ”Óÿ•Õÿ˜Õÿ˜ÓÿŸÔü¹æÿºçÿºèÿ¼èÿÁëÿÃíÿÀèÿÀæýÁåûÇìÿÈîÿ¾èÿ»çÿ¹åÿ¶ãÿ±Þý¶ãÿ¼åÿ»ãü»äúÃéþÁêÿ¾èÿ¹åÿ±Þý¯Üû´ßÿÂêÿÅêÿÏðÿÐïÿÏìôÚõüÝøÿÞúÿÛøÿÒöÿÇðÿ£Ùÿ“Îú‰Ëÿ†Éÿ†ÉþˆËÿ‹Îÿ‘Ðÿ‘Ñÿ–ÓÿÔý Öü«Ýÿ®ßÿ¶âý¸äÿ¾èÿ½çÿÁêÿÉîÿËîÿÌíþÌíþÏïúÙôýãûÿëÿÿìÿÿñÿÿñÿÿìüüîÿÿçüÿâöýÜ÷ÿØóüÙõùÞø÷ãþùæÿüæÿýàüÿÜøÿÖôÿÑíøÖñúâûÿãúÿ×òûÒîùÍïûÏñý×õÿßøÿß÷ûæûüãûÿß÷ÿ×óþÕóýÔöÿÒ÷ÿÇîÿÀéÿ¸ãÿ«Ûÿ¤Øÿ¥×üªÚþ»ãýÅèþÖòÿÛ÷ÿÖóÿÂæü°Ýþ—Íû‘Íÿ‹Íÿ„Éÿ…Çÿ‡ÈÿÊÿÎÿÎÿ’Îÿ–Ïÿ™ÑÿœÒþªÜÿÅðÿÈóÿÉòÿÅîÿÄêýÅëþÈíÿÇìüÆêøÈìøÉíûÅëÿ¿èþ¶âý³âÿ¬Þÿ©Ûþ«Üý®Ûø±Ýø¼æþ½åþ¾èÿ¼èÿµâÿ®Üý°Ýüºãÿ½åÿÆêÿÊíÿÖôþÛøÿÛøÿÜ÷ÿÙõÿÍîÿÄèÿ©ÙýŸÔþ‘ÏÿÏÿŽÎþÌÿÎÿÐÿÏÿšÕÿŸÖý£×üÞÿ¯Þü´àû¸âû¾æÿ¾æÿÅëÿÉîÿÊíÿÍìþÎîýÔòýÚõüäüþêþÿêþýîþýñÿÿìþÿëþÿäøÿßöþÓóÿÏïüÏðùÓðô×õ÷âþÿåÿÿßüÿÕòúÑïùÒðúÖóûßúÿßúÿÕñÿÎîýÇìÿÉîÿÎòÿÚøÿÛøÿàùþß÷ÿÙõÿÔôÿÒôÿÊðýÅïý¿éÿ¸äÿ«Øÿ¥Øÿ¡×ÿ Õÿ£×ÿ±Üþ¸ßüÄæÿÇéÿÁæÿ®Ûü¥Öþ•Ïý‘ÏÿŠÌÿ‡ÌÿŠËÿŠËÿŽÌýŽÌýŽÎþ–ËÿšÌÿ¢Òÿ©ÖÿºåÿÊòþÍõÿÏôÿÊïÿÇêýÈëþËïÿÊîüÌîúÍïùÍïùÈíÿÁçú´àù°ßýªÜÿ£×ü¥×ú©Øö®Ûø¹åþ½æü¾æÿ½çÿ·äÿ¯Ýþ±Þý¶âÿºäýÄêÿÉîÿÓóþÛøÿÚ÷ÿÛöÿØóþÌëýÃæü¬Ùú¤Õý˜Òÿ‘ÎýÍúÍü‘Ïþ“Ñÿ“Ñÿ™Ôÿ Õý£×ü¯Ýÿ¯Þü¶âýºãÿ¿çÿ¿èþÆìÿÊíÿÍîÿÎîýÏïüÖôþÚöúåúýêþÿëÿþïÿþðÿÿëÿÿéüÿà÷ýÞ÷þÒóÿÌðþÎðüÑïùÖôüàýÿâÿÿÝúÿÖóûÒðúÑïùÔòüÞùÿÞùÿÔñÿÎïÿÄêÿÄêÿÊïÿÖöÿÙ÷ÿÛöÿÚõÿÕòÿÏðÿÌðÿÄîþÀëüºæÿµâÿ¥Ôþ ÕÿÕÿŸÕÿ¡Öÿ®Úý´Ýý¼áü¿äÿ·âÿ§ÙüžÒú”ÎþÍÿ†Èÿ†ËÿŒÍÿŽÍÿŽÌûÍüŽÎü–ÊúÍý©Öÿ°Üÿ¿èÿÏïúÑñüÓóþÒòÿÏîÿÏîÿÏîÿÎîýÑñþÕõÿ×øÿÖôþÎðü¿èþ¶äþ©Þÿ£Ùÿ¢Öû§ÙúÞþ»çÿÁêþÀæû¾çý»çÿ´áÿ±Þý³ßü¶âû¾çûÅëÿÎðüÛùÿÞûÿáúÿÞöÿÔðþÌëý¶Ýú®Úý¤×ÿ ÕÿÓÿ—Ðý–Ñý”Ñþ”Ñý™Ôþ¡×ý¦Úÿ±ßÿ¯Þü³àýµáü»åþ½æüÆëþÎïÿÑñÿÔòýÖôþÛöÿÝöûçüÿìÿÿìÿÿðÿÿìþþêýÿæûþâùÿàøÿÊðýÅìûÅìýÆéüËìý×ôÿ×ôÿÖôþÛùÿÙ÷ÿÏïúÑñüÚöÿÚöÿÒñÿÍðÿ¿éÿ¹åþ¼æüÊïÿÎòÿ×ôÿÖóÿÏðÿÄêýÀéý¸åú²âù«Ûÿ§ØÿœÐÿ•Îû•Ðü™ÒýŸÖÿªÜÿ¯Ýþ±Þû²áÿ«ßÿ Úÿ™Òý’ÏþÌÿÆÿ…ÊÿŒÍÿÌÿŽËø‘Ðü’Òþ Ôû¦Öú´âÿ»çÿÁéÿÔòüÔòüÖôÿ×ôÿÕòÿÓðÿÒïÿÑîþÑñþ×÷ÿÛùÿÙöþÓóþÄíÿ»çÿªßÿ¥Ûÿ£ÙýªÜý°áÿ¼èÿÃìÿÃéþÂëÿ¾êÿµâÿ²ßþ³ßü·ãü¼çúÂëÿÎòþÛùÿÝúÿâûÿáøÿÙóÿÔñÿÀåÿ´ßÿ¨Ùÿ¥Ùÿ¢×ÿœÒþšÓþ—Ôÿ–Óÿœ×ÿ£Ùÿ¨Ýÿ±ßÿ®Ýû°Ýú³ßú»åþ½æüÈíÿÎïÿÒòÿØôÿÙõÿÜ÷þáúÿéþÿìÿÿìÿÿïÿÿìþþêýÿçüÿçþÿãûÿÌòÿÄîþÅëþÄçûÈèýÏîÿÑðÿÔñÿÙ÷ÿÚøÿÑñüÓóþÙ÷ÿØõÿÏïÿÊîÿ½éÿ¶âý¸âúÄêýÉîþÐðÿÑðÿËîÿÁçü¼åû³áø¯Þø¤Õý Óþ›Ñÿ‘ÌöÎ÷•ÐúšÔú§ÜþÞþ¯Þü¬Ýý¤Üÿ™×ÿ˜ÑüÍþ‰Ëÿ‚Çþ…ÊÿŽÐÿÏÿ‘Îú–Õÿ™Úÿ§ÝÿÞþ·æÿ½éÿÄíÿÚõÿÙôÿØóüÙôýÛöýÚ÷ýÚ÷ÿÚøÿÕõÿÖøÿÚúÿÜ÷ÿÚøÿËðÿÂëÿ°ßý¨Øþ¦Øý®ßÿ¶åÿÁîÿÆëþÈíÿÇíÿ¼èÿ¸æÿ³áûºæÿ½çÿÂèýÈíÿÖöÿÜ÷ÿáúÿéþÿéþÿäüÿßúÿÎïÿÂèý²Þû¬Üÿ¦ØýžÒùŸÔþŸÕÿ›Ôÿ¥Üÿ¨Þÿ§Ûÿ«Þýàý¬Û÷¯Þú·ãü½çýÉîÿÓóÿØöÿÞùÿâûÿçÿÿçÿÿêÿÿìþÿîýÿïýþðþÿðþÿïþÿëÿÿëÿÿßüÿÙ÷ÿÑñüÍîýÎïÿÊîþÌíþÓðþÙöþÛöÿÞ÷üßøýÞùÿÚöÿÌðÿÉïÿµáú¬Û÷«Úøµäÿ½ëÿÆìÿÂèý¾èÿ·ãþ¯Þü¤ÙûœÓú’ÏüÎÿ‹ÊÿŠËÿ‘Ðÿ‘Îû–Ñû§ßÿ«áÿ©ßÿ¥Ûÿ›Ñÿ—ÑÿÌþÎÿˆÊþƒÈÿƒÊÿŒÏÿÏÿ’Ðù¡Ùü§Ýÿ±àþ´áþ»åþ¾æÿÊðÿÕñÿÔñÿÙõÿÝùÿàýÿàýÿÜùÿÛùÿÓóþÑóÿÓóþÚ÷ÿÜøÿÎòÿÇîÿ¸æÿ¯Ýÿ«Ûÿ°Þÿ´ãÿ»èÿÅëÿÆìÿÂêÿ¹åþ¶äþµãý»åý¿èþÇìÿÊíÿÏìúßúÿäýÿåúûçûüéÿÿçÿÿÚøÿÐñÿ½æü°ÝþªÛü§Ùþ¦Úÿ§Üÿ¦Ûÿ¤Ùÿ¨Üÿ§Üü¬ßü¯áü²ßü´âü»åýÀéýËïÿÕóýÙöþàùýãûýçÿÿçÿÿêÿÿíÿÿðÿÿôÿÿôþÿïýþîþþëÿÿëÿÿìÿÿçÿÿáýÿÜúÿÙùÿÒôÿÐòþÕóþàûÿåýÿëÿÿçÿÿáýÿÞûÿÑõÿËòÿµáúªÙ÷¦×÷©Ûþ°áÿ½æú½çý¹åþ´ãÿßÿÔû“ÎúˆÇú†Èü€Åþ|ÁüƒÆý‹ÊýÍü™ÔþØÿž×ÿ›Öÿ•ÏÿÌþÍÿŠÉþ„Çû…Ëÿ‡ÍÿˆÌýŠÊø—Ñù®ãÿµæÿ¸åÿ¸åÿ»åþ½åþÅëÿÍìþÎîýÔñÿØöÿÝúÿÝúÿÝúÿÛùÿÖôÿÑñþÒòýØõýÚøÿÎòÿÈïÿ»éÿ®ÜÿªÚÿ°Þÿ´ãÿ¹çÿ¼æþ½åþ»åþ´âü´âü¶äþ¼æþÀéýÊíÿÍîÿÐíûßúÿãÿÿçüýéýþêÿÿçÿÿßüÿ×÷ÿÅêý³àý°ÞÿªÜÿ«Üÿ©Ýÿ§Üÿ¥Ùÿ«Ýÿ«Þý²áý´ãý¶âý¸äý¾çýÃéþÎïþÙõÿÝøÿãûýçüýéþÿèýþëÿÿðÿÿòÿÿõÿÿõÿÿòþþîüýìþÿìþÿëÿÿéÿÿåþÿàýÿÛùÿÒòýÑñüÖòýÞùÿãüÿéþÿäüüÝùýÜùÿÏóÿÉïÿ¶âûªØù¥Ö÷¦Øý¬Ýþ¼æü¿éÿ¹åÿ³áÿ®àÿÔý•Ðü‹Êÿ†ÉþÄý{ÀûÄý‡Éý‹ËûÎú“Ðý”Ñþ”Ñþ‘ÎýŽÌý‘ÏÿˆÊþ…ÇûˆÎÿŠÐÿŒÎÿŒÌúšÔú²äÿ¸çÿ¹æÿ¸åÿ·ãþ¹ãüÀéÿÃçÿÃçýÇêýÌíþÓóþÖôþ×ôü×óþÕóþÓðþÓïûÔðûÖôþÎòþÊñÿ»çÿ°Þÿ¬Üÿ¬ÜÿÞþßú¯Þú°ßý¯Þü¯Þü²áý·ãþÀèÿÆìÿÎïÿÐðÿØöÿÛøÿàüÿéÿÿëÿÿêÿþéþÿçÿÿäÿÿ×÷ÿÀèÿºçÿ°Þÿ«Ûÿ¨Úÿ§Ûÿ«Ýÿ±ßÿµâÿ»åý¼æþÁéÿÂëÿÈíÿËîÿ×ôÿÝøÿãúÿçûüçûúéüúëýýíÿþòÿþõÿÿ÷ÿÿöÿÿôÿþóÿýðþþðþÿíýüìÿýêþýçÿÿáúÿÖñúÖòýÙõÿÜ÷ÿÝöýèÿÿçÿýßûþÜùÿÊîþÄêÿ´áþ§×û£Õú¦×ÿ¬Üÿ¸äý»çÿµâÿ¬Þÿ§Ûÿ˜Ñþ’ÏþŠËÿ…Êÿ{Ãý}ÆýÊÿ€ÇÿÄýÃý‚ÃýƒÄú†ÈüŒÎþÏÿŽÍÿ‰Ëÿ†ÈüŠÍÿŒÏÿÍü‘Îú¡×ý¶åÿºæÿ¶åÿ´ãÿ°Þø²àúºäüÀåÿ¿äþÂæüÇêýÒòÿÖôÿ×óþ×óþ×óþÕñýÔðüÔðüÔòýÏóÿÌóÿ¹åþ°ÞÿÝÿ«Ýÿ¬Þÿ«ÞýÞþ¬Ýþ«Üý«Üü±àü¶âýÃìÿÈîÿÎïÿÐðÿÖöÿÛøÿÝøÿäüþéþÿëÿþéÿýèÿÿèÿÿÜùÿÆìÿÀêÿ±Þý¬Úü¨Úÿ©ÛÿÝÿ³àÿ·ãþ½æü¾çýÂèÿÃéþÈëþÍîÿÖôÿßøýãûÿéýþêüüêýùìÿýïÿþòÿþõÿÿ÷ÿþöÿý÷ÿÿöÿÿñÿÿðþþïþûïÿüìÿýëÿÿäüÿÙôûØóüÚõþÜ÷ÿÛöÿäüüäýúßüÿÛùÿÉîÿÂëÿ±Þý¤Ôú Ñù¤Øÿ¬Ýÿ·äÿ¹æÿ´âÿ«ßÿ§Ýÿ–ÐþŽÌý†ÉÿƒÈÿ|Äþ}Æý€Ëÿ|ÄÿzÀü|ÀýÃÿÁû‚Åü‰ÍþÏÿŒËþÌÿˆÊþŠÌÿÏÿŽÍù“Îø¤Øýµäÿ¸äÿµäÿ°âý®Ý÷²àú¹åþ½æÿ¼åÿ½ãúÀäúÏðÿÕõÿÛ÷ÿÜ÷ÿÜ÷ÿÚõÿÙóÿÖóÿÕóþÍñýÈðü¼éÿ¯ÝþÝÿ«Ýÿ©Þÿ©ßÿ§Ýÿ¢Øþ¢Öý©Ûþ°ßý»èÿÂëÿÇìÿÎïþÎîýÒôþÜúÿÜùÿÜõùâúþêÿÿèýÿêÿÿêÿÿãüÿÑòÿÈìÿ·ßù°Üù¬ÝþÝÿ¯àÿ¸äÿ½çÿÃéþÄéüÄèþÆéýÑòÿÐñÿÖòýÞ÷üåúÿéýþéýüìÿýëýýìÿýðÿýóÿÿõÿÿôÿþõÿÿóÿÿñÿÿïýþòÿþïÿþìÿýêÿÿçüÿÞ÷üÛôûÖñúÜ÷ÿÝøÿâþÿÞûùÙ÷ÿÕ÷ÿÆìÿ½æÿ«ÙýÐûÐû¡Öÿ£ØÿªÜÿªÜÿ¨Üÿ¢ÙÿŸØÿ“ÑÿÎÿƒÈÿÇÿ‚Êÿ~Éÿ|ÇÿwÁþu¿þu¼þx¿ÿ{Áÿ{ÁüƒÉýŽÒÿŒÎÿÌÿÌÿÎÿ’Ðÿ˜Õÿ›Ôÿ¨Úÿ´áÿ¶áÿ²ãÿ¯âÿ¯áüµäÿºæÿ»çÿ¼åÿ½ãú¿ãùËìûÐðûÚ÷ÿÞùÿßúÿÚõÿØóþ×ôÿÔôÿÌðüÆîú¹æû¬ÚûªÚþ¥Ùþ¢Øü Øû¦Ýÿ¢×ÿ Õý¦Úÿ³âÿ¸åÿÀéÿÅëþÌðÿÎïþÑóýÚøÿÚøÿÚöúßøýèýÿæûÿåúýåýÿãüÿÔôÿÌïÿ½ãú¶àù¯Ýþ¬Ýþ°áÿ¹æÿ¾èÿÄêÿÆëþÅéÿÆéÿÎïÿÏðÿÖôÿàùÿäüÿéþÿëÿþìÿÿíÿÿìþþíÿþðÿýóÿÿðÿÿñÿÿòÿÿðÿÿîþþðÿÿïÿþíÿÿìÿÿèÿÿßøýÜõüÖñúÜ÷ÿÝøÿàüÿÜúüÔõþÐôÿÁéÿ¸ãÿªÚÿ Õÿ Õÿ Öÿ Öÿ Õý¡ÖþŸÖÿ›Ôÿ™Ôÿ‘ÏÿŒËÿƒÈÿ‚ÈÿÉÿ~ÇþzÅþxÂÿvÀÿu¿ÿw¾ÿ|Âÿ|Âþ‚Éÿ‹ÏÿŒÎÿŽÍÿŽÍÿÐÿ’Ðÿ˜ÒÿšÓþ¦Úÿ±ßÿ°ÝþÞþªÝü®ßý¶åÿ¾êÿÀèÿÁéÿÇëÿÉìÿÐðûÔòüßúÿèÿÿèÿÿÞ÷þÚõÿØõÿÓóÿÌîúÅëøºåø°ßý«Ûÿ¢×ÿ ×þ›Õû›Ôÿ ÖÿŸÕÿ¢Öý°áÿ³àý¼æþÀéÿÈíÿËðÿÑóÿÕõÿÙ÷ÿÛ÷ÿÛöÿß÷ÿÝöýÛôùÞõûáúÿÚ÷ÿ×õÿÌïÿÂëÿ°Ýü¨ÙúªÜÿ¶åÿ¹åÿ¿èþÃéÿÆìÿÅëÿÉîÿÌïÿÓóÿÛ÷ÿßúÿäüÿåýÿèÿÿéþÿéþÿéþÿéþÿêÿþëÿÿìÿÿìÿÿêýÿêýÿéþÿæþÿåýÿâúþáøþÞ÷þÚõüÔñùØôÿÚöÿÜúÿÖ÷þÊîþÄêÿµàÿ¬Üÿ¡Öÿ›Óÿ™Óÿ•Ïý‘Îû‘Îý’Ïþ’Ïþ‘ÎýÍþ‰ÈýƒÄúƒÆý‚Çÿ}Ãþ}Ãþ}Ãþ|Äÿ|ÃÿyÃÿv½û|Âþ|ÂýƒÈÿŠÍÿŽÍÿ‘Ïÿ’Ðÿ“Ñÿ“Ðÿ“Íû–Ïü Õÿ¤Øÿ¦ØýªÜÿªÜý¯àÿ´ãÿ¸äÿÀæýÃéþÎñÿÓôÿÚøÿÜùÿâþÿåþÿåþÿàùþÜ÷ÿÒïÿÏïþÎðúÊðûÂíþ³âÿªÚþŸÔüžÕþšÓþ—ÑÿœÔÿÖÿ£×þ¬Ýþ±Þý¸äý¼æþÀéýÅëÿÏðÿÓóÿÕõÿÙõÿØòÿÙóÿÚôÿÜ÷ÿÜ÷ÿÛöÿßøýßøÿÕõÿËðÿ±àü©Úû¥×üÞþ³âÿ»åþ¼æþ¾èÿÂêÿÅëÿÇíÿËïÿÔôÿØöÿÛøþÞúþãüÿâûÿåþÿæÿÿãÿÿáýþäýÿãüÿãûÿáøþáøþÜ÷þÛøÿÚ÷ýÙôûÚõþÝøÿÜùÿÚöÿØöÿÙ÷ÿÕ÷ÿÎòþÀæû¸âû«Øÿ¦×ÿ™ÑÿÍüÍüÎýŽÎþ‹ÎÿŠÍÿ‹ÍÿŒËÿŒËÿŒËÿ‡Èþ‡Èÿ†ÉÿÆÿ„Æÿ„ÆÿÆÿÆþ~ÇþzÃú|Ãû|Áú„ÆÿÎÿÍÿ‘Ïþ’Ðÿ’Ðÿ’Ïþ“Íû•Ïý™ÒÿžÔÿ¡×ÿ¬Þÿßÿ²àÿµâÿ¹åÿÂæüÆëþÏóÿÓõÿØöþÚ÷ýàùýàùýäüÿàùþÛöÿÑîÿÎîýÎðúÌòýÆñÿ¸çÿ°àÿ¥Úÿ¡Øÿ˜Óÿ˜Òÿ˜Ðÿ™Òý¡ÕüªÛü¯Üû·ãü¹æý¾éüÃìÿÏðÿÓóÿÔôÿÖóÿ×òÿ×òÿØôÿÚöÿÚöÿÚ÷ÿâúþáøþÖöÿÍòÿ´ãÿ¬Ýþ£×üªÛü±ßÿ·ãþ¶âû¹åþ½çÿ¾çýÄêÿÉíýÑñþÓóþØõýÚ÷ýßúÿÞùÿÝøÿÜøüÛøüÜúüÜøüÛ÷ûÝöûÝöýÞ÷þØõýØöÿ×õýÖóû×óþÛ÷ÿÛ÷ÿÚøÿØöÿÕõÿÒôÿËïýºãù±Ýú¦Öþ¡Ôÿ–ÎÿÍþÍþÏýŒÎþˆÍÿ‡ÌÿˆËÿˆÉÿˆÊþ‹ÊÿŠÉÿ†Çý…Èý…Çÿ…Åÿ„ÆÿÆÿ€Çý€Çý|ÃùÄû~Ãú…ÆÿËÿÍÿ’Ïþ’Ïþ’Ïþ‘Îý‘Îý“Ðÿ™Óÿ›ÔÿÖÿ¨ÙÿªÚþ¯Ýÿ²ßÿ¹åÿÆìÿËïÿÐñÿÑîþÔòýÓñûÙ÷ÿØùÿÛøüÝ÷øÝöûÐíûÏíøÖôþÙ÷ÿÔöÿÉïÿÁëÿªÚþ Ôü™Òÿ•Óÿ”Ðÿ•ÏýšÐüžÓû¨Ýÿ©ÝÿßÿºæÿÁêÿÌïÿÓóÿ×óÿÙñûÚòüÙôÿØôÿØöÿÚöÿÜ÷ÿáúþãüÿÛûÿÑöÿ·äÿÞþ ÖüŸÖý ×þ¤Ûÿªàÿ¬ßþàý°ßû³áù¾éüÈïÿÌñÿÏóÿÎòÿÌðþËðÿÊïÿÊðÿÇíÿÈîÿÊïÿÍñÿÍñÿÏïüÏïüÑñþÍîýÏðÿÌíþÌíþÎïÿÐñÿÒóÿÍîÿÊëüÀéý¹æý«Üý¤Úÿ–ÐþÌû’ÎÿŽÌûÍû‹Òÿ‰Ïÿ‹ÌÿˆÉÿ‡ÊÿƒÈÿ‚Çÿ~Äÿ|Âþ‚Çÿ€ÅÿÆÿÆÿ‚Çÿ‚ÇÿÆÿÆý€ÅþƒÅÿ‚ÄþƒÅÿŠÍÿÐÿŠÎÿŒÐÿÏÿŽÍÿŽÌÿÎÿ—Ôÿœ×ÿœ×ÿŸÔþ¡ÔÿªÜÿ¯ÝÿµàÿÂçÿÇíÿÎïÿÐíýÒðûÒðûÓõÿÖøÿÛúÿÝ÷øÜõùÔòýÓñûÙöþÛøÿ×õÿËîÿÃëÿ°Þÿ¥Öþ–Ïü’Ðÿ’Îÿ•Ïÿ™ÒýŸÕÿ Ùÿ¤Ùÿ¨Üÿ¸äÿ¿çÿÊîÿÓóÿÙõÿÝôüÝôúÜ÷þÛøÿÚöÿÚöÿÝöýãüÿàüÿØøÿÎóÿ·åÿ®ßÿ¡Ùþ›Õý™Ôþ™Ôþ×ÿ¥Ûÿ§Üþ«Üü¯Þú¸åüÁêÿÄíÿÉïÿÈïÿÅëþÀéý¿èþÁëÿ¼èÿ¿éÿ¼æÿÁêÿÅëÿÉíýÌðÿÐñÿÍîÿÌðÿÈëþÈëÿÉìÿÉîÿÌñÿÊïÿÇìþ¾èÿ¸æÿ©Ýÿ Úÿ“ÐÿÌû’ÏþŽÍùŽÎü‹Òÿ‰ÏÿŒËÿˆÉÿ‡ÉÿƒÉÿÇÿ{ÃþyÀþ~Äÿ}ÃÿÅÿÅÿÆÿ‚ÇÿÆÿÆÿ€ÅþƒÅÿƒÅÿ„ÆÿŠÍÿ‰Ïÿ‡ÍþˆÎÿˆËÿŠÌÿŽÍÿÎÿ“Ðÿ™Ôÿ›ÖÿŸÕÿ Õÿ¨ÜÿÝÿ³àÿºãùÀéýÌðÿÏïþÒïýÎîýÌðþÎòÿÖöÿÜ÷þÜ÷þÚøÿÙ÷ÿÚ÷ÿÙöþÓñüÍðÿÅíÿ¶äÿ«Üÿ–Ìú’Ïþ•Ïý—Ðý›ÒûÔýšÔüŸÖý¤Øý²áýºãÿÃéÿÍìþÔñÿÞ÷üÞõûÞúþÞùÿßúÿâûÿæûÿåýÿÞúþÏïúÇìþ¸æÿ³äÿžÕü˜Òú™Ôþ—Òü—ÒüœÒþÔý£×þ¨Úý±Þÿ¶âÿ»äÿ¾çÿ½çÿºãÿ´àý³àÿ¶ãÿ²àÿ²Þÿ°Üÿ³Þþ·àü½åþÃéÿËðÿËïÿÉîÿÄèþÁçüÁæÿ¾æÿ¿çÿÁëÿ½çÿÚù®Üþ§Ûÿ ×ÿšÓþšÔüœÓü—Ñù“ÎúŽÎþŠÌþˆÇü†ÇýˆÊÿƒÉÿ€Æÿ}ÅÿzÁÿ{Áý|ÂþÅÿÅÿ€Åþ€Åþ€ÅþÄý€ÅþƒÅÿƒÅÿ†ÈÿŠÍÿˆÎÿ‡Íÿ‡Íÿ„ÇüˆÉÿÎÿŽÍÿËý“Ðý—ÑÿšÓÿœÒÿ£Øÿ§Øÿ¬Úü¸âøÀéýÌðÿÏïþÏïþÍîýÊïÿÉîþÑòÿÚöÿÛøÿÙ÷ÿÚøÿÛøÿÙöþÓñüÌïÿÃëÿ³áÿ©Ûÿ—Íù”Îü—Ðý›ÑýžÓûžÕüœÖþŸÖý¢ØþÞü´àýÀéÿËìýÐðýÜøüßøýáýÿáýÿâþÿåþÿêþÿåýÿÝùýÍíøÆëý¹çÿ³äÿ£ÚÿšÓþ˜ÓÿÍùÌø•Ïý—ÐýŸÔþ¤ØÿªÚþ³àÿµâÿ¸ãÿ¸ãÿ´áÿ±Þÿ¯Ýÿ°Ýÿ«Ûÿ¬ÙÿÚÿ°Üÿ²Ýý¹âþ¾æÿÈíÿÉîÿÈíÿÃéÿ¾æÿ»äÿ¹âþ¸äÿ¸åÿ³âþ¨Öø¨Øþ¤ÙÿŸÖýœÖü Øý¤ÚþŸÕûšÑúÍüŒÊý‡Æû„Åû†ÈÿÇÿ~Äÿ~Æÿ|Ãÿy¿ûzÀü}Ãþ€ÆÿÆÿ€ÅþÄý~ÃüÆÿƒÅÿ„Æÿ‡Éÿ‰Ìÿ†Ìÿ†Ìÿ…ÊÿƒÆý‡ÈþŽÍÿŽÍÿÍþ’Ïü“Ðý–Ðþ—ÏþŸÔÿ¢Öþ©×û»æùÂëÿÊïÿÌíþÌíþÉíýÄêÿÁçüÄéüÍìþÏìüÓñü×õÿÛøÿÚ÷ÿÖôÿÊíÿÂëÿ°Þÿ¦Øý›Ñý—ÐýŸÕÿ£Øÿ©Ýÿ§Þÿ¤ÛÿžØÿŸÖý§Ùü®Üý¼æþÍòÿÔöÿÜøüâûÿèÿÿçÿÿçÿÿêÿÿíýüëÿÿãüÿÒòýËïÿ´âüªÛûžÕü™Ôþ•Òþ’Ïû”Ñþ‘Íÿ‘ÍÿšÓÿžÔÿ¡Õý§Ùþ¨Øþ©ÙÿªÚþªÜÿ¬Þÿ¨Ùÿ¨Ùÿ¤×ÿ¦Úÿ£×ÿªÜÿÞÿµâÿ¸åÿ¿èüÅëþÁêþ¼æÿ¶âÿ¬ÚûªÛü©Ûþ¤Øý ÖúÐûžÑþÔýžÖû§Þü¬âþ¸êÿ³äÿ«ÝÿžÔÿ˜Òÿ‹Êÿ†Çý…ÇÿÅÿ}Ãþ|Äÿ|Ãÿx¾ú{Áý|ÂýÅÿÆÿÆÿÆÿÆÿ‚Çÿ‚ÄþƒÅÿ†Èÿ…Çÿ‚ÇÿƒÅÿ…Çÿ…Èÿ‡ÈÿŽÍÿŽÍÿÎÿÎÿÍþÎÿÍü—ÐýœÑû¨Úÿ¾éüÄïÿÌñÿËïÿËïÿÉîÿÂèý½æüÂæüÇèûÇçöÏìúÓñüÙõÿÙöþÖôÿÌðÿÆïÿ³áÿ¨ÚÿžÕþžÔÿ¤Ùÿ§ÜÿªÞÿ¨àÿ¦ÝÿŸÙÿ ×þ¨Úý°Þÿ¹ãüÎóÿÕ÷ÿÛ÷ûáúþåÿÿåÿÿçÿÿêÿÿïÿþîÿÿæÿÿÖôÿÌðÿ²Þù¦×÷¢Ùÿ›Öÿ•ÒþÍù’Ïü‘Ïÿ’Îÿ›Óÿž×ÿ Õý¤Øÿ¥×ü¦Øý§ÙþªÜÿ¥Ùÿ¡Õý¡Ôÿ Óþ¢×ÿ¥Ùÿ¬Þÿ®àÿ´ãÿ·äÿ½æúÂëÿ¿èþ¸äÿ³ßü¨Öø¥×ø£×üžÔúœÔù˜Ëø˜Ìû›ÒûŸ×ü¯åÿµéÿ¾îÿºéÿ°àÿ¤ØÿžÖÿÌÿ‡Èþ…ÇÿÅÿ}Ãþ|Äÿ}ÄÿzÀü}ÃÿÅÿ~Äÿ€Åþ‚ÇÿƒÈÿƒÈÿ‚Çÿ‚ÄþƒÅÿ†ÈÿƒÅÿƒÈÿƒÅÿ†Èÿ‡ÊÿˆÉÿÎÿŽÍÿÌÿŽÌýÍþÎÿÍü–Ïü›Ñý©Ûÿ
\ No newline at end of file diff --git a/libs/ode-0.16.1/drawstuff/textures/wood.ppm b/libs/ode-0.16.1/drawstuff/textures/wood.ppm new file mode 100644 index 0000000..a53d2dc --- /dev/null +++ b/libs/ode-0.16.1/drawstuff/textures/wood.ppm @@ -0,0 +1,5 @@ +P6 +# Created by Paint Shop Pro +256 256 +255 +ÛÛÛÐÐÐÇÇÇÉÉÉÌÌÌÌÌÌÌÌÌÍÍÍÎÎÎÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÐÐÐÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÍÍÍÊÊÊÉÉÉÇÇÇÃÃÃÌÌÌÌÌÌÇÇÇ¿¿¿°°°¬¬¬¸¸¸±±±±±±µµµ»»»»»»¼¼¼ÉÉÉØØØÕÕÕÔÔÔØØØâââêêêæææØØØÊÊÊÃÃÃÑÑÑÜÜÜîîîîîîäääçççäääÙÙÙÛÛÛÐÐÐÇÇÇÅÅż¼¼æææçççèèèæææÛÛÛæææèèèâââãããÛÛÛèèèçççæææãããàààâââçççêêêêêêëëëîîîñññòòòòòòñññïïïëëëçççääääääèèèêêêêêêççççççÝÝÝíííèèèÎÎÎÂÂÂÂÂÂÇÇÇÆÆÆÅÅÅÂÂÂÂÂÂÂÂÂÃÃÃÅÅÅÅÅÅÅÅÅÆÆÆÅÅÅÎÎÎÅÅÅ°°°´´´······ÍÍÍØØØÌÌÌ»»»¼¼¼ÇÇÇÐÐÐÊÊÊÉÉÉÎÎÎÀÀÀººº¾¾¾¸¸¸¼¼¼¾¾¾ÃÃÿ¿¿³³³³³³¼¼¼¿¿¿¸¸¸ÂÂÂÉÉÉÇÇÇ»»»¸¸¸ÅÅÅÑÑÑÕÕÕØØØÑÑÑÆÆÆØØØãããÒÒÒÉÉÉÉÉÉÆÆÆÍÍÍÊÊÊ»»»ÍÍÍäää×××ÐÐÐÐÐÐÔÔÔØØØØØØ×××ÒÒÒÑÑÑÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÎÎÎÌÌÌÊÊÊÇÇÇÊÊÊÍÍÍÌÌÌÀÀÀºººÅÅÅÇÇÇ»»»ÍÍÍÆÆÆÇÇÇÅÅÅ»»»»»»¿¿¿¸¸¸¸¸¸¿¿¿ÃÃÃÃÃÃÆÆÆÇÇÇÃÃÿ¿¿ÆÆƸ¸¸ÝÝÝçççØØØÇÇÇÐÐÐÍÍÍÕÕÕÔÔÔäääíííßßßÝÝÝãããÝÝÝÜÜÜÙÙÙÕÕÕÑÑÑÍÍÍÊÊÊÉÉÉÆÆÆÆÆÆÇÇÇÉÉÉÌÌÌÌÌÌÇÇÇÅÅÅÀÀÀÆÆÆÉÉÉÃÃø¸¸±±±±±±´´´³³³¿¿¿ÍÍÍÑÑÑÌÌÌÉÉÉÎÎÎÕÕÕÒÒÒÊÊÊÅÅÅÇÇÇÊÊÊÊÊÊÌÌÌÎÎÎÎÎÎÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÐÎÎÎÎÎÎÍÍÍÌÌÌÊÊÊÊÊÊÉÉÉÂÂÂÍÍÍÎÎÎÉÉÉÀÀÀ´´´³³³³³³···ººº¸¸¸ºººÀÀÀÍÍÍ×××ÒÒÒÔÔÔÙÙÙâââèèèæææÛÛÛÐÐÐÌÌÌÎÎÎÑÑÑâââêêêæææçççàààßßßÜÜÜÑÑÑÌÌÌÅÅŸ¸¸ßßßçççßßßàààÛÛÛãããäääÝÝÝãããàààßßßâââæææçççççççççêêêíííêêêêêêèèèçççæææäääääääääãããßßßÝÝÝßßßâââãããâââßßßãããÜÜÜèèèÛÛÛ¼¼¼»»»ÀÀÀÀÀÀÆÆÆÆÆÆÅÅÅÃÃÃÃÃÃÃÃÃÆÆÆÇÇÇÇÇÇÉÉÉÉÉÉÊÊÊÀÀÀ±±±´´´»»»¿¿¿ÌÌÌÐÐÐÆÆÆ¿¿¿ÆÆÆÍÍÍÐÐÐÍÍÍÌÌÌÌÌ̼¼¼ºººÀÀÀ»»»ÀÀÀÀÀÀÃÃÿ¿¿¸¸¸ºººÂÂÂÃÃÿ¿¿¾¾¾ÂÂÂÀÀÀººº¼¼¼ÌÌÌ×××ØØØÕÕÕÎÎÎÂÂÂÒÒÒÝÝÝÐÐÐÊÊÊÊÊÊÇÇÇÂÂÂÃÃÃÂÂÂÔÔÔâââÒÒÒÍÍÍÑÑÑÔÔÔÕÕÕÕÕÕÒÒÒÐÐÐÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÍÍÍÊÊÊÉÉÉÇÇÇÅÅÅÉÉÉÐÐÐÊÊÊ»»»¸¸¸ÀÀÀÃÃõµµ´´´¿¿¿ÆÆƼ¼¼µµµººº¼¼¼ÀÀÀÃÃÃÃÃÃÃÃÃÆÆÆÇÇÇÀÀÀ¸¸¸ÉÉÉ¿¿¿±±±ÒÒÒÛÛÛÑÑÑÇÇÇÒÒÒÇÇÇÕÕÕÐÐÐäääçççÝÝÝÝÝÝàààÝÝÝÜÜÜÙÙÙÕÕÕÑÑÑÍÍÍÊÊÊÉÉÉÇÇÇÉÉÉÉÉÉÊÊÊÌÌÌÊÊÊÇÇÇÅÅÅÂÂÂÉÉÉÐÐÐÑÑÑÍÍÍÉÉÉÊÊÊÍÍÍÊÊÊÉÉÉÊÊÊÍÍÍÑÑÑÑÑÑÎÎÎÊÊÊÇÇÇÅÅÅÃÃÃÆÆÆÇÇÇÉÉÉÊÊÊÎÎÎÎÎÎÎÎÎÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÐÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÇÇÇÐÐÐÐÐÐÇÇǾ¾¾´´´°°°´´´···¾¾¾¾¾¾······ÃÃÃÑÑÑÕÕÕÑÑÑÒÒÒÙÙÙâââçççæææßßßØØØÒÒÒÌÌÌÅÅÅÑÑÑçççæææçççÝÝÝàààÙÙÙÐÐÐÎÎÎÃÃø¸¸ÝÝÝêêêàààãããßßßäääâââÛÛÛâââããããããçççêêêêêêçççæææèèèíííóóóóóóïïïêêêãããààààààãããëëëçççäääæææêêêëëëêêêèèèæææßßßíííØØØ´´´ºººÅÅÅ¿¿¿ÆÆÆÇÇÇÇÇÇÆÆÆÃÃÃÃÃÃÆÆÆÊÊÊÇÇÇÉÉÉÌÌÌ···´´´µµµ¿¿¿ÌÌÌÌÌÌÇÇÇÂÂÂÆÆÆÑÑÑÕÕÕÑÑÑÑÑÑÐÐÐÉÉÉ»»»ÂÂÂÉÉÉÃÃÃÊÊÊÎÎÎÌÌÌÇÇÇÅÅÅÅÅÅÅÅÅÃÃÃÂÂÂÃÃÃÆÆÆÃÃþ¾¾ÂÂÂÎÎÎÕÕÕÔÔÔÎÎÎÌÌÌÅÅÅÔÔÔÝÝÝÎÎÎÇÇÇÇÇÇÇÇǼ¼¼ÅÅÅÑÑÑ×××ØØØÐÐÐÎÎÎÒÒÒÒÒÒÒÒÒÑÑÑÍÍÍÌÌÌÊÊÊÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÊÊÊÉÉÉÆÆÆÆÆÆÃÃÃÀÀÀÌÌÌÑÑÑÀÀÀ´´´»»»ÅÅÅÆÆƾ¾¾¿¿¿ÅÅÅ»»»°°°µµµ¾¾¾¾¾¾¾¾¾ÀÀÀÃÃÃÉÉÉÍÍÍÇÇǼ¼¼ÊÊÊ¿¿¿¯¯¯ÎÎÎÕÕÕÎÎÎÉÉÉÒÒÒÀÀÀ×××ÊÊÊæææàààÝÝÝßßßßßßÜÜÜÛÛÛØØØÕÕÕÑÑÑÎÎÎÌÌÌÊÊÊÊÊÊÌÌÌÍÍÍÍÍÍÊÊÊÇÇÇÆÆÆÆÆÆ¿¿¿ÃÃÃÊÊÊÐÐÐÐÐÐÎÎÎÎÎÎÎÎÎÊÊÊÃÃÿ¿¿ÅÅÅÐÐÐÕÕÕÒÒÒÌÌÌÀÀÀÂÂÂÅÅÅÆÆÆÆÆÆÆÆÆÊÊÊÍÍÍÍÍÍÎÎÎÎÎÎÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÐÐÐÍÍÍÊÊÊÊÊÊÌÌÌÎÎÎÐÐÐÒÒÒÐÐÐÌÌÌÇÇÇ¿¿¿³³³³³³ººº»»»¿¿¿¾¾¾···¸¸¸ÂÂÂÎÎÎÔÔÔÐÐÐÒÒÒÙÙÙàààäääæææãããààà×××ÌÌÌÀÀÀÊÊÊæææäääçççÝÝÝØØØ×××ÐÐÐÌÌÌÂÂÂÃÃÃâââíííàààÛÛÛÕÕÕÕÕÕÑÑÑÌÌÌÎÎÎÒÒÒÌÌÌÐÐÐÒÒÒÔÔÔÕÕÕÛÛÛäääíííøøøùùùöööñññèèèäääæææèèèêêêäääßßßÝÝÝâââæææèèèèèèçççßßßíííÙÙÙ³³³¸¸¸ÅÅÅ¿¿¿ÅÅÅÇÇÇÇÇÇÆÆÆÂÂÂÂÂÂÆÆÆÊÊÊÆÆÆÆÆÆÌÌ̺ºº°°°¸¸¸»»»ÇÇÇÔÔÔÎÎÎÅÅÅÀÀÀÇÇÇÔÔÔ×××ÒÒÒÐÐÐÒÒÒÇÇÇÀÀÀÍÍÍÔÔÔÎÎÎÒÒÒÒÒÒÍÍÍÍÍÍÑÑÑÐÐÐÉÉÉÅÅÅÅÅÅÊÊÊÍÍÍÊÊÊÃÃÃÀÀÀÅÅÅÉÉÉÉÉÉ¿¿¿ÅÅÅÆÆÆÛÛÛäääÕÕÕÎÎÎÍÍÍÆÆÆÂÂÂÒÒÒßßßÔÔÔÌÌÌÐÐÐÔÔÔÔÔÔÒÒÒÑÑÑÍÍÍÉÉÉÇÇÇÇÇÇÊÊÊÌÌÌÌÌÌÊÊÊÉÉÉÇÇÇÆÆÆÅÅÅÃÃÃÇÇǼ¼¼ÀÀÀÌÌÌÉÉÉ¿¿¿¼¼¼»»»ÍÍÍ»»»¾¾¾¿¿¿¾¾¾¿¿¿ÀÀÀÀÀÀÀÀÀÆÆÆÇÇÇÆÆÆÉÉÉÆÆƼ¼¼ÇÇÇ¿¿¿´´´ÕÕÕÛÛÛÔÔÔÌÌÌÐÐп¿¿ØØØÉÉÉèèèÝÝÝßßßâââßßßÜÜÜÛÛÛØØØÕÕÕÑÑÑÎÎÎÌÌÌÊÊÊÌÌÌÍÍÍÎÎÎÍÍÍÉÉÉÆÆÆÆÆÆÆÆÆ¿¿¿ÀÀÀÀÀÀÃÃÃÃÃÃÀÀÀ¼¼¼ººº······¸¸¸¾¾¾ÃÃÃÊÊÊÎÎÎÐÐп¿¿ÃÃÃÆÆÆÆÆÆÅÅÅÆÆÆÉÉÉÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÎÎÎÐÐÐÐÐÐÑÑÑÑÑÑÐÐÐÍÍÍÊÊÊÌÌÌÍÍÍÑÑÑÒÒÒ×××ÌÌÌÊÊÊÑÑÑÇÇǵµµ³³³¼¼¼¾¾¾ººº¸¸¸ººº»»»¾¾¾ÇÇÇÒÒÒÑÑÑÔÔÔØØØÝÝÝâââäääææææææÔÔÔÎÎÎÆÆÆÊÊÊèèèàààæææßßßÒÒÒÙÙÙÒÒÒÉÉÉÀÀÀÑÑÑççççççæææØØØÐÐÐÌÌÌÌÌÌÊÊÊÉÉÉÊÊÊÉÉÉÌÌÌÍÍÍÎÎÎÐÐÐÕÕÕÝÝÝäääëëëîîîñññîîîèèèææææææèèèæææßßßÕÕÕÑÑÑÕÕÕÝÝÝãããæææààà×××æææØØصµµ´´´¼¼¼»»»ÃÃÃÅÅÅÆÆÆÃÃÃÀÀÀ¿¿¿ÃÃÃÉÉÉÉÉÉÉÉÉÌÌ̸¸¸³³³ÂÂÂÇÇÇÔÔÔÒÒÒÎÎÎÆÆÆÀÀÀÃÃÃÊÊÊÍÍÍÌÌÌÉÉÉÍÍÍÅÅÅÅÅÅÔÔÔÙÙÙÕÕÕÑÑÑÀÀÀÀÀÀÇÇÇÒÒÒÔÔÔÌÌÌÇÇÇÊÊÊÊÊÊÐÐÐÐÐÐÉÉÉÀÀÀÀÀÀÆÆÆÉÉÉÍÍÍÔÔÔÒÒÒßßßãããÐÐÐÉÉÉÇÇÇÍÍÍÑÑÑßßßãããÔÔÔÍÍÍÔÔÔÔÔÔÔÔÔÒÒÒÐÐÐÌÌÌÇÇÇÆÆÆÇÇÇÉÉÉÊÊÊÉÉÉÇÇÇÆÆÆÅÅÅÃÃÃÃÃÃÂÂÂÇÇǼ¼¼¾¾¾ÆÆÆÉÉÉÉÉÉÀÀÀ³³³¿¿¿ÂÂÂÀÀÀ¿¿¿ÃÃÃÇÇÇÀÀÀ¸¸¸¾¾¾ÂÂÂÌÌÌÌÌÌÅÅÅÆÆÆÉÉÉÀÀÀÇÇÇ¿¿¿¸¸¸ÙÙÙÜÜÜ×××ÍÍÍÍÍÍÃÃÃÕÕÕÌÌÌëëëßßßââââââàààÛÛÛÛÛÛØØØÕÕÕÑÑÑÎÎÎÌÌÌÌÌÌÌÌÌÍÍÍÎÎÎÌÌÌÇÇÇÅÅÅÅÅÅÆÆÆÅÅž¾¾¼¼¼¾¾¾¼¼¼···´´´±±±µµµººº»»»»»»»»»ÀÀÀÅÅÅ¿¿¿ÃÃÃÆÆÆÅÅÅÃÃÃÆÆÆÉÉÉÉÉÉÊÊÊÊÊÊÊÊÊÌÌÌÍÍÍÎÎÎÐÐÐÑÑÑÑÑÑÎÎÎÍÍÍÌÌÌÌÌÌÎÎÎÒÒÒÔÔÔÒÒÒÉÉÉÎÎÎÙÙÙÑÑѾ¾¾µµµ¸¸¸¼¼¼······¼¼¼¾¾¾¼¼¼ÃÃÃÎÎÎÕÕÕÕÕÕ×××ÙÙÙßßßãããæææçççÒÒÒÐÐÐÌÌÌÌÌÌíííÝÝÝâââÝÝÝÔÔÔÛÛÛÒÒÒÉÉÉÂÂÂÝÝÝêêêàààèèèÙÙÙÒÒÒÐÐÐÒÒÒ×××ÑÑÑÔÔÔØØØÛÛÛÛÛÛÛÛÛÛÛÛÙÙÙÛÛÛÛÛÛàààäääêêêíííëëëêêêêêêëëëêêêâââÙÙÙ×××ÛÛÛãããèèèêêêÝÝÝ×××âââ×××¼¼¼ººº¼¼¼¿¿¿ÃÃÃÅÅÅÅÅÅÃÃÃÀÀÀÀÀÀÃÃÃÇÇÇÌÌÌÌÌÌÊÊʾ¾¾»»»ÉÉÉÔÔÔßßßÐÐÐÎÎÎÉÉÉÃÃÃÀÀÀÀÀÀÃÃÃÃÃÃÂÂÂÅÅÅÂÂÂÊÊÊÔÔÔ×××ÕÕÕÇÇǸ¸¸¼¼¼ÆÆÆÐÐÐÎÎÎÇÇÇÅÅÅÉÉÉÐÐÐÕÕÕ×××ÔÔÔÎÎÎÐÐÐÕÕÕÛÛÛÛÛÛàààØØØÙÙÙØØØÇÇÇÆÆÆÉÉÉØØØÝÝÝàààãããÜÜÜ×××ØØØÐÐÐÕÕÕÔÔÔÑÑÑÌÌÌÇÇÇÆÆÆÉÉÉÌÌÌÉÉÉÉÉÉÆÆÆÅÅÅÃÃÿ¿¿ÂÂÂÃÃÃÃÃÃÇÇÇÅÅŵµµºººÉÉÉÌÌÌÃÃÃÂÂÂÇÇÇÆÆÆÃÃÃÅÅÅÆÆÆÑÑÑÐÐÐÃÃÃÃÃÃÆÆÆ»»»ÉÉÉ¿¿¿···××××××ÕÕÕÐÐÐÎÎÎÌÌÌÎÎÎÎÎÎëëëâââäääàààâââÛÛÛÙÙÙØØØÕÕÕÑÑÑÎÎÎÍÍÍÌÌÌÌÌÌÌÌÌÊÊÊÉÉÉÆÆÆÅÅÅÃÃÃÃÃÃÀÀÀ¼¼¼ºººººº¼¼¼¾¾¾»»»¸¸¸µµµ···¸¸¸»»»¼¼¼¼¼¼¼¼¼¼¼¼¾¾¾ÂÂÂÃÃÃÀÀÀÀÀÀÆÆÆÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÊÊÊÍÍÍÎÎÎÐÐÐÐÐÐÎÎÎÍÍÍÍÍÍÎÎÎÐÐÐÒÒÒÕÕÕÑÑÑÍÍÍÔÔÔØØØÐÐÐÆÆÆ¿¿¿······¸¸¸»»»¾¾¾¿¿¿ÂÂÂÆÆÆÉÉÉÙÙÙ×××ÕÕÕ×××ÜÜÜâââææææææÔÔÔÑÑÑÍÍÍÊÊÊïïïÜÜÜßßßÙÙÙ×××ÕÕÕÍÍÍÌÌÌÊÊÊèèèëëëàààÝÝÝÒÒÒÔÔÔÑÑÑÒÒÒÕÕÕÎÎÎÕÕÕÎÎÎÎÎÎÑÑÑÔÔÔØØØÛÛÛÜÜÜÜÜÜßßßãããçççëëëîîîîîîîîîíííâââÝÝÝÛÛÛÜÜÜàààääääääãããÜÜÜÝÝÝàààÌÌ̼¼¼ÀÀÀÂÂÂÆÆÆÆÆÆÅÅÅÅÅÅÃÃÃÂÂÂÃÃÃÅÅÅÆÆÆÌÌÌÌÌ̾¾¾¾¾¾ÆÆÆ×××ÜÜÜÒÒÒÒÒÒÑÑÑÎÎÎÉÉÉÅÅÅÃÃÃÃÃÃÅÅÅÅÅÅÆÆÆÒÒÒÒÒÒÔÔÔ××׿¿¿¼¼¼ÅÅÅÎÎÎÑÑÑÌÌÌÆÆÆÇÇÇÍÍÍØØØ×××ÔÔÔÔÔÔÔÔÔÕÕÕØØØÙÙÙÉÉÉÑÑÑÊÊÊÐÐÐÒÒÒÌÌÌÔÔÔÝÝÝÙÙÙäääàààæææäääÙÙÙØØØÒÒÒÕÕÕÕÕÕÒÒÒÍÍÍÊÊÊÉÉÉÊÊÊÍÍÍÉÉÉÇÇÇÆÆÆÃÃÃÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀÀÀÀÅÅÅÅÅÅÀÀÀÅÅÅÆÆƼ¼¼³³³ÂÂÂÆÆÆÀÀÀÅÅÅÊÊÊÐÐÐ×××ÒÒÒÌÌÌÑÑÑÐÐÐÃÃÃÃÃð°°ÍÍÍ»»»ÙÙÙØØØØØØÕÕÕÐÐÐÔÔÔÆÆÆÑÑÑèèèæææãããÛÛÛàààÛÛÛÙÙÙ×××ÕÕÕÑÑÑÐÐÐÍÍÍÌÌÌÊÊÊÉÉÉÆÆÆÅÅÅÅÅÅÃÃÃÃÃúºº¸¸¸µµµ···»»»»»»ººº···µµµµµµ···ººº¾¾¾ÀÀÀÀÀÀ¿¿¿»»»¿¿¿¿¿¿¼¼¼¿¿¿ÆÆÆÊÊÊÇÇÇÉÉÉÇÇÇÇÇÇÇÇÇÉÉÉÌÌÌÎÎÎÐÐÐÎÎÎÎÎÎÍÍÍÍÍÍÎÎÎÑÑÑÔÔÔÕÕÕÔÔÔÔÔÔÕÕÕÐÐÐÇÇÇÌÌÌÉÉɺºº³³³ººº¿¿¿¾¾¾ÀÀÀÇÇÇÉÉÉÅÅÅÜÜÜØØØÔÔÔÕÕÕÛÛÛâââäääæææÕÕÕÑÑÑÌÌÌÇÇÇñññÜÜÜÝÝÝÕÕÕÕÕÕÎÎÎÆÆÆÍÍÍÑÑÑïïïíííäääÛÛÛÕÕÕÝÝÝÛÛÛØØØØØØÐÐÐÙÙÙÕÕÕÑÑÑÍÍÍÎÎÎÔÔÔÙÙÙÜÜÜÝÝÝÝÝÝßßßãããçççêêêëëëëëëêêêÜÜÜÜÜÜßßßäääèèèèèèãããÝÝÝÕÕÕÝÝÝØØغºº³³³¿¿¿ÀÀÀÃÃÃÇÇÇÆÆÆÅÅÅÃÃÃÅÅÅÆÆÆÆÆÆÇÇÇÇÇÇÇÇǸ¸¸ººº¼¼¼¿¿¿ÑÑÑÕÕÕÛÛÛÛÛÛÛÛÛÙÙÙÕÕÕÐÐÐÊÊÊÇÇÇÍÍÍÊÊÊÍÍÍÛÛÛÔÔÔÔÔÔÛÛÛ¼¼¼¿¿¿ÊÊÊÔÔÔÔÔÔÎÎÎÎÎÎÕÕÕÜÜÜØØØÐÐÐÆÆÆÅÅÅÉÉÉÊÊÊÆÆÆÀÀÀÂÂÂÍÍÍÉÉÉÍÍÍÐÐÐÉÉÉÑÑÑÙÙÙÕÕÕæææãããêêêèèèÕÕÕÔÔÔÙÙÙ×××ÕÕÕÒÒÒÐÐÐÌÌÌÊÊÊÍÍÍÎÎÎÉÉÉÇÇÇÆÆÆÃÃÃÂÂÂÀÀÀÂÂÂÂÂÂÅÅÅ¿¿¿ÀÀÀÅÅÅÂÂÂÅÅÅÆÆÆ¿¿¿³³³¼¼¼¿¿¿ÃÃÃÊÊÊÅÅž¾¾ÀÀÀ¿¿¿···¿¿¿ÊÊÊÌÌÌ×××ØØØÃÃÃÎÎÎÆÆÆÂÂÂâââàààßßßÙÙÙÑÑÑØØØ¿¿¿ÒÒÒæææçççããã×××àààÛÛÛÙÙÙ×××ÕÕÕÑÑÑÐÐÐÍÍÍÌÌÌÉÉÉÆÆÆÃÃÃÃÃÃÃÃÃÃÃÃÂÂÂÀÀÀ¼¼¼»»»ººº»»»»»»ºººµµµ±±±···¸¸¸ººººººººº»»»¾¾¾ÀÀÀ¿¿¿ÀÀÀ¿¿¿»»»¼¼¼ÃÃÃÆÆÆÅÅÅÊÊÊÉÉÉÇÇÇÉÉÉÌÌÌÎÎÎÎÎÎÍÍÍÒÒÒÑÑÑÎÎÎÍÍÍÍÍÍÍÍÍÎÎÎÐÐÐÎÎÎÕÕÕÒÒÒÇÇÇÇÇÇÎÎÎÌÌÌÀÀÀ³³³µµµººº¼¼¼¾¾¾ÀÀÀÅÅÅÇÇÇâââÜÜÜÕÕÕÒÒÒ×××ÜÜÜàààâââ×××ÐÐÐÑÑÑÊÊÊñññàààÝÝÝÛÛÛÐÐÐÌÌÌßßßêêêèèèëëëçççêêêÛÛÛÙÙÙØØØÕÕÕÔÔÔÒÒÒÒÒÒÑÑÑÎÎÎÒÒÒÕÕÕØØØÙÙÙÙÙÙÜÜÜßßßØØØâââäääàààäääîîîëëëßßßçççßßßãããèèèæææââââââßßßÙÙÙ×××ÌÌ̼¼¼¸¸¸ÂÂÂÇÇÇÅÅÅÉÉÉÅÅÅÇÇÇÉÉÉÅÅÅÇÇÇÌÌÌÉÉÉÐÐÐÆÆƾ¾¾¿¿¿Â¿¿¿¿¿¿ÀÀÀÃÃÃÉÉÉÑÑÑÙÙÙÜÜÜØØØÒÒÒÒÒÒÑÑÑÕÕÕ×××ÑÑÑÔÔÔÎÎμ¼¼ÍÍÍØØØÍÍÍÍÍÍÕÕÕßßßßßßÆÆÆÇÇÇÇÇÇÅÅÅ¿¿¿¼¼¼ÂÂÂÅÅž¾¾ÀÀÀÆÆÆÆÆÆÃÃÃÌÌÌÜÜÜßßß×××ÙÙÙÜÜÜÝÝÝÜÜÜÙÙÙ××××××ØØØÕÕÕÑÑÑÎÎÎÎÎÎÐÐÐÑÑÑÐÐÐÎÎÎÌÌÌÉÉÉÃÃÿ¿¿¼¼¼»»»¼¼¼¾¾¾¾¾¾ÆÆÆÆÆÆÂÂÂÂÂÂÃÃÃÌÌÌÛÛÛÃÃúºº¾¾¾ÎÎÎÂÂÂÍÍÍÎÎÎÇÇÇÃÃÃÌÌÌÉÉÉÆÆÆÊÊÊÌÌÌÎÎÎÛÛÛÊÊÊÆÆƸ¸¸ßßßÙÙÙÛÛÛÍÍÍÒÒÒ×××ØØØÆÆÆããããããÛÛÛÛÛÛÔÔÔØØØÕÕÕÒÒÒÑÑÑÐÐÐÍÍÍÊÊÊÆÆÆÇÇÇÆÆÆÆÆÆÅÅÅÃÃÃÂÂÂÀÀÀ¿¿¿»»»¸¸¸¸¸¸»»»ººº´´´´´´¸¸¸ºººººººººººº»»»¼¼¼¾¾¾¿¿¿¾¾¾ÀÀÀÀÀÀ¾¾¾¿¿¿ÅÅÅÆÆÆÅÅÅÉÉÉÇÇÇÇÇÇÊÊÊÍÍÍÎÎÎÎÎÎÍÍÍÑÑÑÐÐÐÎÎÎÎÎÎÍÍÍÍÍÍÎÎÎÎÎÎÌÌÌÎÎÎÍÍÍÉÉÉÊÊÊÐÐÐÎÎÎÇÇÇ¿¿¿»»»ººº¾¾¾ÃÃÃÆÆÆÇÇÇÙÙÙÙÙÙÛÛÛÜÜÜÝÝÝÜÜÜÛÛÛÙÙÙÐÐÐÊÊÊÍÍÍÉÉÉíííÝÝÝÛÛÛØØØÐÐÐÎÎÎãããíííëëëíííæææäää×××××××××ÕÕÕÔÔÔÔÔÔÒÒÒÒÒÒÎÎÎÎÎÎÐÐÐÑÑÑÒÒÒ×××ÛÛÛßßßÝÝÝââââââßßßâââêêêëëëçççèèèâââçççîîîèèèãããàààÛÛÛÜÜÜÎÎξ¾¾¿¿¿ÂÂÂÅÅÅÇÇÇÉÉÉÅÅÅÇÇÇÉÉÉÆÆÆÉÉÉÍÍÍÊÊÊÎÎÎÅÅž¾¾ÀÀÀÅÅÅÅÅÅÅÅÅÅÅÅÃÃÃÃÃÃÅÅÅÇÇÇÌÌÌÒÒÒÙÙÙÝÝÝÕÕÕÒÒÒÔÔÔÔÔÔÒÒÒÒÒÒÌÌÌÀÀÀÉÉÉÔÔÔÌÌÌÌÌÌÑÑÑØØØàààÒÒÒÇÇÇÆÆÆÂÂÂÂÂÂÌÌÌÒÒÒÒÒÒÐÐÐÂÂÂÅÅÅÆÆÆÇÇÇÐÐÐÛÛÛÝÝÝ×××ÔÔÔÕÕÕ×××ÕÕÕÔÔÔÒÒÒÔÔÔÕÕÕÒÒÒÑÑÑÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÍÍÍÉÉÉÃÃÿ¿¿¾¾¾¾¾¾¾¾¾¾¾¾ÂÂÂÅÅÅÃÃÃÅÅÅÇÇÇÃÃÃÃÃÃÎÎÎÉÉÉ»»»»»»ÐÐÐÃÃÃÌÌÌÎÎÎÑÑÑÒÒÒÔÔÔÎÎÎÎÎÎÔÔÔÒÒÒÍÍÍÐÐÐÍÍÍÍÍÍ¿¿¿âââÛÛÛÛÛÛÐÐÐÔÔÔ×××ÙÙÙÉÉÉãããàààÙÙÙÙÙÙÔÔÔ×××ÕÕÕÒÒÒÑÑÑÐÐÐÍÍÍÉÉÉÆÆÆÆÆÆÆÆÆÅÅÅÃÃÃÂÂÂÀÀÀ¿¿¿¿¿¿»»»······ººººººµµµµµµ¸¸¸¸¸¸¸¸¸ºººººº»»»¼¼¼¿¿¿¿¿¿»»»¿¿¿ÂÂÂÀÀÀÃÃÃÆÆÆÇÇÇÅÅÅÇÇÇÇÇÇÉÉÉÌÌÌÎÎÎÐÐÐÎÎÎÍÍÍÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÍÍÍÍÍÍÉÉÉÇÇÇÇÇÇÊÊÊÍÍÍÎÎÎÎÎÎÎÎÎÇÇÇÀÀÀ»»»»»»ÂÂÂÅÅÅÃÃÃÀÀÀÐÐÐÔÔÔÙÙÙÝÝÝÜÜÜØØØÔÔÔÑÑÑÌÌÌÉÉÉÌÌÌÉÉÉçççÜÜÜÛÛÛØØØÑÑÑÒÒÒæææîîîíííîîîãããÜÜÜÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÔÔÔÒÒÒÑÑÑ×××ÕÕÕÔÔÔÔÔÔØØØßßßãããæææãããâââßßßÜÜÜÝÝÝãããêêêïïïëëëäääçççêêêæææâââßßßØØØÙÙÙÅÅŸ¸¸ÂÂÂÇÇÇÂÂÂÃÃÃÊÊÊÇÇÇÃÃÃÇÇÇÉÉÉÆÆÆÊÊÊÎÎÎÌÌÌÉÉÉ¿¿¿ººº¾¾¾ÂÂÂÃÃÃÂÂÂÂÂÂÂÂÂÃÃÃÃÃÃÂÂÂÃÃÃÊÊÊ×××âââÛÛÛÙÙÙ×××ØØØÛÛÛÔÔÔÌÌÌÌÌÌÂÂÂÊÊÊÆÆÆÆÆÆÆÆÆÇÇÇÎÎÎÊÊÊÌÌÌÊÊÊÂÂÂÆÆÆØØØÙÙÙÔÔÔÙÙÙÅÅÅÆÆÆÉÉÉÎÎÎÕÕÕÙÙÙÙÙÙ×××ÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÎÎÎÑÑÑÒÒÒÎÎÎÐÐÐÑÑÑÑÑÑÐÐÐÐÐÐÐÐÐÐÐÐÎÎÎÉÉÉÃÃÿ¿¿¿¿¿ÀÀÀ¿¿¿¿¿¿¾¾¾¿¿¿¿¿¿ÃÃÃÊÊÊÅÅÅÀÀÀÆÆÆÔÔÔÅÅÅÆÆÆÜÜÜÎÎÎÌÌÌÉÉÉÍÍÍÆÆÆÐÐÐÒÒÒÐÐÐÍÍÍÇÇÇÉÉÉÐÐÐÊÊÊÐÐÐÉÉÉäääÝÝÝßßßØØØÜÜÜ×××ÛÛÛÍÍÍâââÜÜÜ××××××ÕÕÕ×××ÔÔÔÒÒÒÑÑÑÐÐÐÍÍÍÉÉÉÆÆÆÆÆÆÅÅÅÃÃÃÂÂÂÀÀÀ¿¿¿¿¿¿¾¾¾¸¸¸µµµµµµºººººº······ººº¸¸¸¸¸¸¸¸¸ººº»»»¾¾¾¿¿¿ÀÀÀ»»»ÀÀÀÃÃÃÂÂÂÃÃÃÇÇÇÉÉÉÆÆÆÆÆÆÇÇÇÉÉÉÍÍÍÐÐÐÑÑÑÎÎÎÍÍÍÌÌÌÍÍÍÎÎÎÐÐÐÐÐÐÎÎÎÌÌÌÊÊÊÊÊÊÆÆÆÆÆÆÌÌÌÎÎÎÌÌÌÌÌÌÎÎÎÉÉÉ»»»¸¸¸¼¼¼ÀÀÀÀÀÀ¿¿¿ÉÉÉÍÍÍÑÑÑÒÒÒÑÑÑÐÐÐÐÐÐÐÐÐÐÐÐÍÍÍÎÎÎÊÊÊãããÜÜÜÜÜÜÛÛÛÒÒÒÔÔÔæææëëëèèèëëëààà×××ÕÕÕÕÕÕ×××ØØØØØØÕÕÕÒÒÒÑÑÑÒÒÒÑÑÑÐÐÐÔÔÔÙÙÙÝÝÝààààààäääßßßÛÛÛÛÛÛÙÙÙÜÜÜæææñññèèèââââââãããÝÝÝÝÝÝßßßÙÙÙÎÎο¿¿»»»ÆÆÆÌÌÌÅÅÅÃÃÃÌÌÌÇÇÇÃÃÃÇÇÇÊÊÊÇÇÇÌÌÌÐÐÐÍÍÍÃÃü¼¼¸¸¸¼¼¼ÀÀÀÀÀÀÀÀÀÂÂÂÀÀÀÂÂÂÅÅÅÆÆÆÇÇÇÌÌÌÑÑÑ×××ÎÎÎÐÐÐÌÌÌÎÎÎÔÔÔÊÊÊ¿¿¿ÅÅÅ¿¿¿ÃÃÃÆÆÆÊÊÊÌÌÌÊÊÊÍÍÍÍÍÍÇÇÇÊÊÊÂÂÂÆÆÆØØØÕÕÕÐÐÐÝÝÝÎÎÎÌÌÌÎÎÎ×××ÛÛÛØØØÕÕÕÕÕÕÌÌÌÊÊÊÉÉÉÇÇÇÇÇÇÊÊÊÍÍÍÐÐÐÍÍÍÐÐÐÒÒÒÒÒÒÑÑÑÐÐÐÑÑÑÒÒÒÑÑÑÌÌÌÃÃÃÀÀÀÂÂÂÃÃÿ¿¿···ÀÀÀÀÀÀ¾¾¾ÃÃÃÇÇÇÆÆÆÇÇÇØØØÊÊÊÂÂÂÎÎÎÂÂÂÇÇÇÌÌÌÕÕÕÜÜÜ×××ÌÌÌÅÅÅÆÆÆÌÌÌÑÑÑ×××ÊÊÊ×××ÔÔÔçççÝÝÝÜÜÜÙÙÙÙÙÙØØØÝÝÝÒÒÒâââØØØÔÔÔÔÔÔ×××ÕÕÕÒÒÒÑÑÑÐÐÐÎÎÎÍÍÍÉÉÉÆÆÆÅÅÅÅÅÅÃÃÃÂÂÂÀÀÀ¿¿¿¾¾¾¼¼¼¸¸¸´´´´´´¸¸¸ººº¸¸¸¸¸¸ººº¸¸¸¸¸¸¸¸¸ººº»»»¾¾¾¿¿¿ÀÀÀ¾¾¾ÂÂÂÅÅÅÂÂÂÀÀÀÆÆÆÉÉÉÉÉÉÅÅÅÆÆÆÉÉÉÌÌÌÐÐÐÑÑÑÐÐÐÍÍÍÊÊÊÌÌÌÎÎÎÐÐÐÐÐÐÍÍÍÊÊÊÉÉÉÎÎÎÇÇÇÆÆÆÌÌÌÌÌÌÇÇÇÅÅÅÉÉÉÎÎÎÊÊÊ»»»¸¸¸ººº¾¾¾ÂÂÂÃÃÃÆÆÆÌÌÌÍÍÍÍÍÍÎÎÎÐÐÐÑÑÑÒÒÒÐÐÐÎÎÎÊÊÊÙÙÙÙÙÙÛÛÛÙÙÙÔÔÔÑÑÑãããæææãããäääÜÜÜ×××ØØØÙÙÙÛÛÛÛÛÛØØØÕÕÕÒÒÒÑÑÑÐÐÐÑÑÑÔÔÔÙÙÙÝÝÝàààßßßÜÜÜâââÛÛÛØØØÙÙÙØØØ×××ßßßêêêâââÝÝÝàààãããßßßààààààÙÙÙÀÀÀ¿¿¿ÃÃÃÊÊÊÌÌÌÆÆÆÆÆÆÌÌÌÉÉÉÅÅÅÇÇÇÊÊÊÇÇÇÌÌÌÑÑÑÎÎξ¾¾ºººººº¿¿¿ÂÂÂÂÂÂÅÅÅÉÉÉÅÅÅÅÅÅÅÅÅÉÉÉÍÍÍÎÎÎÌÌÌÉÉÉÇÇÇÊÊÊÇÇÇÌÌÌÑÑÑÇÇǼ¼¼ÃÃÃÇÇÇÃÃÃÃÃÃÅÅÅÆÆÆÅÅÅÃÃÃÅÅÅ¿¿¿ÉÉÉÆÆÆÊÊÊ×××ÑÑÑÐÐÐããã×××ÒÒÒÕÕÕÜÜÜÝÝÝÕÕÕÑÑÑÔÔÔÎÎÎÌÌÌÉÉÉÆÆÆÇÇÇÉÉÉÌÌÌÎÎÎÌÌÌÐÐÐÒÒÒÔÔÔÒÒÒÒÒÒÒÒÒÔÔÔÕÕÕÎÎÎÆÆÆÃÃÃÃÃÃÅÅÅ¿¿¿ÀÀÀÒÒÒÎÎμ¼¼»»»ÆÆÆÌÌÌÌÌÌÐÐÐÍÍÍÅÅÅÇÇǸ¸¸ÂÂÂÂÂÂÃÃÃÊÊÊÇÇÇÉÉÉÌÌÌÐÐÐÔÔÔ×××ÕÕÕÍÍÍßßßßßßçççÛÛÛØØØÕÕÕÑÑÑÛÛÛàààØØØâââÕÕÕÔÔÔÒÒÒ×××ÔÔÔÑÑÑÐÐÐÎÎÎÎÎÎÍÍÍÉÉÉÆÆÆÅÅÅÃÃÃÃÃÿ¿¿¾¾¾¾¾¾¼¼¼···³³³±±±···ºººººº¸¸¸ººº······¸¸¸ººº»»»¾¾¾ÀÀÀ¾¾¾ÃÃÃÆÆÆÂÂÂÀÀÀÃÃÃÇÇÇÇÇÇÅÅÅÅÅÅÆÆÆÊÊÊÎÎÎÐÐÐÐÐÐÎÎÎÊÊÊÌÌÌÍÍÍÎÎÎÎÎÎÍÍÍÊÊÊÉÉÉÎÎÎÉÉÉÆÆÆÉÉÉÉÉÉÃÃÃÂÂÂÃÃÃÎÎÎÑÑÑÑÑÑÍÍÍÆÆƾ¾¾ººº¸¸¸¾¾¾ÃÃÃÉÉÉÎÎÎÐÐÐÐÐÐÐÐÐÐÐÐÎÎÎÎÎÎÍÍÍÉÉÉÑÑÑÔÔÔ×××ÕÕÕÔÔÔÎÎÎßßßäääàààßßßÙÙÙÛÛÛÛÛÛÛÛÛÛÛÛÙÙÙØØØÕÕÕÒÒÒÑÑÑÔÔÔ×××ÛÛÛßßßããããããâââàààÝÝÝÙÙÙØØØÙÙÙÙÙÙÕÕÕØØØßßßÙÙÙÛÛÛâââçççäääæææããã×××¼¼¼ÃÃÃÊÊÊÍÍÍÊÊÊÊÊÊÊÊÊÌÌÌÊÊÊÆÆÆÉÉÉÌÌÌÉÉÉÌÌÌÑÑÑÎÎδ´´´´´¸¸¸¼¼¼¼¼¼¼¼¼ÂÂÂÉÉÉÊÊÊÇÇÇÅÅÅÆÆÆÌÌÌÍÍÍÊÊÊÆÆÆÉÉÉÌÌÌÌÌÌÎÎÎÑÑÑÌÌÌÇÇÇÉÉÉÉÉÉÀÀÀ¿¿¿»»»¼¼¼ÂÂÂÀÀÀÅÅÅÇÇÇÒÒÒÔÔÔÒÒÒÕÕÕÐÐÐÑÑÑàààÛÛÛ×××ØØØÛÛÛÙÙÙÒÒÒÐÐÐÑÑÑÐÐÐÍÍÍÉÉÉÇÇÇÉÉÉÌÌÌÍÍÍÎÎÎÎÎÎÐÐÐÒÒÒÔÔÔÔÔÔÕÕÕ××××××ØØØÒÒÒÊÊÊÆÆÆÅÅÅÃÃÃÂÂÂÀÀÀÑÑÑãããÛÛÛÀÀÀºººÃÃÃÉÉÉÊÊÊÅÅÅÐÐÐÐÐÐÔÔÔÉÉÉÐÐÐÆÆÆÀÀÀ»»»ÀÀÀÍÍÍÔÔÔÑÑÑÐÐÐÑÑÑÎÎÎÉÉÉÝÝÝàààâââØØØÙÙÙÜÜÜÕÕÕßßßãããÜÜÜâââÒÒÒÕÕÕÑÑÑ×××ÒÒÒÐÐÐÎÎÎÎÎÎÎÎÎÌÌÌÉÉÉÆÆÆÅÅÅÃÃÃÃÃÃÂÂÂÀÀÀ¿¿¿¾¾¾¼¼¼¸¸¸³³³±±±···ºººººº¸¸¸¸¸¸······¸¸¸ººº»»»¾¾¾ÀÀÀ¼¼¼ÅÅÅÇÇÇÅÅÅÀÀÀÂÂÂÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÇÇÇÌÌÌÎÎÎÐÐÐÎÎÎÊÊÊÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÊÊÊÉÉÉÉÉÉÆÆÆÅÅÅÆÆÆÆÆÆÅÅÅÃÃÃÂÂÂÊÊÊÎÎÎÒÒÒÔÔÔÐÐÐÇÇÇ»»»´´´¼¼¼¿¿¿ÃÃÃÉÉÉÌÌÌÍÍÍÌÌÌÉÉÉÊÊÊÍÍÍÎÎÎÍÍÍÑÑÑ×××ØØØÔÔÔÒÒÒÌÌÌÝÝÝèèèâââÛÛÛØØØàààØØØØØØ××××××ÕÕÕÔÔÔÒÒÒÑÑÑÕÕÕÕÕÕ×××ØØØÙÙÙÛÛÛÝÝÝßßßÝÝÝÛÛÛÙÙÙÙÙÙÙÙÙØØØ××××××ÕÕÕ×××ÝÝÝàààßßßâââàààÔÔÔÃÃÃÆÆÆÉÉÉÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÇÇÇÊÊÊÍÍÍÉÉÉÌÌÌÐÐÐÍÍÍ»»»¾¾¾ÂÂÂÃÃü¼¼···¼¼¼ÆÆÆÉÉÉÇÇÇÆÆÆÅÅÅÆÆÆÇÇÇÉÉÉÉÉÉÃÃÃÃÃÃÆÆÆÆÆÆÃÃÃÇÇÇÊÊÊÆÆÆÅÅÅÅÅÅÎÎÎÊÊÊÌÌÌÕÕÕ×××ßßßÔÔÔÛÛÛÝÝÝØØØÔÔÔÑÑÑÒÒÒÕÕÕÙÙÙ×××ÕÕÕÕÕÕÒÒÒÐÐÐÐÐÐÑÑÑÐÐÐÌÌÌÉÉÉÉÉÉÌÌÌÎÎÎÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÒÒÒÕÕÕØØØÙÙÙÙÙÙÙÙÙÕÕÕÎÎÎÉÉÉÅÅÅÂÂÂÀÀÀÀÀÀÑÑÑØØØÐÐп¿¿¾¾¾ÂÂÂÆÆÆÌÌÌÅÅÅÌÌÌÊÊÊÒÒÒÎÎÎÛÛÛÛÛÛàààæææØØØÐÐÐÍÍÍÍÍÍÒÒÒÕÕÕÍÍÍÊÊÊààààààÛÛÛÕÕÕÙÙÙãããÜÜÜãããæææààààààÒÒÒ×××ÑÑÑ×××ÑÑÑÐÐÐÎÎÎÍÍÍÍÍÍÌÌÌÉÉÉÆÆÆÅÅÅÅÅÅÃÃÃÂÂÂÀÀÀ¿¿¿¾¾¾¾¾¾¸¸¸³³³±±±µµµººº¸¸¸······µµµ······ººº»»»¿¿¿ÀÀÀ»»»ÃÃÃÉÉÉÆÆÆÂÂÂÂÂÂÂÂÂÀÀÀÅÅÅÃÃÃÃÃÃÆÆÆÊÊÊÎÎÎÐÐÐÎÎÎÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÊÊÊÉÉÉÅÅÅÃÃÃÂÂÂÃÃÃÅÅÅÆÆÆÆÆÆÃÃÃÐÐÐÊÊÊÅÅÅÅÅÅÇÇÇÉÉÉÅÅÅ¿¿¿¼¼¼»»»»»»¾¾¾ÂÂÂÅÅÅÅÅÅÃÃÃÉÉÉÍÍÍÒÒÒÔÔÔÕÕÕÛÛÛÜÜÜ×××ÑÑÑÉÉÉÝÝÝíííäääÙÙÙØØØäääÕÕÕÔÔÔÔÔÔÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÝÝÝÝÝÝÛÛÛØØØØØØÛÛÛâââèèèàààÝÝÝÛÛÛÙÙÙÙÙÙÙÙÙ×××ÔÔÔ×××ÔÔÔÕÕÕÔÔÔÑÑÑØØØÜÜÜÒÒÒÍÍÍÆÆÆÅÅÅÊÊÊÎÎÎÎÎÎÎÎÎÐÐÐÍÍÍÉÉÉÌÌÌÍÍÍÉÉÉÌÌÌÐÐÐÍÍÍÑÑÑÕÕÕØØØÒÒÒÅÅÅ»»»¾¾¾ÇÇÇÂÂÂÅÅÅÇÇÇÇÇÇÃÃÃÃÃÃÆÆÆÊÊÊÆÆÆÃÃÃÇÇÇÅÅž¾¾ÉÉÉÑÑÑÊÊÊÎÎÎ×××çççÜÜÜÒÒÒÔÔÔÍÍÍÒÒÒÔÔÔØØØÛÛÛ×××ÔÔÔØØØÙÙÙÔÔÔÕÕÕÕÕÕÒÒÒÐÐÐÎÎÎÎÎÎÐÐÐÐÐÐÍÍÍÊÊÊÉÉÉÊÊÊÍÍÍÑÑÑÒÒÒÒÒÒÔÔÔÑÑÑÑÑÑÒÒÒ×××ÛÛÛÛÛÛÛÛÛÛÛÛØØØÑÑÑÊÊÊÃÃÃÀÀÀÀÀÀÀÀÀÂÂÂÀÀÀ»»»»»»ÀÀÀÂÂÂÃÃÃÎÎÎÑÑÑÑÑÑÌÌÌÔÔÔÊÊÊÍÍÍÊÊÊÕÕÕÒÒÒÌÌÌÐÐÐÑÑÑÎÎÎÒÒÒÙÙÙÕÕÕÙÙÙëëëæææØØØÐÐÐÔÔÔßßß×××æææçççâââàààÒÒÒØØØÑÑÑ×××ÑÑÑÎÎÎÍÍÍÍÍÍÍÍÍÌÌÌÉÉÉÆÆÆÅÅÅÅÅÅÃÃÃÂÂÂÀÀÀ¿¿¿¾¾¾¾¾¾ººº³³³±±±µµµººº¸¸¸···µµµµµµ······ººº¼¼¼¿¿¿ÀÀÀÃÃÃÂÂÂÂÂÂÆÆÆÂÂÂÇÇÇÇÇǼ¼¼ÃÃÃÃÃÃÅÅÅÀÀÀÃÃÃÍÍÍÐÐÐÍÍÍÎÎÎÇÇÇÉÉÉÌÌÌÍÍÍÎÎÎÍÍÍÊÊÊÉÉÉÆÆÆÃÃÃÃÃÃÆÆÆÅÅÅÀÀÀÂÂÂÉÉÉÆÆÆÅÅÅÃÃÃÂÂÂÃÃÃÇÇÇÊÊÊÍÍÍÅÅÅÊÊÊÍÍÍÌÌÌÇÇÇÃÃÃÀÀÀ¿¿¿ÆÆÆÆÆÆÌÌÌÒÒÒÙÙÙÝÝÝÜÜÜ×××ÌÌÌÐÐÐÙÙÙâââßßß×××ÔÔÔÕÕÕÝÝÝÛÛÛØØØÕÕÕÔÔÔÒÒÒÑÑÑÐÐÐÙÙÙÙÙÙÛÛÛÝÝÝßßßààààààààà×××ØØØÙÙÙØØØÕÕÕÔÔÔÒÒÒÑÑÑÊÊÊÐÐÐãããßßßÔÔÔ×××ÕÕÕÕÕÕÔÔÔÃÃþ¾¾ÊÊÊÎÎÎÆÆÆÇÇÇÑÑÑÎÎÎÊÊÊÇÇÇÆÆÆÇÇÇÉÉÉÇÇÇÇÇÇÇÇÇÆÆÆÉÉÉÌÌÌÇÇÇÀÀÀÅÅÅÎÎÎÑÑÑÔÔÔÔÔÔÍÍÍÊÊÊÎÎÎÕÕÕ×××ÙÙÙßßßÒÒÒÂÂÂÅÅÅÊÊÊÊÊÊÍÍÍâââ×××ÐÐÐÐÐÐÐÐÐÍÍÍÎÎÎÔÔÔÒÒÒÔÔÔ××××××ÕÕÕÔÔÔÔÔÔÔÔÔÒÒÒÒÒÒÑÑÑÑÑÑÐÐÐÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÐÐÐÐÐÐÑÑÑÔÔÔÕÕÕ×××ÔÔÔÔÔÔÔÔÔ×××ØØØÙÙÙ×××ÔÔÔÜÜÜÙÙÙÒÒÒÒÒÒÛÛÛâââÝÝÝÔÔÔÃÃÿ¿¿¾¾¾ÀÀÀÂÂÂÂÂÂÆÆÆÊÊÊÍÍÍÐÐÐÒÒÒÑÑÑÎÎÎÌÌÌÊÊÊÌÌÌÊÊÊÌÌÌÌÌÌÍÍÍÎÎÎÒÒÒÒÒÒÒÒÒëëëÛÛÛßßßØØØÒÒÒÜÜÜÙÙÙÛÛÛêêêàààêêê×××ÑÑÑÐÐÐÔÔÔÍÍÍÑÑÑÐÐÐÎÎÎÍÍÍÌÌÌÊÊÊÉÉÉÇÇÇÀÀÀ¿¿¿ÃÃÃÃÃþ¾¾ÀÀÀ¿¿¿´´´µµµ¯¯¯³³³ººº···µµµºººººº»»»´´´³³³···»»»¼¼¼ÂÂÂÇÇÇÆÆÆÅÅÅÇÇÇÂÂÂÆÆÆÇÇÇ¿¿¿ÇÇÇÃÃÃÅÅÅÀÀÀÂÂÂÌÌÌÎÎÎÍÍÍÐÐÐÎÎÎÎÎÎÐÐÐÎÎÎÍÍÍÉÉÉÅÅÅÃÃÃÆÆÆÃÃÃÅÅÅÇÇÇÅÅÅÀÀÀÂÂÂÆÆÆÅÅÅÃÃÃÀÀÀÀÀÀÀÀÀÃÃÃÆÆÆÉÉÉÇÇÇÉÉÉÉÉÉÉÉÉÉÉÉÌÌÌÒÒÒ×××ÔÔÔÕÕÕÙÙÙÜÜÜÜÜÜØØØÑÑÑÍÍÍÊÊÊÎÎÎ×××ÜÜÜÙÙÙÒÒÒÐÐÐÒÒÒÑÑÑÒÒÒÒÒÒÑÑÑÎÎÎÍÍÍÐÐÐÒÒÒÕÕÕ×××××××××ØØØØØØÛÛÛÜÜÜÝÝÝÝÝÝÜÜÜØØØÔÔÔÎÎÎÌÌÌÉÉÉÎÎÎÒÒÒæææäääÝÝÝàààÛÛÛ×××ÍÍÍ¿¿¿ÉÉÉÍÍÍÇÇÇÇÇÇÐÐÐÍÍÍÊÊÊÆÆÆÅÅÅÆÆÆÇÇÇÇÇÇÆÆÆÊÊÊÊÊÊÌÌÌÍÍÍÌÌÌÌÌÌÑÑÑ×××ÛÛÛßßßÝÝÝ×××ÑÑÑÒÒÒ×××ØØØÔÔÔÛÛÛÔÔÔÊÊÊÒÒÒÝÝÝâââäääÜÜÜÙÙÙØØØÙÙÙÙÙÙÕÕÕÑÑÑÐÐÐÒÒÒÔÔÔÔÔÔÔÔÔÑÑÑÑÑÑÒÒÒÔÔÔÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÐÐÐÐÎÎÎÑÑÑÑÑÑÑÑÑÒÒÒÔÔÔÕÕÕØØØØØØ×××ÕÕÕÕÕÕ×××ØØØÙÙÙÙÙÙÙÙÙÙÙÙÕÕÕÐÐÐÑÑÑÛÛÛææææææßßßÔÔÔÇÇÇ¿¿¿ÂÂÂÉÉÉÊÊÊÊÊÊÊÊÊÎÎÎÐÐÐÑÑÑÑÑÑÎÎÎÍÍÍÊÊÊÊÊÊÌÌÌÌÌÌÍÍÍÎÎÎÍÍÍÉÉÉÅÅÅÃÃÃèèèàààçççÝÝÝÕÕÕÜÜÜßßßäääíííâââêêêÕÕÕÑÑÑÐÐÐÕÕÕÐÐÐÒÒÒÑÑÑÐÐÐÎÎÎÌÌÌÊÊÊÉÉÉÉÉÉÃÃÃÀÀÀÃÃþ¾¾ÀÀÀÀÀÀ······°°°´´´»»»······»»»ººº´´´±±±³³³¸¸¸»»»»»»¾¾¾ÂÂÂÉÉÉÇÇÇÇÇÇÀÀÀÅÅÅÇÇÇÀÀÀÊÊÊÃÃÃÃÃþ¾¾¿¿¿ÊÊÊÎÎÎÍÍÍÐÐÐÑÑÑÑÑÑÑÑÑÐÐÐÌÌÌÇÇÇÃÃÿ¿¿ÅÅÅÅÅÅÅÅÅÆÆÆÅÅÅÀÀÀÂÂÂÅÅÅÃÃÿ¿¿¾¾¾¾¾¾¿¿¿ÂÂÂÃÃÃÉÉÉÅÅÅÀÀÀ¼¼¼»»»»»»ÀÀÀÅÅÅÊÊÊÌÌÌÍÍÍÑÑÑÔÔÔÒÒÒÐÐÐÑÑÑÊÊÊÎÎÎÕÕÕÜÜÜÛÛÛÔÔÔÔÔÔØØØÕÕÕØØØÙÙÙÔÔÔÊÊÊÆÆÆÉÉÉÍÍÍÌÌÌÍÍÍÐÐÐÐÐÐÎÎÎÑÑÑÕÕÕÙÙÙÛÛÛØØØ×××ÕÕÕÒÒÒÎÎÎÊÊÊÉÉÉÐÐÐÑÑÑâââãããßßßâââ×××ÌÌÌÅÅÅÀÀÀÂÂÂÆÆÆÉÉÉÇÇÇÉÉÉÍÍÍÊÊÊÉÉÉÅÅÅÃÃÃÅÅÅÅÅÅÅÅÅÅÅÅÇÇÇÊÊÊÉÉÉÉÉÉÊÊÊÑÑÑÕÕÕ×××ÐÐÐ×××ØØØÔÔÔÑÑÑÔÔÔ××××××ÙÙÙßßßØØØÎÎÎÑÑÑÙÙÙÜÜÜÝÝÝÙÙÙØØØÔÔÔÑÑÑÑÑÑÒÒÒÒÒÒÑÑÑÒÒÒÒÒÒÑÑÑÎÎÎÌÌÌÍÍÍÐÐÐÔÔÔÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÔÔÔÔÔÔÔÔÔÕÕÕ×××ØØØÛÛÛÜÜÜÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÛÛÛÝÝÝÛÛÛÕÕÕÐÐÐÑÑÑÛÛÛäääçççãããØØØÌÌÌÂÂÂÃÃÃÊÊÊÍÍÍÎÎÎÎÎÎÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÎÎÎÌÌÌÉÉÉÎÎÎÇÇÇÅÅÅÉÉÉÉÉÉÉÉÉÍÍÍÕÕÕßßßÝÝÝäääÜÜÜÑÑÑÕÕÕÝÝÝçççîîîãããêêêÔÔÔÒÒÒÑÑÑÕÕÕÔÔÔÒÒÒÒÒÒÑÑÑÐÐÐÍÍÍÌÌÌÊÊÊÊÊÊÆÆÆÃÃÃÃÃþ¾¾ÂÂÂÃÃúºº···³³³µµµ¾¾¾···ººº»»»ººº°°°´´´ººº¾¾¾¿¿¿»»»»»»ÀÀÀÇÇÇÇÇÇÉÉÉÀÀÀÃÃÃÆÆÆ¿¿¿ÉÉɼ¼¼¾¾¾ÉÉÉÍÍÍÍÍÍÑÑÑÍÍÍÎÎÎÎÎÎÎÎÎÍÍÍÉÉÉÆÆÆÃÃÃÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀ¿¿¿ÂÂÂÅÅÅÂÂÂÀÀÀ¿¿¿¼¼¼¼¼¼¾¾¾¿¿¿¿¿¿ÀÀÀ¿¿¿ÂÂÂÊÊÊÑÑÑÕÕÕÙÙÙÝÝÝÛÛÛÕÕÕÊÊÊÉÉÉÎÎÎÎÎÎÌÌÌÎÎÎÐÐÐÔÔÔÜÜÜããããããÝÝÝÝÝÝâââààààààßßßÙÙÙÒÒÒÍÍÍÍÍÍÎÎÎÌÌÌÐÐÐÑÑÑÐÐÐÌÌÌÌÌÌÎÎÎÒÒÒÑÑÑÎÎÎÐÐÐÔÔÔÕÕÕÕÕÕÕÕÕ×××ßßßÛÛÛçççèèèçççêêêÛÛÛÌÌ̾¾¾ÀÀÀÃÃÃÅÅÅÇÇÇÉÉÉÊÊÊÊÊÊÉÉÉÇÇÇÅÅÅÃÃÃÃÃÃÃÃÃÅÅÅÅÅÅÇÇÇÊÊÊÊÊÊÇÇÇÊÊÊÒÒÒÒÒÒÎÎÎÃÃÃÌÌÌÒÒÒÑÑÑÑÑÑÔÔÔÕÕÕÕÕÕÐÐÐÕÕÕÒÒÒÊÊÊÎÎÎÙÙÙßßßÝÝÝØØØØØØÒÒÒÊÊÊÊÊÊÑÑÑÕÕÕÒÒÒÒÒÒÑÑÑÍÍÍÉÉÉÆÆÆÉÉÉÎÎÎÒÒÒÎÎÎÎÎÎÎÎÎÐÐÐÑÑÑÑÑÑÒÒÒÒÒÒ×××××××××ØØØÙÙÙÛÛÛÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÙÙÙØØØÛÛÛÜÜÜßßßÙÙÙÔÔÔÔÔÔØØØÝÝÝÝÝÝÛÛÛÍÍÍÉÉÉÆÆÆÇÇÇÉÉÉÊÊÊÎÎÎÕÕÕÑÑÑÐÐÐÐÐÐÐÐÐÑÑÑÐÐÐÌÌÌÉÉÉÅÅÅÂÂÂÉÉÉ×××ÛÛÛ×××ÙÙÙãããÛÛÛÜÜÜßßßÙÙÙÒÒÒÔÔÔÝÝÝçççîîîäääêêêÒÒÒÔÔÔÒÒÒ××××××ÔÔÔÔÔÔÒÒÒÑÑÑÎÎÎÍÍÍÌÌÌÊÊÊÇÇÇÅÅÅÅÅÅÃÃÃÀÀÀÅÅÅÅÅźºº···µµµ···ÀÀÀ···¾¾¾»»»ººº±±±¼¼¼ÂÂÂÅÅÅÅÅÅ¿¿¿¼¼¼ÃÃÃÂÂÂÅÅÅÇÇÇÀÀÀºººÃÃÃÀÀÀ¼¼¼¼¼¼ÇÇÇÍÍÍÍÍÍÑÑÑÊÊÊÌÌÌÍÍÍÎÎÎÍÍÍÊÊÊÇÇÇÆÆÆ¿¿¿¿¿¿¿¿¿¼¼¼»»»¿¿¿ÃÃÃÇÇÇÂÂÂÀÀÀ¿¿¿¾¾¾¼¼¼¼¼¼¾¾¾¾¾¾¼¼¼ººº¼¼¼ÇÇÇÎÎÎÎÎÎÎÎÎÑÑÑäääØØØÇÇÇÃÃÃÍÍÍÉÉÉÀÀÀÃÃÃØØØÜÜÜäääêêêèèèàààÝÝÝàààÝÝÝÛÛÛØØØØØØÜÜÜÝÝÝÜÜÜÛÛÛÙÙÙÝÝÝßßßÜÜÜÕÕÕÎÎÎÍÍÍÎÎÎÕÕÕÒÒÒÔÔÔÛÛÛÝÝÝÝÝÝàààäääæææÝÝÝççççççèèèîîîàààÑÑÑ»»»¿¿¿ÃÃÃÅÅÅÆÆÆÊÊÊÊÊÊÉÉÉÉÉÉÇÇÇÆÆÆÃÃÃÂÂÂÃÃÃÃÃÃÅÅÅÍÍÍÑÑÑÑÑÑÎÎÎÑÑÑÕÕÕÑÑÑÉÉÉÉÉÉÒÒÒÙÙÙÙÙÙ×××ØØØØØØÕÕÕÎÎÎÒÒÒÒÒÒÎÎÎÒÒÒàààèèèæææ×××ÛÛÛÙÙÙÔÔÔÒÒÒ××××××ÒÒÒÒÒÒÐÐÐÌÌÌÆÆÆÅÅÅÆÆÆÌÌÌÐÐÐÍÍÍÍÍÍÎÎÎÐÐÐÑÑÑÑÑÑÒÒÒÒÒÒØØØØØØØØØÙÙÙÛÛÛÜÜÜÝÝÝßßßßßßââââââàààÜÜÜØØØØØØØØØßßßÛÛÛ×××ÕÕÕÕÕÕÕÕÕÔÔÔÒÒÒÌÌÌÉÉÉÊÊÊÎÎÎÐÐÐÎÎÎÐÐÐÔÔÔÒÒÒÑÑÑÐÐÐÑÑÑÒÒÒÑÑÑÍÍÍÉÉÉÉÉÉÉÉÉÒÒÒâââäääÜÜÜÜÜÜäääããããããÜÜÜÛÛÛÛÛÛÜÜÜãããçççëëëæææêêêÔÔÔ×××ÔÔÔÕÕÕ×××ÕÕÕÔÔÔÒÒÒÑÑÑÐÐÐÍÍÍÌÌÌÌÌÌÇÇÇÅÅÅÆÆÆÆÆÆÅÅÅÇÇÇÅÅÅ···¸¸¸ººº¸¸¸ÃÃ÷··ÀÀÀ¼¼¼ººº´´´ÂÂÂÇÇÇÅÅÅÆÆÆÀÀÀ¼¼¼ÃÃþ¾¾ÂÂÂÇÇÇÂÂÂÂÂÂÀÀÀ···¿¿¿¿¿¿ÀÀÀ¼¼¼¾¾¾ÉÉÉÎÎÎÍÍÍÑÑÑÍÍÍÍÍÍÎÎÎÎÎÎÍÍÍÉÉÉÆÆÆÃÃþ¾¾ÀÀÀ¿¿¿¼¼¼»»»¿¿¿ÅÅÅÆÆÆÀÀÀ¿¿¿¾¾¾¾¾¾¼¼¼¼¼¼¼¼¼¾¾¾¿¿¿¸¸¸ºººÇÇÇÒÒÒÕÕÕ×××ÛÛÛÒÒÒÎÎÎÂÂÂÅÅÅÑÑÑÌÌÌÀÀÀÇÇÇàààãããçççêêêãããÙÙÙÕÕÕ×××ØØØÔÔÔÑÑÑÕÕÕÝÝÝãããâââÝÝÝÜÜÜàààääääääâââÝÝÝÜÜÜÜÜÜãããààààààæææãããßßßâââèèèâââÛÛÛããããããäääíííâââ×××¾¾¾¿¿¿ÂÂÂÅÅÅÉÉÉÊÊÊÊÊÊÉÉÉÉÉÉÉÉÉÇÇÇÅÅÅÃÃÃÃÃÃÅÅÅÇÇÇÍÍÍÎÎÎÐÐÐÑÑÑÑÑÑÑÑÑÊÊÊÃÃÃÉÉÉÔÔÔÛÛÛÜÜÜÛÛÛÜÜÜÜÜÜÙÙÙØØØÙÙÙØØØÑÑÑÐÐÐÛÛÛãããÝÝÝØØØÙÙÙØØØÒÒÒÐÐÐÑÑÑÔÔÔÔÔÔÑÑÑÐÐÐÌÌÌÇÇÇÅÅÅÆÆÆÊÊÊÎÎÎÍÍÍÎÎÎÎÎÎÐÐÐÑÑÑÑÑÑÒÒÒÒÒÒ××××××ØØØØØØÙÙÙÜÜÜÝÝÝßßßàààââââââàààÝÝÝÙÙÙ×××ÕÕÕÙÙÙÕÕÕÔÔÔÔÔÔÔÔÔÑÑÑÑÑÑÒÒÒØØØÑÑÑÎÎÎ×××ÜÜÜÛÛÛÒÒÒÎÎÎÒÒÒÒÒÒÒÒÒÔÔÔÒÒÒÑÑÑÎÎÎÌÌÌÍÍÍÍÍÍÕÕÕÝÝÝßßßÛÛÛÝÝÝäääääääää××××××ÜÜÜÜÜÜààààààçççäääêêêÕÕÕÙÙÙÕÕÕÔÔÔÕÕÕÕÕÕÕÕÕÔÔÔÑÑÑÐÐÐÎÎÎÍÍÍÌÌÌÇÇÇÅÅÅÆÆÆÇÇÇÆÆÆÉÉÉÅÅÅ···¸¸¸¼¼¼ºººÆÆƵµµÃÃü¼¼ººº³³³ÅÅÅÆÆÆÂÂÂÅÅÅ¿¿¿ºººÀÀÀ¼¼¼ÂÂÂÇÇÇ¿¿¿µµµ¾¾¾¾¾¾ÀÀÀ¼¼¼¿¿¿ÌÌÌÎÎÎÍÍÍÑÑÑÍÍÍÎÎÎÎÎÎÎÎÎÍÍÍÉÉÉÆÆÆÃÃÃÀÀÀÅÅÅÅÅÅÀÀÀ¿¿¿ÂÂÂÃÃþ¾¾¼¼¼¼¼¼¼¼¼»»»»»»»»»¼¼¼ººº±±±´´´ÅÅÅÒÒÒÕÕÕØØØÜÜÜØØØÛÛÛÕÕÕ×××ÜÜÜÐÐÐÇÇÇ×××äääãããäääãããÜÜÜÒÒÒÑÑÑÔÔÔÙÙÙ×××ÔÔÔÕÕÕÙÙÙÜÜÜÛÛÛÙÙÙ×××ÙÙÙÝÝÝâââããããããããããããäääâââãããæææâââÙÙÙÝÝÝèèèêêêäääíííëëëêêêïïïçççÜÜÜÃÃÃÀÀÀÀÀÀÆÆÆÊÊÊÌÌÌÊÊÊÊÊÊÊÊÊÊÊÊÉÉÉÇÇÇÅÅÅÃÃÃÆÆÆÉÉÉÉÉÉÉÉÉÌÌÌÐÐÐÑÑÑÍÍÍÉÉÉÇÇÇÇÇÇÑÑÑÙÙÙÛÛÛÙÙÙÛÛÛÙÙÙØØØÔÔÔÒÒÒÒÒÒÍÍÍÌÌÌÙÙÙæææàààÙÙÙ×××ÔÔÔÐÐÐÍÍÍÊÊÊÎÎÎÔÔÔÐÐÐÎÎÎÍÍÍÉÉÉÆÆÆÆÆÆÉÉÉÌÌÌÎÎÎÎÎÎÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÒÒÒÕÕÕÕÕÕ××××××ØØØÛÛÛÜÜÜÝÝÝàààßßßÝÝÝÝÝÝÜÜÜÛÛÛØØØ××××××ÒÒÒÑÑÑÒÒÒÒÒÒÑÑÑÔÔÔØØØÜÜÜÕÕÕÔÔÔÜÜÜãããßßßØØØÒÒÒÔÔÔÕÕÕ×××ÕÕÕÔÔÔÑÑÑÐÐÐÎÎÎÃÃÃÍÍÍÙÙÙââââââÝÝÝÛÛÛÜÜÜâââæææÕÕÕÔÔÔÙÙÙ×××ÛÛÛÜÜÜâââãããêêê×××ÝÝÝ×××ÑÑÑÒÒÒÕÕÕÔÔÔÒÒÒÑÑÑÐÐÐÍÍÍÌÌÌÌÌÌÊÊÊÅÅÅÅÅÅÆÆÆÅÅÅÉÉÉÆÆƸ¸¸¸¸¸¿¿¿»»»ÉÉɵµµÆÆƼ¼¼ººº´´´ÇÇÇÉÉÉÃÃÃÉÉɸ¸¸¾¾¾¾¾¾ÃÃÃÉÉÉÂÂÂÀÀÀ¿¿¿µµµ¿¿¿¾¾¾ÀÀÀ¾¾¾ÀÀÀÍÍÍÐÐÐÍÍÍÐÐÐÊÊÊÌÌÌÍÍÍÎÎÎÍÍÍÊÊÊÇÇÇÆÆÆÃÃÃÉÉÉÊÊÊÆÆÆÃÃÃÅÅÅÃÃÿ¿¿»»»»»»»»»ººººººººº»»»»»»µµµ¯¯¯³³³ÆÆÆÔÔÔÔÔÔÒÒÒÔÔÔÕÕÕÝÝÝÛÛÛØØØØØØÊÊÊÌÌÌäääãããâââàààßßßØØØÒÒÒÔÔÔÛÛÛ×××ØØØØØØØØØ×××ØØØÙÙÙÛÛÛØØØØØØÙÙÙÙÙÙÛÛÛÛÛÛÙÙÙØØØÙÙÙØØØÛÛÛàààÛÛÛÔÔÔÛÛÛèèèëëëæææïïïëëëæææèèèÝÝÝÔÔÔÇÇÇÀÀÀ¿¿¿ÇÇÇÍÍÍÌÌÌÊÊÊÌÌÌÊÊÊÌÌÌÊÊÊÉÉÉÅÅÅÅÅÅÇÇÇÊÊÊÍÍÍÊÊÊÍÍÍÔÔÔ×××ÑÑÑÑÑÑÔÔÔÒÒÒÛÛÛàààÝÝÝÙÙÙ×××ÔÔÔÑÑÑÕÕÕÔÔÔÒÒÒÎÎÎÌÌÌÜÜÜèèèããã××××××ÛÛÛßßßÛÛÛÑÑÑÍÍÍÐÐÐÎÎÎÎÎÎÎÎÎÌÌÌÉÉÉÇÇÇÉÉÉÊÊÊÎÎÎÐÐÐÐÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÕÕÕÕÕÕÕÕÕÕÕÕØØØÙÙÙÛÛÛÜÜÜàààÝÝÝÛÛÛÙÙÙÛÛÛÜÜÜÛÛÛÙÙÙØØØÒÒÒÐÐÐÑÑÑÑÑÑÐÐÐÕÕÕÜÜÜÔÔÔÔÔÔØØØßßßàààÜÜÜÛÛÛÜÜÜÔÔÔÕÕÕØØØ×××ÔÔÔÑÑÑÐÐÐÑÑÑÐÐÐ×××ÜÜÜÜÜÜÙÙÙÙÙÙÛÛÛÜÜÜæææíííÜÜÜÙÙÙÜÜÜ×××ÝÝÝàààßßßãããëëëØØØàààØØØÐÐÐÐÐÐÕÕÕÔÔÔÒÒÒÑÑÑÐÐÐÍÍÍÌÌÌÌÌÌÌÌÌÆÆÆÅÅÅÃÃÃÃÃÃÉÉÉÆÆƺºº¸¸¸ÀÀÀ»»»ÊÊʵµµÇÇǼ¼¼ººº···ÌÌÌÍÍÍÉÉÉÎÎÎÇÇÇ»»»¾¾¾Â¿¿¿ÀÀÀÉÉÉÆÆƾ¾¾ÀÀÀÆÆƼ¼¼¿¿¿ÉÉɺººÕÕÕÎÎÎÕÕÕÐÐÐÌÌÌÍÍÍÇÇÇÉÉÉÑÑÑÑÑÑÍÍÍÍÍÍÌÌÌÌÌÌÎÎÎÒÒÒÒÒÒÎÎÎÅÅž¾¾¸¸¸···¸¸¸ººº»»»ºººµµµ³³³¬¬¬°°°ÂÂÂÑÑÑÐÐÐÍÍÍÐÐÐÑÑÑØØØÛÛÛÑÑÑÔÔÔÎÎÎÊÊÊÝÝÝçççÛÛÛãããÜÜÜÝÝÝ×××ÍÍÍÒÒÒÎÎÎÕÕÕÛÛÛßßßâââßßßÙÙÙ×××ÕÕÕÝÝÝÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜßßßÙÙÙÙÙÙÙÙÙÛÛÛÜÜÜßßßâââäääãããæææíííîîîççççççâââÔÔÔÕÕÕÎÎÎÂÂÂÀÀÀÌÌÌÎÎÎÌÌÌÎÎÎÊÊÊÊÊÊÉÉÉÇÇÇÇÇÇÇÇÇÆÆÆÆÆÆÊÊÊÐÐÐÔÔÔÔÔÔÒÒÒÔÔÔÔÔÔÔÔÔàààÙÙÙÕÕÕÕÕÕÕÕÕÒÒÒÒÒÒÔÔÔÒÒÒÎÎÎÐÐÐÍÍÍÆÆÆãããââââââßßßàààëëëíííÛÛÛÍÍÍÌÌÌÌÌÌÑÑÑÐÐÐÐÐÐÎÎÎÍÍÍÌÌÌÉÉÉÉÉÉÐÐÐÉÉÉÇÇÇÎÎÎÒÒÒÐÐÐÍÍÍÍÍÍÑÑÑÔÔÔÕÕÕ×××ÙÙÙÛÛÛÝÝÝâââÝÝÝÜÜÜÙÙÙÙÙÙÛÛÛÛÛÛÙÙÙ××××××ÕÕÕÑÑÑÎÎÎÍÍÍÎÎÎÒÒÒÕÕÕÝÝÝÔÔÔØØØààààààßßßßßßÛÛÛÛÛÛÜÜÜÙÙÙÕÕÕÕÕÕØØØÕÕÕÎÎÎÊÊÊÔÔÔÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛãããÝÝÝãããèèèàààÜÜÜßßßÝÝÝäääâââèèèèèèÛÛÛÒÒÒÒÒÒÒÒÒÕÕÕ×××××××××ÔÔÔÑÑÑÍÍÍÊÊÊÂÂÂÅÅÅÆÆÆÉÉÉÉÉÉÇÇÇÆÆÆÅÅž¾¾ÆÆÆÍÍÍÅÅż¼¼ÃÃÃÆÆƾ¾¾¸¸¸ÊÊÊÊÊÊÌÌÌÍÍÍÉÉÉÍÍÍÎÎÎÆÆÆ¿¿¿ÂÂÂÆÆÆÅÅÅ¿¿¿¼¼¼ÆÆƾ¾¾¾¾¾ÃÃ÷··ÑÑÑÌÌÌÒÒÒÌÌÌÌÌÌÑÑÑÎÎÎÍÍÍÑÑÑÎÎÎÊÊÊÎÎÎÌÌÌÍÍÍÐÐÐÒÒÒÒÒÒÎÎÎÇÇÇÂÂÂÅÅÅÃÃÃÂÂÂÀÀÀÀÀÀ¼¼¼¸¸¸´´´¯¯¯³³³ÆÆÆÒÒÒÊÊÊÉÉÉÐÐÐÐÐÐÔÔÔ×××ÑÑÑÕÕÕÐÐÐÇÇÇÔÔÔØØØÛÛÛÝÝÝÕÕÕØØØÔÔÔÍÍÍÑÑÑÌÌÌÍÍÍÎÎÎÐÐÐÐÐÐÎÎÎÍÍÍÌÌÌÌÌÌÜÜÜÝÝÝÜÜÜÙÙÙ××××××ÔÔÔÒÒÒØØØØØØØØØÙÙÙÛÛÛÝÝÝßßßàààâââàààäääççççççêêêæææÙÙÙØØØÕÕÕÉÉÉÂÂÂÊÊÊÌÌÌÉÉÉÉÉÉÊÊÊÊÊÊÉÉÉÇÇÇÆÆÆÆÆÆÇÇÇÉÉÉÑÑÑÌÌÌÊÊÊÎÎÎÑÑÑÒÒÒØØØàààßßßÙÙÙÕÕÕ××××××ÔÔÔÒÒÒÕÕÕÔÔÔÑÑÑÐÐÐÌÌÌÅÅÅââââââàààãããâââçççççç×××ÍÍÍÍÍÍÍÍÍÑÑÑÐÐÐÎÎÎÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÒÒÒÍÍÍÊÊÊÍÍÍÐÐÐÎÎÎÍÍÍÐÐÐÌÌÌÐÐÐÔÔÔÔÔÔÔÔÔÕÕÕÜÜÜãããÝÝÝÜÜÜÛÛÛÙÙÙÙÙÙØØØ×××ÕÕÕÐÐÐÎÎÎÍÍÍÎÎÎÑÑÑÔÔÔ×××ØØØØØØÑÑÑØØØãããâââÝÝÝÙÙÙÒÒÒàààâââßßßÛÛÛÙÙÙÙÙÙÔÔÔÍÍÍÐÐÐØØØßßßßßßßßßâââãããâââÝÝÝØØØÝÝÝãããÝÝÝÜÜÜââââââäääßßßâââÝÝÝÐÐÐÇÇÇÌÌÌÍÍÍÑÑÑÒÒÒÒÒÒÔÔÔÔÔÔÒÒÒÒÒÒÑÑÑÇÇÇÃÃÿ¿¿¾¾¾¾¾¾ÃÃÃÇÇÇÌÌÌ···ÃÃÃÎÎÎÇÇÇ»»»¾¾¾ÃÃþ¾¾ºººÌÌÌÊÊÊÊÊÊÌÌÌÆÆÆÊÊÊÌÌÌÌÌÌ¿¿¿ÂÂÂÅÅÅÀÀÀÃÃúººÆÆÆ¿¿¿»»»¾¾¾´´´ÍÍÍÉÉÉÐÐÐÉÉÉÊÊÊÔÔÔÔÔÔÑÑÑÑÑÑÊÊÊÇÇÇÎÎÎÊÊÊÍÍÍÒÒÒÔÔÔÒÒÒÎÎÎÊÊÊÉÉÉÌÌÌÊÊÊÇÇÇÆÆÆÅÅÅÀÀÀ»»»¸¸¸¯¯¯°°°ÇÇÇÒÒÒÆÆÆÆÆÆÒÒÒÑÑÑÑÑÑÒÒÒÍÍÍÐÐÐÍÍÍÉÉÉÑÑÑÔÔÔÜÜÜÛÛÛÒÒÒÔÔÔÒÒÒÐÐÐÔÔÔÐÐÐÑÑÑÎÎÎÊÊÊÉÉÉÉÉÉÌÌÌÍÍÍÍÍÍÑÑÑØØØÛÛÛØØØÙÙÙßßßßßßÙÙÙÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝßßßßßßâââÜÜÜßßßâââäääëëëëëëâââ×××ÛÛÛÐÐÐÅÅÅÇÇÇÌÌÌÉÉÉÉÉÉÉÉÉÊÊÊÊÊÊÇÇÇÅÅÅÆÆÆÉÉÉÍÍÍÒÒÒÅÅÅÀÀÀÌÌÌÔÔÔÕÕÕÜÜÜèèèÝÝÝØØØÕÕÕØØØØØØÕÕÕÔÔÔÕÕÕÔÔÔÔÔÔÎÎÎÊÊÊÃÃÃàààããããããêêêããããããàààÒÒÒÌÌÌÎÎÎÐÐÐÑÑÑÎÎÎÍÍÍÊÊÊÊÊÊÌÌÌÎÎÎÐÐÐ×××ÑÑÑÍÍÍÍÍÍÍÍÍÍÍÍÎÎÎÑÑÑÐÐÐÒÒÒ×××ÒÒÒÊÊÊÊÊÊÒÒÒÙÙÙÛÛÛÜÜÜÜÜÜÛÛÛØØØÕÕÕÒÒÒÒÒÒÍÍÍÌÌÌÊÊÊÍÍÍÒÒÒ×××ØØØ×××ÜÜÜ×××ßßßêêêêêêèèèæææßßßäääæææäääàààÝÝÝÜÜÜ×××ÑÑÑÑÑÑ×××ÛÛÛÜÜÜßßßæææèèèèèèàààÛÛÛÝÝÝâââÝÝÝÝÝÝäääçççêêêäääæææâââÒÒÒÉÉÉÌÌÌÍÍÍÑÑÑÑÑÑÐÐÐÐÐÐÑÑÑÑÑÑÒÒÒÔÔÔÍÍÍÉÉÉÃÃÿ¿¿ÀÀÀÆÆÆÎÎÎÔÔÔ»»»ÆÆÆÕÕÕÑÑÑÂÂÂÀÀÀÇÇÇÅÅż¼¼ÎÎÎÌÌÌÊÊÊÊÊÊÅÅÅÇÇÇÉÉÉÎÎξ¾¾ÂÂÂÃÃþ¾¾ÉÉɸ¸¸ÉÉÉÃÃû»»»»»µµµÊÊÊÉÉÉÎÎÎÇÇÇÊÊÊÒÒÒÒÒÒÑÑÑÑÑÑÌÌÌÆÆÆÊÊÊÆÆÆÍÍÍÕÕÕ×××ÔÔÔÐÐÐÍÍÍÍÍÍÉÉÉÇÇÇÆÆÆÆÆÆÆÆÆÅÅÅÀÀÀ¾¾¾¬¬¬¬¬¬ÃÃÃÒÒÒÇÇÇÌÌÌ×××ÐÐÐÐÐÐÌÌÌÅÅÅÃÃÃÆÆÆÍÍÍØØØÝÝÝÙÙÙÙÙÙ×××ÔÔÔÑÑÑÐÐÐÔÔÔ×××ØØØÒÒÒÍÍÍÌÌÌÍÍÍÑÑÑÒÒÒÔÔÔÎÎÎØØØÙÙÙÒÒÒÔÔÔÛÛÛÛÛÛÒÒÒâââàààßßßÝÝÝßßßàààâââããããããßßßàààâââàààæææëëëçççÔÔÔÛÛÛÒÒÒÃÃÃÆÆÆÍÍÍÍÍÍÌÌÌÇÇÇÊÊÊÊÊÊÇÇÇÅÅÅÆÆÆÌÌÌÑÑÑÌÌÌÀÀÀ¾¾¾ÉÉÉÕÕÕÙÙÙßßßçççÜÜÜØØØ×××ÙÙÙÙÙÙÕÕÕÔÔÔÔÔÔÔÔÔÕÕÕÊÊÊÇÇÇÅÅÅàààæææêêêñññçççãããßßßÒÒÒÌÌÌÎÎÎÎÎÎÐÐÐÎÎÎÌÌÌÉÉÉÊÊÊÍÍÍÑÑÑÔÔÔ×××ÔÔÔÑÑÑÐÐÐÎÎÎÍÍÍÎÎÎÐÐÐÑÑÑÐÐÐÒÒÒÎÎÎÆÆÆÆÆÆÍÍÍÐÐÐØØØÛÛÛÜÜÜÛÛÛ×××ÒÒÒÐÐÐÐÐÐÐÐÐÌÌÌÉÉÉÌÌÌÑÑÑÕÕÕÕÕÕÔÔÔ×××ÐÐÐÒÒÒÛÛÛßßßæææëëëçççääääääãããâââàààßßßÜÜÜÙÙÙÎÎÎÒÒÒÕÕÕ×××ÜÜÜæææëëëëëëêêêæææääääääãããâââçççíííëëëèèèíííëëëÛÛÛÐÐÐÎÎÎÍÍÍÔÔÔÒÒÒÑÑÑÎÎÎÍÍÍÌÌÌÌÌÌÌÌÌÊÊÊÉÉÉÇÇÇÆÆÆÇÇÇÊÊÊÍÍÍÎÎÎÃÃÃÆÆÆÒÒÒÒÒÒÅÅÅÅÅÅÌÌÌÇÇÇÂÂÂÒÒÒÎÎÎÌÌÌÊÊÊÅÅÅÇÇÇÇÇÇÐÐп¿¿ÀÀÀÅÅž¾¾ÌÌ̺ººÌÌÌÅÅÅ»»»¼¼¼¼¼¼ÌÌÌÌÌÌÐÐÐÉÉÉÌÌÌÐÐÐÍÍÍÍÍÍÒÒÒÐÐÐÇÇÇÆÆÆÃÃÃÌÌÌÕÕÕÙÙÙÕÕÕÑÑÑÎÎÎÎÎÎÉÉÉÇÇÇÆÆÆÆÆÆÇÇÇÇÇÇÅÅÅÃÃﯯÂÂÂÑÑÑÍÍÍÐÐÐÒÒÒÆÆÆÉÉɾ¾¾ººº¿¿¿ÌÌÌ×××ÝÝÝÒÒÒÕÕÕØØØÒÒÒÌÌÌÌÌÌÐÐÐØØØÕÕÕÑÑÑÍÍÍÌÌÌÎÎÎÑÑÑÒÒÒÒÒÒÜÜÜãããäääÝÝÝßßßêêêëëëæææãããàààÝÝÝÛÛÛÛÛÛÝÝÝàààãããäääâââææææææÜÜÜÝÝÝçççêêê×××ÜÜÜÑÑÑÂÂÂÅÅÅÌÌÌÌÌÌÊÊÊÇÇÇÉÉÉÊÊÊÇÇÇÆÆÆÇÇÇÎÎÎÔÔÔÅÅÅÀÀÀ¿¿¿ÃÃÃÎÎÎÙÙÙâââãããÜÜÜØØØ×××ÙÙÙÙÙÙÕÕÕÒÒÒÔÔÔÒÒÒÔÔÔÅÅÅÉÉÉÊÊÊàààèèèñññóóóèèèæææâââÔÔÔÍÍÍÍÍÍÌÌÌÎÎÎÍÍÍÌÌÌÊÊÊÌÌÌÎÎÎÒÒÒÕÕÕÔÔÔÕÕÕÕÕÕÒÒÒÑÑÑÐÐÐÎÎÎÍÍÍÊÊÊÆÆÆÊÊÊÍÍÍÇÇÇÌÌÌÒÒÒÐÐÐÔÔÔ×××ÙÙÙÙÙÙÕÕÕÑÑÑÎÎÎÎÎÎÐÐÐÊÊÊÆÆÆÇÇÇÍÍÍÒÒÒÔÔÔÔÔÔÙÙÙÒÒÒÔÔÔÙÙÙÝÝÝêêêòòòïïïçççæææäääâââßßßÜÜÜÛÛÛÜÜÜÐÐÐÒÒÒÕÕÕÕÕÕÜÜÜæææëëëëëëëëëèèèççççççæææäääèèèñññæææâââæææäääÕÕÕÌÌÌÍÍÍÍÍÍÒÒÒÑÑÑÐÐÐÎÎÎÌÌÌÇÇÇÆÆÆÃÃÃÂÂÂÃÃÃÅÅÅÆÆÆÆÆÆÅÅÅÃÃÃÃÃÃÇÇǼ¼¼ÅÅÅÊÊÊÀÀÀÂÂÂÉÉÉÂÂÂÆÆÆÕÕÕÑÑÑÎÎÎÍÍÍÆÆÆÊÊÊÊÊÊÐÐÐÅÅÅÀÀÀÊÊʾ¾¾ÊÊÊ»»»ÍÍÍÅÅÅ»»»¿¿¿ÆÆÆÐÐÐÐÐÐÑÑÑÌÌÌÎÎÎÐÐÐÌÌÌÌÌÌÒÒÒÐÐÐÇÇÇÆÆÆÃÃÃÌÌÌÔÔÔØØØÕÕÕÐÐÐÎÎÎÎÎÎÎÎÎÍÍÍÊÊÊÉÉÉÉÉÉÇÇÇÅÅÅÃÃñ±±¸¸¸ÆÆÆÐÐÐÎÎÎÎÎÎÉÉɼ¼¼¿¿¿»»»¼¼¼···»»»ÇÇÇÌÌÌÑÑÑÌÌÌÎÎÎ×××ÑÑÑÉÉÉÊÊÊÊÊÊÒÒÒÑÑÑÐÐÐÎÎÎÎÎÎÐÐÐÑÑÑÑÑÑÑÑÑÊÊÊÐÐÐÑÑÑÎÎÎÒÒÒÜÜÜàààÝÝÝÝÝÝÛÛÛØØØÕÕÕÕÕÕØØØÛÛÛÝÝÝâââàààççççççÜÜÜÙÙÙâââæææßßßÝÝÝÍÍÍ¿¿¿ÃÃÃÉÉÉÇÇÇÅÅÅÆÆÆÇÇÇÉÉÉÉÉÉÉÉÉÌÌÌÐÐÐÕÕÕÅÅÅÃÃÃÀÀÀ¾¾¾ÅÅÅÒÒÒÝÝÝâââßßßÙÙÙÕÕÕØØØ×××ÒÒÒÑÑÑÑÑÑÐÐÐÐÐÐÂÂÂÑÑÑ×××àààçççõõõñññçççäääâââÔÔÔÍÍÍÌÌÌÊÊÊÍÍÍÌÌÌÌÌÌÍÍÍÎÎÎÐÐÐÒÒÒÔÔÔÑÑÑÔÔÔÕÕÕÕÕÕÔÔÔÒÒÒÎÎÎÉÉÉÉÉÉÅÅÅÍÍÍÒÒÒÊÊÊÌÌÌÑÑÑÊÊÊÎÎÎÒÒÒÕÕÕØØØ×××ÒÒÒÐÐÐÍÍÍÌÌÌÇÇÇÃÃÃÅÅÅÊÊÊÐÐÐÔÔÔÕÕÕÌÌÌÇÇÇÌÌÌÐÐÐÒÒÒÜÜÜàààÙÙÙëëëèèèçççäääßßßØØØ×××ØØØÕÕÕÙÙÙÛÛÛÛÛÛÝÝÝäääèèèèèèæææçççäääæææèèèçççèèèòòòèèèââââââÜÜÜÎÎÎÉÉÉÐÐÐÔÔÔÐÐÐÎÎÎÎÎÎÍÍÍÌÌÌÉÉÉÆÆÆÆÆÆÅÅÅÅÅÅÅÅÅÃÃÃÅÅÅÆÆÆÇÇÇÇÇÇÎÎλ»»ÀÀÀÊÊÊÂÂÂÅÅÅÌÌÌÃÃÃÆÆÆ×××ÑÑÑÎÎÎÎÎÎÉÉÉÍÍÍÎÎÎÑÑÑÍÍÍÃÃÃÐÐп¿¿ÆÆÆ»»»ÊÊÊÀÀÀºººÂÂÂÎÎÎÒÒÒÒÒÒÒÒÒÌÌÌÒÒÒÕÕÕÑÑÑÎÎÎÑÑÑÎÎÎÇÇÇÉÉÉÆÆÆÌÌÌÑÑÑÒÒÒÑÑÑÎÎÎÎÎÎÎÎÎÎÎÎÌÌÌÉÉÉÆÆÆÆÆÆÅÅÅ¿¿¿°°°ÂÂÂÍÍÍÍÍÍÍÍÍÇÇÇÀÀÀ¿¿¿¼¼¼»»»ÀÀÀººº¼¼¼ÉÉÉÉÉÉÍÍÍÎÎÎÍÍÍÕÕÕÑÑÑÐÐÐÑÑÑÉÉÉÍÍÍÎÎÎÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÑÒÒÒÑÑÑÒÒÒÑÑÑÐÐÐÐÐÐÐÐÐÐÐÐÎÎÎ××××××ÕÕÕÕÕÕÕÕÕ×××ØØØÙÙÙÜÜÜØØØßßßäääßßßÜÜÜßßßÝÝÝäääÙÙÙÅÅÅ»»»ÃÃÃÉÉÉÅÅÅÅÅÅÅÅÅÆÆÆÇÇÇÉÉÉÌÌÌÎÎÎÒÒÒÔÔÔÃÃÃÂÂÂÂÂÂÂÂÂÃÃÃÇÇÇÒÒÒÝÝÝàààÙÙÙÕÕÕÕÕÕÕÕÕÑÑÑÎÎÎÐÐÐÌÌÌÍÍÍÂÂÂÝÝÝäääàààâââòòòèèèààààààÝÝÝÑÑÑÊÊÊÌÌÌÌÌÌÊÊÊÌÌÌÎÎÎÐÐÐÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÒÒÒÔÔÔÔÔÔÕÕÕÕÕÕÐÐÐÆÆÆÉÉÉÉÉÉÙÙÙÜÜÜÌÌÌÇÇÇÍÍÍÆÆÆÊÊÊÍÍÍÑÑÑÕÕÕØØØÕÕÕÑÑÑÍÍÍÉÉÉÇÇÇÅÅÅÅÅÅÇÇÇÌÌÌÎÎÎÑÑÑÐÐÐÎÎÎÒÒÒ×××ÙÙÙâââäääÜÜÜêêêèèèèèèêêêãããÙÙÙÕÕÕ×××ÙÙÙßßßâââÝÝÝÛÛÛÜÜÜÝÝÝÜÜÜæææêêêèèèêêêîîîèèèçççñññîîîæææãããÝÝÝÐÐÐÌÌÌÒÒÒØØØÑÑÑÑÑÑÎÎÎÍÍÍÌÌÌÊÊÊÊÊÊÊÊÊÊÊÊÇÇÇÆÆÆÅÅÅÆÆÆÊÊÊÐÐÐÒÒÒÑÑѼ¼¼ÆÆÆÒÒÒÇÇÇÆÆÆÐÐÐÉÉÉÅÅÅÔÔÔÐÐÐÎÎÎÍÍÍÉÉÉÎÎÎÑÑÑÔÔÔÔÔÔÅÅÅÕÕÕ¿¿¿ÃÃúººÇÇǾ¾¾¸¸¸ÃÃÃÒÒÒÔÔÔÔÔÔÒÒÒÍÍÍÔÔÔÛÛÛØØØÒÒÒÐÐÐÊÊÊÇÇÇÍÍÍÉÉÉÌÌÌÎÎÎÎÎÎÍÍÍÍÍÍÎÎÎÐÐÐÇÇÇÅÅÅÂÂÂÀÀÀÀÀÀÀÀÀ¾¾¾¼¼¼ªªªÅÅÅÐÐÐÌÌÌÊÊÊÃÃÿ¿¿ÇÇÇÀÀÀ¿¿¿ÅÅż¼¼¾¾¾ÍÍÍÎÎÎÕÕÕ×××ÐÐÐ×××ÕÕÕØØØÜÜÜÍÍÍÌÌÌÉÉÉÊÊÊÌÌÌÊÊÊÉÉÉÉÉÉÌÌÌÎÎÎÍÍÍÍÍÍÎÎÎÑÑÑÑÑÑÎÎÎÎÎÎÎÎÎÔÔÔÕÕÕ×××ØØØÙÙÙÙÙÙØØØØØØØØØÐÐÐÕÕÕââââââàààÝÝÝØØØãããÔÔÔ¼¼¼···ÅÅÅÊÊÊÇÇÇÉÉÉÅÅÅÅÅÅÇÇÇÊÊÊÍÍÍÑÑÑÒÒÒÔÔÔ¿¿¿¾¾¾ÃÃÃÌÌÌÇÇÇÀÀÀÇÇÇ×××âââÛÛÛÕÕÕÔÔÔÒÒÒÎÎÎÍÍÍÐÐÐÊÊÊÌÌÌÃÃÃçççîîîàààÝÝÝîîîâââÛÛÛÛÛÛÛÛÛÎÎÎÉÉÉÍÍÍÎÎÎÉÉÉÌÌÌÎÎÎÒÒÒÒÒÒÒÒÒÐÐÐÎÎÎÐÐÐÒÒÒÒÒÒÑÑÑÔÔÔ×××ÐÐÐÆÆÆÀÀÀÇÇÇßßßãããÌÌÌÆÆÆÐÐÐÍÍÍÇÇÇÊÊÊÎÎÎÔÔÔØØØ×××ÒÒÒÍÍÍÊÊÊÊÊÊÉÉÉÇÇÇÆÆÆÆÆÆÇÇÇÉÉÉÑÑÑÎÎÎÒÒÒÕÕÕØØØäääêêêâââääääääêêêîîîèèèÝÝÝØØØØØØÛÛÛàààãããÝÝÝ×××ÔÔÔÒÒÒÐÐÐíííñññïïïïïïóóóëëëæææîîîëëëääääääàààÑÑÑÊÊÊÐÐÐÒÒÒØØØÕÕÕÑÑÑÍÍÍÊÊÊÊÊÊÌÌÌÍÍÍÃÃÃÂÂÂÂÂÂÂÂÂÆÆÆÊÊÊÐÐÐÒÒÒÊÊʸ¸¸ÆÆÆÔÔÔÅÅÅÀÀÀÌÌÌÇÇÇÂÂÂÒÒÒÎÎÎÌÌÌÍÍÍÉÉÉÐÐÐÑÑÑÔÔÔ×××ÎÎÎÃÃÃÑÑѺºº¸¸¸ÇÇÇÀÀÀºººÑÑÑÐÐÐ×××ÔÔÔÒÒÒÐÐÐÑÑÑÔÔÔÕÕÕÎÎÎÎÎÎÎÎÎÆÆÆÐÐÐÆÆÆÎÎÎÑÑÑÍÍÍÊÊÊÎÎÎÑÑÑÐÐÐÇÇÇ¿¿¿¿¿¿¾¾¾µµµ···¸¸¸°°°ÎÎÎÕÕÕÑÑÑÀÀÀºººÂÂÂÇÇÇÃÃÿ¿¿»»»»»»ÂÂÂÉÉÉÍÍÍÐÐÐÔÔÔÔÔÔÍÍÍÔÔÔÒÒÒÕÕÕÙÙÙÌÌÌÌÌÌÑÑÑÌÌÌÌÌÌÊÊÊÂÂÂÀÀÀÅÅÅÀÀÀÅÅÅÆÆÆÊÊÊÊÊÊÊÊÊÇÇÇÅÅÅÃÃÃÆÆÆÍÍÍÐÐÐÇÇÇÃÃÃÉÉÉÑÑÑ×××ÔÔÔÙÙÙÒÒÒ×××èèèçççÛÛÛÝÝÝãããßßßÙÙÙÒÒÒÍÍÍÉÉÉÆÆÆÃÃÃÂÂÂÃÃÃÆÆÆÉÉÉÍÍÍÔÔÔÛÛÛßßßÅÅÅ¿¿¿ÃÃÃÇÇÇÅÅÅÉÉÉÍÍÍÆÆÆØØØÜÜÜÑÑÑÑÑÑÒÒÒÐÐÐÕÕÕÉÉÉÌÌ̼¼¼ÃÃÃàààîîîãããàààëëëØØØÒÒÒÕÕÕÒÒÒÔÔÔÔÔÔÆÆÆÅÅÅÐÐÐÍÍÍÌÌÌÊÊÊÍÍÍÒÒÒØØØÛÛÛÎÎÎÐÐÐÑÑÑÔÔÔÍÍÍÔÔÔÛÛÛÀÀÀÅÅÅÎÎÎÜÜÜÙÙÙÊÊÊÊÊÊÑÑÑÍÍÍÉÉÉÉÉÉÌÌÌÑÑÑ××××××ÑÑÑÌÌÌÉÉÉÌÌÌÊÊÊÅÅÅÍÍÍÉÉÉÇÇÇêêêÎÎÎÍÍÍÑÑÑØØØÙÙÙÙÙÙßßßççççççïïïòòòêêêßßßÙÙÙ×××ÕÕÕÜÜÜÜÜÜÙÙÙÕÕÕÑÑÑÑÑÑÔÔÔ×××ØØØãããíííòòòóóóïïïäääÙÙÙíííãããêêêçççÍÍÍÆÆÆÑÑÑÎÎÎÑÑÑ×××ØØØÑÑÑÍÍÍÍÍÍÌÌÌÉÉÉÕÕÕÒÒÒÊÊÊÊÊÊÉÉÉÑÑÑÜÜÜÍÍ;¾¾ÂÂÂÆÆÆØØØÅÅÅÉÉÉÍÍÍ¿¿¿ÀÀÀ×××ØØØÎÎÎÐÐÐÔÔÔÑÑÑÑÑÑÔÔÔÔÔÔÊÊÊÊÊÊÕÕÕ¼¼¼ÂÂÂÇÇÇÅÅż¼¼ÊÊÊÒÒÒ×××ÔÔÔÒÒÒÐÐÐØØØØØØÛÛÛØØØÜÜÜÙÙÙÇÇÇÇÇÇÎÎÎÎÎÎÍÍÍÊÊÊÊÊÊÍÍÍÌÌÌÉÉÉÀÀÀÉÉÉ×××ÜÜÜ×××ÔÔÔ××××××ÙÙÙÎÎÎÇÇÇÉÉÉÇÇÇÀÀÀ¾¾¾¿¿¿ÊÊÊÆÆÆÅÅÅÉÉÉÎÎÎÎÎÎÑÑÑÔÔÔ¼¼¼¾¾¾ÊÊÊÍÍÍÑÑÑÕÕÕÇÇÇÃÃÃÊÊÊÉÉÉÊÊÊÆÆƸ¸¸···»»»»»»»»»¼¼¼¾¾¾ÀÀÀÂÂÂÂÂÂÃÃÃÃÃÃÂÂÂÇÇÇÉÉÉÅÅÅÂÂÂÇÇÇÎÎÎÑÑÑÕÕÕÜÜÜÕÕÕ×××çççæææÙÙÙÛÛÛêêêææææææçççÙÙÙÉÉÉÅÅÅÍÍÍÅÅÅÆÆÆÇÇÇÊÊÊÍÍÍÑÑÑØØØÜÜÜØØØÎÎÎÌÌÌÍÍÍÌÌÌÍÍÍÊÊÊÀÀÀÛÛÛâââØØØ×××ÔÔÔÐÐÐÔÔÔÌÌÌÊÊÊÂÂÂÉÉÉßßßêêêäääàààæææäääÛÛÛÙÙÙÔÔÔ×××ÙÙÙÎÎÎÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÎÎÎÑÑÑÔÔÔÕÕÕÙÙÙÙÙÙØØØØØØÊÊÊÊÊÊÕÕÕÂÂÂÇÇÇÇÇÇÌÌÌÌÌÌÇÇÇÌÌÌÍÍÍÅÅÅÅÅÅÅÅÅÆÆÆÌÌÌÑÑÑÑÑÑÍÍÍÉÉÉÇÇÇÇÇÇÉÉÉÃÃÃÇÇÇÆÆÆÅÅÅÜÜÜÐÐÐÐÐÐÒÒÒÙÙÙÜÜÜÛÛÛÝÝÝâââãããêêêëëëäääÜÜÜÙÙÙØØØ×××ÝÝÝÜÜÜØØØÕÕÕÒÒÒÒÒÒÔÔÔ×××ÔÔÔÛÛÛãããçççêêêêêêãããÛÛÛæææßßßÜÜÜÝÝÝ×××ÌÌÌÊÊÊÐÐÐÌÌÌÐÐÐÑÑÑÌÌÌÊÊÊÍÍÍÐÐÐÎÎÎÎÎÎÐÐÐÎÎÎÑÑÑÎÎÎÍÍÍÑÑÑÀÀÀ¿¿¿ÅÅÅÆÆÆÛÛÛÌÌÌÎÎÎÑÑÑÊÊÊÇÇÇÒÒÒ×××ÒÒÒÒÒÒÒÒÒÒÒÒÔÔÔ×××ÐÐÐÅÅÅÎÎÎØØØÀÀÀÍÍÍÉÉÉÇÇǾ¾¾¿¿¿××××××ÔÔÔÒÒÒÐÐÐÜÜÜØØØÙÙÙÙÙÙäääãããÌÌÌÇÇÇÔÔÔÍÍÍÇÇÇÇÇÇÊÊÊÉÉÉÆÆÆÅÅÅ¿¿¿ÎÎÎÛÛÛßßßÝÝÝ×××ÔÔÔØØØÙÙÙÊÊÊÅÅÅÌÌÌÊÊʼ¼¼µµµºººººº´´´±±±´´´µµµ³³³´´´···¿¿¿ÂÂÂÇÇÇÃÃÃÅÅÅÌÌÌÆÆÆÃÃÃÉÉÉÇÇÇÌÌÌÅÅŵµµ±±±¸¸¸ººº¯¯¯°°°±±±µµµººº¾¾¾ÀÀÀ¿¿¿ÅÅÅÆÆÆÅÅÅÆÆÆÊÊÊÎÎÎÐÐÐÔÔÔØØØÔÔÔÕÕÕããããããÛÛÛßßßææææææêêêëëëßßßÊÊÊÀÀÀÂÂÂÆÆÆÇÇÇÊÊÊÌÌÌÍÍÍÐÐÐÕÕÕØØØßßßØØØÔÔÔÑÑÑÌÌÌÍÍÍÐÐÐÌÌÌÝÝÝãããßßßÜÜÜØØØÒÒÒÕÕÕÑÑÑÅÅÅÍÍÍØØØàààãããââââââãããíííßßßÙÙÙÔÔÔØØØÝÝÝÒÒÒÐÐÐÊÊÊÌÌÌÍÍÍÎÎÎÐÐÐÐÐÐÎÎÎÎÎÎÉÉÉÎÎÎ×××àààÔÔÔÍÍÍÔÔÔÉÉÉÆÆÆÂÂÂÂÂÂÂÂÂÃÃÃÉÉÉÊÊÊÃÃÃÃÃÃÃÃÃÆÆÆÌÌÌÒÒÒ×××ÕÕÕÒÒÒÊÊÊÆÆÆÊÊÊÆÆÆÆÆÆÌÌÌÌÌÌÕÕÕÔÔÔÒÒÒÕÕÕÛÛÛÝÝÝÝÝÝÜÜÜÝÝÝàààääääääßßßÛÛÛÛÛÛÛÛÛÙÙÙßßßÜÜÜØØØÕÕÕÔÔÔÕÕÕÕÕÕÕÕÕÒÒÒ×××ÛÛÛÝÝÝâââçççæææàààããããããÙÙÙØØØÛÛÛÇÇǺººÅÅÅÊÊÊÍÍÍÍÍÍÊÊÊÊÊÊÎÎÎÒÒÒÒÒÒÌÌÌÎÎÎÑÑÑÒÒÒÑÑÑÆÆÆÇÇǺººÀÀÀÆÆÆÅÅÅÛÛÛÒÒÒÑÑÑÒÒÒÕÕÕÉÉÉÆÆÆÎÎÎÕÕÕÔÔÔÒÒÒØØØÛÛÛÜÜÜÇÇÇÅÅÅÍÍÍÔÔÔÅÅÅÐÐÐÉÉÉÆÆƾ¾¾···ØØØ×××ÕÕÕÕÕÕÔÔÔÜÜÜ×××ÕÕÕÔÔÔßßßâââÒÒÒÑÑÑÔÔÔÌÌÌÆÆÆÇÇÇÆÆÆÂÂÂÂÂÂÇÇÇÉÉÉÔÔÔÕÕÕ×××ßßßÛÛÛÔÔÔÙÙÙÊÊÊÍÍÍÍÍÍÇÇÇ¿¿¿ººº······¾¾¾¸¸¸·········³³³´´´···¸¸¸¾¾¾ÀÀÀ»»»¾¾¾ÇÇÇÊÊÊÉÉÉÃÃÿ¿¿ÀÀÀ¼¼¼±±±¯¯¯³³³±±±¦¦¦©©©¬¬¬³³³¸¸¸¼¼¼¾¾¾¾¾¾ÃÃÃÅÅÅÇÇÇÊÊÊÎÎÎÑÑÑÒÒÒÒÒÒÎÎÎÑÑÑÍÍÍÎÎÎÛÛÛàààßßßäääÝÝÝãããçççäääàààÕÕÕÃÃó³³ÃÃÃÇÇÇÊÊÊÍÍÍÍÍÍÎÎÎÔÔÔØØØÝÝÝßßßÝÝÝÕÕÕÉÉÉÇÇÇÒÒÒÜÜÜââââââßßßÝÝÝÜÜÜÙÙÙØØØÒÒÒÀÀÀØØØçççãããÜÜÜßßßääääääæææÙÙÙÕÕÕÒÒÒØØØÜÜÜÐÐÐÌÌÌÊÊÊÌÌÌÍÍÍÎÎÎÎÎÎÍÍÍÊÊÊÉÉÉÇÇÇÉÉÉÐÐÐÜÜÜÒÒÒÆÆÆÉÉÉÀÀÀÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀÅÅÅÇÇÇÇÇÇÃÃÃÅÅÅÇÇÇÎÎÎ×××ÜÜÜßßßÝÝÝÔÔÔÇÇÇÍÍÍÊÊÊÊÊÊ×××ØØØØØØ×××ÕÕÕÕÕÕÙÙÙÝÝÝßßßßßßßßßàààãããàààÜÜÜÛÛÛÝÝÝÝÝÝÛÛÛßßßÛÛÛ×××ÕÕÕ×××××××××ÕÕÕ×××ÙÙÙÛÛÛÜÜÜãããêêêêêêæææâââëëëæææâââäääÔÔÔÂÂÂÆÆÆÉÉÉÊÊÊÌÌÌÍÍÍÎÎÎÐÐÐÑÑÑÒÒÒÎÎÎÐÐÐÐÐÐÎÎÎÎÎο¿¿ÆÆƾ¾¾ÀÀÀÇÇÇÂÂÂØØØÔÔÔÐÐÐÎÎÎØØØÐÐÐÂÂÂÉÉÉØØØÕÕÕÑÑÑØØØÛÛÛßßßÂÂÂÉÉÉÆÆÆÊÊÊÇÇÇÊÊÊÇÇÇ»»»µµµØØØØØØ×××ØØØØØØÜÜÜÙÙÙÙÙÙÔÔÔÛÛÛÝÝÝÒÒÒØØØÍÍÍÉÉÉÇÇÇÆÆÆÀÀÀ¼¼¼ÃÃÃÎÎÎØØØÝÝÝÙÙÙ×××ÜÜÜØØØÑÑÑÕÕÕÇÇÇÐÐÐÐÐÐÃÃü¼¼¿¿¿¾¾¾¸¸¸»»»···µµµ···´´´±±±³³³···ºººÀÀÀÀÀÀ¿¿¿¼¼¼ººº···¯¯¯¸¸¸°°°ªªª¬¬¬¦¦¦¦¦¦©©©µµµ»»»¾¾¾»»»¸¸¸ÃÃÃÃÃÃÇÇÇÍÍÍÑÑÑÒÒÒÒÒÒÒÒÒÎÎÎÎÎÎÊÊÊÊÊÊÒÒÒØØØÜÜÜäääßßßæææêêêêêêèèèâââÑÑÑ¿¿¿¿¿¿ÅÅÅÊÊÊÍÍÍÍÍÍÐÐÐÔÔÔÙÙÙÝÝÝæææçççßßßÔÔÔÎÎÎÔÔÔÝÝÝëëëâââÜÜÜÛÛÛÜÜÜÛÛÛÒÒÒÍÍÍÉÉÉÝÝÝèèèâââÝÝÝäääçççàààÛÛÛÒÒÒÕÕÕÔÔÔÙÙÙÛÛÛÌÌÌÆÆÆÊÊÊÊÊÊÊÊÊÌÌÌÌÌÌÊÊÊÊÊÊÉÉÉÐÐÐÇÇÇ¿¿¿ÉÉÉÆÆƾ¾¾ÃÃÿ¿¿ÂÂÂÂÂÂÀÀÀÀÀÀÂÂÂÂÂÂÃÃÃÆÆÆÆÆÆÆÆÆÉÉÉÎÎÎÔÔÔØØØÛÛÛÜÜÜßßßÎÎÎÐÐÐÍÍÍÌÌÌÛÛÛÝÝÝØØØÙÙÙØØØ××××××ÜÜÜâââãããããããããäääâââÜÜÜÜÜÜßßßßßßÜÜÜßßßÛÛÛØØØ×××ØØØØØØØØØ×××ÛÛÛÜÜÜÜÜÜÝÝÝæææíííëëëæææäääêêêèèèãããâââÙÙÙÆÆÆ···ÂÂÂÂÂÂÅÅÅÊÊÊÍÍÍÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÐÐÐÍÍÍÒÒÒ¼¼¼ÆÆÆÅÅÅÆÆÆÌÌÌÅÅÅÛÛÛÕÕÕÐÐÐÍÍÍÕÕÕÝÝÝÌÌÌÎÎÎÛÛÛØØØÔÔÔ×××ØØØØØØÀÀÀÐÐÐÀÀÀÃÃÃÉÉÉÆÆÆÆÆƾ¾¾¸¸¸¾¾¾ÕÕÕ×××ÕÕÕÙÙÙÙÙÙÜÜÜÝÝÝâââÜÜÜßßßÜÜÜÎÎÎÒÒÒÉÉÉÉÉÉÉÉÉÃÃü¼¼¼¼¼ÇÇÇÔÔÔ×××ÝÝÝÝÝÝØØØÑÑÑÉÉÉÅÅÅÉÉÉÎÎÎÌÌÌÆÆÆÂÂÂÂÂÂÃÃÃÀÀÀ»»»¾¾¾»»»»»»¼¼¼»»»¸¸¸»»»ÀÀÀººº¾¾¾ººº¾¾¾¿¿¿»»»¼¼¼¸¸¸¸¸¸©©©¬¬¬³³³±±±¨¨¨¬¬¬°°°µµµ»»»¾¾¾»»»···¿¿¿¿¿¿ÃÃÃÊÊÊÎÎÎÍÍÍÍÍÍÎÎÎÑÑÑÑÑÑÍÍÍÊÊÊÍÍÍÑÑÑ×××ÜÜÜàààãããêêêîîîêêêàààÙÙÙ×××»»»ÂÂÂÊÊÊÎÎÎÎÎÎÐÐÐÕÕÕÙÙÙÛÛÛãããæææçççêêêäääßßßàààñññâââÜÜÜ××××××ÔÔÔÇÇÇÅÅÅØØØßßßàààÜÜÜßßßçççããã×××ÔÔÔÑÑÑØØØØØØØØØ×××ÉÉÉÆÆÆÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÊÊÊÊÊÊÌÌÌÍÍÍÅÅźººÂÂÂÃÃþ¾¾ÃÃÃÀÀÀÇÇÇÃÃû»»»»»ÂÂÂÀÀÀ¾¾¾ÀÀÀÑÑÑÑÑÑÒÒÒÔÔÔÕÕÕ×××ØØØØØØæææÑÑÑÐÐÐÍÍÍÍÍÍØØØØØØÕÕÕÛÛÛÛÛÛÙÙÙ×××ÛÛÛâââææææææääääääãããÝÝÝÜÜÜààààààÜÜÜÝÝÝÛÛÛÙÙÙØØØØØØÙÙÙØØØØØØÛÛÛÛÛÛÜÜÜÝÝÝæææíííëëëããããããàààâââãããâââàààÑÑѸ¸¸¾¾¾»»»»»»¿¿¿ÃÃÃÆÆÆÇÇÇÌÌÌÉÉÉÇÇÇÐÐÐÐÐÐÜÜܾ¾¾ÅÅÅÅÅÅÍÍÍÑÑÑÍÍÍàààÕÕÕÑÑÑÐÐÐÑÑÑÜÜÜÑÑÑÐÐÐ×××ÜÜÜßßßßßßÝÝÝÌÌÌÆÆÆÒÒÒ¿¿¿ÃÃÃÇÇÇÇÇÇÃÃû»»···ÊÊÊÔÔÔÕÕÕÔÔÔ×××ØØØÛÛÛÜÜÜßßßÛÛÛÝÝÝÛÛÛÊÊÊÍÍÍÉÉÉÊÊÊÇÇÇ¿¿¿¼¼¼ÂÂÂÍÍÍÔÔÔÑÑÑÐÐÐÔÔÔÒÒÒÍÍÍÌÌÌÍÍÍÌÌÌÊÊÊÃÃÿ¿¿ÀÀÀÀÀÀ¼¼¼¸¸¸¸¸¸···µµµµµµ···µµµ´´´···¾¾¾ÆÆÆ···¿¿¿ÀÀÀ¸¸¸¼¼¼»»»¾¾¾´´´³³³µµµµµµººº»»»³³³´´´°°°¯¯¯´´´ººº»»»»»»¼¼¼¼¼¼ÀÀÀÇÇÇÊÊÊÇÇÇÉÉÉÍÍÍÑÑÑÒÒÒÑÑÑÐÐÐÎÎÎÐÐÐÔÔÔ×××àààâââäääæææäääàààààààà຺ºÂÂÂÌÌÌÐÐÐÎÎÎÐÐÐÔÔÔÙÙÙØØØßßßàààæææïïïïïïêêêíííêêêÝÝÝÛÛÛÒÒÒÍÍÍÊÊÊÀÀÀÆÆÆßßßàààÝÝÝÛÛÛÜÜÜÜÜÜØØØÒÒÒÒÒÒÒÒÒÛÛÛÕÕÕÐÐÐÍÍÍÅÅÅÆÆÆÅÅÅÅÅÅÇÇÇÉÉÉÊÊÊÌÌÌÍÍÍÍÍÍÎÎÎÎÎÎÆÆÆÇÇÇÆÆÆ¿¿¿ÃÃÿ¿¿ÍÍÍÊÊʾ¾¾ÀÀÀ¼¼¼¼¼¼ÆÆÆÕÕÕ×××ØØØÙÙÙÙÙÙÙÙÙØØØØØØãããÐÐÐÍÍÍÎÎÎÔÔÔÙÙÙÕÕÕÛÛÛÜÜÜßßßÝÝÝÛÛÛÛÛÛàààäääãããàààãããâââÝÝÝÜÜÜßßßàààÝÝÝÛÛÛÜÜÜÛÛÛÛÛÛÙÙÙØØØÙÙÙÙÙÙÛÛÛÜÜÜÜÜÜßßßçççïïïíííæææàààÜÜÜãããëëëæææàààÝÝÝÙÙÙÍÍ͸¸¸···¸¸¸¼¼¼ÃÃÃÌÌÌÆÆÆÅÅÅÍÍÍÎÎÎßßß¾¾¾ÃÃÃÅÅÅÍÍÍÑÑÑÑÑÑâââÑÑÑÒÒÒÒÒÒÊÊÊÕÕÕÔÔÔÍÍÍÌÌÌØØØâââßßßØØØÂÂÂÊÊÊÔÔÔÂÂÂÆÆÆÆÆÆÌÌÌ»»»···ÔÔÔÑÑÑÕÕÕÑÑÑÔÔÔ×××ØØØÕÕÕÕÕÕÑÑÑØØØÙÙÙÊÊÊÊÊÊÌÌÌÌÌÌÅÅż¼¼¼¼¼ÇÇÇÐÐÐÑÑÑÙÙÙÊÊÊÅÅÅÅÅÅÀÀÀÅÅÅÆÆÆ»»»¼¼¼¾¾¾¿¿¿»»»µµµ°°°¯¯¯±±±´´´³³³³³³´´´³³³±±±´´´»»»µµµ³³³ÀÀÀÆÆƸ¸¸ººº···¼¼¼······¸¸¸´´´···»»»···ººº±±±©©©¦¦¦¬¬¬µµµ¼¼¼¾¾¾¾¾¾¾¾¾ÂÂÂÉÉÉÊÊÊÇÇÇÉÉÉÎÎÎÍÍÍÐÐÐÔÔÔÕÕÕÑÑÑÑÑÑÕÕÕ×××äääçççâââÛÛÛâââíííëëëßßß»»»ÃÃÃÌÌÌÐÐÐÎÎÎÎÎÎÒÒÒØØØÝÝÝäääâââßßßãããäääçççòòòßßßÕÕÕÙÙÙÐÐÐÇÇÇÅÅÅÀÀÀÍÍÍßßßâââãããÝÝÝÔÔÔÍÍÍÎÎÎÔÔÔÒÒÒÒÒÒÙÙÙÐÐÐÆÆÆÃÃþ¾¾ÆÆÆÂÂÂÃÃÃÆÆÆÉÉÉÌÌÌÍÍÍÍÍÍÍÍÍÉÉÉÎÎÎÆÆÆÅÅÅÅÅÅÆÆÆÕÕÕÙÙÙÑÑÑÕÕÕÎÎÎÅÅÅ¿¿¿···¾¾¾ÔÔÔÍÍÍÐÐÐÒÒÒÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÝÝÝÍÍÍÌÌÌÒÒÒÜÜÜßßßÛÛÛäääÜÜÜââââââÝÝÝÜÜÜßßßâââàààÛÛÛààààààÝÝÝÜÜÜßßßàààßßßÛÛÛÜÜÜÜÜÜÛÛÛÙÙÙØØØÙÙÙÛÛÛÝÝÝÝÝÝÝÝÝàààêêêóóóòòòëëëäääãããêêêêêêÒÒÒ¸¸¸»»»ÑÑÑâââÐÐм¼¼´´´³³³···ÀÀÀÌÌÌÉÉÉÅÅÅÉÉÉÉÉÉÝÝݺººÂÂÂÅÅÅÉÉÉÌÌÌÐÐÐàààÌÌÌÐÐÐÒÒÒÃÃÃ×××ÛÛÛÍÍÍÀÀÀÎÎÎØØØÎÎÎÅÅÅÂÂÂÔÔÔ×××ÆÆÆÃÃÃÑÑÑÐÐп¿¿···¼¼¼ÐÐÐÙÙÙÑÑÑÐÐÐ×××ØØØÝÝÝÐÐÐÍÍÍÔÔÔÔÔÔÔÔÔÒÒÒÌÌÌÍÍÍÊÊÊÌÌ̼¼¼»»»ÑÑÑÕÕÕÍÍÍÊÊÊÆÆÆÅÅÅÇÇÇÊÊÊÆÆƼ¼¼µµµÂ¼¼¼¯¯¯»»»ÅÅÅ¿¿¿¾¾¾°°°¯¯¯¯¯¯¯¯¯¯¯¯¬¬¬¯¯¯´´´±±±ÃÃþ¾¾°°°´´´¬¬¬µµµ°°°¯¯¯¬¬¬¬¬¬µµµ»»»´´´´´´¯¯¯©©©©©©±±±ººº»»»¸¸¸¾¾¾¿¿¿ÃÃÃÆÆÆÉÉÉÊÊÊÌÌÌÌÌÌÎÎÎÐÐÐÕÕÕÎÎÎÕÕÕÙÙÙÐÐÐÛÛÛÕÕÕäääØØØßßßòòòîîîííííííàààÂÂÂÊÊÊÍÍÍÐÐÐØØØÎÎÎÛÛÛØØØÛÛÛÝÝÝßßßàààâââããããããÝÝÝÒÒÒÌÌÌÉÉÉÍÍ;¾¾´´´ÙÙÙ×××ÝÝÝÔÔÔÉÉÉÌÌÌÌÌÌÆÆÆÇÇÇ×××ÒÒÒÛÛÛÕÕÕ¾¾¾ºººÃÃÿ¿¿¾¾¾ÀÀÀÅÅÅÉÉÉÌÌÌÍÍÍÍÍÍÌÌÌÌÌÌÊÊÊÆÆÆÍÍÍÛÛÛØØØÐÐÐÒÒÒÒÒÒÎÎÎÐÐÐÕÕÕ×××ÑÑÑÐÐÐÑÑÑÑÑÑÔÔÔ×××ØØØØØØÕÕÕÒÒÒÐÐÐÝÝÝÝÝÝÕÕÕÛÛÛÝÝÝÜÜÜßßß×××ÜÜÜàààßßßßßßæææäääâââäääÜÜÜÛÛÛÙÙÙÙÙÙÛÛÛÝÝÝàààâââààààààßßßÝÝÝÛÛÛÙÙÙÙÙÙØØØààààààâââãããæææêêêíííïïïíííëëëëëëêêêÙÙÙººº···ÑÑÑÔÔÔµµµ°°°³³³³³³···¼¼¼ÊÊÊÂÂÂÀÀÀÀÀÀÊÊÊÊÊÊÎÎλ»»ÅÅÅÂÂÂÇÇÇØØØßßß×××ÒÒÒÑÑÑÉÉÉÇÇÇÙÙÙÙÙÙÍÍÍÉÉÉÅÅÅÃÃÃÊÊÊÍÍÍÍÍÍÎÎÎÐÐÐÎÎÎÉÉÉÅÅÅÅÅŵµµÊÊÊ×××ÕÕÕÐÐÐÐÐÐÔÔÔØØØÜÜÜÎÎÎÌÌÌÐÐÐÎÎÎÎÎÎÐÐÐÌÌÌÊÊÊÃÃÃÆÆƾ¾¾¾¾¾ÐÐÐÐÐÐÉÉÉÃÃÃÉÉÉÍÍÍÊÊʼ¼¼¼¼¼ÀÀÀººº¯¯¯ÀÀÀÅÅÅÅÅÅÉÉÉ¿¿¿³³³¦¦¦¥¥¥°°°¸¸¸¸¸¸´´´ººº¾¾¾ÇÇÇ···±±±©©©³³³¯¯¯¬¬¬¥¥¥¥¥¥¨¨¨¨¨¨¬¬¬¨¨¨³³³···±±±©©©¬¬¬···ººº³³³ºººººº»»»¼¼¼¿¿¿ÅÅÅÊÊÊÐÐÐÒÒÒÕÕÕÛÛÛÕÕÕØØØÙÙÙÐÐÐÙÙÙàààæææÛÛÛßßßïïïíííèèèîîîæææÃÃÃÊÊÊÎÎÎÐÐÐÕÕÕÎÎÎØØØ×××ÙÙÙÝÝÝàààââââââàààßßßÝÝÝÔÔÔÑÑÑÍÍÍÇÇǸ¸¸¸¸¸ÝÝÝØØØÕÕÕÌÌÌÇÇÇÍÍÍÑÑÑÐÐÐÎÎÎÎÎÎÍÍÍØØØ×××¾¾¾Â»»»¾¾¾ÀÀÀÅÅÅÉÉÉÌÌÌÍÍÍÍÍÍÍÍÍÐÐÐÆÆÆÃÃÃÍÍÍ×××ÛÛÛ×××ÎÎÎÑÑÑÎÎÎÎÎÎÐÐÐÎÎÎÊÊÊÍÍÍÑÑÑÎÎÎÎÎÎÑÑÑÔÔÔ×××ØØØ×××ÕÕÕ×××ßßßÜÜÜàààÝÝÝ×××ÝÝÝÛÛÛßßßææææææãããæææàààÜÜÜâââßßßÝÝÝÜÜÜÜÜÜÝÝÝßßßâââããããããâââàààßßßÝÝÝÜÜÜÜÜÜÜÜÜàààââââââãããæææèèèêêêëëëêêêçççäääêêêæææÑÑÑÍÍÍÝÝÝÜÜÜ´´´ªªª³³³···¸¸¸ºººÇÇÇÂÂÂÂÂÂÂÂÂÊÊÊÍÍÍÑÑÑ»»»¿¿¿ÇÇÇÇÇÇÔÔÔÛÛÛÕÕÕÒÒÒÔÔÔÐÐÐÅÅÅÐÐÐ×××ÕÕÕÒÒÒÌÌÌÆÆÆÆÆÆÒÒÒÍÍÍÍÍÍÑÑÑÑÑÑÉÉÉÂÂÂÀÀÀÀÀÀ×××ÙÙÙÎÎÎÑÑÑÔÔÔÒÒÒÔÔÔÕÕÕÌÌÌÍÍÍÒÒÒÐÐÐÐÐÐÒÒÒÎÎÎÎÎÎÅÅÅÉÉÉÅÅÅÇÇÇ×××ÒÒÒÊÊÊÀÀÀÉÉÉÍÍÍÇÇǼ¼¼¸¸¸¾¾¾ÃÃúºº©©©···ÃÃü¼¼¼¼¼ÀÀÀÀÀÀÊÊʺººªªªªªª¸¸¸Â¼¼¼¿¿¿ÆÆÆÆÆÆ°°°···¸¸¸ÀÀÀ¼¼¼¼¼¼µµµ···ºººµµµ´´´°°°¥¥¥¨¨¨´´´µµµ©©©©©©µµµ»»»´´´ººº»»»¾¾¾¿¿¿ÀÀÀÆÆÆÍÍÍÒÒÒÒÒÒÕÕÕÛÛÛ×××ØØØ×××ÎÎÎÔÔÔæææâââÛÛÛÝÝÝíííîîîçççòòòëëëÂÂÂÉÉÉÒÒÒÑÑÑÕÕÕÑÑÑÕÕÕÔÔÔØØØÜÜÜßßßàààßßßÜÜÜÙÙÙÑÑÑÍÍÍÎÎÎÅÅźºº»»»ÉÉÉãããäääÕÕÕÌÌÌÊÊÊÌÌÌÎÎÎÍÍÍÇÇÇÍÍÍÊÊÊÒÒÒÒÒÒÅÅÅÂÂÂÅÅž¾¾¾¾¾ÀÀÀÅÅÅÉÉÉÌÌÌÍÍÍÍÍÍÌÌÌÊÊÊÅÅÅÍÍÍÕÕÕÕÕÕÙÙÙÙÙÙÌÌÌÔÔÔÔÔÔ×××ØØØÕÕÕÒÒÒÕÕÕÛÛÛÒÒÒÐÐÐÐÐÐÑÑÑÕÕÕÙÙÙÙÙÙÙÙÙÒÒÒÛÛÛÛÛÛßßßÛÛÛÔÔÔÙÙÙØØØÒÒÒÜÜÜàààâââæææäääâââçççâââààààààßßßßßßàààãããäääçççæææãããâââàààààààààâââããããããäääææææææçççççççççóóóíííçççëëëîîîäääÛÛÛßßßÐÐб±±³³³´´´······ÀÀÀÀÀÀÃÃÃÂÂÂÉÉÉÍÍÍ×××¼¼¼ºººÇÇÇÆÆÆÐÐÐÜÜÜÙÙÙÒÒÒÐÐÐÍÍÍÊÊÊÎÎÎÙÙÙßßß×××ÍÍÍÉÉÉÆÆÆÍÍÍÕÕÕÒÒÒÉÉÉÉÉÉÎÎÎÇÇÇ···ÕÕÕÛÛÛÔÔÔÍÍÍÔÔÔÙÙÙÒÒÒÊÊÊÌÌÌÊÊÊÒÒÒÙÙÙ×××××××××ÑÑÑÐÐÐÉÉÉÌÌÌÅÅÅÉÉÉÜÜÜØØØÊÊÊÆÆÆÆÆƼ¼¼»»»¾¾¾¾¾¾¼¼¼¯¯¯©©©ºººººº³³³¸¸¸···¾¾¾ÀÀÀ¾¾¾»»»¼¼¼ÀÀÀÃÃÃÂÂÂÀÀÀ¿¿¿ÀÀÀººº¬¬¬ÅÅÅÊÊÊÊÊʾ¾¾¾¾¾ÃÃÃÅÅÅÅÅÅÉÉÉÅÅÅ´´´¤¤¤±±±µµµ¨¨¨¯¯¯µµµµµµ···»»»ÀÀÀÅÅÅÅÅÅÆÆÆÊÊÊÍÍÍÎÎÎÑÑÑÕÕÕÒÒÒÑÑÑÎÎÎÍÍÍÑÑÑßßß×××ØØØÜÜÜëëëïïïæææóóóæææÀÀÀÇÇÇ×××ÔÔÔÕÕÕÔÔÔÒÒÒÕÕÕ×××ÙÙÙÜÜÜÝÝÝÜÜÜØØØÕÕÕÐÐÐÌÌÌÊÊÊÀÀÀ¼¼¼ÎÎÎàààãããÜÜÜÌÌÌÉÉÉÎÎÎÌÌÌÍÍÍÑÑÑÎÎÎÍÍÍÆÆÆÇÇÇÆÆƾ¾¾¾¾¾Â¾¾¾¾¾¾ÀÀÀÅÅÅÉÉÉÌÌÌÌÌÌÌÌÌÊÊÊÂÂÂÍÍÍÜÜÜààà×××ÔÔÔÔÔÔÐÐÐÎÎÎÐÐÐÒÒÒ×××××××××ÕÕÕ×××ÙÙÙ×××ÔÔÔÔÔÔ×××ØØØØØØÕÕÕÛÛÛÝÝÝØØØÝÝÝàààÜÜÜßßßØØØÕÕÕÜÜÜÜÜÜàààçççäääßßßàààââââââââââââàààâââäääæææêêêèèèæææäääääääääæææçççæææççççççççççççæææäääãããúúúòòòííííííïïïêêêàààÜÜܵµµ°°°···±±±¬¬¬´´´···¸¸¸ÀÀÀÃÃÃÀÀÀÆÆÆÍÍÍÙÙÙ¿¿¿¸¸¸ÃÃÃÃÃÃÑÑÑãããäääÕÕÕÌÌÌÉÉÉÐÐÐÎÎÎÜÜÜäääØØØÐÐÐÔÔÔÕÕÕÐÐÐÔÔÔÑÑÑÉÉÉÆÆÆÊÊÊÆÆƼ¼¼ããã×××ÒÒÒÒÒÒÔÔÔÕÕÕÒÒÒÉÉÉÌÌÌÍÍÍÔÔÔØØØÔÔÔÔÔÔÕÕÕÐÐÐÇÇÇÇÇÇÊÊʼ¼¼¿¿¿ØØØ×××ÇÇÇÉÉÉÅÅż¼¼···»»»ÀÀÀ¾¾¾µµµ°°°ºººÂ´´´³³³µµµµµµ³³³¸¸¸¾¾¾ÀÀÀÀÀÀ¿¿¿¿¿¿ÀÀÀ¼¼¼µµµ¯¯¯ªªªÅÅÅÃÃþ¾¾ÂÂÂÅÅÅÆÆÆ¿¿¿»»»Âººº¡¡¡ªªª±±±···´´´ªªª¤¤¤¨¨¨¯¯¯±±±´´´ººº¾¾¾ÀÀÀÃÃÃÆÆÆÉÉÉÌÌÌÎÎÎÐÐÐÐÐÐÌÌÌÊÊÊÑÑÑÔÔÔÔÔÔÐÐÐØØØÜÜÜçççëëëâââëëë×××¾¾¾ÉÉÉØØØ××××××ÕÕÕÒÒÒ×××ÕÕÕÕÕÕ×××ØØØØØØÕÕÕÑÑÑÕÕÕÇÇÇÇÇÇÑÑÑ×××âââèèèÝÝÝÔÔÔÉÉÉÍÍÍÑÑÑÉÉÉÆÆÆÌÌÌÌÌÌÉÉÉÂÂÂÀÀÀ¿¿¿»»»¼¼¼¿¿¿»»»¿¿¿ÂÂÂÅÅÅÉÉÉÊÊÊÊÊÊÉÉÉÉÉÉÌÌÌÙÙÙàààÝÝÝØØØÑÑÑÑÑÑÙÙÙÜÜÜØØØÒÒÒÒÒÒ×××ÙÙÙ×××ÒÒÒ×××ÕÕÕÒÒÒÒÒÒÔÔÔÔÔÔÒÒÒÑÑÑ×××ÙÙÙÑÑÑÕÕÕ×××ÔÔÔÙÙÙÕÕÕÜÜÜÝÝÝÛÛÛâââïïïñññçççäääâââãããäääãããââââââäääçççêêêêêêèèèççççççèèèèèèêêêêêêêêêêêêèèèçççæææãããâââïïïëëëêêêëëëëëëèèèäääàà຺º´´´ººº°°°©©©³³³µµµ···¾¾¾Â¾¾¾ÂÂÂÉÉÉÙÙÙ¾¾¾ÀÀÀÃÃÃÑÑÑäääêêêÝÝÝÔÔÔÕÕÕ×××ÎÎÎØØØäääàààßßßâââÝÝÝÛÛÛÎÎÎÌÌÌÒÒÒÍÍÍ¿¿¿ÀÀÀÑÑÑàààÕÕÕ×××ØØØÎÎÎÍÍÍÒÒÒÐÐÐÑÑÑÎÎÎÑÑÑÐÐÐÉÉÉÍÍÍÐÐÐÊÊÊÇÇÇÇÇÇÍÍ;¾¾¼¼¼ÔÔÔ×××ÎÎÎÆÆÆÇÇǺººººº¾¾¾¼¼¼µµµ¦¦¦¸¸¸ºººµµµÂÂÂÇÇÇÂÂÂÌÌÌ´´´´´´´´´···ººº¼¼¼¼¼¼¼¼¼´´´¯¯¯³³³±±±Â¾¾¾ÃÃÃÆÆƺºº¾¾¾ÀÀÀ»»»»»»ÃÃû»»¡¡¡©©©´´´···°°°¦¦¦©©©³³³µµµµµµ···ººº¿¿¿ÆÆÆÌÌÌÐÐÐÊÊÊÍÍÍÍÍÍÐÐÐÊÊÊÉÉÉ××××××ÎÎÎÐÐÐ×××ÙÙÙßßßâââßßßâââÅÅÅÀÀÀÊÊÊÕÕÕ×××ÕÕÕÕÕÕÒÒÒ×××ÔÔÔÒÒÒÒÒÒÕÕÕÔÔÔÑÑÑÍÍÍÉÉɸ¸¸¼¼¼ÝÝÝêêêâââßßßÕÕÕÑÑÑÎÎÎÑÑÑÎÎÎÅÅž¾¾¿¿¿ÀÀÀÇÇÇÅÅÅÅÅÅÇÇÇÇÇÇÇÇÇÆÆÆÂÂÂÂÂÂÃÃÃÆÆÆÉÉÉÉÉÉÉÉÉÆÆÆÅÅÅßßßßßßÕÕÕÒÒÒ×××ÔÔÔÔÔÔâââñññèèèÜÜÜÒÒÒÔÔÔÙÙÙÙÙÙÕÕÕÎÎÎÎÎÎÐÐÐÐÐÐÑÑÑÒÒÒÔÔÔÕÕÕÔÔÔÜÜÜØØØØØØÒÒÒÍÍÍÙÙÙÝÝÝââââââàààçççùùùÿÿÿõõõòòòæææèèèêêêçççäääâââãããæææèèèèèèèèèèèèêêêêêêêêêêêêêêêêêêèèèçççæææãããâââàààèèèäääçççêêêæææââââââßßßÒÒÒ¸¸¸³³³°°°³³³´´´»»»¼¼¼ÀÀÀ¾¾¾ÃÃÃÇÇÇÒÒÒ¿¿¿ÀÀÀÃÃÃÇÇÇÎÎÎÛÛÛäääààààààèèèäääÛÛÛÙÙÙâââççççççßßßÔÔÔßßßÑÑÑÐÐÐÕÕÕÍÍ;¾¾ÇÇÇàààÙÙÙÙÙÙÙÙÙÔÔÔÍÍÍÎÎÎÒÒÒÒÒÒÍÍÍÌÌÌÐÐÐÎÎÎÊÊÊÎÎÎÎÎÎÆÆÆÊÊÊÅÅÅÎÎÎÇÇÇÀÀÀÍÍÍÔÔÔÙÙÙÇÇÇÍÍÍÊÊÊÀÀÀ¼¼¼¿¿¿¾¾¾······»»»···ÀÀÀÎÎÎÊÊÊÉÉÉÎÎÎÆÆÆ¿¿¿¸¸¸µµµ¸¸¸ººº¸¸¸µµµ¯¯¯¯¯¯¾¾¾¼¼¼ÅÅÅÂÂÂÇÇǾ¾¾»»»···»»»¿¿¿¿¿¿¾¾¾³³³¡¡¡¤¤¤ªªª´´´¸¸¸µµµ³³³´´´ºººÀÀÀ¼¼¼»»»¼¼¼ÃÃÃÉÉÉÌÌÌÌÌÌÆÆÆÊÊÊÌÌÌÐÐÐÇÇÇÆÆÆÕÕÕÔÔÔÊÊÊÔÔÔÔÔÔÒÒÒÔÔÔÛÛÛäääãã㸸¸ÆÆÆÍÍÍÐÐÐÒÒÒÒÒÒÒÒÒÔÔÔÕÕÕÒÒÒÑÑÑÒÒÒÔÔÔÒÒÒÍÍÍÇÇÇÅÅÅÂÂÂÆÆÆßßßâââÒÒÒÒÒÒÐÐÐÇÇÇÌÌÌÉÉÉÂÂÂÂÂÂÀÀÀ¿¿¿ÀÀÀ¿¿¿¿¿¿ÀÀÀÃÃÃÆÆÆÉÉÉÇÇÇÇÇÇÅÅÅÆÆÆÇÇÇÉÉÉÉÉÉÆÆÆÃÃÃÂÂÂæææØØØÎÎÎÑÑÑÔÔÔÑÑÑØØØæææëëëèèèßßßÒÒÒÍÍÍÐÐÐÒÒÒÑÑÑÐÐÐÒÒÒÒÒÒÒÒÒÒÒÒÕÕÕÜÜÜââââââëëëèèèèèèãããÝÝÝèèèëëëïïïñññîîîïïïøøøöööïïïïïïïïïñññòòòîîîçççââââââãããäääæææèèèêêêëëëêêêêêêèèèèèèèèèæææãããàààßßßÝÝÝÝÝÝíííâââäääêêêãããÝÝÝÜÜÜÙÙÙÔÔÔµµµ°°°°°°¯¯¯±±±´´´¾¾¾¼¼¼¿¿¿ÀÀÀÉÉÉÆÆÆÌÌ̸¸¸ÀÀÀÃÃÃÉÉÉÉÉÉÊÊÊÒÒÒÕÕÕÛÛÛçççêêêçççßßßÛÛÛàààâââÛÛÛÕÕÕÙÙÙÝÝÝÜÜÜÐÐÐÅÅÅÆÆÆÕÕÕãããÕÕÕÝÝÝÕÕÕÊÊÊÐÐÐ×××ÒÒÒÎÎÎÃÃÃÇÇÇÑÑÑ×××ÕÕÕ×××ÒÒÒÅÅÅÅÅÅ»»»ÇÇÇÉÉÉÀÀÀÀÀÀÉÉÉÙÙÙÌÌÌÐÐÐÍÍÍÃÃÃÂÂÂÅÅÅ¿¿¿´´´Â¸¸¸±±±ÊÊÊÔÔÔÇÇÇÌÌÌÎÎÎ×××ÑÑÑÇÇÇÀÀÀººº···´´´±±±¯¯¯°°°ÂÂÂÀÀÀÆÆƼ¼¼žžž¦¦¦›››¤¤¤···»»»´´´¬¬¬¡¡¡¦¦¦±±±¸¸¸¸¸¸···ºººººº···ÀÀÀ¾¾¾»»»¾¾¾ÃÃÃÃÃÿ¿¿»»»ÀÀÀÆÆÆÇÇÇÎÎÎÅÅÅÀÀÀÑÑÑÌÌÌÆÆÆÕÕÕÑÑÑÍÍÍÍÍÍØØØíííêêê±±±ÌÌÌÐÐÐÌÌÌÐÐÐÎÎÎÐÐÐÕÕÕÔÔÔÑÑÑÑÑÑÒÒÒÕÕÕÒÒÒÊÊÊÃÃÃ×××æææãããßßßÒÒÒÆÆÆÍÍÍÊÊÊÎÎÎÔÔÔÆÆÆ»»»¿¿¿¿¿¿···µµµ°°°¯¯¯¯¯¯´´´ººº¾¾¾ÂÂÂÆÆÆÇÇÇÉÉÉÉÉÉÇÇÇÆÆÆÂÂÂÀÀÀàààÎÎÎÑÑÑÙÙÙÑÑÑÌÌÌÙÙÙçççâââèèèèèèßßßÕÕÕÔÔÔ××××××ÙÙÙÛÛÛÛÛÛØØØ×××ÙÙÙãããëëëãããçççãããææææææâââçççäääèèèïïïïïïïïïóóóòòòïïïõõõöööøøøøøøòòòèèèâââàààâââãããäääçççêêêëëëêêêèèèççççççæææãããßßßÝÝÝÜÜÜÛÛÛÛÛÛíííÝÝÝßßßèèèæææßßßÝÝÝÛÛÛ¾¾¾°°°³³³°°°ªªª±±±´´´»»»»»»¿¿¿ÃÃÃÍÍÍÇÇÇÆÆƱ±±¾¾¾ÂÂÂÉÉÉÅÅÅ¿¿¿ÃÃÃÆÆÆÌÌÌ×××ÝÝÝèèèâââÔÔÔÔÔÔÙÙÙàààíííÐÐÐØØØÙÙÙÌÌÌÎÎÎâââãããÛÛÛæææÝÝÝÕÕÕÑÑÑÒÒÒÔÔÔÎÎÎÊÊÊÑÑÑÒÒÒÔÔÔÕÕÕ×××ÕÕÕÕÕÕÔÔÔÎÎÎÆÆƼ¼¼ÂÂÂÅÅÅÆÆÆßßßÕÕÕÆÆÆÐÐо¾¾ÀÀÀ»»»¿¿¿¿¿¿ÆÆÆÐÐÐÑÑÑÍÍÍÍÍÍÒÒÒØØØ×××ÕÕÕÑÑÑÇÇǸ¸¸°°°°°°©©©±±±¿¿¿ÉÉÉÉÉɵµµ¥¥¥¤¤¤žžž¡¡¡©©©¨¨¨¦¦¦¯¯¯¯¯¯¸¸¸´´´°°°¢¢¢¯¯¯´´´¿¿¿¼¼¼»»»µµµ³³³ºººÆÆÆÊÊÊÇÇÇÇÇÇ···µµµºººÇÇÇÊÊÊÃÃÃ×××ØØØÐÐÐÍÍÍÕÕÕØØØÔÔÔ×××ÝÝÝßß߸¸¸ÉÉÉÐÐÐÊÊÊÔÔÔÍÍÍÔÔÔ×××ÑÑÑÑÑÑÕÕÕÎÎÎÅÅÅÉÉÉÕÕÕêêêØØØÌÌÌÊÊÊÆÆÆ¿¿¿ÃÃÃÎÎÎÀÀÀÇÇÇÀÀÀ»»»°°°¼¼¼ÀÀÀ¿¿¿ÀÀÀÇÇÇÇÇǾ¾¾´´´±±±ºººµµµ¾¾¾ÉÉÉÉÉÉÇÇÇÆÆÆÀÀÀÛÛÛÑÑÑÍÍÍÑÑÑØØØÝÝÝæææïïïßßßâââãããßßßØØØÕÕÕØØØÜÜÜÑÑÑãããíííçççäääëëëîîîêêêèèèãããääääääøøøêêêääääääêêêíííïïïñññïïïïïïñññóóóøøøòòòõõõêêêâââãããÜÜÜãããæææÜÜÜäääñññêêêâââäääæææääääääâââßßßÜÜÜÙÙÙØØØ×××èèèæææãããâââââââââßßßÜÜÜØØؼ¼¼¯¯¯°°°¬¬¬°°°¼¼¼Â¿¿¿ÀÀÀÉÉÉÒÒÒ×××ÔÔÔÑÑÑÑÑѺººººº¿¿¿ÆÆÆÇÇÇÆÆÆÇÇÇÌÌÌÙÙÙïïïæææØØØÝÝÝíííóóóßßßßßßÒÒÒÊÊÊÎÎÎÙÙÙàààÜÜÜ×××ÝÝÝÙÙÙ×××ÕÕÕÑÑÑÌÌÌÌÌÌÎÎÎÔÔÔÕÕÕ×××ØØØØØØØØØ×××ÕÕÕÒÒÒÊÊÊÇÇÇ¿¿¿»»»»»»ÒÒÒÕÕÕÆÆÆÐÐо¾¾¸¸¸»»»ººº¸¸¸ÀÀÀÍÍÍÒÒÒÕÕÕÒÒÒÎÎÎÊÊÊÌÌÌÍÍÍÒÒÒÕÕÕÎÎξ¾¾±±±¬¬¬´´´»»»ÃÃÃÉÉÉÉÉÉÃÃû»»´´´ººº´´´¨¨¨¢¢¢¦¦¦¥¥¥¨¨¨³³³³³³»»»¸¸¸³³³©©©±±±···ÀÀÀÀÀÀ¼¼¼µµµ···¾¾¾ÅÅÅÇÇÇÇÇÇÅÅÅÃÃúºº¼¼¼ÅÅÅÅÅÅÕÕÕÉÉÉÌÌÌÔÔÔÜÜÜØØØÑÑÑ×××ääääää¾¾¾¾¾¾ÀÀÀÂÂÂÌÌÌÇÇÇÎÎÎÑÑÑÍÍÍÌÌÌÌÌÌÉÉÉÊÊÊ×××çççàààÕÕÕÎÎÎÎÎÎÎÎÎÊÊÊÌÌÌÑÑѵµµÂ¼¼¼µµµµµµ¼¼¼ÉÉÉÃÃÃÃÃÃÂÂÂÃÃÃÉÉÉÊÊÊÆÆÆÃÃÿ¿¿´´´ºººÉÉÉÊÊÊÅÅÅÃÃÃÂÂÂÝÝÝÕÕÕÑÑÑ×××àààãããâââààà×××ÛÛÛàààæææèèèêêêêêêêêêÝÝÝæææèèèääääääçççäääÝÝÝÛÛÛÛÛÛæææäääíííèèèîîîçççïïïíííèèèääääääçççíííñññòòòñññúúúõõõñññïïïæææèèèëëëäääççççççßßßÝÝÝââââââàààßßßÜÜÜÙÙÙØØØ×××××××××ààààààâââãããäääãããâââàààæææÍÍͺºº´´´±±±´´´ººº¼¼¼ÂÂÂÂÂÂÅÅÅÌÌÌÐÐÐÑÑÑÕÕÕÜÜÜàààâââçççëëëäää×××ÍÍÍÊÊÊÂÂÂÝÝÝäääãããæææÝÝÝÔÔÔÐÐÐÜÜÜÊÊÊÆÆÆÜÜÜêêêãããÝÝÝÝÝÝÔÔÔÕÕÕ×××ÕÕÕÍÍÍÅÅÅÊÊÊÔÔÔ×××ØØØÙÙÙÙÙÙÙÙÙÙÙÙ××××××ÎÎÎÇÇÇÊÊÊÆÆÆ¿¿¿µµµ···ÑÑÑØØØÆÆÆÌÌÌÀÀÀ¾¾¾´´´¼¼¼Â¸¸¸ÇÇÇÒÒÒÔÔÔÔÔÔÕÕÕÎÎÎÅÅÅÂÂÂÅÅÅÍÍÍÕÕÕÒÒÒÆÆƸ¸¸³³³¿¿¿ÀÀÀÃÃÃÅÅÅÃÃÃÀÀÀ¼¼¼ºººÂ¾¾¾±±±¨¨¨¨¨¨¤¤¤¦¦¦°°°µµµµµµµµµªªª©©©¨¨¨°°°³³³¿¿¿¿¿¿¼¼¼···´´´¸¸¸»»»»»»¿¿¿ÆÆÆÆÆÆ»»»¿¿¿ÇÇǼ¼¼¸¸¸ÀÀÀÆÆÆÑÑÑØØØÔÔÔÐÐÐØØØçççóóóÕÕÕ¾¾¾»»»ÀÀÀÃÃÃÂÂÂÆÆÆÌÌÌÇÇÇÃÃÃÃÃÃÉÉÉÒÒÒÜÜÜãããÔÔÔÎÎÎÇÇǼ¼¼¸¸¸´´´±±±ÃÃü¼¼³³³¼¼¼ÃÃÿ¿¿¾¾¾µµµ»»»¼¼¼¾¾¾¾¾¾¿¿¿ÃÃÃÇÇÇÉÉÉÆÆÆ´´´µµµÆÆÆÉÉÉÃÃÃÃÃÃÃÃÃ×××ÕÕÕÒÒÒÒÒÒÙÙÙãããæææäääÜÜÜÜÜÜÝÝÝãããçççêêêèèèæææíííèèèæææçççêêêèèèâââÛÛÛ³³³¼¼¼ÒÒÒ×××ÙÙÙâââñññèèèîîîíííëëëëëëíííïïïïïïñññîîîïïïùùùùùùøøøöööïïïñññóóóóóóóóóëëëààààààäääãããèèèæææâââÜÜÜÙÙÙ×××××××××ææææææäääâââàààßßßßßßààààààÒÒÒ»»»¯¯¯³³³¸¸¸¾¾¾ÅÅÅÃÃÃÅÅÅÊÊÊÐÐÐÐÐÐÍÍÍÎÎÎÔÔÔÕÕÕÕÕÕØØØÜÜÜÜÜÜØØØÙÙÙÝÝÝÊÊÊÑÑÑâââëëëæææ×××ÐÐÐÜÜÜÎÎÎÒÒÒÛÛÛíííîîîâââßßßÝÝÝÐÐÐÕÕÕ×××ÑÑÑÉÉÉÉÉÉÐÐÐ×××ØØØØØØÙÙÙÙÙÙÙÙÙØØØ×××ÕÕÕÍÍÍÇÇÇÍÍÍÇÇǼ¼¼´´´ºººÔÔÔÛÛÛÆÆÆÅÅÅ»»»¾¾¾¸¸¸¿¿¿¼¼¼ÆÆÆÎÎÎÔÔÔÒÒÒÑÑÑÐÐÐÌÌÌÆÆÆÅÅÅÃÃÃÇÇÇÐÐÐÒÒÒÌÌÌÅÅÅÂÂÂÇÇÇÇÇÇÆÆÆÅÅÅÃÃÃÂÂÂÀÀÀ¿¿¿¾¾¾Â¾¾¾···´´´¨¨¨¬¬¬¼¼¼µµµ´´´¥¥¥¬¬¬ªªªººº¾¾¾¾¾¾¾¾¾»»»ººººººººº¸¸¸µµµºººÀÀÀ¼¼¼´´´¼¼¼ÉÉÉÅÅż¼¼»»»¾¾¾ÂÂÂÃÃÃÅÅÅÎÎÎÙÙÙäääØØØ»»»¸¸¸¿¿¿¸¸¸ººº¼¼¼µµµµµµ¸¸¸ÀÀÀÒÒÒâââäääÝÝÝÌÌÌÌÌÌÇÇÇÂÂÂÂÂÂÆÆÆÅÅÅÀÀÀººº´´´°°°ÂÂÂÆÆƺººººº»»»¸¸¸¼¼¼¼¼¼¸¸¸···»»»ÀÀÀÃÃÃÉÉɸ¸¸µµµ¿¿¿ÃÃÃÅÅÅÆÆÆ¿¿¿ÉÉÉÎÎÎÊÊÊÉÉÉÐÐÐØØØÜÜÜàààÜÜÜ×××ÔÔÔÔÔÔ×××ÛÛÛÜÜÜëëëãããàààæææêêêçççâââààà°°°´´´¼¼¼¼¼¼¿¿¿ÐÐÐçççîîîäääæææèèèîîîòòòóóóñññîîîóóóòòòóóóòòòòòòöööùùùÿÿÿóóóöööùùùóóóèèèââââââäääßßßÝÝÝÛÛÛÛÛÛÜÜÜàààãããæææîîîëëëçççàààÜÜÜÝÝÝâââæææâââÝÝÝÆÆÆ°°°¯¯¯³³³¿¿¿ÃÃÃÆÆÆÌÌÌÑÑÑÎÎÎÊÊÊÌÌÌÑÑÑÙÙÙÔÔÔÐÐÐÐÐÐÐÐÐÒÒÒÜÜÜæææÛÛÛÀÀÀÐÐÐÛÛÛÑÑÑÒÒÒØØØàààÉÉÉæææîîîëëëàààÙÙÙÛÛÛÍÍÍÑÑÑØØØÕÕÕÊÊÊÉÉÉÔÔÔÙÙÙÕÕÕ×××ØØØØØØØØØØØØÕÕÕÔÔÔÒÒÒÔÔÔÍÍÍÑÑÑÇÇǸ¸¸´´´¼¼¼ÔÔÔÔÔÔÉÉÉÆÆƸ¸¸»»»ºººÃÃø¸¸ÒÒÒÒÒÒÔÔÔ×××ÒÒÒÉÉÉÃÃÃÅÅÅÇÇÇÆÆÆÉÉÉÐÐÐÔÔÔÐÐÐÍÍÍÌÌÌÌÌÌÊÊÊÉÉÉÇÇÇÆÆÆÆÆÆÅÅÅÅÅÅ¿¿¿ÇÇÇÉÉÉÅÅÅ···¬¬¬ªªª¸¸¸°°°¯¯¯¤¤¤ªªª¨¨¨µµµººº¾¾¾¾¾¾¿¿¿¾¾¾ºººººº¾¾¾Â¼¼¼ÇÇÇÅÅž¾¾»»»¸¸¸¼¼¼ÅÅÅÀÀÀ¿¿¿¿¿¿ÀÀÀÃÃÃÆÆÆÍÍÍÕÕÕäääëëëÛÛÛÝÝÝæææÝÝÝâââäääçççíííîîîëëëëëëêêêàààÒÒÒÎÎÎÍÍÍÃÃõµµ°°°³³³±±±ªªªººº»»»¼¼¼µµµ±±±ÀÀÀÆÆÆÅÅÅÇÇÇÇÇǼ¼¼ººº»»»¿¿¿ÆÆÆ¿¿¿¼¼¼¸¸¸ºººÆÆÆÊÊÊ¿¿¿»»»ÌÌÌØØØÕÕÕÎÎÎÍÍÍÎÎÎÍÍÍÔÔÔÒÒÒÐÐÐÌÌÌÉÉÉÎÎÎÙÙÙãããàààÜÜÜÝÝÝääääääßßßßßßäääßßßÔÔÔ¾¾¾³³³±±±¾¾¾ÔÔÔîîîïïïîîîîîîñññõõõùùùùùùùùùæææèèèëëëïïïòòòñññïïïíííïïïîîîïïïñññêêêÝÝÝÝÝÝçççææææææäääæææèèèíííñññóóóèèèèèèçççäääããããããèèèíííâââçççÙÙÙÃÃ÷··ºººÂÂÂÂÂÂÅÅÅÇÇÇÉÉÉÊÊÊÔÔÔÝÝÝãããàààßßßÝÝÝÙÙÙÕÕÕ×××ÛÛÛæææÂÂÂÅÅÅÍÍÍÎÎÎÛÛÛÙÙÙÕÕÕÃÃÃêêêëëëÝÝÝÔÔÔØØØàààÆÆÆ×××ØØØÑÑÑÉÉÉÎÎÎÛÛÛÝÝÝÕÕÕ×××ØØØØØØØØØ×××ÔÔÔÑÑÑÐÐÐÑÑÑÌÌÌÎÎη··¾¾¾ÉÉÉØØØÉÉÉÊÊÊÌÌ̼¼¼¸¸¸µµµÊÊÊÀÀÀ×××ÔÔÔ×××ÙÙÙÔÔÔÆÆÆ¿¿¿ÀÀÀÇÇÇÆÆÆÌÌÌÒÒÒÔÔÔÐÐÐÊÊÊÊÊÊÀÀÀÀÀÀ¿¿¿¿¿¿¿¿¿ÀÀÀÂÂÂÃÃÃÀÀÀÉÉÉÇÇÇ¿¿¿¸¸¸ªªª¾¾¾»»»¼¼¼ººº»»»µµµººº¼¼¼µµµ¸¸¸»»»···¯¯¯¬¬¬¸¸¸ÆÆƺººÂ¿¿¿ÀÀÀ¾¾¾³³³»»»¿¿¿ÅÅÅÆÆÆÆÆÆÆÆÆÌÌÌÒÒÒÕÕÕäääßßßäääêêêãããææææææàààêêêïïïçççÝÝÝØØØÒÒÒÎÎÎÇÇÇÆÆƾ¾¾µµµ´´´ººº»»»¸¸¸ººº¼¼¼µµµ······¸¸¸ÇÇÇÌÌÌÐÐÐÎÎÎÍÍÍÊÊʸ¸¸µµµ»»»ÂÂÂÃÃ÷··³³³ÃÃÃÌÌÌ¿¿¿ÃÃÃÊÊÊÐÐÐÑÑÑÐÐÐÑÑÑÑÑÑÎÎÎÉÉÉÍÍÍÑÑÑÑÑÑÎÎÎÒÒÒÜÜÜäääßßßßßßäääèèèçççâââãããèèèñññèèèÍÍÍÀÀÀ······¾¾¾ØØØëëëíííïïïñññòòòòòòïïïîîîöööõõõíííîîîïïïñññùùùøøøòòòîîîëëëïïïíííâââäääõõõõõõóóóñññîîîíííííííííîîîçççèèèëëëëëëêêêçççæææäääãããçççäää×××ÆÆÆ···´´´¼¼¼ÂÂÂÂÂÂÅÅÅÉÉÉÊÊÊÊÊÊÐÐÐØØØÕÕÕÕÕÕÙÙÙÝÝÝÝÝÝØØØØØØÛÛÛêêê×××ÅÅÅÃÃÃÔÔÔßßßÔÔÔÍÍ;¾¾ãããäääßßßÙÙÙÜÜÜæææÎÎÎØØØÒÒÒÎÎÎÐÐÐÕÕÕÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙØØØ×××ÔÔÔÑÑÑÐÐÐÌÌÌÆÆÆÊÊʼ¼¼µµµÇÇÇÔÔÔÙÙÙÇÇÇÇÇÇÇÇÇÀÀÀ¿¿¿¸¸¸ÑÑÑÎÎÎØØØØØØ×××ÔÔÔÍÍÍÆÆÆÂÂÂÂÂÂÆÆÆÆÆÆÊÊÊÐÐÐÎÎÎÆÆÆÂÂÂÃÃø¸¸¸¸¸¸¸¸¸¸¸»»»¿¿¿ÂÂÂÅÅÅÀÀÀÇÇÇÅÅÅ¿¿¿ÂÂÂÀÀÀ¸¸¸´´´³³³´´´µµµ»»»µµµ´´´±±±···´´´³³³´´´µµµ³³³¯¯¯°°°µµµ°°°···¯¯¯µµµ»»»´´´ººº¾¾¾°°°´´´ººº¿¿¿ÃÃÃÅÅÅÎÎÎØØØ×××ØØØÜÜÜÛÛÛÛÛÛÕÕÕÔÔÔÙÙÙÝÝÝÜÜÜØØØÕÕÕÔÔÔÒÒÒ¾¾¾¼¼¼ºººººº»»»¿¿¿¿¿¿¾¾¾ººº···±±±¿¿¿ÊÊÊÌÌÌÔÔÔÒÒÒÑÑÑÊÊÊÉÉÉÌÌÌÅÅŵµµ³³³»»»ÀÀÀÅÅÅÅÅźºº±±±¼¼¼ÉÉÉÃÃÃÀÀÀ¾¾¾»»»¼¼¼¾¾¾ÂÂÂÉÉÉÑÑÑÉÉÉÌÌÌÎÎÎÐÐÐÐÐÐÐÐÐÔÔÔ×××ÙÙÙÜÜÜâââççççççææææææèèèßßßäääÛÛÛÒÒÒºººµµµ´´´ÀÀÀäääèèèíííïïïïïïëëëèèèæææèèèàààÇÇÇÀÀÀÃÃÃÌÌÌâââçççñññòòòïïïñññóóóïïïïïïüüüíííëëëëëëêêêèèèêêêêêêêêêëëëëëëëëëêêêèèèæææâââÝÝÝîîîâââÙÙÙÑÑÑÀÀÀ´´´µµµ¸¸¸ÃÃÃÃÃÃÇÇÇÎÎÎÐÐÐÊÊÊÉÉÉÊÊÊÕÕÕÕÕÕÙÙÙÝÝÝÝÝÝÛÛÛÛÛÛßßßàààÝÝÝÇÇÇÃÃÃÒÒÒÒÒÒÌÌÌÇÇǼ¼¼âââèèèïïïæææÙÙÙâââÑÑÑØØØÍÍÍÌÌÌØØØÜÜÜÕÕÕÒÒÒÙÙÙÙÙÙÛÛÛÛÛÛÙÙÙØØØÔÔÔÑÑÑÐÐÐÎÎÎÊÊÊÍÍÍ»»»´´´ÉÉÉÑÑÑÐÐÐÎÎÎÃÃþ¾¾ÀÀÀÇÇÇ¿¿¿ØØØÕÕÕÛÛÛÜÜÜ×××ÉÉÉÃÃÃÆÆÆÉÉÉÇÇÇÇÇÇÆÆÆÇÇÇÉÉÉÅÅž¾¾¼¼¼ÀÀÀ¾¾¾¼¼¼¼¼¼¾¾¾ÀÀÀÆÆÆÍÍÍÐÐÐÅÅÅÍÍÍÍÍÍÊÊÊÑÑÑÒÒÒÌÌÌÇÇÇÅÅÅÇÇÇÅÅÅÐÐÐÇÇÇÌÌÌÊÊÊÕÕÕ¿¿¿µµµµµµÀÀÀÊÊʱ±±¥¥¥¯¯¯ÅÅÅÆÆÆÉÉÉÅÅÅ···»»»¾¾¾µµµ¬¬¬¥¥¥ªªª¼¼¼ÊÊÊÍÍÍÇÇÇÔÔÔÕÕÕÔÔÔÔÔÔÙÙÙââââââÙÙÙßßßØØØÔÔÔ×××ÙÙÙÕÕÕÊÊÊÀÀÀÃÃÃÂÂÂÀÀÀÀÀÀ¿¿¿ººº´´´°°°°°°ÇÇÇÐÐÐÒÒÒÐÐÐÎÎÎÒÒÒÉÉÉÒÒÒÇÇÇÆÆÆÎÎÎÉÉɸ¸¸···ÂÂÂÂÂÂÃÃÃÅÅž¾¾±±±···ÅÅÅÉÉÉÅÅÅÅÅÅÆÆÆÆÆÆ¿¿¿»»»ÅÅÅÒÒÒÉÉÉÆÆÆÅÅÅÆÆÆÉÉÉÊÊÊÊÊÊÊÊÊÊÊÊÎÎÎÔÔÔÙÙÙßßßãããâââßßßÜÜÜææææææÙÙÙ³³³³³³¸¸¸¾¾¾¼¼¼¼¼¼¼¼¼ºººººº¼¼¼ÂÂÂÆÆÆÃÃÃÉÉÉÂÂÂÊÊÊÍÍÍÇÇÇÊÊÊÂÂÂäääïïïññññññöööõõõïïïòòòÿÿÿÿÿÿúúúøøøõõõòòòñññïïïëëëçççãããâââãããææææææææææææÊÊʼ¼¼ººº³³³³³³¿¿¿ÅÅÅÆÆÆÃÃÃÃÃÃÇÇÇÊÊÊÊÊÊÍÍÍÑÑÑÒÒÒÕÕÕÜÜÜããããããÝÝÝÛÛÛÜÜÜØØØàààÛÛÛßßßßßßÕÕÕÔÔÔÌÌ̼¼¼ÀÀÀæææêêêÙÙÙääääää×××ÛÛÛÎÎÎÐÐÐØØØØØØÛÛÛÝÝÝÙÙÙÕÕÕØØØÙÙÙÛÛÛØØØÒÒÒÎÎÎÌÌÌÑÑÑÎÎο¿¿ºººÎÎÎÛÛÛÔÔÔÎÎÎÉÉÉÂÂÂÎÎÎÊÊÊÅÅÅÑÑÑ×××ÝÝÝäääÛÛÛÑÑÑÍÍÍÉÉÉÅÅÅÆÆÆÌÌÌÊÊÊÊÊÊÊÊÊÇÇÇÅÅž¾¾¼¼¼Â¿¿¿¾¾¾ÃÃÃÍÍÍÑÑÑÐÐÐÊÊÊÍÍÍÂÂÂÂÂÂÌÌÌÐÐÐÒÒÒÔÔÔÎÎÎÎÎÎÍÍÍÑÑÑ×××ØØØÔÔÔÒÒÒÔÔÔÐÐÐÐÐÐÎÎÎÌÌÌÊÊÊÉÉÉÇÇÇÆÆÆÃÃÃÅÅÅÉÉÉÌÌÌÊÊÊÃÃ÷··¯¯¯···ÀÀÀÇÇÇÀÀÀ···µµµÀÀÀÌÌÌÅÅÅÀÀÀÅÅÅÆÆÆÜÜÜÐÐÐÊÊÊÅÅÅÐÐÐÍÍÍÊÊÊÊÊÊÌÌÌÌÌÌÊÊÊÉÉÉÃÃþ¾¾ÀÀÀºººººº³³³¬¬¬ÅÅÅÍÍÍÍÍÍÐÐÐÑÑÑÒÒÒÒÒÒÒÒÒÑÑÑÇÇÇÉÉÉÎÎÎÉÉɸ¸¸³³³¼¼¼ÂÂÂÀÀÀÉÉÉÇÇÇÃÃþ¾¾°°°¯¯¯¾¾¾ÉÉÉÇÇÇÇÇÇÅÅÅ¿¿¿»»»ººº»»»ÕÕÕÐÐÐÊÊÊÇÇÇÃÃÃÂÂÂÇÇÇÎÎÎÊÊÊÐÐÐÒÒÒÒÒÒÙÙÙãããäääàààâââÒÒÒàààÔÔÔ···µµµººº¼¼¼¾¾¾ÂÂÂÆÆÆÅÅÅÂÂÂÀÀÀÃÃÃÆÆÆÆÆÆÉÉÉÎÎÎÎÎÎÌÌÌÇÇÇÆÆÆÆÆÆÇÇÇÜÜÜíííïïïëëëíííñññóóóöööõõõòòòòòòóóóöööúúúÿÿÿöööïïïèèèçççëëëëëëäääßßß´´´¸¸¸¾¾¾ÀÀÀÀÀÀ¿¿¿¾¾¾¿¿¿ÅÅÅÅÅÅÇÇÇÌÌÌÐÐÐÑÑÑÑÑÑÐÐÐÑÑÑÕÕÕÛÛÛàààâââàààÝÝÝÛÛÛÛÛÛØØØÛÛÛààààààØØØÑÑÑÐÐÐÃÃÃÒÒÒïïïëëëßßßäääßßß×××ÜÜÜÒÒÒÔÔÔÜÜÜÛÛÛÛÛÛÛÛÛÕÕÕÛÛÛÙÙÙÙÙÙ×××ÔÔÔÒÒÒÑÑÑÐÐÐÍÍÍÉÉɼ¼¼¾¾¾ÐÐÐÙÙÙÔÔÔÐÐÐÒÒÒÆÆÆÍÍÍÇÇÇÅÅÅÒÒÒ×××ÜÜÜÙÙÙÒÒÒÎÎÎÎÎÎÍÍÍÉÉÉÇÇÇÊÊÊÌÌÌÊÊÊÉÉÉÇÇÇÅÅÅÃÃÃÀÀÀ¿¿¿ÅÅÅÂÂÂÃÃÃÇÇÇÐÐÐÔÔÔÒÒÒÐÐÐÒÒÒÉÉÉÇÇÇÍÍÍÌÌÌÎÎÎÔÔÔÔÔÔÒÒÒÌÌÌÅÅÅÅÅÅÅÅÅÇÇÇÐÐÐØØØ××××××ÕÕÕÒÒÒÑÑÑÐÐÐÎÎÎÍÍÍÅÅÅÇÇÇÌÌÌÑÑÑÔÔÔÐÐÐÉÉÉÃÃû»»¼¼¼¿¿¿ÃÃþ¾¾µµµµµµ¼¼¼ÎÎÎÌÌÌÍÍÍÉÉÉÕÕÕÌÌÌÐÐÐÔÔÔÎÎÎÎÎÎÍÍÍÍÍÍÌÌÌÊÊÊÆÆÆÃÃû»»´´´»»»¿¿¿ÉÉÉÌÌÌÉÉÉÙÙÙÐÐÐÒÒÒÕÕÕØØØØØØ×××ÕÕÕÒÒÒÕÕÕÎÎÎÌÌÌÃÃ÷··¸¸¸¿¿¿¼¼¼ÃÃÃÆÆÆÆÆÆÆÆÆÅÅż¼¼···¸¸¸ÂÂÂÆÆÆÅÅÅÀÀÀ¿¿¿ÂÂÂÀÀÀ»»»¿¿¿¿¿¿ÃÃÃÉÉÉÉÉÉÆÆÆÇÇÇÍÍÍÒÒÒÑÑÑÐÐÐÍÍÍÍÍÍÑÑÑÒÒÒÒÒÒÜÜÜØØØäääàààÆÆƸ¸¸ººº¾¾¾ÀÀÀÅÅÅÉÉÉÌÌÌÌÌÌÉÉÉÃÃÃÀÀÀÇÇÇÌÌÌÎÎÎÐÐÐÍÍÍÊÊÊÇÇÇÇÇÇÂÂÂÔÔÔãããççççççêêêïïïòòòóóóñññîîîîîîîîîñññòòòòòòëëëÜÜÜÇÇǺºº···ººº¾¾¾¿¿¿ÀÀÀÃÃÃÇÇÇÇÇÇÆÆÆÃÃÃÃÃÃÃÃÿ¿¿ÂÂÂÆÆÆÊÊÊÎÎÎÐÐÐÎÎÎÎÎÎÒÒÒ×××ÛÛÛßßßàààßßßÜÜÜÙÙÙÛÛÛØØØÙÙÙÝÝÝÝÝÝÕÕÕÎÎÎÍÍÍÃÃÃàààòòòçççãããâââ×××ÙÙÙÙÙÙÔÔÔÕÕÕÛÛÛÙÙÙ×××ÔÔÔÎÎÎØØØØØØØØØ×××ÕÕÕÒÒÒÑÑÑÎÎÎÉÉɼ¼¼ÅÅÅÔÔÔØØØÒÒÒÑÑÑÕÕÕÉÉÉÉÉÉÆÆÆÇÇÇÒÒÒØØØÝÝÝÐÐÐÍÍÍÌÌÌÎÎÎÐÐÐÍÍÍÌÌÌÌÌÌÌÌÌÊÊÊÉÉÉÇÇÇÆÆÆÅÅÅÃÃÃÃÃÃÅÅÅÅÅÅÆÆÆÊÊÊÎÎÎÒÒÒÑÑÑÐÐÐÐÐÐÊÊÊÐÐÐÔÔÔÎÎÎÍÍÍÕÕÕØØØÊÊÊÃÃÿ¿¿ÀÀÀÀÀÀÀÀÀÅÅÅÊÊÊÇÇÇÇÇÇÆÆÆÃÃÿ¿¿¾¾¾¾¾¾»»»¾¾¾ÃÃÃÉÉÉÎÎÎÑÑÑÑÑÑÐÐл»»¼¼¼ÊÊÊÐÐÐÊÊÊÉÉÉÐÐЯ¯¯´´´ººº¸¸¸Â¾¾¾ÉÉÉ××××××ÒÒÒÌÌÌÅÅÅ¿¿¿¾¾¾¿¿¿ÂÂÂÉÉɼ¼¼ÃÃÃÌÌÌÑÑÑÕÕÕÑÑÑÒÒÒÑÑÑÒÒÒ×××ÙÙÙÙÙÙ×××ÔÔÔÑÑÑÒÒÒÍÍÍÇÇÇ»»»³³³»»»ÃÃÿ¿¿Â¿¿¿¿¿¿ÃÃÃÆÆÆÇÇÇÀÀÀ´´´»»»ÅÅÅÇÇÇÀÀÀ¾¾¾ÃÃÃÃÃü¼¼ººº¼¼¼ÂÂÂÊÊÊÌÌÌÇÇÇÇÇÇÌÌÌÉÉÉÇÇÇÉÉÉÊÊÊÌÌÌÊÊÊÌÌÌÎÎÎÕÕÕÜÜÜâââäääÎÎγ³³³³³»»»ÀÀÀÃÃÃÉÉÉÎÎÎÒÒÒÑÑÑÌÌÌÆÆÆÊÊÊÍÍÍÑÑÑÑÑÑÐÐÐÍÍÍÊÊÊÉÉÉ¿¿¿ÇÇÇÍÍÍÊÊÊÅÅÅÂÂÂÂÂÂÂÂÂÛÛÛØØØÒÒÒÐÐÐÎÎÎÌÌÌÇÇÇÃÃÃÌÌÌÉÉÉÆÆÆÅÅÅÆÆÆÆÆÆÅÅÅÃÃÃÍÍÍÎÎÎÎÎÎÍÍÍÊÊÊÇÇÇÆÆÆÆÆÆ¿¿¿ÂÂÂÇÇÇÌÌÌÎÎÎÐÐÐÐÐÐÐÐÐÕÕÕØØØÜÜÜßßßßßßÝÝÝÙÙÙ×××ÙÙÙ×××ØØØÛÛÛÙÙÙÒÒÒÌÌÌÉÉÉ»»»ãããëëëÜÜÜâââÜÜÜÐÐÐÛÛÛÕÕÕÑÑÑÑÑÑÔÔÔÒÒÒÑÑÑÎÎÎÊÊÊÎÎÎÑÑÑÔÔÔØØØØØØÔÔÔÎÎÎÉÉÉÇÇÇ¿¿¿ÀÀÀÎÎÎÙÙÙÕÕÕÐÐÐÒÒÒÐÐÐÇÇÇÆÆÆÆÆÆÇÇÇÎÎÎ×××ßßßÑÑÑÎÎÎÍÍÍÍÍÍÎÎÎÎÎÎÍÍÍÍÍÍÍÍÍÌÌÌÉÉÉÇÇÇÆÆÆÆÆÆÆÆÆÇÇÇÅÅÅÆÆÆÇÇÇÉÉÉÊÊÊÊÊÊÊÊÊÊÊÊÅÅÅÇÇÇÔÔÔÛÛÛÑÑÑÍÍÍÒÒÒÕÕÕÆÆÆÂÂÂÀÀÀÃÃÃÃÃÿ¿¿¼¼¼¾¾¾¿¿¿¿¿¿¾¾¾»»»ººº¸¸¸···µµµ±±±´´´···¼¼¼ÃÃÃÉÉÉÍÍÍÐÐÐÐÐÐÆÆÆÀÀÀÂÂÂÅÅÅÃÃÃÃÃÃÆÆÆÆÆÆÌÌÌÎÎÎÌÌÌÉÉɼ¼¼¸¸¸ÂÂÂÃÃÃÂÂÂÀÀÀ¾¾¾¾¾¾ÂÂÂÉÉÉÐÐÐÅÅż¼¼ÆÆÆÑÑÑÒÒÒØØØÙÙÙÒÒÒ××××××ØØØÙÙÙÙÙÙØØØ×××ÕÕÕÊÊÊÍÍÍÌÌ̼¼¼´´´¾¾¾ºººÀÀÀººººººººº¸¸¸¾¾¾»»»©©©µµµÀÀÀÉÉÉÅÅÅ¿¿¿¿¿¿ÀÀÀ¿¿¿ººº¸¸¸¸¸¸ººº···´´´µµµººº¼¼¼¾¾¾ÆÆÆÐÐÐÒÒÒÎÎÎÌÌÌÎÎÎÎÎÎÛÛÛÛÛÛâââÒÒÒ±±±³³³ÀÀÀÃÃÃÆÆÆÉÉÉÍÍÍÎÎÎÐÐÐÎÎÎÎÎÎÌÌÌÎÎÎÑÑÑÔÔÔÒÒÒÐÐÐÍÍÍÌÌÌÍÍÍÎÎÎÐÐÐÍÍÍÉÉÉÆÆÆÆÆÆÅÅÅÎÎÎÍÍÍÍÍÍÐÐÐÒÒÒÔÔÔÑÑÑÍÍÍÌÌÌÍÍÍÑÑÑÔÔÔÔÔÔÒÒÒÑÑÑÐÐÐÑÑÑÑÑÑÐÐÐÎÎÎÌÌÌÉÉÉÇÇÇÇÇÇÆÆÆÉÉÉÌÌÌÎÎÎÐÐÐÑÑÑÒÒÒÔÔÔØØØÙÙÙÜÜÜßßßÝÝÝÜÜÜØØØÕÕÕ×××ÕÕÕ×××××××××ÑÑÑÌÌÌÇÇÇ¿¿¿äääãããØØØààà×××ÍÍÍÛÛÛÔÔÔÔÔÔÑÑÑÐÐÐÑÑÑÒÒÒÐÐÐÎÎÎÊÊÊÌÌÌÎÎÎÒÒÒÔÔÔÒÒÒÍÍÍÇÇÇÇÇÇÀÀÀÆÆÆ×××ÜÜÜÕÕÕÐÐÐÑÑÑÉÉÉÉÉÉÇÇÇÉÉÉÇÇÇÅÅÅÍÍÍ×××ÕÕÕÕÕÕÒÒÒÎÎÎÌÌÌÍÍÍÎÎÎÎÎÎÍÍÍÌÌÌÊÊÊÇÇÇÇÇÇÇÇÇÇÇÇÉÉÉÇÇÇÉÉÉÊÊÊÉÉÉÇÇÇÆÆÆÅÅÅÅÅÅÃÃÃÇÇÇÔÔÔÙÙÙÍÍÍÆÆÆÌÌÌÐÐÐÒÒÒÉÉÉ¿¿¿¿¿¿¾¾¾¾¾¾ÀÀÀ¾¾¾¾¾¾¼¼¼»»»ººº¸¸¸······µµµ···¸¸¸»»»¿¿¿ÅÅÅÊÊÊÎÎÎÒÒÒÔÔÔÍÍÍ»»»¾¾¾¿¿¿¼¼¼¼¼¼ÀÀÀÀÀÀÆÆÆÉÉÉÀÀÀ¸¸¸¼¼¼···¾¾¾ÅÅÅÊÊÊÊÊÊÉÉÉÇÇÇÇÇǺºº¾¾¾ÌÌÌÕÕÕÒÒÒØØØàààÙÙÙÜÜÜÛÛÛØØØ××××××ØØØÙÙÙÛÛÛÒÒÒ××××××ÆÆƵµµµµµµµµªªª···´´´······µµµÂÂÂÉÉÉÀÀÀµµµµµµ¼¼¼ÅÅÅÆÆÆ¿¿¿ÂÂÂÇÇÇÃÃÃÀÀÀÀÀÀ¼¼¼¸¸¸»»»ÀÀÀ¿¿¿¿¿¿ÆÆÆÐÐÐÑÑÑÌÌÌÇÇÇÉÉÉÉÉÉ×××ÕÕÕàààÙÙÙ¸¸¸µµµÂÂÂÂÂÂÆÆÆÌÌÌÍÍÍÊÊÊÉÉÉÊÊÊÎÎÎÌÌÌÎÎÎÑÑÑÔÔÔÔÔÔÒÒÒÐÐÐÎÎÎÊÊÊÉÉÉÉÉÉÉÉÉÉÉÉÇÇÇÉÉÉÊÊÊÆÆÆÇÇÇÌÌÌÑÑÑÕÕÕØØØ×××ÔÔÔ××××××ÕÕÕÒÒÒÑÑÑÒÒÒÔÔÔ×××ÒÒÒÒÒÒÑÑÑÑÑÑÐÐÐÎÎÎÍÍÍÌÌÌÍÍÍÍÍÍÍÍÍÎÎÎÐÐÐÒÒÒÔÔÔÕÕÕÙÙÙÛÛÛÝÝÝßßßÝÝÝÛÛÛØØØÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÑÑÑÍÍÍÇÇÇÔÔÔèèèàààÜÜÜàààÒÒÒÍÍÍØØØ×××ÛÛÛ×××ÔÔÔ×××ØØØ××××××ÎÎÎÌÌÌÉÉÉÉÉÉÌÌÌÍÍÍÌÌÌÉÉÉÅÅÅ¿¿¿ÊÊÊÛÛÛÜÜÜÔÔÔÑÑÑÐÐÐÉÉÉÌÌÌÆÆÆÊÊÊÉÉɾ¾¾ÂÂÂÌÌÌÔÔÔØØØ×××ÑÑÑÌÌÌÌÌÌÎÎÎÎÎÎÌÌÌÌÌÌÊÊÊÉÉÉÉÉÉÇÇÇÇÇÇÇÇÇÌÌÌÌÌÌÌÌÌÊÊÊÉÉÉÆÆÆÅÅÅÃÃÃÉÉÉÉÉÉÑÑÑÑÑÑÅÅÅ¿¿¿ÇÇÇÍÍÍÕÕÕÊÊÊÀÀÀ¿¿¿¿¿¿¾¾¾¿¿¿Â¸¸¸¸¸¸······µµµµµµµµµµµµ¸¸¸¸¸¸ººº»»»¼¼¼¿¿¿ÅÅÅÇÇÇÇÇÇ×××ÜÜÜÒÒÒÎÎÎÒÒÒÕÕÕÒÒÒÊÊÊÉÉɾ¾¾ÆÆÆÌÌÌÎÎÎÆÆÆÌÌÌÉÉÉÌÌÌÎÎÎÎÎÎÌÌÌÅÅÅ¿¿¿»»»»»»ÊÊÊÔÔÔØØØÔÔÔÔÔÔÜÜÜ×××ØØØÔÔÔÎÎÎÊÊÊÊÊÊÎÎÎÔÔÔØØØÛÛÛØØØ×××ÐÐÐÉÉÉÇÇÇ¿¿¿¥¥¥¦¦¦©©©ªªªªªª´´´¿¿¿Âººº¬¬¬¼¼¼ÉÉÉÇÇÇÃÃÃÃÃþ¾¾¼¼¼¾¾¾¿¿¿¾¾¾ººº»»»¿¿¿ÅÅÅÂÂÂÀÀÀÅÅÅÇÇÇÉÉÉÇÇÇÉÉÉÇÇÇÑÑÑÔÔÔÝÝÝØØغººªªª¯¯¯´´´¼¼¼ÆÆÆÊÊÊÌÌÌÌÌÌÍÍÍÎÎÎÊÊÊÌÌÌÎÎÎÒÒÒÕÕÕÕÕÕÒÒÒÐÐÐÔÔÔÐÐÐÍÍÍÌÌÌÉÉÉÆÆÆÅÅÅÇÇÇÑÑÑÔÔÔØØØÛÛÛÜÜÜÛÛÛÙÙÙØØØ×××ØØØÛÛÛÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÕÕÕÕÕÕÕÕÕ×××ØØØØØØÕÕÕÔÔÔÐÐÐÎÎÎÎÎÎÐÐÐÔÔÔÕÕÕ×××ÕÕÕÛÛÛÜÜÜÝÝÝßßßÝÝÝÛÛÛØØØ×××ÕÕÕÕÕÕÕÕÕÒÒÒÑÑÑÐÐÐÊÊÊÅÅÅäääçççÜÜÜßßßÝÝÝÎÎÎÐÐÐÔÔÔØØØßßßÜÜÜ×××ÛÛÛÜÜÜØØØØØØÕÕÕÐÐÐÉÉÉÇÇÇÉÉÉÊÊÊÉÉÉÆÆƾ¾¾¼¼¼ÌÌÌÛÛÛØØØÔÔÔÒÒÒÎÎÎÌÌÌÌÌÌ¿¿¿ÇÇÇÍÍÍÀÀÀÂÂÂÆÆÆÉÉÉÔÔÔÛÛÛ×××ÎÎÎÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÊÊÊÉÉÉÇÇÇÆÆÆÅÅÅÉÉÉÉÉÉÇÇÇÇÇÇÆÆÆÅÅÅÃÃÃÂÂÂÇÇÇÅÅÅÊÊÊÍÍÍÃÃÃÀÀÀÇÇÇÌÌÌÉÉɾ¾¾ÀÀÀ¿¿¿¼¼¼¼¼¼¸¸¸¸¸¸¸¸¸ºººººººººººººººµµµ¸¸¸ººººººººº»»»¿¿¿ÂÂÂÂÂÂÑÑÑÜÜÜÛÛÛ×××××××××ÕÕÕÔÔÔÎÎλ»»ÀÀÀÃÃÃÌÌÌÅÅÅÎÎÎÊÊÊÇÇÇÅÅÅÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀ´´´ÌÌÌÐÐÐÔÔÔÕÕÕÕÕÕÜÜÜ×××ÒÒÒÍÍÍÇÇÇÃÃÃÃÃÃÉÉÉÐÐÐÕÕÕÙÙÙÒÒÒÒÒÒÔÔÔÒÒÒÒÒÒÍÍÍÀÀÀÇÇÇÉÉÉÆÆÆ¿¿¿¸¸¸···¼¼¼¼¼¼³³³´´´¾¾¾ÀÀÀÃÃÃÅÅÅÅÅÅÃÃÃÅÅÅÇÇÇÅÅÅÀÀÀÂÂÂÆÆÆÅÅÅ¿¿¿¿¿¿ÅÅÅÌÌÌÍÍÍÉÉÉÉÉÉÊÊÊÔÔÔÙÙÙØØØÇÇÇ´´´±±±µµµ¸¸¸¼¼¼ÃÃÃÊÊÊÎÎÎÎÎÎÌÌÌÆÆÆÇÇÇÌÌÌÑÑÑÕÕÕ×××ÔÔÔÑÑÑÌÌÌÇÇÇÆÆÆÉÉÉÇÇÇÅÅÅÅÅÅÉÉÉÇÇÇÍÍÍÔÔÔØØØÙÙÙÛÛÛÝÝÝàààÝÝÝÜÜÜÙÙÙØØØØØØÙÙÙÛÛÛÛÛÛØØØ×××ØØØÛÛÛÜÜÜÜÜÜÙÙÙ×××ÔÔÔÑÑÑÒÒÒ×××ßßßâââßßßÛÛÛÜÜÜÝÝÝßßßßßßßßßÜÜÜÙÙÙØØØÕÕÕ×××ÕÕÕÐÐÐÍÍÍÌÌÌÆÆƾ¾¾ëëëàààÔÔÔßßßÛÛÛÌÌÌÒÒÒÑÑÑÕÕÕàààÝÝÝØØØÜÜÜÛÛÛÔÔÔÔÔÔ×××ÑÑÑÍÍÍÍÍÍÍÍÍÊÊÊÅÅÅ¿¿¿···ºººÊÊÊØØØÕÕÕÒÒÒÔÔÔÎÎÎÌÌÌÇÇǵµµÃÃÃÑÑÑÇÇÇÇÇÇÉÉɼ¼¼ÍÍÍÛÛÛÛÛÛÒÒÒÎÎÎÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÉÉÉÇÇÇÅÅÅÃÃÃÃÃÃÂÂÂÂÂÂÂÂÂÃÃÃÂÂÂÀÀÀ¾¾¾¾¾¾¼¼¼ÆÆÆÎÎÎÉÉÉÆÆÆÌÌÌÍÍÍ»»»···»»»¾¾¾¾¾¾»»»»»»µµµµµµ······¸¸¸¸¸¸ºººººº¸¸¸»»»¾¾¾¾¾¾¾¾¾¿¿¿ÂÂÂÅÅÅÂÂÂÊÊÊÔÔÔÛÛÛÙÙÙ××××××ÙÙÙÕÕÕÎÎθ¸¸»»»ºººÀÀÀ»»»ÅÅÅÃÃÃÀÀÀ¾¾¾¾¾¾¾¾¾¼¼¼¸¸¸µµµµµµÐÐÐÌÌÌÍÍÍÔÔÔÒÒÒÕÕÕÎÎÎØØØÒÒÒÍÍÍÉÉÉÊÊÊÐÐÐØØØÜÜÜØØØÒÒÒÕÕÕ×××ÐÐÐÍÍÍÎÎÎÊÊÊÇÇÇÊÊÊÆÆÆÆÆÆÆÆƸ¸¸´´´¾¾¾¾¾¾ººº±±±¯¯¯´´´¿¿¿ÇÇÇÊÊÊÆÆÆ¿¿¿»»»µµµ···¼¼¼ÉÉÉÇÇÇÅÅÅÃÃÃÉÉÉÑÑÑÍÍÍÃÃÃÉÉÉÃÃÃÒÒÒÛÛÛâââäää×××ÔÔÔÊÊÊ»»»¼¼¼ÅÅÅÊÊÊÇÇÇÀÀÀÅÅÅÆÆÆÊÊÊÐÐÐÕÕÕØØØÕÕÕÒÒÒÐÐÐÌÌÌÊÊÊÍÍÍÌÌÌÇÇÇÉÉÉÎÎÎÌÌÌÒÒÒÙÙÙÛÛÛÙÙÙØØØÛÛÛßßß×××××××××ÙÙÙÛÛÛÜÜÜÛÛÛØØØ××××××ØØØÛÛÛÜÜÜÜÜÜØØØÔÔÔ×××ÕÕÕØØØàààëëëîîîèèèâââÝÝÝÝÝÝßßßàààßßßÝÝÝÛÛÛÙÙÙ×××ØØØÕÕÕÍÍÍÉÉÉÇÇÇÀÀÀ¸¸¸îîîïïïÙÙÙâââââââââÕÕÕÐÐÐÕÕÕÕÕÕ×××ÙÙÙÛÛÛÙÙÙ×××ÔÔÔÔÔÔÐÐÐÎÎÎÐÐÐÎÎÎÇÇÇÃÃÃÅÅŵµµÌÌÌÙÙÙÕÕÕÔÔÔÙÙÙÔÔÔÉÉÉÎÎÎÇÇǾ¾¾´´´±±±µµµÀÀÀÇÇÇÇÇÇÆÆÆÌÌÌÜÜÜãããÎÎÎÅÅÅÒÒÒÊÊÊÊÊÊÆÆÆÀÀÀÃÃÃÉÉÉÆÆÆ¿¿¿ÃÃÃÂÂÂÀÀÀ¿¿¿¾¾¾¾¾¾¾¾¾¾¾¾ÂÂÂÀÀÀ¾¾¾¼¼¼ÅÅÅÌÌÌÇÇÇ¿¿¿¸¸¸¸¸¸ººº»»»»»»»»»ºººººº¸¸¸···µµµµµµµµµ···¸¸¸ºººººº¾¾¾»»»ºººÀÀÀÀÀÀÃÃÃÑÑÑ×××ÙÙÙÛÛÛ×××ØØØÛÛÛÙÙÙÕÕÕØØØÉÉÉ»»»ººº¾¾¾¾¾¾¿¿¿ÀÀÀ¿¿¿¼¼¼»»»¼¼¼¿¿¿¾¾¾»»»¸¸¸´´´ÅÅÅÐÐÐÎÎÎÊÊÊÍÍÍÎÎÎÎÎÎÐÐÐÑÑÑÌÌÌÅÅÅÊÊÊ×××ÙÙÙÕÕÕ××××××ÕÕÕÔÔÔÑÑÑÐÐÐÎÎÎÎÎÎÊÊÊÌÌÌÆÆÆÇÇÇÉÉɺºº©©©¬¬¬±±±»»»ÀÀÀ»»»¯¯¯ªªª³³³¾¾¾ÅÅž¾¾¸¸¸µµµ±±±¯¯¯´´´¾¾¾ÍÍ;¾¾ÉÉÉÒÒÒÒÒÒÎÎÎÍÍÍÆÆÆÇÇÇÊÊÊÐÐÐ×××ÜÜÜßßßßßßâââØØØÀÀÀ´´´¼¼¼¿¿¿¼¼¼ÀÀÀ¿¿¿ÂÂÂÆÆÆÉÉÉÎÎÎÔÔÔÑÑÑÌÌÌÉÉÉÆÆÆÊÊÊÊÊÊÊÊÊÌÌÌÉÉÉÇÇÇÌÌÌÎÎÎÒÒÒÔÔÔÕÕÕ×××ÙÙÙÛÛÛÙÙÙ××××××ØØØÜÜÜÝÝÝÝÝÝÜÜÜÙÙÙÛÛÛÜÜÜÝÝÝßßßÝÝÝÜÜÜÛÛÛÝÝÝÙÙÙÙÙÙãããîîîñññçççÜÜÜßßßÛÛÛØØØÙÙÙÝÝÝßßßÛÛÛ×××ÑÑÑ×××ÅÅż¼¼ÆÆÆäääâââäääèèèíííÙÙÙâââàààâââØØØÔÔÔÛÛÛÙÙÙØØØØØØØØØ×××ÔÔÔÑÑÑÎÎÎÍÍÍÌÌÌÍÍÍÉÉÉÃÃÿ¿¿¾¾¾¿¿¿ÐÐÐÙÙÙÕÕÕÔÔÔ×××ÑÑÑÆÆÆÊÊÊÇÇÇÀÀÀºººµµµ···¼¼¼ÀÀÀÇÇÇÃÃÃÀÀÀÌÌÌÛÛÛ×××ÊÊÊÉÉÉÇÇÇÊÊÊÉÉÉÅÅÅÃÃÃÃÃÃÃÃÃÂÂÂÀÀÀÀÀÀ¿¿¿¼¼¼»»»»»»»»»»»»»»»»»»¸¸¸···¼¼¼Â¿¿¿¸¸¸µµµ···¸¸¸ººº»»»»»»ºººººº···············¸¸¸ººº»»»···µµµºººÆÆÆÍÍÍÇÇÇÉÉÉÔÔÔÍÍÍÎÎÎÐÐÐÒÒÒÙÙÙßßßØØØÍÍÍÃÃúºº´´´···¾¾¾¿¿¿ÀÀÀÃÃþ¾¾¾¾¾¿¿¿¿¿¿¿¿¿¾¾¾¼¼¼»»»°°°¸¸¸ÀÀÀÅÅÅÊÊÊÍÍÍÍÍÍÌÌÌ×××ÜÜÜÕÕÕÉÉÉÌÌÌÙÙÙÛÛÛÐÐÐÍÍÍÍÍÍÎÎÎÎÎÎÎÎÎÎÎÎÐÐÐÐÐÐÆÆÆÅÅŵµµ©©©¥¥¥³³³ºººÀÀÀÀÀÀ»»»······ººº±±±±±±±±±±±±¬¬¬¯¯¯´´´ÉÉÉÆÆÆÀÀÀ¿¿¿ÃÃÃÊÊÊÉÉÉÅÅÅÊÊÊÊÊÊÉÉÉÉÉÉÊÊÊÎÎÎÒÒÒÕÕÕÝÝÝããããããÝÝÝ×××ÉÉɺºº´´´³³³µµµ¸¸¸¸¸¸¾¾¾ÆÆÆÌÌÌÌÌÌÌÌÌÊÊÊÊÊÊÉÉÉÇÇÇÉÉÉÉÉÉÉÉÉÊÊÊÍÍÍÑÑÑÒÒÒÔÔÔÔÔÔ×××ØØØØØØ××××××ØØØÛÛÛÝÝÝÝÝÝÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÙÙÙÙÙÙÙÙÙßßßãããäääàààÜÜÜÜÜÜÙÙÙÙÙÙÛÛÛßßßßßßÛÛÛ×××ÐÐÐÒÒÒÉÉÉÒÒÒÛÛÛëëëãããçççÜÜÜãããÔÔÔßßßâââçççãããäääçççâââÙÙÙÔÔÔÒÒÒÔÔÔÔÔÔÕÕÕÐÐÐÎÎÎÌÌÌÇÇÇÅÅÅÃÃÃÃÃÃÃÃÃÌÌÌÒÒÒØØØ×××ÔÔÔÒÒÒÍÍÍÃÃÃÇÇÇÇÇÇÆÆƼ¼¼¸¸¸······ÆÆÆÇÇÇÀÀÀÀÀÀÐÐÐÛÛÛÔÔÔÊÊÊÇÇÇÉÉÉÊÊÊÉÉɾ¾¾¿¿¿ÅÅÅÀÀÀ¿¿¿¼¼¼»»»¸¸¸¸¸¸······¸¸¸¸¸¸···µµµ···ººº¸¸¸´´´³³³´´´µµµ¸¸¸ºººººººººººº······¸¸¸¸¸¸¸¸¸ººº»»»»»»¿¿¿µµµ¼¼¼ÊÊÊÅÅŵµµ°°°µµµººº¿¿¿ÇÇÇÎÎÎÔÔÔÒÒÒÇÇÇ»»»¾¾¾»»»»»»¿¿¿ÂÂÂÂÂÂÀÀÀ¿¿¿ÃÃÃÆÆÆÅÅÅÂÂÂÀÀÀ¾¾¾¾¾¾´´´¯¯¯¯¯¯¸¸¸ÅÅÅÉÉÉÊÊÊÊÊÊÑÑÑØØØÕÕÕÇÇÇÌÌÌÝÝÝàààÒÒÒÑÑÑÑÑÑÐÐÐÐÐÐÎÎÎÎÎÎÍÍÍÍÍÍÌÌÌÉÉÉÉÉÉÇÇÇÃÃÿ¿¿µµµ¨¨¨¬¬¬°°°···¾¾¾Â¿¿¿¼¼¼ÀÀÀÂÂÂÃÃÃÂÂÂÂÂÂÀÀÀ»»»µµµ¿¿¿ÇÇÇÇÇǼ¼¼¾¾¾ÌÌÌÑÑÑÌÌÌÆÆÆÆÆÆÃÃÃÂÂÂÂÂÂÇÇÇÒÒÒÛÛÛâââãããëëëîîîçççäääãããßßßââââââÙÙÙÉÉɾ¾¾¾¾¾¿¿¿ÀÀÀÂÂÂÆÆÆÅÅÅÆÆÆÇÇÇÆÆÆÆÆÆÇÇÇÊÊÊÍÍÍÐÐÐÑÑÑÑÑÑÑÑÑÒÒÒÕÕÕ×××ÕÕÕÕÕÕØØØÛÛÛÜÜÜÜÜÜÜÜÜßßßÜÜÜÙÙÙ××××××ØØØÛÛÛÜÜÜÙÙÙÛÛÛÜÜÜÛÛÛÙÙÙÙÙÙÜÜÜßßßØØØØØØÙÙÙÜÜÜàààßßßÙÙÙÕÕÕÐÐÐÌÌÌÇÇÇãããëëëíííãããëëëæææíííÙÙÙßßßÜÜÜàààßßßãããçççäääßßßÜÜÜÙÙÙØØØÔÔÔÑÑÑÒÒÒÑÑÑÊÊÊÅÅÅÅÅÅÌÌÌÑÑÑÒÒÒÕÕÕÔÔÔ××××××ÒÒÒÒÒÒÎÎÎÅÅÅÇÇÇÊÊÊÊÊÊÇÇÇÀÀÀººº³³³°°°ÆÆÆÎÎÎÍÍÍÅÅÅÉÉÉÔÔÔÙÙÙØØØÎÎÎÊÊÊÇÇÇÇÇǼ¼¼¿¿¿ÆÆÆÀÀÀ¿¿¿¾¾¾»»»¸¸¸······µµµººººººººº······µµµµµµ´´´°°°±±±³³³µµµ···¸¸¸ººº»»»¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¿¿¿ºººÅÅÅÎÎÎÀÀÀ´´´µµµ···ººº¾¾¾¾¾¾ºººµµµµµµ¸¸¸¼¼¼ÀÀÀÂÂÂÅÅÅÆÆÆÅÅÅÂÂÂÀÀÀÀÀÀÂÂÂÅÅÅÅÅÅÃÃÃÃÃÃÃÃÿ¿¿ººº»»»¨¨¨³³³¿¿¿ÂÂÂÆÆÆÌÌÌÌÌÌÌÌÌÉÉÉÃÃÃÇÇÇØØØßßßÕÕÕÔÔÔÒÒÒÑÑÑÐÐÐÐÐÐÎÎÎÍÍÍÌÌÌÊÊÊÆÆÆÇÇÇÆÆÆ¿¿¿ÀÀÀ»»»©©©¬¬¬°°°´´´¸¸¸»»»¼¼¼¼¼¼Â¿¿¿¿¿¿ÅÅÅÉÉÉÀÀÀ´´´µµµÃÃÃÉÉÉÀÀÀ¿¿¿ÉÉÉÐÐÐÍÍÍÎÎÎÎÎÎÌÌÌÅÅÅ¿¿¿ÂÂÂÊÊÊÔÔÔßßß×××ÛÛÛàààßßßçççíííçççèèèêêêâââÐÐÐÀÀÀ»»»¼¼¼¿¿¿µµµ¿¿¿¼¼¼ÂÂÂÉÉÉÅÅÅÅÅÅÃÃÃÊÊÊÍÍÍÐÐÐÐÐÐÐÐÐÐÐÐÑÑÑÒÒÒÔÔÔÔÔÔÕÕÕ×××ÙÙÙÛÛÛÜÜÜÜÜÜßßßÜÜÜØØØÕÕÕÔÔÔÕÕÕ×××ÙÙÙÙÙÙÛÛÛÛÛÛÙÙÙØØØÙÙÙÜÜÜàààÕÕÕ×××ÙÙÙÝÝÝàààßßßÙÙÙÔÔÔÎÎÎÇÇÇÂÂÂãããëëëëëëçççïïïëëëñññÛÛÛßßßÛÛÛßßßßßßæææÝÝÝâââæææêêêèèèàààÔÔÔÌÌÌÎÎÎÌÌÌÇÇÇÉÉÉÍÍÍÕÕÕÙÙÙÛÛÛ×××ÒÒÒÕÕÕ×××ÑÑÑÔÔÔÔÔÔÉÉÉÉÉÉÌÌÌÍÍÍÉÉɺºº³³³¯¯¯ÆÆÆÌÌÌÑÑÑÍÍÍÇÇÇÌÌÌÕÕÕÛÛÛØØØÍÍÍÅÅÅÃÃÃÃÃÃÀÀÀÀÀÀÆÆÆÃÃÿ¿¿¼¼¼»»»ººº¸¸¸¸¸¸»»»ºººººº¸¸¸µµµ³³³³³³´´´°°°°°°±±±³³³µµµ¸¸¸ººº»»»ºººººº¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸»»»ÀÀÀÌÌÌÊÊʺºº¸¸¸ÂÂÂÃÃÃÃÃÃÆÆÆÉÉÉÇÇǼ¼¼¼¼¼¿¿¿ÀÀÀÅÅÅÉÉÉÇÇÇÃÃÃÃÃÃÃÃÃÅÅźººººº¸¸¸¸¸¸¿¿¿ÅÅÅÀÀÀµµµµµµªªªªªª¸¸¸ÂÂÂÂÂÂÅÅÅÍÍÍÒÒÒÅÅÅÂÂÂÅÅÅÅÅÅÍÍÍØØØ×××ÎÎÎÍÍÍÌÌÌÍÍÍÐÐÐÑÑÑÐÐÐÎÎÎÌÌÌÇÇÇÉÉÉÇÇÇÀÀÀÅÅÅÃÃô´´¾¾¾¼¼¼¸¸¸±±±¯¯¯´´´ºººªªª°°°´´´´´´ºººÃÃÃÅÅÅÀÀÀ³³³»»»ÂÂÂÃÃÃÀÀÀ¾¾¾¿¿¿ÀÀÀÍÍÍÐÐÐÐÐÐÊÊÊÂÂÂÀÀÀÆÆÆÍÍÍÊÊÊÉÉÉ×××ããããããäääâââÕÕÕäääëëëîîîçççàààßßßâââäää¿¿¿ÆÆƺºº¼¼¼ÆÆÆÂÂÂÅÅÅÅÅÅÉÉÉÌÌÌÎÎÎÐÐÐÐÐÐÐÐÐÑÑÑÒÒÒÑÑÑÒÒÒÔÔÔ×××ØØØÙÙÙÛÛÛÜÜÜÜÜÜÛÛÛØØØ×××ÔÔÔÒÒÒÒÒÒÒÒÒÔÔÔÔÔÔÒÒÒÔÔÔØØØÛÛÛÜÜÜÜÜÜÕÕÕ×××ÙÙÙÜÜÜÝÝÝÜÜÜØØØÔÔÔÌÌÌÉÉÉÂÂÂäääëëëîîîïïïñññçççîîîÙÙÙàààÝÝÝäääæææíííãããããããããäääãããßßßÙÙÙÕÕÕÇÇÇÂÂÂÃÃÃÎÎÎØØØÙÙÙ×××ÕÕÕÔÔÔÑÑÑÕÕÕÕÕÕÐÐÐØØØÛÛÛÍÍÍÊÊÊÌÌÌÌÌÌÉÉɺºº´´´±±±ÃÃÃÂÂÂÇÇÇÍÍÍÊÊÊÊÊÊÎÎÎÎÎÎÜÜÜÑÑÑÇÇÇÃÃÃÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÃÃÃÀÀÀ¿¿¿¼¼¼¼¼¼»»»»»»ººº·········´´´°°°°°°±±±°°°°°°±±±³³³´´´···ººº»»»»»»ººº¸¸¸¸¸¸¸¸¸ººº¼¼¼¾¾¾ÆÆÆÍÍÍÑÑÑÅÅŵµµ···¾¾¾¿¿¿ÍÍÍÅÅž¾¾¿¿¿ÂÂÂÃÃÃÃÃÃÃÃð°°´´´µµµ°°°ªªª©©©ªªªªªª°°°°°°¯¯¯¯¯¯¸¸¸Â¿¿¿´´´ªªª¦¦¦¬¬¬¾¾¾ÇÇÇÆÆÆÆÆÆÌÌÌÔÔÔ¿¿¿¿¿¿ÉÉÉÉÉÉÍÍÍÙÙÙÝÝÝ×××ÔÔÔÑÑÑÑÑÑÔÔÔÔÔÔÑÑÑÍÍÍÍÍÍÊÊÊÊÊÊÇÇÇÅÅÅÇÇÇÉÉÉÅÅÅÊÊÊÉÉÉÃÃúºº³³³³³³¼¼¼ÆÆÆÇÇÇÐÐÐÒÒÒÉÉÉ»»»µµµººº¿¿¿µµµ´´´»»»ÆÆÆÇÇÇÀÀÀ¾¾¾ÃÃÿ¿¿ÆÆÆÌÌÌÊÊÊÆÆÆÂÂÂÅÅÅÉÉÉ¿¿¿ÆÆÆÔÔÔÝÝÝßßßâââæææäääÝÝÝæææíííëëëèèèèèèçççäääØØØÙÙÙ»»»···ÀÀÀ¼¼¼ÅÅÅÆÆÆÆÆÆÉÉÉÌÌÌÍÍÍÍÍÍÎÎÎÐÐÐÑÑÑÎÎÎÑÑÑÔÔÔÕÕÕ×××ØØØÛÛÛÜÜÜÛÛÛÛÛÛØØØ×××ÔÔÔÑÑÑÎÎÎÍÍÍÍÍÍÊÊÊÉÉÉÍÍÍÒÒÒ××××××ÕÕÕØØØØØØÙÙÙÛÛÛÛÛÛÙÙÙ×××ÕÕÕÌÌÌÍÍÍÇÇÇëëëñññóóóøøøòòòñññöööâââçççâââãããßßßàààêêêäääÝÝÝÙÙÙÙÙÙÛÛÛÜÜÜÜÜÜÎÎÎÂÂÂÀÀÀÑÑÑÛÛÛ×××ÑÑÑÑÑÑÑÑÑÑÑÑØØØÕÕÕÎÎÎÛÛÛàààÎÎÎÊÊÊÌÌÌÌÌÌÉÉÉ»»»···´´´ººº¸¸¸ÂÂÂÍÍÍÎÎÎÐÐÐÍÍÍÂÂÂÙÙÙ×××ÐÐÐÉÉÉÆÆÆÆÆÆÆÆÆÅÅÅÃÃÃÂÂÂÀÀÀ¿¿¿¾¾¾¾¾¾¼¼¼¼¼¼ºººµµµ´´´···µµµ±±±¯¯¯±±±±±±±±±±±±±±±´´´µµµ¸¸¸ººº»»»ººº¸¸¸ººº»»»ÀÀÀÅÅÅÉÉÉÍÍÍÐÐÐÌÌÌÅÅÅÂÂÂÀÀÀÀÀÀÅÅźºº±±±¯¯¯´´´ººººººµµµ³³³ÀÀÀÆÆÆÆÆƾ¾¾¸¸¸······µµµ³³³¸¸¸···±±±´´´¾¾¾¾¾¾···¬¬¬¦¦¦©©©···ÃÃÃÇÇÇÇÇÇÉÉÉÎÎξ¾¾ÀÀÀÊÊÊÉÉÉÑÑÑÜÜÜÛÛÛÙÙÙÕÕÕÐÐÐÎÎÎÎÎÎÍÍÍÉÉÉÃÃÃÀÀÀÀÀÀ¼¼¼»»»¼¼¼¼¼¼¿¿¿ÇÇÇÊÊÊÊÊÊÊÊÊÆÆÆÃÃÃÅÅÅÌÌÌÑÑÑÎÎÎÔÔÔØØØÕÕÕÇÇǾ¾¾¿¿¿ÆÆÆ»»»³³³´´´ÀÀÀÊÊÊÇÇÇÆÆÆÊÊÊÃÃÃÉÉÉÎÎÎÎÎÎÇÇÇÀÀÀ¾¾¾¼¼¼ÅÅÅÇÇÇÆÆÆÉÉÉÐÐÐ×××ÝÝÝæææÛÛÛàààæææçççêêêíííêêêäääãããââ⺺º³³³¾¾¾¸¸¸¿¿¿¿¿¿ÂÂÂÅÅÅÇÇÇÊÊÊÊÊÊÌÌÌÍÍÍÎÎÎÍÍÍÐÐÐÒÒÒÕÕÕÕÕÕ×××ÙÙÙÜÜÜÛÛÛÛÛÛØØØÕÕÕÑÑÑÎÎÎÍÍÍÌÌÌÉÉÉÇÇÇÇÇÇÊÊÊÎÎÎÒÒÒÕÕÕÕÕÕÛÛÛÛÛÛÙÙÙØØØ×××ÕÕÕÕÕÕÕÕÕÐÐÐÎÎÎÆÆÆïïïóóóóóóüüüöööîîîõõõãããêêêççççççßßßÝÝÝãããàààßßßÝÝÝÜÜÜÛÛÛ×××ÔÔÔÝÝÝÇÇÇÀÀÀÐÐÐÛÛÛÕÕÕÐÐÐÔÔÔÎÎÎÑÑÑÛÛÛÕÕÕÍÍÍÜÜÜâââÎÎÎÉÉÉÊÊÊÌÌÌÉÉÉÃÃü¼¼¸¸¸µµµ°°°···ÆÆÆÐÐÐÐÐÐÔÔÔÎÎξ¾¾ÔÔÔÙÙÙØØØÎÎÎÆÆÆÆÆÆÇÇÇÅÅÅÂÂÂÂÂÂÀÀÀ¿¿¿¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾···µµµ¸¸¸¸¸¸´´´±±±´´´±±±±±±±±±±±±³³³µµµ¸¸¸ººº»»»ººº¸¸¸ººº¿¿¿ÆÆÆÍÍÍÑÑÑÉÉÉÆÆÆ»»»»»»ÃÃû»»±±±µµµÇÇÇ¿¿¿ºººººººººººº¿¿¿ÆÆÆ¿¿¿ÆÆÆÉÉÉÅÅÅÂÂÂÅÅÅÅÅÅÃÃÿ¿¿ÇÇÇÇÇÇ»»»µµµººº¼¼¼ººº¸¸¸ªªª¢¢¢©©©¸¸¸ÃÃÃÆÆÆÆÆÆÎÎÎÂÂÂÆÆÆÌÌÌÆÆÆÎÎÎÕÕÕÌÌÌÇÇÇÃÃÿ¿¿¿¿¿Â¾¾¾ººº¿¿¿¿¿¿ººº¸¸¸¾¾¾ººº¾¾¾ÎÎÎÌÌÌÍÍÍÎÎÎÐÐÐÑÑÑÐÐÐÎÎÎÍÍÍÙÙÙÕÕÕÕÕÕ×××ÑÑÑÃÃúºº¸¸¸Âµµµ¯¯¯µµµÀÀÀÃÃÃÂÂÂÀÀÀ¾¾¾ÅÅÅÍÍÍÐÐÐÌÌÌÇÇÇÃÃÃÃÃÃÀÀÀÅÅÅÂÂÂÌÌÌàààæææßßßàààÜÜÜàààâââãããèèèíííêêêäääÝÝÝÝÝݵµµ±±±¿¿¿···ºººµµµ¾¾¾ÀÀÀÅÅÅÆÆÆÇÇÇÉÉÉÊÊÊÍÍÍÍÍÍÐÐÐÒÒÒÔÔÔÕÕÕ×××ÙÙÙÜÜÜÜÜÜÛÛÛ×××ÔÔÔÐÐÐÍÍÍÌÌÌÊÊÊÊÊÊÌÌÌÌÌÌÌÌÌÌÌÌÐÐÐÕÕÕÛÛÛÝÝÝÜÜÜÙÙÙÕÕÕÔÔÔÔÔÔÕÕÕ×××ÕÕÕÍÍÍÀÀÀîîîñññîîîüüüüüüöööúúúúúúòòòçççâââãããèèèãããàààÝÝÝÛÛÛÙÙÙØØØÙÙÙÙÙÙÕÕÕÆÆÆÂÂÂÐÐÐÛÛÛ×××ÑÑÑÒÒÒÒÒÒÎÎÎ×××ÒÒÒØØØàààÎÎÎÅÅÅÆÆÆÇÇÇÇÇÇÆÆÆÃÃþ¾¾ºººµµµ±±±···¾¾¾³³³ºººÎÎÎÍÍÍÇÇǸ¸¸×××àààÔÔÔÍÍÍÇÇÇÃÃÃÆÆÆÀÀÀÂÂÂÃÃÿ¿¿¾¾¾¾¾¾¿¿¿ººººººººº¸¸¸···µµµµµµµµµ±±±···ºººµµµ´´´······´´´´´´···ºººÀÀÀÆÆÆÉÉÉÉÉÉÇÇÇ¿¿¿¸¸¸¼¼¼Â¼¼¼ºººÀÀÀÅÅÅÆÆÆÅÅÅÃÃÃÃÃÃÆÆÆÉÉÉÉÉÉÉÉÉÆÆÆÅÅÅÂÂÂÀÀÀÀÀÀÀÀÀÂÂÂÃÃÃÂÂÂÂÂÂÃÃÃÅÅÅ´´´¬¬¬¼¼¼¿¿¿»»»´´´ªªª¦¦¦©©©´´´¿¿¿ÇÇÇÉÉÉÍÍÍÂÂÂÃÃÃÊÊÊÆÆÆÊÊÊÊÊÊÉÉÉÆÆÆÃÃÿ¿¿¼¼¼¼¼¼¼¼¼¾¾¾Â¾¾¾»»»»»»»»»»»»»»»¼¼¼ÍÍÍÐÐÐÎÎÎÉÉÉÂÂÂÂÂÂÊÊÊÒÒÒÙÙÙ×××ÛÛÛÔÔÔÌÌÌÔÔÔÊÊʨ¨¨ÀÀÀ¼¼¼±±±µµµ¿¿¿Â¾¾¾¾¾¾ÅÅÅÍÍÍÑÑÑÎÎÎÌÌÌÍÍÍÀÀÀ¾¾¾ÊÊÊÙÙÙàààçççæææÛÛÛØØØßßßßßßàààëëëïïïèèèäääâââãããÕÕÕ»»»°°°µµµ»»»···¸¸¸¼¼¼¼¼¼ÇÇÇÆÆƼ¼¼ÅÅÅÇÇÇÌÌÌÒÒÒÕÕÕÒÒÒÒÒÒ×××ÕÕÕÑÑÑÙÙÙÙÙÙØØØ×××ÔÔÔÐÐÐÍÍÍÊÊÊÊÊÊÊÊÊÊÊÊÌÌÌÎÎÎÑÑÑÔÔÔÕÕÕ×××ÝÝÝÙÙÙÒÒÒÔÔÔÑÑÑÐÐÐ×××ØØØÅÅÅÆÆÆëëëõõõñññÿÿÿõõõõõõùùùúúúõõõëëëãããàààâââààààààÝÝÝÜÜÜÛÛÛÛÛÛÙÙÙÙÙÙ×××ÎÎÎÍÍÍØØØàààÜÜÜ×××ÔÔÔÑÑÑÐÐÐÒÒÒÑÑÑ×××ÙÙÙÐÐÐÉÉÉÆÆÆÇÇÇÉÉÉÉÉÉÆÆÆ¿¿¿ºººµµµ¬¬¬¯¯¯···³³³´´´ÂÂÂÉÉÉÔÔÔÆÆÆ×××ÝÝÝÕÕÕÎÎÎÊÊÊÆÆÆÆÆÆÇÇÇÉÉÉÇÇÇÆÆÆÃÃÿ¿¿¾¾¾¼¼¼ÃÃÃÀÀÀ»»»···´´´µµµ¸¸¸ºººººº¼¼¼ººº´´´³³³¸¸¸¼¼¼¼¼¼¼¼¼¾¾¾ÀÀÀÆÆÆÌÌÌÍÍÍÌÌÌÉÉɺºººººÀÀÀÀÀÀººº¾¾¾ÅÅÅÃÃþ¾¾¾¾¾¾¾¾¿¿¿ÀÀÀÀÀÀ¾¾¾¼¼¼ÂÂÂÂÂÂÃÃÃÃÃÃÂÂÂÂÂÂÀÀÀÀÀÀ¿¿¿ÂÂÂÀÀÀÃÃø¸¸¯¯¯¼¼¼Â¼¼¼ººº´´´¯¯¯¬¬¬°°°ºººÂÂÂÉÉÉÍÍÍÂÂÂÃÃÃÊÊÊÆÆÆÉÉÉÊÊÊÇÇÇÆÆÆ¿¿¿¼¼¼¼¼¼¼¼¼¼¼¼ººººººººº¼¼¼ÅÅÅÌÌÌÐÐÐÎÎÎÀÀÀÃÃÃÆÆÆÃÃÿ¿¿ÀÀÀÆÆÆÌÌÌÜÜÜÕÕÕ×××ÔÔÔÎÎÎÕÕÕÎÎΰ°°³³³¼¼¼ÀÀÀ¸¸¸¬¬¬´´´¼¼¼ºººººº¿¿¿ÆÆÆÊÊÊÊÊÊÍÍÍÒÒÒÉÉÉÂÂÂÆÆÆÍÍÍÑÑÑÛÛÛâââÝÝÝßßßãããÝÝÝÜÜÜçççîîîêêêèèèÜÜÜßßßÜÜÜÎÎμ¼¼³³³³³³···ºººÀÀÀ¼¼¼¾¾¾»»»ºººÅÅÅÆÆÆÆÆÆÆÆÆÊÊÊÑÑÑ×××ÙÙÙßßßâââÜÜÜÛÛÛØØØÕÕÕÒÒÒÎÎÎÌÌÌÊÊÊÊÊÊÊÊÊÌÌÌÍÍÍÎÎÎÐÐÐÑÑÑÒÒÒÕÕÕÙÙÙÕÕÕÔÔÔÕÕÕÎÎÎÇÇÇÌÌÌÀÀÀ¾¾¾ÉÉÉæææîîîñññÿÿÿïïïóóóöööùùùöööïïïæææßßßÜÜÜßßßÝÝÝÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÑÑÑÒÒÒÕÕÕÙÙÙÝÝÝÛÛÛÕÕÕÐÐÐÑÑÑÐÐÐÍÍÍÒÒÒÒÒÒÎÎÎÎÎÎÌÌÌÅÅÅÇÇÇÊÊÊÊÊÊÇÇÇÀÀÀºººµµµ±±±³³³»»»···µµµ¿¿¿ÃÃÃÎÎÎÃÃÃÍÍÍÙÙÙÜÜÜÒÒÒÌÌÌÍÍÍÌÌÌÇÇÇÆÆÆÃÃÃÂÂÂÀÀÀÀÀÀÀÀÀÀÀÀ¿¿¿¼¼¼»»»»»»¾¾¾ÃÃÃÇÇÇÊÊÊÉÉÉÉÉÉÆÆÆÀÀÀ¿¿¿ÃÃÃÉÉÉÊÊÊÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÊÊÊÅÅÅÀÀÀ¼¼¼¼¼¼¼¼¼¸¸¸¸¸¸ÅÅÅÌÌÌÂÂÂÀÀÀ¾¾¾»»»»»»»»»¼¼¼»»»»»»¾¾¾¾¾¾¾¾¾¾¾¾¿¿¿ÀÀÀÀÀÀÂÂÂÀÀÀÇÇÇÀÀÀ¾¾¾³³³ºººÀÀÀ¾¾¾¿¿¿¿¿¿¸¸¸±±±¯¯¯´´´ºººÉÉÉÎÎÎÂÂÂÅÅÅÊÊÊÆÆÆÉÉÉÉÉÉÇÇÇÅÅÅ¿¿¿¼¼¼»»»»»»»»»ººº¼¼¼¼¼¼¾¾¾ÇÇÇÒÒÒÕÕÕÎÎθ¸¸»»»¿¿¿ÀÀÀÂÂÂÂÂÂÅÅÅÇÇÇ×××ÒÒÒ×××ØØØÑÑÑÒÒÒÑÑÑÀÀÀ´´´µµµººº»»»¸¸¸±±±¯¯¯¯¯¯¼¼¼»»»¼¼¼¿¿¿ÀÀÀ¿¿¿ÆÆÆÍÍÍÉÉÉÃÃÃÂÂÂÂÂÂÅÅÅÎÎÎÜÜÜßßßâââäääÝÝÝÜÜÜçççîîîêêêçççâââßßßââââââÑÑѸ¸¸°°°ºººÆÆÆ»»»µµµ¸¸¸ÅÅÅÂÂÂÊÊÊÆÆÆÇÇÇÐÐÐÔÔÔÐÐÐÑÑÑØØØÜÜÜÛÛÛ×××ÒÒÒÐÐÐÌÌÌÊÊÊÉÉÉÉÉÉÊÊÊÍÍÍÎÎÎÐÐÐÑÑÑÐÐÐÐÐÐÔÔÔÒÒÒÎÎÎÐÐÐÐÐÐÉÉÉÇÇÇÎÎÎÆÆÆÎÎÎÜÜÜêêêëëëöööÿÿÿñññóóóõõõööööööòòòëëëãããÝÝÝÝÝÝÜÜÜÙÙÙØØØØØØØØØÙÙÙÛÛÛÎÎÎ×××ÜÜÜÛÛÛÙÙÙÙÙÙÕÕÕÎÎÎÐÐÐÒÒÒÌÌÌÔÔÔÑÑÑÅÅÅÊÊÊÉÉÉÆÆÆÇÇÇÉÉÉÇÇÇÅÅÅÀÀÀ»»»¸¸¸¸¸¸¼¼¼Âººº¾¾¾ÍÍÍÇÇÇ»»»ÂÂÂ×××ããã×××ÌÌÌÍÍÍÌÌÌÎÎÎÍÍÍÌÌÌÍÍÍÎÎÎÑÑÑÒÒÒÔÔÔÑÑÑÑÑÑÑÑÑÑÑÑÐÐÐÌÌÌÆÆÆÂÂÂÅÅÅÆÆÆÇÇÇÆÆÆÃÃÃÃÃÃÅÅÅÆÆÆÇÇÇÆÆÆÃÃÿ¿¿¼¼¼ºººÀÀÀººº´´´³³³¸¸¸ÉÉÉÍÍÍÀÀÀ¼¼¼»»»»»»¼¼¼¾¾¾¼¼¼ºººµµµ¿¿¿¾¾¾¼¼¼»»»¾¾¾ÀÀÀÅÅÅÇÇÇÅÅÅÎÎÎÅÅÅÃÃô´´µµµ¼¼¼ÀÀÀÂÂÂÀÀÀ¾¾¾¸¸¸³³³±±±°°°ÉÉÉÎÎÎÃÃÃÅÅÅÌÌÌÇÇÇÉÉÉÉÉÉÆÆÆÅÅÅ¿¿¿¼¼¼»»»»»»»»»»»»¿¿¿¼¼¼»»»ÃÃÃÎÎÎÍÍÍ»»»¾¾¾ÀÀÀÃÃÃÆÆÆÉÉÉÉÉÉÊÊÊÍÍÍÎÎÎØØØÜÜÜÒÒÒÐÐÐÒÒÒÐÐÐÀÀÀµµµ°°°¸¸¸¿¿¿»»»±±±´´´µµµººº¼¼¼¼¼¼»»»¿¿¿ÇÇÇ¿¿¿¿¿¿ÀÀÀÀÀÀÂÂÂÊÊÊ×××ÝÝÝßßßãããààààààëëëîîîçççãããçççßßßÝÝÝæææàààÍÍͼ¼¼¸¸¸ÛÛÛäääàààØØØÉÉɼ¼¼¾¾¾···¾¾¾¼¼¼ÀÀÀÉÉÉÍÍÍÌÌÌÎÎÎÒÒÒ×××ÕÕÕÒÒÒÎÎÎÌÌÌÉÉÉÉÉÉÉÉÉÇÇÇÊÊÊÎÎÎÑÑÑÒÒÒÒÒÒÒÒÒÑÑÑÔÔÔÎÎÎÊÊÊÉÉÉÆÆÆÆÆÆÑÑÑãããäääèèèîîîîîîíííöööÿÿÿñññóóóóóóóóóóóóòòòîîîèèèäääÝÝÝÛÛÛ×××ÔÔÔÒÒÒÔÔÔ×××ÙÙÙÔÔÔßßßäääàààÜÜÜÜÜÜÙÙÙÔÔÔÐÐÐÒÒÒÍÍÍÔÔÔÎÎο¿¿ÅÅÅÃÃÃÇÇÇÇÇÇÆÆÆÃÃÃÀÀÀ¾¾¾¼¼¼»»»ººº¼¼¼Â¼¼¼ÀÀÀÐÐÐÌÌÌÊÊÊÆÆÆÂÂÂÐÐÐßßßÛÛÛÔÔÔÑÑÑÍÍÍÐÐÐÒÒÒÕÕÕØØØ×××ÔÔÔÐÐÐÌÌÌÌÌÌÊÊÊÊÊÊÉÉÉÅÅž¾¾´´´¬¬¬ªªªªªª¬¬¬¬¬¬©©©¨¨¨¨¨¨ªªª©©©¨¨¨¦¦¦¨¨¨¬¬¬¯¯¯±±±±±±ººº´´´···¼¼¼¾¾¾ÅÅÅÇÇÇ¿¿¿ÂÂÂÉÉÉÎÎÎÐÐÐÌÌÌÃÃü¼¼¾¾¾¾¾¾¼¼¼¼¼¼¼¼¼¼¼¼¾¾¾¾¾¾ÆÆÆÐÐÐÆÆÆÆÆÆÅÅÅ···¸¸¸ÀÀÀÅÅÅÀÀÀ¾¾¾¿¿¿ÀÀÀ¼¼¼³³³ªªªÊÊÊÐÐÐÅÅÅÇÇÇÍÍÍÇÇÇÉÉÉÇÇÇÆÆÆÅÅÅÃÃÃÀÀÀ¾¾¾¼¼¼»»»»»»µµµ»»»»»»ºººÂÂÂÎÎÎÌÌÌÀÀÀÃÃÃÂÂÂÃÃÃÅÅÅÇÇÇÊÊÊÌÌÌÌÌÌÊÊÊÉÉÉÐÐÐ×××ÕÕÕÔÔÔÔÔÔÑÑÑÇÇǸ¸¸¯¯¯±±±···¸¸¸······¢¢¢¨¨¨³³³¼¼¼¿¿¿¾¾¾ÀÀÀÇÇǼ¼¼ÀÀÀÂÂÂÂÂÂÂÂÂÇÇÇÐÐÐÙÙÙÝÝÝäääâââàààêêêíííçççäääãããßßßÝÝÝàààâââÝÝÝ×××ÐÐÐØØØÝÝÝÙÙÙÛÛÛÎÎλ»»ººº¸¸¸ÂÂÂÆÆÆÆÆÆÃÃÃÃÃÃÉÉÉÎÎÎÐÐÐÐÐÐÎÎÎÌÌÌÉÉÉÇÇÇÇÇÇÇÇÇÇÇÇÆÆÆÊÊÊÎÎÎÒÒÒÕÕÕÕÕÕÔÔÔÒÒÒÒÒÒÐÐÐÍÍÍÉÉÉÀÀÀÆÆÆÜÜÜòòòòòòíííîîîîîîíííòòòñññêêêòòòñññïïïïïïîîîíííëëëêêêàààÜÜÜ×××ÒÒÒÑÑÑÑÑÑÒÒÒÕÕÕÑÑÑÜÜÜãããßßßÙÙÙØØØÕÕÕÒÒÒÎÎÎÒÒÒÑÑÑÑÑÑÊÊÊÀÀÀÀÀÀÂÂÂÇÇÇÅÅÅ¿¿¿¼¼¼»»»»»»¼¼¼¿¿¿¼¼¼ÃÃÿ¿¿¼¼¼¿¿¿ÂÂÂÐÐÐÐÐÐÃÃÃÃÃÃÐÐÐÛÛÛàààßßßÙÙÙÐÐÐÕÕÕÙÙÙÙÙÙÑÑÑÅÅŸ¸¸³³³³³³°°°¯¯¯±±±µµµ···µµµ´´´»»»¸¸¸µµµµµµ³³³±±±´´´ºººµµµ´´´³³³µµµººº¾¾¾ÀÀÀ°°°µµµÅÅÅÊÊÊÂÂÂÀÀÀÅÅÅÅÅÅÌÌÌÌÌÌÌÌÌÎÎÎÐÐÐÐÐÐÍÍÍÊÊÊÒÒÒÔÔÔ×××ØØØÕÕÕÐÐÐÊÊÊÆÆÆÃÃÃÌÌÌÆÆÆÉÉÉÆÆƼ¼¼ÅÅÅÌÌÌÉÉɾ¾¾ÀÀÀÅÅÅÃÃø¸¸ÌÌÌÑÑÑÇÇÇÊÊÊÎÎÎÉÉÉÊÊÊÉÉÉÆÆÆÆÆÆÃÃÿ¿¿¾¾¾¼¼¼»»»ººº¾¾¾¿¿¿ÀÀÀÇÇÇÐÐÐÎÎÎÅÅÅÅÅÅÃÃÃÃÃÃÃÃÃÅÅÅÆÆÆÇÇÇÇÇÇÌÌÌÃÃÃÃÃÃÌÌÌÕÕÕÙÙÙÔÔÔÌÌÌÎÎμ¼¼ªªª©©©±±±¸¸¸¸¸¸···¤¤¤±±±¾¾¾Â¿¿¿¾¾¾ÀÀÀÀÀÀÆÆÆÅÅÅÀÀÀÀÀÀÂÂÂÉÉÉÔÔÔßßßäääàààÜÜÜâââçççèèèëëëäääêêêèèèàààÜÜÜÝÝÝßßßÝÝÝÛÛÛÜÜÜÙÙÙãããâââÙÙÙâââæææâââäääÝÝÝÌÌÌÀÀÀÂÂÂÇÇÇÇÇÇÊÊÊÉÉÉÉÉÉÇÇÇÆÆÆÆÆÆÆÆÆÆÆÆÇÇÇÊÊÊÎÎÎÒÒÒÔÔÔÔÔÔÒÒÒÒÒÒÎÎÎÎÎÎÑÑÑÌÌÌÃÃÃÌÌÌâââïïïîîîçççíííïïïòòòóóóíííëëëïïïïïïíííëëëèèèçççèèèèèèâââßßßÛÛÛ×××ÔÔÔÑÑÑÐÐÐÐÐÐÊÊÊÔÔÔÝÝÝÝÝÝØØØÒÒÒÎÎÎÍÍÍÎÎÎÐÐÐÒÒÒÊÊÊÅÅÅÅÅÅÂÂÂÅÅÅÃÃÿ¿¿¾¾¾»»»ºººººººººÂ¾¾¾ÆÆÆÃÃþ¾¾»»»ºººÆÆÆÐÐÐÊÊÊÃÃÃÆÆÆÒÒÒÙÙÙÛÛÛÝÝÝÛÛÛÝÝÝÝÝÝÕÕÕÉÉɾ¾¾¸¸¸···¾¾¾ººº´´´µµµººº¿¿¿ÀÀÀÀÀÀ»»»¸¸¸···¸¸¸µµµ±±±³³³¸¸¸···µµµ´´´´´´·········µµµµµµ¿¿¿ÊÊÊÉÉÉÂÂÂÇÇÇÍÍÍÇÇÇÐÐÐÌÌÌÇÇÇÅÅÅÆÆÆÇÇÇÉÉÉÉÉÉÊÊÊÌÌÌÎÎÎÐÐÐÎÎÎÌÌÌÇÇÇÅÅÅÅÅÅÉÉÉÉÉÉÍÍÍÅÅž¾¾ÍÍÍÒÒÒÎÎÎÇÇÇÃÃÃÅÅÅÇÇÇÆÆÆ¿¿¿···ÍÍÍÔÔÔÊÊÊÌÌÌÑÑÑÊÊÊÊÊÊÉÉÉÇÇÇÆÆÆÅÅÅÃÃÃÀÀÀ¿¿¿¼¼¼»»»¿¿¿ÀÀÀÅÅÅÉÉÉÎÎÎÑÑÑÎÎÎÉÉÉÂÂÂÂÂÂÃÃÃÃÃÃÃÃÃÃÃÃÅÅÅÆÆÆÇÇÇÃÃÿ¿¿ÂÂÂÌÌÌÔÔÔÒÒÒÍÍÍÐÐÐÃÃô´´¬¬¬±±±ºººººº´´´¤¤¤¨¨¨±±±¼¼¼ÀÀÀ¼¼¼ººº»»»¾¾¾ÆÆÆÆÆÆÃÃÃÅÅÅÂÂÂÅÅÅÎÎÎÛÛÛãããâââÛÛÛßßßäääèèèïïïêêêîîîíííãããÜÜÜÛÛÛÛÛÛÛÛÛßßßàààÛÛÛààààààßßßçççççççççíííëëëßßßÎÎÎÇÇÇÉÉÉÍÍÍÉÉÉÉÉÉÉÉÉÉÉÉÇÇÇÆÆÆÅÅÅÅÅÅÇÇÇÊÊÊÍÍÍÎÎÎÐÐÐÎÎÎÍÍÍÍÍÍÉÉÉÇÇÇÊÊÊÆÆÆÅÅÅ×××çççèèèëëëêêêóóóïïïïïïòòòëëëïïïîîîíííëëëèèèæææãããääääääãããâââßßßÜÜÜØØØÒÒÒÎÎÎÌÌÌÌÌÌÕÕÕàààäääßßßÕÕÕÐÐÐÎÎÎÎÎÎÍÍÍÒÒÒÅÅÅÀÀÀÉÉÉÅÅÅÉÉÉÀÀÀÀÀÀ¿¿¿¾¾¾»»»ººº······¸¸¸»»»ÆÆÆÅÅÅÇÇÇÍÍÍÀÀÀ»»»ÎÎÎ×××ÑÑÑÇÇÇÆÆÆÃÃÃÅÅÅÐÐÐÛÛÛÙÙÙÑÑÑÅÅŸ¸¸µµµ¾¾¾ÆÆƼ¼¼······»»»¿¿¿¿¿¿¾¾¾ºººººº¼¼¼Â¿¿¿···´´´···µµµµµµ···ººº»»»»»»¸¸¸µµµÆÆÆÇÇÇÅÅż¼¼¿¿¿ÒÒÒØØØÇÇÇÕÕÕ×××ÙÙÙÜÜÜÜÜÜ×××ÐÐÐÊÊÊÎÎÎÍÍÍÍÍÍÎÎÎÐÐÐÒÒÒ×××ØØØÉÉÉÊÊÊÍÍÍÑÑѼ¼¼ÐÐÐÒÒÒÑÑÑÍÍÍÊÊÊÇÇÇÇÇÇÆÆÆÃÃÿ¿¿ÎÎÎÕÕÕÊÊÊÍÍÍÒÒÒÌÌÌÌÌÌÉÉÉÇÇÇÇÇÇÆÆÆÅÅÅ¿¿¿¾¾¾¼¼¼»»»¼¼¼ÂÂÂÌÌÌÑÑÑÒÒÒÑÑÑÑÑÑÀÀÀÂÂÂÅÅÅÅÅÅÅÅÅÃÃÃÅÅÅÆÆÆ¿¿¿ÆÆÆÅÅÅ¿¿¿¿¿¿ÇÇÇÐÐÐÔÔÔÉÉÉÎÎÎÊÊʼ¼¼±±±³³³¸¸¸»»»¤¤¤¥¥¥¸¸¸¿¿¿¿¿¿¿¿¿ÀÀÀ´´´ÀÀÀÅÅÅÆÆÆÊÊÊÆÆÆÃÃÃÊÊÊÒÒÒàààãããàààâââäääæææíííäääããããããããããããâââßßßÜÜÜÜÜÜäääÝÝÝÝÝÝàààãããèèèßßßàààçççñññïïïßßßÌÌÌÆÆÆÍÍÍÌÌÌÌÌÌÌÌÌÊÊÊÉÉÉÆÆÆÅÅÅÃÃÃÉÉÉÊÊÊÌÌÌÌÌÌÌÌÌÊÊÊÉÉÉÇÇÇÅÅÅÀÀÀ¾¾¾»»»ÃÃÃÝÝÝîîîçççíííñññøøøèèèàààçççäääíííóóóâââêêêæææàààèèèäääàààÝÝÝßßßÛÛÛãããÝÝÝÎÎÎÐÐÐÐÐÐÃÃÃÙÙÙßßßÙÙÙÙÙÙ×××ÎÎÎÊÊÊÊÊÊÔÔÔÔÔÔÆÆÆ¿¿¿ÅÅÅÉÉÉÅÅž¾¾»»»ººº¸¸¸······¸¸¸»»»±±±¸¸¸ÂÂÂÊÊÊÎÎÎÌÌÌÆÆƾ¾¾ÇÇÇÑÑÑÕÕÕÑÑÑÌÌÌÉÉÉÉÉɸ¸¸µµµµµµººº¾¾¾¿¿¿¿¿¿¿¿¿ººº¸¸¸¸¸¸ººº¾¾¾ÀÀÀ¿¿¿¾¾¾ÀÀÀ¸¸¸¸¸¸¿¿¿¿¿¿···±±±´´´´´´µµµµµµ³³³°°°³³³»»»ÂÂÂÃÃÃÇÇÇÌÌÌÃÃÃÂÂÂÉÉÉÌÌÌÎÎÎ×××ÒÒÒ×××ÛÛÛÑÑÑÎÎÎÕÕÕØØØàààÝÝÝÝÝÝÒÒÒÆÆÆÌÌÌØØØØØØÙÙÙÐÐÐÌÌÌÉÉÉÇÇÇÍÍÍÒÒÒÐÐÐÔÔÔÒÒÒÆÆÆÉÉÉÌÌÌÉÉÉÌÌÌÃÃÃÐÐÐØØØÝÝÝÔÔÔÉÉÉÐÐÐÒÒÒÉÉÉÇÇÇÉÉÉÉÉÉÅÅÅÀÀÀ¾¾¾¾¾¾¿¿¿¾¾¾ÂÂÂÍÍÍ×××ÐÐÐÀÀÀ¼¼¼ÃÃÃÅÅÅÅÅÅÅÅÅÃÃÃÂÂÂÀÀÀÀÀÀ¿¿¿¿¿¿¾¾¾¾¾¾¼¼¼¾¾¾¿¿¿ÂÂÂÂÂÂÐÐÐÒÒÒÎÎÎÉÉÉÅÅźºº´´´¼¼¼µµµ´´´©©©´´´Â¿¿¿ÀÀÀÀÀÀ¼¼¼¼¼¼ÐÐÐÃÃÃÂÂÂÍÍÍÀÀÀÆÆÆÍÍÍÔÔÔÛÛÛÝÝÝßßßâââçççíííóóóîîîçççâââßßßßßßààààààßßßßßßßßßÝÝÝÝÝÝßßßãããçççèèèçççíííîîîàààÌÌÌÇÇÇÑÑÑÎÎÎÌÌÌÇÇÇÅÅÅÅÅÅÆÆÆÅÅÅÂÂÂÇÇÇÊÊÊÉÉÉÃÃÃÂÂÂÅÅÅÅÅÅÀÀÀÃÃúººÇÇÇÅÅÅÝÝÝèèèêêêêêêñññëëëäääâââãããçççëëëîîîëëëçççíííëëëçççèèèäääâââÝÝÝßßßØØØÛÛÛØØØÎÎÎÐÐÐÊÊÊÌÌÌÜÜÜâââÝÝÝàààßßßÕÕÕÐÐÐÌÌÌÒÒÒÐÐÐÆÆÆÀÀÀÅÅÅÆÆÆÀÀÀ±±±´´´´´´±±±¯¯¯ªªª¦¦¦±±±···ÀÀÀÉÉÉÎÎÎÎÎÎÌÌÌÉÉÉÃÃÃÃÃÿ¿¿¾¾¾ÀÀÀÆÆÆÌÌÌÃÃÃÉÉÉÉÉÉÅÅÅÃÃÃÆÆÆÃÃü¼¼ÂÂÂÀÀÀÀÀÀÂÂÂÃÃÃÀÀÀ¼¼¼ºººÀÀÀ···´´´ººº»»»···¸¸¸¾¾¾žžžžžž¡¡¡©©©´´´¾¾¾ÀÀÀ¾¾¾ÃÃÃÇÇÇÇÇÇÇÇÇÎÎÎÔÔÔØØØãããÙÙÙÙÙÙÙÙÙÔÔÔÔÔÔÝÝÝâââÜÜÜÛÛÛÝÝÝÛÛÛÒÒÒ×××ÙÙÙÑÑÑÛÛÛØØØÙÙÙØØØÎÎÎÊÊÊÊÊÊÃÃû»»ÂÂÂÂÂÂÌÌÌÐÐÐÍÍÍÐÐÐÊÊÊÅÅÅÎÎÎÝÝÝÝÝÝÐÐÐÐÐÐÒÒÒÉÉÉÉÉÉÉÉÉÉÉÉÆÆÆ¿¿¿¿¿¿¿¿¿ÀÀÀÂÂÂÉÉÉÑÑÑÌÌÌÀÀÀ¿¿¿ÆÆÆÅÅÅÅÅÅÃÃÃÂÂÂÂÂÂÀÀÀ¿¿¿¿¿¿¾¾¾¾¾¾¼¼¼»»»¼¼¼¾¾¾¿¿¿ÀÀÀÀÀÀÇÇÇÊÊÊÍÍÍÌÌÌ¿¿¿µµµ¸¸¸»»»¸¸¸ªªª³³³ÂÂÂÀÀÀÂÂÂÀÀÀÅÅÅÀÀÀÐÐÐÆÆÆÃÃÃÊÊʾ¾¾ÅÅÅÃÃÃÑÑÑßßßàààÛÛÛØØØÝÝÝäääÙÙÙÝÝÝäääçççæææâââßßßÝÝÝßßßßßßßßßÝÝÝÝÝÝßßßãããæææîîîëëëíííîîîãããÑÑÑÇÇÇÆÆÆÒÒÒÌÌÌÆÆÆÅÅÅÀÀÀ¾¾¾ÃÃÃÌÌÌÅÅÅÇÇÇÆÆÆÂÂÂÂÂÂÅÅž¾¾ÇÇÇÃÃÃØØØÛÛÛçççãããäääëëëòòòîîîçççããããããäääæææçççãããîîîïïïïïïëëëÝÝÝØØØ×××ÝÝÝãããÛÛÛÛÛÛØØØÔÔÔÕÕÕÌÌÌÌÌÌ×××ÙÙÙ×××ÛÛÛÜÜÜÒÒÒÉÉÉÍÍÍÎÎÎÊÊÊÃÃÃÂÂÂÅÅÅÀÀÀººº···ÀÀÀÉÉÉÉÉÉÆÆÆÃÃø¸¸¬¬¬°°°µµµ¿¿¿ÇÇÇÎÎÎÐÐÐÑÑÑÐÐÐÐÐÐÎÎÎÌÌÌÇÇÇÅÅÅÃÃÃÂÂÂÃÃÃÂÂÂÌÌÌÌÌÌÀÀÀ»»»ÀÀÀ¾¾¾¾¾¾¾¾¾¿¿¿ÀÀÀ¿¿¿¼¼¼ººº±±±¬¬¬¬¬¬¦¦¦¥¥¥©©©¯¯¯¯¯¯³³³ºººÀÀÀÅÅž¾¾ÉÉÉÌÌÌÎÎÎÒÒÒÑÑÑÐÐÐÕÕÕÛÛÛÝÝÝÕÕÕÛÛÛÜÜÜÜÜÜØØØÜÜÜ×××ÜÜÜÛÛÛÝÝÝßßßÝÝÝßßßÝÝÝÔÔÔÕÕÕÙÙÙäääæææÛÛÛ×××ÙÙÙ×××ÍÍÍÌÌÌÂÂÂÊÊÊÒÒÒÒÒÒÑÑÑÇÇÇÆÆÆÆÆÆÙÙÙâââÔÔÔÒÒÒÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊÇÇÇÃÃÃÀÀÀÀÀÀÀÀÀÅÅÅÂÂÂÃÃÃÉÉÉÆÆÆÀÀÀÂÂÂÉÉÉÅÅÅÃÃÃÃÃÃÂÂÂÀÀÀ¿¿¿¿¿¿¾¾¾¼¼¼»»»ººººººººº»»»¼¼¼¾¾¾ºººÀÀÀÆÆÆÍÍÍÐÐеµµµµµÀÀÀ¼¼¼ªªª±±±ÀÀÀÂÂÂÅÅÅÃÃÃÉÉÉÂÂÂÍÍÍÇÇÇÆÆÆÇÇǼ¼¼ÅÅÅ¿¿¿ÌÌÌÙÙÙàààßßßÛÛÛÜÜÜàààßßßäääèèèêêêçççãããããããããàààààààààßßßÝÝÝßßßãããçççîîîíííííííííèèèÝÝÝÐÐÐÃÃÃÎÎÎÇÇÇÊÊÊÕÕÕÕÕÕÇÇÇÀÀÀÂÂÂÆÆÆÅÅÅÀÀÀ¾¾¾¿¿¿ÃÃÃÃÃÃÀÀÀ»»»ÂÂÂàààíííñññäääçççõõõîîîêêêæææããããããääääääãããßßßöööïïïëëëæææÌÌÌÂÂÂÃÃÃÐÐÐààààààÝÝÝØØØÕÕÕØØØÎÎÎ×××ÛÛÛÙÙÙÙÙÙÜÜÜÝÝÝÔÔÔÉÉÉÎÎÎÊÊÊÅÅÅÂÂÂÃÃü¼¼µµµ¯¯¯»»»ÃÃõµµ¥¥¥±±±¸¸¸ÂÂÂÊÊÊÐÐÐÒÒÒÒÒÒÒÒÒ××××××ØØØÙÙÙ×××ÐÐÐÇÇÇÀÀÀ¾¾¾ÂÂÂÀÀÀµµµ°°°···ÂÂÂÇÇǼ¼¼¾¾¾ÀÀÀÀÀÀ¾¾¾···°°°¬¬¬µµµ±±±³³³······°°°¯¯¯±±±µµµººº¼¼¼¼¼¼¼¼¼¾¾¾¿¿¿ÀÀÀÅÅÅÇÇÇÔÔÔÕÕÕÒÒÒÜÜÜââââââÕÕÕØØØÔÔÔØØØÕÕÕÝÝÝ×××ßßßÝÝÝÝÝÝßßßßßßâââãããâââÛÛÛÝÝÝäääâââÑÑÑÌÌÌÑÑÑÒÒÒÛÛÛÒÒÒÀÀÀÃÃÃÊÊÊÎÎÎÕÕÕÐÐÐÔÔÔÆÆÆÒÒÒßßßÕÕÕÔÔÔØØØÍÍÍÍÍÍÌÌÌÊÊÊÉÉÉÆÆÆÃÃÃÂÂÂÂÂÂÅÅÅÀÀÀ¿¿¿ÃÃÃÃÃÃÂÂÂÃÃÃÉÉÉÃÃÃÂÂÂÂÂÂÀÀÀ¿¿¿¾¾¾¾¾¾¾¾¾»»»ººº¸¸¸······¸¸¸ººº»»»¾¾¾ÃÃÃÆÆÆÌÌÌÎÎεµµµµµÀÀÀ¼¼¼©©©¾¾¾ÂÂÂÇÇÇÆÆÆÆÆƾ¾¾ÅÅÅÅÅÅÆÆÆÆÆÆ¿¿¿ÇÇÇÃÃÃÅÅÅÍÍÍÛÛÛäääæææææææææííííííëëëêêêèèèçççççççççãããããããããààààààâââäääèèèëëëîîîîîîííííííëëëßßßÒÒÒÊÊÊÇÇÇÎÎÎâââîîîæææÑÑÑÃÃÃÃÃÿ¿¿ººº···ººº¿¿¿ÀÀÀÀÀÀ³³³ÃÃÃßßßîîîïïïèèèíííøøøäääâââââââââäääçççççççççßßßøøøîîîçççàààÃÃ÷··ººº»»»×××àààÝÝÝÕÕÕÒÒÒÙÙÙÔÔÔÝÝÝÛÛÛÙÙÙØØØØØØ×××ÎÎÎÃÃÃÍÍÍÆÆÆ¿¿¿¸¸¸´´´···ÂÂÂÆÆÆÃÃÃÆÆÆÉÉÉÀÀÀ³³³´´´¼¼¼ÇÇÇÐÐÐÒÒÒÒÒÒÒÒÒÑÑÑÕÕÕÔÔÔÒÒÒÔÔÔ×××ÕÕÕÒÒÒÎÎÎÆÆÆÃÃÃÀÀÀ¾¾¾···µµµ¿¿¿ÍÍÍÆÆÆ¿¿¿µµµ¬¬¬°°°¸¸¸¿¿¿¿¿¿¾¾¾¿¿¿ÀÀÀ¿¿¿ººº···¸¸¸»»»ºººººº······¸¸¸¼¼¼¿¿¿¼¼¼ÃÃÃÂÂÂÐÐÐÒÒÒÌÌÌÙÙÙÝÝÝçççÛÛÛÝÝÝÒÒÒØØØÔÔÔàààÙÙÙÝÝÝàààââââââààààààæææîîîââââââæææàààÐÐÐÌÌÌÑÑÑÔÔÔÑÑÑÔÔÔÊÊÊÆÆÆ¿¿¿»»»ÇÇÇÌÌÌ×××ÌÌÌ×××àààÕÕÕÐÐÐÕÕÕÑÑÑÎÎÎÍÍÍÌÌÌÉÉÉÇÇÇÆÆÆÃÃÃÂÂÂÃÃÃÀÀÀ¿¿¿ÂÂÂÃÃÃÃÃÃÃÃÃÅÅÅÂÂÂÂÂÂÀÀÀ¿¿¿¾¾¾¾¾¾¼¼¼¼¼¼ººº¸¸¸···µµµ···¸¸¸ººº»»»ÀÀÀÆÆÆÉÉÉÍÍÍÐÐÐÃÃ÷·····¾¾¾»»»¨¨¨ªªª»»»ÂÂÂÇÇÇÆÆÆÅÅÅ»»»¾¾¾ÀÀÀÃÃÃÃÃÿ¿¿ÅÅÅÆÆÆÂÂÂÆÆÆÒÒÒÝÝÝâââçççëëëëëëèèèçççêêêîîîïïïêêêäääèèèèèèçççæææääääääèèèëëëëëëòòòóóóïïïîîîñññíííæææíííêêêææææææíííëëëÙÙÙÆÆÆÀÀÀ¿¿¿¾¾¾¿¿¿ÂÂÂÂÂÂÀÀÀ¿¿¿ÅÅÅ×××ãããêêêèèèëëëíííêêêÝÝÝÝÝÝßßßâââæææèèèèèèèèèàààóóóîîîæææàààÉÉɺºº¾¾¾¸¸¸ÔÔÔßßßÝÝÝÕÕÕÕÕÕâââàààÝÝÝØØØØØØÕÕÕÎÎÎÌÌÌÇÇÇ¿¿¿ÌÌÌÃÃÃÀÀÀÂÂÂÀÀÀººº···¸¸¸¼¼¼ÀÀÀÂÂÂÀÀÀÃÃÃÇÇÇÃÃúºº¸¸¸ÀÀÀÌÌÌÒÒÒÔÔÔÒÒÒÑÑÑÑÑÑÕÕÕÔÔÔÒÒÒÔÔÔ×××ØØØÕÕÕÔÔÔÎÎÎÉÉÉÉÉÉÌÌÌÃÃ÷··µµµ¿¿¿±±±µµµ»»»¿¿¿ÀÀÀÂÂÂÂÂÂÃÃÃÅÅÅ¿¿¿»»»µµµ±±±±±±´´´¾¾¾···³³³···ÅÅÅÐÐÐÕÕÕÕÕÕÍÍÍÕÕÕÐÐÐØØØ×××ÎÎÎÜÜÜÜÜÜãããØØØÜÜÜÊÊÊÎÎÎÉÉÉÙÙÙÒÒÒÙÙÙàààæææççççççãããæææñññÝÝÝÝÝÝãããäääÝÝÝßßßæææäääÐÐÐ×××ÒÒÒÒÒÒÌÌÌÀÀÀ¼¼¼ÊÊÊÎÎÎÜÜÜãããØØØÎÎÎÐÐÐÒÒÒÐÐÐÍÍÍÊÊÊÉÉÉÉÉÉÆÆÆÅÅÅÂÂÂÂÂÂÀÀÀÀÀÀÃÃÃÃÃÃÃÃÃÂÂÂÂÂÂÀÀÀÀÀÀ¿¿¿¾¾¾¾¾¾¼¼¼»»»»»»······µµµµµµ···¸¸¸»»»¼¼¼¿¿¿ÆÆÆÌÌÌÑÑÑÒÒÒÅÅÅ···¸¸¸»»»¼¼¼ªªª¬¬¬ºººÀÀÀÇÇÇÅÅÅÆÆÆ¿¿¿»»»¼¼¼ÀÀÀ¿¿¿¿¿¿ÃÃÃÂÂÂÅÅÅÌÌÌÍÍÍÎÎÎÙÙÙèèèöööïïïêêêëëëïïïòòòïïïíííîîîîîîíííëëëèèèêêêîîîñññòòòøøøøøøòòòïïïñññòòòïïïíííóóóòòòêêêêêêñññîîîäääæææääääääâââØØØÉÉɼ¼¼¸¸¸ÛÛÛêêêæææêêêèèèñññîîîâââàààßßßßßßâââäääææææææäääâââëëëîîîæææàààÑÑѾ¾¾ÀÀÀ¼¼¼ÎÎÎÑÑÑÑÑÑÎÎÎÑÑÑãããæææãããßßßàààÝÝÝÑÑÑÍÍÍÎÎÎÉÉÉÉÉÉ¿¿¿Â¾¾¾´´´µµµ¾¾¾ÂÂÂÂÂÂÂÂÂÃÃÃÇÇÇÇÇÇÃÃü¼¼¾¾¾ÅÅÅÎÎÎÒÒÒÒÒÒÑÑÑÒÒÒÔÔÔÔÔÔÕÕÕØØØÙÙÙÛÛÛØØØÕÕÕÑÑÑÐÐÐÌÌÌÍÍÍÐÐÐÊÊÊ¿¿¿¸¸¸¸¸¸¿¿¿ÃÃÃÉÉÉÊÊÊÇÇÇÃÃÃÀÀÀ¿¿¿Â¾¾¾»»»»»»¾¾¾ÀÀÀÃÃü¼¼···»»»ÆÆÆÐÐÐÑÑÑÐÐÐÒÒÒàààØØØßßßßßßÛÛÛíííçççêêêÙÙÙÔÔÔ±±±³³³´´´ÕÕÕÛÛÛÛÛÛàààâââæææëëëçççæææïïïäääÜÜÜÜÜÜÝÝÝÛÛÛßßßàààÛÛÛÕÕÕÒÒÒÉÉÉÐÐÐ×××ÔÔÔÑÑÑÅÅÅÀÀÀÊÊÊÒÒÒÙÙÙÝÝÝØØØÐÐÐÑÑÑÐÐÐÍÍÍÊÊÊÉÉÉÉÉÉÇÇÇÅÅÅÂÂÂÂÂÂÃÃÃÃÃÃÃÃÃÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀ¿¿¿¿¿¿¾¾¾¼¼¼»»»»»»ººº···µµµµµµµµµ¸¸¸ººº¼¼¼¾¾¾ÆÆÆÌÌÌÎÎÎÐÐÐÍÍÍ¿¿¿´´´¸¸¸»»»ÀÀÀ±±±±±±»»»¿¿¿ÅÅÅÂÂÂÅÅÅÀÀÀºººººº¿¿¿ÅÅÅÅÅž¾¾Â¿¿¿ÂÂÂÇÇÇÆÆÆÃÃÃÎÎÎÝÝÝöööóóóñññïïïïïïòòòõõõøøøóóóóóóòòòïïïîîîïïïòòòõõõùùùøøøöööóóóòòòòòòóóóòòòîîîóóóõõõïïïíííîîîîîîêêêçççèèèíííîîîèèèàààÜÜÜßßßçççñññæææïïïëëëñññíííàààâââààààààâââäääæææäääããããããæææîîîæææßßßÔÔÔ¼¼¼¾¾¾ºººÀÀÀ»»»»»»¾¾¾ÆÆÆÙÙÙÝÝÝßßßÜÜÜßßßÜÜÜÍÍÍÉÉÉÍÍÍÊÊÊÇÇÇÀÀÀÀÀÀ¼¼¼±±±µµµÀÀÀ¿¿¿¼¼¼¼¼¼ÂÂÂÅÅÅ»»»µµµÀÀÀÇÇÇÎÎÎÒÒÒÑÑÑÑÑÑÔÔÔ×××ÍÍÍÍÍÍÐÐÐÑÑÑÔÔÔ××××××ØØØÐÐÐÐÐÐÎÎÎÎÎÎÐÐÐÎÎÎÇÇÇÂÂÂÇÇÇÊÊÊÊÊÊÉÉÉÅÅÅÃÃÃÃÃÃÅÅÅÇÇÇÊÊÊÊÊÊÇÇǾ¾¾»»»ººº¸¸¸ººº¼¼¼ÂÂÂÉÉÉÐÐÐÕÕÕØØØØØØçççÛÛÛÜÜÜÙÙÙÕÕÕæææÜÜÜëëëÜÜÜØØر±±°°°°°°×××ÝÝÝââââââÜÜÜàààëëëèèèçççñññòòòãããÛÛÛÙÙÙÛÛÛàààâââÙÙÙâââÛÛÛÇÇÇÆÆÆÉÉÉÉÉÉÎÎÎÉÉÉÂÂÂÅÅÅÀÀÀÊÊÊâââäääÔÔÔÍÍÍÐÐÐÍÍÍÊÊÊÉÉÉÉÉÉÇÇÇÅÅÅÂÂÂÃÃÃÅÅÅÅÅÅÃÃÃÂÂÂÀÀÀ¿¿¿¿¿¿¾¾¾¾¾¾¼¼¼»»»ººººººµµµµµµµµµ···¸¸¸»»»¾¾¾ÀÀÀÒÒÒÔÔÔÐÐÐÉÉÉÃÃ÷··±±±¸¸¸¼¼¼ÅÅŸ¸¸µµµ¼¼¼¾¾¾ÃÃÃÀÀÀÀÀÀ¿¿¿¸¸¸¸¸¸ÀÀÀÊÊÊÌÌÌÃÃÃÃÃü¼¼¼¼¼ÆÆÆÉÉÉÇÇÇÌÌÌÕÕÕÙÙÙãããïïïõõõõõõóóóõõõùùùøøøøøøöööóóóñññòòòõõõøøøùùùõõõñññòòòõõõöööóóóòòòöööñññëëëëëëëëëíííííííííèèèææææææäääàààÜÜÜâââëëëîîîóóóæææõõõíííêêêâââÙÙÙâââààààààâââäääææææææäääâââêêêæææèèèßßßÇÇÇÀÀÀ···¾¾¾ÀÀÀÅÅÅÃÃÃÀÀÀ¿¿¿ÂÂÂÆÆÆÝÝÝßßß×××ÑÑÑÒÒÒÍÍÍÉÉÉÐÐп¿¿Â¾¾¾······¼¼¼ÀÀÀ¿¿¿¾¾¾¿¿¿»»»ÆÆÆÅÅÅÍÍÍÀÀÀ»»»¼¼¼ÀÀÀÉÉÉÐÐÐÕÕÕ×××ÕÕÕÔÔÔÐÐÐÑÑÑÔÔÔ×××ØØØØØØ×××ÕÕÕÕÕÕÐÐÐÍÍÍÎÎÎÔÔÔ×××ÒÒÒÍÍÍÎÎÎÍÍÍÊÊÊÇÇÇÆÆÆÅÅÅÆÆÆÆÆÆÇÇÇÆÆÆÃÃÃÃÃÃÃÃÃÃÃÃÀÀÀ¾¾¾»»»¸¸¸ÅÅÅÕÕÕ××××××ÙÙÙØØØàààäääÝÝÝäää×××ÔÔÔíííÝÝÝçççààà×××ÀÀÀ¬¬¬³³³ÒÒÒçççÜÜÜæææäääãããèèèæææäääíííãããîîîíííßßßÙÙÙÝÝÝßßßÜÜÜØØØÛÛÛÜÜÜÙÙÙÔÔÔÍÍÍÉÉÉÇÇÇÇÇÇÉÉÉÅÅÅÐÐÐÒÒÒêêêãããÒÒÒÑÑÑÎÎÎÍÍÍÌÌÌÊÊÊÇÇÇÇÇÇÉÉÉÅÅÅÃÃÃÂÂÂÂÂÂÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ¿¿¿¼¼¼»»»ºººººº¸¸¸¸¸¸ººº¸¸¸¸¸¸µµµµµµ»»»ÅÅÅÍÍÍÌÌÌÌÌÌÍÍÍÊÊÊÀÀÀµµµ³³³µµµ¸¸¸¿¿¿¸¸¸±±±ºººÀÀÀ¾¾¾¼¼¼¼¼¼¼¼¼»»»³³³¯¯¯¿¿¿ÉÉÉ¿¿¿ÀÀÀÃÃÃÆÆÆÆÆÆÇÇÇÇÇÇÊÊÊÌÌÌÕÕÕ×××ÝÝÝêêêöööúúúõõõîîîîîîøøøüüüõõõîîîïïïöööúúúòòòòòòòòòòòòóóóõõõööööööóóóòòòïïïîîîíííííííííîîîãããâââãããæææäääßßßâââçççîîîïïïñññîîîèèèãããßßßßßßààà×××ÛÛÛãããâââãããæææâââíííîîîãããÝÝÝÌÌ̵µµµµµ±±±¾¾¾ÀÀÀÃÃÃÆÆÆÉÉÉÉÉÉÆÆÆÅÅÅÕÕÕÙÙÙÕÕÕÔÔÔØØØÒÒÒÌÌÌÎÎÎÃÃÃÃÃþ¾¾¸¸¸¸¸¸¾¾¾ÀÀÀ¾¾¾ÀÀÀ¿¿¿ÇÇÇÃÃÃÇÇǼ¼¼¸¸¸¾¾¾ÂÂÂÊÊÊÑÑÑ×××ØØØØØØ×××××××××ÕÕÕ××××××ÕÕÕÔÔÔÒÒÒÔÔÔÕÕÕ××××××ÕÕÕÔÔÔÔÔÔÔÔÔÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÊÊÊÉÉÉÆÆÆÅÅÅÆÆÆÆÆÆÅÅÅÃÃÃÂÂÂÂÂÂÃÃÃÀÀÀ¿¿¿ÇÇÇÎÎÎÌÌÌÑÑÑÜÜÜààààààäääÝÝÝâââÕÕÕ×××íííÜÜÜîîîèèèãããÒÒÒ¿¿¿ÀÀÀÕÕÕâââàààâââØØØÑÑÑÜÜÜëëëñññïïïññññññïïïíííæææÜÜÜ×××ÕÕÕÕÕÕØØØÛÛÛÛÛÛØØØÒÒÒÌÌÌÉÉÉÑÑÑÇÇÇÂÂÂÑÑÑÌÌÌØØØØØØÛÛÛâââÝÝÝÕÕÕÌÌÌÉÉÉÊÊÊÉÉÉÅÅÅ¿¿¿¿¿¿¼¼¼»»»ºººººº¸¸¸¸¸¸···¸¸¸ººº»»»¼¼¼ÂÂÂÊÊÊÒÒÒÍÍÍÎÎÎÎÎÎÊÊÊ¿¿¿µµµºººÂ¸¸¸³³³¼¼¼Â¿¿¿Â¿¿¿···´´´³³³¸¸¸ÆÆÆÉÉÉ»»»ÀÀÀÃÃÃÆÆÆÇÇÇÆÆÆÇÇÇÉÉÉÊÊÊÍÍÍÐÐÐ×××ßßßçççïïïõõõøøøïïïöööøøøóóóïïïñññóóóóóóïïïïïïïïïïïïñññóóóõõõöööóóóòòòïïïíííëëëëëëíííîîîèèèææææææçççæææãããæææëëëöööóóóîîîçççãããààààààâââãããÛÛÛßßßæææãããããããããàààëëëãããÒÒÒÉÉɸ¸¸¬¬¬´´´ººº¿¿¿¿¿¿ÃÃÃÊÊÊÑÑÑÑÑÑÊÊÊÅÅÅÇÇÇÍÍÍÎÎÎÐÐÐ×××ÕÕÕÍÍÍÊÊÊÅÅÅÃÃþ¾¾»»»»»»¿¿¿¾¾¾»»»¿¿¿ÂÂÂÀÀÀÇÇǺºººººÀÀÀÆÆÆÍÍÍÒÒÒ×××ÙÙÙÙÙÙÙÙÙÙÙÙ×××ÕÕÕÔÔÔÕÕÕÕÕÕÔÔÔÑÑÑÕÕÕÕÕÕÕÕÕÔÔÔÑÑÑÑÑÑÔÔÔ×××ÐÐÐÐÐÐÐÐÐÎÎÎÌÌÌÊÊÊÉÉÉÇÇÇÅÅÅÆÆÆÉÉÉÊÊÊÉÉÉÆÆÆÂÂÂÀÀÀ¿¿¿ÉÉÉØØØÝÝÝ×××ÙÙÙààààààßßßäääÝÝÝÝÝÝÕÕÕÛÛÛíííÛÛÛêêêçççèèèããã××××××ßßßâââçççÒÒÒ¾¾¾···ÂÂÂØØØæææãããäääçççïïïóóóíííäääßßßÝÝÝÕÕÕÔÔÔÕÕÕØØØÛÛÛØØØÒÒÒÌÌÌÃÃÃÅÅÅÆÆÆÑÑÑÅÅÅÌÌÌÊÊÊÊÊÊÝÝÝàààÜÜÜÑÑÑÌÌÌÌÌÌÊÊÊÃÃÃÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÃÃÿ¿¿¾¾¾¼¼¼»»»ººººººººººººµµµººº¼¼¼¼¼¼¾¾¾ÃÃÃÌÌÌÑÑÑÌÌÌÉÉÉÅÅż¼¼±±±¬¬¬µµµÃÃû»»³³³µµµ¾¾¾¾¾¾»»»¾¾¾¼¼¼³³³±±±¸¸¸ÀÀÀÉÉÉÇÇǾ¾¾ÀÀÀÃÃÃÆÆÆÇÇÇÆÆÆÆÆÆÆÆÆÇÇÇÇÇÇÌÌÌÐÐÐÑÑÑÔÔÔÝÝÝíííùùùïïïóóóõõõñññïïïïïïîîîëëëëëëëëëëëëíííîîîñññòòòóóóõõõòòòîîîëëëêêêêêêíííîîîîîîëëëêêêêêêèèèçççêêêîîîóóóïïïêêêæææããããããããããããçççàààãããèèèçççãããâââßßßäääÐÐп¿¿ººº±±±°°°ººº¿¿¿¾¾¾ÀÀÀÆÆÆÍÍÍÑÑÑÐÐÐÊÊÊÅÅž¾¾ÀÀÀÂÂÂÅÅÅÍÍÍÑÑÑÍÍÍÆÆÆ¿¿¿¼¼¼¼¼¼¿¿¿ÀÀÀ»»»µµµººº¼¼¼ÂÂÂÇÇǾ¾¾»»»¾¾¾ÆÆÆÊÊÊÐÐÐÕÕÕØØØØØØØØØÙÙÙÔÔÔÑÑÑÐÐÐÑÑÑÔÔÔÕÕÕÔÔÔÑÑÑÐÐÐÐÐÐÑÑÑ×××ÜÜÜÛÛÛÔÔÔÍÍÍÒÒÒÐÐÐÌÌÌÉÉÉÉÉÉÌÌÌÐÐÐÒÒÒÑÑÑÍÍÍÉÉÉÇÇÇÇÇÇÆÆÆ¿¿¿¾¾¾ÊÊÊÝÝÝãããÝÝÝßßßàààØØØÝÝÝãããÝÝÝÙÙÙÕÕÕÝÝÝëëëÛÛÛæææãããèèèêêêââââââäääàààÜÜÜ¿¿¿µµµÀÀÀÅÅÅÆÆÆÇÇÇÃÃÃÇÇÇØØØêêêîîîèèèëëëîîîçççÙÙÙÔÔÔÐÐÐÑÑÑØØØÛÛÛ×××ÒÒÒÌÌÌÌÌÌÇÇÇÌÌ̾¾¾ÇÇÇÊÊÊÍÍÍÅÅÅÎÎÎ×××ØØØÔÔÔÍÍÍÉÉÉÇÇÇÊÊÊÊÊÊÊÊÊÉÉÉÆÆÆÃÃÃÂÂÂÀÀÀ¿¿¿¾¾¾¼¼¼»»»ºººººººººººº¸¸¸¼¼¼¼¼¼ººº»»»ÀÀÀÆÆÆÉÉÉÊÊÊ···¯¯¯¦¦¦¦¦¦±±±¿¿¿¿¿¿´´´°°°ºººÃÃÿ¿¿¸¸¸ºººµµµ±±±µµµ¿¿¿ÅÅÅÅÅÅÃÃÃÅÅÅÀÀÀÃÃÃÆÆÆÇÇÇÆÆÆÅÅÅÅÅÅÆÆÆÇÇÇÊÊÊÊÊÊÉÉÉÇÇÇÎÎÎÜÜÜèèèëëëïïïòòòñññíííêêêççççççççççççèèèêêêëëëîîîñññòòòõõõòòòíííêêêèèèêêêíííîîîñññïïïííííííëëëêêêëëëíííæææææææææèèèêêêêêêæææâââçççãããæææêêêèèèäääââââââæææÆÆÆ···µµµ³³³´´´······¼¼¼ÂÂÂÉÉÉÍÍÍÌÌÌÉÉÉÇÇÇÇÇǼ¼¼¼¼¼»»»»»»ÂÂÂÌÌÌÎÎÎÉÉɼ¼¼ººº»»»¿¿¿Â¿¿¿¸¸¸³³³¸¸¸»»»ÃÃÃÆÆÆÃÃø¸¸ººº¾¾¾ÇÇÇÍÍÍÔÔÔ××××××ÕÕÕÕÕÕÕÕÕÎÎÎÍÍÍÍÍÍÐÐÐÑÑÑÒÒÒÑÑÑÎÎÎÊÊÊÑÑÑßßßëëëïïïèèèÛÛÛÐÐÐÑÑÑÐÐÐÎÎÎÎÎÎÑÑÑ×××ÜÜÜàààßßßÙÙÙÐÐÐÆÆÆ¿¿¿¿¿¿ÃÃÃÇÇÇÆÆÆÇÇÇÎÎÎÎÎÎÍÍÍ×××ÜÜÜ×××ÜÜÜàààÜÜÜØØØÕÕÕÝÝÝçççÜÜÜëëëçççêêêëëëäääãããäääÝÝÝÛÛÛÃÃþ¾¾ÇÇÇÇÇÇÆÆÆÉÉÉÇÇÇÂÂÂÉÉÉÙÙÙãããæææíííîîîãããâââØØØÎÎÎÌÌÌÒÒÒØØØÛÛÛÙÙÙÜÜÜÎÎÎÆÆÆ×××ÊÊÊÌÌÌÌÌÌÔÔÔÀÀÀÂÂÂÌÌÌ×××ÙÙÙÒÒÒÊÊÊÇÇÇÉÉÉÉÉÉÇÇÇÆÆÆÃÃÃÂÂÂÀÀÀ¿¿¿¾¾¾¼¼¼¼¼¼»»»ºººººº»»»»»»¼¼¼¾¾¾¼¼¼¸¸¸»»»ÃÃÃÆÆÆÅÅÅÉÉÉ»»»¨¨¨©©©···ÀÀÀ¿¿¿°°°ºººÂ¾¾¾»»»¾¾¾´´´±±±´´´¿¿¿ÆÆÆÃÃÃÂÂÂÆÆÆÀÀÀÃÃÃÆÆÆÆÆÆÆÆÆÅÅÅÅÅÅÆÆÆÉÉÉÉÉÉÇÇÇÆÆÆÆÆÆÉÉÉÐÐÐÔÔÔæææëëëññññññêêêäääãããçççääääääæææçççèèèëëëîîîïïïóóóñññíííêêêèèèêêêíííïïïïïïïïïïïïîîîîîîíííêêêçççàààâââäääèèèëëëèèèäääßßßããããããäääèèèêêêäääãããæææããã¾¾¾´´´······»»»¸¸¸´´´»»»ÂÂÂÉÉÉÌÌÌÉÉÉÆÆÆÆÆÆÉÉÉÃÃÃÀÀÀ¾¾¾ººº¼¼¼ÊÊÊÑÑÑÌÌ̼¼¼»»»¼¼¼ÀÀÀ¼¼¼···³³³¼¼¼¼¼¼ÅÅÅÅÅÅÃÃó³³´´´ºººÅÅÅÌÌÌÔÔÔØØØ×××ÔÔÔÑÑÑÑÑÑÍÍÍÎÎÎÍÍÍÍÍÍÍÍÍÌÌÌÍÍÍÍÍÍØØØâââíííñññïïïëëëêêêêêêÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÛÛÛÛÛÛØØØßßßàààØØØÊÊÊÂÂÂÃÃÃÉÉÉÎÎÎÉÉÉÇÇÇÆÆÆÆÆÆÒÒÒÝÝÝÜÜÜÜÜÜÝÝÝÜÜÜØØØ×××ÜÜÜâââàààêêêæææêêêëëëæææçççêêêæææÂÂÂÃÃÃÉÉÉÎÎÎÑÑÑÕÕÕÒÒÒÊÊÊÉÉɺººÅÅÅßßßêêêîîîíííâââèèèàààÕÕÕÐÐÐÒÒÒ×××ÛÛÛÜÜÜÕÕÕÎÎÎÊÊÊ×××ÍÍÍÑÑÑÊÊÊÆÆÆÑÑÑÇÇÇÃÃÃÍÍÍØØØØØØÐÐÐÆÆÆÆÆÆÅÅÅÃÃÃÀÀÀ¿¿¿¿¿¿¿¿¿¿¿¿¾¾¾¼¼¼»»»»»»ººº»»»»»»»»»¿¿¿¿¿¿¼¼¼ºººÀÀÀÌÌÌÊÊÊÃÃúºº¯¯¯¥¥¥¥¥¥ªªª±±±¸¸¸ÀÀÀ¼¼¼¬¬¬¦¦¦°°°´´´µµµ¸¸¸»»»ººº´´´°°°¸¸¸ÅÅÅÅÅÅÀÀÀÃÃÃÂÂÂÃÃÃÆÆÆÆÆÆÅÅÅÅÅÅÇÇÇÉÉÉÇÇÇÆÆÆÆÆÆÆÆÆÇÇÇÉÉÉÊÊÊÊÊÊãããçççëëëîîîêêêããããããçççäääääääääæææèèèêêêííííííñññïïïíííêêêêêêíííïïïñññïïïññññññïïïîîîîîîèèèãããææææææäääããããããâââßßßÝÝÝàààââââââäääçççãããâââèèèÛÛÛ···µµµ»»»¸¸¸¼¼¼»»»¼¼¼ººº¿¿¿ÅÅÅÊÊÊÌÌÌÊÊÊÉÉÉÇÇÇÃÃÃÃÃü¼¼ºººÆÆÆÎÎÎÆÆÆÅÅÅÀÀÀÀÀÀÂÂÂÀÀÀºººµµµµµµ¾¾¾»»»ÅÅÅÃÃÃÃÃñ±±´´´¸¸¸¿¿¿ÇÇÇÑÑÑ×××ÕÕÕÒÒÒÑÑÑÐÐÐÍÍÍÎÎÎÍÍÍÊÊÊÇÇÇÉÉÉÎÎÎÔÔÔæææèèèèèèæææâââãããíííóóóèèèçççæææãããßßßÙÙÙÕÕÕÒÒÒ×××ÝÝÝäääæææßßßÕÕÕÍÍÍÉÉÉÎÎÎÉÉÉÌÌÌÐÐÐÌÌÌÑÑÑÝÝÝâââÜÜÜÛÛÛÛÛÛÙÙÙØØØÙÙÙÝÝÝäääßßßßßßçççëëëæææçççíííëëë¾¾¾ÆÆÆÆÆÆÃÃÃÍÍÍÕÕÕÕÕÕÐÐÐÉÉɺººÇÇÇãããëëëîîîñññçççíííèèèãããÜÜÜØØØØØØØØØÙÙÙØØØÙÙÙÑÑÑÎÎÎÀÀÀÑÑÑÎÎÎÆÆÆÎÎÎÎÎÎÇÇÇÂÂÂÌÌÌÙÙÙØØØÍÍÍÐÐÐÍÍÍÉÉÉÅÅÅÀÀÀÀÀÀÀÀÀÀÀÀ¼¼¼¼¼¼»»»»»»»»»»»»»»»¼¼¼¿¿¿¿¿¿¼¼¼¼¼¼ÆÆÆÎÎÎÇÇǸ¸¸¬¬¬©©©¨¨¨ªªª¬¬¬´´´¼¼¼»»»ªªª±±±±±±³³³···µµµ¼¼¼»»»³³³´´´¾¾¾ÀÀÀ¿¿¿ÅÅÅÃÃÃÅÅÅÅÅÅÅÅÅÅÅÅÆÆÆÊÊÊÍÍÍÊÊÊÌÌÌÌÌÌÊÊÊÇÇÇÆÆÆÇÇÇÉÉÉäääââââââèèèëëëèèèääääääææææææææææææçççêêêëëëëëëîîîííííííëëëíííïïïñññóóóòòòóóóòòòîîîîîîïïïêêêãããçççæææãããßßßÜÜÜÜÜÜÜÜÜßßßßßßâââààààààäääàààßßßèèèÛÛÛ···ººº¼¼¼´´´···¸¸¸¾¾¾»»»¼¼¼ÀÀÀÉÉÉÐÐÐÐÐÐÌÌÌÆÆÆÀÀÀÀÀÀÃÃþ¾¾¸¸¸ÂÂÂÉÉɾ¾¾ÍÍÍÇÇÇÃÃþ¾¾···µµµ¸¸¸ºººµµµÂÂÂÂÂÂÅÅų³³···»»»ºººÃÃÃÐÐÐ×××ÕÕÕÒÒÒÑÑÑÐÐÐÌÌÌÌÌÌÌÌÌÇÇÇÆÆÆÊÊÊÕÕÕÝÝÝâââßßßÝÝÝÜÜÜÝÝÝßßßààààààæææãããàààÜÜÜÙÙÙØØØØØØØØØæææßßßÙÙÙÝÝÝäääæææÜÜÜÑÑÑÌÌÌÆÆÆÌÌÌÎÎÎÆÆÆÉÉÉÙÙÙæææÜÜÜØØØÛÛÛÛÛÛÙÙÙ×××ÛÛÛèèèÜÜÜßßßèèèëëëâââàààãããâââÃÃÃÊÊÊÇÇÇÌÌÌØØØÕÕÕÊÊÊÊÊÊÆÆÆÇÇÇÜÜÜêêêäääêêêòòòèèèîîîîîîíííçççßßßÙÙÙ××××××ÝÝÝßßßÝÝÝâââÐÐÐÔÔÔÎÎÎÌÌ̺ººÌÌÌÍÍ;¾¾ÀÀÀ×××ààà×××ßßßÛÛÛÔÔÔÌÌÌÆÆƼ¼¼¼¼¼»»»»»»»»»»»»»»»¼¼¼¿¿¿¿¿¿¼¼¼¼¼¼ÅÅÅÌÌÌ¿¿¿ªªª¯¯¯±±±···¸¸¸³³³¯¯¯´´´¾¾¾¿¿¿···¼¼¼ÃÃÃÀÀÀ¾¾¾¼¼¼µµµ¸¸¸¿¿¿»»»´´´···¸¸¸¾¾¾ÊÊÊÅÅÅÅÅÅÅÅÅÃÃÃÃÃÃÆÆÆÌÌÌÐÐÐÎÎÎÑÑÑÑÑÑÌÌÌÅÅÅÀÀÀÅÅÅÊÊÊçççÝÝÝÛÛÛäääîîîîîîçççãããççççççæææççççççèèèêêêëëëííííííííííííîîîñññòòòóóóõõõöööòòòííííííïïïíííæææâââââââââàààÜÜÜÛÛÛÜÜÜßßßßßßâââßßßÝÝÝâââÜÜÜÜÜÜèè謬¬¾¾¾¿¿¿ººº»»»»»»···ººººººÃÃÃÊÊÊÌÌÌÌÌÌÌÌÌÉÉÉÃÃÃÆÆÆÅÅÅÇÇÇÂÂÂÀÀÀ¼¼¼µµµÃÃÃÎÎÎÍÍÍÇÇǾ¾¾ººº»»»¸¸¸³³³³³³µµµÂÂÂÆÆƼ¼¼¸¸¸¸¸¸³³³¸¸¸ÂÂÂÎÎÎÔÔÔÒÒÒÎÎÎÍÍÍÌÌÌÇÇÇÐÐÐÍÍÍÀÀÀÀÀÀÐÐÐÝÝÝàààØØØÙÙÙÛÛÛÛÛÛÙÙÙÙÙÙÜÜÜßßßÜÜÜâââæææäääßßßÙÙÙ×××ØØØÜÜÜÝÝÝÜÜÜÙÙÙÙÙÙÝÝÝçççîîîÎÎÎÍÍÍÌÌÌÌÌÌÌÌÌÎÎÎÑÑÑÒÒÒÐÐÐÎÎÎÙÙÙÝÝÝÝÝÝÛÛÛÒÒÒØØØâââèèèæææçççãããÝÝÝæææäääÂÂÂÆÆÆÊÊÊÐÐÐÑÑÑÑÑÑÐÐÐÍÍÍÇÇÇ¿¿¿ççççççïïïóóóêêêîîîñññèèèàààÜÜÜÜÜÜÜÜÜÛÛÛ×××ÙÙÙ×××ÝÝÝäääÛÛÛÊÊÊÉÉÉÔÔÔÒÒÒÀÀÀÎÎÎÊÊʺºº¿¿¿ÊÊÊ××××××ØØØÙÙÙÕÕÕÉÉÉ¿¿¿ÅÅÅÐÐÐÐÐÐÀÀÀµµµ···ºººººº»»»¿¿¿ÅÅÅ¿¿¿ÊÊÊÊÊÊÅÅż¼¼©©©ªªª¸¸¸···¸¸¸ººº¾¾¾¾¾¾ºººµµµ¸¸¸¼¼¼ÀÀÀÀÀÀ¼¼¼»»»¾¾¾ÀÀÀªªªÀÀÀ¾¾¾´´´»»»¸¸¸´´´¿¿¿¼¼¼¸¸¸ÀÀÀÎÎÎÑÑÑÉÉÉÉÉÉÑÑÑÊÊÊÐÐÐÑÑÑÊÊÊÃÃÃÅÅÅÆÆÆÅÅÅÇÇÇÆÆÆ×××æææäääæææëëëêêêèèèççççççæææææææææææææææççççççæææçççëëëñññöööúúúõõõöööøøøöööóóóñññòòòòòòâââäääÝÝÝßßßîîîñññíííïïïïïïîîîëëëêêêíííïïïæææÙÙÙººº···»»»¿¿¿¾¾¾ºººººº»»»¼¼¼ÅÅÅÌÌÌÊÊÊÊÊÊÊÊÊÇÇÇÃÃÃÅÅÅÂÂÂÅÅÅÀÀÀ¿¿¿µµµÂÂÂÂÂÂÆÆÆÆÆÆ¿¿¿ººº···´´´¯¯¯¸¸¸···¿¿¿ÅÅÅÃÃÃÆÆÆÆÆƼ¼¼µµµ¿¿¿ÊÊÊÑÑÑÑÑÑÎÎÎÌÌÌÌÌÌÉÉÉÉÉÉÆÆÆÅÅÅÍÍÍÙÙÙÛÛÛÕÕÕÙÙÙÛÛÛÝÝÝÜÜÜÙÙÙÙÙÙÛÛÛÝÝÝàààãããæææãããÝÝÝÙÙÙÙÙÙÜÜÜÙÙÙÙÙÙØØØÔÔÔÒÒÒØØØàààèèèÌÌÌÍÍÍÎÎÎÑÑÑÑÑÑÐÐÐÍÍÍÌÌÌÐÐÐÊÊÊÒÒÒ×××ÙÙÙÙÙÙÐÐÐÔÔÔØØØããããããçççëëëëëëëëëÜÜÜÀÀÀÃÃÃÉÉÉÍÍÍÐÐÐÎÎÎÍÍÍÌÌÌÃÃÃÃÃÃæææçççñññòòòîîîêêêäääàààÜÜÜÛÛÛÜÜÜÝÝÝÝÝÝÛÛÛ×××ØØØÙÙÙÜÜÜÛÛÛØØØÕÕÕÕÕÕÔÔÔÀÀÀÐÐÐÒÒÒ¾¾¾ºººÅÅÅ×××ÔÔÔÕÕÕØØØØØØÒÒÒÎÎÎÐÐÐÒÒÒÊÊÊÇÇÇÃÃþ¾¾¸¸¸¸¸¸¾¾¾ÃÃÃÐÐÐÅÅÅÅÅż¼¼´´´±±±©©©±±±¸¸¸ººº»»»»»»ººº¸¸¸¸¸¸¸¸¸³³³µµµ······µµµµµµººº¼¼¼ªªªººº¼¼¼»»»¿¿¿¼¼¼ºººÀÀÀÐÐÐÅÅž¾¾ÆÆÆÑÑÑÒÒÒÊÊÊÂÂÂÍÍÍÑÑÑÐÐÐÉÉÉÃÃÃÃÃÃÃÃÃÂÂÂÅÅÅÃÃÃÌÌÌ×××ÜÜÜàààçççëëëêêêèèèçççæææääääääääääääææææææçççèèèëëëïïïòòòõõõòòòóóóõõõõõõòòòòòòòòòóóóçççãããÜÜÜÝÝÝçççëëëèèèçççëëëíííêêêèèèêêêëëëãããÙÙÙÌÌ̵µµµµµÂ¿¿¿ººº¾¾¾¾¾¾ÂÂÂÇÇÇÊÊÊÊÊÊÉÉÉÉÉÉÇÇÇÅÅÅÆÆÆÂÂÂÃÃÃÀÀÀÃÃÿ¿¿³³³ººº¸¸¸ÂÂÂÇÇÇÃÃû»»µµµ±±±°°°³³³¸¸¸ÂÂÂÅÅÅÂÂÂÉÉÉÎÎÎÊÊÊ´´´¼¼¼ÇÇÇÍÍÍÎÎÎÌÌÌÊÊÊÊÊÊÆÆÆÅÅÅÆÆÆÍÍÍØØØÜÜÜ×××ÐÐÐÙÙÙÜÜÜàààßßßÛÛÛÙÙÙÛÛÛßßßãããääääääâââÜÜÜÛÛÛÝÝÝàààÛÛÛÛÛÛØØØÔÔÔÑÑÑÔÔÔÝÝÝäääÎÎÎÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÊÊÊÑÑÑÔÔÔÙÙÙÛÛÛÑÑÑÔÔÔÙÙÙèèèäääãããèèèëëëÝÝÝ»»»¾¾¾ÀÀÀÅÅÅÉÉÉÌÌÌÌÌÌÊÊÊÉÉÉÅÅÅÎÎÎèèèêêêòòòòòòõõõæææßßßÝÝÝÝÝÝßßßßßßßßßÝÝÝÝÝÝ×××ÛÛÛÙÙÙÕÕÕÛÛÛäääàààÒÒÒØØØÀÀÀÌÌÌÕÕÕÇÇǼ¼¼¿¿¿ÍÍÍÔÔÔÔÔÔÒÒÒÑÑÑÑÑÑÐÐÐÌÌÌÇÇÇÍÍÍÑÑÑÌÌ̼¼¼···¿¿¿ÇÇÇÊÊÊÎÎÎÃÃü¼¼¯¯¯¨¨¨©©©¬¬¬···µµµ······ººº»»»ººº···´´´³³³´´´´´´µµµ···¸¸¸¼¼¼¾¾¾¸¸¸»»»¾¾¾ÀÀÀ¿¿¿ÂÂÂÆÆÆÆÆÆÇÇÇÆÆÆÆÆÆÊÊÊÒÒÒÒÒÒÎÎÎÇÇÇÊÊÊÊÊÊÇÇÇÆÆÆÉÉÉÊÊÊÉÉÉÅÅÅÃÃÃÃÃÃÍÍÍÙÙÙßßßàààçççêêêèèèçççæææããããããââââââãããäääçççêêêíííîîîïïïïïïòòòóóóóóóóóóïïïîîîíííîîîçççßßßÛÛÛÜÜÜßßßäääçççâââèèèèèèèèèççççççæææàààÛÛÛØØØÀÀÀ···¾¾¾¿¿¿¼¼¼¿¿¿ÂÂÂÆÆÆÉÉÉÊÊÊÉÉÉÆÆÆÆÆÆÆÆÆÆÆÆÌÌÌÅÅÅÅÅÅÀÀÀÃÃü¼¼±±±¼¼¼ÅÅÅÊÊÊÆÆÆ»»»´´´µµµ¸¸¸´´´µµµ¾¾¾ÂÂÂÀÀÀÇÇÇÌÌÌÆÆƸ¸¸¿¿¿ÆÆÆÌÌÌÌÌÌÊÊÊÇÇÇÇÇÇÅÅÅÇÇÇÎÎÎ××××××ÑÑÑÑÑÑÕÕÕ×××ÛÛÛßßßßßßÜÜÜÛÛÛÝÝÝàààäääæææäääâââßßßÝÝÝàààããããããâââßßßÙÙÙÕÕÕØØØàààçççÐÐÐÐÐÐÑÑÑÒÒÒÔÔÔÔÔÔÕÕÕÕÕÕÒÒÒÐÐÐÙÙÙÙÙÙÛÛÛÝÝÝÕÕÕØØØ×××êêêçççàààçççîîîÝÝݵµµººº¼¼¼ÀÀÀÅÅÅÇÇÇÇÇÇÆÆÆÅÅÅÑÑÑàààñññîîîóóóñññúúúããããããäääææææææâââÝÝÝÜÜÜÛÛÛÛÛÛÝÝÝÛÛÛ×××ÛÛÛäääßßßÑÑÑÙÙÙÃÃÃÃÃÃÑÑÑÑÑÑÉÉÉÃÃÿ¿¿ÑÑÑÑÑÑÐÐÐÌÌÌÌÌÌÌÌÌÉÉÉÅÅÅÍÍÍÒÒÒÍÍÍÂÂÂÂÂÂÍÍÍÌÌÌÀÀÀ¼¼¼¸¸¸´´´©©©ªªª°°°¸¸¸³³³ªªª³³³¾¾¾ÀÀÀ···³³³³³³´´´···ººº¼¼¼¾¾¾¾¾¾ÇÇǺººµµµ···¬¬¬³³³´´´¸¸¸ÃÃÃÍÍÍÌÌÌÇÇÇÌÌÌÕÕÕÝÝÝÔÔÔÑÑÑÍÍÍÇÇÇÅÅÅÂÂÂÀÀÀ¿¿¿ÅÅÅÅÅÅÃÃÃÍÍÍßßßàààÙÙÙßßßêêêèèèæææãããâââàààààààààâââäääçççêêêíííïïïïïïïïïòòòóóóóóóñññëëëæææäääãããâââÛÛÛÝÝÝàààÜÜÜàààçççãããäääççççççæææäääãããàààÝÝÝßßßÔÔÔÀÀÀ···¼¼¼ÀÀÀÂÂÂÆÆÆÇÇÇÇÇÇÉÉÉÇÇÇÅÅÅÃÃÃÅÅÅÆÆÆÉÉÉÃÃþ¾¾¿¿¿»»»¬¬¬³³³ÃÃÃÇÇÇÉÉɸ¸¸³³³¸¸¸ÀÀÀÃÃõµµ´´´¾¾¾ÇÇÇÍÍÍÆÆÆ´´´¾¾¾ÂÂÂÇÇÇÊÊÊÊÊÊÇÇÇÅÅÅÃÃÃÌÌÌÎÎÎÔÔÔ×××ÐÐÐÇÇÇÍÍÍÙÙÙÔÔÔØØØÜÜÜÜÜÜÜÜÜÜÜÜàààããããããäääääääääãããâââââââââççççççäääßßßÛÛÛÛÛÛâââçççÑÑÑÒÒÒÔÔÔÔÔÔÔÔÔÒÒÒÑÑÑÐÐÐÐÐÐÔÔÔàààÝÝÝÛÛÛÛÛÛÕÕÕÛÛÛÔÔÔèèèãããÙÙÙÜÜÜäääÙÙÙµµµ···¸¸¸¼¼¼ÀÀÀÂÂÂÃÃÃÃÃÃÂÂÂãããóóóùùùòòòóóóñññÿÿÿãããäääçççèèèçççâââÜÜÜÛÛÛÛÛÛÜÜÜÝÝÝÜÜÜÜÜÜÝÝÝÝÝÝÛÛÛ×××ÒÒÒÇÇÇÅÅÅÍÍÍÐÐÐÎÎÎÉÉɾ¾¾ÃÃÃÊÊÊÑÑÑÒÒÒÐÐÐÍÍÍÍÍÍÍÍÍÇÇÇÑÑÑÔÔÔÎÎÎÎÎÎÎÎÎÀÀÀ¯¯¯±±±³³³±±±°°°¯¯¯¯¯¯´´´µµµ¨¨¨¤¤¤ªªª···¾¾¾ººº³³³¯¯¯°°°±±±´´´···ºººººº¸¸¸»»»¬¬¬´´´±±±···ÃÃÃÅÅÅÀÀÀÂÂÂÉÉÉÎÎÎÐÐÐÌÌÌÌÌÌÐÐÐÕÕÕÑÑÑÌÌÌÇÇÇÅÅÅÀÀÀ¿¿¿¿¿¿ÂÂÂÃÃÃÀÀÀÊÊÊÜÜÜßßßÙÙÙßßßæææäääãããâââàààßßßßßßßßßãããäääçççêêêîîîñññòòòòòòîîîïïïïïïíííèèèãããàààßßßßßßßßßçççèèèÜÜÜÜÜÜääääääãããäääææææææäääâââââââââàààâââÍÍ͸¸¸»»»ÀÀÀÂÂÂÆÆÆÇÇÇÆÆÆÆÆÆÆÆÆÅÅÅÂÂÂÂÂÂÆÆÆÀÀÀ¼¼¼¾¾¾ººº»»»ººº³³³¿¿¿ÆÆÆÅÅž¾¾···´´´»»»ÅÅÅÍÍÍ»»»¸¸¸ÅÅÅÉÉÉÆÆÆ¿¿¿µµµÂÂÂÅÅÅÇÇÇÉÉÉÉÉÉÆÆÆÂÂÂÀÀÀØØØÒÒÒÐÐÐÑÑÑÎÎÎÌÌÌÎÎÎ×××ÒÒÒÔÔÔ×××ØØØÙÙÙÝÝÝàààäääâââãããäääææææææäääãããâââääääääãããßßßÛÛÛÙÙÙÝÝÝâââãããÝÝÝÕÕÕÎÎÎÍÍÍÎÎÎÒÒÒÕÕÕÒÒÒ×××ãããÜÜÜØØØÙÙÙÕÕÕÙÙÙßßßëëëãããÛÛÛÜÜÜàààÙÙÙ¾¾¾´´´µµµººº¼¼¼¿¿¿¿¿¿ÀÀÀ¿¿¿îîîùùùÿÿÿóóóóóóïïïÿÿÿæææàààãããäääãããâââààààààãããâââÝÝÝÝÝÝàààßßßÛÛÛÛÛÛßßßÉÉÉÎÎÎÌÌÌÍÍÍÊÊÊÇÇÇÍÍÍÆÆÆ»»»ÂÂÂÍÍÍÒÒÒÌÌÌÂÂÂÀÀÀÆÆÆÎÎÎÑÑÑÒÒÒÍÍÍÆÆƾ¾¾µµµ°°°³³³···³³³³³³³³³±±±´´´¯¯¯¬¬¬ªªªªªª©©©¬¬¬±±±¸¸¸¼¼¼³³³µµµ···¸¸¸¸¸¸ºººººº»»»Â»»»¿¿¿ÆÆÆÂÂÂÅÅÅÌÌÌÉÉÉÂÂÂÂÂÂÇÇÇÑÑÑÔÔÔÎÎÎÇÇÇÅÅÅÍÍÍÉÉÉÇÇÇÆÆÆÅÅÅÃÃÃÆÆÆÊÊÊÀÀÀ¾¾¾¼¼¼ÅÅÅÒÒÒÙÙÙÜÜÜãããàààßßßßßßÝÝÝÝÝÝÝÝÝßßßßßßäääæææèèèëëëîîîïïïñññòòòçççèèèëëëëëëèèèäääããããããäääçççíííëëëàààÜÜÜßßßààààààßßßâââääääääããããããæææâââæææÛÛÛÆÆÆ»»»¾¾¾ÂÂÂÃÃÃÅÅÅÃÃÃÃÃÃÆÆÆÅÅÅÀÀÀÂÂÂÆÆƺººººº¼¼¼µµµµµµ···µµµÉÉÉÇÇÇÃÃÃÀÀÀ¿¿¿¾¾¾¾¾¾ÂÂÂÊÊÊÌÌ̼¼¼ÀÀÀÌÌÌÃÃ÷··ºººÀÀÀÀÀÀÂÂÂÅÅÅÆÆÆÆÆÆÃÃÃÀÀÀ¿¿¿ÜÜÜÔÔÔÍÍÍÍÍÍÐÐÐÑÑÑÑÑÑÒÒÒÕÕÕÒÒÒÒÒÒÔÔÔ×××ÜÜÜßßßâââââââââäääæææææææææäääãããßßßââââââÝÝÝÙÙÙØØØÙÙÙÝÝÝïïïèèèàààØØØÕÕÕØØØßßßãããÝÝÝÜÜÜâââÙÙÙØØØßßßØØØØØØëëëîîîäääæææííííííæææÑÑѳ³³´´´···ººº¼¼¼¾¾¾¾¾¾¾¾¾ëëëòòòúúúòòòóóóïïïùùùçççââââââãããäääæææèèèîîîñññïïïçççàààßßßßßßÜÜÜÜÜÜßßßÊÊÊÑÑÑÌÌÌÍÍÍÇÇÇ¿¿¿ÌÌÌÐÐо¾¾ÀÀÀÅÅÅ¿¿¿³³³µµµÂÂÂÐÐÐÆÆÆÂÂÂÅÅÅÀÀÀµµµ±±±µµµ´´´»»»µµµ¸¸¸ºººµµµµµµ©©©¬¬¬±±±´´´³³³¬¬¬°°°µµµ»»»¼¼¼¼¼¼ººº···¸¸¸¼¼¼¿¿¿¸¸¸ººº¿¿¿ÀÀÀÀÀÀÆÆÆÉÉÉÆÆƸ¸¸ÃÃÃÎÎÎÔÔÔÒÒÒÐÐÐÊÊÊÆÆÆÔÔÔÐÐÐÌÌÌÉÉɼ¼¼¾¾¾ÃÃÃÅÅÅÀÀÀÅÅÅÍÍÍÐÐÐÕÕÕÜÜÜâââÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÝÝÝßßßàààäääçççêêêíííîîîíííëëëêêêæææèèèííííííëëëèèèçççæææëëëíííèèèææææææâââÝÝÝÝÝÝÜÜÜÙÙÙÛÛÛàààãããâââãããæææããããããâââÒÒÒ»»»ºººÂÂÂÀÀÀÃÃÃÂÂÂÂÂÂÆÆÆÅÅÅ¿¿¿ÀÀÀÆÆÆ»»»»»»¾¾¾´´´±±±±±±µµµÌÌÌÉÉÉÃÃÃÂÂÂÆÆÆÉÉÉÇÇÇÊÊÊÐÐÐÍÍ͸¸¸ºººÇÇÇÀÀÀ±±±···ÃÃþ¾¾¿¿¿ÀÀÀÂÂÂÃÃÃÂÂÂÀÀÀ¾¾¾ØØØÔÔÔÐÐÐÍÍÍÐÐÐÒÒÒÒÒÒÑÑÑ×××ÔÔÔÐÐÐÐÐÐÕÕÕÛÛÛÝÝÝÝÝÝââââââãããääääääæææääääääÝÝÝàààâââßßßÛÛÛØØØÙÙÙÜÜÜèèèëëëïïïòòòñññîîîêêêçççëëëãããàààØØØÜÜÜæææßßßÛÛÛñññêêêÜÜÜâââçççÝÝÝÑÑÑ»»»±±±´´´µµµ¸¸¸»»»¼¼¼¾¾¾¾¾¾äääçççöööïïïòòòïïïöööèèèçççççççççèèèíííòòòøøøüüüÿÿÿòòòäääÜÜÜÜÜÜÝÝÝÝÝÝÛÛÛÒÒÒÑÑÑÅÅÅÍÍÍÊÊʾ¾¾ÉÉÉÑÑÑÎÎξ¾¾µµµººº¸¸¸³³³¾¾¾ÒÒÒÃÃó³³³³³ÇÇÇÎÎο¿¿¯¯¯±±±»»»¸¸¸¿¿¿ÃÃü¼¼¸¸¸¥¥¥¯¯¯´´´»»»¾¾¾ººº±±±©©©¥¥¥»»»»»»¸¸¸³³³¯¯¯°°°···¼¼¼ºººÀÀÀÀÀÀ»»»¼¼¼ÃÃÃÆÆÆÆÆƺººÉÉÉÒÒÒÑÑÑÑÑÑÕÕÕÍÍÍ¿¿¿ÒÒÒÎÎÎÌÌÌÉÉÉ»»»¾¾¾ÆÆÆÊÊÊÇÇÇÒÒÒÛÛÛÕÕÕÕÕÕÛÛÛÙÙÙ××××××ØØØÙÙÙÛÛÛÝÝÝàààâââäääçççëëëîîîîîîëëëæææâââêêêíííïïïïïïíííêêêçççæææîîîíííàààßßßêêêèèèßßßÝÝÝÙÙÙÕÕÕ×××ÝÝÝâââââââââæææßßßçççßßßßßßÛÛÛ±±±¼¼¼¿¿¿ÀÀÀÅÅÅÅÅÅÂÂÂÀÀÀÃÃÃÃÃÃÀÀÀººº¾¾¾°°°¼¼¼»»»ÂÂÂÇÇÇÆÆÆÊÊÊÎÎÎÑÑÑÑÑÑÐÐÐÎÎÎÎÎÎÌÌ̾¾¾»»»ºººÅÅÅ°°°°°°ºººµµµººº¾¾¾ÂÂÂÂÂÂÀÀÀÂÂÂÂÂÂ×××ÙÙÙÉÉÉÌÌÌÑÑÑÊÊÊÎÎÎÎÎÎÎÎÎÊÊÊÑÑÑÔÔÔÐÐÐÔÔÔÜÜÜÙÙÙßßßàààãããäääääääääãããâââæææâââàààâââßßßØØØÕÕÕ×××ßßßãããææææææãããâââäääèèèêêêäääãããäääãããÝÝÝÝÝÝâââëëëëëëâââêêêÜÜÜÐÐеµµ±±±´´´µµµµµµ»»»¼¼¼ÃÃü¼¼âââæææòòòííííííîîîêêêõõõÿÿÿæææäääæææíííõõõùùùùùùöööóóóñññëëëãããÛÛÛØØØØØØÙÙÙÒÒÒæææÍÍÍÅÅÅÕÕÕÎÎÎÊÊÊÎÎÎÍÍÍÊÊʾ¾¾¾¾¾»»»¸¸¸ÊÊÊÔÔÔÍÍÍÍÍÍÑÑÑÎÎÎÉÉÉÌÌÌÃÃñ±±³³³»»»¾¾¾»»»¾¾¾¸¸¸ªªª°°°¾¾¾Âººº···ººº³³³¨¨¨¼¼¼»»»´´´©©©¨¨¨¯¯¯µµµµµµ»»»···ºººÂ¿¿¿µµµµµµ¼¼¼ÂÂÂÍÍÍÑÑÑÐÐÐÑÑÑÕÕÕÍÍÍÀÀÀÎÎÎÍÍÍÃÃÃÊÊÊÉÉɾ¾¾ÃÃÃÂÂÂÉÉÉÑÑÑÙÙÙØØØÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÎÎÎÎÎÎÕÕÕÛÛÛÛÛÛÜÜÜâââääääääçççíííïïïíííçççãããâââæææëëëïïïïïïîîîëëëëëëíííæææßßßÛÛÛØØØØØØâââíííàààÜÜÜÙÙÙÛÛÛàààæææçççæææëëëñññæææäääããã···ººº»»»¿¿¿Â¾¾¾¾¾¾ÀÀÀÀÀÀ¾¾¾¼¼¼¾¾¾°°°ººº¸¸¸¯¯¯ÅÅÅÍÍÍÉÉÉÌÌÌÑÑÑÒÒÒÒÒÒÑÑÑÐÐÐÐÐÐÐÐÐÅÅž¾¾ÆÆÆ´´´´´´¼¼¼···ººº¾¾¾ÀÀÀÀÀÀ¿¿¿ÀÀÀÂÂÂÊÊÊÒÒÒÉÉÉÉÉÉÎÎÎÌÌÌÑÑÑÑÑÑÉÉÉÉÉÉÐÐÐÒÒÒÎÎÎÒÒÒÛÛÛÛÛÛßßßàààâââãããäääãããâââàààçççäääãããæææäääßßßÝÝÝàààäääææææææäääâââãããèèèîîîæææãããâââããããããâââæææíííêêêëëëæææäääÍÍÍÃÃ÷··µµµ´´´µµµ³³³»»»¾¾¾ÀÀÀºººâââçççñññêêêèèèëëëèèèòòòúúúæææëëëòòòøøøùùùøøøöööõõõõõõòòòëëëãããÜÜÜÙÙÙÜÜÜààà×××âââÊÊÊÅÅÅÔÔÔÐÐÐÌÌÌÊÊÊÅÅÅÍÍÍÍÍÍÐÐÐÆÆƼ¼¼ÊÊÊÕÕÕÑÑÑÑÑÑÔÔÔÔÔÔÐÐÐÐÐÐÅÅű±±³³³ººº¼¼¼»»»ÀÀÀ¸¸¸¬¬¬¸¸¸ÃÃÃÀÀÀ»»»µµµ°°°¬¬¬¬¬¬¨¨¨¢¢¢¦¦¦±±±¸¸¸»»»¿¿¿ºººººº¾¾¾»»»³³³µµµ¾¾¾ÆÆÆÐÐÐÔÔÔÑÑÑÒÒÒÕÕÕÎÎÎÂÂÂÍÍÍÍÍÍÉÉÉÌÌÌÌÌÌÆÆƺººÊÊÊ×××ßßßÛÛÛØØØÛÛÛÕÕÕÌÌÌÅÅŵµµ´´´ÊÊÊÜÜÜÝÝÝÛÛÛÜÜÜâââæææèèèçççäääæææïïïøøøóóóïïïëëëèèèëëëîîîñññòòòßßßÙÙÙ××××××ÕÕÕÔÔÔØØØÝÝÝãããßßßÙÙÙÛÛÛàààæææèèèèèèëëëîîîàààÛÛÛßßß···ººº¿¿¿¾¾¾¿¿¿¾¾¾ºººººº¾¾¾¾¾¾»»»¼¼¼¾¾¾±±±¸¸¸µµµ°°°ÉÉÉÔÔÔÌÌÌÐÐÐÔÔÔÕÕÕÔÔÔÒÒÒÒÒÒÒÒÒÑÑÑÌÌÌÉÉÉ¿¿¿ÆÆƵµµ¸¸¸¾¾¾ººº¼¼¼¾¾¾¾¾¾¾¾¾¾¾¾¿¿¿ÀÀÀÇÇÇ×××ÑÑÑÍÍÍÎÎÎÍÍÍÑÑÑÐÐÐÎÎÎÐÐÐÕÕÕÕÕÕÑÑÑÒÒÒÙÙÙÛÛÛßßßßßßâââââââââàààßßßßßßãããââââââææææææããããããæææäääçççèèèçççæææçççëëëïïïëëëêêêêêêèèèäääàààâââæææëëëëëëêêêßßß¼¼¼µµµººº»»»ººº»»»´´´»»»ÀÀÀºººµµµßßßæææíííãããâââæææãããíííòòòæææïïïøøøùùùóóóîîîïïïòòòõõõóóóîîîæææÝÝÝÛÛÛßßßäääÜÜÜÝÝÝÍÍÍÉÉÉÑÑÑÑÑÑÍÍÍÇÇǸ¸¸ÅÅÅÊÊÊÑÑÑÉÉɼ¼¼ÃÃÃÅÅÅÔÔÔÔÔÔÕÕÕÕÕÕÔÔÔÔÔÔÉÉɵµµ´´´´´´ººº¼¼¼ºººÀÀÀÆÆƬ¬¬³³³¿¿¿ÆÆÆ¿¿¿³³³¯¯¯³³³³³³°°°ªªª¦¦¦ªªª´´´¸¸¸¸¸¸ÀÀÀ¼¼¼»»»¼¼¼ºººµµµ¼¼¼ÉÉÉÊÊÊÑÑÑÔÔÔÒÒÒÔÔÔÕÕÕÎÎÎÃÃÃÐÐÐÊÊÊÉÉÉÃÃÃÅÅÅÊÊÊÇÇÇÆÆÆÔÔÔÜÜÜÙÙÙÌÌÌÆÆÆÉÉÉÀÀÀ°°°³³³¨¨¨¦¦¦¸¸¸ÎÎÎÙÙÙÜÜÜÜÜÜÛÛÛÝÝÝâââããããããæææèèèèèèõõõïïïëëëëëëïïïññññññïïïãããÝÝÝÙÙÙÙÙÙØØØ××××××ØØØæææàààÛÛÛÛÛÛàààæææêêêêêêäääçççßßßÙÙÙÜÜÜ···¸¸¸ÀÀÀ¿¿¿ÀÀÀ¼¼¼¸¸¸¸¸¸¾¾¾¾¾¾»»»¼¼¼¾¾¾´´´¸¸¸···µµµÌÌÌØØØÐÐÐÒÒÒ×××ØØØ×××ÕÕÕÕÕÕÕÕÕÑÑÑÎÎÎÌÌ̾¾¾Â´´´···¼¼¼¼¼¼¾¾¾¾¾¾¼¼¼»»»¼¼¼¾¾¾ÀÀÀÀÀÀÔÔÔÔÔÔÊÊÊÉÉÉÊÊÊÊÊÊÊÊÊÉÉÉÍÍÍÑÑÑÒÒÒÑÑÑÔÔÔÛÛÛßßßßßßßßßààààààßßßßßßÝÝÝÜÜÜÜÜÜÙÙÙÜÜÜàààâââßßßßßßâââÜÜÜâââèèèííííííëëëëëëëëëãããæææêêêëëëèèèæææäääæææïïïëëëîîîÝÝݸ¸¸µµµÂººº¾¾¾ÃÃõµµµµµÝÝÝëëëñññäääãããèèèçççîîîòòòíííòòòõõõòòòíííêêêîîîóóóóóóóóóñññèèèàààÜÜÜßßßãããßßßÜÜÜÕÕÕÒÒÒÐÐÐÐÐÐÐÐÐÌÌÌ»»»¾¾¾ºººÃÃÃÉÉÉ¿¿¿³³³ÌÌÌÑÑÑÔÔÔÔÔÔÒÒÒÔÔÔÎÎÎÅÅŵµµµµµ¼¼¼¿¿¿»»»¿¿¿ÅÅÅ´´´°°°···ÂÂÂÀÀÀ´´´±±±ººº´´´°°°ªªª¬¬¬±±±¸¸¸»»»ººº°°°°°°¯¯¯°°°ºººÆÆÆÉÉÉÍÍÍÑÑÑÑÑÑÒÒÒÔÔÔÎÎÎÆÆÆØØØÎÎÎÎÎÎÃÃü¼¼¿¿¿¼¼¼ÇÇÇÜÜÜØØØÉÉÉ···±±±µµµ°°°¤¤¤´´´³³³¯¯¯···ÌÌÌÙÙÙÛÛÛÝÝÝßßßÜÜÜÛÛÛÝÝÝãããäääãããëëëííííííîîîîîîîîîííííííëëëäääÛÛÛ×××ÔÔÔÒÒÒÑÑÑÑÑÑäääßßßÛÛÛÛÛÛàààæææççççççããããããæææàààÜÜܺºº¸¸¸¿¿¿ÅÅÅÃÃÿ¿¿»»»¼¼¼ÀÀÀÀÀÀ¼¼¼»»»¼¼¼¸¸¸ºººººº»»»ÍÍÍØØØÔÔÔ×××ÙÙÙÙÙÙØØØ××××××ØØØÔÔÔÑÑÑÍÍ;¾¾ÃÃõµµ¸¸¸¾¾¾¾¾¾¿¿¿¾¾¾¼¼¼»»»»»»¾¾¾ÀÀÀÆÆÆØØØÜÜÜÑÑÑÐÐÐÒÒÒÐÐÐÑÑÑÜÜÜßßßßßßÜÜÜÙÙÙØØØÛÛÛßßßßßßßßßßßßÝÝÝÜÜÜÛÛÛÛÛÛÙÙÙØØØ×××ØØØÜÜÜÝÝÝÛÛÛÛÛÛÝÝÝÙÙÙßßßæææëëëííííííëëëëëëäääçççêêêèèèçççæææææææææóóóëëëïïïâââÅÅž¾¾ÉÉÉÅÅÅÃÃÃÃÃþ¾¾ÂÂÂÆÆƵµµÀÀÀàààæææëëëÝÝÝÝÝÝãããâââçççêêêïïïïïïñññïïïîîîîîîïïïòòòïïïòòòòòòîîîæææßßßÜÜÜÜÜÜßßßÜÜÜßßßÛÛÛÑÑÑÎÎÎÐÐÐÑÑÑÍÍÍÆÆÆ···¼¼¼ÇÇÇÇÇÇÆÆƸ¸¸ºººÆÆÆÑÑÑÔÔÔÕÕÕÔÔÔÐÐÐÎÎα±±³³³¼¼¼ÃÃÿ¿¿¾¾¾ÀÀÀ¾¾¾¿¿¿±±±¸¸¸¿¿¿ººº¸¸¸¿¿¿¿¿¿¸¸¸±±±°°°°°°°°°ªªª¯¯¯¯¯¯°°°³³³´´´µµµ¾¾¾ÆÆÆÃÃÃÇÇÇÊÊÊÍÍÍÐÐÐÑÑÑÎÎÎÉÉÉÀÀÀ»»»ÉÉÉÊÊÊÅÅÅÀÀÀ¿¿¿ÑÑÑÔÔÔÉÉÉ»»»µµµµµµ···¸¸¸¸¸¸µµµÀÀÀÀÀÀ±±±»»»ÇÇÇÊÊÊÍÍÍÙÙÙââââââßßßãããçççèèèèèèíííîîîëëëçççæææêêêîîîïïïëëëäääßßßÝÝÝÜÜÜØØØÕÕÕàààÜÜÜÛÛÛÜÜÜàààäääãããâââãããÒÒÒÔÔÔÎÎÎÉÉÉ···ÃÃÃÊÊÊÉÉÉÇÇÇÃÃÿ¿¿ÂÂÂÆÆÆÃÃÿ¿¿¼¼¼¼¼¼»»»»»»¼¼¼ÂÂÂÎÎÎ××××××ÙÙÙÛÛÛÛÛÛÙÙÙØØØÙÙÙÙÙÙÙÙÙÒÒÒÎÎÎÂÂÂÇÇǸ¸¸»»»Â¿¿¿¿¿¿¿¿¿¾¾¾¼¼¼¼¼¼¿¿¿Â»»»ÉÉÉÒÒÒÐÐÐÕÕÕÝÝÝÛÛÛàààßßßâââßßßÜÜÜÝÝÝÛÛÛÙÙÙÝÝÝßßßÝÝÝÝÝÝÜÜÜÙÙÙØØØØØØ×××ÙÙÙØØØÙÙÙÝÝÝßßßÜÜÜÜÜÜßßßßßßàààãããæææçççêêêíííîîîîîîîîîêêêääääääçççèèèçççõõõëëëñññçççÕÕÕÅÅÅÊÊÊÆÆÆÀÀÀ¿¿¿ÀÀÀÃÃÃÅÅŸ¸¸ÑÑÑäääâââèèèÜÜÜÝÝÝãããàààäääçççääääääçççêêêíííëëëèèèæææíííïïïòòòòòòíííäääÜÜÜØØØÜÜÜÛÛÛãããßßß×××ÑÑÑÎÎÎÔÔÔÔÔÔÑÑÑÀÀÀ¼¼¼¾¾¾ÀÀÀÉÉÉÅÅż¼¼ÊÊÊÒÒÒØØØÕÕÕÎÎÎÎÎΰ°°¯¯¯ºººÃÃÃÀÀÀÀÀÀ¾¾¾ÅÅÅ´´´ªªª¯¯¯»»»¿¿¿¿¿¿¿¿¿»»»···´´´¸¸¸»»»»»»ººº»»»¿¿¿¿¿¿ÀÀÀÂÂÂÃÃÃÅÅÅÇÇÇÊÊÊÂÂÂÃÃÃÆÆÆÊÊÊÍÍÍÐÐÐÎÎÎÊÊÊ¿¿¿¾¾¾ÆÆÆÉÉÉÃÃþ¾¾¿¿¿ÍÍÍÀÀÀººº···¼¼¼¿¿¿¼¼¼¾¾¾ÃÃÃÀÀÀÀÀÀÀÀÀ¼¼¼µµµ³³³³³³´´´±±±ÀÀÀÎÎÎ×××ÝÝÝäääâââÛÛÛÜÜÜäääíííîîîêêêääääääæææêêêíííïïïîîîîîîëëëæææßßßÝÝÝÜÜÜÛÛÛÜÜÜàààãããâââßßßààà»»»ºººººº»»»ºººÐÐÐÐÐÐÌÌÌÊÊÊÇÇÇÃÃÃÆÆÆÉÉÉÆÆÆ¿¿¿¿¿¿¾¾¾»»»ººº¾¾¾ÇÇÇÐÐÐ×××ÙÙÙÛÛÛÜÜÜÜÜÜÛÛÛÙÙÙÙÙÙÛÛÛÜÜÜÐÐÐÉÉÉÂÂÂÊÊʸ¸¸ºººÃÃþ¾¾¿¿¿ÀÀÀ¿¿¿¾¾¾¿¿¿ÀÀÀÃÃÃÆÆÆÇÇÇÌÌÌÅÅÅÇÇÇÇÇǺºº¿¿¿¾¾¾ÃÃÃÃÃÃÇÇÇÔÔÔØØØÙÙÙàààßßßÝÝÝÜÜÜÙÙÙØØØ×××ÕÕÕÕÕÕÛÛÛÙÙÙÛÛÛàààâââßßßàààãããäääääääääæææçççèèèêêêêêêäääæææäääæææíííõõõöööóóóòòòêêêòòòëëëàààÃÃÃÂÂÂÅÅÅÀÀÀ¼¼¼ÅÅÅÅÅÅ¿¿¿¸¸¸ÛÛÛàààèèèñññçççèèèîîîêêêîîîñññâââãããæææèèèèèèèèèæææäääëëëîîîòòòóóóòòòëëëâââÙÙÙÛÛÛ×××ÝÝÝÜÜÜÜÜÜØØØÊÊÊÑÑÑÐÐÐÔÔÔÉÉɾ¾¾······ÆÆÆÇÇÇ···¼¼¼¾¾¾ÆÆÆÔÔÔÕÕÕÍÍÍÍÍ͸¸¸³³³¸¸¸ÀÀÀ¿¿¿¿¿¿ÀÀÀ¿¿¿¿¿¿¸¸¸°°°···ÃÃÃÃÃü¼¼ÅÅÅÀÀÀÀÀÀÃÃÃÃÃÃÀÀÀ¿¿¿ÀÀÀ¾¾¾¼¼¼¼¼¼¾¾¾ÀÀÀÂÂÂÃÃÃÂÂÂÃÃÃÃÃÃÅÅÅÉÉÉÍÍÍÎÎÎÍÍÍÌÌÌ¿¿¿ÃÃÃÀÀÀÀÀÀÂÂÂÇÇÇÌÌÌÆÆƳ³³µµµ»»»ÀÀÀ¿¿¿¼¼¼¼¼¼¾¾¾Â¿¿¿¿¿¿ÀÀÀ¾¾¾µµµ°°°°°°³³³±±±µµµÃÃÃÒÒÒÑÑÑÆÆÆÃÃÃÍÍÍÛÛÛæææëëëêêêãããßßßÝÝÝæææëëëëëëêêêèèèãããÝÝÝàààÝÝÝÛÛÛÜÜÜàààããããããàààâââ³³³¸¸¸ÀÀÀÃÃÃÅÅÅÑÑÑÂÂÂÌÌÌÌÌÌÉÉÉÆÆÆÇÇÇÌÌÌÆÆÆ¿¿¿ÃÃþ¾¾»»»¸¸¸¾¾¾ÉÉÉÐÐÐ×××ÛÛÛÜÜÜÝÝÝÜÜÜÛÛÛÙÙÙÙÙÙÛÛÛÙÙÙÊÊÊÃÃþ¾¾ÇÇÇ´´´µµµÀÀÀ¾¾¾¿¿¿ÀÀÀÀÀÀ¿¿¿ÀÀÀÂÂÂÃÃÃÆÆÆÃÃÃÇÇÇÅÅÅÍÍÍÐÐÐÂÂÂÉÉÉÃÃÃÇÇÇÃÃÃÇÇÇÔÔÔÙÙÙ×××ÜÜÜßßßÝÝÝÛÛÛÙÙÙ×××ÕÕÕÕÕÕÔÔÔÙÙÙØØØÙÙÙàààâââàààâââææææææçççêêêëëëëëëêêêæææãããâââæææêêêîîîöööüüüöööíííïïïêêêòòòíííäää¿¿¿»»»ÃÃÃÃÃÿ¿¿ÉÉÉÆÆƺºº´´´ÜÜÜØØØßßßèèèâââãããçççãããçççêêêîîîññññññïïïííííííñññõõõêêêíííñññõõõöööñññæææßßßÛÛÛÔÔÔØØØØØØàààÜÜÜÇÇÇÌÌÌÑÑÑØØØÎÎÎÃÃúºº¸¸¸ÆÆÆÇÇÇÉÉÉ´´´¸¸¸ÌÌÌÔÔÔÎÎÎÎÎÎÅÅźººººº¿¿¿¼¼¼¼¼¼¿¿¿¾¾¾¸¸¸»»»···°°°µµµÅÅÅÅÅźºº¿¿¿¾¾¾¿¿¿ÃÃÃÃÃÃÀÀÀ¿¿¿ÃÃúºº¸¸¸¸¸¸»»»¿¿¿ÃÃÃÃÃÃÂÂÂÆÆÆÅÅÅÆÆÆÊÊÊÍÍÍÍÍÍÌÌÌÊÊÊÃÃÃÑÑÑÇÇÇÅÅÅÉÉÉÍÍÍÇÇÇ©©©ºººÂÂÂÀÀÀ¿¿¿ÀÀÀÂÂÂÀÀÀ¿¿¿ÃÃÃÃÃÿ¿¿¼¼¼¼¼¼ºººµµµ´´´µµµ³³³µµµ¿¿¿¾¾¾´´´µµµ¸¸¸ÂÂÂÑÑÑâââêêêèèèããããããêêêîîîêêêççççççæææâââäääàààÜÜÜÜÜÜàààääääääãããÔÔÔÅÅźºº¼¼¼ÅÅÅÉÉÉÉÉÉÉÉÉÍÍÍÊÊÊÇÇÇÇÇÇÉÉÉÉÉÉÇÇÇÆÆÆÃÃÃÆÆÆÀÀÀÃÃÃÀÀÀ¾¾¾ÐÐÐÙÙÙàààÝÝÝØØØÑÑÑÐÐÐÔÔÔÙÙÙÜÜÜÕÕÕÐÐп¿¿¿¿¿ÊÊÊ»»»¯¯¯¾¾¾»»»ÀÀÀ¾¾¾¾¾¾ÃÃÃÇÇÇÆÆÆÊÊÊÉÉÉÉÉÉÊÊÊÍÍÍÍÍÍÌÌÌÉÉÉÇÇÇÇÇÇÇÇÇÂÂÂÙÙÙØØØÙÙÙØØØÝÝÝàààßßßØØØÔÔÔÕÕÕ×××ÔÔÔÛÛÛÜÜÜÜÜÜÝÝÝàààäääçççèèèëëëèèèâââäääîîîèèèãããêêêñññõõõöööõõõõõõøøøøøøóóóøøøúúúøøøàà྾¾ÅÅÅ¿¿¿Â¿¿¿ÅÅÅÊÊʼ¼¼···ÎÎÎÙÙÙçççÛÛÛÙÙÙÍÍÍÀÀÀØØØÛÛÛèèèççççççèèèææææææëëëóóóñññíííñññïïïêêêñññòòòæææÜÜÜØØØ×××ÕÕÕÛÛÛßßßÕÕÕÌÌÌÌÌÌÕÕÕÑÑÑÐÐп¿¿ÍÍÍÐÐÐÉÉÉÊÊÊÂÂÂÂÂÂÌÌÌÒÒÒÐÐÐÎÎÎÐÐÐÌÌÌÑÑÑÊÊÊ»»»µµµ¼¼¼Â¿¿¿¼¼¼ÃÃúºº¯¯¯ºººÆÆÆÃÃÿ¿¿ÀÀÀÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀÀÀÀ¾¾¾¸¸¸···¼¼¼¿¿¿¾¾¾¾¾¾ÀÀÀÃÃÃÃÃÃÆÆÆÉÉÉÆÆÆÃÃÃÉÉÉÔÔÔÐÐÐÊÊÊÉÉÉÔÔÔÎÎÎÐÐкºº´´´···¸¸¸¾¾¾ÆÆÆÉÉÉÆÆÆÅÅÅÆÆÆÇÇÇÆÆÆÃÃÃÂÂÂÀÀÀ¿¿¿¿¿¿¾¾¾¼¼¼»»»»»»¾¾¾ÂÂÂÃÃÃÃÃÃÂÂÂÀÀÀºººµµµ»»»ÉÉÉÛÛÛæææëëëæææãããäääïïïëëëçççíííàààÛÛÛßßßàààÔÔÔßßßÛÛÛàààãããÃÃÿ¿¿ÀÀÀÇÇÇÊÊÊÉÉÉÇÇÇÉÉÉÐÐÐÍÍÍÌÌÌÌÌÌÍÍÍÍÍÍÌÌÌÉÉÉÇÇÇÉÉÉÀÀÀÃÃÃÀÀÀ¿¿¿ÑÑÑÜÜÜâââßßßØØØÒÒÒÐÐÐÑÑÑÕÕÕ×××ÙÙÙÕÕÕÆÆÆÀÀÀÃÃû»»´´´¼¼¼ººº¿¿¿ÀÀÀ¾¾¾¼¼¼ÀÀÀÂÂÂÂÂÂÊÊÊÊÊÊÊÊÊÊÊÊÌÌÌÌÌÌÊÊÊÉÉÉÉÉÉÅÅÅÇÇÇÇÇÇÛÛÛÒÒÒ×××ÜÜÜÛÛÛÝÝÝÝÝÝÙÙÙ×××ØØØÙÙÙØØØØØØØØØÛÛÛßßßæææèèèèèèæææäääíííîîîîîîïïïíííîîîúúúäääëëëïïïïïïïïïñññïïïëëëêêêïïïíííÛÛÛÇÇÇÅÅÅÇÇÇÃÃþ¾¾»»»ÀÀÀÇÇÇÀÀÀ³³³´´´¿¿¿···Â¸¸¸¾¾¾»»»³³³ÀÀÀ»»»ÙÙÙÜÜÜàààãããàààÝÝÝäääîîîõõõõõõöööóóóïïïòòòòòòëëëçççäääÝÝÝ××××××ÛÛÛ×××ÑÑÑÍÍÍÒÒÒÑÑÑÑÑÑ»»»ÂÂÂÆÆÆÊÊÊÍÍ;¾¾ºººÌÌÌ×××ÑÑÑÍÍÍÑÑÑÎÎÎÒÒÒÐÐÐÀÀÀ´´´´´´»»»¿¿¿¿¿¿Â¸¸¸³³³¾¾¾ÆÆÆÃÃÃÂÂÂÀÀÀÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀÀÀÀ¾¾¾ººº¸¸¸¼¼¼¾¾¾¾¾¾ÀÀÀÅÅÅ»»»»»»¼¼¼¿¿¿¾¾¾¿¿¿ÅÅÅÌÌÌÐÐÐÆÆÆÊÊÊÒÒÒÐÐÐÑÑѱ±±»»»ººº¾¾¾ÅÅÅÇÇÇÅÅÅÅÅÅÇÇÇÀÀÀÃÃÃÇÇÇÇÇÇÃÃü¼¼»»»¾¾¾¾¾¾ÃÃÃÇÇÇÊÊÊÉÉÉÆÆÆÅÅÅÅÅÅÀÀÀ¾¾¾ººº¸¸¸»»»ÆÆÆÒÒÒÜÜÜäääçççæææîîîîîîëëëíííßßßßßßÜÜÜßßßÝÝÝòòòèèèâââÛÛÛ···¾¾¾ÇÇÇÎÎÎÎÎÎÊÊÊÌÌÌÐÐÐÒÒÒÑÑÑÐÐÐÑÑÑÑÑÑÑÑÑÐÐÐÎÎÎÌÌÌÌÌÌÂÂÂÃÃÃÀÀÀ¿¿¿ÑÑÑÜÜÜâââÝÝÝØØØÕÕÕÒÒÒÐÐÐÐÐÐÑÑÑÙÙÙÙÙÙÑÑÑÆÆÆ¿¿¿¾¾¾ººº´´´¾¾¾¿¿¿¾¾¾¸¸¸¸¸¸¾¾¾ÃÃÃÆÆÆÉÉÉÊÊÊÌÌÌÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÃÃÃÇÇÇÌÌÌÜÜÜÐÐÐÕÕÕÜÜÜÙÙÙÜÜÜÝÝÝÙÙÙØØØÙÙÙÛÛÛÛÛÛ×××ØØØÜÜÜâââäääèèèëëëïïïòòòöööóóóõõõüüüüüüõõõòòòêêêïïïïïïëëëæææææææææãããêêêêêêÜÜÜÇÇÇ¿¿¿ÃÃÃÆÆÆÉÉÉÇÇÇÅÅÅÅÅÅÇÇÇÆÆÆÀÀÀ¼¼¼¾¾¾µµµ¼¼¼´´´ÀÀÀÆÆÆ¿¿¿Â´´´···¼¼¼ÉÉÉ×××ÝÝÝàààæææíííëëëòòòóóóïïïïïïïïïïïïòòòèèèæææÝÝÝ××××××ÜÜÜâââàààÎÎÎÑÑÑÒÒÒÔÔÔ»»»¿¿¿ÃÃÃÎÎÎÍÍͺºº···ÍÍÍÛÛÛÔÔÔÎÎÎÒÒÒÍÍÍÒÒÒÑÑÑÃÃô´´°°°¸¸¸Â¿¿¿······ÂÂÂÆÆÆÃÃÃÃÃÃÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀ¿¿¿»»»¸¸¸¸¸¸»»»¾¾¾ÀÀÀÆÆÆÍÍÍÑÑÑÑÑÑÍÍÍÆÆÆÃÃÃÆÆÆÇÇÇÆÆÆÇÇÇÀÀÀÌÌÌÒÒÒÒÒÒÒÒÒ±±±±±±¾¾¾»»»¾¾¾ÂÂÂÅÅÅÅÅÅÆÆÆÊÊÊÌÌÌÇÇÇÇÇÇÌÌÌÊÊÊÃÃÃÀÀÀÃÃÿ¿¿ÂÂÂÅÅÅÆÆÆÇÇÇÆÆÆÃÃÃÂÂÂÉÉÉÉÉÉÇÇÇÃÃþ¾¾ººº¸¸¸¸¸¸ØØØçççããããããæææãããäääÝÝÝòòòèèèæææâââëëëÑÑÑÀÀÀ···¾¾¾ÃÃÃÊÊÊÎÎÎÎÎÎÎÎÎÒÒÒ×××ÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÒÒÒÒÒÒÌÌÌÌÌÌÃÃÃÅÅÅ¿¿¿ÎÎÎ×××ÝÝÝØØØÕÕÕÕÕÕÔÔÔÐÐÐÎÎÎÎÎÎÑÑÑ×××ÙÙÙÌÌ̾¾¾ÀÀÀ¾¾¾¯¯¯···ºººººººººººº¾¾¾ÃÃÃÇÇÇÇÇÇÊÊÊÎÎÎÐÐÐÎÎÎÎÎÎÐÐÐÒÒÒÑÑÑÇÇÇÊÊÊÊÊÊÙÙÙÒÒÒ×××ÕÕÕÛÛÛÜÜÜÜÜÜÙÙÙØØØØØØÙÙÙÛÛÛÙÙÙÜÜÜàààããããããæææòòòÿÿÿúúúÿÿÿüüüööööööùùùøøøóóóóóóñññæææÔÔÔÆÆÆÂÂÂÀÀÀ¿¿¿ÜÜÜÜÜÜÉÉɸ¸¸¾¾¾ÅÅÅÉÉÉÐÐÐÑÑÑÎÎÎÉÉÉÆÆÆÆÆÆÆÆÆÆÆÆÃÃÃÅÅÅÇÇÇ¿¿¿ÉÉÉÐÐÐÉÉÉÇÇǺºº···´´´µµµÀÀÀÍÍÍÕÕÕÝÝÝãããîîîùùùøøøññññññëëëèèèñññòòòïïïàààØØØ×××ØØØÜÜÜÕÕÕÍÍÍÑÑÑ×××ÕÕÕÀÀÀÌÌÌÊÊÊÑÑÑÅÅż¼¼¿¿¿ÐÐÐÛÛÛ×××ÑÑÑÒÒÒÊÊÊÑÑÑÍÍͼ¼¼±±±µµµ¿¿¿ÅÅźºº´´´ºººÂÂÂÃÃÃÂÂÂÃÃÃÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀ¿¿¿¿¿¿µµµµµµ···ººº¼¼¼ÃÃÃÍÍÍÔÔÔÍÍÍÍÍÍÉÉÉÂÂÂÃÃÃÉÉÉÊÊÊÆÆÆÆÆÆÊÊÊÑÑÑØØØÕÕÕÆÆÆ´´´···¿¿¿»»»»»»ÀÀÀÃÃÃÅÅÅÉÉÉÎÎÎÆÆƸ¸¸°°°ºººÅÅÅÇÇÇÆÆÆÆÆÆÎÎÎÎÎÎÎÎÎÍÍÍÌÌÌÊÊÊÊÊÊÊÊÊÇÇÇÅÅÅÅÅÅÇÇÇÌÌÌÇÇÇ¿¿¿······àààïïïîîîêêêæææïïïöööîîîçççèèèâââßßß¾¾¾···¿¿¿ÉÉÉÊÊÊÌÌÌÎÎÎÑÑÑÕÕÕ×××ØØØÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÔÔÔÕÕÕÕÕÕÉÉÉÊÊÊÃÃÃÆÆÆÃÃÿ¿¿ÊÊÊÎÎÎÕÕÕÑÑÑÐÐÐÕÕÕ×××ÒÒÒÎÎÎÐÐÐÎÎÎÒÒÒÙÙÙÍÍÍ»»»¿¿¿Â³³³©©©´´´ººº¼¼¼¼¼¼¾¾¾¿¿¿ÅÅÅÉÉÉÍÍÍÎÎÎÐÐÐÑÑÑÔÔÔ×××ÕÕÕÍÍÍÎÎÎÆÆÆÕÕÕØØØÛÛÛÎÎÎØØØØØØÙÙÙÙÙÙØØØØØØÛÛÛÝÝÝâââÝÝÝàààçççëëëïïïøøøÿÿÿüüüúúúõõõïïïòòòøøøöööíííçççæææÜÜÜÎÎÎÆÆÆÅÅÅÆÆÆÆÆÆÀÀÀÅÅż¼¼ºººÇÇÇÐÐÐÐÐÐÔÔÔÐÐÐÐÐÐÍÍÍÇÇÇÅÅÅÆÆÆÆÆÆÆÆÆÊÊÊÌÌÌÅÅÅÉÉÉÉÉÉÆÆÆÆÆÆÀÀÀÃÃû»»´´´±±±´´´¿¿¿ÑÑÑâââæææïïïïïïíííïïïêêêçççïïïóóóñññÝÝÝÙÙÙÛÛÛØØØØØØÉÉÉÍÍÍÒÒÒØØØÑÑÑÂÂÂ×××ÎÎÎÉÉɾ¾¾ÆÆÆÎÎÎÕÕÕÙÙÙÙÙÙÕÕÕÑÑÑÎÎÎÑÑÑÆÆƳ³³°°°¾¾¾ÅÅÅ¿¿¿Â´´´°°°ºººÀÀÀÂÂÂÀÀÀÀÀÀÀÀÀÂÂÂÂÂÂÀÀÀÀÀÀ¿¿¿¾¾¾¼¼¼···¸¸¸ºººººº»»»ÂÂÂÊÊÊÐÐÐÉÉÉÊÊÊÅÅÅ¿¿¿ÀÀÀÇÇÇÇÇÇÂÂÂÎÎÎâââÛÛÛâââÕÕÕ°°°³³³µµµ¼¼¼ºººººº¿¿¿ÂÂÂÅÅÅÊÊÊÑÑÑÀÀÀµµµ°°°»»»ÌÌÌÔÔÔÕÕÕÕÕÕÎÎÎÑÑÑÑÑÑÐÐÐÍÍÍÌÌÌÍÍÍÎÎÎÐÐÐÊÊÊÅÅÅÅÅÅÊÊÊÍÍÍÊÊÊÇÇǺººØØØßßßãããêêêçççæææàààçççãããçççßßß×××´´´µµµÆÆÆÍÍÍÎÎÎÐÐÐÑÑÑÕÕÕÙÙÙØØØÔÔÔÔÔÔÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔ×××ØØØÉÉÉÊÊÊÃÃÃÇÇÇÅÅÅ¿¿¿ÇÇÇÊÊÊÐÐÐÉÉÉÊÊÊÔÔÔØØØÔÔÔÐÐÐÒÒÒÐÐÐÒÒÒÕÕÕÌÌ̺ºººººÂ¿¿¿¬¬¬ªªª¬¬¬¯¯¯°°°³³³ºººÀÀÀ¿¿¿ÂÂÂÆÆÆÉÉÉÌÌÌÎÎÎÐÐÐÑÑÑÔÔÔÐÐÐÒÒÒÅÅÅÐÐÐ×××ßßßÐÐÐ××××××ØØØÛÛÛÛÛÛÛÛÛßßßãããäääÝÝÝßßßîîîúúúüüüöööõõõöööòòòòòòööööööñññàààÊÊÊÀÀÀÅÅÅÅÅÅÃÃÃÆÆÆÌÌÌÎÎÎÌÌÌÀÀÀ¾¾¾¾¾¾ÉÉÉÐÐÐÒÒÒÕÕÕÐÐÐÔÔÔ×××ÔÔÔÐÐÐÍÍÍÌÌÌÊÊÊÉÉÉÉÉÉÆÆÆÅÅÅÃÃÃÂÂÂÆÆÆÇÇÇ¿¿¿ÀÀÀ¾¾¾´´´³³³ÃÃÃÕÕÕâââæææèèèîîîòòòîîîëëëïïïíííîîîÛÛÛÜÜÜßßßÛÛÛÝÝÝÌÌÌÎÎÎÔÔÔÙÙÙÌÌ̼¼¼ØØØÉÉÉ¿¿¿ÂÂÂÑÑÑÜÜÜÙÙÙØØØÛÛÛÙÙÙÑÑÑÕÕÕÑÑÑÀÀÀ°°°³³³ÀÀÀÃÃû»»Â³³³¯¯¯···¾¾¾ÂÂÂÃÃÿ¿¿ÀÀÀÀÀÀÀÀÀ¿¿¿¿¿¿¼¼¼»»»»»»»»»¾¾¾¼¼¼ººº»»»¿¿¿ÂÂÂÂÂÂÕÕÕÒÒÒÎÎÎÉÉÉÉÉÉÊÊÊÇÇÇÃÃÃÍÍÍçççÛÛÛâââ×××¥¥¥µµµººº»»»¸¸¸ººº¿¿¿ÃÃÃÅÅÅÉÉÉÐÐШ¨¨ªªª°°°´´´¸¸¸¼¼¼¾¾¾¾¾¾ÀÀÀ»»»ºººÃÃÃÒÒÒÙÙÙÕÕÕÍÍÍÒÒÒÒÒÒÐÐÐÌÌÌÇÇÇÅÅÅÆÆÆÇÇÇ»»»¾¾¾³³³»»»ÑÑÑâââêêêãããäääàààæææààààààÂÂÂÀÀÀÍÍÍÍÍÍÑÑÑÒÒÒÑÑÑÒÒÒØØØØØØÕÕÕ×××××××××ÕÕÕÔÔÔÕÕÕÙÙÙÜÜÜÍÍÍÌÌÌÅÅÅÇÇÇÆÆÆ¿¿¿ÇÇÇÊÊÊÌÌÌÅÅÅÆÆÆÑÑÑØØØÔÔÔÑÑÑÔÔÔÑÑÑÑÑÑ×××ÒÒÒÃÃø¸¸¼¼¼ÅÅÅ»»»µµµ°°°¯¯¯¯¯¯···ÀÀÀºººººº¼¼¼¿¿¿ÃÃÃÅÅÅÅÅÅÅÅÅÐÐÐÍÍÍÕÕÕÉÉÉÌÌÌÐÐÐâââÝÝÝßßßÜÜÜÝÝÝàààßßßÜÜÜÝÝÝãããâââÝÝÝäääóóóÿÿÿøøøòòòóóóïïïóóóÿÿÿüüüäääÑÑÑÉÉÉÂÂÂÎÎÎÐÐÐÐÐÐÎÎÎÑÑÑÕÕÕÒÒÒÌÌÌÔÔÔÍÍÍÉÉÉÆÆÆÅÅÅÊÊÊÒÒÒÔÔÔÙÙÙØØØÙÙÙÛÛÛÛÛÛ×××ÒÒÒÒÒÒÇÇÇÆÆÆÆÆÆÃÃÃÂÂÂÃÃÃÅÅÅÇÇÇÅÅÅÊÊÊÎÎÎÎÎεµµ´´´»»»äääàààæææñññóóóñññíííçççòòòøøøäääâââÝÝÝÕÕÕßßßÑÑÑÒÒÒÒÒÒÛÛÛÌÌÌ»»»ÔÔÔÇÇÇÆÆÆÒÒÒÛÛÛßßßÜÜÜÛÛÛÜÜÜÙÙÙÔÔÔÕÕÕÉÉÉ»»»···ººº¾¾¾¿¿¿¿¿¿ÃÃô´´°°°µµµ¼¼¼ÅÅÅÇÇÇ¿¿¿¿¿¿¿¿¿¿¿¿¾¾¾¼¼¼»»»ººº¸¸¸ººº¼¼¼¼¼¼»»»»»»¿¿¿¾¾¾¸¸¸ÍÍÍÊÊÊÉÉÉÌÌÌÌÌÌÉÉÉÉÉÉÉÉÉÅÅÅÜÜÜÒÒÒÙÙÙ××צ¦¦···¾¾¾»»»¸¸¸»»»ÀÀÀÃÃÃÃÃÃÅÅÅÉÉɬ¬¬···¿¿¿¼¼¼¾¾¾ÂÂÂÅÅÅÃÃÃÃÃúºº³³³¼¼¼ÐÐÐÜÜÜÜÜÜÕÕÕÎÎÎÐÐÐÑÑÑÑÑÑÍÍÍÊÊÊÉÉÉÉÉÉÆÆÆÇÇǾ¾¾¼¼¼ºººÂÂÂÛÛÛâââêêêääääääÜÜÜßßßÆÆÆÃÃÃÊÊÊÍÍÍÒÒÒÔÔÔÎÎÎÌÌÌÒÒÒÙÙÙÛÛÛÙÙÙÙÙÙØØØÕÕÕÔÔÔÕÕÕÛÛÛßßßÑÑÑÎÎÎÆÆÆÇÇÇÆÆÆÀÀÀÉÉÉÌÌÌÌÌÌÃÃÃÅÅÅÑÑÑØØØÔÔÔÑÑÑÔÔÔÍÍÍÑÑÑÙÙÙÝÝÝÐÐкºº···ÃÃþ¾¾¼¼¼¾¾¾ÀÀÀ¼¼¼´´´³³³µµµµµµ´´´´´´···»»»¼¼¼»»»ºººÊÊÊÉÉÉ×××ÎÎÎÊÊÊÉÉÉâââëëëèèèæææääääääàààÛÛÛÛÛÛßßßÝÝÝàààíííöööóóóëëëïïïúúúÿÿÿóóóïïïäääÍÍÍÂÂÂÌÌÌÒÒÒÔÔÔÑÑÑÎÎÎÌÌÌÑÑÑØØØ×××ÑÑÑÔÔÔÎÎÎÒÒÒÔÔÔÌÌÌÎÎÎÔÔÔÑÑÑßßßÕÕÕÐÐÐÔÔÔ×××ÕÕÕÔÔÔÔÔÔÕÕÕÒÒÒÒÒÒÐÐÐÐÐÐÑÑÑÌÌÌÌÌÌÊÊÊÅÅÅÃÃÃÇÇÇÊÊÊÆÆÆÀÀÀ¿¿¿ººº³³³ÀÀÀØØØäääëëëíííæææëëëöööæææãããÜÜÜ×××êêêæææÔÔÔÑÑÑÜÜÜÐÐм¼¼ÔÔÔÌÌÌ×××âââßßßÜÜÜÝÝÝÝÝÝÜÜÜÙÙÙ×××ÑÑÑ¿¿¿···¾¾¾ÀÀÀ»»»¾¾¾ÇÇÇÅÅŵµµ±±±µµµ»»»ÆÆÆÊÊÊÀÀÀ¾¾¾¾¾¾¾¾¾¾¾¾¼¼¼ººº¸¸¸···´´´¸¸¸ºººººº¾¾¾Â¾¾¾···ÔÔÔÎÎÎÍÍÍÐÐÐÌÌÌÃÃÃÀÀÀÃÃÃÅÅÅÕÕÕÎÎÎÒÒÒÕÕÕ¨¨¨¯¯¯µµµ»»»ººº¼¼¼ÂÂÂÃÃÃÂÂÂÂÂÂÅÅű±±¼¼¼ÂÂÂÂÂÂÌÌÌÜÜÜãããÝÝÝÆÆÆÃÃþ¾¾···³³³ºººÉÉÉÕÕÕäääÛÛÛÑÑÑÌÌÌÌÌÌÌÌÌÉÉÉÆÆÆÌÌÌÆÆÆÃÃÃÇÇǾ¾¾¸¸¸ÀÀÀ···ººº¸¸¸¾¾¾»»»ÆÆÆ»»»ÃÃÃÑÑÑÒÒÒ×××ÒÒÒÒÒÒÛÛÛÙÙÙÕÕÕÙÙÙØØØßßßÒÒÒÑÑÑ××××××ÛÛÛÙÙÙÒÒÒÐÐÐÇÇÇÅÅÅÇÇÇÃÃÃÂÂÂÌÌÌÍÍÍÀÀÀÃÃÃÑÑÑÔÔÔÒÒÒÒÒÒÒÒÒÎÎÎÐÐÐÙÙÙÜÜÜÐÐÐÅÅž¾¾±±±ÅÅÅÃÃÃÂÂÂÂÂÂÀÀÀ¼¼¼´´´¯¯¯°°°³³³ÅÅÅÑÑÑÅÅźºº¸¸¸µµµÀÀÀÇÇÇÊÊÊÉÉÉÇÇÇÊÊÊÊÊÊÇÇÇÌÌÌÍÍÍèèèÜÜÜããããããÜÜÜÝÝÝÜÜÜàààíííïïïîîîöööÿÿÿöööüüüãããÉÉÉÊÊÊÔÔÔÑÑÑÒÒÒÔÔÔÑÑÑÔÔÔÎÎÎÕÕÕÙÙÙÔÔÔ×××ÔÔÔÍÍÍÐÐÐÑÑÑÐÐÐÍÍÍÍÍÍÒÒÒØØØÛÛÛØØØ××××××ÔÔÔÑÑÑ×××àààßßßÜÜÜ×××ÑÑÑÎÎÎÍÍÍÐÐÐÒÒÒÑÑÑÕÕÕÉÉÉÎÎÎÔÔÔÑÑÑÐÐл»»¿¿¿ºººÆÆÆ¿¿¿¿¿¿ÜÜÜîîîöööïïïñññóóóëëëÜÜÜàààæææßßß×××ÎÎÎÔÔÔÑÑÑÆÆÆÐÐÐÑÑÑ¿¿¿ãããàààßßßààààààßßßÛÛÛØØØÇÇÇ¿¿¿ºººººº»»»»»»¾¾¾ÂÂÂÂÂÂÃÃꪪªªª¾¾¾¿¿¿ÀÀÀÅÅÅ¿¿¿¾¾¾¼¼¼»»»ººº¸¸¸¸¸¸¸¸¸ºººººº¾¾¾ÃÃõµµ»»»···ÊÊÊÃÃÃÌÌÌÐÐÐÌÌÌÇÇÇÆÆÆÅÅÅÂÂÂÂÂÂÇÇÇÐÐÐÍÍÍÑÑÑÉÉɱ±±¯¯¯¼¼¼······ÅÅž¾¾¼¼¼ÌÌ̼¼¼±±±´´´¾¾¾ÎÎÎÑÑÑâââÙÙÙâââÝÝÝÍÍÍÆÆƸ¸¸···»»»ºººÙÙÙØØØÔÔÔÍÍÍÍÍÍÎÎÎÊÊÊÃÃÃÌÌÌÌÌÌÌÌÌÊÊÊÇÇÇÃÃÿ¿¿¼¼¼ººº»»»¼¼¼¾¾¾ÀÀÀÅÅÅÊÊÊÐÐÐÕÕÕØØØÔÔÔÔÔÔÛÛÛÛÛÛÙÙÙßßßÝÝÝëëëâââÜÜÜßßßÝÝÝÙÙÙÍÍÍÒÒÒÐÐÐÇÇÇÃÃÃÆÆÆÂÂÂÂÂÂÌÌÌÍÍÍÂÂÂÆÆÆÔÔÔÔÔÔÑÑÑÒÒÒÑÑÑÌÌÌÉÉÉÑÑÑØØØÔÔÔÑÑÑÉÉÉ»»»¼¼¼»»»»»»¾¾¾ÀÀÀÃÃÃÂÂÂÀÀÀÇÇÇÅÅÅÊÊÊÐÐÐÇÇÇÂÂÂÀÀÀºººÅÅÅÊÊÊÌÌÌÉÉÉÇÇÇÊÊÊÌÌÌÊÊÊÌÌÌÎÎÎëëëßßßæææäääÜÜÜÝÝÝãããæææîîîñññíííòòòöööñññÜÜÜÔÔÔÉÉÉÉÉÉÐÐÐÔÔÔ×××ÕÕÕÑÑÑÙÙÙÔÔÔ×××ØØØÛÛÛÝÝÝÔÔÔÕÕÕÔÔÔÑÑÑÐÐÐÑÑÑÕÕÕÛÛÛÝÝÝõõõæææØØØ××××××ÐÐÐÆÆÆ¿¿¿¿¿¿¿¿¿¾¾¾ººººººÃÃÃÕÕÕäääÒÒÒÝÝÝ×××ÔÔÔÌÌÌÇÇÇÐÐÐÍÍÍÆÆÆÅÅÅÉÉɾ¾¾¼¼¼ÊÊÊ×××íííóóóïïïùùùùùùæææÝÝÝßßßØØØçççØØØÙÙÙ×××ÊÊÊÒÒÒÜÜÜÒÒÒÛÛÛßßßßßßÛÛÛÙÙÙÜÜÜÜÜÜ××׿¿¿ººº¸¸¸»»»¼¼¼¼¼¼¿¿¿ÅÅÅÃÃÃÅÅŬ¬¬¾¾¾¾¾¾¼¼¼¾¾¾ÂÂÂÀÀÀ¾¾¾»»»¸¸¸·········¸¸¸ººº¼¼¼ÀÀÀ···Â¼¼¼ÊÊÊÆÆÆÍÍÍÐÐÐÊÊÊÆÆÆÆÆÆÆÆÆÅÅÅÇÇÇÂÂÂÌÌÌÎÎÎÐÐÐÎÎμ¼¼´´´ººº¸¸¸ºººÂ¿¿¿ÅÅÅÌÌÌ´´´´´´´´´¸¸¸ÂÂÂÆÆÆÛÛÛÕÕÕÝÝÝâââÎÎÎÃÃÿ¿¿¿¿¿ÀÀÀ¼¼¼ÇÇÇÑÑÑÕÕÕÑÑÑÊÊÊÉÉÉÊÊÊÉÉÉÉÉÉÊÊÊÌÌÌÌÌÌÊÊÊÆÆÆ¿¿¿ÂÂÂÂÂÂÂÂÂÃÃÃÇÇÇÌÌÌÑÑÑÔÔÔÕÕÕÛÛÛÛÛÛÛÛÛÝÝÝÜÜÜØØØÙÙÙÔÔÔàààÐÐÐÅÅÅÌÌÌ×××ÙÙÙÎÎÎÔÔÔÐÐÐÆÆÆÂÂÂÃÃÃÀÀÀÀÀÀÊÊÊÊÊÊÃÃÃÊÊÊÕÕÕÔÔÔÐÐÐÐÐÐÎÎÎÌÌÌÇÇÇÌÌÌÔÔÔÙÙÙÙÙÙÎÎο¿¿ÀÀÀ¾¾¾¼¼¼¼¼¼¿¿¿ÂÂÂÃÃÃÅÅÅÐÐÐÊÊÊÉÉÉÉÉÉÉÉÉÌÌÌÆÆÆ»»»ÆÆÆÊÊÊÌÌÌÊÊÊÉÉÉÌÌÌÍÍÍÍÍÍÍÍÍÑÑÑîîîâââçççäääÜÜÜÝÝÝäääçççîîîñññîîîñññóóóïïïÃÃÃÊÊÊÎÎÎÌÌÌÎÎÎØØØÛÛÛ×××ÒÒÒßßßØØØÙÙÙØØØßßßàààÒÒÒ×××ÔÔÔÑÑÑÑÑÑÕÕÕØØØÛÛÛÛÛÛÃÃÃÇÇÇÉÉÉÆÆƼ¼¼ºººÃÃÃÐÐÐâââäääæææààà×××ÍÍÍÉÉÉÇÇÇÌÌÌ×××ØØØÙÙÙÔÔÔÐÐÐÕÕÕÒÒÒÎÎÎÐÐÐÌÌÌ¿¿¿¼¼¼ÃÃÃäääöööîîîõõõùùùèèèßßßãããäääàààÑÑÑ×××ÜÜÜÎÎÎÐÐÐÜÜÜ×××ÐÐÐÜÜÜàààÛÛÛÙÙÙÝÝÝÛÛÛÑÑѺºº···¸¸¸»»»¼¼¼»»»¿¿¿ÅÅÅÅÅÅÅÅů¯¯°°°¿¿¿¿¿¿¿¿¿¾¾¾ÂÂÂÀÀÀ¾¾¾ººº¸¸¸µµµµµµµµµ»»»¼¼¼¼¼¼¾¾¾¸¸¸ÉÉÉÀÀÀÆÆÆÉÉÉÍÍÍÎÎÎÊÊÊÅÅÅÆÆÆÇÇÇÉÉÉÇÇÇ»»»ÉÉÉÒÒÒÑÑÑÐÐо¾¾¬¬¬¸¸¸ººº¼¼¼ÂÂÂÂÂÂÉÉÉÇÇǬ¬¬°°°³³³´´´¼¼¼ÂÂÂßßßÛÛÛßßßâââÔÔÔÍÍÍÊÊÊÆÆÆÃÃÃÃÃÃÀÀÀºººÊÊÊØØØÕÕÕÊÊÊÅÅÅÇÇÇÍÍÍÇÇÇÉÉÉÌÌÌÍÍÍÌÌÌÊÊÊÇÇÇÅÅÅÃÃÃÂÂÂÂÂÂÃÃÃÇÇÇÍÍÍÑÑÑÔÔÔÜÜÜßßßÝÝÝÙÙÙØØØØØØ×××ÕÕÕâââäääÌÌÌ¿¿¿ÉÉÉÒÒÒÜÜÜ×××ÒÒÒÐÐÐÅÅÅÀÀÀ¿¿¿¿¿¿ÉÉÉÇÇÇÅÅÅÎÎÎØØØÒÒÒÍÍÍÍÍÍÌÌÌÎÎÎÍÍÍÐÐÐ×××ÙÙÙÕÕÕÉÉÉ»»»ÆÆÆÃÃÿ¿¿¼¼¼¼¼¼¾¾¾¿¿¿ÀÀÀÆÆÆÆÆÆÅÅÅÂÂÂÅÅÅÇÇÇ¿¿¿±±±ÀÀÀÅÅÅÉÉÉÌÌÌÌÌÌÍÍÍÎÎÎÎÎÎÐÐÐÒÒÒïïïâââäääãããÜÜÜßßßßßßãããèèèîîîñññóóóõõõóóóÌÌÌÊÊÊÔÔÔÒÒÒÐÐÐÙÙÙØØØÕÕÕ×××àààßßßêêêãããêêêêêêàààëëëêêêäääÝÝÝÕÕÕÍÍÍÇÇÇÃÃÃÉÉÉÆÆÆÆÆÆÌÌÌÔÔÔØØØØØØ×××ÂÂÂÀÀÀÅÅÅÎÎÎÙÙÙââââââßßßÐÐÐÍÍÍÉÉÉÐÐÐÙÙÙÛÛÛÕÕÕÊÊÊÑÑÑÐÐÐÍÍÍÍÍÍÌÌÌ¿¿¿ÂÂÂÜÜÜîîîñññõõõóóóíííääääääííí×××ÌÌÌÐÐÐÛÛÛÎÎÎÉÉÉÙÙÙÙÙÙÍÍÍÕÕÕÛÛÛÝÝÝßßßÝÝÝÒÒÒÆÆÆ»»»ºººººº»»»¸¸¸···»»»ÂÂÂÃÃÃÃÃð°°±±±¾¾¾¿¿¿Â¾¾¾¼¼¼»»»¸¸¸······µµµ···¾¾¾ÀÀÀ¼¼¼»»»¸¸¸ÎÎÎÃÃÃÂÂÂÉÉÉÍÍÍÐÐÐÍÍÍÉÉÉÆÆÆÇÇÇÊÊÊÊÊʼ¼¼ÅÅÅÊÊÊÍÍÍÉÉɵµµ¨¨¨ºººººº¿¿¿ÃÃÿ¿¿ÀÀÀ¼¼¼ªªªªªª°°°´´´»»»ÃÃÃàààÙÙÙ×××ÜÜÜÛÛÛÛÛÛØØØÍÍÍÃÃÃÃÃÃÇÇÇ»»»ÇÇÇÔÔÔÕÕÕÐÐÐÌÌÌÊÊÊÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÌÌÌÊÊÊÊÊÊÆÆÆÅÅÅÅÅÅÆÆÆÊÊÊÎÎÎÒÒÒÕÕÕâââàààÜÜÜÔÔÔÑÑÑ×××ÜÜÜÙÙÙÜÜÜÜÜÜÍÍÍÑÑÑÜÜÜÛÛÛÝÝÝÜÜÜÒÒÒÎÎÎÅÅÅÀÀÀ¾¾¾¾¾¾ÇÇÇÆÆÆÆÆÆÑÑÑØØØÒÒÒÍÍÍÎÎÎÌÌÌÍÍÍÒÒÒ×××ÙÙÙØØØÍÍÍ¿¿¿¸¸¸¿¿¿¿¿¿¾¾¾¾¾¾¾¾¾¿¿¿ÂÂÂÃÃÃÅÅÅÉÉÉÆÆÆÀÀÀÀÀÀÀÀÀ»»»³³³µµµ»»»ÅÅÅÌÌÌÎÎÎÎÎÎÎÎÎÐÐÐÒÒÒÒÒÒëëëÜÜÜàààâââÜÜÜàààÜÜÜßßßäääëëëñññóóóóóóõõõàààÉÉÉÎÎÎÒÒÒÑÑÑ×××ÒÒÒÕÕÕÝÝÝßßßÙÙÙèèèÑÑÑÉÉÉÃÃþ¾¾ÂÂÂÅÅÅÆÆÆÃÃÿ¿¿¾¾¾ÂÂÂÆÆÆÉÉÉÌÌÌÎÎÎÒÒÒ×××ÔÔÔÊÊÊÂÂÂßßßÕÕÕÌÌÌÉÉÉÍÍÍÐÐÐÎÎÎÌÌÌçççÛÛÛÐÐÐÎÎÎÔÔÔÙÙÙ×××ÔÔÔÎÎÎÌÌÌÌÌÌÕÕÕÔÔÔÇÇÇÆÆÆÐÐÐÜÜÜöööúúúõõõöööêêêÛÛÛâââãããÛÛÛÑÑÑ×××ÎÎÎÆÆÆÙÙÙãããÕÕÕÍÍÍÌÌÌÔÔÔÙÙÙÒÒÒÅÅż¼¼¾¾¾ººº¸¸¸¸¸¸···µµµ¼¼¼ÃÃÃÂÂÂÀÀÀ°°°¯¯¯µµµµµµ»»»»»»···············¸¸¸¸¸¸¸¸¸»»»¾¾¾»»»ººººººÑÑÑÇÇÇÃÃÃÇÇÇÌÌÌÐÐÐÑÑÑÎÎÎÉÉÉÇÇÇÉÉÉÎÎÎÅÅÅÃÃÃÃÃÃÉÉÉÅÅű±±³³³¾¾¾¸¸¸ÀÀÀÅÅž¾¾µµµ°°°¯¯¯±±±³³³¸¸¸¿¿¿ÛÛÛÒÒÒÐÐÐØØØÛÛÛÝÝÝßßßØØØÍÍÍÇÇÇÌÌÌÃÃÃÃÃÃÉÉÉÑÑÑØØØØØØÒÒÒÎÎÎÒÒÒÑÑÑÎÎÎÍÍÍÌÌÌÍÍÍÍÍÍÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÒÒÒ×××ÛÛÛÝÝÝÜÜÜÝÝÝàààßßßÝÝÝãããâââÕÕÕÊÊÊÍÍÍÆÆÆÔÔÔàààÛÛÛÙÙÙÛÛÛÐÐÐÍÍÍÅÅÅÀÀÀ¼¼¼»»»ÃÃÃÊÊÊÊÊÊÕÕÕÛÛÛÕÕÕÒÒÒÒÒÒÎÎÎÌÌÌÕÕÕÛÛÛÛÛÛ×××ÉÉɾ¾¾»»»¾¾¾¿¿¿ÀÀÀÀÀÀ¿¿¿ÀÀÀÂÂÂÅÅÅÅÅÅÉÉÉÆÆÆÀÀÀÃÃÃÅÅÅÅÅÅÆÆƯ¯¯µµµÀÀÀÌÌÌÐÐÐÎÎÎÎÎÎÐÐÐÒÒÒÐÐÐæææ×××ÝÝÝàààÜÜÜßßßÝÝÝàààâââèèèññññññîîîñññêêêÀÀÀÂÂÂÍÍÍÐÐÐÔÔÔÎÎÎØØØààààààÝÝÝóóóÕÕÕÍÍÍÌÌÌÍÍÍÑÑÑÐÐÐÌÌÌÆÆÆÀÀÀÃÃÃÊÊÊÑÑÑÍÍÍØØØÝÝÝØØØÐÐÐÍÍÍÒÒÒ×××ÍÍÍÐÐÐÔÔÔ×××ØØØØØØÙÙÙÛÛÛÐÐÐÍÍÍÐÐÐÊÊÊÃÃÃÃÃÃÆÆÆÑÑÑÌÌÌÐÐÐÍÍÍÔÔÔÔÔÔÌÌÌÉÉÉÅÅÅÍÍÍíííöööñññöööíííßßßäääçççëëë×××ØØØ×××ÅÅÅÎÎÎÛÛÛÝÝÝÊÊÊ¿¿¿ÅÅÅÌÌÌÅÅż¼¼»»»¾¾¾¸¸¸µµµ···¸¸¸ºººÀÀÀÇÇÇÃÃÃÃÃô´´°°°¨¨¨¯¯¯°°°³³³µµµ¸¸¸¸¸¸¸¸¸¸¸¸µµµ¸¸¸¸¸¸¸¸¸¸¸¸ÑÑÑÉÉÉÉÉÉÆÆÆÊÊÊÑÑÑ×××ÒÒÒÊÊÊÇÇÇÉÉÉÅÅÅÇÇÇÎÎÎÑÑÑÕÕÕÇÇÇ°°°···ÀÀÀ¸¸¸ÀÀÀÅÅÅ¿¿¿´´´¬¬¬³³³³³³´´´´´´»»»ÀÀÀÝÝÝÛÛÛàààØØØ×××ÔÔÔÛÛÛãããÜÜÜÐÐÐÌÌÌÇÇÇÀÀÀ¿¿¿ÉÉÉ×××ÛÛÛÙÙÙÕÕÕ×××ÕÕÕÑÑÑÎÎÎÍÍÍÎÎÎÎÎÎÐÐÐÎÎÎÐÐÐÑÑÑÑÑÑÒÒÒÕÕÕÛÛÛßßßãããäääëëëíííêêêîîîæææÑÑÑÔÔÔÙÙÙÑÑÑÕÕÕÜÜÜÕÕÕÔÔÔÒÒÒÎÎÎÍÍÍÅÅÅÂÂÂÃÃü¼¼ºººÀÀÀÐÐÐÐÐÐÙÙÙßßßÛÛÛÙÙÙÛÛÛÔÔÔÑÑÑÙÙÙÛÛÛØØØÕÕÕÊÊÊ¿¿¿¿¿¿ÃÃÃÅÅÅÅÅÅÃÃÃÀÀÀÀÀÀÂÂÂÅÅÅÆÆÆÆÆÆÂÂÂÂÂÂÉÉÉÆÆÆÀÀÀÆÆƯ¯¯´´´¿¿¿ÌÌÌÐÐÐÎÎÎÎÎÎÑÑÑÐÐÐÌÌÌàààÒÒÒÜÜÜàààÛÛÛÛÛÛÝÝÝààààààçççñññîîîèèèîîîèè躺º¿¿¿ÌÌÌÎÎÎÕÕÕÐÐÐÛÛÛßßßãããßßßïïïÉÉÉÇÇÇÊÊÊÎÎÎæææßßßÕÕÕÎÎÎÌÌÌÌÌÌÊÊÊÊÊÊßßß×××ÌÌÌÉÉÉÎÎÎ×××ÒÒÒÉÉÉÅÅÅÆÆÆÉÉÉÊÊÊÉÉÉÉÉÉÌÌÌÎÎÎÐÐÐÎÎÎÛÛÛÙÙÙÕÕÕÔÔÔÐÐÐÛÛÛÇÇÇÝÝÝÔÔÔÍÍÍÒÒÒÎÎÎÎÎÎÌÌÌÅÅÅÙÙÙëëëññññññêêêçççêêêâââóóóØØØ×××ßßßÆÆÆÅÅÅÒÒÒÝÝÝÐÐÐÅÅÅÃÃÃÅÅÅÀÀÀ¿¿¿¿¿¿ÀÀÀ»»»···ººº¼¼¼¼¼¼ÀÀÀÅÅÅÅÅÅÇÇǾ¾¾¸¸¸¯¯¯¥¥¥ªªª¨¨¨¨¨¨¬¬¬±±±µµµ¸¸¸¸¸¸···µµµµµµ¸¸¸ººº»»»···ÊÊÊÃÃÃÇÇÇÆÆÆÊÊÊÒÒÒØØØÔÔÔÌÌÌÇÇÇÊÊÊÀÀÀÆÆÆÛÛÛààà××ׯ¯¯µµµÂ¸¸¸¿¿¿ÂÂÂÃÃÿ¿¿°°°³³³´´´´´´µµµ¿¿¿ÃÃÃÛÛÛØØØâââÝÝÝØØØÐÐÐ×××äääàààÑÑÑÌÌÌÊÊÊÃÃÃÀÀÀÃÃÃÉÉÉÍÍÍÒÒÒÙÙÙÕÕÕÕÕÕÔÔÔÒÒÒÒÒÒÑÑÑÑÑÑÐÐÐÍÍÍÐÐÐÒÒÒÑÑÑÐÐÐÑÑÑÙÙÙßßßúúúõõõñññêêêæææîîîëëëØØØÍÍÍÙÙÙÔÔÔÕÕÕÛÛÛ×××ÕÕÕÎÎÎÍÍÍÌÌÌÅÅÅÂÂÂÃÃü¼¼¸¸¸¿¿¿ÔÔÔÔÔÔÜÜÜâââßßßßßßàààÙÙÙÙÙÙÝÝÝÙÙÙÕÕÕ×××ÍÍÍÀÀÀÀÀÀÅÅÅÆÆÆÆÆÆÃÃÃÂÂÂÃÃÃÇÇÇÌÌÌÌÌÌÉÉÉÂÂÂÅÅÅÊÊʼ¼¼¬¬¬¬¬¬³³³µµµ¿¿¿ÌÌÌÐÐÐÍÍÍÎÎÎÔÔÔÌÌÌÇÇÇÝÝÝÑÑÑÜÜÜàààØØØØØØÛÛÛÝÝÝÝÝÝäääñññîîîèèèïïïççç»»»ÅÅÅÎÎÎÐÐÐØØØÒÒÒÜÜÜÝÝÝçççâââëëëÀÀÀÇÇÇÐÐÐÑÑÑçççßßßÙÙÙÛÛÛââââââÛÛÛÑÑÑÅÅÅÐÐÐÕÕÕÒÒÒÍÍÍÊÊÊÇÇÇÂÂÂßßßÜÜÜÛÛÛÝÝÝâââãããàààÜÜÜÛÛÛÊÊÊÊÊÊÊÊÊÒÒÒ×××ÉÉÉÊÊÊÆÆÆëëëÙÙÙÉÉÉÒÒÒÔÔÔ×××ÙÙÙÂÂÂÍÍÍëëëÿÿÿõõõæææâââÝÝÝäääüüü×××ÐÐÐàààÊÊÊÊÊÊÝÝÝØØØ×××ÒÒÒÌÌÌÇÇÇÆÆÆÅÅÅÃÃÃÅÅž¾¾»»»¼¼¼¿¿¿¼¼¼¼¼¼¿¿¿ÅÅÅÊÊÊÆÆÆÃÃõµµªªª¯¯¯¬¬¬¥¥¥©©©°°°µµµ¸¸¸···´´´³³³ººº¼¼¼¼¼¼¼¼¼´´´Â»»»ÃÃÃÇÇÇÊÊÊÑÑÑØØØÕÕÕÌÌÌÉÉÉÌÌÌÌÌÌÉÉÉÜÜÜÜÜÜÅÅÅ´´´°°°¸¸¸ÀÀÀººº¿¿¿¿¿¿ÇÇÇÍÍÍ···°°°³³³±±±´´´¾¾¾¼¼¼ÉÉÉ¿¿¿ÇÇÇãããßßßÕÕÕ×××ßßßÙÙÙÍÍÍÍÍÍÍÍÍÉÉÉÆÆƼ¼¼¼¼¼ÉÉÉØØØÒÒÒÔÔÔÕÕÕ×××ÕÕÕÔÔÔÑÑÑÐÐÐÐÐÐÕÕÕÙÙÙ×××ÔÔÔÕÕÕÝÝÝæææèèèíííäääÛÛÛñññøøøæææèèèÊÊÊÔÔÔßßßàààÙÙÙÑÑÑÌÌÌÊÊÊÐÐÐÍÍÍ¿¿¿ÌÌÌÀÀÀ»»»¼¼¼ÅÅÅÒÒÒÙÙÙßßßÝÝÝÜÜÜÝÝÝÜÜÜØØØÙÙÙÔÔÔÒÒÒÔÔÔÌÌ̾¾¾ºººÀÀÀÃÃÃÆÆÆÅÅÅÂÂÂÀÀÀÀÀÀ»»»±±±°°°±±±¼¼¼ÇÇÇ¿¿¿©©©°°°···ºººÀÀÀÉÉÉÎÎÎÑÑÑÎÎÎÌÌÌÇÇÇÌÌÌÕÕÕÝÝÝÝÝÝØØØÙÙÙâââßßßÝÝÝßßßöööñññèèèÿÿÿîîîßßßÆÆƺººÊÊÊÇÇÇÕÕÕÔÔÔ×××ÛÛÛààààààäääÒÒÒ¿¿¿ÌÌÌÔÔÔÜÜÜÐÐÐÐÐÐÆÆÆÃÃÃÉÉÉÉÉÉØØØÉÉÉÍÍÍÌÌ̾¾¾ÆÆÆÒÒÒÛÛÛÒÒÒÒÒÒÔÔÔÕÕÕ×××ØØØÙÙÙÙÙÙÙÙÙ×××ØØØÙÙÙÒÒÒÉÉÉÍÍÍÙÙÙÎÎÎÉÉÉÛÛÛÙÙÙØØØÑÑÑÛÛÛÑÑÑÎÎλ»»õõõøøøòòòõõõêêêãããëëëîîîÝÝÝØØØâââÐÐÐÆÆÆßßßßßß×××ÎÎÎÊÊÊÊÊÊÌÌÌÊÊÊÇÇÇÃÃÿ¿¿¼¼¼»»»»»»¼¼¼¼¼¼ÂÂÂÉÉÉ»»»»»»³³³ªªª¦¦¦¢¢¢¦¦¦´´´¼¼¼ºººµµµ´´´µµµººº¼¼¼»»»»»»¿¿¿ÀÀÀ¿¿¿ÉÉÉÐÐÐÎÎÎÔÔÔÇÇÇÌÌÌÉÉÉÐÐÐÊÊÊÆÆÆÕÕÕÝÝÝÐÐЬ¬¬···»»»¼¼¼¼¼¼ººº¾¾¾ÎÎÎÙÙÙÉÉɳ³³±±±···¿¿¿ÃÃÃÂÂÂÃÃÃÉÉÉÉÉÉÑÑÑÔÔÔÒÒÒØØØÝÝÝ×××ÉÉÉÉÉÉÒÒÒÐÐÐÇÇÇÇÇÇÇÇÇÆÆÆÊÊÊÕÕÕÒÒÒÙÙÙ×××ÕÕÕØØØÑÑÑÕÕÕÙÙÙÛÛÛÛÛÛÙÙÙÙÙÙßßßêêêóóóâââèèèëëëãããçççêêêàààëëëçççâââÙÙÙÔÔÔÑÑÑÎÎÎÌÌÌÉÉÉÎÎÎÊÊʺººÇÇǾ¾¾¿¿¿ÅÅÅÎÎÎÐÐÐØØØÝÝÝÜÜÜÙÙÙÙÙÙØØØÕÕÕÒÒÒÍÍÍÎÎÎÒÒÒÌÌÌ¿¿¿»»»¿¿¿¿¿¿ÃÃÃÅÅÅÂÂÂÀÀÀ¾¾¾···´´´±±±±±±³³³¨¨¨¸¸¸ººº¼¼¼ÂÂÂÉÉÉÎÎÎÐÐÐÍÍÍÊÊÊÉÉÉÉÉÉÍÍÍÕÕÕÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜàààâââõõõïïïíííÿÿÿîîîêêê×××¾¾¾ÆÆÆÃÃÃÐÐÐÔÔÔØØØÜÜÜàààßßßààà×××ÅÅÅÇÇÇÑÑÑÑÑÑÐÐÐ×××ÙÙÙ×××ÔÔÔÐÐÐÔÔÔÃÃÃÐÐÐÛÛÛÛÛÛ×××ÔÔÔÑÑÑÍÍÍÌÌÌÌÌÌÌÌÌÍÍÍÎÎÎÐÐÐÐÐÐÑÑÑÍÍÍÉÉÉÊÊÊÑÑÑÐÐÐÇÇÇÆÆÆÍÍÍÑÑÑßßßÑÑÑÅÅÅçççÜÜÜÍÍÍÙÙÙÔÔÔ¾¾¾ÝÝÝîîîõõõòòòïïïæææîîîèèèÛÛÛØØØàààÕÕÕÊÊÊÒÒÒÛÛÛÕÕÕÒÒÒÔÔÔ×××ÔÔÔÌÌÌÃÃÃÆÆÆÅÅÅ¿¿¿¼¼¼¼¼¼¼¼¼¼¼¼ÂÂÂÅÅÅÆÆÆÆÆÆÃÃþ¾¾¾¾¾ÆÆƸ¸¸°°°°°°µµµººº»»»¼¼¼»»»µµµ³³³¸¸¸¿¿¿ÀÀÀÂÂÂÃÃÃÙÙÙÙÙÙÑÑÑ×××ÍÍÍÒÒÒÊÊÊÊÊÊÌÌÌÍÍÍÝÝÝäääÒÒÒ¬¬¬¸¸¸¾¾¾¸¸¸¾¾¾¿¿¿¿¿¿ÆÆÆÐÐÐÒÒÒÎÎÎÃÃÃÀÀÀººº±±±³³³¼¼¼ÀÀÀ¾¾¾ÐÐÐÕÕÕ×××ÕÕÕÙÙÙàààÜÜÜÑÑÑÑÑÑÝÝÝßßßÕÕÕÐÐÐÊÊÊÉÉÉÍÍÍîîîßßßØØØÐÐÐÔÔÔßßßÝÝÝâââãããêêêîîîëëëäääàààãããçççããããããëëëæææàààßßßÜÜÜçççàààÛÛÛÔÔÔÑÑÑÒÒÒÒÒÒÎÎÎÊÊÊÇÇÇÆÆƸ¸¸ÉÉÉÅÅÅÇÇÇÍÍÍÔÔÔÍÍÍ×××ÜÜÜÛÛÛ×××ÕÕÕÒÒÒÐÐÐÑÑÑÍÍÍÎÎÎÑÑÑÍÍÍÀÀÀ¼¼¼¿¿¿¼¼¼ÀÀÀÃÃÃÃÃÃÂÂÂÂÂÂÀÀÀ¾¾¾ªªª°°°±±±°°°°°°³³³´´´»»»¾¾¾ÂÂÂÇÇÇÍÍÍÍÍÍÊÊÊÇÇÇÊÊÊÇÇÇÆÆÆÌÌÌØØØâââàààÛÛÛÛÛÛàààãããòòòïïïïïïÿÿÿîîîîîîæææÀÀÀÅÅÅÅÅÅÍÍÍÕÕÕØØØÜÜÜÝÝÝÜÜÜÛÛÛÜÜÜÎÎÎÂÂÂÎÎÎÑÑÑÑÑÑÎÎÎÑÑÑÐÐÐÌÌÌÒÒÒÕÕÕÐÐÐÒÒÒÑÑÑÍÍÍÊÊÊÌÌÌÎÎÎÐÐÐÆÆÆÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÉÉÉÉÉÉÆÆÆ¿¿¿¿¿¿ÇÇÇÊÊÊÇÇÇÅÅÅÇÇÇÑÑÑÐÐÐÐÐÐÊÊÊÒÒÒÍÍÍÍÍÍÍÍÍÒÒÒÂÂÂÇÇÇäääùùùñññóóóæææîîîãããØØØØØØÝÝÝÜÜÜÑÑÑÇÇÇÜÜÜÙÙÙ×××××××××ÕÕÕÑÑÑÎÎÎÊÊÊÉÉÉÅÅÅ¿¿¿¾¾¾¾¾¾¾¾¾ÀÀÀ¿¿¿ÅÅÅÇÇÇÀÀÀ¼¼¼ÀÀÀÆÆÆ¿¿¿¸¸¸°°°±±±¸¸¸ººº···µµµ¸¸¸»»»¼¼¼¿¿¿ÀÀÀÀÀÀ¿¿¿ÇÇÇÐÐÐÐÐÐ×××ÌÌÌÎÎÎÊÊÊÐÐÐÍÍÍÑÑÑäääèèè××ׯ¯¯»»»ÅÅÅ»»»ÀÀÀÃÃÃÃÃÃÃÃÃÊÊÊØØØãããÕÕÕÒÒÒÉÉÉ»»»···¼¼¼ÂÂÂÂÂÂÐÐÐ×××ÙÙÙÛÛÛàààäääààà×××ãããçççãããàààãããÜÜÜÎÎÎÇÇÇæææÜÜÜßßßÜÜÜàààäääÜÜÜÜÜÜàààæææêêêæææÛÛÛÐÐÐÌÌÌÌÌÌïïïÝÝÝââââââÜÜÜÝÝÝÛÛÛÜÜÜÑÑÑÒÒÒÔÔÔÒÒÒÎÎÎÌÌÌÉÉÉÇÇÇÀÀÀÅÅž¾¾ÔÔÔÒÒÒÒÒÒÐÐÐÐÐÐÊÊÊÔÔÔÛÛÛØØØÔÔÔÑÑÑÐÐÐÍÍÍÔÔÔÐÐÐÎÎÎÐÐÐÊÊʼ¼¼¿¿¿¼¼¼ÀÀÀÅÅÅÃÃÃÂÂÂÀÀÀÀÀÀÀÀÀ¥¥¥¯¯¯¸¸¸»»»¿¿¿ÀÀÀ¼¼¼´´´ººº»»»¿¿¿ÆÆÆÊÊÊÌÌÌÉÉÉÆÆÆÉÉÉÇÇÇÃÃÃÆÆÆÒÒÒààààààÙÙÙÛÛÛÝÝÝâââòòòòòòîîîøøøïïïæææêêêÀÀÀÆÆÆÉÉÉÎÎÎÕÕÕÔÔÔØØØØØØØØØ×××ßßßÕÕÕ¿¿¿ÎÎÎÕÕÕÕÕÕÇÇÇÇÇÇÆÆÆÅÅÅÕÕÕØØØÎÎÎÌÌÌÇÇÇÃÃÃÂÂÂÅÅÅÉÉÉÊÊÊÊÊÊÊÊÊÉÉÉÉÉÉÇÇÇÇÇÇÇÇÇÆÆÆÊÊʾ¾¾ÀÀÀÅÅÅÆÆÆÉÉÉÎÎÎÅÅÅÎÎÎÎÎÎÍÍÍÙÙÙ×××ÔÔÔÜÜÜÎÎÎÇÇÇÂÂÂÙÙÙòòòòòòñññæææèèèäääÛÛÛ×××ÝÝÝâââØØØÌÌÌ×××ÙÙÙÛÛÛØØØÕÕÕÔÔÔ×××ÛÛÛÐÐÐÍÍÍÉÉÉÅÅÅÂÂÂÀÀÀ¿¿¿¿¿¿¾¾¾»»»ÂÂÂÃÃü¼¼¼¼¼¿¿¿···¬¬¬¬¬¬¬¬¬³³³¼¼¼»»»´´´¾¾¾ÐÐÐÒÒÒ¿¿¿±±±¸¸¸¼¼¼ººº···ÅÅÅÌÌÌÕÕÕÊÊÊÍÍÍÉÉÉÐÐÐÎÎÎÑÑÑßßßäääÙÙÙµµµ¿¿¿ÉÉÉÆÆÆÂÂÂÂÂÂÆÆÆÉÉÉÊÊÊÑÑÑÙÙÙÌÌÌÌÌÌÌÌÌÊÊʸ¸¸¸¸¸¿¿¿ÆÆÆÐÐÐÙÙÙßßßääääääÜÜÜÑÑÑççççççâââæææñññêêêÔÔÔÇÇÇÑÑÑÙÙÙîîîóóóóóóñññãããâââçççäääâââÝÝÝ×××ÑÑÑÌÌÌÇÇÇõõõÜÜÜÛÛÛÛÛÛØØØÜÜÜØØØÔÔÔÙÙÙÕÕÕÎÎÎÆÆÆÀÀÀ¿¿¿ÀÀÀÃÃÃÅÅÅÌÌÌÆÆÆÛÛÛÙÙÙÙÙÙÑÑÑÊÊÊÇÇÇÐÐÐ×××ÕÕÕÑÑÑÐÐÐÎÎÎÌÌÌÎÎÎÊÊÊÆÆÆÆÆÆÃÃÿ¿¿¿¿¿ÀÀÀÀÀÀÂÂÂÅÅÅÅÅÅ¿¿¿¿¿¿Âµµµ»»»»»»ÀÀÀÇÇÇÆÆÆÀÀÀ···¸¸¸¼¼¼ÂÂÂÇÇÇÊÊÊÉÉÉÇÇÇÉÉÉÉÉÉÇÇÇÆÆÆÎÎÎÛÛÛßßßÛÛÛÝÝÝÛÛÛâââóóóóóóíííñññïïïäääççç¿¿¿ÃÃÃÇÇÇÍÍÍÒÒÒÑÑÑÒÒÒÒÒÒÔÔÔÒÒÒÝÝÝÕÕÕÀÀÀÑÑÑÎÎÎØØØÔÔÔÙÙÙÙÙÙÔÔÔÛÛÛÕÕÕÊÊÊÉÉÉÇÇÇÉÉÉÊÊÊÊÊÊÊÊÊÊÊÊÍÍÍÍÍÍÌÌÌÊÊÊÉÉÉÇÇÇÆÆÆÅÅÅÆÆÆÃÃÃÂÂÂÂÂÂÂÂÂÂÂÂÉÉÉÐÐÐØØØÂÂÂÌÌÌØØØÌÌÌØØØãããÎÎÎÐÐÐÎÎÎÊÊÊÍÍÍßßßñññîîîëëëâââêêêààà×××ßßßâââÛÛÛÛÛÛÐÐÐÒÒÒ×××ÛÛÛÜÜÜÛÛÛ×××ÔÔÔÒÒÒÐÐÐÌÌÌÇÇÇÅÅÅÂÂÂÂÂÂÀÀÀ¿¿¿ÀÀÀÆÆÆÅÅÅÃÃÃÌÌÌÇÇDZ±±°°°³³³³³³³³³ºººÂ¼¼¼¸¸¸ÉÉÉÊÊʸ¸¸³³³ÀÀÀÐÐÐÒÒÒÉÉÉÌÌÌÆÆÆÑÑÑÌÌÌÒÒÒÉÉÉÇÇÇÍÍÍÌÌÌÔÔÔÜÜÜÜÜÜ»»»ÃÃÃÌÌÌÌÌÌÃÃÿ¿¿ÅÅÅÉÉÉÆÆÆÇÇÇÌÌÌÇÇÇÆÆÆÌÌÌÒÒÒÑÑÑÅÅÅ»»»¸¸¸¾¾¾ÆÆÆÑÑÑØØØÜÜÜÛÛÛÔÔÔÌÌÌ×××ÝÝÝàààèèèñññèèè×××ÐÐÐÀÀÀÉÉÉÜÜÜâââæææêêêæææëëëäääÝÝÝ××××××ÜÜÜÜÜÜÔÔÔÌÌÌîîîÜÜÜÜÜÜ×××ÐÐÐÔÔÔÒÒÒÒÒÒÒÒÒÌÌÌÃÃÃÀÀÀÆÆÆÌÌÌÎÎÎÎÎÎÒÒÒÕÕÕÉÉÉÙÙÙ×××ØØØÐÐÐÇÇÇÃÃÃÊÊÊÎÎÎÎÎÎÍÍÍÐÐÐÎÎÎÊÊÊÀÀÀ¼¼¼ºººººº¼¼¼¿¿¿ÂÂÂÅÅÅÅÅÅÃÃÃÅÅÅÆÆÆÃÃÿ¿¿¿¿¿ÀÀÀ¯¯¯µµµººº»»»ÀÀÀÇÇÇÇÇÇÃÃ÷··¸¸¸¼¼¼ÂÂÂÇÇÇÊÊÊÉÉÉÇÇÇÉÉÉÉÉÉÊÊÊÌÌÌÑÑÑÙÙÙÝÝÝÝÝÝßßßßßßæææóóóõõõïïïîîîïïïëëëâââ¼¼¼ÀÀÀÃÃÃÌÌÌÐÐÐÎÎÎÎÎÎÐÐÐÑÑÑÒÒÒ×××ÍÍÍÅÅÅÔÔÔÅÅÅÑÑÑÙÙÙàààâââÜÜÜÙÙÙÑÑÑÍÍÍÉÉÉÅÅÅÆÆÆÇÇÇÉÉÉÌÌÌÑÑÑÍÍÍÍÍÍÊÊÊÇÇÇÆÆÆÃÃÃÀÀÀÀÀÀ¼¼¼¿¿¿ÂÂÂÃÃÃÂÂÂÀÀÀÂÂÂÆÆÆÇÇÇÝÝÝÅÅž¾¾ÕÕÕÔÔÔÂÂÂßßß×××ÕÕÕÒÒÒÃÃÃÉÉÉííííííõõõßßßëëëæææÜÜÜààààààÝÝÝäääÙÙÙÒÒÒÎÎÎÑÑÑÙÙÙÜÜÜ×××ÐÐÐÔÔÔÑÑÑÎÎÎÊÊÊÆÆÆÅÅÅÃÃÃÃÃÃÇÇÇÉÉÉÉÉÉÆÆÆÇÇÇÌÌ̯¯¯¸¸¸¾¾¾ÂÂÂÃÃÃÃÃþ¾¾¸¸¸ÃÃÃÅÅÅÅÅÅÅÅÅÅÅÅÆÆÆÆÆÆÆÆÆÍÍÍÍÍÍÅÅÅÌÌÌÇÇÇÐÐÐÊÊÊÌÌÌÌÌÌÉÉÉÍÍÍ×××ÜÜܼ¼¼ÀÀÀÇÇÇÆÆÆÀÀÀ¾¾¾ÀÀÀÀÀÀ¿¿¿ÃÃÃÊÊÊÎÎÎÍÍÍÊÊÊÍÍÍÕÕÕØØØÉÉÉ···¼¼¼ÀÀÀÅÅÅÉÉÉÍÍÍÎÎÎÍÍÍÌÌÌÌÌÌÐÐÐÕÕÕâââïïïêêêÙÙÙÒÒÒÕÕÕÎÎÎÐÐÐÌÌÌÍÍÍÑÑÑÌÌÌÎÎÎÕÕÕÎÎÎÊÊÊÑÑÑÜÜÜÝÝÝÑÑÑÅÅÅâââÛÛÛÝÝÝÒÒÒÌÌÌÐÐÐÌÌÌÌÌÌÉÉÉÇÇÇÉÉÉÍÍÍÔÔÔÛÛÛÜÜÜÜÜÜÙÙÙÛÛÛÊÊÊÕÕÕÒÒÒÔÔÔÌÌÌ¿¿¿ÂÂÂÅÅÅÆÆÆÉÉÉÎÎÎÍÍÍÉÉɸ¸¸µµµ´´´···¼¼¼ÂÂÂÆÆÆÇÇÇÆÆÆÂÂÂÂÂÂÅÅÅÆÆÆÂÂÂÀÀÀ¬¬¬³³³»»»ÀÀÀÃÃÃÅÅÅÃÃû»»¼¼¼¿¿¿ÅÅÅÉÉÉÌÌÌÊÊÊÉÉÉÊÊÊÆÆÆÇÇÇÐÐÐÙÙÙÝÝÝßßßßßßßßßçççïïïñññóóóöööòòòëëëëëëÕÕÕºººÅÅÅÅÅÅÑÑÑÐÐÐÎÎÎÍÍÍÑÑÑÑÑÑÔÔÔÍÍÍÀÀÀÇÇÇÔÔÔÊÊÊÎÎÎÔÔÔÑÑÑÐÐÐÒÒÒÐÐÐÎÎÎÇÇÇÅÅÅÅÅÅÉÉÉÉÉÉÆÆÆÇÇÇÌÌÌÍÍÍÍÍÍÊÊÊÇÇÇÃÃÃÀÀÀ¾¾¾¼¼¼ºººººº¼¼¼¿¿¿ÂÂÂÂÂÂÀÀÀ¿¿¿¾¾¾ÎÎÎÍÍÍÒÒÒÐÐÐÕÕÕÕÕÕçççÛÛÛÕÕÕÔÔÔÇÇÇÅÅÅçççëëëøøøâââçççêêêäääßßßÝÝÝßßßâââãããÛÛÛÐÐÐÌÌÌÎÎÎÒÒÒÕÕÕÕÕÕÔÔÔÒÒÒÎÎÎÊÊÊÇÇÇÆÆÆÆÆÆÅÅÅÊÊÊÌÌÌÉÉÉÇÇÇÇÇÇÀÀÀ¸¸¸µµµ¿¿¿ÃÃÃÉÉÉÌÌÌÇÇÇ¿¿¿»»»»»»ÀÀÀ¾¾¾ÀÀÀÉÉÉÎÎÎÊÊÊÃÃÃÀÀÀÂÂÂÇÇÇÇÇÇÔÔÔÎÎÎ×××ÐÐÐÑÑÑÌÌÌÍÍÍÑÑÑØØØÛÛÛ······¿¿¿¿¿¿¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼ÀÀÀÃÃÃÅÅÅÃÃÃÂÂÂÃÃÃÍÍÍÒÒÒÌÌÌ¿¿¿»»»¼¼¼¿¿¿ÂÂÂÅÅÅÆÆÆÇÇÇÉÉÉÉÉÉÉÉÉÌÌÌÜÜÜîîîêêêÙÙÙÑÑÑÝÝÝØØØÛÛÛ×××ØØØßßßÛÛÛßßßØØØÔÔÔÒÒÒØØØßßßÝÝÝÒÒÒÉÉÉÛÛÛÙÙÙÙÙÙÍÍÍÌÌÌÐÐÐÆÆÆÃÃÃØØØÜÜÜßßßÛÛÛÕÕÕÔÔÔØØØÜÜÜÛÛÛÛÛÛÊÊÊÕÕÕÑÑÑÒÒÒÇÇÇ»»»»»»¾¾¾¾¾¾¿¿¿ÆÆÆÍÍÍÍÍÍÇÇǺºº¸¸¸¸¸¸»»»ÀÀÀÆÆÆÉÉÉÉÉÉÇÇÇÀÀÀÀÀÀÅÅÅÆÆÆÃÃÃÂÂÂÃÃñ±±µµµ»»»¿¿¿ÂÂÂÂÂÂÅÅÅÆÆÆÀÀÀÀÀÀÃÃÃÇÇÇÊÊÊÌÌÌÊÊÊÉÉÉÌÌÌÃÃÃÅÅÅÒÒÒßßßâââààààààßßßñññùùùïïïòòòÿÿÿöööèèèãããÇÇǺººÌÌÌÍÍÍÙÙÙÑÑÑÎÎÎÎÎÎÒÒÒÑÑÑÕÕÕÆÆƸ¸¸ÉÉÉÔÔÔÕÕÕÒÒÒÕÕÕÆÆÆÂÂÂÊÊÊÆÆÆÊÊÊÌÌÌÉÉÉÉÉÉÊÊÊÊÊÊÆÆÆÉÉÉÐÐÐÐÐÐÎÎÎÌÌÌÇÇÇÅÅÅÀÀÀ¾¾¾¼¼¼¾¾¾ºººµµµ¸¸¸ÀÀÀÆÆÆÅÅÅÀÀÀÅÅÅÊÊÊÎÎÎÙÙÙÍÍÍÐÐÐÆÆÆÅÅÅØØØÑÑÑÑÑÑÒÒÒÊÊÊæææëëëóóóæææãããêêêëëëÝÝÝÛÛÛßßßÛÛÛÛÛÛßßßßßß×××ÌÌÌÇÇÇÍÍÍÕÕÕÔÔÔÒÒÒÎÎÎÌÌÌÉÉÉÇÇÇÆÆÆÆÆÆÇÇÇÇÇÇÆÆÆÌÌÌÍÍÍ¿¿¿»»»ÌÌÌÍÍÍÉÉÉÉÉÉÇÇÇÃÃÿ¿¿ÇÇÇÔÔÔÆÆÆÇÇÇÃÃþ¾¾¾¾¾ÂÂÂÆÆÆÆÆÆÆÆÆÊÊÊÌÌÌâââçççíííØØØÌÌÌÊÊÊÑÑÑØØØÝÝÝÛÛÛ±±±°°°¸¸¸»»»»»»»»»¼¼¼ÀÀÀ¼¼¼¸¸¸¿¿¿¿¿¿ÆÆÆÎÎÎÎÎÎÍÍÍÐÐÐØØØ···ººº¿¿¿ÃÃÃÅÅÅÅÅÅÃÃÃÅÅÅÂÂÂÊÊÊÒÒÒßßßèèèààà×××ØØØòòòïïïóóóçççÝÝÝÜÜÜÙÙÙâââÝÝÝÜÜÜÛÛÛÛÛÛÛÛÛØØØÑÑÑÌÌÌÔÔÔÙÙÙÐÐÐÐÐÐÅÅÅÅÅÅÂÂÂÜÜÜãããæææãããÙÙÙÕÕÕ×××ØØØØØØÐÐÐÒÒÒ××××××ÒÒÒÌÌÌÆÆÆÃÃÿ¿¿¼¼¼»»»¾¾¾¿¿¿¿¿¿ÆÆÆÍÍÍÇÇǼ¼¼µµµ»»»ÃÃÃÇÇÇÊÊÊÌÌÌÇÇÇÌÌÌÌÌÌÊÊÊÊÊÊÇÇÇ»»»¬¬¬³³³»»»ÂÂÂÆÆÆÇÇÇÅÅÅÂÂÂÂÂÂÀÀÀÅÅÅÌÌÌÌÌÌÇÇÇÉÉÉÐÐÐÊÊÊÌÌÌÍÍÍâââÜÜÜÜÜÜÙÙÙçççüüüõõõóóóøøøøøøñññíííïïïÝÝÝÇÇÇÃÃÃÎÎÎÐÐÐÎÎÎÑÑÑÑÑÑÆÆÆÒÒÒÊÊÊÌÌÌÛÛÛ¼¼¼ÙÙÙÀÀÀÃÃÃÎÎÎÌÌÌÃÃÃÆÆÆÇÇÇÆÆÆÊÊÊÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÉÉÉÊÊÊÌÌÌÍÍÍÊÊÊÇÇÇÃÃÃÀÀÀ¿¿¿¾¾¾¾¾¾ººº¸¸¸¸¸¸¸¸¸ººº¼¼¼¿¿¿ÀÀÀÃÃÃÃÃÃÐÐÐÎÎÎÅÅÅÒÒÒÛÛÛÆÆÆÛÛÛÑÑÑÐÐÐÑÑѾ¾¾ÂÂÂçççòòòîîîäääÜÜÜßßßèèèñññëëëßßßØØØÒÒÒÒÒÒÙÙÙÜÜÜÒÒÒÇÇÇ»»»ÑÑÑÊÊÊÐÐÐÆÆÆÆÆÆÅÅÅÉÉÉÉÉÉÌÌÌÎÎÎÇÇǼ¼¼ÂÂÂÐÐÐÑÑÑÅÅÅÀÀÀ¿¿¿¿¿¿»»»¸¸¸ÀÀÀÍÍÍÊÊÊÂÂÂÀÀÀÆÆÆÌÌÌÊÊÊÊÊÊÍÍÍèèèâââßßßàààãããèèèëëëêêêäääàààÕÕÕÜÜÜäääÌÌ̯¯¯¯¯¯±±±µµµÀÀÀµµµ³³³···µµµÂÂÂÂÂÂÅÅÅÊÊÊÎÎÎÎÎÎÍÍÍÊÊÊàààÌÌÌ······Â¿¿¿»»»ÃÃÃÇÇÇÆÆÆÌÌÌÕÕÕ×××ÕÕÕÔÔÔÕÕÕñññíííêêêëëëçççàààßßßààààààÙÙÙÜÜÜÒÒÒ×××ÜÜÜÌÌÌÅÅÅÛÛÛÙÙÙÌÌÌÊÊÊÅÅÅÍÍÍÑÑÑâââäääçççæææßßßØØØÕÕÕÒÒÒÐÐÐÌÌÌÎÎÎÑÑÑÑÑÑÎÎÎÉÉÉÃÃÃÀÀÀ¿¿¿¿¿¿ÀÀÀ¿¿¿»»»¼¼¼ÂÂÂÑÑÑÇÇÇÀÀÀÅÅÅÉÉÉÊÊÊÉÉÉÇÇÇÊÊÊÍÍÍÎÎÎÍÍÍÊÊÊÃÃõµµ©©©³³³»»»ÃÃÃÇÇÇÉÉÉÇÇÇÆÆÆÅÅÅÇÇÇÇÇÇÇÇÇÇÇÇÉÉÉÉÉÉÉÉÉÒÒÒ××××××ãããßßßæææçççïïïïïïëëëÿÿÿòòòÇÇÇÉÉÉãããàààÂÂÂÀÀÀÊÊÊÒÒÒÑÑÑÐÐÐÒÒÒÐÐÐÌÌÌÌÌÌÉÉÉÎÎÎÊÊÊ»»»ÕÕÕÍÍÍÇÇÇÎÎÎÊÊÊÂÂÂÆÆÆÇÇÇÆÆÆÊÊÊÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÉÉÉÊÊÊÌÌÌÌÌÌÉÉÉÆÆÆ¿¿¿¾¾¾¼¼¼¼¼¼ººº¸¸¸¸¸¸¸¸¸ººº¼¼¼¿¿¿ÀÀÀÆÆÆÂÂÂÊÊÊÎÎÎÍÍÍÔÔÔÕÕÕÆÆÆÛÛÛÝÝÝ××××××ÎÎÎÃÃÃÔÔÔæææíííëëëçççààààààæææçççäääïïïãããØØØØØØÛÛÛØØØÎÎÎÇÇǼ¼¼ÒÒÒÍÍÍÒÒÒÉÉÉÉÉÉÇÇÇÌÌÌÎÎÎÊÊÊÇÇÇÃÃÿ¿¿ÆÆÆÊÊʺººÆÆÆÍÍÍÍÍÍÐÐÐÕÕÕÑÑÑÆÆÆÌÌÌÆÆÆÅÅÅÍÍÍÙÙÙÝÝÝÜÜÜÙÙÙÝÝÝçççíííêêêææææææèèèêêêàààäääÛÛÛÙÙÙßßßÌÌ̱±±¬¬¬±±±¬¬¬¯¯¯¬¬¬°°°···´´´ººº¼¼¼ÂÂÂÃÃÃÅÅÅÇÇÇÌÌÌÐÐÐÑÑÑÒÒÒÑÑÑÑÑÑÎÎμ¼¼ÆÆÆÂÂÂÇÇÇÐÐÐÔÔÔÐÐÐÍÍÍÕÕÕàààïïïçççæææïïïøøøöööîîîèèèÝÝÝÝÝÝãããÛÛÛ×××ØØØÊÊÊÆÆÆßßß×××ÊÊÊÆÆÆÂÂÂÔÔÔâââæææÛÛÛàààãããßßßÜÜÜÙÙÙÕÕÕÑÑÑÐÐÐÑÑÑÑÑÑÑÑÑÐÐÐÌÌÌÇÇÇÃÃÃÂÂÂÀÀÀÂÂÂÃÃÿ¿¿¸¸¸···ºººÂ¼¼¼¼¼¼ÅÅÅÍÍÍÎÎÎÎÎÎÎÎÎÒÒÒÑÑÑÑÑÑÐÐÐÊÊÊ¿¿¿···³³³±±±···¾¾¾ÃÃÃÉÉÉÊÊÊÊÊÊÉÉÉÆÆÆÊÊÊÊÊÊÅÅÅÆÆÆÍÍÍÎÎÎÊÊÊÜÜÜàààÝÝÝâââàààîîîòòòöööñññòòòÿÿÿëëëÀÀÀÀÀÀÑÑÑ¿¿¿ÅÅÅÎÎÎÐÐÐÍÍÍÒÒÒ×××ÒÒÒÐÐÐÇÇÇÌÌÌÒÒÒººº¼¼¼ÅÅÅÌÌÌÌÌÌÍÍÍÇÇÇÂÂÂÅÅÅÇÇÇÇÇÇÉÉÉÇÇÇÆÆÆÆÆÆÆÆÆÇÇÇÉÉÉÊÊÊÊÊÊÉÉÉÇÇÇÅÅÅ¿¿¿¼¼¼¼¼¼»»»¸¸¸¸¸¸¸¸¸¸¸¸ººº¼¼¼¿¿¿ÀÀÀÆÆÆÀÀÀÃÃÃÎÎÎÕÕÕÒÒÒÍÍÍÊÊÊ¿¿¿ØØØÐÐÐÐÐÐ×××ÇÇÇÆÆÆÔÔÔçççíííêêêßßßÛÛÛàààæææêêêïïïäää×××ÑÑÑ×××ÜÜÜ×××ÍÍÍ¿¿¿ÕÕÕÎÎÎÕÕÕÌÌÌÌÌÌÊÊÊÍÍÍÑÑÑÉÉÉÆÆÆÅÅÅÃÃÃÉÉÉÇÇǾ¾¾ÊÊÊÍÍÍÇÇÇÀÀÀÅÅÅÐÐÐÎÎÎÃÃÃÀÀÀÆÆÆÍÍÍ×××àààççççççâââæææííííííçççæææèèèèèèçççÝÝÝçççâââÜÜÜäääßßßÑÑÑÍÍÍÊÊʵµµªªª¯¯¯»»»ÆÆÆÅÅÅ···±±±¸¸¸ÀÀÀÅÅÅÅÅÅÅÅÅÅÅÅÃÃÃÌÌÌÒÒÒÕÕÕÙÙÙßßß×××ÇÇÇÂÂÂÂÂÂÇÇÇÐÐÐÔÔÔÔÔÔÔÔÔÝÝÝêêêçççÝÝÝÙÙÙâââñññúúúüüüúúúüüüóóóîîîàààØØØÕÕÕÉÉÉÅÅÅ×××ÒÒÒÌÌÌÇÇǾ¾¾ÑÑÑêêêãããÙÙÙÝÝÝßßßÛÛÛÙÙÙÙÙÙØØØÒÒÒÑÑÑÐÐÐÐÐÐÎÎÎÎÎÎÌÌÌÉÉÉÆÆÆ¿¿¿¿¿¿ÀÀÀÃÃü¼¼»»»¿¿¿¾¾¾¼¼¼¿¿¿ÉÉÉÎÎÎÎÎÎÌÌÌÍÍÍÒÒÒÍÍÍÊÊÊÉÉÉÃÃúºº¸¸¸¾¾¾ººº¼¼¼ÀÀÀÆÆÆÉÉÉÊÊÊÊÊÊÊÊÊÅÅÅÇÇÇÇÇÇÇÇÇÍÍÍÕÕÕØØØ×××àààßßßÝÝÝâââæææïïïõõõùùùüüüüüüçççÎÎÎÌÌÌÑÑÑÍÍÍÉÉÉÑÑÑÐÐÐÐÐÐÐÐÐÒÒÒ×××ÕÕÕÐÐÐÒÒÒÌÌÌÒÒÒ×××»»»ÐÐо¾¾ÍÍÍÑÑÑÍÍÍÅÅÅÂÂÂÅÅÅÇÇÇÇÇÇÆÆÆÆÆÆÅÅÅÅÅÅÅÅÅÆÆÆÇÇÇÉÉÉÉÉÉÆÆÆÅÅÅÃÃÃÀÀÀ¿¿¿¼¼¼»»»ººº¸¸¸¸¸¸¸¸¸¸¸¸ººº¼¼¼¿¿¿ÀÀÀÆÆÆÂÂÂÀÀÀÍÍÍ×××ÍÍÍÇÇÇÒÒÒÃÃÃÜÜÜÛÛÛØØØÙÙÙÐÐÐÇÇÇÀÀÀäääíííèèèÜÜÜÛÛÛßßßàààããããããàààÙÙÙÔÔÔ×××ÜÜÜØØØÎÎÎÀÀÀ×××ÐÐÐÕÕÕÌÌÌÌÌÌÊÊÊÎÎÎÐÐÐÊÊÊÌÌÌÊÊÊÃÃÃÆÆÆÊÊÊÆÆÆÊÊÊÀÀÀ¾¾¾ÃÃÃÅÅÅ¿¿¿¼¼¼¾¾¾ÊÊÊÙÙÙäääãããÝÝÝÝÝÝßßßÝÝÝâââäääãããæææëëëèèèãããäääíííòòòêêêâââæææäääàààãããÛÛÛÑÑÑÐÐÐÎÎÎÌÌÌÎÎÎÒÒÒÍÍÍ°°°µµµººº¾¾¾ÅÅÅÊÊÊÌÌÌÉÉÉÊÊÊÍÍÍÇÇÇÍÍÍßßßäääÕÕÕÉÉÉÉÉÉÉÉÉÊÊÊ×××æææèèèæææèèèÜÜÜ×××ÒÒÒÔÔÔÜÜÜæææîîîòòòëëëäääâââãããèèèæææÕÕÕÇÇÇÉÉÉÍÍÍÐÐÐÊÊʼ¼¼ÇÇÇçççÜÜÜààààààÜÜÜÔÔÔÑÑÑÒÒÒÑÑÑÎÎÎÉÉÉÉÉÉÉÉÉÇÇÇÆÆÆÅÅÅÃÃÃÂÂÂÂÂÂÀÀÀÀÀÀÃÃÿ¿¿ÂÂÂÆÆÆÃÃÃÃÃÃÇÇÇÑÑÑÔÔÔÑÑÑÎÎÎÐÐÐÅÅÅÂÂÂÂÂÂÃÃÿ¿¿ººº»»»ÂÂÂÂÂÂÃÃÃÅÅÅÇÇÇÉÉÉÉÉÉÉÉÉÉÉÉÆÆÆÅÅÅÉÉÉÑÑÑ×××ÙÙÙÝÝÝããããããÛÛÛÜÜÜçççïïïïïïóóóúúúîîîäääÎÎÎÅÅÅÐÐÐ×××ÕÕÕÙÙÙÕÕÕÒÒÒÔÔÔØØØÛÛÛÕÕÕÍÍÍÌÌÌÊÊÊÊÊÊÇÇÇÃÃü¼¼ØØظ¸¸ÇÇÇÔÔÔÌÌÌÅÅÅÃÃÃÅÅÅÆÆÆÆÆÆÅÅÅÃÃÃÃÃÃÃÃÃÃÃÃÅÅÅÅÅÅÆÆÆÇÇÇÅÅÅÃÃÃÂÂÂÀÀÀ¿¿¿¼¼¼»»»ººº¸¸¸¸¸¸···¸¸¸ººº»»»¾¾¾¿¿¿ÃÃÃÅÅÅÂÂÂÉÉÉÑÑÑÇÇÇÆÆÆÛÛÛÌÌÌÐÐÐ×××ßßß×××ÐÐÐÐÐм¼¼ÛÛÛíííëëëßßßÜÜÜÜÜÜØØØÛÛÛâââçççæææÝÝÝ××××××ÕÕÕÑÑÑÀÀÀ×××ÑÑÑ×××ÍÍÍÍÍÍÌÌÌÎÎÎÑÑÑÊÊÊÊÊÊÉÉÉÂÂÂÂÂÂÇÇÇÇÇÇÉÉÉÂÂÂÉÉÉÛÛÛßßßÒÒÒÑÑÑÜÜÜÒÒÒÛÛÛÙÙÙÊÊÊ»»»···¸¸¸ºººÅÅÅÎÎÎÜÜÜîîîõõõæææÜÜÜæææííííííæææâââàààÛÛÛÙÙÙàààâââÝÝÝàààÜÜÜÒÒÒÒÒÒÙÙÙÙÙÙ××××××ÍÍÍ¿¿¿···ººº¿¿¿ÂÂÂÃÃÃÍÍÍÌÌÌÊÊÊÕÕÕÝÝÝÝÝÝÜÜÜÍÍÍÍÍÍÌÌÌÛÛÛïïïîîîßßßÛÛÛÕÕÕÕÕÕÕÕÕ×××ÛÛÛÝÝÝÝÝÝÜÜÜ×××ÒÒÒÎÎÎ×××àààßßßØØØÎÎÎÀÀÀÍÍÍÒÒÒÍÍ;¾¾¿¿¿ãããÙÙÙÝÝÝÜÜÜÕÕÕÎÎÎÍÍÍÐÐÐÐÐÐÍÍÍÅÅÅÇÇÇÉÉÉÇÇÇÅÅÅÃÃÃÃÃÃÃÃÃÆÆÆÃÃÃÃÃÃÅÅÅÃÃÃÀÀÀÃÃÃÊÊÊÃÃÃÃÃÃÉÉÉÐÐÐÐÐÐÌÌÌÊÊÊÍÍÍÀÀÀÃÃÃÇÇÇÍÍÍÌÌÌÇÇÇÇÇÇÊÊÊÉÉÉÉÉÉÇÇÇÇÇÇÇÇÇÇÇÇÉÉÉÉÉÉÊÊÊÉÉÉÐÐÐÛÛÛÝÝÝÛÛÛÝÝÝäääæææÙÙÙßßßíííúúúóóóöööúúúêêêÍÍÍÉÉÉÔÔÔÒÒÒØØØÝÝÝÒÒÒÑÑÑÒÒÒÒÒÒÔÔÔÔÔÔÎÎÎÍÍÍÕÕÕÕÕÕÎÎÎÀÀÀ···ÀÀÀÐÐеµµÀÀÀÕÕÕÊÊÊÆÆÆÆÆÆÅÅÅÅÅÅÆÆÆÃÃÃÂÂÂÀÀÀÀÀÀÀÀÀÂÂÂÃÃÃÅÅÅÅÅÅÃÃÃÃÃÃÂÂÂÀÀÀ¿¿¿¼¼¼»»»ººº¸¸¸·········¸¸¸»»»¾¾¾¿¿¿ÂÂÂÆÆÆÃÃÃÅÅÅÊÊÊÇÇÇÊÊÊÙÙÙÎÎξ¾¾ÅÅÅÛÛÛÒÒÒÊÊÊÔÔÔÆÆÆÂÂÂâââíííãããààààààßßßæææßßßääääääÝÝÝÔÔÔÑÑÑÕÕÕØØØÂÂÂØØØÑÑÑØØØÍÍÍÎÎÎÌÌÌÐÐÐÒÒÒÇÇÇÅÅÅÆÆÆÂÂÂÂÂÂÆÆÆÃÃÃØØØÔÔÔÐÐÐÍÍÍÉÉÉÃÃÃÃÃÃÉÉÉâââÛÛÛÌÌ̾¾¾···»»»¿¿¿Â¼¼¼ÂÂÂÉÉÉßßßõõõîîîäääíííääääääãããäääààà×××ÒÒÒ×××æææÛÛÛØØØÙÙÙÙÙÙßßßãããÝÝÝàààçççãããÐÐо¾¾»»»¾¾¾¿¿¿ÀÀÀÎÎÎÑÑÑÎÎÎÔÔÔÙÙÙÝÝÝäääÇÇÇÐÐÐÒÒÒÝÝÝëëëâââÑÑÑÑÑÑ×××ÕÕÕÕÕÕÛÛÛäääíííêêêâââçççãããÕÕÕÒÒÒÎÎÎÉÉÉÐÐÐÑÑÑÂÂÂÎÎÎÑÑÑÌÌ̼¼¼ãããÝÝÝÕÕÕÕÕÕÑÑÑÍÍÍÍÍÍÐÐÐÍÍÍÇÇÇÂÂÂÇÇÇÌÌÌÊÊÊÆÆÆÂÂÂÃÃÃÆÆÆÅÅÅÂÂÂÂÂÂÅÅÅÃÃÃÂÂÂÆÆÆÌÌÌÍÍÍÌÌÌÍÍÍÍÍÍÇÇǾ¾¾»»»¾¾¾ÇÇÇÌÌÌÐÐÐÐÐÐÐÐÐÒÒÒÒÒÒÑÑÑÌÌÌÊÊÊÉÉÉÇÇÇÇÇÇÇÇÇÊÊÊÌÌÌÆÆÆÍÍÍØØØßßßßßßÜÜÜÝÝÝâââãããÛÛÛãããêêêüüüøøøúúúøøøëëëÐÐÐÊÊÊÒÒÒÒÒÒ×××ÛÛÛÒÒÒÐÐÐÕÕÕÑÑÑÌÌÌÑÑÑÔÔÔÕÕÕÛÛÛâââÑÑÑÆÆÆÂÂÂÕÕÕÊÊÊÅÅÅÉÉÉÕÕÕÉÉÉÇÇÇÊÊÊÅÅÅÃÃÃÅÅÅ¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿ÀÀÀÂÂÂÃÃÿ¿¿¾¾¾»»»ººº············¸¸¸»»»¾¾¾¿¿¿ÀÀÀÅÅÅÃÃÃÀÀÀÇÇÇÐÐÐÑÑÑÐÐÐÛÛÛÔÔÔÊÊÊÑÑÑÒÒÒÎÎÎÑÑÑÇÇǵµµÙÙÙçççãããèèèëëëèèèîîîàààââââââßßßØØØÒÒÒÔÔÔÛÛÛÅÅÅÛÛÛÔÔÔÙÙÙÐÐÐÐÐÐÎÎÎÒÒÒÌÌÌÅÅÅÉÉÉÌÌÌÆÆÆÆÆÆÌÌÌÎÎÎÔÔÔ×××ÔÔÔÐÐÐÐÐÐÒÒÒÍÍÍÅÅÅÆÆƼ¼¼³³³³³³···¾¾¾ÅÅÅÊÊÊÍÍÍÊÊÊ¿¿¿ÉÉÉêêêöööîîîëëëèèèêêêèèèâââÙÙÙÕÕÕÑÑÑÍÍÍØØØÙÙÙâââãããÛÛÛÝÝÝæææçççàààèèèëëëâââØØØÎÎο¿¿°°°¿¿¿ÉÉÉÌÌÌÍÍÍ×××ÛÛÛÝÝÝäääÂÂÂÐÐÐÕÕÕÜÜÜäääÙÙÙÍÍÍ×××ØØØÛÛÛÝÝÝâââêêêóóóòòòíííäääçççàààãããÛÛÛÍÍÍÐÐÐÎÎÎÉÉÉÑÑÑÎÎÎÇÇÇÆÆÆ¿¿¿æææãããÕÕÕ×××ÔÔÔÐÐÐÍÍÍÌÌÌÅÅÅ»»»ºººÀÀÀÇÇÇÆÆÆÀÀÀ¼¼¼¾¾¾Â¿¿¿¾¾¾ÀÀÀÅÅÅÅÅÅÅÅÅÇÇÇÎÎÎÌÌÌÊÊÊÍÍÍÎÎÎÊÊÊÃÃÃÅÅÅÉÉÉÌÌÌÍÍÍÊÊÊÅÅÅÅÅÅÍÍÍÑÑÑÐÐÐÌÌÌÊÊÊÇÇÇÆÆÆÇÇÇÉÉÉÌÌÌÍÍ;¾¾ÎÎÎÜÜÜßßßÝÝÝààààààßßßÝÝÝÛÛÛããããããøøøøøøüüüñññÆÆÆÐÐÐÍÍÍÐÐÐÝÝÝÕÕÕÌÌÌ×××ÎÎÎØØØÒÒÒÎÎÎÜÜÜæææÛÛÛÐÐÐÍÍ͵µµ···ÃÃÃÛÛÛ¼¼¼ÊÊÊÊÊÊÕÕÕÉÉÉÉÉÉÌÌÌÅÅÅÂÂÂÃÃÃÀÀÀ¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¿¿¿ÀÀÀÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀ¾¾¾»»»ººº············¸¸¸»»»¾¾¾¿¿¿ÂÂÂÃÃÃÀÀÀ¾¾¾ÇÇÇ×××ÕÕÕÇÇÇÉÉÉÛÛÛÅÅŸ¸¸ÌÌÌÕÕÕÑÑÑÆÆÆÀÀÀÝÝÝæææâââïïïóóóèèèæææïïïíííííííííæææØØØÒÒÒÔÔÔÆÆÆÜÜÜ×××ÜÜÜÒÒÒÒÒÒÑÑÑÕÕÕ¿¿¿ÃÃÃÒÒÒØØØÌÌÌÉÉÉ×××ãããÎÎÎÎÎÎÉÉÉÅÅÅÆÆÆÆÆƺºº¨¨¨¬¬¬©©©µµµººº»»»ÀÀÀÉÉÉÐÐÐØØØÌÌÌÇÇÇãããõõõíííæææÝÝÝâââßßßÒÒÒÎÎÎÙÙÙÝÝÝ×××ÎÎÎÔÔÔâââèèèâââßßßàààÝÝÝ×××ÙÙÙÛÛÛßßßêêêëëëÔÔÔ¸¸¸···ÀÀÀÆÆÆÊÊÊÒÒÒ×××ÝÝÝêêêÀÀÀÎÎÎÒÒÒØØØäääÜÜÜÕÕÕàààÕÕÕäääññññññîîîêêêäääßßßæææäääÛÛÛâââßßßÐÐÐÑÑÑÊÊÊàààÌÌÌÍÍÍÊÊÊÇÇÇÔÔÔÛÛÛæææÔÔÔÜÜÜÒÒÒÔÔÔÙÙÙÎÎÎÅÅż¼¼ÇÇÇÆÆÆÅÅÅÅÅÅÃÃÃÃÃÃÃÃÃÅÅÅÃÃÃÀÀÀ»»»¿¿¿ÉÉÉÉÉÉÇÇÇÎÎÎÍÍÍÌÌÌÎÎÎÌÌÌ¿¿¿µµµ»»»ÆÆÆÍÍÍÑÑÑÐÐÐÉÉÉÇÇÇÌÌÌÐÐÐÐÐÐÑÑÑÌÌÌÍÍÍÃÃÃÊÊÊÅÅÅÍÍÍÌÌÌëëëãããÜÜÜÜÜÜàààãããàààÛÛÛßßßæææâââñññòòòóóóÿÿÿäääÍÍÍÑÑÑ×××ÙÙÙ×××ÒÒÒÎÎÎÌÌÌÐÐÐÌÌÌÉÉÉÔÔÔÊÊÊØØØ°°°¼¼¼···µµµÆÆÆÝÝÝÆÆƺººÐÐÐÆÆÆÝÝÝÐÐÐÅÅÅÃÃÃÅÅÅÆÆÆÅÅÅ¿¿¿¾¾¾¾¾¾¼¼¼¼¼¼¼¼¼¿¿¿ÀÀÀÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀ¿¿¿¾¾¾ººº¸¸¸¸¸¸ººº»»»¼¼¼¾¾¾¾¾¾ÀÀÀÅÅÅÂÂÂÆÆÆÉÉÉÒÒÒÜÜÜÌÌÌÕÕÕÉÉÉÉÉɾ¾¾ÒÒÒÎÎÎÇÇÇÊÊÊÀÀÀ···°°°±±±¼¼¼ÍÍÍãããõõõòòòõõõïïïïïïâââßßßÑÑÑÕÕÕÊÊÊÛÛÛßßßÛÛÛÜÜÜØØØÒÒÒÔÔÔÅÅÅÃÃÃÉÉÉÃÃÃÃÃÃàààêêêÎÎγ³³ÅÅÅ···°°°©©©µµµ¯¯¯¬¬¬±±±°°°°°°´´´ººº¿¿¿ÆÆÆÒÒÒÑÑÑÃÃÃÍÍÍæææööööööÜÜÜäääÜÜÜØØØÛÛÛÜÜÜÙÙÙØØØÛÛÛÒÒÒÙÙÙçççÜÜÜÜÜÜæææÙÙÙÒÒÒçççêêêèèèääääääçççäääÝÝݸ¸¸···¿¿¿ÍÍÍÑÑÑÒÒÒÜÜÜêêê¿¿¿ÊÊÊÑÑÑÜÜÜíííëëëßßßÛÛÛßßßëëëïïïçççäääèèèæææÝÝÝçççÝÝÝâââÕÕÕØØØÒÒÒ×××ÆÆÆÔÔÔÉÉÉÀÀÀ¸¸¸ÂÂÂÙÙÙÜÜÜÒÒÒÍÍÍÙÙÙÑÑÑÑÑÑÎÎÎÂÂÂÀÀÀÀÀÀÇÇÇÇÇÇÆÆÆÆÆÆÅÅÅÃÃÃÂÂÂÂÂÂÆÆÆÅÅÅ¿¿¿ÅÅÅÎÎÎÌÌÌÇÇÇÍÍÍÌÌÌÎÎÎÎÎÎÉÉÉ¿¿¿ººº¿¿¿ÉÉÉÎÎÎÑÑÑÐÐÐÉÉÉÇÇÇÊÊÊÎÎÎÎÎÎÊÊÊÆÆÆÉÉÉÂÂÂÍÍÍÍÍÍÜÜÜàààãããßßßÜÜÜÝÝÝãããäääâââÝÝÝããããããßßßïïïïïïòòòóóóÇÇÇÍÍÍÑÑÑ×××ØØØÕÕÕÒÒÒÐÐÐÎÎÎÐÐÐÍÍÍÌÌÌÒÒÒÍÍÍÛÛÛµµµ¾¾¾¿¿¿¸¸¸ÆÆÆÒÒÒÆÆÆÆÆÆÑÑÑÀÀÀ×××ÔÔÔÊÊÊÃÃÃÂÂÂÀÀÀ»»»¸¸¸¾¾¾¼¼¼¼¼¼»»»¼¼¼¾¾¾ÀÀÀÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀ¿¿¿¿¿¿ºººººººººººº»»»¼¼¼¾¾¾¿¿¿ÅÅÅÉÉÉÅÅÅÇÇÇÉÉÉÐÐÐ×××ÆÆÆÒÒÒÌÌÌÐÐÐÅÅÅÒÒÒÍÍÍÆÆÆÆÆƼ¼¼¸¸¸»»»¾¾¾ÀÀÀÇÇÇÐÐÐèèèóóóöööòòòäääèèèãããÝÝÝÒÒÒØØØßßßâââàààßßß×××ÌÌÌÊÊÊÌÌÌÔÔÔÔÔÔÔÔÔßßßÕÕÕ´´´¦¦¦©©©¯¯¯ŸŸŸ¥¥¥¥¥¥ªªª°°°¯¯¯¯¯¯¯¯¯³³³···¼¼¼ÀÀÀÃÃÃÂÂÂÊÊÊäääõõõïïïèèèâââÜÜÜÝÝÝÛÛÛÕÕÕÕÕÕØØØÕÕÕÎÎÎÑÑÑÕÕÕßßßØØØØØØßßß×××ÕÕÕÔÔÔÕÕÕÔÔÔÕÕÕÝÝÝæææçççãããÐÐо¾¾µµµÂÂÂÎÎÎÔÔÔßßßîîîÊÊÊÊÊÊÑÑÑßßßèèèêêêäääÝÝÝßßßèèèîîîîîîîîîñññíííæææâââØØØØØØÎÎÎÐÐÐÐÐÐØØØÌÌÌÌÌÌÊÊʼ¼¼¾¾¾ÐÐÐßßßßßßÎÎÎÐÐÐØØØÐÐÐÐÐÐÍÍÍÃÃÃÇÇÇÊÊÊÅÅÅÅÅÅÆÆÆÆÆÆÆÆÆÅÅÅÅÅÅÅÅÅÉÉÉÉÉÉÅÅÅÉÉÉÑÑÑÎÎÎÉÉÉÌÌÌÍÍÍÑÑÑÐÐÐÆÆÆÀÀÀ¿¿¿ÅÅÅÌÌÌÐÐÐÑÑÑÐÐÐÉÉÉÇÇÇÊÊÊÍÍÍÍÍÍÌÌÌÊÊÊÑÑÑÊÊÊÒÒÒÑÑÑßßßâââÝÝÝÝÝÝÝÝÝàààããããããàààßßßââââââæææõõõóóóøøøóóó¿¿¿ÎÎÎÑÑÑÕÕÕÕÕÕÔÔÔÒÒÒÑÑÑÐÐÐÑÑÑÐÐÐÎÎÎÑÑÑÐÐÐÛÛÛ¼¼¼¿¿¿Â¾¾¾ÎÎÎÉÉÉÃÃÃÎÎÎÑÑÑ¿¿¿¿¿¿ÍÍÍÊÊÊ¿¿¿Â¼¼¼¿¿¿¼¼¼»»»»»»»»»»»»¼¼¼¿¿¿ÀÀÀÂÂÂÂÂÂÃÃÃÃÃÃÃÃÃÂÂÂÀÀÀÀÀÀ¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼¾¾¾¿¿¿ÀÀÀÅÅÅÇÇÇÆÆÆÊÊÊÊÊÊÎÎÎÕÕÕÅÅÅÑÑÑÊÊÊÐÐÐÃÃÃÒÒÒÒÒÒÎÎÎÍÍÍÀÀÀ¾¾¾¿¿¿Â¾¾¾¼¼¼¾¾¾ÀÀÀ×××îîîîîîàààããããããÎÎÎÛÛÛÔÔÔÙÙÙßßßÜÜÜÝÝÝ×××ÃÃÃÐÐÐÌÌÌÅÅÅÃÃÃÎÎÎÝÝÝÝÝÝÒÒÒ¯¯¯©©©¯¯¯¼¼¼©©©¨¨¨©©©···±±±±±±±±±°°°±±±¸¸¸¾¾¾¾¾¾¿¿¿ÉÉÉàààòòòóóóêêêÝÝÝßßßßßßâââàààÛÛÛØØØØØØÒÒÒÊÊÊÍÍÍÎÎÎ×××ÔÔÔÔÔÔ×××ÔÔÔØØØØØØ×××ÒÒÒÔÔÔÜÜÜæææêêêçççíííÑÑÑ»»»¾¾¾ÌÌÌÒÒÒØØØâââ×××ÊÊÊÐÐÐÝÝÝàààäääêêêäää×××ÜÜÜæææîîîòòòñññíííèèèÝÝÝÝÝÝàààÒÒÒÍÍÍÌÌÌÛÛÛÛÛÛÅÅÅÃÃþ¾¾ÔÔÔäääÛÛÛÙÙÙ×××ÔÔÔÒÒÒÉÉÉÍÍÍÎÎÎÉÉÉÌÌÌÊÊÊÃÃÃÃÃÃÃÃÃÃÃÃÅÅÅÆÆÆÉÉÉÊÊÊÊÊÊÌÌÌÆÆÆÇÇÇÐÐÐÎÎÎÉÉÉÌÌÌÎÎÎ×××ÑÑÑÅÅÅÂÂÂÅÅÅÇÇÇÍÍÍÎÎÎÐÐÐÎÎÎÉÉÉÉÉÉÍÍÍÎÎÎÍÍÍÊÊÊÎÎÎÜÜÜØØØÝÝÝÔÔÔØØØ×××ßßßßßßàààââââââàààßßßÝÝÝÜÜÜàààîîîùùùñññõõõóóóÃÃÃÍÍÍÐÐÐÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÒÒÒÒÒÒÑÑÑÑÑÑÍÍÍÑÑÑÕÕÕ¾¾¾»»»¼¼¼ÂÂÂÜÜÜÅÅÅ¿¿¿ÐÐÐÎÎÎÀÀÀ¸¸¸ÒÒÒÑÑÑÀÀÀÀÀÀ¼¼¼µµµ»»»»»»»»»ººººººººº¼¼¼¾¾¾¿¿¿ÂÂÂÂÂÂÃÃÃÃÃÃÃÃÃÃÃÃÂÂÂÀÀÀ¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¿¿¿ÀÀÀÀÀÀ¿¿¿ÅÅÅÅÅÅÌÌÌÌÌÌÐÐÐ×××ÉÉÉÒÒÒÇÇÇÇÇÇ´´´ÂÂÂÉÉÉÉÉÉÅÅÅÊÊÊÆÆÆÆÆÆÉÉÉÉÉÉÅÅÅÅÅÅÇÇÇ···ÊÊÊçççñññãããàààèèèÕÕÕÝÝÝÔÔÔÑÑÑÑÑÑÑÑÑÒÒÒÎÎÎÃÃÃÔÔÔÑÑÑÃÃÃÂÂÂÐÐÐ×××ØØØÝÝÝÑÑÑÉÉÉÇÇÇÐÐо¾¾´´´¦¦¦´´´³³³±±±¯¯¯¨¨¨¥¥¥°°°¸¸¸´´´ßßßçççúúúöööîîîëëëâââäääæææâââßßßàààÛÛÛÑÑÑÌÌÌÍÍÍÊÊÊÉÉÉÐÐÐÔÔÔÔÔÔÑÑÑÒÒÒÙÙÙÛÛÛÙÙÙÕÕÕÒÒÒÒÒÒØØØßßßãããñññãããÍÍÍÅÅÅÌÌÌÒÒÒÒÒÒÕÕÕÝÝÝÎÎÎÌÌÌÔÔÔØØØßßßèèèîîîæææßßßÜÜÜàààâââßßßÝÝÝßßßÜÜÜÕÕÕÎÎÎÆÆÆÉÉÉÍÍÍÍÍÍÅÅÅ¿¿¿µµµ´´´×××äääÔÔÔÒÒÒÕÕÕÒÒÒÎÎÎÅÅÅÉÉÉÆÆƾ¾¾ÃÃÃÀÀÀÉÉÉÇÇÇÅÅÅÂÂÂÂÂÂÅÅÅÇÇÇÉÉÉÊÊÊÊÊÊÃÃÃÀÀÀÉÉÉÌÌÌÉÉÉÌÌÌÑÑÑÙÙÙÑÑÑÅÅÅÆÆÆÉÉÉÉÉÉÎÎÎÍÍÍÐÐÐÎÎÎÊÊÊÊÊÊÐÐÐÐÐÐÍÍÍÆÆÆÍÍÍÝÝÝÜÜÜâââ×××ÙÙÙ×××ßßßßßßàààààààààßßßàààâââßßßàààíííòòòèèèíííççç¾¾¾ÊÊÊÍÍÍÎÎÎÐÐÐÐÐÐÐÐÐÐÐÐÑÑÑÔÔÔÑÑÑÑÑÑÊÊÊÑÑÑÊÊʺºº···»»»ÂÂÂàààÀÀÀÃÃÃÑÑÑÊÊÊ¿¿¿¸¸¸ÒÒÒÒÒÒ¾¾¾···¾¾¾»»»»»»ººººººººº»»»¾¾¾¿¿¿ÀÀÀÂÂÂÃÃÃÃÃÃÃÃÃÃÃÃÂÂÂÂÂÂÀÀÀ¿¿¿¿¿¿¿¿¿¿¿¿ÀÀÀÀÀÀ¿¿¿ÃÃÃÅÅÅÌÌÌÌÌÌÎÎÎ×××ÌÌÌÇÇÇÆÆÆÎÎθ¸¸¾¾¾ÇÇÇÑÑÑÑÑÑÙÙÙÔÔÔÐÐÐÐÐÐÎÎÎÊÊÊÌÌÌÎÎÎÊÊÊÍÍÍÙÙÙîîîàààÝÝÝïïïëëëÙÙÙÙÙÙÒÒÒÎÎÎÐÐÐÊÊÊÅÅÅÇÇÇÔÔÔÕÕÕÎÎÎÍÍÍÔÔÔÐÐÐÌÌÌ×××××××××ÎÎÎÐÐÐÍÍÍÆÆƦ¦¦±±±±±±±±±´´´±±±µµµÎÎÎâââßßßîîîêêêñññèèèââââââÜÜÜäääâââÜÜÜØØØ×××ÑÑÑÉÉÉÆÆÆÊÊÊÉÉÉÇÇÇÌÌÌÕÕÕ×××ÐÐÐÒÒÒØØØÕÕÕ×××ØØØÔÔÔÎÎÎÑÑÑÝÝÝèèèàààêêêÝÝÝÉÉÉÊÊÊÔÔÔ×××ÙÙÙÛÛÛÔÔÔÉÉÉÇÇÇÐÐÐ×××ãããóóóõõõêêêãããäääçççèèèîîîøøøÜÜÜÜÜÜÔÔÔÑÑÑÑÑÑÔÔÔÌÌÌÅÅÅÀÀÀ±±±´´´ÎÎÎÛÛÛÙÙÙÙÙÙÑÑÑÕÕÕÒÒÒÍÍÍÎÎο¿¿³³³¾¾¾ÂÂÂÐÐÐÍÍÍÉÉÉÅÅÅÂÂÂÂÂÂÂÂÂÃÃÃÆÆÆÇÇǾ¾¾ºººÃÃÃÊÊÊÊÊÊÍÍÍÒÒÒØØØÎÎÎÆÆÆÌÌÌÌÌÌÉÉÉÑÑÑÐÐÐÑÑÑÎÎÎÌÌÌÍÍÍÑÑÑÑÑÑÍÍÍÐÐÐÑÑÑÜÜÜ×××ÝÝÝÕÕÕÛÛÛÙÙÙÛÛÛÜÜÜÝÝÝàààâââãããæææçççäääàààçççîîîîîîïïïàà྾¾ÅÅÅÇÇÇÌÌÌÍÍÍÍÍÍÍÍÍÎÎÎÐÐÐÒÒÒÎÎÎÑÑÑÇÇÇÑÑѾ¾¾···µµµ¼¼¼¿¿¿ØØØ»»»ÊÊÊÑÑÑÇÇǼ¼¼»»»ÍÍÍÌÌÌÂÂÂÂÂÂÀÀÀ¾¾¾ÅÅÅ»»»»»»ººººººººº¼¼¼¾¾¾¿¿¿ÀÀÀÀÀÀÂÂÂÃÃÃÃÃÃÃÃÃÂÂÂÂÂÂÂÂÂÀÀÀÀÀÀ¿¿¿¿¿¿ÀÀÀÀÀÀÂÂÂÂÂÂÅÅÅÅÅÅÍÍÍÌÌÌÌÌÌÔÔÔÌÌ̼¼¼ÉÉÉÝÝÝÃÃû»»ÀÀÀÐÐÐÒÒÒØØØÔÔÔÒÒÒÔÔÔÒÒÒÎÎÎÎÎÎÑÑÑÐÐÐÊÊÊÆÆÆíííâââÜÜÜæææêêêØØØÝÝÝÛÛÛØØØØØØÍÍÍÃÃÃÊÊÊÒÒÒÔÔÔÍÍÍÌÌÌÑÑÑÎÎÎÎÎÎÛÛÛÐÐÐÕÕÕÐÐÐÎÎÎÕÕÕÒÒÒ¨¨¨°°°±±±±±±³³³¬¬¬ÊÊÊàààÙÙÙãããâââàààÙÙÙÛÛÛãããßßßÛÛÛÛÛÛÝÝÝÙÙÙÐÐÐÊÊÊÌÌÌÍÍÍÊÊÊÉÉÉÊÊÊÉÉÉÔÔÔ×××ÒÒÒ××××××ÕÕÕØØØÛÛÛØØØÑÑÑÐÐÐÜÜÜêêêßßßîîîàààÆÆÆÅÅÅÐÐÐÔÔÔÙÙÙ×××ØØØÌÌÌÂÂÂÉÉÉÑÑÑÛÛÛíííúúúöööóóóõõõïïïæææÝÝÝÝÝÝÅÅÅÔÔÔÕÕÕÑÑÑÃÃÃÀÀÀ¾¾¾ÃÃþ¾¾±±±ÃÃÃÔÔÔÕÕÕààààààÑÑÑ×××ÑÑÑÌÌÌÍÍÍ¿¿¿´´´ÅÅÅÌÌÌÍÍÍÌÌÌÊÊÊÇÇÇÅÅÅÃÃÃÂÂÂÀÀÀÂÂÂÃÃû»»···ÀÀÀÊÊÊÌÌÌÎÎÎÐÐÐÔÔÔÊÊÊÇÇÇÑÑÑÎÎÎÊÊÊÕÕÕÔÔÔÔÔÔÑÑÑÎÎÎÎÎÎÑÑÑÎÎÎÊÊÊÜÜÜÙÙÙÝÝÝÕÕÕÛÛÛÔÔÔÙÙÙØØØÙÙÙÛÛÛßßßâââæææççççççæææäääãããêêêòòòóóóëëëÔÔÔ¾¾¾ÀÀÀÃÃÃÇÇÇÊÊÊÊÊÊÊÊÊÌÌÌÍÍÍÑÑÑÊÊÊÑÑÑÉÉÉÔÔÔ´´´µµµ¸¸¸¼¼¼¾¾¾ÒÒÒºººÍÍÍÇÇÇÃÃÃÂÂÂÎÎÎÎÎÎÉÉɾ¾¾¼¼¼»»»¼¼¼¼¼¼»»»ºººººº»»»¼¼¼¾¾¾¿¿¿¿¿¿¿¿¿ÀÀÀÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀ¿¿¿¿¿¿ÀÀÀÀÀÀÀÀÀÂÂÂÃÃÃÃÃÃÌÌÌÊÊÊÊÊÊÕÕÕÎÎÎÀÀÀÌÌÌßßß¿¿¿°°°´´´¿¿¿»»»ÒÒÒÐÐÐÑÑÑÔÔÔÕÕÕÒÒÒÒÒÒÕÕÕÒÒÒÑÑÑÂÂÂøøøñññëëëãããæææßßßÝÝÝÝÝÝÝÝÝÛÛÛÑÑÑÊÊÊÌÌÌ×××ÔÔÔÎÎÎÐÐÐÔÔÔÑÑÑÌÌÌÌÌÌ×××ÙÙÙÙÙÙÙÙÙØØØÐÐС¡¡©©©°°°±±±´´´¯¯¯°°°ÑÑÑêêêàààãããçççâââßßßäääêêêçççØØØØØØÛÛÛØØØÐÐÐÌÌÌÎÎÎÑÑÑÐÐÐÌÌÌÍÍÍÆÆÆÐÐÐÕÕÕÒÒÒÙÙÙÕÕÕÕÕÕÕÕÕ×××ÕÕÕÑÑÑÎÎÎ×××àààæææêêêÔÔÔÀÀÀÆÆÆÌÌÌÊÊÊÑÑÑÒÒÒÙÙÙ×××ÉÉÉÅÅÅÌÌÌ×××ßßß×××ÛÛÛàààäääàààØØØÑÑÑÎÎÎÒÒÒÜÜÜÑÑÑÎÎÎÆÆÆÉÉɾ¾¾ÀÀÀ³³³ªªªÐÐÐàààÔÔÔÛÛÛÜÜÜÑÑÑÑÑÑÅÅÅ»»»Â»»»¸¸¸ÉÉÉÍÍÍÆÆÆÇÇÇÉÉÉÉÉÉÉÉÉÆÆÆÅÅÅÃÃÿ¿¿ÂºººµµµÂÂÂÌÌÌÎÎÎÐÐÐÍÍÍÐÐÐÇÇÇÉÉÉÕÕÕÑÑÑÌÌÌÙÙÙØØØØØØÔÔÔÐÐÐÎÎÎÐÐÐÍÍÍÇÇÇÝÝÝÙÙÙÝÝÝÕÕÕÝÝÝ×××ÜÜÜÙÙÙÜÜÜÝÝÝâââæææèèèçççäääàààßßßçççñññóóóîîî×××»»»°°°¾¾¾ÂÂÂÆÆÆÉÉÉÉÉÉÉÉÉÉÉÉÊÊÊÑÑÑÉÉÉÐÐÐÉÉÉÕÕÕ°°°µµµ¾¾¾¸¸¸¿¿¿ÒÒÒ»»»ÊÊÊ»»»ÂÂÂÌÌÌÑÑÑÇÇÇÀÀÀ¿¿¿¼¼¼¾¾¾ÀÀÀ¿¿¿¼¼¼»»»»»»ººº»»»¼¼¼¿¿¿ÀÀÀ¾¾¾¿¿¿ÀÀÀÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀ¿¿¿¿¿¿¿¿¿ÀÀÀÀÀÀ¾¾¾¿¿¿ÀÀÀÊÊÊÊÊÊÍÍÍÙÙÙÕÕÕÇÇÇÊÊÊØØؼ¼¼¼¼¼ÌÌÌØØØÎÎÎØØØÔÔÔÑÑÑÒÒÒÒÒÒÐÐÐÒÒÒ×××ØØØÙÙÙ¼¼¼öööòòòóóóäääçççèèèÛÛÛÙÙÙÜÜÜÕÕÕÒÒÒÑÑÑÌÌÌÙÙÙÐÐÐÉÉÉÊÊÊÒÒÒ×××ÒÒÒÌÌÌÉÉÉÇÇÇÕÕÕßßßØØØÐÐШ¨¨³³³°°°µµµ¯¯¯°°°ÔÔÔëëëàààçççßßßÔÔÔãããæææÕÕÕÒÒÒÍÍÍÒÒÒÎÎÎÎÎÎÎÎÎÌÌÌÆÆÆÉÉÉÐÐÐÎÎÎÎÎÎÃÃÃÊÊÊÑÑÑÒÒÒÜÜÜÔÔÔÛÛÛØØØØØØÜÜÜßßßßßßãããèèèäääÜÜÜÃÃü¼¼ÍÍÍÐÐÐÇÇÇÎÎÎÑÑÑÙÙÙßßßÒÒÒÂÂÂÉÉÉÕÕÕÒÒÒ××××××ÕÕÕÔÔÔÕÕÕÜÜÜæææíííØØØßßßÎÎÎÇÇǾ¾¾ÀÀÀµµµ»»»°°°ÑÑÑØØØÔÔÔàààÔÔÔÊÊÊÀÀÀÉÉÉÉÉÉ»»»ÅÅÅÐÐÐÇÇÇÇÇÇÉÉÉÊÊÊÊÊÊÉÉÉÆÆÆÅÅÅÃÃÃÅÅÅÆÆÆ»»»´´´¸¸¸ÇÇÇÐÐÐÇÇÇ»»»ÀÀÀÂÂÂÉÉÉÒÒÒ×××ÔÔÔÒÒÒÕÕÕÕÕÕÕÕÕÎÎÎÔÔÔÒÒÒÉÉÉÊÊÊÆÆÆÙÙÙÝÝÝââââââàààÝÝÝÜÜÜÜÜÜàààâââãããææææææääääääæææßßßøøøòòòñññêêêÝÝݼ¼¼ººº¼¼¼ÂÂÂÇÇÇÇÇÇÆÆÆÅÅÅÉÉÉÌÌÌÐÐÐÎÎÎÑÑÑ××׺ºº´´´¸¸¸ÅÅÅÙÙÙÑÑÑÂÂÂÐÐÐÅÅŵµµÐÐÐØØØÕÕÕÆÆÆÂÂÂÀÀÀ¼¼¼¿¿¿ÃÃü¼¼ºººººº»»»¼¼¼¼¼¼¾¾¾¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿ÂÂÂÃÃÃÅÅÅÂÂÂÀÀÀ¾¾¾¼¼¼¼¼¼¿¿¿ÂÂÂÃÃÿ¿¿ÌÌÌÊÊÊÊÊÊÛÛÛÒÒÒºººÌÌÌÔÔÔ¿¿¿ÝÝÝÊÊÊÑÑÑÍÍÍÕÕÕÕÕÕÑÑÑÒÒÒÎÎÎÌÌÌÔÔÔÙÙÙÔÔÔÍÍÍîîîëëëøøøäääææææææ×××ÝÝÝÜÜÜÝÝÝÍÍÍÐÐÐÊÊÊÎÎÎÕÕÕÒÒÒÆÆÆÂÂÂÌÌÌÑÑÑÎÎÎÒÒÒÂÂÂÅÅÅÐÐÐÒÒÒØØØÊÊʨ¨¨±±±¸¸¸°°°³³³ÔÔÔßßßäääÙÙÙÔÔÔÛÛÛäääææææææßßßÐÐÐÐÐÐÒÒÒÔÔÔÑÑÑÎÎÎÍÍÍÎÎÎÐÐÐÔÔÔÉÉÉÃÃÃÐÐÐÕÕÕÑÑÑ×××ÝÝÝêêêæææíííêêêííííííßßßããã××׿¿¿ÊÊÊÊÊÊÉÉÉÌÌÌÌÌÌÙÙÙÒÒÒîîîÙÙÙ¼¼¼ÉÉÉÇÇÇÉÉÉÅÅÅÒÒÒÝÝÝæææñññùùùòòòäääâââÛÛÛÅÅÅÐÐÐÀÀÀµµµ±±±¸¸¸ÎÎÎÆÆÆÙÙÙÕÕÕÉÉÉÎÎÎÅÅźººÅÅÅÅÅÅÀÀÀ´´´»»»ÉÉÉÆÆÆÍÍÍÐÐÐÐÐÐÍÍÍÊÊÊÆÆÆÃÃÃÅÅÅÆÆÆÆÆÆ¿¿¿»»»¿¿¿ÆÆÆÇÇÇÃÃþ¾¾¾¾¾¾¾¾ÃÃÃÍÍÍÒÒÒÒÒÒÔÔÔØØØÛÛÛØØØÍÍÍÒÒÒÑÑÑÊÊÊÎÎÎÍÍÍÙÙÙÛÛÛÜÜÜÜÜÜÛÛÛÜÜÜßßßâââàààâââäääæææææææææääääääèèèõõõñññøøøíííØØغºº»»»¿¿¿ÃÃÃÇÇÇÇÇÇÅÅÅÅÅÅÉÉÉÍÍÍÍÍÍÊÊÊÉÉÉÆÆƵµµ¸¸¸ÆÆÆÒÒÒÔÔÔÌÌ̼¼¼ÌÌÌÆÆƺººÊÊÊÇÇÇÎÎÎÉÉÉÉÉÉÇÇÇÅÅÅÃÃÃÃÃÿ¿¿ºººººº»»»¼¼¼¼¼¼¾¾¾¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿ÀÀÀÂÂÂÃÃÃÅÅÅÅÅÅÃÃÃÀÀÀ¿¿¿¼¼¼¾¾¾¿¿¿ÂÂÂÃÃÃÃÃÃÅÅÅÃÃÃÊÊÊÇÇÇÇÇÇÒÒÒÉÉɾ¾¾ÐÐÐÔÔÔ»»»¸¸¸ÙÙÙÉÉÉÉÉÉÒÒÒÕÕÕÐÐÐÌÌÌÐÐÐÎÎÎÍÍÍÒÒÒÔÔÔ×××ÎÎÎææææææùùùèèèâââãããÔÔÔÝÝÝââââââÐÐÐÍÍÍÆÆÆÎÎÎÙÙÙßßßÔÔÔÇÇÇÃÃÃÃÃÃÂÂÂ×××ÐÐÐÍÍÍÉÉÉÊÊÊ×××ÎÎί¯¯¯¯¯³³³±±±ÀÀÀÉÉÉàààæææëëëÙÙÙÕÕÕÜÜÜæææææææææàààÒÒÒÒÒÒÔÔÔÕÕÕÒÒÒÐÐÐÎÎÎÎÎÎÐÐÐÊÊÊÊÊÊÎÎÎÙÙÙÝÝÝÙÙÙ×××ÕÕÕîîîææææææãããæææíííèèèäääÉÉÉ¿¿¿ÂÂÂÊÊÊÉÉÉÉÉÉÐÐÐÔÔÔÌÌÌÒÒÒîîîâââÍÍÍÑÑÑÌÌÌÉÉÉÕÕÕâââêêêèèèèèèëëëæææÛÛÛÙÙÙÎÎÎÆÆÆÇÇÇ°°°¥¥¥¦¦¦ÝÝÝÕÕÕ×××ÐÐÐÃÃÃÇÇÇÇÇǾ¾¾ÆÆÆÀÀÀ¼¼¼µµµ¼¼¼ÆÆÆÅÅÅÎÎÎÎÎÎÍÍÍÊÊÊÆÆÆÃÃÃÂÂÂÅÅÅÇÇÇÇÇÇÃÃÃÅÅÅÇÇÇÅÅž¾¾¾¾¾ÃÃÃÀÀÀÀÀÀÃÃÃÍÍÍÒÒÒÔÔÔØØØÝÝÝÙÙÙ×××ÍÍÍÒÒÒÔÔÔÑÑÑÙÙÙÙÙÙÝÝÝßßßàààßßßÝÝÝÜÜÜÛÛÛÜÜÜääääääææææææçççççççççäääóóóøøøöööõõõÜÜÜÊÊʼ¼¼¿¿¿ÃÃÃÆÆÆÇÇÇÇÇÇÆÆÆÇÇÇÌÌÌÐÐÐÙÙÙÕÕÕÐÐÐÀÀÀ»»»ÃÃÃÕÕÕÙÙÙÐÐÐÇÇǺººÆÆÆÇÇÇÀÀÀÇÇǺººÌÌÌÐÐÐÎÎÎÍÍÍÍÍÍÇÇÇ¿¿¿¼¼¼ºººººº»»»¼¼¼¼¼¼¾¾¾¿¿¿¿¿¿¿¿¿ÀÀÀÂÂÂÃÃÃÅÅÅÅÅÅÅÅÅÅÅÅÃÃÃÂÂÂÀÀÀ¾¾¾¾¾¾ÀÀÀÂÂÂÃÃÃÅÅÅÉÉÉÇÇÇÇÇÇÅÅÅÅÅÅÊÊÊ¿¿¿¿¿¿ÇÇÇÊÊʸ¸¸´´´ÊÊʼ¼¼¿¿¿ÉÉÉÊÊÊÇÇÇÇÇÇÎÎÎÐÐÐÎÎÎÑÑÑÒÒÒ×××ÐÐÐæææëëëüüüèèèâââêêê×××ÛÛÛãããàààÍÍÍÉÉÉÅÅÅÂÂÂÌÌÌÔÔÔÔÔÔÎÎÎÉÉÉÇÇÇÇÇÇÆÆÆÇÇÇÅÅÅÀÀÀÌÌÌßßßâââÔÔÔ©©©¯¯¯¸¸¸ÑÑÑßßßêêêçççêêêØØØØØØßßßæææææææææâââÙÙÙÔÔÔÕÕÕÔÔÔÒÒÒÐÐÐÎÎÎÎÎÎÎÎÎâââÝÝÝÙÙÙÕÕÕÕÕÕØØØÙÙÙÛÛÛíííäääßßßàààâââêêêëëëÕÕÕ¾¾¾ÀÀÀÉÉÉÌÌÌÇÇÇÊÊÊÔÔÔ×××ÑÑÑßßßèèèàààØØØÙÙÙÜÜÜßßßÛÛÛæææíííçççããããããâââÝÝÝØØØÇÇÇÌÌÌÆÆÆ···ÑÑÑÙÙÙÛÛÛàààÛÛÛÔÔÔÍÍÍÃÃÃÆÆÆÌÌÌ»»»ÂÂÂÃÃÃÉÉÉÊÊÊÃÃÃÊÊÊÃÃÃÃÃÃÃÃÃÂÂÂÀÀÀÂÂÂÅÅÅÇÇÇÊÊÊÆÆÆÇÇÇÍÍÍÆÆÆ»»»¾¾¾ÇÇÇÊÊÊÉÉÉÌÌÌÒÒÒÕÕÕ×××ÛÛÛßßßÕÕÕÔÔÔÍÍÍ×××ÛÛÛÙÙÙââââââãããââââââàààààààààãããäääóóóõõõóóóòòòóóóööööööóóóõõõøøøöööàà྾¾ºººÂÂÂÅÅÅÆÆÆÇÇÇÉÉÉÉÉÉÉÉÉÍÍÍÒÒÒØØØâââßßßÙÙÙÀÀÀÅÅÅÍÍÍÜÜÜÕÕÕÍÍÍÉÉÉ¿¿¿ÆÆÆÇÇÇÆÆÆÌÌ̼¼¼ÃÃÃÌÌÌÉÉÉÇÇÇÑÑÑÎÎÎÀÀÀ¼¼¼ºººººº»»»¼¼¼¼¼¼¾¾¾¿¿¿¿¿¿¿¿¿ÀÀÀÂÂÂÅÅÅÆÆÆÆÆÆÆÆÆÅÅÅÅÅÅÃÃÃÂÂÂÀÀÀ¿¿¿ÀÀÀÂÂÂÃÃÃÆÆÆÊÊÊÊÊÊÅÅÅÃÃÃÆÆÆÆÆƾ¾¾ÅÅÅ···¸¸¸¾¾¾ÇÇÇÌÌ̺ºººººÀÀÀÅÅÅÇÇÇÌÌÌÎÎÎÎÎÎÍÍÍÎÎÎÔÔÔÑÑÑÍÍÍêêêõõõúúúæææçççøøøßßßØØØÝÝÝØØØÉÉÉÇÇÇÊÊÊÆÆÆÃÃÃÂÂÂÆÆÆÊÊÊÍÍÍÌÌÌÊÊÊÅÅÅÅÅÅÂÂÂÅÅÅÎÎÎ×××ÝÝÝãããâââàààßßßäääæææäääÛÛÛÕÕÕ×××ÙÙÙßßßäääæææææææææãããøøøöööóóóîîîèèèãããàààÝÝÝçççàààßßß×××ÕÕÕØØØØØØÝÝÝêêêãããßßßäääâââæææäää¼¼¼ÀÀÀÉÉÉÐÐÐÍÍÍÊÊÊÎÎÎÒÒÒÒÒÒÛÛÛëëëäääàààààààààëëëñññÛÛÛãããçççäääãããäääãããàààÙÙÙÌÌÌÅÅÅ···³³³ÑÑÑÜÜÜÕÕÕÉÉÉÇÇÇÆÆÆÇÇÇÇÇÇÎÎÎÒÒÒÌÌÌ¿¿¿¸¸¸ÃÃÃÊÊÊÍÍÍÊÊÊÀÀÀÅÅÅ¿¿¿ÀÀÀÃÃÃÃÃÃÃÃÃÃÃÃÆÆÆÇÇÇÍÍÍÇÇÇÇÇÇÍÍÍÉÉÉÀÀÀÃÃÃÍÍÍÒÒÒÐÐÐÑÑÑÕÕÕ×××ÕÕÕÕÕÕØØØÔÔÔÕÕÕÒÒÒßßßãããÝÝÝâââßßßÝÝÝÛÛÛÙÙÙÛÛÛàààèèèñññõõõîîîîîîíííèèèêêêîîîîîîèèèëëëäääßßßÉÉɳ³³µµµÆÆÆÇÇÇÇÇÇÇÇÇÉÉÉÊÊÊÎÎÎÔÔÔÛÛÛßßßßßßÝÝÝÔÔÔ¸¸¸ÅÅÅÑÑÑÜÜÜÑÑÑÎÎÎÍÍÍÊÊÊÊÊÊÆÆÆÉÉÉÒÒÒÌÌ̾¾¾Â»»»¾¾¾ÐÐÐÔÔÔÇÇǾ¾¾ºººººº»»»¼¼¼¼¼¼¾¾¾¿¿¿¿¿¿¿¿¿ÀÀÀÂÂÂÅÅÅÅÅÅÆÆÆÅÅÅÅÅÅÆÆÆÅÅÅÃÃÃÂÂÂÂÂÂÂÂÂÃÃÃÃÃÃÆÆÆÉÉÉÉÉÉÃÃÃÃÃÃÇÇÇÅÅÅÃÃÃÅÅÅ»»»ÅÅÅÍÍÍÎÎεµµ···¼¼¼ÀÀÀÇÇÇÉÉÉÅÅÅÃÃÃÆÆÆÇÇÇÑÑÑÌÌÌÅÅÅÝÝÝñññöööæææêêêùùùâââ×××ÛÛÛÒÒÒÌÌÌÍÍÍÒÒÒÙÙÙÐÐÐÆÆÆ¿¿¿¼¼¼»»»ÅÅÅÆÆÆÆÆÆÉÉÉÎÎÎÐÐÐÕÕÕÜÜÜæææçççäääÝÝÝâââèèèèèèßßßÕÕÕÙÙÙßßßãããççççççèèèêêêâââàààâââãããääääääææææææÛÛÛ×××àààÝÝÝÝÝÝàààÜÜÜçççêêêäääàààèèèäääæææßßßµµµÅÅÅÍÍÍÎÎÎÍÍÍÐÐÐÕÕÕÕÕÕÐÐÐÔÔÔêêêãããçççîîîäääèèèçççàààãããããããããääääääÝÝÝ×××ÐÐÐÍÍÍ¿¿¿¼¼¼ÎÎÎßßßæææÒÒÒÇÇÇÆÆÆÇÇÇÅÅÅÅÅÅÉÉÉ»»»ÃÃø¸¸ÀÀÀÅÅÅÅÅÅÆÆÆÀÀÀÃÃÃÅÅÅÆÆÆÉÉÉÉÉÉÇÇÇÇÇÇÇÇÇÉÉÉÎÎÎÊÊÊÊÊÊÍÍÍÊÊÊÆÆÆÊÊÊÔÔÔÔÔÔÑÑÑÑÑÑÔÔÔÔÔÔÐÐÐÐÐÐÒÒÒÙÙÙÜÜÜÙÙÙäääæææÝÝÝÝÝÝÙÙÙÕÕÕØØØÝÝÝäääêêêîîîîîîîîîõõõùùùöööòòòòòòõõõîîîäääÙÙÙÅÅž¾¾¾¾¾¼¼¼ÇÇÇÅÅÅÉÉÉÉÉÉÉÉÉÌÌÌÐÐÐ×××ÝÝÝâââæææäääÒÒÒºººÂÂÂÒÒÒ×××ÍÍÍÍÍÍÎÎÎÒÒÒÐÐÐÅÅÅÆÆÆÑÑÑÒÒÒÇÇÇÆÆƼ¼¼ºººÇÇÇÐÐÐÅÅÅ···ºººººº»»»¼¼¼¼¼¼¾¾¾¿¿¿¿¿¿¾¾¾¿¿¿ÀÀÀÂÂÂÃÃÃÃÃÃÃÃÃÅÅÅÇÇÇÆÆÆÅÅÅÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÆÆÆÆÆÆÉÉÉÅÅÅÇÇÇÇÇÇ¿¿¿ÅÅŵµµµµµÅÅÅÃÃÃÀÀÀ······³³³···¸¸¸¾¾¾¿¿¿»»»¾¾¾ÆÆÆÉÉÉÆÆÆÇÇǾ¾¾ÉÉÉäääòòòèèèçççíííßßßØØØÝÝÝÒÒÒÔÔÔÕÕÕÙÙÙÕÕÕÕÕÕÒÒÒÊÊʾ¾¾¼¼¼¼¼¼»»»ÀÀÀÆÆÆÆÆÆÉÉÉÕÕÕÜÜÜØØØÎÎÎÙÙÙäääÝÝÝääääääàààÐÐÐ×××ÜÜÜÝÝÝàààçççèèèèèèíííèèèçççäääãããâââàààßßßÜÜÜàààâââñññêêêçççîîîäääííííííæææâââäääãããæææÜÜÜ¿¿¿ÃÃÃÊÊÊÉÉÉÊÊÊÔÔÔÛÛÛØØØÔÔÔÐÐÐàààÝÝÝäääëëëâââàààÜÜÜâââààààààâââäääãããÛÛÛÑÑÑÊÊÊÇÇǸ¸¸¾¾¾ÙÙÙÝÝÝßßßÌÌÌÃÃÃÀÀÀÉÉÉÃÃÃÇÇÇÐÐÐÂÂÂÀÀÀÉÉɼ¼¼ÂÂÂÀÀÀ¾¾¾ÅÅÅÅÅÅÆÆÆÆÆÆÇÇÇÉÉÉÉÉÉÉÉÉÉÉÉÌÌÌÍÍÍÍÍÍÐÐÐÑÑÑÍÍÍÆÆÆÆÆÆÐÐÐÜÜÜ×××ÑÑÑÐÐÐÑÑÑÒÒÒÐÐÐÒÒÒ×××ÝÝÝßßßÙÙÙâââãããÜÜÜßßßÛÛÛßßßâââèèèïïïóóóòòòíííçççíííóóóóóóïïïíííêêêÛÛÛÊÊÊÇÇǺºº»»»»»»ÅÅÅ¿¿¿ÆÆÆÃÃÃÉÉÉÉÉÉÉÉÉÌÌÌÐÐÐÕÕÕÛÛÛÝÝÝäääçççÒÒÒÂÂÂÆÆÆ×××ÑÑÑÉÉÉÉÉÉÊÊÊÔÔÔÔÔÔÆÆÆÂÂÂÇÇÇÌÌÌÑÑÑÍÍÍÇÇÇÀÀÀÀÀÀÉÉÉÅÅÅ´´´ºººººº»»»¼¼¼¼¼¼¾¾¾¿¿¿¿¿¿¾¾¾¾¾¾¾¾¾¿¿¿ÀÀÀÂÂÂÃÃÃÃÃÃÇÇÇÇÇÇÆÆÆÅÅÅÅÅÅÃÃÃÃÃÃÃÃÃÆÆÆÃÃÃÉÉÉÇÇÇÊÊÊÃÃô´´¿¿¿ÎÎξ¾¾ººº±±±´´´¬¬¬¯¯¯ŸŸŸ¨¨¨¤¤¤©©©¯¯¯¯¯¯±±±³³³¬¬¬¼¼¼ÀÀÀ»»»ÉÉÉèèèóóóçççäääçççãããÜÜÜßßßÑÑÑØØØØØØÛÛÛÌÌÌÔÔÔØØØÑÑÑÌÌÌÍÍÍÎÎÎÊÊÊÆÆÆÃÃÃÇÇÇÇÇÇÅÅÅÐÐÐÙÙÙÑÑÑÎÎÎØØØèèèæææëëëâââÜÜÜÎÎÎÜÜÜâââßßßßßßæææçççäääêêêêêêçççääääääääääääâââßßßâââíííÿÿÿæææßßßïïïäääâââëëëâââßßßÝÝÝÝÝÝÜÜÜÍÍÍ¿¿¿¿¿¿ÆÆÆÅÅÅÇÇÇÒÒÒ×××ÕÕÕØØØ×××ÛÛÛØØØÜÜÜàààÝÝÝßßßÝÝÝÝÝÝßßßàààâââàààÝÝÝØØØÕÕÕÎÎο¿¿ÃÃÃÎÎÎãããââââââÔÔÔÊÊÊÃÃÃÎÎÎÆÆÆÊÊÊ×××ÅÅÅÇÇÇÎÎÎÂÂÂÇÇÇ¿¿¿ÇÇÇÉÉÉÇÇÇÂÂÂÂÂÂÃÃÃÃÃÃÅÅÅÉÉÉÍÍÍÑÑÑÌÌÌÕÕÕØØØÎÎÎÃÃÃÅÅÅÒÒÒàààØØØÒÒÒÐÐÐÑÑÑÒÒÒÔÔÔÙÙÙßßßßßßÝÝÝ×××ÝÝÝàààÜÜÜãããâââñññîîîêêêëëëïïïöööùùùüüüæææîîîñññíííèèèàààÌÌ̵µµ»»»¿¿¿ÆÆƸ¸¸¿¿¿»»»ÅÅÅÃÃÃÉÉÉÉÉÉÉÉÉÊÊÊÎÎÎÒÒÒ×××ØØØÍÍÍØØØÉÉÉÅÅÅÉÉÉÙÙÙÌÌÌÅÅÅÅÅÅÅÅÅÒÒÒÕÕÕÇÇǾ¾¾¼¼¼ÀÀÀÍÍÍÌÌÌÌÌÌÆÆÆ¿¿¿ÊÊÊÎÎÎÀÀÀºººººº»»»¼¼¼¼¼¼¾¾¾¿¿¿¿¿¿¾¾¾¼¼¼¼¼¼¼¼¼¾¾¾¿¿¿ÂÂÂÃÃÃÉÉÉÇÇÇÇÇÇÆÆÆÅÅÅÃÃÃÃÃÃÃÃÃÇÇÇÂÂÂÉÉÉÌÌÌÍÍÍÀÀÀªªª¸¸¸¾¾¾°°°···³³³°°°©©©ÇÇÇÕÕÕÝÝÝ×××ÛÛÛãããâââßßßÒÒÒ¾¾¾¸¸¸ººº¼¼¼×××úúúøøøääääääíííêêêàààßßßÌÌÌÕÕÕØØØÛÛÛØØØÝÝÝÜÜÜÒÒÒÒÒÒØØØÔÔÔÊÊÊÒÒÒ¿¿¿ÂÂÂÊÊÊÅÅÅÌÌÌØØØÕÕÕÙÙÙÕÕÕÜÜÜÕÕÕÜÜÜÒÒÒÜÜÜÝÝÝâââäääßßßÝÝÝæææäääâââæææèèèæææããããããääääääâââßßßâââëëëëëë¼¼¼´´´ÝÝÝäääçççæææÜÜÜÝÝÝØØØØØØÒÒÒºººµµµ¾¾¾ÅÅÅÅÅÅÇÇÇÐÐÐÐÐÐÐÐÐØØØÛÛÛØØØÙÙÙÝÝÝßßßààààààÝÝÝàààãããäääâââÛÛÛÔÔÔÒÒÒÔÔÔÊÊÊ´´´ÒÒÒäääíííãããÙÙÙÌÌÌÐÐÐÊÊÊÉÉÉÍÍÍÒÒÒÑÑÑÉÉÉ¿¿¿ÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÃÃÿ¿¿ÅÅÅÍÍÍÑÑÑÒÒÒÒÒÒÑÑÑÑÑÑ×××ØØØÔÔÔÍÍÍÌÌÌÒÒÒÙÙÙÜÜÜàààÐÐÐÔÔÔÒÒÒÔÔÔÔÔÔÍÍÍÙÙÙ×××ÝÝÝâââóóóííííííæææïïïîîîïïïòòòõõõöööøøøùùùùùùñññóóóõõõíííØØØÃÃþ¾¾ÃÃÿ¿¿ÀÀÀÀÀÀ¿¿¿¾¾¾¿¿¿ÂÂÂÅÅÅÉÉÉÆÆÆÅÅÅÇÇÇÌÌÌÑÑÑÒÒÒÔÔÔÛÛÛÔÔÔÀÀÀÃÃÃÆÆÆ×××ÎÎÎÆÆÆÉÉÉÑÑÑÑÑÑÒÒÒÎÎÎÎÎÎÍÍÍ···¸¸¸ÀÀÀÐÐÐÀÀÀ¾¾¾ÔÔÔÎÎξ¾¾»»»¼¼¼¼¼¼¼¼¼»»»»»»¾¾¾¿¿¿¼¼¼¼¼¼¼¼¼¼¼¼¾¾¾ÀÀÀÃÃÃÅÅÅÉÉÉÇÇÇÆÆÆÅÅÅÃÃÃÃÃÃÅÅÅÆÆÆÆÆÆÊÊÊÆÆÆÌÌÌÔÔÔÃÃó³³»»»»»»³³³°°°žžž©©©ÍÍÍÑÑÑ×××ÕÕÕÑÑÑ×××ãããÝÝÝÕÕÕÙÙÙØØØæææèèèèèèóóóõõõêêêäääëëëöööÜÜÜàààÒÒÒÔÔÔÝÝÝÕÕÕÙÙÙßßßÝÝÝÔÔÔÐÐÐÕÕÕÒÒÒÊÊÊÑÑÑÂÂÂÆÆÆÊÊÊÍÍÍÉÉÉâââÜÜÜØØØÑÑÑØØØÝÝÝØØØ×××ÝÝÝßßßâââßßßâââçççèèèææææææêêêäääàààßßßâââãããßßßßßßäääàààäääÝÝÝ»»»»»»±±±ÙÙÙÝÝÝÛÛÛ···³³³µµµ······°°°ºººÂÂÂÃÃÃÅÅÅÉÉÉÍÍÍÑÑÑÔÔÔ××××××ÙÙÙÛÛÛÝÝÝßßßàààààààààÛÛÛÝÝÝÜÜÜÕÕÕÒÒÒÔÔÔÑÑÑÌÌÌ···ºººÝÝÝâââÝÝÝæææÕÕÕÎÎÎÍÍÍÎÎÎÎÎÎÐÐÐÎÎÎÍÍÍÊÊÊÇÇÇ¿¿¿¿¿¿¿¿¿ÀÀÀÂÂÂÅÅÅÇÇÇÉÉÉÃÃÃÅÅÅÇÇÇÌÌÌÐÐÐÑÑÑÍÍÍÊÊÊØØØÙÙÙÕÕÕÍÍÍÌÌÌÑÑÑØØØÛÛÛÔÔÔÇÇÇÍÍÍÐÐÐÔÔÔÕÕÕÔÔÔààààààääääääóóóïïïõõõîîîòòòîîîîîîîîîïïïññññññïïïîîîöööîîîäääØØØÉÉÉ»»»¸¸¸¾¾¾¿¿¿¿¿¿¿¿¿¾¾¾¾¾¾¾¾¾ÂÂÂÅÅÅÇÇÇÆÆÆÆÆÆÇÇÇÌÌÌÐÐÐÒÒÒÔÔÔÍÍÍÆÆƺººÅÅÅÌÌÌÜÜÜÕÕÕÑÑÑÊÊÊÐÐÐÍÍÍÊÊÊÂÂÂÀÀÀÇÇǸ¸¸ÀÀÀÂÂÂÉÉɼ¼¼ÆÆÆÇÇǾ¾¾»»»¼¼¼¼¼¼¼¼¼»»»»»»¼¼¼¿¿¿¼¼¼¼¼¼¼¼¼¼¼¼¾¾¾ÀÀÀÃÃÃÅÅÅÉÉÉÇÇÇÆÆÆÅÅÅÃÃÃÃÃÃÅÅÅÆÆÆÆÆÆÉÉÉÆÆÆÍÍÍÕÕÕÆÆÆ´´´»»»Â¾¾¾´´´¬¬¬¦¦¦¾¾¾ÛÛÛÒÒÒ×××ÑÑÑÍÍÍÕÕÕãããæææãããäääãããëëëêêêêêêñññíííâââÜÜÜêêêïïïÛÛÛêêêÜÜÜÕÕÕÛÛÛÛÛÛÛÛÛßßßÜÜÜÒÒÒÐÐÐÕÕÕÕÕÕÐÐÐÊÊÊÀÀÀÇÇÇÌÌÌÎÎÎÌÌÌãããÛÛÛØØØ×××ÜÜÜÜÜÜ×××ÛÛÛâââßßßâââßßßàààãããàààÛÛÛÙÙÙÜÜÜâââãããäääæææãããÛÛÛÕÕÕÔÔÔãããäääÛÛÛ¸¸¸¸¸¸±±±ÕÕÕØØØÎÎεµµ´´´µµµ···¾¾¾¼¼¼Â¿¿¿ÂÂÂÅÅÅÉÉÉÍÍÍÑÑÑÒÒÒÔÔÔ×××ØØØÙÙÙÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛàààÕÕÕÑÑÑ×××ÔÔÔÉÉÉÂÂÂÅÅÅÉÉÉÊÊÊäääâââßßßæææÕÕÕÔÔÔÔÔÔÒÒÒÑÑÑÎÎÎÍÍÍÌÌÌÍÍÍÍÍÍÐÐÐÐÐÐÐÐÐÎÎÎÍÍÍÌÌÌÊÊÊÊÊÊÎÎÎÌÌÌÉÉÉÍÍÍÔÔÔÕÕÕÐÐÐÊÊÊÙÙÙÙÙÙÕÕÕÎÎÎÍÍÍÒÒÒØØØÙÙÙÛÛÛÐÐÐÒÒÒÑÑÑÑÑÑÑÑÑÑÑÑÜÜÜæææëëëëëëóóóëëëóóóèèèãããçççæææçççíííòòòöööõõõóóóäääØØØÌÌÌÃÃÿ¿¿¼¼¼¾¾¾¿¿¿¾¾¾¿¿¿¿¿¿¾¾¾¼¼¼¼¼¼ÀÀÀÃÃÃÆÆÆÆÆÆÉÉÉÉÉÉÊÊÊÍÍÍÐÐÐÒÒÒÃÃÃÃÃþ¾¾ÊÊÊÆÆÆÎÎÎÆÆÆÇÇÇÐÐÐÒÒÒÎÎÎÌÌ̾¾¾···¾¾¾µµµÊÊÊÆÆÆÃÃÃÅÅÅ»»»¸¸¸ÀÀÀ¿¿¿»»»¼¼¼¼¼¼»»»»»»»»»¼¼¼¿¿¿¾¾¾¼¼¼¼¼¼¼¼¼¾¾¾ÀÀÀÃÃÃÅÅÅÉÉÉÇÇÇÆÆÆÅÅÅÃÃÃÃÃÃÅÅÅÆÆÆÅÅÅÇÇÇÆÆÆÎÎÎÙÙÙÉÉÉ···»»»»»»ÀÀÀµµµªªªÊÊÊàààÎÎÎÑÑÑÐÐÐØØØâââäääãããâââÝÝÝêêêèèèçççêêêîîîçççÜÜÜÜÜÜÜÜÜãããÕÕÕçççÜÜÜÒÒÒÕÕÕ×××ÔÔÔÛÛÛßßßÛÛÛÙÙÙÛÛÛÕÕÕÌÌÌÃÃÃÃÃÃÍÍÍÎÎÎÑÑÑÎÎÎäääØØØÛÛÛÝÝÝàààÜÜÜØØØÝÝÝâââÛÛÛãããâââââââââßßßÝÝÝàààæææÛÛÛÝÝÝàààßßßØØØÔÔÔÒÒÒÐÐÐäääâââØØصµµ´´´¯¯¯ÊÊÊÊÊÊ°°°¨¨¨°°°´´´···ÀÀÀ¿¿¿»»»¾¾¾ÀÀÀÅÅÅÉÉÉÍÍÍÐÐÐÐÐÐÑÑÑÕÕÕÕÕÕ××××××××××××ÕÕÕÕÕÕ×××ÒÒÒÒÒÒÒÒÒÇÇǼ¼¼ÃÃÃÔÔÔÕÕÕØØØæææàààãããêêêÝÝÝäääãããÙÙÙÎÎÎÉÉÉÌÌÌÐÐÐÎÎÎÌÌÌÉÉÉÌÌÌÐÐÐÒÒÒÒÒÒÐÐÐÌÌÌÉÉÉÑÑÑÎÎÎÌÌÌÎÎÎÒÒÒÔÔÔÑÑÑÍÍÍ×××ØØØÕÕÕÐÐÐÎÎÎÕÕÕÙÙÙÙÙÙÙÙÙÒÒÒÑÑÑÑÑÑÒÒÒÔÔÔÙÙÙäääãããîîîññññññÝÝÝàààÔÔÔÉÉÉÂÂÂÃÃÃÇÇÇÒÒÒßßßèèèëëëëëëÊÊÊÅÅÅÀÀÀ¿¿¿ÀÀÀÂÂÂÀÀÀÀÀÀ¿¿¿¿¿¿¿¿¿¾¾¾¼¼¼¼¼¼¿¿¿ÂÂÂÃÃÃÆÆÆÊÊÊÊÊÊÊÊÊÌÌÌÍÍÍÐÐи¸¸¼¼¼ºººÆÆÆÇÇÇÔÔÔÍÍÍÊÊÊ××××××ÔÔÔ×××ÉÉÉ»»»»»»¯¯¯ÊÊÊÊÊÊÃÃÃÆÆƺºº³³³ÀÀÀ¾¾¾ººº»»»¼¼¼»»»ºººººº¼¼¼¿¿¿¾¾¾¾¾¾¾¾¾¾¾¾¿¿¿ÂÂÂÅÅÅÆÆÆÉÉÉÇÇÇÆÆÆÃÃÃÃÃÃÃÃÃÅÅÅÅÅÅÂÂÂÆÆÆÅÅÅÐÐÐÛÛÛÌÌ̺ºº¾¾¾¨¨¨¸¸¸³³³©©©¬¬¬ÂÂÂ×××ÌÌÌØØØÕÕÕÜÜÜÝÝÝÔÔÔÕÕÕßßßàààãããÝÝÝÝÝÝçççíííæææâââæææÝÝÝêêêâââíííããããããâââÝÝÝÑÑÑØØØÜÜÜÙÙÙØØØ×××ÐÐÐÇÇÇÆÆÆÊÊÊÔÔÔÑÑÑÒÒÒÐÐÐäääØØØÝÝÝßßßàààßßßÜÜÜÛÛÛÙÙÙ×××ÕÕÕÙÙÙßßßâââßßßÜÜÜÛÛÛÜÜÜàààßßßßßß×××ÍÍÍÐÐÐÕÕÕÕÕÕÜÜÜØØØÍÍͬ¬¬¨¨¨¤¤¤³³³°°°¥¥¥¦¦¦©©©ªªªµµµÀÀÀÃÃþ¾¾¿¿¿ÂÂÂÆÆÆÉÉÉÌÌÌÎÎÎÐÐÐÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÍÍÍÕÕÕÒÒÒÃÃû»»ÆÆÆÛÛÛçççÝÝÝàààæææßßßæææëëëàààëëëëëëßßßÑÑÑÊÊÊÊÊÊÍÍÍÎÎÎÍÍÍÉÉÉÌÌÌÍÍÍÎÎÎÎÎÎÌÌÌÉÉÉÆÆÆÉÉÉÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÌÌÌÌÌÌÑÑÑÔÔÔÒÒÒÑÑÑÒÒÒÙÙÙÜÜÜÛÛÛØØØÒÒÒÌÌÌÍÍÍÐÐÐÔÔÔßßßæææàààîîîòòòêêêÉÉÉÌÌÌÇÇÇÀÀÀÌÌÌÇÇÇÅÅÅÆÆÆÉÉÉÉÉÉÅÅÅÀÀÀÅÅÅÇÇÇÉÉÉÇÇÇÃÃÃÀÀÀ¾¾¾¼¼¼ÀÀÀÀÀÀÀÀÀ¾¾¾¼¼¼¼¼¼¿¿¿ÂÂÂÃÃÃÆÆÆÊÊÊÌÌÌÊÊÊÊÊÊÌÌÌÍÍÍÃÃÃÅÅŸ¸¸¾¾¾ÃÃÃÛÛÛ×××ÎÎÎÕÕÕÑÑÑÍÍÍÔÔÔÎÎÎÅÅű±±ÃÃÃÌÌÌÇÇÇÆÆÆ»»»ºººÆÆÆ»»»ººº»»»¼¼¼»»»ºººººº¼¼¼¾¾¾¿¿¿¾¾¾¾¾¾¾¾¾ÀÀÀÂÂÂÅÅÅÆÆÆÇÇÇÆÆÆÅÅÅÂÂÂÂÂÂÂÂÂÃÃÃÃÃÃÀÀÀÅÅÅÅÅÅÎÎÎÛÛÛÍÍͼ¼¼Â¢¢¢···µµµ©©©±±±ÊÊÊÕÕÕÛÛÛÕÕÕØØØ×××ÐÐÐ×××âââàààØØØÑÑÑÕÕÕäääêêêæææçççïïïÛÛÛâââÙÙÙäääÝÝÝàààÝÝÝÜÜÜÒÒÒÑÑÑÌÌÌÅÅÅÂÂÂÃÃÃÆÆÆÅÅÅÎÎÎÔÔÔÙÙÙÒÒÒÔÔÔÐÐÐâââØØØÙÙÙÕÕÕ×××àààâââÙÙÙ×××ÜÜÜàààêêêõõõùùùóóóçççÛÛÛÑÑÑÐÐÐÎÎÎÔÔÔÕÕÕÍÍÍÑÑÑÛÛÛÛÛÛàààÛÛÛÑÑÑ´´´¬¬¬©©©¨¨¨±±±¨¨¨¨¨¨°°°¯¯¯°°°¾¾¾ÆÆÆ¿¿¿¿¿¿¿¿¿ÀÀÀÃÃÃÉÉÉÍÍÍÐÐÐÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÔÔÔÔÔÔÕÕÕÑÑÑÕÕÕÊÊʸ¸¸¼¼¼ÔÔÔäääâââèèèèèèçççâââçççæææÛÛÛäääæææãããÛÛÛÑÑÑÉÉÉÇÇÇÌÌÌÐÐÐÔÔÔÑÑÑÎÎÎÌÌÌÊÊÊÉÉÉÉÉÉÉÉÉÊÊÊÍÍÍÎÎÎÎÎÎÌÌÌÊÊÊÍÍÍÎÎÎÍÍÍÑÑÑÒÒÒÔÔÔØØØÜÜÜÝÝÝÙÙÙØØØÔÔÔÉÉÉÊÊÊÎÎÎÑÑÑÜÜÜÝÝÝâââîîîïïïããã¾¾¾ÅÅÅÌÌÌÍÍÍÑÑÑÎÎÎÍÍÍÎÎÎÑÑÑÑÑÑÎÎÎÌÌÌÉÉÉÎÎÎÐÐÐÊÊÊÃÃÃÀÀÀÀÀÀÀÀÀÂÂÂÃÃÃÂÂÂÀÀÀ¾¾¾¾¾¾ÀÀÀÃÃÃÃÃÃÆÆÆÊÊÊÌÌÌÌÌÌÊÊÊÉÉÉÉÉÉÎÎÎÒÒÒÆÆÆ¿¿¿±±±¾¾¾¿¿¿ÃÃÃÇÇÇ»»»ÃÃÃÆÆÆÇÇÇÌÌ̼¼¼»»»ÇÇÇÊÊÊÃÃü¼¼ÃÃÃÇÇǸ¸¸ººº»»»»»»»»»ºººººº»»»¾¾¾¿¿¿¿¿¿¿¿¿¿¿¿ÀÀÀÃÃÃÆÆÆÇÇÇÆÆÆÅÅÅÃÃÃÀÀÀÀÀÀÀÀÀ¿¿¿ÅÅÅÃÃÃÌÌÌ×××ÌÌÌ¿¿¿ÉÉÉ°°°Â»»»³³³¬¬¬©©©ÂÂÂÙÙÙØØØÕÕÕÕÕÕØØØÙÙÙÝÝÝÙÙÙÐÐÐÒÒÒÍÍÍÕÕÕâââãããàààçççîîîíííãããÛÛÛîîîêêêçççàààèèèêêêçççâââÜÜÜÙÙÙÙÙÙÛÛÛÛÛÛ×××ÙÙÙÙÙÙÒÒÒÕÕÕÍÍÍÜÜÜÕÕÕÑÑÑÊÊÊÌÌÌÛÛÛäääÜÜÜÛÛÛèèèäääêêêëëëêêêçççâââÙÙÙÑÑÑÒÒÒÎÎÎÛÛÛæææÝÝÝÜÜÜâââÝÝÝâââÝÝÝ×××»»»±±±±±±¯¯¯ªªª¨¨¨¥¥¥©©©¸¸¸´´´µµµµµµ¿¿¿¾¾¾¼¼¼¾¾¾ÀÀÀÅÅÅÊÊÊÎÎÎÐÐÐÐÐÐÐÐÐÐÐÐÑÑÑÒÒÒÔÔÔÔÔÔÒÒÒÒÒÒÊÊÊÀÀÀ¿¿¿ÉÉÉÕÕÕÛÛÛèèèçççææææææèèèäääßßßãããßßßàààÝÝÝØØØÐÐÐÊÊÊÊÊÊÍÍÍÅÅÅÆÆÆÉÉÉÌÌÌÎÎÎÑÑÑÒÒÒÒÒÒÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÒÒÒÐÐÐÎÎÎÌÌÌÐÐÐÔÔÔ×××ÛÛÛßßßÛÛÛÕÕÕÔÔÔÒÒÒÉÉÉÐÐÐ×××ÙÙÙâââÜÜÜäääêêêíííæææÀÀÀÉÉÉÒÒÒÔÔÔÒÒÒÒÒÒÒÒÒÒÒÒÔÔÔÒÒÒÑÑÑÐÐÐÊÊÊÍÍÍÍÍÍÉÉÉÆÆÆÇÇÇÉÉÉÆÆÆÅÅÅÅÅÅÅÅÅÂÂÂÀÀÀÀÀÀÂÂÂÅÅÅÅÅÅÆÆÆÉÉÉÌÌÌÍÍÍÌÌÌÇÇÇÅÅÅÅÅÅÌÌÌÌÌÌÎÎθ¸¸±±±¯¯¯¼¼¼¸¸¸¸¸¸³³³···»»»ÅÅÅÐÐи¸¸¿¿¿ÉÉɼ¼¼ÇÇÇÅÅŸ¸¸ººº»»»»»»ººººººººº»»»¾¾¾ÀÀÀ¿¿¿¿¿¿¿¿¿ÀÀÀÃÃÃÆÆÆÇÇÇÅÅÅÃÃÃÀÀÀ¿¿¿¿¿¿¿¿¿ÀÀÀÀÀÀ¾¾¾ÅÅÅÃÃÃÉÉÉÒÒÒÇÇÇÀÀÀÐÐкººÉÉɼ¼¼´´´´´´¬¬¬³³³ÀÀÀÌÌÌÒÒÒÒÒÒÑÑÑÔÔÔÔÔÔÐÐÐÍÍÍÎÎÎÍÍÍØØØâââÜÜÜÛÛÛãããèèèëëëÜÜÜÒÒÒæææääääääÙÙÙâââßßßàààââââââàààÛÛÛ×××ÒÒÒÙÙÙØØØÕÕÕÑÑÑØØØÊÊÊÕÕÕÒÒÒÐÐÐÌÌÌÉÉÉÒÒÒàààßßßâââïïïëëëèèèäääàààãããêêêíííêêêíííÛÛÛßßßæææÙÙÙÒÒÒÙÙÙÙÙÙÔÔÔÐÐÐÊÊÊ°°°¦¦¦ªªª¨¨¨¨¨¨©©©¨¨¨¤¤¤ªªª¦¦¦¨¨¨¸¸¸µµµ¼¼¼¼¼¼»»»¼¼¼¿¿¿ÃÃÃÇÇÇÊÊÊÑÑÑÐÐÐÎÎÎÎÎÎÎÎÎÎÎÎÐÐÐÑÑÑÍÍÍÎÎÎÐÐÐÊÊÊ¿¿¿»»»ÍÍÍãããêêêääääääëëëëëëèèèèèèæææÜÜÜÛÛÛÙÙÙÙÙÙØØØÔÔÔÌÌÌÆÆÆÌÌÌÑÑÑØØØßßßâââßßßÛÛÛØØØØØØÔÔÔÐÐÐÑÑÑÔÔÔÒÒÒÌÌÌÅÅÅÌÌÌÑÑÑÕÕÕØØØÜÜÜßßßÙÙÙÑÑÑããããããÕÕÕÛÛÛÝÝÝÙÙÙÜÜÜÐÐÐãããæææëëëëëëÊÊÊÎÎÎÒÒÒÐÐÐÕÕÕÕÕÕÕÕÕÔÔÔÒÒÒÑÑÑÐÐÐÎÎÎÌÌÌÎÎÎÍÍÍÉÉÉÉÉÉÌÌÌÉÉÉÂÂÂÆÆÆÆÆÆÆÆÆÃÃÃÂÂÂÀÀÀÃÃÃÆÆÆÅÅÅÆÆÆÇÇÇÊÊÊÍÍÍÌÌÌÇÇÇÃÃÃÌÌÌÆÆÆÊÊÊãããÙÙÙÆÆƯ¯¯±±±°°°···µµµ······ÂÂÂÎÎκºº¸¸¸ÆÆÆ¿¿¿¼¼¼ÇÇÇÀÀÀ¸¸¸ºººººº»»»ººº¸¸¸ººº»»»¾¾¾ÀÀÀÀÀÀ¿¿¿ÀÀÀÂÂÂÃÃÃÆÆÆÇÇÇÃÃÃÂÂÂÀÀÀ¿¿¿¾¾¾¾¾¾¿¿¿¿¿¿¾¾¾ÅÅÅÂÂÂÇÇÇÐÐÐÆÆÆÂÂÂÔÔÔ···ÇÇǸ¸¸´´´»»»¯¯¯¢¢¢ŸŸŸ¤¤¤ÂÂÂÔÔÔÕÕÕÕÕÕÍÍÍÆÆÆÌÌÌÌÌÌÍÍÍÙÙÙàààØØØØØØâââäääëëëâââØØØããããããëëëÝÝÝÜÜÜàààààààààâââàààÜÜÜÙÙÙØØØØØØÔÔÔÑÑÑÑÑÑÙÙÙÉÉÉÑÑÑÐÐÐÔÔÔÒÒÒÌÌÌÍÍÍÛÛÛàààäääïïïÝÝÝÝÝÝÜÜÜÜÜÜãããëëëëëëäääÕÕÕ···°°°···¯¯¯³³³ÉÉÉÔÔÔÕÕÕÐÐÐÊÊʱ±±¨¨¨±±±¯¯¯´´´©©©¯¯¯©©©ªªª¨¨¨°°°Â···ººº»»»»»»¾¾¾ÀÀÀÃÃÃÆÆÆÇÇÇÑÑÑÐÐÐÎÎÎÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÌÌÌÊÊÊÊÊÊÇÇÇÀÀÀÂÂÂÕÕÕíííóóóêêêêêêñññëëëçççêêêãããæææÜÜÜàààãããÙÙÙ×××ÛÛÛÛÛÛÙÙÙ×××ÕÕÕ×××ÙÙÙÜÜÜÜÜÜÛÛÛâââÝÝÝÔÔÔÔÔÔÛÛÛÔÔÔÎÎÎÕÕÕÙÙÙÙÙÙÝÝÝÜÜÜÙÙÙßßßãããÝÝÝÌÌÌÎÎÎÑÑÑÒÒÒÙÙÙßßßÝÝÝ×××àààæææñññçççÉÉÉÒÒÒÊÊÊÎÎÎÐÐÐÑÑÑÔÔÔÔÔÔÔÔÔÑÑÑÎÎÎÌÌÌÍÍÍÔÔÔÍÍÍÍÍÍÌÌÌÉÉÉÐÐÐÃÃÃÀÀÀÆÆÆÉÉÉÆÆÆÃÃÃÆÆÆÉÉÉÆÆÆÅÅÅÅÅÅÆÆÆÆÆÆÆÆÆÆÆÆÅÅÅÅÅÅÅÅÅÐÐÐÌÌÌÉÉÉÆÆÆÌÌÌÍÍͪªª±±±¬¬¬±±±°°°´´´»»»ºººÂ¿¿¿°°°»»»ÀÀÀµµµÇÇÇ»»»»»»ººººººººººººººº»»»¼¼¼¾¾¾ÀÀÀÀÀÀ¿¿¿ÀÀÀÀÀÀÃÃÃÅÅÅÆÆÆÃÃÃÂÂÂÀÀÀ¾¾¾¾¾¾¾¾¾¿¿¿¿¿¿ÂÂÂÂÂÂÀÀÀÃÃÃÅÅÅÜÜÜÎÎÎÆÆƸ¸¸ÍÍÍÃÃþ¾¾°°°¯¯¯¿¿¿¤¤¤¥¥¥¿¿¿ÑÑÑÕÕÕÕÕÕÍÍÍÎÎÎÝÝÝÝÝÝâââÝÝÝÕÕÕ×××âââäääàààäääëëëÛÛÛÙÙÙßßßÝÝÝâââÝÝÝßßß×××ßßßæææÜÜÜ×××ØØØ×××ÙÙÙÎÎÎÕÕÕÙÙÙÎÎÎÐÐÐÛÛÛØØØÑÑÑÌÌÌÐÐÐæææÛÛÛßßßãããíííÜÜܸ¸¸±±±¼¼¼ÀÀÀÑÑÑÒÒÒ´´´¼¼¼¿¿¿Â¾¾¾µµµ¬¬¬¦¦¦ÐÐÐÀÀÀ°°°ªªª±±±···µµµ°°°°°°°°°°°°´´´¸¸¸ºººººº···¸¸¸¸¸¸ººº¼¼¼¿¿¿ÃÃÃÇÇÇÉÉÉÌÌÌÌÌÌÊÊÊÊÊÊÉÉÉÇÇÇÉÉÉÉÉÉÇÇÇÊÊÊÊÊÊÀÀÀºººÃÃÃÜÜÜòòòñññíííêêêêêêíííëëëçççãããâââÜÜÜãããçççßßßÙÙÙÙÙÙ×××ÛÛÛÙÙÙØØØÙÙÙÜÜÜÝÝÝÜÜÜÛÛÛßßßÛÛÛÒÒÒÒÒÒØØØÕÕÕÔÔÔÛÛÛÙÙÙÙÙÙÝÝÝÜÜÜØØØÝÝÝâââÜÜÜÕÕÕØØØØØØÕÕÕØØØÜÜÜÛÛÛ×××ÝÝÝæææòòòãããÌÌÌÐÐÐÊÊÊÇÇÇÎÎÎÐÐÐÒÒÒÒÒÒÑÑÑÎÎÎÌÌÌÉÉÉÉÉÉÎÎÎÇÇÇÉÉÉÊÊÊÇÇÇÍÍÍÃÃÿ¿¿¿¿¿ÀÀÀÅÅÅÉÉÉÊÊÊÉÉÉÆÆÆÇÇÇÉÉÉÊÊÊÊÊÊÉÉÉÇÇÇÆÆÆÆÆÆÌÌÌÌÌÌÎÎÎÊÊÊÎÎÎÜÜÜÔÔÔÀÀÀ°°°°°°°°°±±±´´´ºººÐÐл»»°°°¾¾¾ÂµµµÍÍÍ¿¿¿»»»ºººººººººººº»»»»»»¼¼¼¾¾¾ÀÀÀÀÀÀÀÀÀÂÂÂÃÃÃÃÃÃÅÅÅÅÅÅÂÂÂÀÀÀ¿¿¿¼¼¼¼¼¼¼¼¼¾¾¾¾¾¾¿¿¿ÂÂÂÂÂÂÅÅÅÆÆÆÙÙÙÇÇÇÀÀÀ¾¾¾¾¾¾»»»¿¿¿¸¸¸´´´ººº¯¯¯ªªªµµµÂÂÂÎÎÎ××××××ÑÑÑÑÑÑàààßßß×××ÍÍÍÐÐÐÜÜÜçççêêêèèèîîîßßßÛÛÛàààßßßãããßßßñññäääÝÝÝÝÝÝÜÜÜÝÝÝàààßßßÜÜÜØØØæææëëëÙÙÙÑÑÑ×××ÒÒÒÔÔÔ×××ÜÜÜÜÜÜÛÛÛóóóêêêäää¾¾¾´´´¼¼¼¿¿¿±±±···ÀÀÀ¸¸¸ÀÀÀÂÂÂÃÃþ¾¾¸¸¸³³³¯¯¯°°°¬¬¬¯¯¯´´´¸¸¸¸¸¸···¸¸¸······ººº¼¼¼¾¾¾¼¼¼ºººººººººººº¼¼¼¾¾¾ÂÂÂÅÅÅÆÆÆÊÊÊÉÉÉÉÉÉÇÇÇÆÆÆÅÅÅÅÅÅÆÆÆÃÃÃÆÆÆÃÃü¼¼ÅÅÅØØØèèèîîîíííëëëèèèêêêëëëëëëçççäääâââßßßäääçççàààÛÛÛÛÛÛØØØÜÜÜÜÜÜÛÛÛÜÜÜÝÝÝÝÝÝÜÜÜÛÛÛÛÛÛØØØÒÒÒÑÑÑ××××××ÙÙÙàààÛÛÛÙÙÙÝÝÝÝÝÝÙÙÙÝÝÝßßßØØØÊÊÊÐÐÐÑÑÑÐÐÐÒÒÒØØØÜÜÜÜÜÜàààèèèòòòØØØÇÇÇÉÉÉÌÌÌÆÆÆÍÍÍÎÎÎÑÑÑÑÑÑÐÐÐÍÍÍÉÉÉÆÆÆÆÆÆÊÊÊÃÃÃÅÅÅÆÆÆÃÃÃÅÅÅ¿¿¿ÊÊÊÃÃû»»¼¼¼ÅÅÅÊÊÊÉÉÉÉÉÉÇÇÇÉÉÉÌÌÌÍÍÍÍÍÍÌÌÌÉÉÉÇÇÇÉÉÉÆÆÆÅÅÅÍÍÍÉÉÉÅÅÅÔÔÔÛÛÛÒÒÒ´´´±±±µµµ´´´¸¸¸ÐÐл»»³³³¿¿¿Â···ÎÎλ»»»»»»»»ººº»»»»»»¼¼¼¾¾¾¿¿¿ÀÀÀÀÀÀÃÃÃÅÅÅÆÆÆÅÅÅÅÅÅÃÃÃÀÀÀ¿¿¿¾¾¾»»»»»»»»»¼¼¼¼¼¼¾¾¾ÀÀÀÀÀÀÆÆÆÆÆÆÕÕÕÀÀÀ»»»ÐÐл»»ºººÀÀÀÀÀÀ»»»³³³´´´¬¬¬¥¥¥¨¨¨³³³ÂÂÂÒÒÒÝÝÝÜÜÜÙÙÙÛÛÛÙÙÙØØØÜÜÜäääêêêíííæææêêêÙÙÙÔÔÔÛÛÛÛÛÛÜÜÜÙÙÙíííäää×××ÔÔÔàààëëëííííííàààÜÜÜäääãããÐÐÐÉÉÉÒÒÒ×××ÑÑÑÕÕÕàààÙÙÙÙÙÙäää¿¿¿µµµÂÂÂÂÂÂÊÊÊÌÌÌÂÂÂÂÂÂÆÆÆÅÅÅÇÇÇÆÆÆÅÅÅÃÃÿ¿¿¼¼¼¸¸¸···¥¥¥ªªª±±±´´´³³³³³³µµµººº¼¼¼¼¼¼¼¼¼¼¼¼¾¾¾¾¾¾»»»ººººººººº»»»»»»¼¼¼¿¿¿ÀÀÀÂÂÂÇÇÇÆÆÆÆÆÆÅÅÅÅÅÅÃÃÃÃÃÿ¿¿¼¼¼ÅÅÅ×××êêêïïïíííæææçççèèèêêêëëëêêêçççæææäääâââàààßßßÙÙÙØØØÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÙÙÙØØØ×××ÔÔÔÒÒÒÔÔÔ×××ÛÛÛàààÙÙÙÙÙÙßßßàààÜÜÜßßßÝÝÝÒÒÒÎÎÎÔÔÔ×××ÔÔÔÑÑÑÒÒÒ××××××èèèîîîíííÊÊÊÂÂÂÃÃÃÐÐÐÌÌÌÍÍÍÎÎÎÑÑÑÒÒÒÑÑÑÍÍÍÉÉÉÅÅÅÇÇÇÇÇÇÀÀÀÀÀÀÃÃþ¾¾»»»¼¼¼ØØØÕÕÕÆÆÆ»»»ÀÀÀÇÇÇÆÆÆÂÂÂÇÇÇÉÉÉÌÌÌÍÍÍÍÍÍÌÌÌÉÉÉÇÇÇÊÊÊÂÂÂÀÀÀÊÊÊÊÊÊÂÂÂÃÃÃÆÆÆ××׸¸¸°°°´´´»»»¸¸¸³³³¿¿¿ÇÇÇ···¿¿¿ÀÀÀ´´´ÊÊÊ¿¿¿¿¿¿»»»»»»»»»»»»¼¼¼¼¼¼¾¾¾¿¿¿ÀÀÀÂÂÂÅÅÅÇÇÇÇÇÇÆÆÆÅÅÅÃÃÃÂÂÂÀÀÀ¾¾¾¼¼¼»»»¼¼¼¼¼¼¾¾¾¼¼¼ÀÀÀÀÀÀÅÅÅÆÆÆÔÔÔ¿¿¿¾¾¾ÕÕÕÃÃü¼¼¼¼¼ÂÂÂÃÃþ¾¾»»»¿¿¿±±±¬¬¬©©©¦¦¦´´´ÇÇÇÊÊÊÛÛÛÛÛÛÙÙÙ×××ØØØÝÝÝæææêêêãããäääÙÙÙÑÑÑØØØÛÛÛÛÛÛÙÙÙæææèèèÜÜÜ×××äääëëëäääâââëëëããããããßßßÒÒÒÒÒÒàààèèèÜÜÜØØØàààââââââÕÕÕºººÇÇÇÉÉÉÇÇÇÇÇÇÉÉÉÍÍÍÍÍÍÇÇÇÅÅÅÌÌÌÊÊÊÇÇÇÅÅž¾¾»»»ººº³³³···ººº···±±±°°°···¾¾¾ººººººººº»»»»»»ººº¸¸¸¸¸¸»»»»»»»»»¼¼¼¼¼¼¾¾¾¾¾¾¾¾¾ÃÃÃÃÃÃÃÃÃÃÃÃÅÅÅÅÅÅÃÃÃÂÂÂÀÀÀ¼¼¼ÅÅÅÙÙÙèèèëëëëëëîîîâââäääçççêêêêêêèèèçççæææàààâââßßßÙÙÙ××××××ØØØÛÛÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØÔÔÔÑÑÑÔÔÔÙÙÙÜÜÜØØØÙÙÙàààãããààààààÜÜÜÎÎÎÒÒÒÛÛÛàààÝÝÝÙÙÙÛÛÛÜÜÜÜÜÜëëëîîîãããÃÃÃÂÂÂÃÃÃÑÑÑÍÍÍÍÍÍÐÐÐÒÒÒÔÔÔÒÒÒÐÐÐÊÊÊÇÇÇÅÅž¾¾¼¼¼ÀÀÀ»»»···ÃÃÃÝÝÝäääÒÒÒ»»»¼¼¼ÆÆÆÅÅÅÀÀÀÆÆÆÇÇÇÉÉÉÊÊÊÊÊÊÉÉÉÇÇÇÆÆÆÇÇÇÆÆÆÊÊÊÍÍÍÎÎÎÌÌÌÆÆÆÆÆÆÍÍÍ¿¿¿¼¼¼µµµ´´´···±±±···ÔÔÔ»»»¾¾¾¿¿¿°°°Â»»»Â»»»»»»»»»»»»¼¼¼¼¼¼¾¾¾¿¿¿ÀÀÀÃÃÃÆÆÆÉÉÉÉÉÉÆÆÆÃÃÃÂÂÂÃÃÿ¿¿¾¾¾¾¾¾¾¾¾¾¾¾¿¿¿¼¼¼Â¿¿¿ÃÃÃÇÇÇÔÔÔÂÂÂÆÆÆÅÅÅÉÉÉ»»»³³³ºººÉÉÉÎÎÎÃÃÃÆÆƾ¾¾¾¾¾¸¸¸ªªª©©©¯¯¯¬¬¬ØØØÝÝÝßßßÝÝÝÜÜÜàààããããããæææçççààà×××ÜÜÜàààßßßâââÝÝÝèèèäääÝÝÝäääæææßßßßßßäääßßßàààãããßßßÝÝÝâââãããÜÜÜâââæææäääÝÝÝÅÅž¾¾ÐÐÐÅÅÅÉÉÉÉÉÉÇÇÇÉÉÉÆÆÆÅÅÅÉÉÉÌÌÌÌÌÌÊÊÊÇÇÇÅÅÅ¿¿¿»»»¸¸¸ººº»»»ººº···µµµ···¼¼¼ÀÀÀ···¸¸¸ººº»»»»»»»»»»»»»»»¾¾¾¾¾¾¾¾¾¾¾¾¼¼¼¼¼¼¼¼¼¼¼¼ÂÂÂÀÀÀÀÀÀÃÃÃÇÇÇÇÇÇÆÆÆÅÅż¼¼ÇÇÇÜÜÜííííííæææäääëëëâââäääçççêêêêêêèèèçççæææÛÛÛàààßßßÛÛÛÙÙÙØØØÔÔÔÕÕÕ×××ØØØØØØ×××ÕÕÕÕÕÕØØØÙÙÙÙÙÙÙÙÙÙÙÙÔÔÔÌÌÌÐÐÐØØØÙÙÙÙÙÙÙÙÙàààãããàààâââÝÝÝÐÐÐÍÍÍ×××ÝÝÝÝÝÝÝÝÝàààããããããæææççç×××ÅÅÅÆÆÆÆÆÆÍÍÍÉÉÉÍÍÍÐÐÐÔÔÔÕÕÕÕÕÕÑÑÑÍÍÍÉÉÉÀÀÀ¾¾¾¼¼¼»»»ÀÀÀ»»»ºººÑÑÑÙÙÙãããÐÐз··»»»ÅÅÅÅÅÅÅÅÅÆÆÆÆÆÆÇÇÇÇÇÇÇÇÇÇÇÇÆÆÆÆÆÆÆÆÆÍÍÍÔÔÔÎÎÎÌÌÌÌÌÌÆÆÆÌÌÌÃÃÃÇÇÇÌÌ̸¸¸´´´···¿¿¿ÔÔÔ¼¼¼¼¼¼¼¼¼ÀÀÀ»»»ÀÀÀ»»»»»»ººº»»»»»»¼¼¼¾¾¾¿¿¿ÀÀÀÃÃÃÆÆÆÇÇÇÇÇÇÆÆÆÃÃÃÀÀÀÃÃÃÂÂÂÀÀÀ¿¿¿¾¾¾¾¾¾¿¿¿¿¿¿¼¼¼Â¼¼¼ÀÀÀÇÇÇÔÔÔÃÃÃÎÎλ»»ÌÌÌ°°°±±±ÀÀÀÉÉÉÂÂÂÀÀÀ»»»¼¼¼¾¾¾»»»ºººµµµºººÇÇÇÒÒÒÕÕÕÙÙÙâââäääâââàààäääãããØØØÙÙÙÝÝÝÙÙÙàààÛÛÛâââãããàààâââããããããçççàààÙÙÙÙÙÙßßßàààÝÝÝÝÝÝÝÝÝëëëÿÿÿÿÿÿæææ×××ÉÉÉÉÉÉÃÃÃÉÉÉÍÍÍÍÍÍÌÌÌÊÊÊÉÉÉÊÊÊÎÎÎÌÌÌÌÌÌÌÌÌÊÊÊÇÇǾ¾¾»»»¼¼¼»»»ººº»»»»»»»»»ººº¸¸¸¸¸¸»»»¾¾¾¿¿¿¿¿¿¿¿¿¿¿¿ÀÀÀ¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¾¾¾¼¼¼¼¼¼ÀÀÀ¿¿¿ÀÀÀÃÃÃÇÇÇÉÉÉÇÇÇÃÃ÷··×××ññññññèèèçççèèèçççæææçççèèèêêêëëëêêêçççæææÙÙÙãããàààÙÙÙÛÛÛÙÙÙÕÕÕ××××××××××××ÕÕÕÔÔÔÕÕÕÙÙÙÝÝÝÛÛÛÙÙÙÙÙÙÐÐÐÅÅÅÌÌÌÙÙÙÛÛÛÝÝÝÛÛÛßßßàààßßßãããàààÔÔÔÒÒÒÙÙÙÝÝÝÛÛÛØØØÛÛÛÜÜÜÛÛÛâââàààÆÆÆÂÂÂÅÅÅÆÆÆÇÇÇÆÆÆÊÊÊÍÍÍÒÒÒÕÕÕÕÕÕÒÒÒÍÍÍÊÊÊÅÅÅÀÀÀÀÀÀ»»»¿¿¿ººº···ØØØ×××ÕÕÕ¿¿¿±±±¼¼¼ÀÀÀ¿¿¿ÇÇÇÇÇÇÆÆÆÆÆÆÅÅÅÅÅÅÆÆÆÆÆÆÇÇÇÊÊÊÍÍÍÕÕÕÎÎÎÐÐÐÍÍÍ¿¿¿ÇÇÇÂÂÂÉÉÉÎÎξ¾¾µµµ¿¿¿ÀÀÀÆÆÆÅÅŸ¸¸¿¿¿ººº¬¬¬ÉÉÉÀÀÀ»»»ºººººººººººº»»»»»»¼¼¼¾¾¾ÂÂÂÃÃÃÆÆÆÆÆÆÆÆÆÅÅÅÃÃÃÀÀÀÂÂÂÀÀÀ¿¿¿¾¾¾¼¼¼¼¼¼¾¾¾¿¿¿»»»Â»»»ÀÀÀÇÇÇÒÒÒÂÂÂÐÐо¾¾ÌÌÌÎÎλ»»³³³µµµ···ÆÆÆÉÉÉÃÃúººµµµ»»»»»»µµµ´´´¨¨¨µµµººº±±±¸¸¸ÐÐÐààààààÜÜÜàààäääÕÕÕÒÒÒÕÕÕÎÎÎÙÙÙãããßßßààààààÛÛÛØØØÜÜÜÝÝÝæææàààÜÜÜÜÜÜÝÝÝßßßäääíííæææÝÝÝÛÛÛ¿¿¿¾¾¾ÅÅÅÍÍÍÆÆÆÌÌÌÉÉÉÉÉÉÌÌÌÊÊÊÌÌÌÌÌÌÇÇÇÊÊÊÌÌÌÌÌÌÌÌÌÊÊÊÇÇÇÃÃÃÂÂÂÂÂÂÀÀÀ¿¿¿¾¾¾¼¼¼»»»¸¸¸···»»»¾¾¾ÀÀÀÀÀÀÀÀÀÀÀÀÂÂÂÃÃÃÀÀÀÀÀÀÂÂÂÂÂÂÀÀÀ¿¿¿¾¾¾¼¼¼ÂÂÂÀÀÀÀÀÀÃÃÃÇÇÇÇÇÇÃÃÿ¿¿ºººÛÛÛòòòîîîèèèîîîñññêêêíííëëëèèèêêêëëëëëëçççäääßßßçççàààÕÕÕ×××ØØØØØØÜÜÜØØØØØØ×××ÔÔÔÔÔÔÕÕÕÛÛÛàààÜÜÜÙÙÙØØØÍÍÍ¿¿¿ÉÉÉÛÛÛÝÝÝâââÜÜÜÝÝÝÜÜÜÜÜÜããããããØØØÔÔÔÙÙÙÜÜÜÛÛÛÜÜÜâââææææææâââÜÜܸ¸¸¼¼¼¿¿¿ÃÃÃÅÅÅÉÉÉÇÇÇÌÌÌÑÑÑÕÕÕÕÕÕÒÒÒÍÍÍÊÊÊÍÍÍÇÇÇÆÆƾ¾¾¾¾¾µµµ³³³ØØØ×××ÉÉÉ°°°¾¾¾¼¼¼¸¸¸ÅÅÅÉÉÉÇÇÇÅÅÅÅÅÅÅÅÅÅÅÅÇÇÇÉÉÉÌÌÌÉÉÉÐÐÐÔÔÔßßßÛÛÛÃÃÃÇÇÇÆÆÆÅÅÅÉÉÉÃÃÃÆÆÆÐÐÐÉÉÉÆÆƳ³³µµµÂ¸¸¸ÒÒÒÆÆƵµµººººººººººººººº»»»¼¼¼¾¾¾ÂÂÂÃÃÃÅÅÅÆÆÆÆÆÆÅÅÅÂÂÂÀÀÀÀÀÀ¿¿¿¾¾¾¼¼¼»»»»»»¼¼¼¾¾¾ºººÂ»»»ÀÀÀÇÇÇÑÑѾ¾¾ÍÍÍÀÀÀÃÃÃ×××ÉÉɼ¼¼µµµ°°°ÕÕÕÆÆÆÅÅŸ¸¸±±±¸¸¸µµµ±±±···´´´ÅÅÅÅÅŵµµ¸¸¸ÎÎÎÜÜÜØØØßßßäääëëëÛÛÛÔÔÔÕÕÕÍÍÍØØØÙÙÙÎÎÎÔÔÔÜÜÜØØØ×××ÜÜÜÛÛÛÛÛÛÙÙÙØØØ××××××ØØØãããñññââ⺺ºÀÀÀ¼¼¼ÊÊÊÐÐÐÎÎÎÒÒÒÍÍÍÊÊÊÐÐÐÒÒÒÌÌÌÍÍÍÐÐÐÌÌÌÊÊÊÌÌÌÌÌÌÌÌÌÌÌÌÊÊÊÉÉÉÉÉÉÃÃÃÃÃÿ¿¿¼¼¼¼¼¼¿¿¿Â»»»¾¾¾ÀÀÀÀÀÀ¿¿¿¾¾¾¿¿¿ÂÂÂÀÀÀÂÂÂÃÃÃÃÃÃÂÂÂÀÀÀ¿¿¿¾¾¾ÃÃÃÀÀÀÀÀÀÂÂÂÆÆÆÅÅÅ¿¿¿»»»ÀÀÀ×××èèèëëëíííòòòõõõññññññíííêêêêêêíííëëëçççãããßßßààààààÝÝÝØØØ×××ÙÙÙÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÙÙÙÎÎÎØØØÕÕÕÉÉÉ×××ßßßßßßÜÜÜÝÝÝãããæææâââÜÜÜÜÜÜÛÛÛÜÜÜÙÙÙÕÕÕÙÙÙãããäääßßßÕÕÕ¾¾¾···ºººÃÃÃÀÀÀµµµÇÇÇÃÃÃÊÊÊÒÒÒÕÕÕÒÒÒÎÎÎÎÎÎÐÐÐÉÉÉÇÇÇÆÆƼ¼¼µµµ°°°¬¬¬ªªª¬¬¬±±±µµµ»»»¿¿¿ÃÃÃÃÃÃÃÃÃÂÂÂÂÂÂÀÀÀÂÂÂÅÅÅÆÆÆÇÇÇÔÔÔÊÊÊÐÐÐÝÝÝÛÛÛØØØÎÎÎÉÉÉÍÍÍÒÒÒ±±±ÆÆƼ¼¼ººººººÀÀÀÀÀÀ±±±¸¸¸ÆÆƼ¼¼´´´³³³´´´···¸¸¸ººº»»»¾¾¾ÀÀÀÂÂÂÃÃÃÅÅÅÆÆÆÅÅÅ¿¿¿¾¾¾¼¼¼»»»ºººººº»»»»»»ººº¸¸¸ººº»»»¸¸¸¿¿¿ÂÂÂÎÎÎÀÀÀÊÊÊÅÅÅÂÂÂÕÕÕÌÌÌ···¿¿¿¿¿¿»»»ÅÅÅÆÆÆ»»»¾¾¾±±±¸¸¸µµµ¾¾¾ººº¾¾¾Â¿¿¿¸¸¸´´´´´´µµµ±±±âââêêêëëëÎÎÎÙÙÙÎÎÎÙÙÙÛÛÛÔÔÔÙÙÙæææçççßßßÙÙÙÛÛÛÒÒÒÛÛÛÙÙÙãããäääàààæææÝÝÝ···¸¸¸¾¾¾ÃÃÃÉÉÉÎÎÎÑÑÑÔÔÔÎÎÎÎÎÎÎÎÎÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÊÊÊÊÊÊÉÉÉÉÉÉÇÇÇÆÆÆÆÆÆÅÅÅÅÅÅÃÃÃÃÃÃÂÂÂÀÀÀ¿¿¿¾¾¾¾¾¾¼¼¼¾¾¾¿¿¿ÂÂÂÂÂÂÂÂÂÀÀÀ¿¿¿ÃÃÃÃÃÃÂÂÂÂÂÂÂÂÂÃÃÃÃÃÃÃÃþ¾¾ÂÂÂÅÅÅÇÇÇÃÃø¸¸¿¿¿×××äääæææëëëñññíííâââÝÝÝààààààëëëëëëêêêîîîêêêãããèèèßßßàààâââßßßÙÙÙÙÙÙÜÜÜààààààßßßÜÜÜÙÙÙÙÙÙÜÜÜßßßâââÝÝÝÜÜÜÒÒÒÙÙÙ×××ÐÐÐÛÛÛßßßßßßÝÝÝàààããããããÝÝÝÙÙÙÛÛÛßßßßßßÜÜÜÙÙÙÙÙÙßßßãããããã»»»µµµºººººº¾¾¾¼¼¼¼¼¼ÕÕÕ¾¾¾ÅÅÅÎÎÎÔÔÔÒÒÒÐÐÐÎÎÎÎÎÎÊÊÊÉÉÉÆÆÆ»»»´´´¯¯¯¬¬¬ªªªªªª¬¬¬°°°µµµ»»»¿¿¿ÂÂÂÂÂÂÀÀÀ¿¿¿¿¿¿¿¿¿ÂÂÂÅÅÅÆÆÆÊÊÊÔÔÔÎÎÎ×××âââãããæææÜÜÜÌÌÌÃÃÃÇÇǵµµÐÐо¾¾ÃÃø¸¸ÀÀÀ¸¸¸¼¼¼Â¸¸¸µµµ³³³³³³´´´···¸¸¸¸¸¸ººº¼¼¼¿¿¿ÂÂÂÃÃÃÅÅÅÅÅÅÃÃÃÀÀÀ¾¾¾¼¼¼ººº···µµµµµµ···¸¸¸···µµµ»»»»»»¸¸¸¾¾¾¿¿¿ÊÊʸ¸¸¿¿¿ÍÍÍ¿¿¿ÎÎÎÐÐÐÆÆÆÊÊÊÆÆÆÀÀÀ¸¸¸ÃÃÿ¿¿¼¼¼±±±¼¼¼···³³³»»»¾¾¾ÀÀÀ¿¿¿»»»·········¸¸¸ÕÕÕÙÙÙëëëàààèèèÔÔÔÔÔÔ×××ÒÒÒØØØçççîîîæææÙÙÙÔÔÔßßßæææãããàààâââæææäää×××µµµ¸¸¸¼¼¼ÂÂÂÆÆÆÌÌÌÎÎÎÑÑÑÎÎÎÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÊÊÊÊÊÊÊÊÊÉÉÉÉÉÉÇÇÇÆÆÆÅÅÅÅÅÅÃÃÃÃÃÃÃÃÃÂÂÂÂÂÂÀÀÀÀÀÀ¿¿¿¿¿¿¿¿¿ÀÀÀÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÅÅÅÅÅÅÅÅÅ¿¿¿¼¼¼ÂÂÂÀÀÀ¸¸¸ÂÂÂÜÜÜîîîîîîíííëëëèèèãããÝÝÝÜÜÜßßßÝÝÝãããæææèèèëëëêêêçççêêêàààâââãããàààÝÝÝÝÝÝâââäääâââàààßßßÝÝÝÝÝÝßßßâââãããÜÜÜßßßÙÙÙÜÜÜÛÛÛÙÙÙààààààØØØÛÛÛâââæææãããÛÛÛØØØÙÙÙâââØØØÔÔÔÛÛÛãããäääÝÝÝÙÙÙ±±±···¿¿¿»»»¸¸¸µµµºººÑÑѺºº¿¿¿ÉÉÉÐÐÐÒÒÒÑÑÑÎÎÎÌÌÌÌÌÌÉÉÉÆÆÆ¿¿¿ººº³³³ªªªªªª©©©ªªª¯¯¯···¼¼¼¿¿¿¿¿¿¾¾¾¼¼¼»»»»»»¼¼¼ÀÀÀÅÅÅÇÇÇÊÊÊÎÎÎÎÎÎÔÔÔ×××ÛÛÛàààÕÕÕÇÇÇ···»»»ºººØØØÅÅž¾¾ÊÊÊ°°°ÀÀÀÀÀÀÀÀÀ¼¼¼¯¯¯°°°°°°±±±´´´···¸¸¸¸¸¸ººº»»»¾¾¾ÂÂÂÃÃÃÅÅÅÅÅÅ¿¿¿¼¼¼ººº¸¸¸µµµ´´´´´´µµµ······µµµººº»»»¸¸¸¿¿¿ÂÂÂÌÌÌ···»»»ÉÉÉ»»»ÊÊÊÜÜÜÝÝÝÛÛÛÍÍÍÀÀÀµµµÅÅÅÇÇÇÆÆƺºº¾¾¾¸¸¸´´´¼¼¼¾¾¾¾¾¾¾¾¾¾¾¾¼¼¼»»»»»»¸¸¸ÀÀÀ»»»ÔÔÔÛÛÛîîîäääèèèââââââãããæææèèèçççæææèèèâââââââââÜÜÜßßßàààÎÎο¿¿µµµ···»»»¿¿¿ÃÃÃÇÇÇÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÊÊÊÊÊÊÊÊÊÊÊÊÉÉÉÉÉÉÇÇÇÆÆÆÆÆÆÅÅÅÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÂÂÂÂÂÂÂÂÂÃÃÃÃÃÃÅÅÅÅÅÅÃÃÃÃÃÃÅÅÅÅÅÅÆÆÆÆÆÆÆÆÆÆÆÆÇÇÇ¿¿¿¼¼¼¾¾¾ÔÔÔíííóóóîîîîîîêêêãããÝÝÝÜÜÜÜÜÜÛÛÛÜÜÜÛÛÛâââèèèêêêêêêêêêçççâââãããäääãããââââââæææèèèàààâââãããäääãããâââßßßÜÜÜÛÛÛâââàààßßßßßßãããæææâââÊÊÊÐÐÐÜÜÜäääãããÝÝÝÝÝÝââââââÕÕÕÒÒÒÛÛÛÜÜÜÌÌ̺ºº°°°¸¸¸¾¾¾¾¾¾ººº»»»ººº¸¸¸ÀÀÀ¼¼¼¿¿¿ÅÅÅÌÌÌÐÐÐÑÑÑÍÍÍÊÊÊÊÊÊÇÇÇÃÃü¼¼µµµ°°°¬¬¬©©©©©©¨¨¨¨¨¨µµµ»»»¼¼¼»»»»»»¸¸¸···¸¸¸»»»ÀÀÀÅÅÅÆÆÆÇÇÇÆÆÆÊÊÊÎÎÎÌÌÌÑÑÑ×××ÍÍͼ¼¼°°°¸¸¸¾¾¾×××···ÇÇÇ°°°ÅÅÅÅÅÅÀÀÀººº¬¬¬°°°±±±´´´·········¸¸¸»»»¼¼¼ÂÂÂÃÃÃÅÅÅÃÃþ¾¾ººº¸¸¸ººº···´´´´´´···¸¸¸¸¸¸¸¸¸···¸¸¸¸¸¸ÃÃÃÊÊÊÔÔÔ¾¾¾¿¿¿ÆÆƼ¼¼ÇÇÇØØØÝÝÝÝÝÝÔÔÔÇÇDZ±±µµµ¾¾¾ÆÆÆÃÃÿ¿¿ÀÀÀÆÆÆ¿¿¿¾¾¾¼¼¼¾¾¾ÀÀÀÂÂÂÀÀÀ¿¿¿ÇÇÇÆÆƺººÂÂÂÀÀÀÒÒÒÒÒÒÛÛÛæææçççßßßÙÙÙÜÜÜßßßàààäääâââØØØÜÜÜàààäää×××µµµ¯¯¯···¸¸¸»»»¾¾¾ÂÂÂÆÆÆÉÉÉÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÊÊÊÊÊÊÊÊÊÌÌÌÊÊÊÊÊÊÉÉÉÇÇÇÇÇÇÆÆÆÆÆÆÅÅÅÅÅÅÅÅÅÆÆÆÆÆÆÆÆÆÆÆÆÇÇÇÆÆÆÅÅÅÂÂÂÂÂÂÂÂÂÃÃÃÅÅÅÆÆÆÃÃÃÅÅÅÆÆÆÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÃÃÿ¿¿ºººÃÃÃÝÝÝíííîîîîîîæææèèèèèèàààÝÝÝßßßÜÜÜ×××ÛÛÛÕÕÕßßßêêêèèèççççççßßßæææææææææäääãããäääçççèèèãããäääæææäääãããàààÜÜÜÙÙÙÜÜÜâââäääâââãããëëëêêêæææãããââââââßßßØØØÎÎÎÎÎÎÒÒÒÒÒÒÑÑÑØØØßßßÔÔÔ¾¾¾µµµ»»»ººº¿¿¿»»»ºººÂÂÂÂÂÂÀÀÀ¿¿¿ÅÅÅÃÃÃÅÅÅÉÉÉÍÍÍÐÐÐÍÍÍÊÊÊÇÇÇÅÅÅ¿¿¿ººº³³³¯¯¯¬¬¬ªªªªªª©©©©©©¯¯¯µµµºººººº···¸¸¸···´´´···¼¼¼ÀÀÀÅÅÅÆÆÆÅÅÅÃÃÃÌÌÌÐÐÐÍÍÍ×××ÙÙÙÐÐг³³µµµÅÅÅÆÆÆÔÔÔ¿¿¿³³³Â···ÉÉÉÃÃþ¾¾¸¸¸°°°±±±°°°³³³´´´·········¸¸¸ººº¼¼¼ÂÂÂÃÃÃÃÃÃÃÃÃÀÀÀ¾¾¾ººº······´´´³³³±±±´´´·········´´´···¸¸¸ÆÆÆÍÍÍ××׿¿¿ÀÀÀÉÉÉÆÆÆÃÃÃÃÃÃÅÅÅÑÑÑÜÜÜØØØÃÃõµµ°°°···ÃÃÃÃÃÿ¿¿¼¼¼¾¾¾ÂÂÂÆÆÆÆÆÆÅÅÅÉÉÉÎÎÎÇÇÇÅÅźººÃÃÿ¿¿»»»ÎÎÎàààæææãããâââÜÜÜÙÙÙâââçççÝÝÝâââçççêêêÕÕÕ³³³³³³¸¸¸ººº»»»¾¾¾ÂÂÂÆÆÆÉÉÉÌÌÌÊÊÊÊÊÊÊÊÊÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÌÌÌÌÌÌÊÊÊÉÉÉÇÇÇÇÇÇÆÆÆÆÆÆÆÆÆÇÇÇÇÇÇÉÉÉÉÉÉÉÉÉÊÊÊÇÇÇÅÅÅÃÃÃÂÂÂÀÀÀÂÂÂÅÅÅÆÆÆÆÆÆÆÆÆÆÆÆÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÆÆÆÀÀÀÂÂÂØØØòòòòòòäääâââäääçççäääÜÜÜÙÙÙÜÜÜÛÛÛÕÕÕÛÛÛÔÔÔÝÝÝêêêçççãããâââÙÙÙèèèèèèçççäääääääääæææççççççæææâââßßßÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝàààæææãããçççïïïëëëêêêêêêàààØØØÒÒÒÎÎÎÍÍÍÒÒÒÛÛÛ×××ÒÒÒÒÒÒÒÒÒÉÉɺºº¸¸¸ÀÀÀ»»»ÅÅÅ¿¿¿ÀÀÀÅÅÅÀÀÀÃÃÃÅÅÅÉÉÉÇÇÇÆÆÆÇÇÇÊÊÊÍÍÍÌÌÌÊÊÊÆÆÆÃÃþ¾¾¸¸¸´´´±±±±±±°°°¯¯¯¯¯¯³³³···ºººººº······µµµ´´´···¾¾¾ÃÃÃÅÅÅÃÃÃÆÆÆÅÅÅÎÎÎÎÎÎÎÎÎÔÔÔÍÍÍÅÅű±±ÀÀÀÒÒÒÑÑÑÔÔÔ³³³Â»»»ÊÊÊÃÃü¼¼ººº´´´···³³³´´´µµµ¸¸¸¸¸¸¸¸¸¸¸¸ººº¼¼¼ÂÂÂÂÂÂÃÃÃÃÃþ¾¾»»»¸¸¸µµµ³³³°°°¯¯¯±±±´´´µµµ···´´´¸¸¸»»»ÆÆÆÊÊÊÑÑѺºººººÃÃÃÌÌÌÇÇÇÀÀÀ¼¼¼ÅÅÅØØØÙÙÙÛÛÛÃÃñ±±¯¯¯ÇÇÇÒÒÒÐÐп¿¿ÅÅÅ¿¿¿¿¿¿ÃÃÃÇÇÇÊÊÊÊÊÊÃÃÃÇÇÇÇÇÇÉÉÉÅÅÅÎÎÎÉÉɼ¼¼»»»ÌÌÌÔÔÔÜÜÜçççæææãããîîîäääæææãããÝÝÝÝÝÝÍÍ͵µµ¸¸¸¸¸¸¸¸¸ººº¼¼¼ÀÀÀÅÅÅÉÉÉÌÌÌÊÊÊÊÊÊÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÌÌÌÊÊÊÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÊÊÊÊÊÊÌÌÌÌÌÌÌÌÌÉÉÉÇÇÇÅÅÅÃÃÃÃÃÃÅÅÅÆÆÆÇÇÇÉÉÉÇÇÇÇÇÇÆÆÆÆÆÆÆÆÆÇÇÇÇÇÇÇÇÇÂÂÂÒÒÒëëëñññëëëèèèçççëëëçççßßß×××ÔÔÔÕÕÕ×××ÕÕÕÙÙÙÕÕÕÜÜÜçççæææàààÝÝÝÜÜÜíííêêêçççäääããããããããããããäääâââÝÝÝÛÛÛÙÙÙÛÛÛÜÜÜÝÝÝàààÝÝÝæææäääèèèòòòëëëíííëëëÝÝÝÒÒÒÎÎÎÐÐÐÐÐÐÒÒÒ×××ÀÀÀ···±±±···»»»»»»¼¼¼ÀÀÀÀÀÀÊÊÊÃÃÃÆÆÆÆÆƼ¼¼ÀÀÀÅÅÅÆÆÆÆÆÆÆÆÆÇÇÇÊÊÊÊÊÊÊÊÊÉÉÉÆÆÆÃÃÿ¿¿ººº······¸¸¸¸¸¸´´´µµµ···ººº»»»¼¼¼»»»»»»···µµµµµµºººÀÀÀÅÅÅÅÅÅÂÂÂÅÅÅÆÆÆÍÍÍÉÉÉÍÍÍÎÎκºº´´´µµµÂÂÂÒÒÒÔÔÔÕÕÕ³³³ÆÆƸ¸¸ÊÊÊÃÃû»»ºººµµµººº···µµµ···¸¸¸ººº¸¸¸¸¸¸»»»¼¼¼ÀÀÀÂÂÂÃÃÃÃÃÿ¿¿¼¼¼ººº¸¸¸µµµ³³³±±±´´´¸¸¸ººº»»»¸¸¸¾¾¾¿¿¿ÉÉÉÊÊÊÐÐз··¸¸¸¼¼¼ÌÌÌÌÌÌÍÍÍÆÆÆÀÀÀÍÍÍÑÑÑÕÕÕ···°°°ÇÇÇÑÑÑØØØÑÑÑÆÆÆÃÃÃÂÂÂÂÂÂÅÅÅÉÉÉÌÌÌÍÍÍÐÐÐÌÌÌÍÍÍÎÎÎÊÊÊÍÍÍÍÍÍÅÅÅ¿¿¿¸¸¸ªªªµµµÑÑÑØØØÔÔÔÝÝÝÙÙÙâââÙÙÙ×××ÑÑѺºº···µµµµµµ···ººº¾¾¾ÃÃÃÇÇÇÊÊÊÊÊÊÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÎÎÎÐÐÐÐÐÐÎÎÎÍÍÍÌÌÌÌÌÌÊÊÊÊÊÊÊÊÊÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÌÌÌÊÊÊÉÉÉÇÇÇÇÇÇÇÇÇÉÉÉÉÉÉÌÌÌÊÊÊÇÇÇÅÅÅÃÃÃÅÅÅÆÆÆÇÇÇÇÇÇÉÉÉÜÜÜîîîîîîîîîòòòòòòêêêâââÛÛÛ×××ÕÕÕÔÔÔÔÔÔÕÕÕÕÕÕÔÔÔ×××ßßßäääßßßßßßèèèîîîëëëèèèäääãããâââààààààÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜâââÛÛÛääääääêêêòòòëëëïïïàààÕÕÕÎÎÎÒÒÒØØØØØØÔÔÔÒÒÒºººµµµµµµ¸¸¸»»»¼¼¼ÀÀÀÅÅÅÃÃÃÇÇǾ¾¾ÅÅÅÊÊÊ¿¿¿ÃÃÃÆÆÆÂÂÂÃÃÃÆÆÆÇÇÇÉÉÉÉÉÉÉÉÉÇÇÇÇÇÇÅÅÅÀÀÀ¼¼¼»»»»»»¾¾¾¿¿¿¸¸¸»»»¼¼¼¾¾¾¿¿¿¾¾¾¾¾¾¾¾¾···µµµ···»»»ÂÂÂÆÆÆÃÃÃÀÀÀ¿¿¿ÅÅÅÌÌÌÇÇÇÑÑÑÑÑÑ···´´´···¾¾¾ÊÊÊÒÒÒÔÔÔÀÀÀ±±±ÇÇÇ´´´ÉÉÉÅÅż¼¼¸¸¸µµµººº¸¸¸µµµ¸¸¸ºººººº¸¸¸ººº»»»¼¼¼ÀÀÀÂÂÂÃÃÃÃÃÃÃÃÃÀÀÀ¾¾¾»»»¿¿¿»»»¸¸¸¸¸¸»»»¾¾¾ÀÀÀ»»»ÀÀÀÅÅÅÍÍÍÍÍÍÒÒÒ»»»¾¾¾ÂÂÂÍÍÍÌÌÌÒÒÒÌÌ̼¼¼ÉÉÉÐÐÐÕÕÕÅÅÅÀÀÀ···»»»¯¯¯¼¼¼ÊÊÊÇÇÇÅÅÅÃÃÃÂÂÂÅÅÅÉÉÉÍÍÍÐÐÐÒÒÒÌÌÌÔÔÔÙÙÙÐÐÐÆÆÆÉÉÉÊÊÊÃÃÃÅÅźºº³³³´´´¬¬¬³³³ÒÒÒÔÔÔÜÜÜÔÔÔÜÜÜÔÔÔªªª¥¥¥¸¸¸³³³³³³´´´···»»»ÀÀÀÆÆÆÉÉÉÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÎÎÎÎÎÎÑÑÑÐÐÐÐÐÐÎÎÎÍÍÍÌÌÌÌÌÌÊÊÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÎÍÍÍÌÌÌÌÌÌÊÊÊÊÊÊÊÊÊÌÌÌÎÎÎÌÌÌÇÇÇÃÃÃÂÂÂÃÃÃÆÆÆÇÇÇàààëëëíííëëëîîîèèèßßßÝÝÝâââÙÙÙ×××ÛÛÛÛÛÛ×××ÔÔÔÕÕÕÑÑÑÒÒÒÑÑÑÙÙÙãããßßßâââõõõîîîèèèãããàààâââàààÝÝÝÙÙÙØØØÛÛÛ×××ØØØßßßàààÜÜÜßßßäääæææææææææíííõõõñññçççÕÕÕÔÔÔÔÔÔÕÕÕØØØÕÕÕÌÌÌÅÅž¾¾¼¼¼»»»¼¼¼¿¿¿ÃÃÃÇÇÇÊÊÊÃÃÃÀÀÀÂÂÂÉÉÉÌÌÌÇÇÇÃÃÃÃÃÃÉÉÉÉÉÉÊÊÊÌÌÌÌÌÌÊÊÊÊÊÊÉÉÉÆÆÆÅÅż¼¼µµµ···¿¿¿Â¿¿¿¿¿¿¾¾¾¾¾¾¿¿¿ÂÂÂÃÃÃÀÀÀ¿¿¿¾¾¾ÂÂÂÃÃþ¾¾¾¾¾ÂÂÂÇÇÇÂÂÂÅÅÅÊÊÊÆÆÆÑÑÑÒÒÒ»»»»»»»»»¸¸¸¿¿¿¼¼¼ÒÒÒµµµÃÃõµµÂÂÂÆÆƾ¾¾»»»¿¿¿¼¼¼´´´¸¸¸¸¸¸ººº»»»¼¼¼¾¾¾¿¿¿¿¿¿ÆÆÆÂÂÂÀÀÀÂÂÂÀÀÀ»»»¸¸¸¼¼¼»»»¾¾¾¾¾¾ÀÀÀÅÅž¾¾¼¼¼ÆÆÆÃÃþ¾¾ÃÃÃÅÅÅÎÎÎÎÎλ»»¿¿¿ÆÆÆÐÐÐ×××ÔÔÔÊÊÊÂÂÂÀÀÀÅÅÅÌÌÌ×××àààèèèÙÙÙÇÇDZ±±ÊÊÊÇÇÇÍÍÍÐÐÐÌÌÌÐÐÐÕÕÕÑÑÑØØØÎÎÎÎÎÎÑÑÑÐÐÐÔÔÔÒÒÒÉÉÉÇÇÇÃÃþ¾¾»»»ººº···±±±ÙÙÙÒÒÒâââÔÔÔ¯¯¯···ªªª³³³´´´»»»¸¸¸µµµ¿¿¿ÆÆÆÃÃÃÃÃÃÐÐÐÐÐÐÎÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÐÐÐÐÐÐÐÐÐÎÎÎÎÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÎÑÑÑÒÒÒÑÑÑÎÎÎÉÉÉÆÆÆÉÉÉÎÎÎÎÎÎÊÊÊÉÉÉÌÌÌÇÇǼ¼¼¿¿¿ÃÃÃÆÆÆÀÀÀÃÃÃèèèõõõúúúïïïîîîäääØØØßßßÛÛÛÔÔÔÜÜÜÜÜÜÜÜÜàààÛÛÛØØØàààÔÔÔÐÐÐÒÒÒ×××èèèçççÛÛÛóóóëëëçççãããâââàààßßßÛÛÛ×××ÐÐÐÙÙÙÙÙÙØØØÜÜÜÑÑÑÆÆÆÆÆÆÝÝÝâââæææèèèëëëëëëçççãããØØØÛÛÛàààäääãããØØØÇÇÇ»»»ÀÀÀÀÀÀÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÇÇÇÅÅÅÂÂÂÃÃÃÂÂÂÂÂÂÆÆÆÍÍÍÆÆÆÉÉÉÍÍÍÐÐÐÐÐÐÌÌÌÇÇÇÅÅÅÆÆÆÃÃþ¾¾¸¸¸ºººÀÀÀÃÃÃÀÀÀÅÅÅÃÃÃÀÀÀÀÀÀÂÂÂÅÅÅÆÆÆÆÆÆÆÆÆÀÀÀ¼¼¼¼¼¼ÀÀÀÅÅÅÃÃÃÂÂÂÇÇÇÇÇÇÌÌÌÆÆÆÍÍÍÑÑѼ¼¼µµµ»»»¾¾¾»»»ÂÂÂÒÒÒ¼¼¼¼¼¼¾¾¾»»»Â¼¼¼ººº¾¾¾¾¾¾¸¸¸ºººººº»»»¼¼¼¾¾¾¾¾¾¿¿¿¿¿¿ÅÅÅÂÂÂÂÂÂÃÃÿ¿¿ººº¸¸¸»»»ÂÂÂÃÃÃÅÅÅÉÉÉÍÍÍÍÍÍÊÊÊÉÉÉÇÇÇ¿¿¿ÂÂÂÅÅÅÐÐÐÎÎμ¼¼ÂÂÂÇÇÇÎÎÎÔÔÔÑÑÑÆÆƾ¾¾¾¾¾ÀÀÀÃÃÃÊÊÊÉÉÉÍÍÍÑÑÑÜÜÜàààÊÊÊÀÀÀ¼¼¼ÊÊÊØØØÔÔÔÊÊÊÌÌÌÍÍÍãããÍÍÍÍÍÍÜÜÜØØØÍÍÍÍÍÍÒÒÒÆÆƾ¾¾¼¼¼¾¾¾¾¾¾ºººµµµ¬¬¬ÑÑÑÔÔÔ¬¬¬³³³¬¬¬°°°³³³ººº¸¸¸···ÀÀÀÇÇÇÆÆÆÉÉÉÐÐÐÐÐÐÎÎÎÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÐÐÐÐÐÐÐÐÐÎÎÎÎÎÎÎÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÐÐÐÑÑÑÑÑÑÐÐÐÐÐÐÒÒÒÍÍÍÉÉÉÉÉÉÊÊÊÊÊÊÊÊÊÌÌÌÆÆÆÐÐÐÝÝÝäääîîîíííêêêöööêêêêêêàààààààààÝÝÝäääâââßßßàààØØØÒÒÒØØØÙÙÙØØØÜÜÜÕÕÕÒÒÒÒÒÒÕÕÕæææèèèßßßñññæææäääãããâââßßßÜÜÜØØØÕÕÕ×××ßßßØØØ×××âââÛÛÛÌÌÌÎÎÎàààãããêêêïïïëëëâââÝÝÝÝÝÝàààààààààÝÝÝÙÙÙÑÑÑÉÉÉÅÅÅÃÃÃÃÃÃÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÆÆÆÃÃÃÃÃÃÇÇÇÇÇÇÅÅÅÆÆÆÉÉÉÉÉÉÌÌÌÎÎÎÑÑÑÐÐÐÌÌÌÇÇÇÃÃÃÃÃÃÃÃÿ¿¿¼¼¼¾¾¾ÂÂÂÃÃÃÂÂÂÃÃÃÃÃÿ¿¿¼¼¼»»»»»»¼¼¼Â¿¿¿¼¼¼¾¾¾ÂÂÂÅÅÅ¿¿¿¿¿¿ÀÀÀÊÊÊÉÉÉÍÍÍÕÕÕÅÅű±±µµµ¾¾¾¸¸¸ÃÃÃÊÊÊ´´´¾¾¾µµµÃÃÃÀÀÀ¾¾¾»»»»»»¼¼¼¾¾¾¾¾¾»»»»»»¼¼¼¾¾¾¾¾¾¿¿¿ÀÀÀÀÀÀÅÅÅÃÃÃÅÅÅÅÅÅÀÀÀ»»»ººº¼¼¼¿¿¿ÅÅÅÉÉÉÆÆÆÂÂÂÆÆÆÐÐÐ×××ÍÍÍÃÃÃÃÃÃÉÉÉÑÑÑÌÌ̾¾¾ÆÆÆÎÎÎÔÔÔ×××ÑÑÑÆÆÆ¿¿¿¾¾¾ÀÀÀ¾¾¾ÉÉÉÅÅÅ¿¿¿ÅÅÅÙÙÙàààÅÅÅÃÃû»»ÀÀÀÎÎÎÑÑÑÐÐÐÕÕÕÛÛÛÙÙÙÐÐÐØØØçççäääØØØÔÔÔ×××ÊÊÊÆÆÆÂÂÂÂÂÂÃÃÃÃÃÃÀÀÀ¾¾¾³³³±±±×××ÜÜܱ±±´´´¸¸¸´´´»»»¼¼¼¼¼¼ÂÂÂÇÇÇÉÉÉÌÌÌÐÐÐÎÎÎÎÎÎÍÍÍÍÍÍÎÎÎÎÎÎÐÐÐÑÑÑÐÐÐÐÐÐÐÐÐÐÐÐÎÎÎÎÎÎÎÎÎÍÍÍÎÎÎÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÍÍÍÌÌÌÊÊÊÊÊÊÍÍÍÎÎÎÌÌÌÉÉÉ»»»âââøøøøøøóóóññññññîîîíííçççÙÙÙØØØÛÛÛÛÛÛßßßÛÛÛããããããØØØÎÎÎÒÒÒØØØÕÕÕÒÒÒÕÕÕÕÕÕÒÒÒÑÑÑâââêêêãããîîîããããããâââàààÝÝÝÙÙÙØØØ×××ÔÔÔÑÑѾ¾¾¿¿¿ÜÜÜãããÙÙÙÝÝÝãããÝÝÝàààæææâââÔÔÔÎÎÎÒÒÒãããàààØØØÎÎÎÇÇÇÅÅÅÆÆÆÉÉÉÇÇÇÆÆÆÅÅÅÅÅÅÇÇÇÊÊÊÍÍÍÐÐÐÇÇÇÃÃÃÅÅÅÌÌÌÐÐÐÌÌÌÆÆÆÃÃÃÐÐÐÎÎÎÍÍÍÌÌÌÊÊÊÉÉÉÇÇÇÇÇÇÂÂÂÂÂÂÀÀÀÀÀÀÀÀÀ¿¿¿ÃÃÃÇÇÇÉÉÉÇÇÇÅÅÅÃÃÃÅÅÅÃÃÃÊÊÊÐÐÐÎÎÎÆÆÆÃÃÃÆÆÆÌÌÌÒÒÒÎÎÎÎÎÎÉÉÉÍÍÍâââäääÑÑѵµµ»»»ÆÆÆÇÇÇÀÀÀ···»»»»»»ÇÇÇ¿¿¿»»»¼¼¼¿¿¿¼¼¼¾¾¾ÀÀÀ¾¾¾¾¾¾¾¾¾¿¿¿ÀÀÀÀÀÀÂÂÂÂÂÂÃÃÃÅÅÅÇÇÇÇÇÇÃÃÃÀÀÀÀÀÀÂÂÂÆÆÆÉÉÉÃÃúºº´´´°°°···ÆÆÆÍÍÍÉÉÉÉÉÉÎÎÎÐÐÐÃÃü¼¼ÉÉÉÒÒÒÔÔÔÔÔÔÎÎÎÆÆÆ¿¿¿¾¾¾¿¿¿ÇÇÇÙÙÙÙÙÙÎÎÎÇÇÇÒÒÒßßßÍÍÍÇÇÇÃÃÃÃÃÃÇÇÇÎÎÎÕÕÕÔÔÔÍÍÍÙÙÙæææèèèÝÝÝ×××ÛÛÛÙÙÙÍÍÍÑÑÑÌÌÌÇÇÇÅÅÅÆÆÆÅÅÅ¿¿¿···´´´ÍÍÍÕÕÕ¯¯¯°°°°°°¸¸¸···¼¼¼ÀÀÀÃÃÃÅÅÅÆÆÆÉÉÉÌÌÌÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÍÍÍÐÐÐÒÒÒÑÑÑÐÐÐÎÎÎÎÎÎÐÐÐÆÆÆÌÌÌÐÐÐÐÐÐÍÍÍÊÊÊÆÆÆÀÀÀÃÃÃëëëüüüüüüóóóñññúúúñññïïïêêêâââàààâââäääèèèèèèÛÛÛâââßßßÕÕÕÕÕÕÙÙÙÕÕÕÌÌÌÕÕÕØØØÒÒÒÎÎÎÝÝÝèèèçççëëëäääãããâââßßßÛÛÛØØØ××××××ÔÔÔÐÐп¿¿ÀÀÀÜÜÜäääÝÝÝààà×××ÉÉÉÃÃÃÌÌÌÍÍÍÆÆÆÂÂÂÇÇÇÃÃÃÆÆÆÊÊÊÌÌÌÌÌÌÎÎÎÔÔÔØØØÎÎÎÎÎÎÍÍÍÌÌÌÊÊÊÌÌÌÍÍÍÍÍÍÌÌÌÊÊÊÌÌÌÎÎÎÍÍÍÇÇÇÇÇÇÊÊÊÐÐÐÎÎÎÍÍÍÊÊÊÉÉÉÇÇÇÆÆÆÆÆÆÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀÀÀÀÀÀÀÃÃÃÆÆÆÊÊÊÊÊÊÇÇÇÅÅÅÅÅÅÅÅż¼¼ÃÃÃÆÆƼ¼¼©©©±±±¾¾¾ÌÌÌÍÍÍÍÍÍÊÊÊÌÌÌÜÜÜÝÝÝÆÆƸ¸¸»»»ØØØÌÌÌ»»»ÃÃúººÊÊÊÆÆƾ¾¾»»»ÀÀÀ¾¾¾¾¾¾ÂÂÂÀÀÀÀÀÀÀÀÀÀÀÀÂÂÂÂÂÂÃÃÃÃÃÃÂÂÂÆÆÆÉÉÉÊÊÊÉÉÉÇÇÇÇÇÇÇÇÇÍÍÍÃÃñ±±¯¯¯ººº±±±¬¬¬ºººÊÊÊÐÐÐÐÐÐÑÑÑÊÊÊ»»»»»»ÉÉÉÐÐÐÑÑÑÐÐÐÊÊÊÅÅÅ¿¿¿¾¾¾¿¿¿ÇÇÇÕÕÕØØØÒÒÒÆÆÆÍÍÍâââßßßÊÊÊÉÉÉÅÅÅÂÂÂÆÆÆÍÍÍÑÑÑÕÕÕÒÒÒÛÛÛÕÕÕÃÃÃÂÂÂÒÒÒâââæææÒÒÒÍÍÍÇÇÇÆÆÆÇÇÇÇÇÇÅÅż¼¼¼¼¼ÌÌÌßßßÍÍÍÃÃð°°´´´µµµºººÀÀÀÆÆÆÇÇÇÉÉÉÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÐÐÐÑÑÑÒÒÒÒÒÒÒÒÒÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÐÐÐÒÒÒÔÔÔÒÒÒÐÐÐÎÎÎÎÎÎÐÐÐÍÍÍÐÐÐÑÑÑÌÌÌÅÅÅÂÂÂÅÅÅÇÇÇèèèöööõõõøøøöööóóóöööçççÝÝÝÜÜÜÛÛÛÔÔÔÐÐÐÎÎÎÐÐÐÒÒÒÒÒÒßßßäääÜÜÜÕÕÕØØØØØØÑÑÑÔÔÔÙÙÙÒÒÒÎÎÎÙÙÙäääêêêèèèæææäääâââÝÝÝÛÛÛÕÕÕÑÑÑÎÎκºº¿¿¿¿¿¿ÀÀÀÆÆƺºº¸¸¸ÇÇǺºº´´´¾¾¾ÆÆÆÆÆÆÆÆÆÌÌÌÌÌÌÎÎÎÑÑÑÑÑÑÎÎÎÍÍÍÎÎÎÐÐÐÕÕÕÕÕÕÒÒÒÐÐÐÍÍÍÉÉÉÆÆÆÃÃÃÉÉÉÐÐÐÙÙÙÛÛÛÑÑÑÆÆÆÆÆÆÍÍÍÉÉÉÊÊÊÌÌÌÌÌÌÊÊÊÆÆÆÃÃÃÀÀÀÂÂÂÀÀÀÂÂÂÂÂÂÀÀÀ¼¼¼¼¼¼¿¿¿ÃÃÃÃÃÃÃÃÃÂÂÂÀÀÀÂÂÂÃÃÃÅÅÅÑÑÑÍÍ͵µµ¬¬¬¬¬¬µµµ¾¾¾ÐÐÐÝÝÝãããèèèçççàààÒÒÒµµµ³³³ºººÒÒÒÃÃ÷··ÆÆÆ···ÍÍÍÅÅÅ¿¿¿¾¾¾ÂÂÂÃÃÿ¿¿¿¿¿ÃÃÃÂÂÂÂÂÂÃÃÃÃÃÃÃÃÃÃÃÃÅÅÅÅÅÅÃÃÃÇÇÇÊÊÊÊÊÊÌÌÌÎÎÎÌÌÌÉÉÉÔÔÔÊÊÊ···¯¯¯´´´´´´ºººÌÌÌÉÉÉÒÒÒÍÍÍÊÊÊÃÃ÷··¾¾¾ÊÊÊÔÔÔÔÔÔÒÒÒÐÐÐÍÍÍÊÊÊÉÉÉÉÉÉÉÉÉÍÍÍÎÎÎÒÒÒÉÉÉÆÆÆÑÑÑÍÍÍÛÛÛ×××ÒÒÒÐÐÐÌÌÌÅÅÅÐÐÐäääÔÔÔÊÊÊÂÂÂÂÂÂÀÀÀ¾¾¾ÊÊÊãããÑÑÑÍÍÍÇÇÇÆÆÆÉÉÉÊÊÊÊÊÊÇÇǸ¸¸µµµ»»»ØØØ×××ÌÌÌ´´´´´´µµµ´´´¼¼¼ÆÆÆÇÇÇÊÊÊÐÐÐÑÑÑÍÍÍÍÍÍÍÍÍÎÎÎÐÐÐÑÑÑÒÒÒÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕ××××××××××××ÔÔÔÔÔÔÕÕÕÔÔÔÒÒÒÐÐÐÐÐÐÐÐÐÑÑÑÊÊÊÅÅÅÃÃÃÃÃÃÊÊÊÙÙÙèèèüüüøøøóóóöööïïïæææãããÛÛÛàààßßßâââØØØÎÎÎÌÌÌÆÆÆÌÌÌÑÑÑÙÙÙâââÜÜÜÒÒÒÕÕÕÜÜÜÛÛÛÒÒÒØØØÑÑÑÑÑÑ×××ßßßèèèæææçççäääâââßßßÙÙÙÑÑÑÆÆƾ¾¾¸¸¸¼¼¼ÆÆÆÇÇǾ¾¾···´´´°°°¾¾¾···¸¸¸ÀÀÀÉÉÉÊÊÊÍÍÍÒÒÒÕÕÕÔÔÔÒÒÒÑÑÑÐÐÐÐÐÐÒÒÒÔÔÔÔÔÔÑÑÑÍÍÍÉÉÉÇÇÇÇÇÇÊÊÊÌÌÌÎÎÎÒÒÒÛÛÛàààÛÛÛÎÎÎÆÆÆÆÆÆÆÆÆÇÇÇÉÉÉÉÉÉÇÇÇÅÅÅ¿¿¿ÂÂÂÀÀÀÀÀÀ¾¾¾¸¸¸¸¸¸¼¼¼¾¾¾¿¿¿ÂÂÂÆÆÆÊÊÊÌÌÌÊÊÊÉÉÉÃÃû»»°°°ªªªªªª°°°´´´···ÊÊÊ×××ÑÑÑÑÑÑÑÑÑÇÇÇÀÀÀ±±±°°°ÃÃþ¾¾¼¼¼¼¼¼ÇÇÇÂÂÂÉÉÉÃÃÃÂÂÂÀÀÀÂÂÂÀÀÀÀÀÀÂÂÂÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÆÆÆÉÉÉÊÊÊÉÉÉÍÍÍÐÐÐÊÊÊÃÃÃÒÒÒÑÑÑÎÎξ¾¾ªªª³³³ÉÉÉÐÐÐÊÊÊÑÑÑ»»»¼¼¼ºººÆÆÆÊÊÊÒÒÒÒÒÒÒÒÒÒÒÒÔÔÔÒÒÒÑÑÑÐÐÐÒÒÒÔÔÔÔÔÔÙÙÙÑÑÑÊÊÊÎÎÎÃÃÃÝÝÝâââãããçççâââÍÍÍÂÂÂÌÌÌÅÅÅÀÀÀÀÀÀÌÌÌÍÍÍ¿¿¿ÀÀÀØØØÕÕÕÐÐÐÊÊÊÇÇÇÊÊÊÌÌÌÌÌÌÊÊÊÀÀÀ´´´µµµÛÛÛâââãããÙÙÙÜÜÜ¿¿¿···ºººÂÂÂÂÂÂÇÇÇÐÐÐÑÑÑÌÌÌÌÌÌÍÍÍÎÎÎÐÐÐÒÒÒÔÔÔÕÕÕ××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØ×××ÕÕÕÕÕÕÔÔÔÒÒÒÑÑÑÎÎÎÌÌÌ¿¿¿¼¼¼ÍÍÍÜÜÜãããîîîúúúõõõíííõõõöööêêêääääääèèèÎÎÎÊÊÊÑÑÑÌÌÌÌÌÌÐÐÐÊÊÊÐÐÐÑÑÑÒÒÒÙÙÙÙÙÙÒÒÒÕÕÕÝÝÝÜÜÜÐÐÐÕÕÕÐÐÐÔÔÔ×××ÙÙÙçççæææèèèæææãããàààÙÙÙÍÍ;¾¾±±±ºººµµµ¼¼¼¿¿¿µµµ···¾¾¾¸¸¸´´´···¼¼¼ÃÃÃÆÆÆÇÇÇÊÊÊÎÎÎÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÍÍÍÆÆÆ¿¿¿»»»¿¿¿ÊÊÊ×××àààãããØØØÑÑÑÕÕÕÛÛÛ×××ÍÍÍÅÅÅÉÉÉÇÇÇÅÅÅÃÃÃÂÂÂÂÂÂÂÂÂÃÃÿ¿¿¿¿¿ÀÀÀ¼¼¼µµµµµµ»»»ÃÃÃÆÆÆÉÉÉÌÌÌÉÉɾ¾¾°°°¦¦¦ªªª¨¨¨¦¦¦ªªª°°°µµµ···µµµ¸¸¸ÅÅŸ¸¸¸¸¸¾¾¾´´´´´´±±±···×××´´´ÂÂÂÍÍÍÐÐÐ×××ÌÌÌÂÂÂÃÃÃÃÃÃÀÀÀ¿¿¿ÀÀÀÅÅÅÇÇÇÅÅÅÅÅÅÅÅÅÅÅÅÆÆÆÆÆÆÆÆÆÆÆÆÉÉÉÊÊÊÉÉÉÇÇÇÌÌÌÎÎÎÇÇǾ¾¾¯¯¯···ÎÎÎÊÊʵµµÊÊÊßßßÊÊÊÌÌÌÐÐи¸¸°°°¸¸¸¿¿¿ÌÌÌÊÊÊÆÆÆÇÇÇÉÉÉÊÊÊÍÍÍÎÎÎÍÍÍÊÊÊÌÌÌÎÎÎÊÊÊÌÌÌÇÇÇÊÊÊØØØÑÑÑÆÆÆÎÎÎÐÐÐØØØäääàààÍÍÍÃÃÃÊÊÊÔÔÔÒÒÒÍÍÍÌÌÌÅÅÅ¿¿¿ÆÆÆÛÛÛÕÕÕÎÎÎÊÊÊÊÊÊÌÌÌÉÉÉÇÇÇÇÇdz³³´´´ÛÛÛÛÛÛÝÝÝÛÛÛÙÙÙÊÊʼ¼¼ººº¾¾¾¼¼¼ÂÂÂÌÌÌÍÍÍÌÌÌÌÌÌÍÍÍÎÎÎÐÐÐÒÒÒÕÕÕ×××ØØØØØØÙÙÙÙÙÙÛÛÛÛÛÛÛÛÛÜÜÜÙÙÙØØØÕÕÕÕÕÕ×××ÕÕÕÑÑÑÎÎÎÉÉɼ¼¼ÂÂÂâââøøøöööîîîîîîùùùçççíííêêêàààâââÜÜÜßßßÑÑÑÇÇÇÌÌÌÇÇÇÌÌÌÒÒÒÊÊÊÍÍÍÐÐÐÌÌÌÔÔÔÙÙÙ×××ØØØÛÛÛØØØÎÎÎÔÔÔÐÐÐÕÕÕÕÕÕÕÕÕææææææÝÝÝÝÝÝãããÛÛÛÒÒÒÇÇǵµµ´´´µµµ»»»ÀÀÀÂÂÂÀÀÀ¾¾¾»»»»»»¸¸¸»»»¾¾¾ÂÂÂÇÇÇÍÍÍÒÒÒ××××××àààÜÜÜÒÒÒÔÔÔÕÕÕÒÒÒ××׿¿¿ÊÊÊÊÊÊÃÃû»»´´´µµµÇÇÇÌÌÌÉÉÉÍÍÍãããÕÕÕÐÐÐÀÀÀÅÅÅÃÃÃÂÂÂÀÀÀ¾¾¾¾¾¾¼¼¼¼¼¼»»»ÀÀÀÃÃÿ¿¿ººº¸¸¸······»»»ÊÊÊÎÎξ¾¾¯¯¯¯¯¯ªªª©©©¸¸¸¾¾¾¬¬¬¬¬¬ºººººº¿¿¿´´´···¼¼¼······¾¾¾¿¿¿ÍÍͼ¼¼ÀÀÀººº···ÊÊÊÌÌ̾¾¾ÀÀÀÂÂÂÃÃÃÃÃÃÅÅÅÅÅÅÅÅÅÅÅÅÉÉÉÉÉÉÅÅÅÅÅÅÌÌÌÉÉÉÇÇÇÒÒÒÒÒÒÅÅÅÐÐÐÉÉÉÌÌÌÑÑѸ¸¸µµµººº¿¿¿ÍÍÍÔÔÔÐÐÐÐÐÐÑÑÑÌÌÌØØØÊÊÊ»»»···¾¾¾ÅÅÅÆÆÆÃÃÃÀÀÀÃÃÃÃÃÃÅÅÅÅÅż¼¼ºººÅÅÅÃÃÿ¿¿ÀÀÀÅÅÅÃÃÃÆÆÆÐÐÐÐÐп¿¿ÆÆÆ×××êêêÆÆÆÉÉÉÙÙÙêêêèèèãããÕÕÕÅÅÅÀÀÀºººÔÔÔÐÐÐ×××ÑÑÑÍÍÍÎÎÎÆÆÆÍÍÍÊÊÊÀÀÀ···´´´ÐÐÐäääÛÛÛààààààÑÑÑ»»»···¾¾¾¾¾¾ÂÂÂÒÒÒÌÌÌÅÅÅÉÉÉÉÉÉÍÍÍÒÒÒÎÎÎÔÔÔÔÔÔÔÔÔÕÕÕØØØÛÛÛÜÜÜÝÝÝßßßÛÛÛÑÑÑÑÑÑ××××××ÙÙÙÔÔÔÆÆƼ¼¼ÇÇÇæææøøøòòòõõõõõõäääâââäääëëëäääããããããÑÑÑÆÆÆÉÉÉÊÊÊÊÊÊÌÌÌÌÌÌÍÍÍÎÎÎÎÎÎÎÎÎÑÑÑÊÊÊÙÙÙçççÛÛÛÒÒÒÒÒÒÕÕÕÐÐÐÍÍÍÎÎÎÑÑÑ×××âââîîîèèèßßßàààØØØÌÌ̾¾¾³³³»»»¼¼¼¿¿¿Â¿¿¿¼¼¼»»»»»»¼¼¼¼¼¼¿¿¿ÅÅÅÊÊÊÎÎÎÎÎÎÍÍÍÃÃÃÍÍÍÌÌÌÆÆÆÉÉÉÊÊÊÇÇÇÊÊÊÅÅÅÍÍÍÌÌÌÅÅÅÆÆÆÅÅÅ¿¿¿ÀÀÀ¾¾¾¼¼¼¾¾¾ÌÌÌãããÔÔÔÐÐÐÉÉÉÃÃÃÃÃÃÀÀÀ¿¿¿¾¾¾¾¾¾¾¾¾¾¾¾Â¼¼¼ººº¼¼¼»»»···¸¸¸¼¼¼¿¿¿Â¾¾¾±±±±±±´´´±±±ªªªÂÂÂÌÌ̺ºº±±±¸¸¸¸¸¸»»»¸¸¸¿¿¿ÃÃø¸¸µµµÃÃÃÎÎμ¼¼¸¸¸¸¸¸ÂÂÂÉÉÉÎÎÎÎÎÎÃÃÃÂÂÂÂÂÂÂÂÂÃÃÃÃÃÃÅÅÅÆÆÆÆÆÆÇÇÇÊÊÊÇÇÇÉÉÉÍÍÍÉÉÉÊÊÊÕÕÕÜÜÜÐÐÐØØØÑÑÑÐÐÐÎÎεµµµµµ¾¾¾¼¼¼ººº¿¿¿ÍÍÍÕÕÕÕÕÕÒÒÒÅÅž¾¾¸¸¸¼¼¼ÅÅÅÉÉÉÆÆÆÀÀÀ¿¿¿ÀÀÀ»»»»»»ÂÂÂÃÃÃÅÅÅÐÐÐÔÔÔÒÒÒÃÃÃÀÀÀÅÅÅ¿¿¿ÃÃÃÍÍÍÕÕÕÑÑÑÐÐÐÊÊÊÌÌÌãããÑÑÑØØØãããâââÝÝÝäääßßßÑÑÑÌÌÌ¿¿¿ÇÇÇÍÍÍÙÙÙÒÒÒÑÑÑ×××ÎÎÎÍÍÍÊÊÊÅÅÅ»»»´´´ÇÇÇßßßâââãããßßßàààÝÝÝØØØÍÍÍ»»»···ÆÆÆÆÆÆÆÆÆÊÊÊÃÃÃÆÆÆÒÒÒÒÒÒÕÕÕÑÑÑÔÔÔ×××ÕÕÕÔÔÔÕÕÕÙÙÙÝÝÝßßßÙÙÙàààäääÛÛÛÑÑÑÌÌÌÅÅÅÎÎÎÝÝÝñññõõõíííêêêèèèäääßßßÝÝÝãããÛÛÛ××××××ÍÍÍÌÌÌÊÊÊÊÊÊÊÊÊÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÊÊÊÍÍÍÊÊÊÛÛÛâââ×××ÒÒÒÑÑÑÐÐÐÍÍÍÌÌÌÎÎÎÑÑÑÔÔÔÜÜÜæææçççßßßÝÝÝÍÍͼ¼¼······ÂÂÂÂÂÂÂÂÂÃÃÃÀÀÀ¿¿¿¾¾¾¾¾¾¿¿¿¼¼¼ÃÃÃÊÊÊÉÉÉÅÅÅÅÅÅÊÊÊÑÑÑÇÇÇÎÎÎÍÍÍÉÉÉÉÉÉÆÆÆÃÃÃÃÃÃÅÅÅÐÐÐÔÔÔÔÔÔÙÙÙÒÒÒÅÅž¾¾ÃÃÃÀÀÀ»»»ÃÃÃÕÕÕÍÍÍÍÍÍÅÅÅÂÂÂÂÂÂÀÀÀ¿¿¿¿¿¿¿¿¿¿¿¿ÀÀÀÅÅż¼¼¼¼¼ÃÃÿ¿¿´´´³³³»»»ÊÊÊ»»»µµµ¼¼¼¸¸¸°°°¯¯¯ÀÀÀÐÐÐÀÀÀ´´´¸¸¸»»»¾¾¾¾¾¾Âººº¸¸¸ÂÂÂÉÉÉÃÃúººÊÊÊÔÔÔÆÆÆÃÃþ¾¾ÂÂÂÂÂÂÂÂÂÂÂÂÃÃÃÅÅÅÇÇÇÇÇÇÇÇÇÌÌÌÌÌÌÌÌÌÌÌÌÊÊÊÍÍÍØØØÙÙÙÍÍÍÕÕÕÑÑÑÐÐÐÎÎο¿¿ÆÆÆÃÃÃÃÃø¸¸µµµÌÌÌÛÛÛ×××ÒÒÒ¼¼¼»»»¼¼¼ÂÂÂÉÉÉÊÊÊÅÅž¾¾¾¾¾¿¿¿¸¸¸¸¸¸ÆÆÆÑÑÑÔÔÔØØØÜÜÜßßß»»»ÅÅž¾¾ÀÀÀÌÌÌÐÐÐÐÐÐÕÕÕÎÎÎÅÅÅâââÜÜÜâââÎÎÎÅÅÅÃÃÃÔÔÔÛÛÛßßßâââÍÍÍ»»»ÇÇÇ×××ÒÒÒÔÔÔÜÜÜÕÕÕÍÍÍÊÊÊÉÉÉ¿¿¿ººº¼¼¼ÑÑÑçççäääæææîîîñññêêêØØØÅÅÅÅÅÅÕÕÕääääääâââÉÉÉÀÀÀÍÍÍÍÍÍÎÎÎÎÎÎÑÑÑÕÕÕ×××ØØØÙÙÙÜÜÜßßßÛÛÛÜÜÜããããããÒÒÒÅÅÅÆÆÆÉÉÉâââòòòùùùòòòçççààààààæææñññæææäääÙÙÙÑÑÑÍÍÍÇÇÇÐÐÐÊÊÊÊÊÊÊÊÊÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÆÆÆÆÆÆÌÌÌÝÝÝÜÜÜÑÑÑÔÔÔÐÐÐÌÌÌÊÊÊÌÌÌÐÐÐÑÑÑÐÐÐÕÕÕÜÜÜÛÛÛÜÜÜßßßÅÅű±±ººº¿¿¿ÂÂÂÃÃÃÃÃÃÃÃÃÂÂÂÀÀÀÀÀÀÀÀÀ¾¾¾ÅÅÅÊÊÊÇÇÇÂÂÂÃÃÃÍÍÍ×××ÕÕÕ×××ÕÕÕÑÑÑÐÐÐÍÍÍÊÊÊÉÉÉÑÑÑÙÙÙØØØÕÕÕÛÛÛ×××ÊÊÊÃÃÃÌÌÌÍÍÍÀÀÀ¼¼¼ÆÆÆÊÊÊÎÎÎÀÀÀÃÃÃÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÃÃÃÃÃÿ¿¿ÂÂÂÅÅž¾¾´´´···Â¾¾¾´´´°°°···¼¼¼¾¾¾¼¼¼¾¾¾¸¸¸¬¬¬³³³ÀÀÀ»»»³³³ºººÀÀÀÆÆÆÆÆÆÃÃÃÀÀÀÅÅÅÎÎÎÌÌÌ¿¿¿ÌÌÌ¿¿¿¸¸¸ÌÌÌÑÑÑÃÃÃÃÃÃÆÆÆÃÃÃÂÂÂÂÂÂÀÀÀÂÂÂÅÅÅÉÉÉÊÊÊÉÉÉÍÍÍÎÎÎÍÍÍÊÊÊÌÌÌÒÒÒÛÛÛ¿¿¿µµµ¼¼¼»»»»»»»»»¸¸¸ÅÅÅÃÃÃÊÊÊÅÅŸ¸¸ÂÂÂÕÕÕÔÔÔÀÀÀ¾¾¾¾¾¾¾¾¾ÂÂÂÇÇÇÊÊÊÇÇÇÅÅż¼¼ÀÀÀ»»»¼¼¼ÐÐÐÜÜÜÛÛÛØØØ×××ÝÝݼ¼¼µµµÇÇÇÀÀÀÂÂÂÌÌÌÉÉÉÆÆÆÎÎÎÑÑÑÅÅÅÛÛÛÕÕÕÕÕÕÌÌÌÉÉÉÆÆÆÉÉÉÇÇÇØØØãããÆÆƺººÂÂÂÍÍÍÎÎÎÑÑÑ×××ÔÔÔÑÑÑÍÍÍÇÇÇÀÀÀÀÀÀ···ÃÃÃææææææêêêêêêëëëêêêãããÝÝÝâââîîîëëëíííëëëÔÔÔÅÅÅÇÇÇÀÀÀÂÂÂÍÍÍÎÎÎÑÑÑ×××ÜÜÜÝÝÝÜÜÜÙÙÙâââàààÙÙÙÌÌÌÂÂÂÉÉÉÛÛÛêêêïïïöööùùùïïïãããàààäääçççæææÔÔÔÐÐÐÌÌÌÊÊÊÉÉÉÇÇÇÔÔÔÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÃÃÃÃÃÃÍÍÍßßßÙÙÙÎÎÎÕÕÕÑÑÑÊÊÊÉÉÉÍÍÍÑÑÑÒÒÒÎÎÎÐÐÐÔÔÔÙÙÙÝÝÝæææÍÍ͵µµ¼¼¼ÃÃÃÅÅÅÆÆÆÆÆÆÅÅÅÃÃÃÃÃÃÀÀÀ¿¿¿¾¾¾Â¿¿¿¿¿¿ÅÅÅÍÍÍÑÑÑÑÑÑÎÎÎÐÐÐÍÍÍÍÍÍÎÎÎÎÎÎÎÎÎÎÎÎÍÍÍÒÒÒÛÛÛØØØÕÕÕÙÙÙ×××ÍÍÍÉÉÉÉÉÉÊÊÊ¿¿¿ÃÃÃÉÉÉÐÐÐÔÔÔÇÇÇÅÅÅÃÃÃÃÃÃÃÃÃÃÃÃÅÅÅÆÆÆÆÆÆÃÃÃÀÀÀ¾¾¾¼¼¼¼¼¼¿¿¿ÃÃÃÆÆÆ´´´ºººÃÃÃÉÉɾ¾¾ÌÌÌÝÝÝÉÉɳ³³···¸¸¸´´´ºººÂÂÂÂÂÂÆÆÆÀÀÀ»»»ÉÉÉØØØÍÍÍ´´´ÑÑѸ¸¸ÀÀÀÎÎÎÇÇÇÃÃÃÂÂÂÇÇÇÃÃÃÃÃÃÂÂÂÂÂÂÃÃÃÇÇÇÊÊÊÌÌÌÍÍÍÎÎÎÎÎÎÌÌÌÉÉÉÍÍÍÕÕÕÙÙÙÃÃÃÀÀÀÇÇÇÇÇÇÃÃÃÀÀÀ¾¾¾ÆÆÆÀÀÀÆÆÆÇÇǸ¸¸···ÕÕÕØØس³³¼¼¼¼¼¼¾¾¾¿¿¿ÂÂÂÅÅÅÇÇÇÇÇǾ¾¾ÀÀÀ»»»¼¼¼ÎÎÎÛÛÛ×××ÒÒÒÐÐÐÙÙÙÀÀÀ¼¼¼ÐÐÐÊÊÊÃÃÃÊÊÊÌÌÌÅÅÅÊÊÊÕÕÕÃÃÃÉÉÉÃÃÃÉÉÉÙÙÙÙÙÙØØØÒÒÒÃÃÃÌÌÌßßßÎÎÎÃÃÃÂÂÂÂÂÂÉÉÉÊÊÊÇÇÇÍÍÍÔÔÔÐÐÐÅÅÅÂÂÂÇÇÇ···¼¼¼àààçççææææææëëëñññïïïíííîîîïïïñññòòòùùùîîîßßßÑÑÑÀÀÀ¾¾¾µµµ»»»ÃÃÃÉÉÉÍÍÍÒÒÒØØØÝÝÝÜÜÜßßß×××ÊÊÊÐÐÐãããóóóùùùöööñññóóóîîîàààãããêêêàààãããÌÌÌÆÆÆÆÆÆÊÊÊÊÊÊÅÅÅÎÎÎÊÊÊÊÊÊÊÊÊÉÉÉÉÉÉÇÇÇÇÇÇÇÇÇÂÂÂÂÂÂÌÌÌßßßÙÙÙÎÎÎ×××ÒÒÒÌÌÌÌÌÌÐÐÐÔÔÔÔÔÔÐÐÐÐÐÐÒÒÒæææßßßêêêÝÝÝ»»»¿¿¿ÇÇÇÌÌÌÉÉÉÆÆÆÃÃÿ¿¿»»»¸¸¸¼¼¼¾¾¾ÃÃÃÌÌÌÒÒÒÔÔÔÐÐÐÊÊÊÎÎÎÇÇÇÊÊÊÎÎÎÌÌÌÊÊÊÊÊÊÇÇÇÊÊÊÕÕÕØØØÕÕÕØØØ×××ÐÐÐÎÎÎÇÇÇÀÀÀ¼¼¼ÔÔÔÔÔÔÐÐÐÍÍÍÉÉÉÅÅÅÅÅÅÃÃÃÃÃÃÃÃÃÅÅÅÅÅÅÆÆÆÆÆÆÅÅÅÀÀÀÀÀÀÅÅÅÅÅż¼¼°°°µµµ´´´´´´µµµ³³³³³³¼¼¼ÉÉÉÕÕÕ¸¸¸¼¼¼¿¿¿»»»¼¼¼ÂÂÂÌÌÌÒÒÒÍÍÍÅÅÅÌÌÌÑÑÑÃÃó³³ÌÌ̸¸¸ÊÊÊÑÑÑÃÃÿ¿¿ÀÀÀÃÃÃÃÃÃÃÃÃÅÅÅÆÆÆÉÉÉÌÌÌÍÍÍÐÐÐÍÍÍÍÍÍÌÌÌÊÊÊÑÑÑÕÕÕÑÑÑ¿¿¿ÆÆÆÎÎÎÐÐÐÌÌÌÇÇÇÅÅÅÅÅÅÉÉÉÃÃÃÅÅÅ»»»¼¼¼àààççç»»»¿¿¿ÀÀÀÂÂÂÀÀÀ¼¼¼ºººººº»»»¼¼¼¼¼¼µµµ¸¸¸ÇÇÇÐÐÐÎÎÎÎÎÎÒÒÒÙÙÙÐÐÐÊÊÊØØØÕÕÕÃÃÃÅÅÅÆÆÆÅÅÅÇÇÇÔÔÔÃÃÃÂÂÂÂÂÂÑÑÑÑÑÑÐÐÐÒÒÒØØØÊÊÊÇÇÇÝÝÝäääÑÑÑÉÉÉ¿¿¿ÆÆÆÅÅž¾¾ÉÉÉÔÔÔÑÑÑÃÃÃÃÃÃÇÇÇ»»»ÃÃÃâââêêêëëëíííóóóõõõëëëæææèèèèèèëëëèèèòòòóóóòòòñññçççëëëëëëïïïñññäääÔÔÔÊÊÊÍÍÍÔÔÔÎÎÎÔÔÔÎÎÎÍÍÍÝÝÝñññõõõòòòøøøíííïïïëëëÜÜÜàààçççÙÙÙçççÑÑÑÌÌÌÊÊÊÍÍÍÊÊÊ¿¿¿ÅÅÅÊÊÊÉÉÉÉÉÉÇÇÇÆÆÆÆÆÆÅÅÅÅÅÅÂÂÂÃÃÃÇÇÇÙÙÙÛÛÛÑÑÑ×××ÔÔÔÑÑÑÐÐÐÑÑÑÔÔÔÒÒÒÐÐÐÑÑÑ×××êêêÜÜÜçççßß߸¸¸¾¾¾ÇÇÇÌÌÌÇÇÇ¿¿¿¿¿¿¿¿¿¾¾¾¼¼¼»»»ÃÃÃÍÍÍÐÐÐÍÍÍÊÊÊÌÌÌÎÎÎÎÎÎÇÇÇÍÍÍÔÔÔÐÐÐÌÌÌÉÉÉÂÂÂÑÑÑÙÙÙÔÔÔÊÊÊÊÊÊÍÍÍÔÔÔÝÝÝÊÊÊ¿¿¿»»»ÙÙÙÒÒÒÉÉÉÅÅÅÃÃÃÃÃÃÂÂÂÂÂÂÀÀÀÀÀÀÂÂÂÂÂÂÃÃÃÆÆÆÅÅÅÅÅÅÇÇÇÃÃúºº°°°¬¬¬ÎÎθ¸¸ºººÂÂÂÆÆÆÃÃÃÀÀÀÕÕÕÍÍÍÇÇÇÆÆÆÅÅÅÂÂÂÆÆÆÍÍÍßßßßßßØØØÕÕÕ×××ÌÌÌÂÂÂÅÅŸ¸¸»»»ÉÉÉÌÌÌÂÂÂÃÃÃÆÆÆÅÅÅÃÃÃÅÅÅÆÆÆÇÇÇÉÉÉÌÌÌÍÍÍÎÎÎÎÎÎÊÊÊÌÌÌÎÎÎÐÐÐÕÕÕÒÒÒÅÅÅÅÅÅÎÎÎÒÒÒÐÐÐÐÐÐÔÔÔÕÕÕÒÒÒÎÎÎÅÅÅÅÅÅÃÃÃÅÅÅÛÛÛßßßÅÅÅÆÆÆÇÇÇÆÆÆÀÀÀººº···¸¸¸¼¼¼µµµ···µµµ¼¼¼ÊÊÊÌÌÌÉÉÉÍÍÍÒÒÒÕÕÕÜÜÜÔÔÔÛÛÛÛÛÛÀÀÀ¿¿¿ººº¿¿¿¼¼¼ÊÊÊÇÇÇÌÌÌÊÊÊ×××ÇÇÇÅÅÅÃÃÃÒÒÒÎÎÎÅÅÅÒÒÒÜÜÜÛÛÛÕÕÕÇÇÇÇÇÇÅÅž¾¾ÌÌÌÒÒÒÐÐÐÆÆÆÇÇÇÀÀÀ¾¾¾ÔÔÔêêêññññññïïïóóóîîîàààßßßçççêêêîîîçççêêêæææêêêòòòíííëëëîîîòòòòòòêêêÛÛÛÌÌÌÃÃÃÂÂÂÍÍÍÇÇǾ¾¾ÅÅÅÜÜÜêêêîîîòòòñññííííííäääØØØÛÛÛßßßÙÙÙÎÎÎÃÃÃÆÆÆÅÅÅÆÆÆÆÆÆÀÀÀÉÉÉÉÉÉÉÉÉÇÇÇÆÆÆÅÅÅÃÃÃÂÂÂÂÂÂÂÂÂÃÃÃÀÀÀÑÑÑÛÛÛÒÒÒÒÒÒÔÔÔÕÕÕÑÑÑÑÑÑÑÑÑÑÑÑÐÐÐÔÔÔÙÙÙâââØØØãããÕÕÕººº¸¸¸¿¿¿ÅÅÅÆÆƼ¼¼»»»¾¾¾ÀÀÀÃÃÃÅÅÅÉÉÉÊÊÊÊÊÊÉÉÉÇÇÇÇÇÇÊÊÊÎÎÎÆÆÆ¿¿¿ÉÉÉ×××ÔÔÔÐÐÐÍÍÍÅÅÅÐÐÐÛÛÛÙÙÙÍÍÍÉÉÉÉÉÉÎÎÎÙÙÙÇÇÇ¿¿¿¸¸¸ÑÑÑÉÉÉÇÇÇÇÇÇÃÃÃÂÂÂÀÀÀ¿¿¿¿¿¿¾¾¾¿¿¿¿¿¿¿¿¿Â¿¿¿ÀÀÀ¿¿¿³³³©©©´´´ÉÉɸ¸¸······»»»ÀÀÀÃÃÿ¿¿ÎÎÎÐÐÐÍÍÍÇÇÇÃÃÃÃÃÃÎÎÎÜÜÜÒÒÒÉÉÉÂÂÂÍÍÍÒÒÒÀÀÀ»»»ÌÌ̼¼¼ÎÎÎÌÌÌÆÆƾ¾¾¸¸¸ÀÀÀ¼¼¼ÃÃÃÅÅÅÆÆÆÉÉÉÌÌÌÍÍÍÎÎÎÎÎÎÍÍÍÇÇÇÌÌÌÑÑÑÔÔÔØØØÑÑÑ»»»ÂÂÂÌÌÌÆÆƼ¼¼»»»ÆÆÆÑÑÑÎÎÎÇÇÇÂÂÂÅÅÅÇÇÇÃÃÃÃÃÃÃÃþ¾¾ÃÃÃÅÅÅÅÅÅ¿¿¿»»»¿¿¿ÉÉÉÒÒÒ¯¯¯´´´»»»ÇÇÇÔÔÔÎÎÎÉÉÉÎÎÎÐÐÐÎÎÎàààÕÕÕØØØÜÜܾ¾¾»»»µµµ¿¿¿´´´ÃÃÃÍÍÍ×××ÊÊÊÊÊʾ¾¾¿¿¿¼¼¼ÊÊÊÒÒÒÎÎÎÑÑÑÒÒÒÝÝÝßßßÐÐÐÌÌÌÆÆÆÃÃÃÑÑÑÐÐÐÍÍÍÊÊÊÌÌ̺ºº¾¾¾ãããóóóöööêêêçççëëëëëëãããæææîîîëëëêêêëëëñññêêêïïïùùùêêêÜÜÜÜÜÜÝÝÝäääîîîóóóëëëØØØÇÇÇ¿¿¿»»»¾¾¾×××ñññîîîäääêêêçççíííëëëßßß××××××ÙÙÙßßßÌÌÌÇÇÇÐÐÐÌÌÌÆÆÆÆÆÆÃÃÃÎÎÎÉÉÉÇÇÇÆÆÆÅÅÅÃÃÃÂÂÂÀÀÀ¿¿¿ÀÀÀÃÃû»»ÊÊÊÛÛÛÒÒÒÐÐÐÒÒÒ×××ÒÒÒÐÐÐÐÐÐÎÎÎÎÎÎÔÔÔÜÜÜâââÜÜÜèèèÔÔÔ···»»»¾¾¾¼¼¼ÆÆÆ»»»ºººººº···¾¾¾ÅÅÅÂÂÂÃÃÃÊÊÊÍÍÍÌÌÌÌÌÌÎÎÎÌÌÌÆÆÆÉÉÉÍÍÍÑÑÑÑÑÑÎÎÎÍÍÍÎÎÎÑÑÑÝÝÝÑÑÑÌÌÌÔÔÔÕÕÕÎÎÎÌÌÌÐÐÐÑÑÑÜÜÜÔÔÔ¾¾¾ÉÉÉÔÔÔÅÅÅÆÆƼ¼¼»»»¿¿¿ÂÂÂÀÀÀ¿¿¿Â¼¼¼ÆÆÆÀÀÀ°°°ººº¿¿¿¸¸¸¼¼¼µµµµµµ´´´°°°»»»ÍÍÍÑÑÑÀÀÀÍÍÍÙÙÙßßßÜÜÜ×××ÔÔÔÔÔÔÅÅż¼¼ººº¾¾¾ÀÀÀ¿¿¿ÀÀÀÆÆÆ»»»ÆÆÆÌÌÌÇÇÇÀÀÀÀÀÀÂÂÂÃÃÿ¿¿ÍÍÍÇÇÇÊÊÊÎÎÎÇÇÇÊÊÊÐÐÐÊÊÊÌÌÌÉÉÉØØØÒÒÒÕÕÕÉÉÉÊÊÊÐÐÐÅÅÅÅÅÅÍÍÍÉÉÉ¿¿¿ÅÅÅÒÒÒÆÆÆÇÇÇÇÇÇÆÆÆÆÆÆÅÅÅÅÅÅÇÇÇÃÃÃÆÆÆÊÊÊÃÃø¸¸ÕÕÕÐÐÐÎÎÎÎÎÎÎÎÎÎÎÎÌÌÌÉÉÉÇÇÇÉÉÉÊÊÊÍÍÍÎÎÎØØØÎÎÎÙÙÙ×××´´´¼¼¼ÜÜÜØØØÎÎÎÂÂÂÀÀÀÇÇÇÉÉÉÅÅÅÂÂÂÔÔÔÑÑÑÃÃÃÊÊÊÕÕÕÑÑÑÉÉÉÕÕÕäääÍÍÍÊÊÊÃÃÿ¿¿ÝÝÝÔÔÔÑÑÑÍÍÍÆÆÆ···çççëëëïïïèèèïïïîîîêêêæææèèèïïïòòòïïïõõõíííñññîîîëëëæææÙÙÙÛÛÛ×××ÙÙÙâââíííòòòñññêêêäääÇÇǾ¾¾ãããæææàààèèèíííçççîîîëëëßßßØØØØØØÕÕÕÍÍÍÎÎÎÉÉÉÍÍÍÎÎÎÆÆÆÅÅÅÆÆÆ¿¿¿ÆÆÆÇÇÇÇÇÇÅÅÅÂÂÂÀÀÀÂÂÂÅÅÅ¿¿¿ÃÃÿ¿¿ÇÇÇÕÕÕ×××ÎÎÎÉÉÉÌÌÌÒÒÒ×××ÒÒÒÍÍÍÎÎÎÔÔÔäääÛÛÛâââ×××¼¼¼¸¸¸ÀÀÀ¿¿¿ººº¾¾¾Â¿¿¿ÃÃÃÆÆÆ¿¿¿ÉÉÉÊÊÊÉÉÉÇÇÇÆÆÆÉÉÉÊÊÊÉÉÉÔÔÔÑÑÑÍÍÍÇÇÇÃÃÃÆÆÆÍÍÍÔÔÔÝÝÝÔÔÔÐÐÐÑÑÑÑÑÑÉÉÉÂÂÂÂÂÂÊÊÊÔÔÔ×××ÀÀÀºººÊÊÊÌÌÌÉÉÉÉÉÉÆÆÆ¿¿¿ÀÀÀÃÃÃÆÆÆÇÇÇÇÇǾ¾¾³³³°°°³³³¸¸¸¼¼¼¾¾¾µµµ¾¾¾ÌÌÌÊÊʺºº¸¸¸ÆÆÆÍÍͼ¼¼ÃÃÃÌÌÌÐÐÐÐÐÐÊÊÊÃÃÿ¿¿ÉÉÉÅÅÅ¿¿¿»»»¼¼¼ÀÀÀÅÅÅÆÆÆÒÒÒÒÒÒÍÍÍÅÅÅÂÂÂÃÃÃÅÅÅÂÂÂÆÆÆÌÌÌÆÆÆÌÌÌÒÒÒÎÎÎÐÐÐÌÌÌÀÀÀÎÎÎÑÑÑÒÒÒÃÃÃÉÉÉÊÊÊÐÐÐÅÅÅÂÂÂÊÊÊÕÕÕÑÑÑÅÅÅÂÂÂÉÉÉÔÔÔÔÔÔÔÔÔÕÕÕÔÔÔÍÍÍÆÆÆÀÀÀÂÂÂÅÅÅÉÉÉÅÅż¼¼×××ÑÑÑÌÌÌÌÌÌÍÍÍÌÌÌÊÊÊÆÆÆÆÆÆÇÇÇÉÉÉÇÇÇÊÊÊÕÕÕÎÎÎÙÙÙÕÕÕµµµ»»»ÕÕÕ×××ÕÕÕÎÎÎÅÅÅÀÀÀÉÉÉÑÑÑÑÑÑ××××××ÐÐÐÍÍÍÔÔÔÒÒÒÊÊÊÎÎÎàààÍÍÍÍÍÍÃÃþ¾¾ÙÙÙÒÒÒÊÊÊÆÆÆ¿¿¿ÀÀÀçççîîîëëëëëëññññññïïïëëëëëëïïïïïïíííïïïàààÝÝÝÝÝÝâââæææÜÜÜÝÝÝäääâââÜÜÜØØØÝÝÝçççëëëêêêÛÛÛÆÆÆÍÍÍääääääÝÝÝâââçççòòòòòòêêêÜÜÜ×××ØØØÔÔÔÊÊÊÆÆÆÃÃÃÇÇÇÉÉÉÂÂÂÃÃÃÇÇÇÃÃÃÉÉÉÉÉÉÉÉÉÇÇÇÅÅÅÂÂÂÀÀÀÀÀÀÂÂÂÅÅÅ¿¿¿ÆÆÆÕÕÕÙÙÙÕÕÕÔÔÔÑÑÑÐÐÐÎÎÎÉÉÉÆÆÆÍÍÍÕÕÕßßßØØØÛÛÛÜÜÜÅÅŵµµ¼¼¼¼¼¼ÅÅż¼¼ººººººººº¿¿¿ÆÆÆÆÆÆÉÉÉÅÅÅÃÃÃÃÃÃÆÆÆÇÇÇÌÌÌÐÐÐÕÕÕÐÐÐÉÉÉÂÂÂÀÀÀÆÆÆÎÎÎÔÔÔàààØØØÑÑÑÐÐÐÑÑÑÑÑÑÑÑÑÒÒÒ»»»ÇÇÇÕÕÕÆÆÆ¿¿¿ÌÌÌÇÇÇÂÂÂÃÃÃÅÅÅÆÆÆÆÆÆÉÉÉÍÍÍÒÒÒÕÕÕ¼¼¼ºººµµµµµµ¼¼¼ÀÀÀ¾¾¾···´´´ÀÀÀÐÐÐÎÎξ¾¾»»»ÉÉÉÒÒÒÇÇÇ»»»ººº¾¾¾ÇÇÇÎÎÎÑÑÑÎÎÎÕÕÕÔÔÔÍÍÍÉÉÉÊÊÊÇÇÇÀÀÀÙÙÙÒÒÒÇÇÇÂÂÂÅÅÅÊÊÊÊÊÊÆÆÆÀÀÀÅÅÅÆÆÆÑÑÑÔÔÔÒÒÒØØØÐÐÐÙÙÙÎÎο¿¿ÃÃÃÇÇÇÐÐÐÅÅž¾¾»»»ÃÃÃÐÐÐÛÛÛÛÛÛÎÎÎÆÆÆÇÇÇÇÇÇÇÇÇÌÌÌÐÐÐÔÔÔÕÕÕÑÑÑÊÊÊÅÅÅÆÆÆÅÅÅÃÃü¼¼ÔÔÔÐÐÐÉÉÉÉÉÉÉÉÉÇÇÇÆÆÆÃÃÃÃÃÃÆÆÆÇÇÇÊÊÊÍÍÍ×××ÑÑÑ×××ÐÐб±±´´´ÒÒÒÒÒÒÕÕÕÕÕÕÍÍÍÅÅÅÌÌÌÙÙÙÔÔÔÌÌÌÑÑÑ×××ÑÑÑÒÒÒØØØÔÔÔÇÇÇÝÝÝÎÎÎÑÑÑÆÆƾ¾¾ÒÒÒÒÒÒÐÐÐÊÊÊ¿¿¿×××îîîùùùñññùùùõõõöööóóóëëëæææäääàààÜÜÜâââÜÜÜàààÛÛÛ×××ØØØØØØãããÝÝÝââââââÙÙÙÙÙÙãããëëëîîîñññææææææííííííääääääëëëããããããÜÜÜÔÔÔÔÔÔ×××ÎÎÎÃÃÃÇÇÇÆÆÆÉÉÉÇÇÇÂÂÂÀÀÀÅÅÅÃÃÿ¿¿¼¼¼ºººººº»»»¾¾¾¿¿¿ÀÀÀÅÅÅÆÆÆÃÃü¼¼¿¿¿ÌÌÌÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÐÐÐÊÊÊÆÆÆÇÇÇÌÌÌÔÔÔØØØÙÙÙàààÎÎκºº»»»°°°´´´³³³³³³µµµººº¿¿¿ÃÃÃÃÃÃÇÇÇ¿¿¿ÅÅÅÇÇÇÅÅÅÇÇÇÌÌÌÍÍÍÌÌÌÉÉÉÉÉÉÊÊÊÍÍÍÐÐÐÑÑÑÒÒÒÕÕÕØØØÙÙÙØØØÔÔÔÊÊÊÂÂÂÍÍÍÍÍÍÆÆƸ¸¸¾¾¾ÇÇÇÃÃÃÍÍͼ¼¼¸¸¸···±±±¬¬¬¯¯¯µµµ»»»ÆÆÆÅÅÅ»»»···¾¾¾ÅÅÅÆÆÆÉÉÉÍÍÍÉÉÉÀÀÀ¼¼¼¾¾¾ÀÀÀÌÌÌÍÍÍÎÎÎÎÎÎÌÌÌÆÆÆ¿¿¿»»»¿¿¿ÆÆÆÊÊÊÆÆÆÃÃþ¾¾ºººÑÑÑÊÊÊÃÃÃÂÂÂÆÆÆÊÊÊÉÉÉÅÅÅÉÉÉÎÎÎ×××àààÕÕÕÑÑÑÜÜÜ×××ÒÒÒÐÐÐÉÉÉÆÆÆÃÃÃÆÆÆÇÇÇÊÊÊÌÌÌÕÕÕÛÛÛàààâââÜÜÜØØØÝÝÝÎÎÎÌÌÌÌÌÌÉÉÉÅÅÅÊÊÊÎÎÎÊÊÊÉÉÉÇÇÇ¿¿¿¿¿¿¸¸¸ÐÐÐÎÎÎÉÉÉÆÆÆÆÆÆÃÃÃÂÂÂÀÀÀÂÂÂÅÅÅÆÆÆÌÌÌÎÎÎÕÕÕÑÑÑÕÕÕÎÎθ¸¸¸¸¸ÔÔÔÎÎÎÍÍÍÑÑÑÕÕÕÔÔÔÒÒÒÔÔÔÎÎÎÃÃÃÇÇÇÔÔÔÒÒÒÎÎÎÔÔÔÙÙÙÉÉÉàààÑÑÑÔÔÔÆÆÆÀÀÀÎÎÎÒÒÒÍÍÍÅÅÅ»»»âââèèèõõõèèèøøøãããççççççâââÝÝÝÝÝÝÝÝÝÜÜÜàààØØØÜÜÜÜÜÜÝÝÝßßßÙÙÙßßßÝÝÝßßßàààßßßÝÝÝÜÜÜÙÙÙØØØãããæææâââàààãããÝÝÝÛÛÛääääääßßß×××ÒÒÒ×××ÛÛÛÔÔÔÉÉÉÉÉÉÊÊÊÍÍÍÌÌÌÆÆÆÃÃÃÅÅÅÅÅÅÉÉÉÀÀÀ···±±±´´´»»»ÂÂÂÆÆÆÆÆÆÇÇÇÃÃû»»¸¸¸¾¾¾ÂÂÂÂÂÂÆÆÆÉÉÉÌÌÌÐÐÐÐÐÐÎÎÎÎÎÎÎÎÎÍÍÍØØØÛÛÛàààÕÕÕÊÊÊÇÇǵµµ¯¯¯¯¯¯¬¬¬¯¯¯µµµ»»»¿¿¿Â¼¼¼¼¼¼ÃÃÃÅÅÅÀÀÀ¼¼¼¾¾¾ÌÌÌÍÍÍÎÎÎÐÐÐÑÑÑÐÐÐÎÎÎÍÍÍÍÍÍÒÒÒØØØÛÛÛÛÛÛØØØÐÐÐÇÇÇÌÌÌÉÉÉÑÑÑ×××ØØØÉÉɳ³³µµµ¼¼¼°°°¯¯¯···¸¸¸´´´¾¾¾ÑÑѺºººººÂÂÂÀÀÀ¸¸¸¿¿¿ÐÐÐÅÅÅÇÇÇÉÉÉÊÊÊÌÌÌÇÇÇ¿¿¿ººº¾¾¾ÀÀÀÂÂÂÀÀÀÂÂÂÊÊÊÕÕÕßßß¾¾¾»»»»»»¼¼¼¼¼¼¾¾¾ÅÅÅÍÍÍÎÎÎÊÊÊÅÅÅÃÃÃÃÃÃÅÅÅÅÅÅÆÆÆÐÐÐÔÔÔ×××ÛÛÛÎÎÎÆÆÆÐÐÐÇÇÇÅÅÅÇÇÇÉÉÉÆÆÆÊÊÊÎÎÎ×××ØØØÐÐÐÒÒÒÉÉÉÃÃÃÆÆÆÆÆÆÌÌÌÙÙÙÜÜÜÛÛÛÙÙÙÎÎÎÀÀÀÃÃÃÍÍÍÊÊÊÀÀÀ¼¼¼ÃÃþ¾¾ÐÐÐÐÐÐÆÆÆÅÅÅÂÂÂÀÀÀ¿¿¿¿¿¿ÂÂÂÃÃÃÅÅÅÇÇÇÉÉÉÎÎÎÍÍÍÒÒÒÒÒÒÉÉÉÊÊÊÎÎÎÊÊÊÇÇÇÉÉÉÒÒÒÛÛÛÕÕÕÊÊÊÐÐÐÉÉÉÆÆÆÎÎÎÔÔÔÊÊÊÉÉÉØØØÍÍÍçççÕÕÕÔÔÔÆÆÆÉÉÉÎÎÎÒÒÒÉÉÉÃÃÃÅÅÅîîîêêêïïïâââëëëãããæææãããÜÜÜ×××××××××ÕÕÕÝÝÝÕÕÕÙÙÙÙÙÙÛÛÛÝÝÝÙÙÙàààßßßÕÕÕÐÐÐÔÔÔÙÙÙØØØÒÒÒÐÐÐÛÛÛäääâââßßßäääßßßÛÛÛãããêêêàààÔÔÔÍÍÍÑÑÑÕÕÕÑÑÑÉÉÉÆÆÆÉÉÉÊÊÊÊÊÊÇÇÇÅÅÅÂÂÂÃÃü¼¼µµµªªª¯¯¯···¿¿¿ÅÅÅÂÂÂÆÆÆÅÅÅ¿¿¿ººº¸¸¸¸¸¸¸¸¸ÕÕÕÔÔÔÐÐÐÍÍÍÊÊÊÊÊÊÇÇÇÆÆÆÌÌÌÕÕÕØØØÙÙÙØØØÙÙÙØØØÌÌÌÆÆÆ···°°°³³³´´´···»»»´´´³³³···¿¿¿ÅÅÅÅÅÅÂÂÂÀÀÀÕÕÕÕÕÕÔÔÔÑÑÑÎÎÎÍÍÍÌÌÌÌÌÌÔÔÔÒÒÒÒÒÒÕÕÕ××××××ØØØÛÛÛØØØÂÂÂÉÉÉÍÍÍÃÃÃÆÆÆÐÐÐÜÜÜÛÛÛÐÐÐÎÎÎÔÔÔÎÎμ¼¼¸¸¸ÀÀÀÉÉÉ»»»µµµ¾¾¾ÆÆÆÆÆÆÃÃÃÃÃþ¾¾ÃÃÃÅÅÅÆÆÆÌÌÌÌÌÌÌÌÌÑÑÑ»»»ÍÍÍØØØØØØÕÕÕÒÒÒÔÔÔÔÔÔÍÍÍÌÌÌÐÐÐÐÐÐÌÌÌÐÐÐÙÙÙÍÍÍÉÉÉÅÅÅÃÃÃÅÅÅÆÆÆÍÍÍÒÒÒÑÑÑÎÎÎÇÇÇÍÍÍÍÍÍÉÉÉÍÍÍÂÂÂÑÑѼ¼¼¾¾¾ÌÌÌÛÛÛÎÎÎÑÑÑÙÙÙàààÛÛÛÉÉɾ¾¾ÀÀÀ¿¿¿ÉÉÉàààÕÕÕÕÕÕÙÙÙÑÑÑÂÂÂÇÇÇÑÑÑÊÊʵµµ¿¿¿¾¾¾ÎÎÎÇÇÇÒÒÒÐÐÐÃÃÃÃÃÃÀÀÀ¾¾¾¼¼¼¿¿¿ÂÂÂÅÅÅÆÆÆÊÊÊÊÊÊÊÊÊÉÉÉÌÌÌÍÍÍÊÊÊÍÍÍÃÃÃÆÆÆÅÅÅÂÂÂÇÇÇÐÐÐÐÐÐÉÉÉÊÊÊÌÌÌÆÆÆÌÌÌÕÕÕÐÐÐÎÎÎÝÝÝÐÐÐííí×××ÑÑÑÆÆÆÔÔÔÑÑÑÑÑÑÆÆÆÇÇÇÛÛÛøøøïïïíííãããßßßÛÛÛÝÝÝÝÝÝÙÙÙÙÙÙßßßâââààààààØØØÙÙÙÒÒÒÌÌÌÌÌÌÌÌÌØØØÙÙÙÙÙÙÜÜÜÜÜÜØØØÒÒÒÕÕÕÙÙÙÌÌÌÔÔÔÔÔÔÒÒÒÕÕÕÐÐÐÊÊÊÐÐÐ×××ÒÒÒÐÐÐÐÐÐÒÒÒÑÑÑÊÊÊÂÂÂÉÉÉÌÌÌÇÇÇÃÃÃÃÃþ¾¾······±±±¯¯¯¬¬¬¬¬¬¯¯¯±±±´´´µµµ»»»¿¿¿ÅÅÅÃÃÃÀÀÀ¾¾¾»»»¸¸¸ÂÂÂÅÅÅÇÇÇÊÊÊÐÐÐÔÔÔÒÒÒÍÍÍÌÌÌÌÌÌÑÑÑÔÔÔØØØÜÜÜ×××ÔÔÔÐÐÐÒÒÒÌÌÌÇÇÇÉÉÉ······µµµ···ººº¿¿¿ÇÇÇÐÐÐÑÑÑÎÎÎØØØØØØÕÕÕÐÐÐÊÊÊÉÉÉÊÊÊÎÎÎÒÒÒÐÐÐÒÒÒØØØÒÒÒÇÇÇ¿¿¿¿¿¿âââÑÑÑÛÛÛØØØÇÇÇÇÇÇÅÅÅÀÀÀ»»»»»»¿¿¿ÅÅÅÅÅž¾¾···µµµ···ÀÀÀÇÇÇÅÅÅÀÀÀÀÀÀ¿¿¿ÆÆÆÊÊÊÆÆÆÀÀÀÂÂÂÃÃÃÇÇÇÒÒÒÊÊÊÎÎÎÒÒÒÕÕÕÔÔÔÒÒÒÔÔÔ×××ÕÕÕÒÒÒÑÑÑÑÑÑÐÐÐÍÍÍÊÊÊÉÉÉÉÉÉÃÃÃÀÀÀÅÅÅÊÊÊÌÌÌÐÐÐÕÕÕ×××ÕÕÕÇÇÇÊÊÊÒÒÒÑÑÑÒÒÒÍÍÍÉÉÉÃÃÃÒÒÒ×××ÎÎα±±ÀÀÀßßßÕÕÕÐÐÐÀÀÀ¼¼¼ÀÀÀ»»»ÂÂÂÜÜÜ×××ÑÑÑÔÔÔÍÍÍ¿¿¿ÅÅÅÉÉɺºº¾¾¾ÉÉÉÆÆÆÕÕÕÌÌÌÐÐÐÎÎÎÀÀÀÅÅÅÀÀÀ¼¼¼¼¼¼¿¿¿ÃÃÃÆÆÆÇÇÇÍÍÍÌÌÌÇÇÇÅÅÅÂÂÂÀÀÀÂÂÂÀÀÀ¾¾¾¿¿¿¿¿¿¾¾¾¾¾¾ÂÂÂÆÆÆÉÉÉÅÅÅÆÆÆÇÇÇÉÉÉÐÐÐÕÕÕÙÙÙÝÝÝÍÍÍíííÔÔÔÍÍÍÆÆÆßßßÔÔÔÎÎÎÃÃÃÇÇÇäääëëëæææÝÝÝãããÕÕÕâââäääâââÝÝÝÝÝÝßßßÝÝÝÙÙÙäääÒÒÒÌÌÌÇÇÇÊÊÊÍÍÍÅÅÅÆÆÆÒÒÒäääëëëàààÔÔÔÔÔÔ××××××ÔÔÔ××××××ØØØ×××ÑÑÑÍÍÍÐÐÐÍÍÍÎÎÎÒÒÒÕÕÕ×××ÔÔÔÎÎÎÊÊÊÌÌÌÌÌ̼¼¼ÀÀÀ¾¾¾···¸¸¸ÇÇÇÆÆÆÅÅÅÀÀÀ»»»µµµ³³³³³³³³³¸¸¸¿¿¿ÃÃÃÅÅÅÀÀÀ¼¼¼ººº¸¸¸¾¾¾ÃÃÃÉÉÉÑÑÑ×××ÒÒÒÉÉÉÊÊÊÂÂÂÌÌÌÒÒÒØØØ×××ÉÉÉÍÍÍÑÑÑÕÕÕÐÐÐÎÎÎÕÕÕÒÒÒÍÍÍÐÐÐÊÊÊÊÊÊÇÇÇÅÅÅÌÌÌ×××ØØØÒÒÒÔÔÔÕÕÕÕÕÕÐÐÐÊÊÊÉÉÉÌÌÌÐÐÐ×××ÑÑÑÒÒÒÙÙÙÔÔÔÅÅž¾¾ÂÂÂÙÙÙÕÕÕØØØÒÒÒÕÕÕØØØÅÅŵµµ¾¾¾ÀÀÀ¼¼¼···»»»ÆÆÆÊÊÊÆÆÆÅÅž¾¾»»»¾¾¾ÂÂÂÀÀÀ¾¾¾¾¾¾¼¼¼ÂÂÂÀÀÀ¿¿¿ÆÆÆÅÅÅÂÂÂÉÉÉÍÍÍÎÎÎÒÒÒ×××ÙÙÙ×××ÐÐÐÊÊÊÊÊÊÊÊÊÆÆÆ¿¿¿ÀÀÀÉÉÉÊÊÊÆÆÆÉÉÉÂÂÂÀÀÀÉÉÉÎÎÎÍÍÍÇÇÇÅÅÅÒÒÒ×××ÅÅÅ¿¿¿Â¼¼¼¾¾¾ÀÀÀÃÃÃÌÌÌÔÔÔÃÃÃÃÃÿ¿¿ÊÊÊÇÇÇÆÆÆÆÆƾ¾¾ÃÃÃÌÌÌÂÂÂÃÃÃßßßÛÛÛÐÐÐÎÎÎÇÇǾ¾¾ÉÉÉÌÌÌ···ÐÐÐ×××ÍÍÍ×××ÇÇÇÉÉÉÊÊÊ¿¿¿ÅÅÅÀÀÀ¼¼¼»»»¿¿¿ÃÃÃÆÆÆÇÇÇÇÇÇÆÆÆÂÂÂÀÀÀ¼¼¼ººº¾¾¾¼¼¼¿¿¿¸¸¸µµµººº»»»ººº¾¾¾ÆÆÆÆÆÆÆÆÆÊÊÊÉÉÉÆÆÆÒÒÒÛÛÛÒÒÒÇÇÇëëëÑÑÑÉÉÉÇÇÇççç×××ÌÌÌÎÎÎÑÑÑïïïãããàààÙÙÙïïïßßßßßßâââàààßßßßßßàààÜÜÜÕÕÕÍÍÍÅÅÅÊÊÊÊÊÊÍÍÍÐÐÐÉÉÉÎÎο¿¿ÎÎÎÎÎÎÅÅÅÎÎÎçççëëëÛÛÛ×××ÔÔÔÔÔÔ×××ÔÔÔÐÐÐÍÍÍÎÎÎÕÕÕÑÑÑÊÊÊÅÅÅÂÂÂÃÃÃÉÉÉÍÍÍÃÃÃÃÃúºº¸¸¸ÃÃÃÇÇÇÆÆÆÊÊÊÃÃÃÃÃÃÅÅÅÃÃÃÂÂÂÂÂÂÅÅÅÉÉɯ¯¯³³³ºººÀÀÀ¾¾¾ºººµµµ»»»¼¼¼¼¼¼¾¾¾ÇÇÇÒÒÒÔÔÔÎÎÎÑÑÑÉÉÉÎÎÎÎÎÎ×××ßßßÔÔÔÔÔÔÐÐÐÑÑÑÔÔÔÙÙÙÝÝÝÝÝÝÛÛÛ×××ÒÒÒÒÒÒÒÒÒÕÕÕÙÙÙÛÛÛÙÙÙØØØ×××ÎÎÎÍÍÍÒÒÒÔÔÔÎÎÎÍÍÍÑÑÑÎÎÎÕÕÕÕÕÕÍÍÍÅÅÅÂÂÂÃÃÃÃÃÃÂÂÂÇÇÇÎÎÎÑÑÑÐÐÐÎÎÎÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÊÊÊÇÇÇÃÃÿ¿¿¼¼¼¿¿¿¾¾¾¾¾¾¼¼¼¼¼¼¼¼¼¾¾¾¾¾¾ÀÀÀ¿¿¿ÂÂÂÆÆÆÇÇÇÆÆÆÉÉÉÎÎÎÍÍÍÒÒÒººº¸¸¸¿¿¿ÇÇÇØØØÇÇÇÅÅÅÉÉÉÌÌÌÉÉÉÃÃÃÀÀÀÅÅÅÉÉÉÂÂÂÉÉÉÉÉÉÕÕÕÕÕÕÃÃÃÉÉÉØØØ¿¿¿ÉÉÉÒÒÒØØØ×××ÔÔÔÒÒÒÒÒÒÝÝÝÑÑÑÅÅÅÀÀÀÀÀÀÀÀÀÂÂÂÆÆÆÅÅÅÂÂÂÂÂÂÅÅÅÃÃÃÃÃÃÍÍÍØØØÕÕÕÑÑÑÇÇǼ¼¼ÆÆÆÇÇÇ¿¿¿×××ÌÌÌÐÐÐÊÊÊÆÆÆÉÉÉÅÅÅ¿¿¿ÂÂÂÃÃÃÂÂÂÂÂÂÂÂÂÅÅÅÇÇÇÊÊÊÌÌÌÇÇÇÅÅÅÀÀÀ¾¾¾»»»ººººººººººººººººººººº»»»¼¼¼¿¿¿¿¿¿ÂÂÂÇÇÇÍÍÍÉÉÉÅÅÅÒÒÒÛÛÛÐÐÐÒÒÒÒÒÒâââ¼¼¼ÅÅÅàààÜÜÜÎÎÎÉÉÉâââëëë×××ßßßèèèÙÙÙäääÍÍÍÐÐÐÌÌÌÔÔÔßßßíííÐÐÐÊÊÊÍÍÍÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÌÌÌÌÌÌÉÉÉÉÉÉÊÊÊÊÊÊÊÊÊÉÉÉÇÇÇÆÆÆÉÉÉâââÝÝÝÐÐÐÊÊÊÐÐÐ×××¼¼¼ÇÇÇÆÆÆÃÃÃÊÊÊÉÉÉÂÂÂÃÃþ¾¾ÊÊÊÑÑÑÌÌÌÊÊÊÎÎÎÐÐÐÌÌÌÃÃÃÃÃÃÂÂÂÂÂÂÂÂÂÃÃÃÃÃÃÅÅÅÃÃÃÃÃô´´µµµ¾¾¾ÂÂÂÇÇÇ···¼¼¼ÆÆÆÃÃÿ¿¿ÇÇÇÎÎÎÎÎÎÐÐÐÐÐÐÇÇÇÍÍÍÍÍÍÔÔÔÛÛÛÒÒÒÔÔÔÔÔÔÒÒÒÑÑÑÑÑÑÕÕÕÙÙÙÜÜÜßßßÛÛÛÕÕÕÎÎÎÌÌÌÍÍÍÔÔÔÙÙÙÝÝÝÔÔÔÑÑÑÌÌÌÊÊÊÌÌÌÑÑÑÔÔÔÕÕÕÒÒÒÕÕÕÒÒÒÇÇǾ¾¾¾¾¾ÀÀÀÃÃÃÑÑÑÒÒÒÒÒÒÎÎÎÉÉÉÅÅÅÂÂÂÀÀÀÃÃÃÃÃÃÂÂÂÂÂÂÀÀÀ¾¾¾¼¼¼»»»¿¿¿¾¾¾¾¾¾¼¼¼¼¼¼¼¼¼¾¾¾¾¾¾ÂÂÂÀÀÀÀÀÀÅÅÅÅÅÅÅÅÅÉÉÉÐÐд´´ÅÅźººººº¸¸¸¼¼¼ÑÑÑÊÊÊÉÉÉÆÆÆÅÅÅÅÅÅÇÇÇÉÉÉÉÉÉÉÉÉÌÌÌÔÔÔÀÀÀ¸¸¸ÆÆÆÔÔÔÑÑѾ¾¾ÕÕÕÒÒÒÍÍÍÉÉÉÉÉÉÎÎÎÙÙÙâââÙÙÙÎÎÎÃÃÿ¿¿¼¼¼ºººººº¼¼¼ÂÂÂÀÀÀÀÀÀÀÀÀ¿¿¿ÀÀÀÉÉÉÑÑÑÛÛÛÒÒÒÃÃþ¾¾ÇÇÇÃÃü¼¼ÍÍÍÌÌÌÍÍÍÇÇÇÅÅÅÊÊÊÆÆÆÀÀÀÂÂÂÀÀÀÀÀÀÂÂÂÂÂÂÅÅÅÆÆÆÉÉÉÊÊÊÅÅÅÃÃÃÀÀÀ¼¼¼ººº¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸ººº»»»¾¾¾¿¿¿ÀÀÀÃÃÃÆÆÆÌÌÌÊÊÊÆÆÆÑÑÑÙÙÙÕÕÕÑÑÑÔÔÔàààÉÉÉÔÔÔÜÜÜÕÕÕÍÍÍÆÆÆçççëëëÛÛÛàààßßßÐÐÐÙÙÙÑÑÑÔÔÔÎÎÎÎÎÎÒÒÒßßßÌÌÌÌÌÌÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÎÎÎÎÎÎÎÎÎÉÉÉÉÉÉÊÊÊÊÊÊÉÉÉÇÇÇÆÆÆÅÅż¼¼ÊÊÊÅÅÅ¿¿¿¼¼¼¿¿¿ÇÇǾ¾¾ÅÅÅÉÉÉÇÇÇÆÆÆÉÉÉÂÂÂÀÀÀÉÉÉÀÀÀÊÊÊÎÎÎÇÇÇÃÃÃÇÇÇÉÉÉÆÆÆÇÇÇÅÅÅ¿¿¿»»»»»»¿¿¿ÃÃÃÆÆÆÆÆÆÉÉɺººµµµ´´´¸¸¸ÆÆÆÂÂÂÃÃÃÉÉÉÅÅÅ¿¿¿ÃÃÃÃÃÃÂÂÂÅÅÅÍÍÍÉÉÉÌÌÌÊÊÊÎÎÎÔÔÔÐÐÐÑÑÑ×××ÔÔÔÑÑÑÎÎÎÐÐÐÔÔÔÙÙÙÝÝÝÕÕÕÔÔÔÔÔÔÕÕÕ××××××ÔÔÔÑÑÑÐÐÐÒÒÒÎÎÎÆÆÆÉÉÉÒÒÒÕÕÕÐÐÐÔÔÔÛÛÛÛÛÛÐÐÐÃÃü¼¼ººº···ÒÒÒÑÑÑÎÎÎÉÉÉÃÃÃÀÀÀ¿¿¿ÀÀÀ¼¼¼»»»»»»»»»ººº»»»»»»»»»¿¿¿¾¾¾¾¾¾¼¼¼¼¼¼¾¾¾¾¾¾¿¿¿ÃÃÃÀÀÀ¿¿¿ÂÂÂÂÂÂÂÂÂÉÉÉÐÐа°°ÅÅÅÅÅÅÇÇÇÂÂÂÀÀÀÔÔÔÒÒÒÍÍÍÊÊÊÇÇÇÆÆÆÊÊÊÎÎÎÑÑÑÑÑÑØØØÕÕÕÇÇÇÊÊÊÍÍÍÂÂÂÃÃÃÉÉÉÉÉÉÆÆÆ¿¿¿¼¼¼¿¿¿ÂÂÂÆÆÆÅÅÅ¿¿¿»»»»»»»»»···¸¸¸»»»¼¼¼¿¿¿¿¿¿»»»¸¸¸¼¼¼ÂÂÂÆÆÆ×××ÑÑÑ¿¿¿ÂÂÂÌÌÌÀÀÀ¸¸¸¾¾¾ÐÐÐÎÎÎÆÆÆÂÂÂÅÅÅÃÃÃÀÀÀÀÀÀ¾¾¾¿¿¿ÀÀÀÃÃÃÅÅÅÅÅÅÆÆÆÆÆÆÀÀÀÀÀÀ¾¾¾¼¼¼ººº¸¸¸···µµµ···¸¸¸¸¸¸ººº¼¼¼¿¿¿ÀÀÀÂÂÂÅÅÅÅÅÅÊÊÊÌÌÌÉÉÉÎÎÎØØØÜÜÜÔÔÔ×××ÙÙÙÑÑÑàààÔÔÔÍÍÍÍÍ;¾¾êêêçççÜÜÜãããÕÕÕÉÉÉÒÒÒÕÕÕ×××ÒÒÒÎÎÎÍÍÍÕÕÕÉÉÉÎÎÎÒÒÒÒÒÒÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÊÊÊÊÊÊÊÊÊÉÉÉÇÇÇÆÆÆÃÃÃÃÃÃÊÊÊÉÉÉÂÂÂÅÅÅÃÃÿ¿¿ÆÆÆÉÉÉÉÉÉÍÍÍÇÇǾ¾¾ÀÀÀÆÆÆÅÅÅÃÃÿ¿¿ÆÆÆÆÆƾ¾¾¸¸¸»»»»»»¸¸¸¾¾¾ºººµµµ±±±°°°³³³···ºººÂÂÂÉÉÉ»»»±±±°°°ÀÀÀÉÉÉÀÀÀÃÃÃÀÀÀ¿¿¿ÀÀÀ¿¿¿¿¿¿ÊÊÊÍÍÍÌÌÌÌÌÌÉÉÉÉÉÉÌÌÌÊÊÊÍÍÍÕÕÕÕÕÕ×××ÔÔÔÒÒÒÑÑÑÔÔÔ×××ØØØØØØÙÙÙÜÜÜÝÝÝÛÛÛÕÕÕÑÑÑÌÌÌÑÑÑÑÑÑÍÍÍÍÍÍÐÐÐÊÊÊÀÀÀ»»»ÇÇÇÒÒÒÔÔÔÑÑÑÑÑÑÑÑÑÐÐÐÌÌÌÊÊÊÇÇÇÃÃÃÀÀÀ¿¿¿ÀÀÀÀÀÀ¼¼¼»»»ººº¸¸¸¸¸¸»»»¼¼¼¾¾¾¾¾¾¾¾¾¼¼¼¼¼¼¼¼¼¾¾¾¿¿¿¿¿¿Â¿¿¿¼¼¼¿¿¿¿¿¿ÀÀÀÇÇÇÐÐи¸¸ÆÆÆÇÇÇÌÌÌÇÇÇÂÂÂÍÍÍÍÍÍÀÀÀÉÉÉÒÒÒ×××ÕÕÕÕÕÕÙÙÙÜÜÜ´´´ÊÊÊÇÇÇÃÃÃÆÆÆÎÎÎÝÝÝâââÅÅÅÅÅÅÃÃÃÃÃÃÂÂÂÀÀÀ¾¾¾¼¼¼µµµ³³³´´´¸¸¸¸¸¸···¸¸¸»»»ºººÀÀÀÀÀÀºººµµµººº¾¾¾¼¼¼ÇÇÇÌÌÌ»»»ÀÀÀÊÊÊ»»»°°°ÐÐÐÎÎÎÉÉÉ¿¿¿¾¾¾¾¾¾ÀÀÀ¼¼¼¾¾¾ÀÀÀÃÃÃÃÃÃÃÃÃÃÃþ¾¾¾¾¾¼¼¼»»»ººº···µµµ´´´······¸¸¸ººº¼¼¼¿¿¿ÂÂÂÃÃÃÅÅÅÅÅÅÉÉÉÍÍÍÊÊÊÌÌÌ×××ãããÔÔÔÛÛÛÑÑÑÍÍÍßßßÉÉÉÇÇÇÊÊÊ···èèèàààÝÝÝæææÐÐÐÊÊÊÕÕÕØØØÔÔÔÔÔÔÐÐÐÐÐÐÕÕÕÍÍÍÐÐÐÑÑÑÑÑÑÐÐÐÐÐÐÐÐÐÐÐÐÑÑÑÑÑÑÌÌÌÌÌÌÊÊÊÉÉÉÇÇÇÅÅÅÃÃÃÃÃÃÉÉÉÅÅÅÂÂÂÇÇÇÇÇÇÅÅÅÆÆÆÊÊÊÉÉÉÆÆƾ¾¾¸¸¸¾¾¾ÆÆÆÅÅÅ¿¿¿ÂÂÂÇÇÇÇÇÇÀÀÀ»»»»»»ººº···¬¬¬±±±´´´µµµ···µµµµµµµµµ¿¿¿ÆÆÆÅÅźºº±±±¸¸¸ÂÂÂÉÉÉÊÊÊÅÅÅÃÃúºººººÆÆÆÍÍÍÎÎÎÌÌÌÉÉÉÆÆÆÅÅÅÇÇÇÇÇÇÐÐÐÒÒÒÕÕÕÕÕÕÔÔÔÒÒÒÔÔÔÕÕÕÛÛÛÜÜÜßßßããããããàààÙÙÙÔÔÔÌÌÌÍÍÍÎÎÎÐÐÐÐÐÐÌÌÌÅÅž¾¾ÆÆÆÎÎÎÔÔÔÐÐÐÌÌÌÌÌÌÎÎÎÎÎÎÌÌÌÊÊÊÆÆÆ¿¿¿¼¼¼ººº¸¸¸¼¼¼»»»¸¸¸······¸¸¸»»»¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼¾¾¾¾¾¾¿¿¿ÀÀÀ¼¼¼¼¼¼¾¾¾¿¿¿ÀÀÀÇÇÇÐÐÐÀÀÀÊÊÊÌÌÌÐÐÐÊÊÊÃÃÃÊÊÊÎÎÎÐÐÐÑÑÑÐÐÐÉÉÉÀÀÀ¼¼¼¿¿¿ÅÅÅÂÂÂÊÊÊÃÃÃÉÉÉÐÐÐÇÇÇÃÃû»»ÆÆƺºº´´´´´´···¼¼¼¿¿¿···´´´´´´······´´´´´´¸¸¸»»»ÂÂÂÃÃü¼¼···¸¸¸ººº¸¸¸»»»ÇÇǺºº···¿¿¿ÂÂÂÃÃó³³ÀÀÀÅÅÅÌÌÌÊÊÊÃÃþ¾¾¾¾¾¾¾¾»»»¼¼¼¿¿¿ÂÂÂÃÃÃÃÃÃÀÀÀÀÀÀ¼¼¼¼¼¼»»»»»»ººº¸¸¸···µµµ···¸¸¸¸¸¸»»»¼¼¼¿¿¿ÂÂÂÃÃÃÅÅÅÅÅÅÇÇÇÌÌÌÍÍÍÌÌÌÕÕÕäääÎÎÎÙÙÙÌÌÌÆÆÆÙÙÙÅÅÅÅÅÅ¿¿¿¼¼¼çççÛÛÛÝÝÝæææÎÎÎÎÎÎØØØÕÕÕÊÊÊÌÌÌÇÇÇÍÍÍÔÔÔÐÐÐÐÐÐÊÊÊÌÌÌÌÌÌÌÌÌÍÍÍÎÎÎÎÎÎÐÐÐÍÍÍÌÌÌÊÊÊÇÇÇÆÆÆÅÅÅÃÃÃÃÃþ¾¾¿¿¿ÃÃÃÃÃÃÆÆÆÇÇÇÅÅÅÃÃÃÅÅŵµµ´´´ÀÀÀººº¾¾¾ÌÌÌÐÐÐÔÔÔÕÕÕÑÑÑÎÎÎÌÌÌÉÉÉÅÅÅÇÇÇÉÉÉÊÊÊÉÉÉÅÅż¼¼µµµ°°°°°°´´´ÀÀÀÇÇǸ¸¸µµµ¼¼¼ÊÊÊÌÌÌÉÉÉÇÇÇÆÆÆ¿¿¿¿¿¿ÌÌÌÌÌÌÎÎÎÉÉÉÊÊÊÇÇÇÃÃÃÇÇÇÅÅÅÌÌÌÌÌÌÍÍÍÎÎÎÐÐÐÔÔÔØØØÛÛÛØØØÙÙÙÜÜÜàààâââßßßÙÙÙÕÕÕÐÐÐÍÍÍÊÊÊÊÊÊÌÌÌÊÊÊÉÉÉÇÇǼ¼¼ÇÇÇÐÐÐÎÎÎÌÌÌÌÌÌÍÍÍÌÌÌÉÉÉÆÆÆÃÃÃÀÀÀ¾¾¾»»»···´´´¸¸¸···´´´³³³³³³´´´µµµ···»»»»»»ººº»»»»»»¼¼¼¾¾¾¿¿¿¾¾¾¼¼¼¾¾¾ÃÃÃÅÅÅÆÆÆÌÌÌÒÒÒÃÃÃÉÉÉÐÐÐÒÒÒÊÊÊÂÂÂÊÊÊÕÕÕÔÔÔÐÐÐÊÊÊÆÆÆÇÇÇÌÌÌÎÎÎÐÐÐÐÐÐÊÊÊÅÅÅÔÔÔÑÑÑ´´´³³³Â³³³µµµ¸¸¸¼¼¼ÀÀÀÅÅÅÉÉÉÌÌ̾¾¾¸¸¸µµµ···¸¸¸···¸¸¸¼¼¼¼¼¼ÂÂÂÃÃÿ¿¿ººº¸¸¸·········ÃÃþ¾¾³³³µµµ¿¿¿ÇÇÇÀÀÀ³³³ºººÇÇÇÎÎÎÉÉÉÅÅÅ»»»»»»¼¼¼¿¿¿ÂÂÂÂÂÂÂÂÂÀÀÀ¿¿¿¼¼¼¼¼¼»»»ºººººº¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸ººº»»»¾¾¾¿¿¿ÂÂÂÃÃÃÅÅÅÆÆÆÇÇÇÊÊÊÍÍÍÍÍÍÒÒÒâââÍÍÍÔÔÔÌÌÌÆÆÆØØØÇÇÇÃÃô´´ÊÊÊæææØØØÝÝÝãããÍÍÍÎÎÎÕÕÕÐÐп¿¿Â¾¾¾ÅÅÅÉÉÉÊÊÊÊÊÊÃÃÃÅÅÅÆÆÆÉÉÉÌÌÌÌÌÌÍÍÍÍÍÍÊÊÊÉÉÉÇÇÇÆÆÆÅÅÅÃÃÃÃÃÃÃÃÃÅÅÅÇÇÇÍÍÍÅÅÅÀÀÀÅÅž¾¾ººº¸¸¸³³³»»»ÃÃþ¾¾¸¸¸ÆÆÆÕÕÕ×××ØØØÛÛÛÙÙÙØØØÔÔÔÐÐÐÍÍÍÍÍÍÎÎÎÎÎÎÎÎÎÎÎÎÌÌÌÉÉÉÇÇǸ¸¸±±±ºººÂÂÂÃÃü¼¼µµµ¾¾¾ÃÃÃÉÉÉÇÇÇÇÇÇÌÌÌÉÉÉÉÉÉÑÑÑÇÇÇÌÌÌÆÆÆÊÊÊÊÊÊÆÆÆÊÊÊÅÅÅÉÉÉÇÇÇÇÇÇÉÉÉÍÍÍÑÑÑÔÔÔÕÕÕÛÛÛÕÕÕÎÎÎÌÌÌÎÎÎÔÔÔÙÙÙÜÜÜÔÔÔÕÕÕÐÐÐÇÇÇÇÇÇÎÎÎÐÐÐÊÊʵµµÃÃÃÐÐÐÒÒÒÐÐÐÎÎÎÍÍÍÊÊÊÅÅÅ¿¿¿¾¾¾¾¾¾¼¼¼ººº···´´´³³³³³³±±±±±±³³³´´´µµµ¸¸¸¸¸¸¸¸¸ºººººº»»»¼¼¼¾¾¾¾¾¾¾¾¾ÃÃÃÊÊÊÍÍÍÍÍÍÑÑÑ××׿¿¿ÅÅÅÌÌÌÇÇÇÀÀÀÂÂÂÌÌ̸¸¸»»»ÀÀÀÆÆÆÊÊÊÇÇÇÃÃþ¾¾ÅÅÅØØØÌÌ̸¸¸´´´¼¼¼ÐÐÐÕÕÕÐÐÐ×××ÝÝÝßßßÜÜÜÕÕÕÑÑÑÎÎÎÊÊÊÀÀÀ¸¸¸¸¸¸ººº»»»¾¾¾Â¾¾¾¿¿¿ÂÂÂÃÃü¼¼µµµ´´´···¸¸¸¿¿¿ÇÇÇÀÀÀ¸¸¸¼¼¼ÂÂÂÊÊʼ¼¼···¼¼¼ÅÅÅÆÆÆÉÉÉÆÆÆ»»»¼¼¼¾¾¾¿¿¿ÀÀÀÂÂÂÀÀÀÀÀÀ¿¿¿¾¾¾¼¼¼»»»ººººººººº»»»¼¼¼ºººººº»»»»»»¾¾¾¿¿¿ÀÀÀÂÂÂÃÃÃÉÉÉÇÇÇÉÉÉÎÎÎÎÎÎÑÑÑÜÜÜ×××ÐÐÐÊÊÊÉÉÉØØØÊÊÊÆÆƵµµ×××ààà×××ÝÝÝàààÎÎÎÎÎÎÎÎÎÆÆƸ¸¸ÇÇÇÂÂÂÅÅÅ¿¿¿¿¿¿¾¾¾¼¼¼¿¿¿ÃÃÃÇÇÇÊÊÊÌÌÌÌÌÌÌÌÌÆÆÆÅÅÅÃÃÃÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÅÅÅÃÃÃÆÆƸ¸¸±±±µµµ¯¯¯³³³···¼¼¼Â¿¿¿»»»ÉÉÉ×××ÕÕÕØØØØØØØØØØØØ×××ÒÒÒÐÐÐÍÍÍÎÎÎÎÎÎÎÎÎÍÍÍÍÍÍÌÌÌÌÌÌÊÊÊÃÃô´´ºººÀÀÀÃÃÿ¿¿¸¸¸ÅÅÅÇÇÇÎÎÎÌÌÌÇÇÇÊÊÊÇÇÇÃÃÃÅÅÅÅÅÅÊÊÊÃÃÃÊÊÊÍÍÍÉÉÉÎÎÎÇÇÇÇÇÇÇÇÇÇÇÇÉÉÉÌÌÌÍÍÍÊÊÊÉÉÉÍÍÍÊÊÊÉÉÉÉÉÉÍÍÍÐÐÐÒÒÒÒÒÒØØØßßßÙÙÙÉÉÉÇÇÇÒÒÒÑÑÑÅÅÅÇÇÇÐÐÐÔÔÔÐÐÐÊÊÊÊÊÊÊÊÊÊÊÊÇÇÇÃÃþ¾¾»»»»»»ººº¸¸¸µµµ³³³³³³³³³³³³´´´µµµ···¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸ººº»»»¼¼¼¾¾¾¾¾¾ÀÀÀÇÇÇÐÐÐÔÔÔÒÒÒÕÕÕÙÙÙÒÒÒÅÅÅÃÃÃÍÍÍÒÒÒÍÍÍÅÅÅÆÆÆÅÅÅÇÇÇÊÊÊÉÉÉÇÇÇÌÌÌÕÕÕßßßÀÀÀ¿¿¿¯¯¯···ÊÊÊÍÍÍÌÌÌÅÅÅÉÉÉÉÉÉÉÉÉÇÇÇÉÉÉÐÐÐÜÜÜæææÜÜÜÎÎÎÀÀÀ»»»ººº¸¸¸ººº¼¼¼¾¾¾¼¼¼ÀÀÀÅÅž¾¾´´´±±±µµµ···»»»ÒÒÒÒÒÒÃÃû»»¸¸¸ÊÊÊÐÐм¼¼´´´···¼¼¼ÇÇÇÇÇÇ»»»¾¾¾¾¾¾¿¿¿ÀÀÀÀÀÀÀÀÀÀÀÀ¿¿¿¿¿¿¾¾¾»»»ºººººº»»»¼¼¼¾¾¾»»»»»»»»»¼¼¼¼¼¼¿¿¿ÀÀÀÂÂÂÂÂÂÊÊÊÇÇÇÆÆÆÎÎÎÐÐÐÐÐÐØØØäääÎÎÎÉÉÉÇÇÇÕÕÕÌÌÌÊÊÊ¿¿¿ÙÙÙÙÙÙÔÔÔÝÝÝßßßÒÒÒÐÐÐÍÍ;¾¾¸¸¸ÒÒÒÐÐÐÌÌÌ»»»···´´´¸¸¸¼¼¼ÂÂÂÇÇÇÌÌÌÍÍÍÌÌÌÌÌÌÂÂÂÀÀÀ¿¿¿¾¾¾¼¼¼¾¾¾¾¾¾¿¿¿¾¾¾···»»»°°°¬¬¬±±±±±±¿¿¿ÅÅž¾¾¼¼¼¾¾¾ÅÅÅØØØàààÔÔÔÝÝÝÜÜÜÙÙÙÙÙÙ×××ÕÕÕÒÒÒÑÑÑÍÍÍÎÎÎÐÐÐÐÐÐÐÐÐÎÎÎÌÌÌÊÊÊÉÉÉ···¾¾¾ÃÃÃÅÅÅÀÀÀ···ÆÆÆ¿¿¿ÉÉÉÇÇÇÃÃÃÉÉÉÌÌÌÆÆÆÅÅÅÆÆÆÅÅÅÅÅÅÉÉÉÍÍÍÐÐÐÍÍÍÉÉÉÍÍÍÉÉÉÆÆÆÆÆÆÊÊÊÎÎÎÐÐÐÑÑÑØØØ×××ÔÔÔÑÑÑÊÊÊÅÅÅÉÉÉÑÑÑÒÒÒÎÎÎÔÔÔÕÕÕÆÆÆ¿¿¿ÊÊÊÑÑÑÉÉÉÃÃÃÔÔÔØØØÑÑÑÍÍÍÅÅÅÅÅÅÃÃÿ¿¿»»»¼¼¼ÀÀÀ¾¾¾······³³³±±±µµµµµµ³³³µµµ¼¼¼µµµ···¸¸¸ººººººººººººººººººÐÐÐÇÇÇÀÀÀ¾¾¾ººº¿¿¿¸¸¸ÕÕÕÂÂÂÃÃÃÔÔÔÔÔÔÍÍÍÐÐÐÕÕÕÒÒÒÊÊʾ¾¾¿¿¿ÌÌÌÊÊÊÀÀÀ¾¾¾´´´¾¾¾ÊÊÊÎÎÎÊÊÊÆÆÆÆÆÆÉÉÉÅÅÅÃÃÃÂÂÂÂÂÂÅÅÅÉÉÉÍÍÍÐÐÐÐÐÐÒÒÒÕÕÕÒÒÒÉÉÉÀÀÀ»»»»»»¸¸¸¼¼¼ÀÀÀÀÀÀººº···ººº¼¼¼¼¼¼ÃÃÃÌÌÌÐÐÐÑÑÑÃÃø¸¸ÂÂÂÌÌÌÀÀÀÀÀÀÀÀÀµµµµµµÃÃÃÊÊÊÀÀÀ»»»¿¿¿ÀÀÀ»»»¾¾¾ÃÃþ¾¾¼¼¼¼¼¼¼¼¼¼¼¼¾¾¾¾¾¾¿¿¿ÀÀÀ¿¿¿¾¾¾¼¼¼»»»»»»¼¼¼¿¿¿ÀÀÀÆÆÆÌÌÌÉÉÉÍÍÍÒÒÒÍÍÍÍÍÍÛÛÛÇÇÇÑÑÑÉÉÉÉÉɸ¸¸ÑÑÑÀÀÀÆÆƯ¯¯ëëëßßßØØØßßßÐÐÐÑÑÑ»»»¾¾¾ÍÍÍÛÛÛÑÑѸ¸¸±±±»»»···¼¼¼ÃÃÃÉÉÉÌÌÌÌÌÌÌÌÌÌÌÌÂÂÂÀÀÀ¿¿¿¾¾¾¼¼¼ººº¸¸¸···±±±±±±±±±ÂÂÂÅÅÅÃÃÃÊÊÊ»»»ÅÅÅ»»»±±±»»»ÐÐÐÔÔÔÌÌÌÉÉÉÎÎÎÝÝÝÑÑÑÐÐÐÔÔÔÎÎÎÑÑÑÐÐÐÍÍÍÊÊÊÇÇÇÉÉÉÎÎÎÑÑÑÍÍÍÉÉɵµµººº»»»ÂÂÂÉÉÉ»»»ÀÀÀÆÆÆÆÆÆÇÇÇÉÉÉÊÊÊÊÊÊÊÊÊÉÉÉÇÇÇÉÉÉÊÊÊÉÉÉÉÉÉÊÊÊÎÎÎÒÒÒÊÊÊÊÊÊÉÉÉÊÊÊÌÌÌÍÍÍÍÍÍÌÌÌÒÒÒÑÑÑÒÒÒÒÒÒÍÍÍÅÅÅÃÃÃÇÇÇÎÎÎÉÉÉÎÎÎÒÒÒÍÍÍÌÌÌÎÎÎÌÌÌÊÊÊÀÀÀÌÌÌÎÎÎÉÉÉÊÊÊÇÇÇÊÊÊÅÅÅÇÇÇÅÅÅ¿¿¿»»»»»»¸¸¸´´´ºººººº¸¸¸¸¸¸´´´³³³µµµ»»»ººº»»»¼¼¼¼¼¼¾¾¾¿¿¿ÀÀÀÃÃÃÀÀÀÒÒÒÌÌÌÊÊÊÍÍÍÌÌÌÑÑÑÎÎÎÊÊÊÇÇÇÊÊÊÉÉɼ¼¼ººº¾¾¾¾¾¾ººº¾¾¾»»»ÅÅÅÑÑѱ±±»»»ÅÅÅÌÌÌÑÑÑÐÐÐÇÇÇ¿¿¿»»»»»»¾¾¾¾¾¾¼¼¼¼¼¼¾¾¾ÂÂÂÆÆÆÉÉÉÎÎÎÍÍÍÐÐÐÐÐÐÒÒÒÎÎÎÀÀÀ¼¼¼»»»¼¼¼ÀÀÀÂÂÂÀÀÀÀÀÀÂÂÂÂÂÂÑÑÑÔÔÔÆÆÆÃÃÃÒÒÒÎÎλ»»ºººÅÅÅÆÆÆÇÇÇÆÆÆÅÅÅÀÀÀÀÀÀÅÅÅÉÉÉÀÀÀ¿¿¿ÀÀÀ¼¼¼»»»¼¼¼¼¼¼¾¾¾¾¾¾¼¼¼¼¼¼¾¾¾¿¿¿ÀÀÀÀÀÀ¾¾¾¼¼¼¼¼¼»»»»»»¼¼¼¾¾¾¿¿¿ÂÂÂÉÉÉÌÌÌÌÌÌÍÍÍÌÌÌÑÑÑÜÜÜÍÍÍÐÐÐÎÎÎÒÒÒ¼¼¼ÐÐÐÂÂÂÃÃð°°çççÛÛÛÒÒÒÔÔÔÇÇÇÑÑÑÌÌ̺ºº¸¸¸¿¿¿ÉÉÉÆÆƸ¸¸µµµ¼¼¼¸¸¸¾¾¾ÅÅÅÊÊÊÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÅÅž¾¾ººº¸¸¸¸¸¸···´´´³³³¸¸¸»»»ÅÅÅÃÃÃÂÂÂÉÉÉ»»»···µµµµµµÃÃÃÕÕÕ×××ÍÍÍÌÌÌÍÍÍÛÛÛÔÔÔÑÑÑÔÔÔÍÍÍÑÑÑÎÎÎÎÎÎÌÌÌÌÌÌÍÍÍÎÎÎÉÉɼ¼¼³³³´´´¿¿¿ÃÃÃÃÃÿ¿¿µµµ¸¸¸ÇÇÇÆÆÆÇÇÇÇÇÇÇÇÇÇÇÇÆÆÆÇÇÇÇÇÇÅÅÅÉÉÉÌÌÌÇÇÇÃÃÃÅÅÅÍÍÍ×××ÊÊÊÍÍÍÐÐÐÑÑÑÐÐÐÎÎÎÍÍÍÌÌÌÎÎÎÍÍÍÎÎÎÒÒÒÑÑÑÊÊÊÇÇÇÉÉÉÆÆÆÂÂÂÅÅÅÊÊÊÎÎÎÔÔÔÑÑÑÅÅÅÎÎο¿¿ÀÀÀººº³³³······ºººÃÃÃÊÊÊÍÍÍÉÉÉÃÃÿ¿¿ººº´´´±±±µµµ···´´´´´´¸¸¸¼¼¼¿¿¿¸¸¸ºººººº¸¸¸···ººº¾¾¾Â°°°ÀÀÀÀÀÀÀÀÀ¿¿¿ÇÇÇÎÎÎÔÔÔÒÒÒÔÔÔÐÐÐÉÉÉÌÌÌÌÌÌÂÂÂÇÇÇÍÍÍÆÆÆÊÊÊÕÕÕÅÅž¾¾ÜÜÜÉÉÉÌÌÌÎÎÎÍÍÍÇÇÇÀÀÀ¼¼¼»»»»»»ººº¸¸¸¸¸¸»»»¾¾¾ÂÂÂÃÃÃÍÍÍÉÉÉÊÊÊÉÉÉØØØÙÙÙ¾¾¾¸¸¸»»»¾¾¾¼¼¼¼¼¼ÂÂÂÉÉÉÎÎÎÒÒÒÕÕÕ×××¼¼¼µµµÑÑÑÙÙÙÊÊÊÃÃþ¾¾ÊÊÊÊÊÊÇÇÇÍÍÍÉÉÉ¿¿¿ÀÀÀÌÌÌÆÆÆÀÀÀ¿¿¿¿¿¿ººº¸¸¸¾¾¾¿¿¿¿¿¿¾¾¾¾¾¾¾¾¾¿¿¿ÀÀÀ»»»»»»»»»»»»¼¼¼¼¼¼¼¼¼¾¾¾¿¿¿ÅÅÅÍÍÍÌÌÌÇÇÇÌÌÌÕÕÕÙÙÙÒÒÒÍÍÍÔÔÔÛÛÛ¾¾¾ÎÎÎÅÅž¾¾¬¬¬ßßßÛÛÛ××××××ÊÊÊÑÑÑÉÉÉÀÀÀ»»»¸¸¸»»»¼¼¼ºººººº¼¼¼»»»ÀÀÀÇÇÇÌÌÌÍÍÍÎÎÎÎÎÎÎÎÎÎÎÎÉÉÉÀÀÀ»»»¸¸¸µµµ³³³°°°···¿¿¿ÃÃÃÆÆÆÂÂÂÀÀÀÅÅÅ»»»³³³»»»ÃÃÃÎÎÎØØØÑÑÑÆÆÆÆÆÆÉÉÉ×××ÕÕÕÔÔÔÒÒÒÍÍÍÎÎÎÍÍÍÅÅÅÉÉÉÍÍÍÎÎÎÊÊÊÃÃû»»µµµºººÅÅÅÆÆƾ¾¾µµµ¬¬¬±±±ÃÃÃÅÅÅÇÇÇÉÉÉÆÆÆÃÃÃÂÂÂÅÅÅÆÆÆÀÀÀÅÅÅÇÇÇÆÆÆÂÂÂÃÃÃÉÉÉÐÐÐÌÌÌÐÐÐÔÔÔÔÔÔÒÒÒÑÑÑÐÐÐÑÑÑÎÎÎÉÉÉÉÉÉÎÎÎÒÒÒÑÑÑÒÒÒÕÕÕÀÀÀÀÀÀ¿¿¿ÀÀÀÉÉÉÑÑÑÎÎÎÃÃÃÐÐÐÃÃÃÆÆÆÀÀÀ¸¸¸¸¸¸°°°¬¬¬µµµ¾¾¾ÃÃÃÆÆÆÇÇÇÆÆƾ¾¾³³³³³³µµµ´´´±±±´´´»»»¼¼¼···Â¿¿¿¿¿¿ÂÂÂÊÊÊÐÐÐÂÂÂÆÆÆÂÂÂÂÂÂÅÅÅÀÀÀÂÂÂÇÇÇÇÇÇÃÃÃÌÌÌÔÔÔ×××ÜÜÜÝÝÝØØØ×××ÝÝÝÜÜÜÜÜÜÛÛÛÇÇǼ¼¼ÌÌÌÃÃÃÅÅÅÅÅÅÆÆÆÅÅÅÃÃÃÀÀÀ¿¿¿¼¼¼»»»»»»»»»¼¼¼¿¿¿ÂÂÂÅÅÅÊÊÊÅÅÅÅÅÅÂÂÂÔÔÔØØغºº³³³ººº¿¿¿»»»···¾¾¾ÉÉÉÕÕÕàààÐÐÐÍÍ͸¸¸µµµÇÇÇÒÒÒÕÕÕÒÒÒ»»»ÆÆÆÇÇÇÆÆÆÌÌÌÌÌÌÆÆÆÂÂÂÀÀÀÊÊÊÇÇÇ¿¿¿¿¿¿»»»ºººÂ¿¿¿¿¿¿ÀÀÀÀÀÀÂÂÂÀÀÀÀÀÀ¿¿¿ºººººº»»»¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼¿¿¿ÂÂÂÌÌÌÍÍÍÇÇÇÐÐÐØØØÐÐÐÔÔÔÉÉÉÒÒÒÛÛÛ¼¼¼ÉÉÉÃÃúºº¬¬¬ÛÛÛÝÝÝÜÜÜÝÝÝØØØÙÙÙÇÇÇÊÊÊÆÆƾ¾¾¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼ÀÀÀÇÇÇÌÌÌÍÍÍÍÍÍÎÎÎÐÐÐÊÊÊÊÊÊÆÆÆÀÀÀ¸¸¸´´´³³³³³³¼¼¼ÅÅÅÇÇÇÅÅÅÀÀÀÂÂÂÀÀÀ···¸¸¸ÅÅÅÎÎÎ×××ØØØÌÌÌÂÂÂÆÆÆÆÆÆÒÒÒØØØ×××ÒÒÒÎÎÎÍÍÍÌÌÌÍÍÍÒÒÒÒÒÒÊÊʾ¾¾···¸¸¸¼¼¼ÀÀÀ»»»´´´´´´°°°´´´¿¿¿ÃÃÃÇÇÇÇÇÇÃÃÃÂÂÂÃÃÃÆÆÆÂÂÂÂÂÂÃÃÃÆÆÆÉÉÉÊÊÊÉÉÉÇÇÇÉÉÉÊÊÊÍÍÍÎÎÎÍÍÍÍÍÍÐÐÐÑÑÑÌÌÌÆÆÆÆÆÆÌÌÌÑÑÑÑÑÑÒÒÒÔÔÔÃÃÃÆÆÆÃÃÿ¿¿ÃÃÃÊÊÊÌÌÌÇÇÇ¿¿¿ºººÆÆÆÆÆÆ···ªªª°°°µµµÀÀÀÇÇǸ¸¸¸¸¸···³³³³³³»»»ÃÃÃÀÀÀ······µµµ³³³¯¯¯¯¯¯´´´¸¸¸ÅÅž¾¾ÃÃÃÔÔÔÛÛÛØØØÝÝÝÑÑÑÔÔÔÛÛÛ×××ÇÇǾ¾¾ÀÀÀÀÀÀ¿¿¿¾¾¾¿¿¿ÃÃÃÇÇÇÉÉÉÃÃÃÂÂÂÀÀÀÀÀÀÀÀÀ¿¿¿¾¾¾»»»¼¼¼¼¼¼¼¼¼¼¼¼¾¾¾ÀÀÀÂÂÂÃÃÃÆÆÆÅÅÅÅÅÅÀÀÀÎÎÎÔÔÔ¿¿¿¸¸¸···ÅÅÅÅÅż¼¼¾¾¾ÃÃÃÌÌÌØØØ×××ÇÇÇ···¾¾¾¾¾¾ÀÀÀÒÒÒÍÍÍ»»»ÀÀÀÉÉÉÌÌÌÌÌÌÐÐÐÐÐÐÅÅÅ···ÎÎÎÒÒÒÃÃþ¾¾¼¼¼»»»ÀÀÀ¾¾¾¿¿¿ÂÂÂÅÅÅÅÅÅ¿¿¿¼¼¼¸¸¸ººº»»»»»»¼¼¼¼¼¼¾¾¾¾¾¾ÃÃÃÂÂÂÉÉÉÍÍÍÍÍÍÕÕÕÕÕÕÇÇÇÑÑÑÇÇÇÎÎÎÎÎλ»»ÇÇǸ¸¸±±±ÜÜÜäääàààÜÜÜÜÜÜæææ×××ÌÌÌÎÎÎÌÌÌÆÆÆÂÂÂÀÀÀ¿¿¿¼¼¼¾¾¾ÂÂÂÇÇÇÊÊÊÌÌÌÍÍÍÎÎÎÐÐÐÉÉÉÌÌÌÉÉÉÀÀÀµµµ³³³ºººÀÀÀÅÅÅÆÆÆÆÆÆÀÀÀÀÀÀ»»»´´´¾¾¾ÉÉÉÒÒÒ××××××ÌÌÌÆÆÆÎÎÎÅÅÅÐÐÐÛÛÛØØØÑÑÑÐÐÐÍÍÍÌÌÌÍÍÍÌÌÌÇÇÇÀÀÀººº···»»»¿¿¿¸¸¸¸¸¸°°°¯¯¯···¸¸¸±±±±±±ºººÀÀÀÆÆÆÉÉÉÆÆÆÃÃÃÅÅÅÆÆÆÆÆÆÃÃÃÂÂÂÆÆÆÍÍÍÎÎÎÌÌÌÆÆÆÂÂÂÃÃÃÃÃÃÅÅÅÅÅÅÆÆÆÉÉÉÌÌÌÆÆÆÃÃÃÅÅÅÊÊÊÍÍÍÉÉÉÆÆÆÅÅÅÉÉÉÎÎÎÌÌÌÆÆÆÆÆÆÇÇÇÉÉÉÍÍÍÃÃû»»¿¿¿ººº´´´¼¼¼»»»ººº³³³°°°¬¬¬¯¯¯»»»ÉÉÉÌÌÌÆÆÆÃÃÿ¿¿»»»»»»ÀÀÀÃÃÿ¿¿¸¸¸ÀÀÀÀÀÀ¿¿¿ÀÀÀÃÃÃÉÉÉÍÍÍÎÎξ¾¾ÃÃÃÇÇÇ¿¿¿ÀÀÀÆÆÆÆÆÆÔÔÔÕÕÕÛÛÛÛÛÛÌÌÌ»»»¼¼¼»»»¯¯¯¸¸¸³³³±±±°°°³³³ÃÃÃÍÍÍÅÅÅ¿¿¿¿¿¿¾¾¾¾¾¾¾¾¾¼¼¼»»»»»»»»»»»»»»»»»»¼¼¼¾¾¾ÀÀÀÀÀÀÂÂÂÆÆÆÅÅÅÆÆÆÌÌÌÒÒÒÎÎÎÀÀÀ¸¸¸ÎÎÎÒÒÒÉÉÉÇÇǾ¾¾ÃÃÃÜÜÜÃÃô´´Â»»»¼¼¼ÔÔÔÆÆƼ¼¼¾¾¾ÌÌÌÔÔÔÐÐÐÒÒÒÔÔÔÉÉɺººÎÎÎÕÕÕÉÉÉ¿¿¿¼¼¼¼¼¼¼¼¼¼¼¼¿¿¿ÃÃÃÅÅÅÅÅž¾¾»»»ººººººººº»»»¼¼¼¾¾¾¿¿¿¿¿¿ÆÆÆÅÅÅÉÉÉÎÎÎÒÒÒ×××ÒÒÒÉÉÉÊÊÊÌÌÌÊÊÊÀÀÀÀÀÀÍÍÍÀÀÀ¾¾¾°°°ÑÑÑæææëëëßßßÙÙÙäääßßßÇÇÇÌÌÌÍÍÍÌÌÌÉÉÉÆÆÆÃÃÃÀÀÀÀÀÀÅÅÅÉÉÉÌÌÌÍÍÍÍÍÍÎÎÎÐÐÐÎÎÎÍÍÍÆÆÆ»»»³³³···ÃÃÃÐÐÐÉÉÉÇÇÇÆÆÆ¿¿¿ÀÀÀ¿¿¿µµµ»»»ÌÌÌÒÒÒÕÕÕØØØØØØÍÍÍÇÇÇÎÎÎÇÇÇÌÌÌÛÛÛÙÙÙÑÑÑÔÔÔÎÎÎÌÌÌ¿¿¿»»»···¸¸¸¾¾¾¿¿¿¼¼¼···¨¨¨¯¯¯¯¯¯°°°»»»¾¾¾»»»¼¼¼ººº¿¿¿ÅÅÅÇÇÇÇÇÇÆÆÆÆÆÆÇÇÇÇÇǾ¾¾¿¿¿ÅÅÅÉÉÉÊÊÊÉÉÉÂÂÂÀÀÀÀÀÀÀÀÀÂÂÂÅÅÅÅÅÅÅÅÅÇÇÇÃÃÃÃÃÃÇÇÇÇÇÇÃÃÃÀÀÀÂÂÂÇÇÇÍÍÍÍÍÍÌÌÌÍÍÍÅÅÅÀÀÀÇÇÇÒÒÒÉÉÉÉÉÉ»»»±±±»»»¾¾¾¾¾¾ºººººº¸¸¸µµµºººÂÂÂÅÅÅÃÃÃÇÇÇÆÆÆÃÃþ¾¾···µµµµµµ¾¾¾»»»¸¸¸···¸¸¸ººº···´´´»»»ÇÇÇÐÐм¼¼´´´ººº»»»ÍÍÍÒÒÒÎÎÎÉÉɼ¼¼³³³¸¸¸»»»±±±ªªª±±±¿¿¿ÍÍÍÔÔÔÒÒÒÇÇǺºº¼¼¼¼¼¼¾¾¾¾¾¾¾¾¾¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼¾¾¾¿¿¿ÀÀÀÀÀÀÃÃÃÆÆÆÂÂÂÊÊÊÊÊÊÎÎÎØØؼ¼¼¿¿¿ÕÕÕ×××ÎÎÎÒÒÒÌÌ̼¼¼»»»ÙÙÙÉÉÉ···ÀÀÀ¼¼¼ÀÀÀÙÙÙÉÉɾ¾¾¿¿¿ÇÇÇÍÍÍÌÌÌÊÊÊÌÌÌÎÎÎÂÂÂÅÅÅÌÌÌÍÍÍÃÃÿ¿¿¿¿¿¾¾¾¿¿¿ÀÀÀÂÂÂÂÂÂÂÂÂÀÀÀ¾¾¾¼¼¼»»»»»»ººº»»»¼¼¼¾¾¾ÀÀÀÂÂÂÆÆÆÉÉÉÊÊÊÎÎÎÔÔÔÒÒÒÑÑÑÕÕÕÃÃÃÔÔÔÉÉɸ¸¸ÌÌÌØØØÃÃÃÅÅŵµµ¼¼¼ÑÑÑíííççç×××ÛÛÛÜÜÜÎÎÎÌÌÌÊÊÊÎÎÎÑÑÑÎÎÎÉÉÉÆÆÆÅÅÅÇÇÇÌÌÌÎÎÎÎÎÎÐÐÐÑÑÑÔÔÔÒÒÒÌÌÌÀÀÀººº»»»ÂÂÂÌÌÌÑÑÑÌÌÌÉÉÉÊÊÊÃÃÿ¿¿ººº´´´ÇÇÇÔÔÔ×××ØØØÛÛÛÝÝÝÒÒÒÇÇÇÉÉÉÊÊÊÊÊÊÛÛÛØØØÑÑÑ×××ÐÐÐÌÌ̾¾¾¼¼¼¼¼¼¾¾¾¾¾¾¸¸¸°°°©©©¥¥¥°°°³³³´´´¾¾¾ÃÃÃÂÂÂÃÃÃÀÀÀÂÂÂÅÅÅÆÆÆÆÆÆÇÇÇÉÉÉÉÉÉÅÅÅ¿¿¿ºººµµµ¸¸¸¿¿¿ÆÆÆÊÊÊÆÆÆÃÃÃÂÂÂÃÃÃÆÆÆÆÆÆÅÅÅÃÃÃÌÌÌÆÆÆÃÃÃÃÃÃÃÃÃÃÃÃÆÆÆÊÊÊÂÂÂÇÇÇÉÉÉÍÍÍÐÐÐÃÃø¸¸¾¾¾ÀÀÀÀÀÀÌÌÌÅÅźººººº±±±©©©³³³ººº¾¾¾ººº´´´³³³³³³±±±©©©¯¯¯¸¸¸¿¿¿¼¼¼¸¸¸ÀÀÀÎÎδ´´´´´···ÀÀÀÎÎÎ×××ØØØ×××ÍÍÍÎÎÎÌÌÌ···¸¸¸Â¸¸¸»»»ÃÃû»»¾¾¾¾¾¾···ºººÍÍÍÛÛÛÒÒÒÎÎÎÃÃÃÂÂÂÅÅž¾¾¸¸¸¾¾¾ÀÀÀÂÂÂÂÂÂÀÀÀ¾¾¾»»»ºººººº¿¿¿¿¿¿¿¿¿ÀÀÀÀÀÀÂÂÂÂÂÂÃÃÃÅÅÅÆÆƾ¾¾ÊÊÊÇÇÇÉÉÉ×××±±±ÆÆÆØØØÔÔÔÍÍÍØØØÕÕÕÅÅÅ¿¿¿ØØØ×××ÀÀÀ¿¿¿»»»ÀÀÀÛÛÛÌÌÌÀÀÀ¾¾¾¾¾¾Â¾¾¾ÂÂÂÒÒÒÉÉɺºº¿¿¿ÍÍÍÊÊÊÃÃÃÃÃÃÅÅÅÂÂÂÀÀÀÀÀÀ¿¿¿¿¿¿¾¾¾¾¾¾¿¿¿¼¼¼»»»ºººººº»»»¾¾¾ÂÂÂÃÃÃÃÃÃÊÊÊÌÌÌÎÎÎÔÔÔÎÎÎÑÑÑâââÀÀÀÛÛÛÊÊÊ´´´ÕÕÕâââÆÆÆÊÊÊÉÉɯ¯¯´´´ÝÝÝæææÔÔÔ×××ÜÜÜÛÛÛÐÐÐÊÊÊÑÑÑØØØÕÕÕÎÎÎÊÊÊÇÇÇÊÊÊÎÎÎÑÑÑÑÑÑÒÒÒÔÔÔÕÕÕÒÒÒÉÉɾ¾¾¾¾¾ÆÆÆÍÍÍÍÍÍÊÊÊÌÌÌÊÊÊÐÐÐÇÇǾ¾¾´´´³³³ÒÒÒÎÎÎÑÑÑÔÔÔÜÜÜäääÜÜÜÎÎÎÍÍÍÌÌÌÊÊÊÛÛÛØØØÒÒÒØØØÑÑÑÌÌÌ´´´¾¾¾ÆÆÆÆÆƼ¼¼´´´±±±´´´µµµµµµµµµÀÀÀÇÇÇÃÃÃÀÀÀÇÇÇÆÆÆÅÅÅÃÃÃÅÅÅÇÇÇÉÉÉÊÊÊÀÀÀ³³³°°°¸¸¸»»»µµµ¾¾¾ÎÎÎÆÆÆÇÇÇÇÇÇÆÆÆÅÅÅÆÆÆÉÉÉÌÌÌÕÕÕÒÒÒÌÌÌÀÀÀµµµÇÇÇÇÇÇÅÅÅÀÀÀÐÐÐÕÕÕÔÔÔÌÌÌ···¸¸¸···ºººÂÂÂÌÌÌÊÊʼ¼¼¾¾¾±±±°°°±±±ºººÀÀÀ¾¾¾µµµ¯¯¯¼¼¼¿¿¿¸¸¸¿¿¿ÆÆƸ¸¸¯¯¯¯¯¯°°°±±±¬¬¬±±±±±±´´´ÝÝÝÛÛÛÃÃÿ¿¿¾¾¾¼¼¼ÀÀÀ¾¾¾¿¿¿ÆÆƱ±±¸¸¸³³³ÀÀÀÇÇÇÉÉÉÂÂÂÀÀÀÃÃÃÆÆƼ¼¼¸¸¸»»»¾¾¾ÆÆƾ¾¾»»»¾¾¾»»»´´´³³³···µµµ»»»¾¾¾¼¼¼¾¾¾ÃÃÃÃÃÿ¿¿ÉÉÉ»»»ÅÅÅÇÇÇÅÅÅÌÌÌÆÆƼ¼¼ÆÆÆÕÕÕÑÑÑÌÌÌÅÅÅÛÛÛ´´´¿¿¿ÒÒÒÕÕÕÔÔÔººººººÑÑÑÐÐÐÌÌÌÉÉÉÂÂÂÂÂÂÌÌÌÐÐÐÉÉÉÀÀÀ¼¼¼ÅÅÅÌÌ̼¼¼ÕÕÕÌÌÌÃÃÃÇÇÇÀÀÀÀÀÀÀÀÀ¿¿¿¿¿¿¾¾¾¾¾¾¼¼¼¼¼¼¾¾¾ººº»»»¿¿¿Â¿¿¿ÀÀÀÅÅÅÃÃÃÍÍÍÉÉÉÎÎÎÙÙÙÍÍÍÇÇÇÜÜÜÊÊÊÎÎÎâââÉÉɳ³³»»»ØØØÌÌÌÀÀÀÀÀÀ¿¿¿ÌÌÌÛÛÛØØØÑÑÑÙÙÙÙÙÙèèèÕÕÕÉÉÉÎÎÎÊÊÊÐÐÐÙÙÙÑÑÑÒÒÒÒÒÒÒÒÒÔÔÔÕÕÕ×××ØØØÐÐÐÆÆƸ¸¸»»»ÍÍÍÍÍÍ»»»°°°¸¸¸ÌÌÌÎÎÎÃÃÿ¿¿ººº¸¸¸ÔÔÔÔÔÔÙÙÙÛÛÛØØØÙÙÙÒÒÒÃÃÃÌÌÌÒÒÒâââØØØÛÛÛÔÔÔÐÐи¸¸ºººÃÃÃÅÅźºº´´´ººº¾¾¾¾¾¾¸¸¸°°°¯¯¯³³³¸¸¸ÂÂÂÅÅż¼¼ÃÃÃÉÉÉÊÊÊÅÅÅÃÃÃÆÆÆÆÆÆÃÃû»»ºººÀÀÀÉÉɱ±±±±±¾¾¾ÉÉÉÊÊÊÌÌÌÌÌÌÌÌÌÍÍÍÑÑÑÔÔÔÑÑÑÑÑÑÇÇǵµµ¸¸¸´´´ÆÆÆÂÂÂÅÅÅÂÂÂÍÍÍÑÑÑÒÒÒÎÎμ¼¼¸¸¸¼¼¼¸¸¸»»»ÆÆÆÐÐÐÒÒÒÐÐÐÎÎÎÉÉÉÇÇÇÀÀÀººº¼¼¼ÀÀÀ¼¼¼´´´ººº¼¼¼ººº»»»ÃÃÃÀÀÀ³³³¯¯¯¯¯¯ªªªªªª©©©³³³¸¸¸ºººÒÒÒ···¼¼¼»»»ºººÀÀÀ¿¿¿¿¿¿Â¼¼¼ÕÕÕÎÎÎÑÑÑÍÍÍÇÇǾ¾¾ÀÀÀ¿¿¿¼¼¼ººº»»»¾¾¾¼¼¼¼¼¼¼¼¼»»»´´´±±±´´´ººº¾¾¾¼¼¼¼¼¼ÀÀÀ¿¿¿ÇÇǾ¾¾ÅÅÅÅÅÅÆÆÆÊÊÊÀÀÀ»»»ÊÊÊÔÔÔÎÎÎÍÍÍÊÊÊàààÃÃÃ×××ÍÍÍÒÒÒ×××ÆÆÆÇÇÇØØØÐÐÐÅÅÅÂÂÂÅÅÅÊÊÊÐÐÐÔÔÔÑÑÑÆÆƼ¼¼¾¾¾ÍÍÍÀÀÀÔÔÔÍÍÍ¿¿¿¿¿¿¿¿¿¿¿¿¾¾¾¾¾¾¾¾¾¾¾¾¼¼¼»»»¸¸¸ººº¿¿¿ÂÂÂÀÀÀÂÂÂÆÆÆÅÅÅÅÅÅÉÉÉÎÎÎÐÐÐÍÍÍÑÑÑÜÜÜÌÌÌÕÕÕÙÙÙÉÉÉ»»»´´´ÃÃÃÒÒÒÆÆÆÃÃúºººººÍÍÍÝÝÝÛÛÛÑÑÑÜÜÜàààÍÍÍÊÊÊÕÕÕÑÑÑÌÌÌÃÃÃÌÌÌÍÍÍÐÐÐÔÔÔ×××ØØØØØØ×××ÕÕÕÐÐÐÀÀÀ···¸¸¸ººº»»»Â¸¸¸ÆÆÆÐÐÐÊÊÊÀÀÀ¾¾¾¼¼¼···ÍÍÍÎÎÎØØØÜÜÜÜÜÜâââàààÕÕÕÒÒÒÎÎÎÜÜÜÛÛÛÛÛÛÐÐÐÍÍ͸¸¸ÀÀÀÅÅÅ¿¿¿´´´°°°¸¸¸¾¾¾¼¼¼ººº°°°¯¯¯¯¯¯¬¬¬´´´ÀÀÀÅÅÅÀÀÀÅÅÅÅÅÅÂÂÂÃÃÃÇÇÇÇÇÇÃÃô´´»»»ÇÇÇÎÎγ³³···ÅÅÅÌÌÌÍÍÍÎÎÎÎÎÎÎÎÎÐÐÐÒÒÒÕÕÕÎÎÎÑÑÑÆÆƱ±±´´´µµµÇÇÇ¿¿¿ÃÃÃÃÃÃÊÊÊÌÌÌÐÐÐÑÑÑÃÃû»»¼¼¼µµµ±±±···¼¼¼¾¾¾¾¾¾¼¼¼³³³¿¿¿ÅÅž¾¾ººº¿¿¿¾¾¾···ÃÃû»»³³³¼¼¼ÆÆÆ»»»³³³µµµ¯¯¯¬¬¬¬¬¬¦¦¦©©©±±±³³³¼¼¼¾¾¾ºººÅÅž¾¾ÅÅÅ¿¿¿Â»»»ÛÛÛÎÎÎÍÍÍÌÌÌÆÆÆÉÉɼ¼¼¼¼¼¼¼¼¼¼¼¼¼¼»»»»»»»»»¾¾¾¼¼¼µµµ¬¬¬©©©°°°°°°¯¯¯µµµ»»»¼¼¼¾¾¾ÂÂÂÃÃÃÃÃÃÅÅÅÂÂÂÃÃÃÀÀÀÉÉÉÊÊÊ»»»»»»ÝÝÝØØØÇÇÇÅÅÅÃÃÃÔÔÔ···ÃÃÃÒÒÒÕÕÕÕÕÕÇÇÇÉÉÉØØØÔÔÔÌÌÌÀÀÀÉÉÉÐÐÐÐÐÐÐÐÐÐÐÐÅÅŵµµ¸¸¸ÍÍÍÃÃÃÐÐÐÍÍÍÀÀÀ¼¼¼¾¾¾¼¼¼¼¼¼¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¼¼¼»»»¼¼¼¿¿¿ÂÂÂÀÀÀÃÃÃÆÆÆÉÉÉÅÅÅÐÐÐÕÕÕÊÊÊÊÊÊÒÒÒÍÍÍÆÆÆÙÙÙÎÎÎÃÃ÷·····ÙÙÙÊÊÊÇÇǼ¼¼°°°¼¼¼ÜÜÜæææ×××ÔÔÔÜÜÜÔÔÔÎÎÎÊÊÊÆÆÆÉÉÉÅÅÅÍÍÍÌÌÌÌÌÌÎÎÎÒÒÒÕÕÕÕÕÕÔÔÔÕÕÕØØØÑÑÑÅÅż¼¼¸¸¸»»»ÃÃü¼¼¿¿¿ÍÍÍÐÐÐÃÃÿ¿¿ÀÀÀ¸¸¸ÌÌÌÐÐÐÙÙÙÝÝÝÛÛÛÝÝÝàààÙÙÙàààÑÑÑàààãããâââÔÔÔÔÔÔ¿¿¿ÆÆÆÅÅÅ»»»°°°···¾¾¾¼¼¼µµµ³³³»»»ÀÀÀµµµ±±±¼¼¼ÆÆÆ¿¿¿ÀÀÀÀÀÀÀÀÀÅÅÅÉÉÉÆÆƱ±±»»»ÇÇÇÎÎÎÆÆÆ»»»¿¿¿ÉÉÉÌÌÌÍÍÍÎÎÎÍÍÍÌÌÌÊÊÊÊÊÊÌÌÌÎÎÎÐÐÐÉÉÉ»»»¿¿¿ºººÇÇÇ¿¿¿¿¿¿ÆÆÆÌÌÌÊÊÊÌÌÌÎÎÎÉÉÉÀÀÀ»»»»»»¼¼¼»»»¸¸¸µµµµµµ···¼¼¼ÆÆÆÀÀÀººººººÀÀÀÅÅÅ···ººº¸¸¸ÇÇÇÎÎξ¾¾´´´µµµµµµ¸¸¸ººº¯¯¯¥¥¥ªªª±±±´´´´´´¯¯¯ººº»»»»»»ÅÅÅÅÅÅÅÅÅ¿¿¿µµµ×××ÍÍÍÍÍÍÌÌÌ¿¿¿¾¾¾¾¾¾»»»ºººººº»»»»»»ººº···µµµ´´´°°°¯¯¯¸¸¸ÀÀÀµµµ¤¤¤···»»»ÀÀÀÀÀÀ¿¿¿¾¾¾¾¾¾¿¿¿ÀÀÀÃÃþ¾¾ÍÍÍÌÌ̸¸¸¾¾¾×××ÍÍÍ»»»»»»ÀÀÀÒÒÒ···µµµ¿¿¿ÅÅÅÃÃø¸¸»»»ÊÊÊÑÑÑÑÑÑÐÐÐÔÔÔ×××ÔÔÔÐÐÐÉÉɼ¼¼±±±···ÌÌÌÀÀÀÅÅÅÍÍÍ»»»»»»»»»»»»¼¼¼¼¼¼¾¾¾¿¿¿¿¿¿¿¿¿ÂÂÂÀÀÀ¿¿¿¿¿¿ÀÀÀÂÂÂÃÃÃÆÆÆÆÆÆÅÅÅÔÔÔÙÙÙÍÍÍÎÎÎÒÒÒÇÇÇÌÌÌâââÊÊÊ¿¿¿Â¿¿¿±±±ÎÎÎÌÌÌÇÇÇÅÅŸ¸¸´´´ÊÊÊäääæææÑÑÑÛÛÛÙÙÙ×××ÍÍÍÇÇÇÍÍÍÅÅÅÌÌÌÊÊÊÌÌÌÑÑÑÕÕÕ×××ÑÑÑÌÌÌÑÑÑ××××××ÔÔÔÑÑÑÎÎÎÊÊÊÇÇÇÃÃÃÀÀÀÇÇÇÍÍÍÊÊÊÆÆÆÃÃü¼¼¼¼¼ÂÂÂÑÑÑÙÙÙÙÙÙÝÝÝâââßßßàààÒÒÒãããçççäääÛÛÛÙÙÙ¿¿¿ÅÅÅÅÅÅ¿¿¿´´´°°°µµµ»»»¼¼¼´´´³³³¿¿¿ÉÉɼ¼¼±±±···ÀÀÀÀÀÀÀÀÀÀÀÀÃÃÃÇÇÇÇÇǼ¼¼ºººÀÀÀÌÌÌÑÑÑÎÎÎÅÅÅ»»»¸¸¸ÆÆÆÉÉÉÊÊÊÊÊÊÉÉÉÆÆÆÆÆÆÆÆÆÌÌÌÊÊÊÊÊÊÊÊÊÍÍͺººÂ¿¿¿ºººÆÆÆÍÍÍÌÌÌÇÇÇÉÉÉÌÌÌÉÉÉÆÆÆÊÊÊÍÍÍÊÊÊÅÅż¼¼µµµ±±±´´´···¿¿¿ÅÅŸ¸¸´´´µµµ¬¬¬¿¿¿ÃÃÃÍÍÍÎÎλ»»´´´°°°¬¬¬±±±±±±ªªª¦¦¦¸¸¸···ÆÆƵµµ¸¸¸ººººººÂÂÂÂÂÂÅÅÅÆÆÆ¿¿¿ÜÜÜÒÒÒÑÑÑÊÊÊ¿¿¿¼¼¼¿¿¿»»»¸¸¸¸¸¸ººº¸¸¸µµµ³³³³³³±±±¯¯¯¿¿¿ÎÎÎÅÅÅ°°°³³³···¼¼¼ÂÂÂÃÃÃÃÃÃÅÅÅÆÆƾ¾¾ÃÃþ¾¾ÎÎÎÍÍ͸¸¸¿¿¿ÅÅÅÉÉÉÃÃÃÃÃÃÇÇÇÕÕÕÀÀÀ¸¸¸¯¯¯¸¸¸¼¼¼»»»¼¼¼ÅÅÅÐÐÐÒÒÒ××××××ÙÙÙÜÜÜ×××ÆÆƸ¸¸±±±»»»ÉÉɼ¼¼¸¸¸ÉÉÉÅÅž¾¾ººº»»»»»»¼¼¼¾¾¾¾¾¾¿¿¿ÀÀÀÀÀÀÂÂÂÂÂÂÀÀÀ¿¿¿ÂÂÂÆÆÆÊÊÊÍÍÍÎÎÎÒÒÒ×××ÕÕÕÍÍÍÉÉÉÉÉÉÅÅÅßßßäääÊÊÊÂÂÂÀÀÀ¾¾¾¬¬¬¼¼¼ÐÐÐÅÅÅÆÆÆÅÅÅ´´´µµµÐÐÐäääèèèäääÕÕÕÔÔÔÔÔÔ×××ÙÙÙÌÌÌÃÃÃÇÇÇÐÐÐÛÛÛãããâââÛÛÛÒÒÒÔÔÔÔÔÔÔÔÔÔÔÔ×××ÝÝÝÝÝÝ×××ÎÎÎÊÊÊÂÂÂÅÅÅÐÐÐÐÐÐÆÆÆÃÃúºº¾¾¾ÍÍÍÙÙÙÙÙÙÜÜÜßßßÜÜÜÔÔÔÐÐÐàààÝÝÝßßßÛÛÛ×××···ÀÀÀÆÆÆÅÅż¼¼µµµµµµ»»»¾¾¾¾¾¾±±±±±±µµµ©©©´´´¿¿¿ÃÃÃÃÃÃÆÆÆÉÉÉÉÉÉÃÃü¼¼···ÆÆÆÆÆÆÇÇÇÊÊÊÍÍÍÊÊÊ¿¿¿´´´¿¿¿ÃÃÃÇÇÇÉÉÉÉÉÉÇÇÇÇÇÇÇÇÇÅÅÅÃÃÃÊÊÊÐÐÐÒÒÒ···¾¾¾¼¼¼¸¸¸ÆÆÆÊÊÊÌÌÌÇÇÇÃÃÃÌÌÌÊÊÊÎÎÎÍÍÍÌÌÌÉÉÉÉÉÉÃÃ÷··ªªª¯¯¯¤¤¤¨¨¨¾¾¾ÍÍÍÅÅÅ···°°°»»»ÌÌÌÀÀÀ¼¼¼ººº¯¯¯···³³³¬¬¬³³³±±±¿¿¿ÉÉÉÐÐÐÌÌÌÝÝÝÍÍÍÊÊÊÀÀÀ»»»ÂÂÂÂÂÂÂÂÂÆÆÆÇÇÇÝÝÝÕÕÕÐÐÐÅÅÅÉÉÉÇÇǾ¾¾»»»¸¸¸¸¸¸¸¸¸···´´´±±±µµµ´´´ªªªºººÎÎÎÕÕÕÍÍͱ±±³³³¸¸¸ÂÂÂÆÆÆÇÇÇÇÇÇÉÉɾ¾¾Â¿¿¿ÍÍÍÌÌÌ···¼¼¼ºººÇÇÇÑÑÑÒÒÒÊÊÊÆÆƸ¸¸´´´¸¸¸¾¾¾ºººººº¸¸¸¸¸¸ÃÃÃÃÃÃÃÃÃÃÃÃÊÊÊÕÕÕÔÔÔÃÃó³³¼¼¼ÅÅż¼¼±±±ÂÂÂÅÅÅ»»»¼¼¼¼¼¼¾¾¾¾¾¾¿¿¿ÀÀÀÀÀÀÀÀÀ¿¿¿ÂÂÂÂÂÂÃÃÃÇÇÇÎÎÎÔÔÔÔÔÔÑÑÑÔÔÔÐÐÐÊÊÊÉÉÉÆÆÆÆÆÆÐÐÐàààÒÒÒÂÂÂÅÅÅÀÀÀººº´´´¿¿¿ÕÕÕÅÅÅÂÂÂÆÆƺºººººÎÎÎÝÝÝêêêäääßßßØØØÒÒÒÛÛÛÛÛÛàààßßßÝÝÝÝÝÝßßßÝÝÝÙÙÙÕÕÕÛÛÛÜÜÜßßßØØØÔÔÔÙÙÙÛÛÛÒÒÒÕÕÕÒÒÒÅÅÅÂÂÂÑÑÑÔÔÔÌÌÌÊÊÊÆÆÆÅÅÅÐÐÐÜÜÜÝÝÝÜÜÜÜÜÜ×××ÑÑÑÕÕÕâââÙÙÙßßßÛÛÛÔÔÔ¸¸¸ÀÀÀÅÅÅÆÆÆ¿¿¿¸¸¸···»»»¿¿¿ÅÅŵµµ¯¯¯¯¯¯ªªª¸¸¸¾¾¾ÂÂÂÅÅÅÇÇÇÊÊÊÅÅż¼¼¸¸¸¸¸¸ÊÊÊÇÇÇÃÃÃÃÃÃÉÉÉÍÍÍÆÆƼ¼¼ººº¾¾¾ÃÃÃÆÆÆÆÆÆÅÅÅÅÅÅÅÅÅÀÀÀÆÆÆÎÎÎÎÎÎÎÎη··¿¿¿¾¾¾¼¼¼ÃÃÃÂÂÂÊÊÊÊÊÊÃÃÃÊÊÊÉÉÉÉÉÉÇÇÇÃÃÃÃÃÃÉÉÉÎÎÎÌÌÌÅÅž¾¾¬¬¬¢¢¢ÀÀÀÉÉÉÇÇÇÅÅÅÃÃÃÍÍÍ´´´¯¯¯¯¯¯¨¨¨´´´°°°©©©´´´©©©±±±ÂÂÂÂÂÂÀÀÀ¾¾¾ÉÉÉÊÊÊÐÐо¾¾µµµÇÇÇÍÍÍÊÊÊÊÊÊÎÎÎÜÜÜÛÛÛÕÕÕÃÃÃÊÊÊ¿¿¿»»»ººº¸¸¸¸¸¸······µµµ³³³¬¬¬±±±ÃÃÃÕÕÕØØØÑÑѼ¼¼¸¸¸»»»ÂÂÂÅÅÅÀÀÀ»»»ººº¿¿¿ÀÀÀÀÀÀ¿¿¿ÉÉÉÇÇÇ´´´µµµ°°°µµµÅÅÅÔÔÔÎÎξ¾¾µµµ¸¸¸»»»ººº¯¯¯³³³µµµ±±±µµµ³³³´´´»»»ÅÅÅÉÉÉÃÃø¸¸°°°¸¸¸¿¿¿ÃÃñ±±»»»ÂÂÂÇÇÇ¿¿¿¾¾¾¾¾¾¿¿¿¿¿¿ÀÀÀÀÀÀÀÀÀ¿¿¿ÅÅÅÉÉÉÊÊÊÎÎÎÔÔÔÕÕÕÑÑÑ¿¿¿ÀÀÀÀÀÀÅÅÅÊÊÊÉÉÉÐÐÐßßßÉÉɾ¾¾¾¾¾¾¾¾¾¾¾»»»ÅÅÅÍÍÍÎÎÎÉÉÉÃÃÃÃÃÃÀÀÀ¸¸¸···Â´´´ÕÕÕàààäääâââÔÔÔÔÔÔØØØÜÜÜÙÙÙ××××××ÛÛÛâââçççëëëßßßâââçççâââÙÙÙÜÜÜÛÛÛÎÎÎØØØØØØÑÑÑÉÉÉÍÍÍÔÔÔÔÔÔÐÐÐÇÇÇÀÀÀÇÇÇØØØßßßäääæææàààØØØÝÝÝãããÙÙÙâââ×××ÎÎÎÀÀÀÆÆƼ¼¼ººº¸¸¸ººº¼¼¼¿¿¿ÀÀÀ¸¸¸¸¸¸¸¸¸´´´···»»»¸¸¸¼¼¼¿¿¿ÅÅÅÅÅż¼¼µµµ¸¸¸ÂÂÂÆÆÆÉÉÉÉÉÉÉÉÉÍÍÍÎÎÎÃÃô´´···»»»ÀÀÀ¿¿¿¾¾¾¼¼¼ÀÀÀÌÌÌÔÔÔÍÍÍÊÊʺººÅÅÅÀÀÀÀÀÀÀÀÀ»»»ÉÉÉÎÎÎÆÆÆÉÉÉÅÅÅÇÇÇÇÇÇÃÃû»»»»»ÃÃÃÊÊÊÍÍÍÆÆƺºº¬¬¬¦¦¦¬¬¬³³³³³³°°°µµµ¿¿¿···¼¼¼¬¬¬žžžÉÉÉÛÛÛÎÎÎÐÐÐØØØÇÇÇÀÀÀÂÂÂÀÀÀÔÔÔâââÆÆƸ¸¸ÑÑÑÙÙÙÑÑÑóóóèèèÜÜÜÒÒÒÐÐп¿¿ÌÌ̺ºº¸¸¸¸¸¸¸¸¸············µµµ³³³©©©¤¤¤ÆÆÆÛÛÛÛÛÛÑÑÑ°°°°°°¼¼¼ÆÆÆÆÆÆÂÂÂÂÂÂÀÀÀ¿¿¿ÀÀÀ¿¿¿ÅÅÅÃÃð°°¯¯¯¸¸¸···ÔÔÔØØØÀÀÀµµµ¸¸¸´´´´´´°°°ÅÅÅÒÒÒÍÍÍÅÅű±±···ºººººº»»»ÃÃÃÌÌÌÉÉÉ¿¿¿³³³¼¼¼ÉÉÉ´´´···¾¾¾ÉÉÉ¿¿¿¿¿¿¿¿¿ÀÀÀÀÀÀÀÀÀÂÂÂÂÂÂÂÂÂÊÊÊÐÐÐÑÑÑÒÒÒÕÕÕÑÑÑÊÊÊÃÃÃÀÀÀÅÅÅÍÍÍÊÊÊÂÂÂÂÂÂÍÍ͵µµºººÃÃõµµ···ºººÎÎÎÐÐÐÂÂÂÐÐÐÌÌÌÂÂÂÅÅÅÆÆÆÂÂÂÃÃúººÀÀÀ°°°ºººÛÛÛâââÛÛÛÔÔÔÙÙÙÛÛÛÝÝÝßßßÝÝÝÛÛÛØØØ×××ÝÝÝÝÝÝâââàààßßßêêêíííÝÝÝ×××ÙÙÙÛÛÛÑÑÑÇÇÇÑÑÑÛÛÛÒÒÒÑÑÑÃÃÃÆÆÆÔÔÔÜÜÜââââââÛÛÛÛÛÛÝÝÝÝÝÝÔÔÔßßßÌÌÌÃÃÃÂÂÂÌÌÌÀÀÀ´´´±±±···¼¼¼¿¿¿¾¾¾¸¸¸µµµ¸¸¸¸¸¸±±±´´´¸¸¸³³³µµµ»»»ÀÀÀ¿¿¿µµµ±±±»»»ÊÊÊÃÃÃÂÂÂÀÀÀÃÃÃÇÇÇÌÌÌÍÍÍÍÍÍÇÇÇ»»»ººº¾¾¾ÀÀÀÀÀÀ¿¿¿ÎÎÎÌÌÌÍÍÍÐÐÐÊÊÊÀÀÀ¿¿¿ÅÅÅÃÃÃÂÂÂÂÂÂÅÅÅÉÉÉÊÊÊÉÉÉÆÆƸ¸¸¿¿¿ºººººº¾¾¾»»»ÌÌÌÌÌ̺ºº¨¨¨¥¥¥¦¦¦¨¨¨©©©³³³¯¯¯µµµ±±±©©©°°°Â»»»ÃÃÃÅÅž¾¾ÃÃÃÉÉÉÃÃÃÂÂÂÊÊÊÉÉÉÙÙÙÎÎÎÒÒÒãããÔÔÔÕÕÕÜÜÜÛÛÛØØØÒÒÒÍÍÍÇÇǾ¾¾¸¸¸······´´´³³³³³³´´´µµµ¥¥¥¢¢¢³³³ÊÊÊÒÒÒ××××××ÐÐÐ¥¥¥°°°ººº¾¾¾ÂÂÂÇÇÇÆÆÆ¿¿¿ÀÀÀ¾¾¾¿¿¿ÀÀÀÂÂÂÉÉÉÇÇÇ»»»¬¬¬¼¼¼××××××¾¾¾°°°···³³³´´´±±±ÃÃÃßßßÛÛÛÉÉÉÊÊʵµµ······±±±»»»Â¾¾¾ÍÍÍÆÆƱ±±ºººÇÇÇÌÌ̾¾¾³³³ÇÇÇÅÅÅ¿¿¿ÀÀÀÃÃÃÃÃÃÃÃÃÃÃÃÊÊÊÊÊÊÎÎÎÔÔÔÒÒÒÌÌÌÇÇÇÉÉÉÌÌÌÔÔÔÎÎÎÂÂÂÀÀÀÍÍÍÐÐÐÇÇǼ¼¼¿¿¿±±±¸¸¸ÌÌÌÑÑÑÑÑÑÊÊÊÊÊÊÊÊÊÉÉÉÆÆÆÅÅÅÅÅÅÅÅÅÆÆÆÍÍÍÊÊÊ¿¿¿ÃÃü¼¼···×××îîîÔÔÔØØØ×××ØØØ×××ÝÝÝèèèÛÛÛñññííííííúúúñññàààçççààààààæææÝÝÝÙÙÙÜÜÜÍÍÍÂÂÂÑÑÑØØØÔÔÔÀÀÀÂÂÂÝÝÝäääÙÙÙÝÝÝÑÑÑÙÙÙàààÙÙÙÊÊÊÀÀÀÂÂÂÇÇÇ¿¿¿ÇÇDZ±±¸¸¸Â¼¼¼ÅÅÅ»»»ÀÀÀ¼¼¼¸¸¸ººº¸¸¸±±±±±±»»»ºººÂÂÂÊÊÊ···µµµÊÊÊÍÍÍÍÍÍÅÅÅ¿¿¿ÂÂÂÆÆÆÊÊÊÊÊÊÊÊÊÉÉÉÃÃþ¾¾ººº»»»¼¼¼»»»ºººÌÌÌÎÎÎÑÑÑÎÎÎÅÅž¾¾ÀÀÀÆÆÆÅÅÅÃÃÃÂÂÂÂÂÂÃÃÃÅÅÅÅÅÅÃÃû»»···»»»ººº»»»¾¾¾¿¿¿ÉÉÉÀÀÀ¸¸¸©©©¨¨¨¤¤¤¡¡¡¡¡¡¢¢¢©©©°°°³³³±±±³³³¸¸¸¿¿¿ÂÂÂ×××ÙÙÙÇÇÇÀÀÀÂÂÂÂÂÂÅÅÅÆÆÆÌÌÌÜÜÜÍÍÍÐÐÐæææÝÝÝßßßÛÛÛÙÙÙ×××ÒÒÒÌÌÌÆÆÆÀÀÀ¾¾¾´´´±±±±±±µµµ¸¸¸µµµ°°°ªªªµµµ±±±¿¿¿ÐÐÐÔÔÔ××××××ÒÒÒ¯¯¯°°°···¾¾¾¾¾¾ººº···¸¸¸¾¾¾»»»¿¿¿ÀÀÀÀÀÀÆÆÆÇÇǼ¼¼³³³±±±ºººÆÆÆÉÉÉÀÀÀ¸¸¸¸¸¸´´´ººº´´´¾¾¾ÛÛÛâââÑÑÑÉÉÉ´´´³³³´´´¬¬¬¬¬¬±±±°°°¾¾¾¾¾¾Â¿¿¿´´´¼¼¼ÆÆÆ¿¿¿ÌÌÌÍÍÍÇÇÇÀÀÀ¾¾¾ÃÃÃÇÇÇÇÇÇÃÃÃÃÃÃÇÇÇÎÎÎÑÑÑÌÌÌÂÂÂÀÀÀÅÅÅÑÑÑÊÊÊÂÂÂÀÀÀÍÍÍÕÕÕÎÎο¿¿»»»¼¼¼···ÊÊÊÜÜÜÕÕÕÎÎÎÌÌÌÎÎÎÊÊÊÊÊÊÍÍÍÍÍÍÊÊÊÌÌÌÐÐÐÉÉÉÉÉÉÂÂÂÌÌÌÍÍ;¾¾³³³æææßßßÙÙÙàààÛÛÛÙÙÙææææææíííêêêâââïïïöööíííïïïïïïãããæææãããßßßÙÙÙ×××ÐÐÐÉÉÉÕÕÕØØØÌÌÌÃÃÃÒÒÒÜÜÜÜÜÜßßßÜÜÜÙÙÙÔÔÔÊÊÊÃÃÃÀÀÀÃÃÃÇÇÇÉÉÉÇÇǪªª¯¯¯»»»¸¸¸Â¼¼¼¾¾¾»»»»»»···©©©³³³¸¸¸¾¾¾Âµµµ»»»ÉÉÉÃÃÃÂÂÂÅÅÅÀÀÀ¼¼¼¿¿¿ÅÅÅÊÊÊÌÌÌÌÌÌÌÌÌÉÉÉÃÃÿ¿¿¼¼¼»»»ººººººÌÌÌÒÒÒÔÔÔÊÊʾ¾¾»»»ÂÂÂÇÇÇÅÅÅÅÅÅÃÃÃÀÀÀ¿¿¿¾¾¾¿¿¿Âººº¾¾¾»»»¾¾¾¼¼¼¿¿¿ÉÉÉÆÆƾ¾¾¼¼¼ºººµµµ±±±¯¯¯©©©¢¢¢¤¤¤¯¯¯±±±ªªª¬¬¬ºººÅÅÅÇÇǸ¸¸ÑÑÑÒÒÒ¼¼¼ÃÃÃÍÍÍÔÔÔ¿¿¿ÎÎÎããã××××××èèèßßßØØØÛÛÛÙÙÙ×××ÑÑÑÌÌÌÆÆÆ¿¿¿´´´¯¯¯¯¯¯´´´···³³³°°°¯¯¯ÊÊÊÇÇÇÐÐÐØØØØØØØØØØØØÕÕÕÉÉɺºº´´´¿¿¿ÃÃúººµµµººº¸¸¸¸¸¸¾¾¾ÀÀÀ¿¿¿ÃÃÃÇÇÇÀÀÀººº³³³±±±ºººÀÀÀ¿¿¿¼¼¼ººº···ÀÀÀººº¸¸¸ÑÑÑààà×××ÊÊÊÆÆÆÂÂÂÉÉɼ¼¼°°°±±±···ºººÇÇÇÍÍͺºº¸¸¸ÅÅÅÀÀÀ¼¼¼ÇÇÇÍÍÍÍÍÍÇÇÇÃÃÃÇÇÇÊÊÊÊÊÊÉÉÉÎÎÎÕÕÕÔÔÔÉÉɾ¾¾ÀÀÀÊÊÊÑÑѾ¾¾ºººÅÅÅÙÙÙÔÔÔÇÇÇ»»»ººº¸¸¸»»»ÙÙÙæææÒÒÒÌÌÌÎÎÎÐÐÐÊÊÊÉÉÉÌÌÌÌÌÌÉÉÉÊÊÊÎÎÎÑÑÑÑÑÑÇÇÇÉÉÉÐÐÐÒÒÒÑÑÑÅÅÅÉÉÉÀÀÀ¸¸¸¾¾¾»»»¼¼¼ÒÒÒÜÜÜäääãããÐÐÐÆÆÆÃÃþ¾¾ÎÎÎçççÝÝÝëëëîîîæææØØØÝÝÝØØØÍÍÍÒÒÒÛÛÛ×××ÉÉÉÆÆÆÒÒÒÛÛÛÛÛÛÜÜÜÑÑÑÆÆÆÀÀÀÂÂÂÆÆÆÇÇÇÇÇÇÉÉÉÅÅŪªª¯¯¯µµµ···»»»ººº¸¸¸¿¿¿¾¾¾´´´¼¼¼ÆÆÆ´´´···ººº¸¸¸ÆÆÆÎÎÎÅÅÅÆÆÆÆÆÆÀÀÀ»»»»»»ÀÀÀÉÉÉÍÍÍÐÐÐÎÎÎÎÎÎÌÌÌÇÇÇÃÃÃÀÀÀÂÂÂÃÃÃÎÎÎÒÒÒÐÐÐÃÃû»»¾¾¾ÃÃÃÅÅÅÃÃÃÃÃÃÅÅÅ¿¿¿¾¾¾¿¿¿ÀÀÀ¿¿¿ÇÇǾ¾¾ÀÀÀ¿¿¿¿¿¿ÑÑÑÅÅž¾¾¾¾¾¸¸¸´´´µµµººº´´´©©©¢¢¢°°°©©©ªªª···¿¿¿¿¿¿¿¿¿ÍÍÍÇÇÇÃÃÃÆÆÆÆÆÆÉÉÉÆÆÆ×××ÝÝÝëëëãããäääîîîâââÛÛÛÜÜÜÛÛÛ×××ÒÒÒÍÍÍÉÉÉÅÅÅÃÃø¸¸···´´´±±±¯¯¯»»»ÉÉÉØØØØØØÜÜÜßßßÝÝÝÛÛÛÙÙÙØØØÕÕÕ»»»ªªª°°°¸¸¸···³³³³³³´´´µµµ¼¼¼ÀÀÀ¾¾¾ÂÂÂÆÆÆÃÃÃÃÃ󳳬¬¬···¿¿¿»»»ººº¾¾¾¼¼¼ÅÅż¼¼´´´ÃÃÃÒÒÒÔÔÔÑÑÑÉÉÉÅÅÅÒÒÒÇÇǬ¬¬©©©³³³°°°ÅÅÅÍÍÍÀÀÀÂÂÂÇÇÇÀÀÀ¾¾¾ÊÊÊÑÑÑÎÎÎÌÌÌÎÎÎÐÐÐÍÍÍÔÔÔÔÔÔÔÔÔÐÐÐÆÆÆ¿¿¿ÆÆÆÐÐÐÊÊʸ¸¸¿¿¿ÐÐÐÝÝÝÇÇǾ¾¾¼¼¼¸¸¸ººº¿¿¿ÙÙÙàààÎÎÎÎÎÎÑÑÑÍÍÍÌÌÌÉÉÉÇÇÇÉÉÉÍÍÍÐÐÐÐÐÐÕÕÕÍÍÍ¿¿¿»»»ÀÀÀÊÊÊÑÑÑÐÐÐÊÊÊÎÎÎÊÊÊÊÊÊÃÃþ¾¾ÉÉÉÊÊÊ¿¿¿ÃÃÃÅÅÅÌÌÌÒÒÒÎÎÎÐÐÐÙÙÙÒÒÒòòòøøøîîîÝÝÝÜÜÜÕÕÕÛÛÛÒÒÒÕÕÕÙÙÙÒÒÒÆÆÆÌÌÌÔÔÔÑÑÑÌÌÌÆÆÆÀÀÀÃÃÃÊÊÊÎÎÎÌÌÌÇÇÇÆÆÆÊÊÊÀÀÀÅÅÅ¿¿¿¬¬¬±±±¼¼¼¿¿¿»»»ÀÀÀ¾¾¾´´´ÂÂÂÍÍ;¾¾ÃÃÃÆÆÆÂÂÂÅÅÅÎÎÎÉÉÉ¿¿¿ÆÆÆÎÎÎÉÉÉÀÀÀ¼¼¼¾¾¾ÃÃÃÊÊÊÎÎÎÑÑÑÒÒÒÒÒÒÑÑÑÍÍÍÌÌÌÍÍÍÐÐÐÑÑÑÐÐÐÇÇǾ¾¾»»»ÂÂÂÃÃÿ¿¿¿¿¿ÂÂÂÆÆÆÆÆÆÃÃÃÀÀÀÀÀÀ¿¿¿ÆÆƺººÀÀÀ¾¾¾¿¿¿×××ÆÆƼ¼¼´´´¨¨¨¢¢¢ªªª´´´°°°¥¥¥©©©···ÇÇÇÒÒÒÔÔÔÐÐÐÇÇÇÂÂÂÆÆÆÊÊÊ¿¿¿ÇÇÇÒÒÒÌÌÌÍÍÍÉÉÉßßßÔÔÔÐÐÐÍÍÍÐÐÐÕÕÕÒÒÒÕÕÕÜÜÜÛÛÛØØØÔÔÔÐÐÐÍÍÍÊÊÊÉÉÉ¿¿¿¸¸¸°°°¯¯¯¸¸¸ÌÌÌÜÜÜÜÜÜàààâââââââââßßßÛÛÛÙÙÙÜÜÜÌÌÌ···±±±´´´´´´³³³³³³»»»ÀÀÀ¾¾¾¿¿¿ÆÆÆÅÅÅÊÊÊ»»»°°°³³³¸¸¸¸¸¸¼¼¼ÀÀÀÂÂÂÃÃü¼¼´´´µµµ¼¼¼ÉÉÉØØؾ¾¾¼¼¼ÒÒÒÌÌ̱±±°°°°°°¦¦¦···©©©ºººÑÑÑÆÆƺººÃÃÃÆÆÆÀÀÀÂÂÂÃÃÃÇÇÇÑÑÑØØØÕÕÕÌÌÌØØØÎÎÎÅÅÅÀÀÀ¿¿¿ÀÀÀÉÉÉÑÑÑÉÉɸ¸¸ÆÆÆÕÕÕßßß¿¿¿¸¸¸¼¼¼µµµÀÀÀÊÊÊÛÛÛÛÛÛÐÐÐÔÔÔÒÒÒÌÌÌÑÑÑÐÐÐÉÉÉÍÍÍÙÙÙÜÜÜÔÔÔÃÃþ¾¾ÀÀÀÌÌÌØØØÛÛÛÔÔÔÐÐÐÇÇÇ×××ßßßëëëäääÒÒÒÎÎÎÍÍÍÍÍÍÍÍÍØØØàààßßßßßßààààààÒÒÒêêêñññöööãããßßßÕÕÕàààÕÕÕÌÌÌÔÔÔÛÛÛÐÐÐÊÊÊÌÌÌÆÆÆÂÂÂÃÃÃÆÆÆÍÍÍÑÑÑÑÑÑÍÍÍÉÉÉÀÀÀÇÇÇÅÅÅÉÉɬ¬¬©©©³³³¾¾¾¾¾¾ÇÇÇÀÀÀ±±±¾¾¾ÌÌÌ¿¿¿ÆÆÆÊÊÊÉÉÉÌÌÌÍÍÍÂÂÂÃÃÃÒÒÒÙÙÙÔÔÔÌÌÌÃÃþ¾¾¿¿¿ÅÅÅÉÉÉÑÑÑÒÒÒÕÕÕÕÕÕÒÒÒÑÑÑÑÑÑÒÒÒÐÐÐÊÊÊÀÀÀ»»»¾¾¾ÂÂÂÀÀÀ¼¼¼¾¾¾ÀÀÀÅÅÅÇÇÇÆÆÆÅÅÅ»»»¾¾¾´´´¿¿¿¼¼¼¿¿¿×××ÇÇǾ¾¾°°°¡¡¡¤¤¤ªªª©©©¡¡¡ŸŸŸ©©©¾¾¾ÑÑÑÕÕÕÊÊÊÀÀÀ¾¾¾ÀÀÀÃÃô´´ÂÂÂÉÉÉßßßèèèäääÕÕÕÎÎÎÔÔÔÙÙÙØØØØØØÝÝÝÛÛÛÙÙÙ×××ÔÔÔÑÑÑÎÎÎÎÎÎÍÍÍÉÉÉÆÆÆ»»»³³³ºººÌÌÌÙÙÙÜÜÜÜÜÜââââââàààäääãããßßßÜÜÜààààààÕÕÕ¾¾¾¯¯¯°°°µµµ¸¸¸³³³±±±ºººÂ¾¾¾¿¿¿ÅÅÅÆÆÆÌÌÌÊÊÊ¿¿¿±±±¯¯¯ºººÀÀÀÂÂÂÃÃÿ¿¿ºººµµµ¯¯¯¯¯¯ÀÀÀÛÛÛ¾¾¾¿¿¿ÕÕÕÐÐм¼¼ÂÂÂÀÀÀ···³³³´´´···ÊÊÊÍÍÍ»»»···»»»ÀÀÀ¿¿¿¾¾¾ÀÀÀÆÆÆÍÍÍÒÒÒÔÔÔ×××ÉÉɼ¼¼¼¼¼ÂÂÂÇÇÇÐÐÐ×××ÌÌ̺ººÇÇÇÑÑÑâââÀÀÀ»»»¸¸¸´´´ÉÉÉÙÙÙäääÜÜÜÕÕÕÙÙÙÐÐÐÑÑÑ×××ÕÕÕÍÍÍÎÎÎÔÔÔÐÐÐÃÃúºº»»»ÊÊÊÒÒÒÒÒÒÍÍÍÂÂÂÆÆÆÉÉÉÌÌÌÎÎÎãããàààÅÅÅÃÃÃÐÐÐëëëàààäääÛÛÛÊÊÊÐÐÐÛÛÛäääÛÛÛÙÙÙàààúúúäääçççÜÜÜÛÛÛÙÙÙÊÊÊÐÐÐÝÝÝÙÙÙÐÐÐÉÉÉÂÂÂÅÅÅÉÉÉÍÍÍÐÐÐÐÐÐÍÍÍÊÊÊÉÉÉÇÇÇÅÅÅ¿¿¿ÂÂÂÃÃ÷··±±±´´´¿¿¿ÊÊÊ°°°¸¸¸ÉÉÉÇÇǼ¼¼ÂÂÂÅÅÅÌÌÌÇÇÇÀÀÀÑÑÑàààÛÛÛÙÙÙÕÕÕÌÌÌ¿¿¿ÂÂÂÇÇÇÐÐÐÑÑÑÒÒÒÑÑÑÎÎÎÌÌÌÊÊÊÉÉÉÌÌÌÃÃþ¾¾¾¾¾¿¿¿¾¾¾¼¼¼¼¼¼¿¿¿ÀÀÀÂÂÂÅÅÅÆÆÆÅÅÅÂÂÂÀÀÀ»»»¸¸¸ÇÇÇÂÂÂÂÂÂÒÒÒÅÅŸ¸¸¯¯¯¨¨¨¦¦¦©©©©©©¨¨¨¦¦¦¬¬¬¯¯¯µµµ¿¿¿ÃÃÃÅÅÅÇÇÇÍÍÍÃÃÃÍÍÍ°°°©©©³³³ÂÂÂàààäääÒÒÒÐÐÐÐÐÐ××××××ÑÑÑÒÒÒÕÕÕ×××ÕÕÕÒÒÒÑÑÑÐÐÐÐÐÐÐÐÐÐÐÐÉÉÉÌÌ̵µµ¾¾¾ÕÕÕÝÝÝ×××ÝÝÝãããßßßÛÛÛãããæææâââàààÛÛÛâââÝÝÝÊÊʺººµµµ³³³¯¯¯µµµ±±±¸¸¸Â¿¿¿ÀÀÀÅÅÅÅÅÅÉÉÉÑÑÑÐÐп¿¿´´´¸¸¸¾¾¾¾¾¾¿¿¿ººº···´´´¯¯¯¯¯¯ÀÀÀÕÕÕÃÃÃÂÂÂÎÎÎÅÅźººÂÂÂÀÀÀºººžžž¬¬¬¼¼¼ÎÎÎÇÇÇÃÃÃÀÀÀ¾¾¾¿¿¿Âººº···ÆÆÆØØØÉÉÉÀÀÀ»»»¿¿¿ÇÇÇÍÍÍÔÔÔÙÙÙÌÌ̾¾¾ÊÊÊÍÍÍßßßÅÅÅÀÀÀ¸¸¸´´´ÌÌÌßßßèèèÛÛÛÒÒÒÙÙÙÐÐÐÕÕÕÔÔÔÔÔÔ×××ÔÔÔÊÊʼ¼¼³³³¾¾¾ÇÇÇØØØÑÑÑÌÌÌÐÐÐÑÑÑÝÝÝÆÆÆ¿¿¿ÕÕÕÛÛÛÉÉÉÔÔÔíííÐÐÐÍÍÍÛÛÛßßßäääêêêßßßÛÛÛØØØÑÑÑÕÕÕöööäääëëëÝÝÝ×××ÜÜÜÒÒÒÑÑÑÙÙÙÜÜÜ×××ÎÎÎÆÆÆÇÇÇÊÊÊÎÎÎÐÐÐÎÎÎÌÌÌÉÉÉÆÆÆÎÎÎÌÌÌÅÅÅÃÃÃÊÊÊÇÇÇ¿¿¿ÀÀÀ³³³ººº¾¾¾···¯¯¯³³³»»»¼¼¼ÆÆÆÆÆÆÇÇÇÐÐÐÀÀÀ¼¼¼ÒÒÒØØØÕÕÕÙÙÙÙÙÙÒÒÒÇÇÇÂÂÂÅÅÅÊÊÊÎÎÎÐÐÐÎÎÎÍÍÍÊÊÊÅÅÅ¿¿¿ÆÆÆÀÀÀ¿¿¿ÀÀÀ¿¿¿ºººººº¿¿¿ÂÂÂÀÀÀÀÀÀÀÀÀÃÃÃÃÃÃÀÀÀ¿¿¿ÍÍÍÂÂÂÃÃÃÑÑÑÊÊÊÅÅÅÎÎά¬¬©©©ªªª¯¯¯¨¨¨¨¨¨¬¬¬´´´³³³¯¯¯¯¯¯³³³¼¼¼ÇÇÇÐÐо¾¾ÕÕÕÀÀÀ¸¸¸ÃÃÃÐÐÐßßßÍÍÍÍÍÍÒÒÒÔÔÔÒÒÒÍÍÍÊÊÊÑÑÑÕÕÕÒÒÒÑÑÑÐÐÐÎÎÎÎÎÎÎÎÎÐÐÐÐÐÐÆÆÆÑÑÑÊÊÊ···ºººÑÑÑÝÝÝØØØàààäääÜÜÜØØØâââçççääääääâââãããâââÙÙÙÒÒÒÊÊʼ¼¼¯¯¯···±±±¸¸¸ÂÂÂÀÀÀÀÀÀÅÅÅÅÅÅÅÅÅÐÐÐØØØÒÒÒ···µµµººº¼¼¼···´´´´´´±±±µµµÂÂÂÐÐÐÐÐÐÌÌÌÍÍͼ¼¼´´´¿¿¿¼¼¼¸¸¸¦¦¦¬¬¬¢¢¢¯¯¯¿¿¿ÆÆÆÐÐÐÇÇÇ¿¿¿¼¼¼ÀÀÀÃÃúºº±±±»»»ÎÎεµµ³³³µµµ¾¾¾ÆÆÆÉÉÉÎÎÎÒÒÒÉÉÉ¿¿¿ÐÐÐÊÊÊÜÜÜÃÃÃÆÆƾ¾¾···ÊÊÊÜÜÜæææÕÕÕÊÊÊÕÕÕÒÒÒÑÑÑÌÌÌÒÒÒâââãããÐÐо¾¾»»»ÂÂÂÉÉÉÕÕÕÇÇÇÅÅÅÎÎÎÃÃÿ¿¿ÃÃÃÆÆÆÀÀÀÎÎÎÒÒÒÅÅÅÊÊÊÛÛÛÎÎÎÕÕÕàààÝÝÝââââââÒÒÒÙÙÙÎÎÎÕÕÕÔÔÔïïïãããëëëÙÙÙÛÛÛßßßÛÛÛÕÕÕÕÕÕÙÙÙÛÛÛÔÔÔÍÍÍÅÅÅÇÇÇÌÌÌÐÐÐÑÑÑÎÎÎÉÉÉÅÅż¼¼¿¿¿¿¿¿»»»ÀÀÀ»»»¿¿¿±±±±±±¯¯¯±±±¿¿¿ÊÊÊÌÌÌÊÊÊÉÉÉÅÅÅÇÇÇÒÒÒÂÂÂÂÂÂÜÜÜØØØ×××ÔÔÔÔÔÔÕÕÕÎÎÎÅÅÅÂÂÂÅÅÅÊÊÊÃÃÃÅÅÅÆÆÆÂÂÂÆÆÆÊÊÊÃÃÃÆÆÆÃÃÃÀÀÀ¿¿¿ÀÀÀÂÂÂÀÀÀ¿¿¿¾¾¾¿¿¿ÃÃþ¾¾»»»ÌÌÌÕÕÕÌÌ̺ºº°°°···±±±¬¬¬°°°³³³ªªªªªª©©©©©©ªªª¯¯¯¯¯¯³³³±±±······ÅÅÅÂÂÂÇÇÇàààÙÙÙÑÑÑÐÐÐÔÔÔÕÕÕÒÒÒÍÍÍÔÔÔÔÔÔÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÑÑÑÐÐÐÎÎÎÎÎÎÎÎÎÐÐÐÌÌÌÐÐÐÍÍÍ¿¿¿»»»ÒÒÒçççÛÛÛææææææâââäääàààâââîîîèèèêêêêêêçççääääääßßßÐÐп¿¿°°°³³³ºººÂÂÂÃÃÃÀÀÀÀÀÀÃÃÃÇÇÇÀÀÀÉÉÉÐÐÐÃÃø¸¸¸¸¸···´´´±±±°°°³³³³³³³³³»»»ÅÅÅÅÅÅÅÅÅÇÇÇÃÃû»»ºººµµµ©©©ŸŸŸ¤¤¤©©©¯¯¯´´´¾¾¾ÇÇÇÎÎÎÆÆƸ¸¸¼¼¼ÅÅž¾¾´´´±±±°°°³³³µµµ´´´ºººÅÅÅÆÆÆÇÇÇÔÔÔÊÊʾ¾¾ÇÇÇÒÒÒàààÌÌÌÃÃþ¾¾ÂÂÂÆÆÆßßßãããÔÔÔÍÍÍÉÉÉÎÎÎÍÍÍ×××ÜÜÜÜÜÜØØØÊÊʾ¾¾¿¿¿ÍÍÍÜÜÜÊÊÊÊÊÊÐÐÐÂÂÂÀÀÀºººÑÑÑÎÎÎÍÍÍÐÐÐÒÒÒÔÔÔÐÐÐÌÌÌÌÌÌâââæææçççÝÝÝÕÕÕÝÝÝÙÙÙÔÔÔÛÛÛÎÎÎÀÀÀèèèàààçççØØØâââàààÕÕÕ¿¿¿ÙÙÙÜÜÜÔÔÔÍÍÍÂÂÂßßßÎÎÎÆÆÆÆÆÆÃÃÃÊÊʸ¸¸¿¿¿¸¸¸···¾¾¾ÃÃÃÃÃÃÃÃÃÅÅÅ©©©¯¯¯°°°ÃÃÃÌÌÌÃÃÃÊÊÊÇÇÇÇÇÇÇÇÇÆÆÆÅÅÅÆÆÆÊÊÊÑÑÑÕÕÕ¿¿¿¾¾¾¾¾¾ÀÀÀÀÀÀ¿¿¿ÂÂÂÆÆÆÉÉÉÃÃÃÇÇÇÌÌÌÇÇÇÇÇÇÇÇÇÀÀÀ¿¿¿ÂÂÂÆÆÆÊÊÊÌÌÌÉÉÉÅÅÅÀÀÀÅÅÅ¿¿¿»»»¾¾¾ÅÅÅÍÍÍÃÃð°°¸¸¸¬¬¬¯¯¯µµµ°°°¬¬¬°°°³³³¬¬¬ªªªªªª¬¬¬¯¯¯°°°¸¸¸···ººº¸¸¸¬¬¬ÃÃÃÇÇÇÐÐÐÝÝÝÝÝÝàààæææèèèäääÙÙÙÑÑÑÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÒÒÒÑÑÑÑÑÑÒÒÒÒÒÒÑÑÑÐÐÐÐÐÐÐÐÐÐÐÐÑÑÑÌÌÌÌÌÌÊÊÊÀÀÀ¾¾¾ÐÐÐääääääçççãããâââëëëäääàààííííííïïïíííçççààààààâââÛÛÛÒÒÒ¸¸¸±±±°°°¸¸¸¿¿¿¿¿¿¿¿¿ÃÃÃÆÆÆÇÇÇÌÌÌÇÇǼ¼¼»»»¼¼¼···³³³¯¯¯°°°······±±±¬¬¬ªªª¸¸¸···¿¿¿ÀÀÀ´´´©©©¤¤¤¢¢¢¤¤¤¨¨¨¬¬¬³³³ÀÀÀÎÎθ¸¸¼¼¼ÅÅž¾¾µµµ´´´³³³³³³µµµµµµºººÃÃÃÅÅÅÇÇÇÔÔÔÐÐп¿¿ÆÆÆÑÑÑßßßÌÌÌÅÅÅÀÀÀ¼¼¼¾¾¾ÕÕÕßßßÛÛÛÙÙÙÕÕÕ×××ÐÐÐÙÙÙÕÕÕÊÊÊÆÆÆÂÂÂÀÀÀÆÆÆÐÐÐÐÐÐÀÀÀÉÉÉÎÎÎÅÅÅÊÊÊÐÐÐÍÍÍÌÌÌÊÊÊÌÌÌÎÎÎÐÐÐÍÍÍÌÌÌÉÉÉÔÔÔÒÒÒ×××ÕÕÕÕÕÕãããâââçççßßßØØØÌÌÌëëëëëëäääÐÐÐÙÙÙâââÛÛÛÉÉÉßßßàààÔÔÔÉÉÉçççóóóÛÛÛÎÎÎÆÆƺººÃÃÿ¿¿ÌÌÌÀÀÀººº¿¿¿ÉÉÉÌÌÌÉÉÉÆÆÆÆÆÆÊÊÊÅÅÅÉÉÉÆÆÆÀÀÀÊÊÊÊÊÊÊÊÊÍÍÍÐÐÐÐÐÐÌÌÌÇÇÇÅÅÅÅÅÅÊÊÊÉÉÉÅÅÅÀÀÀÃÃÃÉÉÉÍÍÍÎÎÎÊÊÊÆÆÆÇÇÇÉÉÉÆÆÆÅÅÅÃÃü¼¼¿¿¿ÅÅÅÍÍÍÒÒÒÒÒÒÐÐÐÌÌÌÇÇÇÊÊÊÉÉÉÅÅÅÇÇÇÎÎÎÉÉɺºº¯¯¯···¯¯¯´´´±±±°°°³³³±±±°°°¯¯¯¬¬¬¬¬¬±±±³³³ººº······ººº¯¯¯ÅÅÅÍÍÍÙÙÙÜÜÜØØØÔÔÔÒÒÒÕÕÕØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØ×××ÔÔÔÑÑÑÐÐÐÔÔÔÒÒÒÑÑÑÐÐÐÐÐÐÑÑÑÒÒÒÒÒÒÎÎÎÉÉÉÆÆÆÀÀÀººº¿¿¿ÐÐÐàààèèèãããäääñññêêêàààîîîòòòñññïïïèèèããããããææææææãããÑÑÑ¿¿¿´´´ºººÀÀÀ¿¿¿¾¾¾ÀÀÀÆÆÆÍÍÍÎÎÎÀÀÀµµµ¾¾¾ÀÀÀµµµ¸¸¸±±±°°°µµµ»»»¸¸¸±±±¬¬¬¨¨¨¥¥¥°°°···¬¬¬¤¤¤¥¥¥¨¨¨©©©¨¨¨¨¨¨ªªª©©©¼¼¼ÍÍ;¾¾¸¸¸¾¾¾ÃÃþ¾¾···µµµµµµ³³³µµµ···ºººÀÀÀÃÃÃÊÊÊÕÕÕØØØÅÅÅÉÉÉÔÔÔäääÐÐÐÉÉÉÆÆƾ¾¾ºººÌÌÌØØØÝÝÝàààÙÙÙØØØÕÕÕÛÛÛÎÎλ»»µµµ»»»ÂÂÂÌÌÌÝÝÝÑÑÑÀÀÀÇÇÇÍÍÍÀÀÀÆÆÆÙÙÙÇÇÇÇÇÇÇÇÇÇÇÇÊÊÊÌÌÌÌÌÌÌÌÌÑÑÑÔÔÔÐÐÐÕÕÕÕÕÕÑÑÑÕÕÕÕÕÕäääÐÐÐØØØÐÐÐàààòòòæææÙÙÙÜÜÜäääÛÛÛÌÌÌÛÛÛÝÝÝÙÙÙÒÒÒçççëëëÜÜÜÝÝÝÕÕÕÃÃÃÎÎÎÕÕÕÕÕÕÊÊÊÀÀÀÀÀÀÃÃÃÅÅÅÃÃÃÃÃÃÀÀÀÊÊÊÊÊÊÉÉÉÃÃÿ¿¿ÇÇÇÇÇÇÅÅÅÊÊÊÐÐÐÒÒÒÐÐÐÌÌÌÇÇÇÆÆÆÒÒÒÒÒÒÌÌÌÃÃÃÅÅÅÍÍÍÎÎÎÌÌÌÐÐÐÊÊÊÅÅÅÂÂÂÀÀÀÀÀÀÀÀÀ¿¿¿ÉÉÉÌÌÌÐÐÐÑÑÑÐÐÐÐÐÐÑÑÑÑÑÑÍÍÍÐÐÐÌÌÌÍÍÍÑÑÑÅÅŸ¸¸¼¼¼¸¸¸±±±°°°´´´´´´±±±³³³´´´···µµµ±±±¯¯¯°°°³³³···µµµ±±±°°°¼¼¼¸¸¸ÌÌÌÑÑÑÙÙÙÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕ×××ÙÙÙÙÙÙÝÝÝÝÝÝÝÝÝÜÜÜÙÙÙ×××ÒÒÒÐÐÐÔÔÔÑÑÑÐÐÐÐÐÐÑÑÑÒÒÒÒÒÒÑÑÑÊÊÊÂÂÂÂÂÂÀÀÀ»»»···ÃÃÃãããêêêèèèêêêñññèèèãããóóóöööïïïïïïïïïíííêêêèèèçççäääÔÔÔ···¾¾¾Â¾¾¾¼¼¼ÂÂÂÃÃÃÍÍÍÌÌÌ¿¿¿···¼¼¼¾¾¾µµµººº´´´³³³µµµ»»»¼¼¼¸¸¸³³³¨¨¨ªªª¬¬¬¨¨¨¬¬¬µµµ···ªªª©©©¬¬¬µµµÀÀÀÆÆÆ»»»¼¼¼ÀÀÀÃÃþ¾¾¸¸¸µµµµµµ´´´µµµ¸¸¸»»»¿¿¿ÅÅÅÍÍÍÕÕÕÙÙÙÇÇÇÐÐÐÜÜÜëëëÕÕÕÎÎÎÊÊÊÅÅÅ¿¿¿ÊÊÊÑÑÑ×××ØØØÑÑÑÔÔÔÛÛÛÛÛÛÎÎξ¾¾ººº¸¸¸¿¿¿ÌÌÌãããÙÙÙÉÉÉÆÆÆÎÎλ»»×××ÅÅÅÅÅÅÅÅÅÆÆÆÇÇÇÉÉÉÌÌÌÎÎÎÍÍÍÍÍÍÎÎÎ×××ÙÙÙÕÕÕÙÙÙßßßÕÕÕ¾¾¾ÔÔÔÉÉÉÇÇÇããã××××××ÝÝÝàààÕÕÕÑÑÑÛÛÛØØØÛÛÛÜÜÜæææèèèâââæææÜÜÜÊÊÊÔÔÔÜÜÜÕÕÕÒÒÒÌÌÌ···´´´¸¸¸¿¿¿ÂÂÂÉÉÉÇÇÇÀÀÀ¼¼¼¾¾¾Â¿¿¿ÂÂÂÆÆÆÊÊÊÍÍÍÍÍÍÎÎÎÑÑÑÒÒÒÍÍÍÎÎÎÌÌÌÆÆÆÉÉÉÐÐÐÑÑÑÍÍÍÍÍÍÊÊÊÆÆÆÅÅÅÇÇÇÉÉÉÉÉÉÊÊÊÐÐÐÑÑÑÑÑÑÐÐÐÎÎÎÎÎÎÑÑÑÔÔÔÎÎÎÎÎÎÇÇÇÊÊÊÎÎÎÀÀÀ´´´ººººººµµµ³³³µµµ¸¸¸¸¸¸µµµ¸¸¸ººº¸¸¸···³³³°°°±±±···»»»¼¼¼´´´±±±ÉÉÉÊÊÊÕÕÕÒÒÒÑÑÑÎÎÎÒÒÒÙÙÙßßßàààßßßÜÜÜÛÛÛàààààààààßßßÜÜÜØØØÒÒÒÑÑÑÒÒÒÑÑÑÎÎÎÐÐÐÑÑÑÑÑÑÐÐÐÎÎÎÊÊÊÂÂÂÆÆÆÃÃÿ¿¿µµµ»»»ãããëëëòòòñññïïïçççêêêúúúöööñññòòòòòòòòòîîîçççãããâââ»»»´´´´´´¼¼¼ÀÀÀ¼¼¼¾¾¾ÅÅÅÂÂÂÆÆÆÇÇÇÅÅÅ¿¿¿ººº···¸¸¸´´´µµµ¸¸¸ººº»»»ººº´´´¯¯¯³³³¯¯¯¬¬¬©©©¯¯¯ÂÂÂÌÌ̬¬¬¨¨¨¥¥¥±±±ÂÂÂÃÃø¸¸¸¸¸ÀÀÀÅÅż¼¼¸¸¸´´´´´´´´´···ººº¼¼¼¿¿¿ÇÇÇÐÐÐÒÒÒÑÑÑÇÇÇÔÔÔßßßêêêÔÔÔÍÍÍÉÉÉÂÂÂÂÂÂÌÌÌÍÍÍÍÍÍÍÍÍÊÊÊÕÕÕÜÜÜÜÜÜÕÕÕÐÐÐÌÌÌ¿¿¿»»»ÅÅÅÑÑÑÙÙÙÑÑÑÃÃÃÑÑÑÌÌ̺ººØØØÅÅÅÅÅÅÆÆÆÆÆÆÇÇÇÊÊÊÍÍÍÎÎÎÔÔÔÐÐÐÑÑÑÑÑÑÎÎÎÐÐÐÙÙÙèèèÑÑÑ¿¿¿ÛÛÛ×××ÜÜÜöööêêêîîî××××××ÎÎÎßßßãããÕÕÕØØØßßßííííííæææãããØØØÒÒÒÜÜÜàààØØØÙÙÙÕÕÕÉÉɼ¼¼¸¸¸¼¼¼ÃÃÃÇÇÇÃÃÿ¿¿···¼¼¼ÊÊÊÎÎÎÎÎÎÇÇÇÉÉÉÊÊÊÌÌÌÊÊÊÌÌÌÐÐÐÑÑÑÑÑÑÒÒÒÒÒÒÑÑÑÒÒÒÔÔÔÒÒÒÐÐÐÆÆÆÌÌÌÍÍÍÑÑÑØØØØØØÔÔÔÕÕÕÒÒÒÒÒÒÒÒÒÒÒÒÐÐÐÎÎÎÎÎÎÐÐÐÐÐÐÑÑÑÒÒÒÐÐÐÉÉÉ»»»µµµ»»»»»»ºººµµµµµµ¼¼¼¼¼¼¸¸¸»»»ººº»»»ººº···´´´µµµººº¿¿¿ÆÆƾ¾¾¸¸¸×××ØØØÙÙÙÒÒÒÊÊÊÐÐÐÑÑÑÑÑÑÒÒÒÕÕÕÙÙÙÝÝÝßßßààààààßßßÝÝÝÙÙÙÕÕÕÒÒÒÐÐÐÑÑÑÎÎÎÎÎÎÐÐÐÑÑÑÐÐÐÌÌÌÇÇǾ¾¾¼¼¼Â»»»¼¼¼¸¸¸¸¸¸æææîîîøøøöööñññèèèïïïÿÿÿõõõõõõóóóòòòòòòíííæææââââââ³³³µµµ¼¼¼Â¿¿¿ÀÀÀÅÅÅÀÀÀÃÃÃÆÆÆÌÌÌÊÊÊ»»»µµµ¼¼¼ººº»»»»»»»»»¼¼¼ÂÂÂÃÃü¼¼»»»¸¸¸³³³ºººÍÍÍÎÎκºº©©©¨¨¨¢¢¢¥¥¥µµµÆÆÆÀÀÀ¯¯¯µµµÃÃÃÉÉɼ¼¼¸¸¸´´´´´´······»»»¿¿¿ÂÂÂÌÌÌÒÒÒÐÐÐÉÉÉÉÉÉØØØØØØÝÝÝÊÊÊÇÇÇÃÃþ¾¾ÃÃÃÐÐÐÎÎÎÌÌÌÉÉÉÇÇÇÙÙÙÙÙÙÝÝÝÜÜÜÜÜÜÛÛÛÌÌ̾¾¾¼¼¼ÂÂÂÒÒÒÙÙÙÃÃÃÎÎÎÐÐз··ÔÔÔÆÆÆÅÅÅÆÆÆÇÇÇÊÊÊÌÌÌÍÍÍÍÍÍÆÆÆÆÆÆÐÐÐÎÎÎÍÍÍÒÒÒØØØæææÎÎÎÂÂÂÍÍÍÉÉÉÝÝÝäääÒÒÒÎÎÎ×××ÕÕÕÇÇÇßßßßßßÔÔÔÝÝÝèèèæææææææææäääßßßàààãããÝÝÝÛÛÛÛÛÛØØØÒÒÒÐÐÐÐÐÐÐÐÐÍÍ͸¸¸´´´ººº¼¼¼ÉÉÉ×××ÔÔÔÒÒÒÆÆÆÉÉÉÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÍÍÍÒÒÒÑÑÑÒÒÒÔÔÔÑÑÑÌÌÌÉÉÉÉÉÉÉÉÉÐÐÐÑÑÑÕÕÕÝÝÝÜÜÜÕÕÕÕÕÕÕÕÕÔÔÔÒÒÒÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÔÔÔÔÔÔÕÕÕÎÎο¿¿···¼¼¼ÀÀÀººº»»»´´´´´´¼¼¼¾¾¾ººº»»»ººº»»»¼¼¼»»»¸¸¸¸¸¸¼¼¼ÂÂÂÅÅÅ¿¿¿»»»ÛÛÛØØØÔÔÔÑÑÑÍÍÍÎÎÎÐÐÐÒÒÒÕÕÕÙÙÙÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÛÛÛØØØÕÕÕÑÑÑÐÐÐÎÎÎÎÎÎÍÍÍÍÍÍÐÐÐÑÑÑÎÎÎÇÇÇÀÀÀººº¾¾¾Â´´´¼¼¼ÂÂÂÂÂÂñññòòòøøøøøøøøøñññòòòüüüòòòóóóññññññóóóñññêêêäääää人ºÀÀÀÅÅÅÅÅÅÅÅÅÅÅÅÃÃÃÂÂÂÀÀÀÆÆÆÊÊÊÑÑÑÑÑѺººÂÂÂÅÅÅÀÀÀ»»»ºººÂÂÂÐÐÐÕÕÕÒÒÒÐÐÐÍÍÍÊÊÊÅÅÅÂÂÂÉÉÉÃÃð°°¥¥¥¢¢¢¬¬¬¼¼¼Âººº°°°°°°ÅÅÅÊÊÊÀÀÀ¼¼¼ºººµµµµµµ¸¸¸···¼¼¼ÀÀÀÅÅÅÐÐÐÕÕÕÍÍÍÌÌÌÔÔÔßßßÒÒÒÎÎÎÀÀÀÆÆÆÅÅÅÇÇÇÐÐÐÛÛÛ×××ÑÑÑÉÉÉÂÂÂÒÒÒÕÕÕâââàààÙÙÙÛÛÛ×××ÆÆƸ¸¸ÀÀÀÇÇÇÝÝÝÉÉÉÆÆÆÌÌ̸¸¸ÐÐÐÆÆÆÅÅÅÅÅÅÇÇÇÌÌÌÍÍÍÌÌÌÊÊÊÉÉÉÌÌÌ×××ÑÑÑÐÐÐÔÔÔÌÌÌÎÎÎÑÑÑÎÎÎÃÃû»»ãããÙÙÙÒÒÒÒÒÒØØØÙÙÙÆÆÆÙÙÙØØØÙÙÙêêêñññëëëãããäääæææàààÝÝÝ×××ÌÌÌÑÑÑÕÕÕØØØ××××××ÙÙÙ×××ÑÑÑ´´´³³³ÅÅÅÍÍÍÒÒÒÐÐп¿¿¼¼¼ÅÅÅÇÇÇÌÌÌÍÍÍÍÍÍÌÌÌÌÌÌÍÍÍÑÑÑÐÐÐÒÒÒÕÕÕÒÒÒÊÊÊÉÉÉÎÎÎÑÑÑÕÕÕÑÑÑÑÑÑØØØÕÕÕÎÎÎÑÑÑÛÛÛÕÕÕÐÐÐÎÎÎÐÐÐÒÒÒÔÔÔÔÔÔÛÛÛÊÊʺºº³³³ºººÀÀÀ»»»¸¸¸»»»´´´³³³¼¼¼¾¾¾¸¸¸ººº¸¸¸¼¼¼¾¾¾¼¼¼ºººººº¿¿¿ÃÃû»»ººº···ØØØÑÑÑÌÌÌÐÐÐÒÒÒÊÊÊÌÌÌÎÎÎÒÒÒ×××ÙÙÙÙÙÙØØØÛÛÛÙÙÙ×××ÔÔÔÐÐÐÎÎÎÍÍÍÌÌÌÍÍÍÌÌÌÌÌÌÎÎÎÑÑÑÍÍÍÅÅż¼¼ßßßâââÜÜÜ¿¿¿ÂÂÂÅÅž¾¾èèèõõõööööööÿÿÿøøøòòòùùùñññíííëëëïïïøøøøøøïïïæææããã···¾¾¾¿¿¿¾¾¾ÀÀÀÇÇÇÇÇÇÀÀÀÀÀÀÊÊÊÎÎÎÒÒÒÔÔÔÇÇÇ¿¿¿ÆÆÆÆÆƼ¼¼¾¾¾ÉÉÉÒÒÒÎÎÎÃÃÃÆÆÆÃÃÃÇÇÇÌÌÌÌÌÌÑÑÑÒÒÒÊÊÊ´´´¦¦¦¥¥¥···Â¾¾¾···¸¸¸¬¬¬ÃÃÃÊÊÊÀÀÀ¾¾¾»»»¸¸¸¸¸¸ººº···¼¼¼ÂÂÂÇÇÇÒÒÒ×××ÌÌÌÕÕÕßßßçççÐÐÐÆÆƼ¼¼ÉÉÉÉÉÉ×××ÝÝÝçççààà×××ÉÉɺººÆÆÆÒÒÒäääàààÐÐÐÕÕÕÝÝÝÎÎθ¸¸¾¾¾ºººÜÜÜÍÍ;¾¾ÉÉɾ¾¾ÔÔÔÆÆÆÃÃÃÃÃÃÆÆÆÌÌÌÍÍÍÊÊÊÆÆÆÊÊÊÇÇÇÐÐÐÉÉÉÐÐÐÝÝÝ×××ØØØßßßçççÊÊÊ···ãããÎÎÎ×××âââÐÐÐÜÜÜÊÊÊÝÝÝÛÛÛãããñññëëëñññÜÜÜØØØÙÙÙ××××××ÒÒÒÌÌÌÂÂÂÎÎÎØØØ×××ÑÑÑÑÑÑÐÐÐÎÎδ´´´´´ÊÊÊÔÔÔÔÔÔÎÎξ¾¾ÀÀÀÌÌÌÌÌÌÌÌÌÊÊÊÇÇÇÇÇÇÉÉÉÌÌÌÐÐÐÊÊÊÑÑÑÕÕÕÌÌÌÉÉÉÒÒÒØØØÕÕÕÑÑÑÌÌÌÉÉÉÊÊÊÍÍÍÐÐÐÑÑÑÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÕÕÕØØØØØØÌÌÌ»»»···ººº¸¸¸»»»¼¼¼µµµ´´´´´´µµµ¸¸¸»»»¼¼¼¸¸¸µµµ»»»¼¼¼¾¾¾¿¿¿¿¿¿¿¿¿ÃÃÃÇÇǼ¼¼ºººÍÍÍãããÔÔÔÔÔÔÊÊÊÒÒÒÕÕÕÎÎÎÑÑÑØØØÙÙÙßßßãããÜÜÜÕÕÕÔÔÔÑÑÑÍÍÍÍÍÍÍÍÍÊÊÊÇÇÇÌÌÌÊÊÊÉÉÉÌÌÌÑÑÑÒÒÒÊÊʾ¾¾âââäääâââæææçççíííóóóãããóóóõõõîîîèèèñññóóóïïïïïïêêêïïïöööüüüÿÿÿùùùñññêêêäää¾¾¾ÅÅÅÃÃÃÃÃÃÐÐÐÆÆÆÅÅÅÆÆÆÌÌÌÌÌÌÊÊÊÐÐз··¼¼¼ÂÂÂÅÅÅÆÆÆ¿¿¿ÃÃÃÕÕÕÛÛÛÉÉɺºº»»»ÀÀÀÅÅÅÇÇÇÆÆÆÆÆÆÊÊÊÎÎγ³³¯¯¯´´´¾¾¾ÀÀÀººº±±±»»»ÇÇÇÉÉÉÅÅÅÂÂÂÂÂÂÀÀÀ¿¿¿¾¾¾ÂÂÂÉÉÉÔÔÔÜÜÜÒÒÒÅÅÅÔÔÔèèèÒÒÒÉÉÉÇÇÇÂÂÂØØØÝÝÝòòòêêêçççèèèàààÒÒÒÌÌÌÐÐÐÝÝÝÝÝÝÐÐÐÒÒÒÊÊÊÌÌÌØØصµµ¾¾¾¼¼¼ÍÍÍÑÑÑ¿¿¿ÍÍÍÆÆÆÔÔÔÍÍÍÊÊÊÇÇÇÇÇÇÊÊÊÊÊÊÉÉÉÆÆÆÉÉÉÎÎÎÎÎÎÐÐÐÌÌÌÒÒÒäääÝÝÝÒÒÒßßßÀÀÀ¼¼¼æææçççÐÐÐÕÕÕÎÎÎæææÇÇÇÛÛÛØØØíííñññãããÛÛÛØØØÕÕÕÔÔÔÒÒÒÑÑÑÍÍÍÊÊÊÉÉÉÃÃÃÆÆÆÆÆÆÅÅÅÔÔÔÐÐа°°°°°¿¿¿ÀÀÀÌÌÌÊÊʸ¸¸»»»ÀÀÀÇÇÇÍÍÍÎÎÎÅÅÅÉÉÉÌÌÌÅÅÅÐÐÐÎÎÎÌÌÌÍÍÍÊÊÊÀÀÀÅÅÅÒÒÒØØØÐÐÐÍÍÍÊÊÊÊÊÊÌÌÌÎÎÎÐÐÐÐÐÐÒÒÒÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÌÌ̺ºº´´´······¸¸¸»»»µµµ´´´´´´µµµ¸¸¸»»»»»»¸¸¸µµµ···ººº¼¼¼¼¼¼¾¾¾ÀÀÀ¼¼¼ÀÀÀÑÑÑàààÕÕÕÕÕÕÉÉÉÒÒÒÕÕÕÒÒÒÙÙÙßßßÛÛÛÛÛÛÜÜÜÕÕÕ×××ÔÔÔÌÌÌ¿¿¿¸¸¸¼¼¼ÆÆÆÍÍÍÉÉÉÊÊÊÇÇÇÉÉÉÉÉÉÇÇÇÃÃÃÅÅÅííííííæææçççêêêíííèèèÌÌÌàààíííîîîçççèèèêêêêêêíííëëëíííîîîòòòööööööóóóïïïààà»»»ÃÃÃÇÇÇÇÇÇÑÑÑÇÇÇÇÇÇÉÉÉÍÍÍÌÌÌÉÉÉÍÍ͵µµ»»»ÂÂÂÀÀÀÃÃÃÅÅÅÍÍÍÙÙÙÔÔÔÅÅž¾¾¼¼¼ÃÃÃÇÇÇÉÉÉÉÉÉÉÉÉÊÊÊÊÊÊÉÉÉÃÃÿ¿¿ÂÂÂÆÆÆÅÅźºº°°°»»»ÇÇÇÉÉÉÅÅÅÅÅÅÅÅÅÅÅÅ¿¿¿ÆÆÆÐÐÐÕÕÕÛÛÛÜÜÜÔÔÔÊÊÊÛÛÛâââÊÊÊÃÃÿ¿¿¿¿¿ÝÝÝèèèÑÑÑÒÒÒßßßïïïòòòçççààààààÝÝÝ×××ÇÇÇÎÎÎÍÍÍÑÑÑßßßÂÂÂÅÅÅÂÂÂÌÌÌÎÎÎÆÆÆÐÐÐÅÅÅÜÜÜÌÌÌÊÊÊÇÇÇÉÉÉÌÌÌÍÍÍÌÌÌÌÌÌÊÊÊÍÍÍÊÊÊÐÐÐÐÐÐÕÕÕâââØØØÇÇÇÊÊÊÉÉÉÑÑÑàààãããÜÜÜÙÙÙÍÍÍÛÛÛÉÉÉÜÜÜÔÔÔëëëîîîÝÝÝÛÛÛØØØÕÕÕÒÒÒÒÒÒÐÐÐÍÍÍÊÊÊÇÇÇÃÃÃÆÆÆÆÆÆÆÆÆÕÕÕÒÒÒ···»»»ÀÀÀ···ººº»»»±±±»»»ÃÃÃÃÃÃÂÂÂÇÇÇÃÃÃÅÅÅÇÇÇÂÂÂÌÌÌÎÎÎÉÉÉÇÇÇÅÅÅÅÅÅÍÍÍÕÕÕÕÕÕÍÍÍÌÌÌÊÊÊÊÊÊÍÍÍÎÎÎÎÎÎÎÎÎÐÐÐÑÑÑÒÒÒÔÔÔÔÔÔÒÒÒÑÑÑÐÐÐÌÌÌ»»»±±±³³³´´´···¸¸¸µµµµµµµµµ···¸¸¸»»»»»»ººº¸¸¸···¼¼¼ÀÀÀÂÂÂÆÆÆÌÌÌÌÌÌÇÇÇ¿¿¿ÌÌÌÛÛÛßßß××××××ÌÌÌÕÕÕ×××ØØØÝÝÝàààÛÛÛØØØØØØÔÔÔÒÒÒÉÉɾ¾¾¸¸¸´´´»»»ÇÇÇÀÀÀÃÃþ¾¾ÀÀÀ¿¿¿¿¿¿ÅÅÅÜÜÜíííîîîæææèèèîîîñññäää¼¼¼ÇÇÇãããïïïèèèçççèèèêêêïïïòòòíííèèèêêêïïïóóóõõõóóóããã¿¿¿ÂÂÂÇÇÇÉÉÉÎÎÎÉÉÉÍÍÍÉÉÉÍÍÍÍÍÍÍÍÍÌÌÌ´´´¸¸¸¾¾¾¼¼¼ÅÅÅÍÍÍØØØÛÛÛÌÌÌ¿¿¿ÂÂÂÆÆÆÍÍÍÐÐÐÍÍÍÊÊÊÌÌÌÇÇÇÂÂÂÆÆÆ¿¿¿ÂÂÂÆÆÆÃÃúºº±±±¬¬¬»»»ÇÇÇÊÊÊÇÇÇÉÉÉÌÌÌÌÌ̾¾¾ÊÊÊÑÑÑÔÔÔÒÒÒÐÐÐÎÎÎÍÍÍÜÜÜ×××ÆÆÆÉÉÉÀÀÀ¾¾¾ÜÜÜçççÔÔÔÕÕÕßßßëëëîîîæææàààâââããã×××ÆÆÆÍÍÍÎÎÎÐÐÐÝÝÝÊÊʾ¾¾ÇÇÇÑÑÑÊÊÊÌÌÌ×××ÊÊÊßßßÐÐÐÍÍÍÌÌÌÊÊÊÌÌÌÍÍÍÍÍÍÍÍÍÊÊÊÊÊÊÇÇÇÎÎÎÒÒÒ×××ÝÝÝÑÑÑÊÊÊÌÌÌÎÎÎÔÔÔÜÜÜÜÜÜ×××ÕÕÕÔÔÔÕÕÕÔÔÔãããÔÔÔòòòóóóàààÛÛÛØØØÕÕÕÒÒÒÑÑÑÎÎÎÌÌÌÉÉÉÆÆÆÂÂÂÅÅÅÆÆÆÇÇÇ×××ØØØÂÂÂÌÌÌÉÉÉ···³³³······ÀÀÀÇÇǺººÃÃÃÇÇÇÆÆÆÇÇÇÆÆÆÎÎÎÌÌÌÅÅÅÆÆÆÐÐÐÙÙÙÜÜÜ×××ÑÑÑÐÐÐÎÎÎÌÌÌÌÌÌÍÍÍÎÎÎÐÐÐÎÎÎÐÐÐÐÐÐÑÑÑÑÑÑÐÐÐÎÎÎÎÎÎÍÍÍÐÐÐÀÀÀµµµ´´´´´´´´´´´´´´´µµµµµµ···ººº»»»»»»»»»»»»ÂÂÂÇÇÇÊÊÊÉÉÉÊÊÊÎÎÎÉÉÉ¿¿¿ÃÃÃ×××âââÛÛÛØØØÙÙÙÐÐÐÛÛÛÙÙÙÙÙÙÛÛÛÛÛÛÙÙÙØØØ×××ÕÕÕÆÆÆ»»»¿¿¿ÑÑÑÕÕÕÃÃø¸¸»»»ÀÀÀµµµ»»»¸¸¸¸¸¸ÂÂÂæææèèèíííèèèêêêîîîòòòäää¾¾¾¿¿¿ÝÝÝïïïîîîîîîñññòòòöööùùùñññèèèçççíííòòòóóóòòòèèèÆÆÆÂÂÂÆÆÆÆÆÆÉÉÉÆÆÆÎÎÎÇÇÇÍÍÍÍÍÍÒÒÒÊÊÊ´´´µµµ¸¸¸¾¾¾ÌÌÌÕÕÕØØØ×××ÉÉɼ¼¼¾¾¾ÂÂÂÇÇÇÉÉÉÃÃÃÃÃÃÆÆÆÃÃü¼¼¸¸¸······»»»¿¿¿¿¿¿¸¸¸³³³»»»ÉÉÉÍÍÍÎÎÎÐÐÐÑÑÑÑÑÑÎÎÎ×××ÐÐÐÌÌÌÉÉÉÅÅÅÉÉÉÍÍÍâââÎÎÎÆÆÆÍÍÍ¿¿¿»»»ØØØààà×××ÙÙÙäääïïïòòòêêêãããàààÔÔÔÊÊÊÂÂÂÎÎÎÑÑÑÔÔÔäääààà´´´ÊÊÊÝÝÝÊÊÊÉÉÉÜÜÜÒÒÒ×××ÕÕÕÒÒÒÐÐÐÍÍÍÊÊÊÉÉÉÉÉÉÉÉÉÉÉÉÊÊÊÆÆÆÍÍÍÐÐÐÐÐÐ×××ÐÐÐÂÂÂÎÎÎÀÀÀ¸¸¸ÙÙÙãããÒÒÒßßßØØØÎÎÎÛÛÛãããÐÐÐóóóõõõàààÛÛÛØØØÔÔÔÒÒÒÐÐÐÎÎÎÊÊÊÇÇÇÆÆÆÂÂÂÅÅÅÇÇÇÉÉÉÕÕÕÙÙÙÍÍÍÑÑÑÎÎξ¾¾µµµ»»»¿¿¿ÂÂÂÅÅÅÀÀÀ±±±¿¿¿ÉÉÉÅÅÅÆÆÆÆÆÆÍÍÍÃÃÃÂÂÂÌÌÌÜÜÜãããÛÛÛÔÔÔ×××ØØØÔÔÔÎÎÎÌÌÌÍÍÍÎÎÎÐÐÐÐÐÐÑÑÑÐÐÐÎÎÎÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÒÒÒÇÇǼ¼¼¸¸¸···³³³±±±´´´´´´µµµ···ººº»»»¼¼¼¾¾¾¿¿¿¾¾¾ÃÃÃÇÇÇÉÉÉÌÌÌÎÎÎÉÉÉÀÀÀÅÅÅ×××âââÕÕÕÕÕÕ×××ÑÑÑÛÛÛÜÜÜÛÛÛØØØÙÙÙÜÜÜÙÙÙÑÑÑÍÍ;¾¾ÀÀÀÎÎÎâââæææØØØÇÇÇ¿¿¿³³³´´´¾¾¾¸¸¸»»»ÂÂÂäääêêêñññïïïîîîêêêëëëæææÇÇÇÊÊÊâââîîîîîîóóóøøøóóóòòòöööïïïêêêëëëïïïóóóñññíííßßßÅÅÅÂÂÂÇÇÇÉÉÉÇÇÇÅÅÅÌÌÌÍÍÍÎÎÎÌÌÌÐÐа°°µµµ»»»ÂÂÂÔÔÔØØØÐÐÐÎÎÎÉÉɾ¾¾···µµµ¸¸¸¸¸¸µµµ···¼¼¼¾¾¾ººº¼¼¼»»»»»»¼¼¼¾¾¾»»»···³³³°°°¼¼¼ÉÉÉÎÎÎÒÒÒ×××ÕÕÕÒÒÒÔÔÔÙÙÙÊÊÊÍÍÍ×××ÕÕÕÝÝÝâââæææÌÌÌÂÂÂÆÆƸ¸¸¼¼¼ÛÛÛãããçççææææææêêêêêêèèèèèèëëëÍÍÍÉÉÉÉÉÉÔÔÔÒÒÒÑÑÑÝÝÝããã¾¾¾ÊÊÊãããÍÍÍÀÀÀÑÑÑÐÐÐÐÐÐÔÔÔÒÒÒÐÐÐÌÌÌÉÉÉÇÇÇÆÆÆÆÆÆÅÅÅÌÌÌÆÆÆÊÊÊÊÊÊÆÆÆÐÐÐÑÑÑ¿¿¿ÌÌ̾¾¾¬¬¬ÌÌÌâââÒÒÒÙÙÙÑÑÑÇÇÇØØØÙÙÙÊÊÊëëëíííÝÝÝÛÛÛØØØÕÕÕÒÒÒÐÐÐÍÍÍÊÊÊÇÇÇÆÆÆÃÃÃÅÅÅÇÇÇÊÊÊÒÒÒØØØÕÕÕÐÐÐÍÍÍÀÀÀ´´´ºººÀÀÀ¾¾¾¼¼¼¾¾¾»»»ÅÅÅÂÂÂÂÂÂÂÂÂÇÇÇ»»»ÇÇÇÔÔÔÛÛÛ×××ÌÌÌÎÎÎÝÝÝÛÛÛ×××ÐÐÐÍÍÍÍÍÍÎÎÎÑÑÑÑÑÑÑÑÑÐÐÐÍÍÍÊÊÊÉÉÉÉÉÉÉÉÉÉÉÉÐÐÐÌÌÌÅÅž¾¾ººº±±±¯¯¯µµµ±±±´´´···ººº»»»¾¾¾ÀÀÀÃÃÃÉÉÉÊÊÊÐÐÐÔÔÔÕÕÕÒÒÒÍÍÍÉÉÉÃÃÃÎÎÎßßßÔÔÔÕÕÕÔÔÔÒÒÒØØØÛÛÛÝÝÝÙÙÙÙÙÙÜÜÜÕÕÕÇÇÇÂÂÂÂÂÂØØØæææãããßßßâââÝÝÝÑÑѳ³³······ÌÌ̺ºº»»»¾¾¾ØØØæææîîîïïïñññêêêèèèîîîßßßÜÜÜæææçççêêêóóóóóóëëëèèèíííêêêêêêîîîñññïïïèèèãããÉÉÉ¿¿¿ÀÀÀÉÉÉÍÍÍÊÊÊÆÆÆÇÇÇÑÑÑÑÑÑÉÉÉÍÍ͸¸¸···¿¿¿ÂÂÂ×××ØØØÉÉÉÆÆÆÇÇÇ¿¿¿···ÂÂÂÀÀÀ¿¿¿»»»ººº¸¸¸¸¸¸ººº¼¼¼»»»ººººººººº¸¸¸µµµ´´´µµµ¾¾¾ÅÅÅÊÊÊÑÑÑØØØ×××ÑÑÑÍÍÍÕÕÕÅÅÅÒÒÒæææãããæææäääØØØÇÇÇÅÅÅÆÆƾ¾¾ÇÇÇÜÜÜÝÝÝÝÝÝàààæææêêêçççÝÝÝÒÒÒÍÍÍÑÑÑÑÑÑÔÔÔ×××ÑÑÑÊÊÊÎÎÎÔÔÔ×××ÇÇÇÛÛÛÍÍÍÂÂÂÃÃÃÆÆÆÎÎÎÉÉÉÊÊÊÊÊÊÊÊÊÇÇÇÆÆÆÆÆÆÆÆÆÂÂÂÊÊÊÅÅÅÇÇÇÆÆÆ¿¿¿ÇÇÇÎÎÎÉÉÉÂÂÂÇÇǺºº¿¿¿ÙÙÙÔÔÔÌÌÌÍÍÍÍÍÍÙÙÙÕÕÕÒÒÒëëëèèèàààÜÜÜÙÙÙÕÕÕÒÒÒÑÑÑÎÎÎÊÊÊÇÇÇÇÇÇÅÅÅÆÆÆÉÉÉÊÊÊÎÎÎÔÔÔ×××ÒÒÒÒÒÒÇÇÇ´´´¸¸¸ÅÅÅ¿¿¿ÀÀÀÃÃ÷··¿¿¿ÃÃÃÅÅÅÆÆÆÂÂÂÇÇǼ¼¼ÑÑÑØØØÑÑÑÌÌÌÊÊÊÍÍÍ×××ØØØÔÔÔÐÐÐÍÍÍÎÎÎÐÐÐÐÐÐÐÐÐÐÐÐÎÎÎÍÍÍÌÌÌÉÉÉÇÇÇÆÆÆÆÆÆÇÇÇÌÌÌÇÇǼ¼¼±±±···°°°³³³···ººº»»»¿¿¿ÃÃÃÇÇÇäääââââââäääÝÝÝÎÎÎÆÆÆÇÇÇÆÆÆÉÉÉâââÜÜÜÝÝÝÙÙÙÛÛÛÙÙÙÙÙÙßßßÛÛÛÕÕÕÒÒÒÌÌÌÅÅÅÇÇÇÒÒÒçççïïïäääÜÜÜâââãããÝÝÝÒÒÒÕÕÕÕÕÕßßß´´´µµµ¼¼¼ÔÔÔæææëëëîîîóóóíííëëëõõõïïïêêêèèèâââæææñññîîîççççççæææçççëëëîîîíííäääØØØÎÎο¿¿¾¾¾¾¾¾ÅÅÅÉÉÉÉÉÉÆÆÆÅÅÅÌÌÌÍÍÍÉÉÉÔÔÔººº°°°µµµ»»»¾¾¾ÑÑÑÕÕÕÉÉÉÂÂÂÀÀÀ¾¾¾¾¾¾ÑÑÑÍÍÍÊÊÊÉÉɸ¸¸···¼¼¼·········µµµµµµµµµ¸¸¸ººº¼¼¼¼¼¼¼¼¼ÀÀÀÊÊÊÔÔÔÔÔÔÎÎÎÕÕÕÝÝÝÇÇÇÔÔÔãããÔÔÔÐÐÐÊÊÊÉÉÉÇÇÇÌÌÌÇÇÇÅÅÅÒÒÒÛÛÛÑÑÑÑÑÑÔÔÔ×××ØØØ×××ÔÔÔÐÐÐÍÍÍÉÉÉÊÊÊÎÎÎÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒàààÃÃÃÍÍÍÊÊÊÑÑÑÉÉÉ¿¿¿ÊÊÊÂÂÂÅÅÅÇÇÇÇÇÇÅÅÅÂÂÂÂÂÂÂÂÂÀÀÀÇÇÇ¿¿¿ÃÃÃÇÇÇ¿¿¿ÂÂÂÆÆÆÎÎκººÂ¾¾¾ÇÇÇàààØØØÔÔÔÉÉÉØØØÜÜÜ×××âââïïïçççãããÝÝÝÛÛÛ×××ÔÔÔÑÑÑÎÎÎÊÊÊÇÇÇÉÉÉÇÇÇÇÇÇÊÊÊÊÊÊÉÉÉÍÍÍÕÕÕÒÒÒÕÕÕÍÍÍ´´´µµµÅÅÅÂÂÂÅÅÅÃÃÿ¿¿ÀÀÀ¼¼¼ÂÂÂÃÃû»»ÂÂÂÅÅÅÛÛÛÙÙÙÊÊÊÌÌÌÔÔÔÐÐÐÊÊÊÒÒÒÑÑÑÎÎÎÎÎÎÐÐÐÐÐÐÐÐÐÎÎÎÎÎÎÎÎÎÎÎÎÍÍÍÊÊÊÇÇÇÅÅÅÃÃÃÀÀÀÉÉÉÉÉÉÅÅž¾¾°°°¬¬¬¸¸¸¯¯¯±±±µµµººº¼¼¼ÀÀÀÆÆÆÊÊÊßßßÛÛÛÝÝÝæææàààÑÑÑÌÌÌÒÒÒÌÌÌÊÊÊèèèèèèèèèâââãããÝÝÝØØØßßßÙÙÙÍÍÍÇÇÇÃÃÃÇÇÇ×××ãããçççëëëíííçççàààÜÜÜÛÛÛßßßààààààççç³³³¾¾¾ÕÕÕóóóñññññññññøøøïïïèèèòòòîîîïïïçççßßßäääïïïíííèèèîîîæææèèèííííííçççØØØÇÇǼ¼¼ÂÂÂÃÃü¼¼¼¼¼¿¿¿ÃÃÃÆÆÆÃÃÃÂÂÂÉÉÉÍÍÍÝÝÝ´´´±±±³³³¸¸¸ÌÌÌÒÒÒÌÌ̺ºº»»»ÆÆÆÉÉÉÃÃÃÅÅÅÊÊÊÅÅÅ······Â¾¾¾¼¼¼»»»¸¸¸µµµ···ººº»»»ÀÀÀ¼¼¼······ÃÃÃÐÐÐÒÒÒÍÍÍÒÒÒÜÜÜÆÆÆÒÒÒâââÐÐÐÍÍÍÉÉÉÌÌÌÐÐÐÐÐÐÀÀÀÀÀÀÕÕÕÙÙÙÎÎÎÑÑÑÔÔÔ×××ØØØ×××ÕÕÕÒÒÒÐÐÐÍÍÍÌÌÌÌÌÌÍÍÍÔÔÔÕÕÕÎÎÎÊÊÊ××׿¿¿ÆÆÆÆÆÆàààØØØÂÂÂÅÅÅÂÂÂÅÅÅÇÇÇÆÆƾ¾¾»»»»»»ÀÀÀÅÅźººÂÂÂÌÌ̾¾¾¿¿¿ãããÉÉɺºº···ÙÙÙäääÉÉÉØØØ¿¿¿ÛÛÛÙÙÙÔÔÔçççíííßßßàààßßßÜÜÜØØØÔÔÔÒÒÒÎÎÎÊÊÊÇÇÇÉÉÉÉÉÉÉÉÉÌÌÌÊÊÊÅÅÅÉÉÉÒÒÒÉÉÉÎÎÎÌÌ̱±±±±±ÀÀÀ»»»¾¾¾ºººººº···µµµ¸¸¸³³³
\ No newline at end of file diff --git a/libs/ode-0.16.1/include/Makefile.am b/libs/ode-0.16.1/include/Makefile.am new file mode 100644 index 0000000..0a0830e --- /dev/null +++ b/libs/ode-0.16.1/include/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = ode drawstuff diff --git a/libs/ode-0.16.1/include/Makefile.in b/libs/ode-0.16.1/include/Makefile.in new file mode 100644 index 0000000..3a7f2b2 --- /dev/null +++ b/libs/ode-0.16.1/include/Makefile.in @@ -0,0 +1,640 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = include +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ode/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_CFLAGS = @CCD_CFLAGS@ +CCD_LIBS = @CCD_LIBS@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSTDCXX = @LIBSTDCXX@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ODE_PRECISION = @ODE_PRECISION@ +ODE_VERSION = @ODE_VERSION@ +ODE_VERSION_INFO = @ODE_VERSION_INFO@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = ode drawstuff +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign include/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/include/drawstuff/Makefile.am b/libs/ode-0.16.1/include/drawstuff/Makefile.am new file mode 100644 index 0000000..14a9fb1 --- /dev/null +++ b/libs/ode-0.16.1/include/drawstuff/Makefile.am @@ -0,0 +1,2 @@ +noinst_HEADERS = drawstuff.h version.h + diff --git a/libs/ode-0.16.1/include/drawstuff/Makefile.in b/libs/ode-0.16.1/include/drawstuff/Makefile.in new file mode 100644 index 0000000..3bc421d --- /dev/null +++ b/libs/ode-0.16.1/include/drawstuff/Makefile.in @@ -0,0 +1,528 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = include/drawstuff +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ode/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +HEADERS = $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_CFLAGS = @CCD_CFLAGS@ +CCD_LIBS = @CCD_LIBS@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSTDCXX = @LIBSTDCXX@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ODE_PRECISION = @ODE_PRECISION@ +ODE_VERSION = @ODE_VERSION@ +ODE_VERSION_INFO = @ODE_VERSION_INFO@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_HEADERS = drawstuff.h version.h +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/drawstuff/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign include/drawstuff/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(HEADERS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool cscopelist-am ctags ctags-am distclean \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/include/drawstuff/drawstuff.h b/libs/ode-0.16.1/include/drawstuff/drawstuff.h new file mode 100644 index 0000000..9a3ac20 --- /dev/null +++ b/libs/ode-0.16.1/include/drawstuff/drawstuff.h @@ -0,0 +1,325 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/** @defgroup drawstuff DrawStuff + +DrawStuff is a library for rendering simple 3D objects in a virtual +environment, for the purposes of demonstrating the features of ODE. +It is provided for demonstration purposes and is not intended for +production use. + +@section Notes + +In the virtual world, the z axis is "up" and z=0 is the floor. + +The user is able to click+drag in the main window to move the camera: + * left button - pan and tilt. + * right button - forward and sideways. + * left + right button (or middle button) - sideways and up. +*/ + + +#ifndef __DRAWSTUFF_H__ +#define __DRAWSTUFF_H__ + +/* Define a DLL export symbol for those platforms that need it */ +#if defined(ODE_PLATFORM_WINDOWS) + #if defined(DS_DLL) + #define DS_API __declspec(dllexport) + #elif !defined(DS_LIB) + #define DS_DLL_API __declspec(dllimport) + #endif +#endif + +#if !defined(DS_API) + #define DS_API +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +#include <drawstuff/version.h> + + +/* texture numbers */ + enum DS_TEXTURE_NUMBER + { + DS_NONE = 0, /* uses the current color instead of a texture */ + DS_WOOD, + DS_CHECKERED, + DS_GROUND, + DS_SKY + }; + +/* draw modes */ + +#define DS_POLYFILL 0 +#define DS_WIREFRAME 1 + +/** + * @struct dsFunctions + * @brief Set of functions to be used as callbacks by the simulation loop. + * @ingroup drawstuff + */ +typedef struct dsFunctions { + int version; /* put DS_VERSION here */ + /* version 1 data */ + void (*start)(); /* called before sim loop starts */ + void (*step) (int pause); /* called before every frame */ + void (*command) (int cmd); /* called if a command key is pressed */ + void (*stop)(); /* called after sim loop exits */ + /* version 2 data */ + const char *path_to_textures; /* if nonzero, path to texture files */ +} dsFunctions; + + +/** + * @brief Does the complete simulation. + * @ingroup drawstuff + * This function starts running the simulation, and only exits when the simulation is done. + * Function pointers should be provided for the callbacks. + * @param argv supports flags like '-notex' '-noshadow' '-pause' + * @param fn Callback functions. + */ +DS_API void dsSimulationLoop (int argc, char **argv, + int window_width, int window_height, + struct dsFunctions *fn); + +/** + * @brief exit with error message. + * @ingroup drawstuff + * This function displays an error message then exit. + * @param msg format strin, like printf, without the newline character. + */ +DS_API void dsError (const char *msg, ...); + +/** + * @brief exit with error message and core dump. + * @ingroup drawstuff + * this functions tries to dump core or start the debugger. + * @param msg format strin, like printf, without the newline character. + */ +DS_API void dsDebug (const char *msg, ...); + +/** + * @brief print log message + * @ingroup drawstuff + * @param msg format string, like printf, without the \n. + */ +DS_API void dsPrint (const char *msg, ...); + +/** + * @brief Sets the viewpoint + * @ingroup drawstuff + * @param xyz camera position. + * @param hpr contains heading, pitch and roll numbers in degrees. heading=0 + * points along the x axis, pitch=0 is looking towards the horizon, and + * roll 0 is "unrotated". + */ +DS_API void dsSetViewpoint (float xyz[3], float hpr[3]); + + +/** + * @brief Gets the viewpoint + * @ingroup drawstuff + * @param xyz position + * @param hpr heading,pitch,roll. + */ +DS_API void dsGetViewpoint (float xyz[3], float hpr[3]); + +/** + * @brief Stop the simulation loop. + * @ingroup drawstuff + * Calling this from within dsSimulationLoop() + * will cause it to exit and return to the caller. it is the same as if the + * user used the exit command. using this outside the loop will have no + * effect. + */ +DS_API void dsStop(); + +/** + * @brief Get the elapsed time (on wall-clock) + * @ingroup drawstuff + * It returns the nr of seconds since the last call to this function. + */ +DS_API double dsElapsedTime(); + +/** + * @brief Toggle the rendering of textures. + * @ingroup drawstuff + * It changes the way objects are drawn. these changes will apply to all further + * dsDrawXXX() functions. + * @param the texture number must be a DS_xxx texture constant. + * The current texture is colored according to the current color. + * At the start of each frame, the texture is reset to none and the color is + * reset to white. + */ +DS_API void dsSetTexture (int texture_number); + +/** + * @brief Set the color with which geometry is drawn. + * @ingroup drawstuff + * @param red Red component from 0 to 1 + * @param green Green component from 0 to 1 + * @param blue Blue component from 0 to 1 + */ +DS_API void dsSetColor (float red, float green, float blue); + +/** + * @brief Set the color and transparency with which geometry is drawn. + * @ingroup drawstuff + * @param alpha Note that alpha transparency is a misnomer: it is alpha opacity. + * 1.0 means fully opaque, and 0.0 means fully transparent. + */ +DS_API void dsSetColorAlpha (float red, float green, float blue, float alpha); + +/** + * @brief Draw a box. + * @ingroup drawstuff + * @param pos is the x,y,z of the center of the object. + * @param R is a 3x3 rotation matrix for the object, stored by row like this: + * [ R11 R12 R13 0 ] + * [ R21 R22 R23 0 ] + * [ R31 R32 R33 0 ] + * @param sides[] is an array of x,y,z side lengths. + */ +DS_API void dsDrawBox (const float pos[3], const float R[12], const float sides[3]); + +/** + * @brief Draw a sphere. + * @ingroup drawstuff + * @param pos Position of center. + * @param R orientation. + * @param radius + */ +DS_API void dsDrawSphere (const float pos[3], const float R[12], float radius); + +/** + * @brief Draw a triangle. + * @ingroup drawstuff + * @param pos Position of center + * @param R orientation + * @param v0 first vertex + * @param v1 second + * @param v2 third vertex + * @param solid set to 0 for wireframe + */ +DS_API void dsDrawTriangle (const float pos[3], const float R[12], + const float *v0, const float *v1, const float *v2, int solid); + +/** + * @brief Draw triangles. + * @ingroup drawstuff + * @param pos Position of center + * @param R orientation + * @param v list of vertices (x0, y0, z0, x1, y1, z1, ...) + * @param n number of vertices + * @param solid set to 0 for wireframe + */ +DS_API void dsDrawTriangles (const float pos[3], const float R[12], + const float *v, const int n, int solid); + +/** + * @brief Draw a z-aligned cylinder + * @ingroup drawstuff + */ +DS_API void dsDrawCylinder (const float pos[3], const float R[12], + float length, float radius); + +/** + * @brief Draw a z-aligned capsule + * @ingroup drawstuff + */ +DS_API void dsDrawCapsule (const float pos[3], const float R[12], + float length, float radius); + +/** + * @brief Draw a line. + * @ingroup drawstuff + */ +DS_API void dsDrawLine (const float pos1[3], const float pos2[3]); + +/** + * @brief Draw a convex shape. + * @ingroup drawstuff + */ +DS_API void dsDrawConvex(const float pos[3], const float R[12], + const float *_planes, + unsigned int _planecount, + const float *_points, + unsigned int _pointcount, + const unsigned int *_polygons); + + /* these drawing functions are identical to the ones above, except they take + * double arrays for `pos' and `R'. + */ +DS_API void dsDrawBoxD (const double pos[3], const double R[12], + const double sides[3]); +DS_API void dsDrawSphereD (const double pos[3], const double R[12], + const float radius); +DS_API void dsDrawTriangleD (const double pos[3], const double R[12], + const double *v0, const double *v1, const double *v2, int solid); +DS_API void dsDrawTrianglesD (const double pos[3], const double R[12], + const double *v, const int n, int solid); +DS_API void dsDrawCylinderD (const double pos[3], const double R[12], + float length, float radius); +DS_API void dsDrawCapsuleD (const double pos[3], const double R[12], + float length, float radius); +DS_API void dsDrawLineD (const double pos1[3], const double pos2[3]); +DS_API void dsDrawConvexD(const double pos[3], const double R[12], + const double *_planes, + unsigned int _planecount, + const double *_points, + unsigned int _pointcount, + const unsigned int *_polygons); + +/** + * @brief Set the quality with which curved objects are rendered. + * @ingroup drawstuff + * Higher numbers are higher quality, but slower to draw. + * This must be set before the first objects are drawn to be effective. + * Default sphere quality is 1, default capsule quality is 3. + */ +DS_API void dsSetSphereQuality (int n); /* default = 1 */ +DS_API void dsSetCapsuleQuality (int n); /* default = 3 */ + +/** + * @brief Set Drawmode 0=Polygon Fill,1=Wireframe). + * Use the DS_POLYFILL and DS_WIREFRAME macros. + * @ingroup drawstuff + */ +DS_API void dsSetDrawMode(int mode); + +/* Backwards compatible API */ +#define dsDrawCappedCylinder dsDrawCapsule +#define dsDrawCappedCylinderD dsDrawCapsuleD +#define dsSetCappedCylinderQuality dsSetCapsuleQuality + +/* closing bracket for extern "C" */ +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/libs/ode-0.16.1/include/drawstuff/version.h b/libs/ode-0.16.1/include/drawstuff/version.h new file mode 100644 index 0000000..71d95f4 --- /dev/null +++ b/libs/ode-0.16.1/include/drawstuff/version.h @@ -0,0 +1,29 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __VERSION_H +#define __VERSION_H + +/* high byte is major version, low byte is minor version */ +#define DS_VERSION 0x0002 + +#endif diff --git a/libs/ode-0.16.1/include/ode/Makefile.am b/libs/ode-0.16.1/include/ode/Makefile.am new file mode 100644 index 0000000..ad06509 --- /dev/null +++ b/libs/ode-0.16.1/include/ode/Makefile.am @@ -0,0 +1,34 @@ +libode_la_includedir = $(includedir)/ode +libode_la_include_HEADERS = \ + collision.h \ + collision_space.h \ + collision_trimesh.h \ + common.h \ + compatibility.h \ + contact.h \ + cooperative.h \ + error.h \ + export-dif.h \ + mass.h \ + matrix.h matrix_coop.h \ + memory.h \ + misc.h \ + objects.h \ + ode.h \ + odeconfig.h \ + odecpp.h \ + odecpp_collision.h \ + odeinit.h \ + odemath.h \ + odemath_legacy.h \ + rotation.h \ + threading.h \ + threading_impl.h \ + timer.h + + +EXTRA_DIST = README precision.h.in version.h.in + +dist_libode_la_include_HEADERS = precision.h version.h + + diff --git a/libs/ode-0.16.1/include/ode/Makefile.in b/libs/ode-0.16.1/include/ode/Makefile.in new file mode 100644 index 0000000..1dac65e --- /dev/null +++ b/libs/ode-0.16.1/include/ode/Makefile.in @@ -0,0 +1,642 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = include/ode +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(dist_libode_la_include_HEADERS) \ + $(libode_la_include_HEADERS) $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ode/src/config.h +CONFIG_CLEAN_FILES = version.h precision.h +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libode_la_includedir)" \ + "$(DESTDIR)$(libode_la_includedir)" +HEADERS = $(dist_libode_la_include_HEADERS) \ + $(libode_la_include_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/precision.h.in \ + $(srcdir)/version.h.in README +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_CFLAGS = @CCD_CFLAGS@ +CCD_LIBS = @CCD_LIBS@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSTDCXX = @LIBSTDCXX@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ODE_PRECISION = @ODE_PRECISION@ +ODE_VERSION = @ODE_VERSION@ +ODE_VERSION_INFO = @ODE_VERSION_INFO@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +libode_la_includedir = $(includedir)/ode +libode_la_include_HEADERS = \ + collision.h \ + collision_space.h \ + collision_trimesh.h \ + common.h \ + compatibility.h \ + contact.h \ + cooperative.h \ + error.h \ + export-dif.h \ + mass.h \ + matrix.h matrix_coop.h \ + memory.h \ + misc.h \ + objects.h \ + ode.h \ + odeconfig.h \ + odecpp.h \ + odecpp_collision.h \ + odeinit.h \ + odemath.h \ + odemath_legacy.h \ + rotation.h \ + threading.h \ + threading_impl.h \ + timer.h + +EXTRA_DIST = README precision.h.in version.h.in +dist_libode_la_include_HEADERS = precision.h version.h +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/ode/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign include/ode/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +version.h: $(top_builddir)/config.status $(srcdir)/version.h.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +precision.h: $(top_builddir)/config.status $(srcdir)/precision.h.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-dist_libode_la_includeHEADERS: $(dist_libode_la_include_HEADERS) + @$(NORMAL_INSTALL) + @list='$(dist_libode_la_include_HEADERS)'; test -n "$(libode_la_includedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(libode_la_includedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libode_la_includedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libode_la_includedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(libode_la_includedir)" || exit $$?; \ + done + +uninstall-dist_libode_la_includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(dist_libode_la_include_HEADERS)'; test -n "$(libode_la_includedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(libode_la_includedir)'; $(am__uninstall_files_from_dir) +install-libode_la_includeHEADERS: $(libode_la_include_HEADERS) + @$(NORMAL_INSTALL) + @list='$(libode_la_include_HEADERS)'; test -n "$(libode_la_includedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(libode_la_includedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libode_la_includedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libode_la_includedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(libode_la_includedir)" || exit $$?; \ + done + +uninstall-libode_la_includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(libode_la_include_HEADERS)'; test -n "$(libode_la_includedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(libode_la_includedir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libode_la_includedir)" "$(DESTDIR)$(libode_la_includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-dist_libode_la_includeHEADERS \ + install-libode_la_includeHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-dist_libode_la_includeHEADERS \ + uninstall-libode_la_includeHEADERS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool cscopelist-am ctags ctags-am distclean \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am \ + install-dist_libode_la_includeHEADERS install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am \ + install-libode_la_includeHEADERS install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-dist_libode_la_includeHEADERS \ + uninstall-libode_la_includeHEADERS + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/include/ode/README b/libs/ode-0.16.1/include/ode/README new file mode 100644 index 0000000..9d7e99a --- /dev/null +++ b/libs/ode-0.16.1/include/ode/README @@ -0,0 +1,18 @@ + +this is the public C interface to the ODE library. + +all these files should be includable from C, i.e. they should not use any +C++ features. everything should be protected with + + #ifdef __cplusplus + extern "C" { + #endif + + ... + + #ifdef __cplusplus + } + #endif + +the only exceptions are the odecpp.h and odecpp_collisioh.h files, which define a C++ wrapper for +the C interface. remember to keep this in sync! diff --git a/libs/ode-0.16.1/include/ode/collision.h b/libs/ode-0.16.1/include/ode/collision.h new file mode 100644 index 0000000..fef6e7b --- /dev/null +++ b/libs/ode-0.16.1/include/ode/collision.h @@ -0,0 +1,1526 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_COLLISION_H_ +#define _ODE_COLLISION_H_ + +#include <ode/common.h> +#include <ode/collision_space.h> +#include <ode/contact.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup collide Collision Detection + * + * ODE has two main components: a dynamics simulation engine and a collision + * detection engine. The collision engine is given information about the + * shape of each body. At each time step it figures out which bodies touch + * each other and passes the resulting contact point information to the user. + * The user in turn creates contact joints between bodies. + * + * Using ODE's collision detection is optional - an alternative collision + * detection system can be used as long as it can supply the right kinds of + * contact information. + */ + + +/* ************************************************************************ */ +/* general functions */ + +/** + * @brief Destroy a geom, removing it from any space. + * + * Destroy a geom, removing it from any space it is in first. This one + * function destroys a geom of any type, but to create a geom you must call + * a creation function for that type. + * + * When a space is destroyed, if its cleanup mode is 1 (the default) then all + * the geoms in that space are automatically destroyed as well. + * + * @param geom the geom to be destroyed. + * @ingroup collide + */ +ODE_API void dGeomDestroy (dGeomID geom); + + +/** + * @brief Set the user-defined data pointer stored in the geom. + * + * @param geom the geom to hold the data + * @param data the data pointer to be stored + * @ingroup collide + */ +ODE_API void dGeomSetData (dGeomID geom, void* data); + + +/** + * @brief Get the user-defined data pointer stored in the geom. + * + * @param geom the geom containing the data + * @ingroup collide + */ +ODE_API void *dGeomGetData (dGeomID geom); + + +/** + * @brief Set the body associated with a placeable geom. + * + * Setting a body on a geom automatically combines the position vector and + * rotation matrix of the body and geom, so that setting the position or + * orientation of one will set the value for both objects. Setting a body + * ID of zero gives the geom its own position and rotation, independent + * from any body. If the geom was previously connected to a body then its + * new independent position/rotation is set to the current position/rotation + * of the body. + * + * Calling these functions on a non-placeable geom results in a runtime + * error in the debug build of ODE. + * + * @param geom the geom to connect + * @param body the body to attach to the geom + * @ingroup collide + */ +ODE_API void dGeomSetBody (dGeomID geom, dBodyID body); + + +/** + * @brief Get the body associated with a placeable geom. + * @param geom the geom to query. + * @sa dGeomSetBody + * @ingroup collide + */ +ODE_API dBodyID dGeomGetBody (dGeomID geom); + + +/** + * @brief Set the position vector of a placeable geom. + * + * If the geom is attached to a body, the body's position will also be changed. + * Calling this function on a non-placeable geom results in a runtime error in + * the debug build of ODE. + * + * @param geom the geom to set. + * @param x the new X coordinate. + * @param y the new Y coordinate. + * @param z the new Z coordinate. + * @sa dBodySetPosition + * @ingroup collide + */ +ODE_API void dGeomSetPosition (dGeomID geom, dReal x, dReal y, dReal z); + + +/** + * @brief Set the rotation matrix of a placeable geom. + * + * If the geom is attached to a body, the body's rotation will also be changed. + * Calling this function on a non-placeable geom results in a runtime error in + * the debug build of ODE. + * + * @param geom the geom to set. + * @param R the new rotation matrix. + * @sa dBodySetRotation + * @ingroup collide + */ +ODE_API void dGeomSetRotation (dGeomID geom, const dMatrix3 R); + + +/** + * @brief Set the rotation of a placeable geom. + * + * If the geom is attached to a body, the body's rotation will also be changed. + * + * Calling this function on a non-placeable geom results in a runtime error in + * the debug build of ODE. + * + * @param geom the geom to set. + * @param Q the new rotation. + * @sa dBodySetQuaternion + * @ingroup collide + */ +ODE_API void dGeomSetQuaternion (dGeomID geom, const dQuaternion Q); + + +/** + * @brief Get the position vector of a placeable geom. + * + * If the geom is attached to a body, the body's position will be returned. + * + * Calling this function on a non-placeable geom results in a runtime error in + * the debug build of ODE. + * + * @param geom the geom to query. + * @returns A pointer to the geom's position vector. + * @remarks The returned value is a pointer to the geom's internal + * data structure. It is valid until any changes are made + * to the geom. + * @sa dBodyGetPosition + * @ingroup collide + */ +ODE_API const dReal * dGeomGetPosition (dGeomID geom); + + +/** + * @brief Copy the position of a geom into a vector. + * @ingroup collide + * @param geom the geom to query + * @param pos a copy of the geom position + * @sa dGeomGetPosition + */ +ODE_API void dGeomCopyPosition (dGeomID geom, dVector3 pos); + + +/** + * @brief Get the rotation matrix of a placeable geom. + * + * If the geom is attached to a body, the body's rotation will be returned. + * + * Calling this function on a non-placeable geom results in a runtime error in + * the debug build of ODE. + * + * @param geom the geom to query. + * @returns A pointer to the geom's rotation matrix. + * @remarks The returned value is a pointer to the geom's internal + * data structure. It is valid until any changes are made + * to the geom. + * @sa dBodyGetRotation + * @ingroup collide + */ +ODE_API const dReal * dGeomGetRotation (dGeomID geom); + + +/** + * @brief Get the rotation matrix of a placeable geom. + * + * If the geom is attached to a body, the body's rotation will be returned. + * + * Calling this function on a non-placeable geom results in a runtime error in + * the debug build of ODE. + * + * @param geom the geom to query. + * @param R a copy of the geom rotation + * @sa dGeomGetRotation + * @ingroup collide + */ +ODE_API void dGeomCopyRotation(dGeomID geom, dMatrix3 R); + + +/** + * @brief Get the rotation quaternion of a placeable geom. + * + * If the geom is attached to a body, the body's quaternion will be returned. + * + * Calling this function on a non-placeable geom results in a runtime error in + * the debug build of ODE. + * + * @param geom the geom to query. + * @param result a copy of the rotation quaternion. + * @sa dBodyGetQuaternion + * @ingroup collide + */ +ODE_API void dGeomGetQuaternion (dGeomID geom, dQuaternion result); + + +/** + * @brief Return the axis-aligned bounding box. + * + * Return in aabb an axis aligned bounding box that surrounds the given geom. + * The aabb array has elements (minx, maxx, miny, maxy, minz, maxz). If the + * geom is a space, a bounding box that surrounds all contained geoms is + * returned. + * + * This function may return a pre-computed cached bounding box, if it can + * determine that the geom has not moved since the last time the bounding + * box was computed. + * + * @param geom the geom to query + * @param aabb the returned bounding box + * @ingroup collide + */ +ODE_API void dGeomGetAABB (dGeomID geom, dReal aabb[6]); + + +/** + * @brief Determing if a geom is a space. + * @param geom the geom to query + * @returns Non-zero if the geom is a space, zero otherwise. + * @ingroup collide + */ +ODE_API int dGeomIsSpace (dGeomID geom); + + +/** + * @brief Query for the space containing a particular geom. + * @param geom the geom to query + * @returns The space that contains the geom, or NULL if the geom is + * not contained by a space. + * @ingroup collide + */ +ODE_API dSpaceID dGeomGetSpace (dGeomID); + + +/** + * @brief Given a geom, this returns its class. + * + * The ODE classes are: + * @li dSphereClass + * @li dBoxClass + * @li dCylinderClass + * @li dPlaneClass + * @li dRayClass + * @li dConvexClass + * @li dGeomTransformClass + * @li dTriMeshClass + * @li dSimpleSpaceClass + * @li dHashSpaceClass + * @li dQuadTreeSpaceClass + * @li dFirstUserClass + * @li dLastUserClass + * + * User-defined class will return their own number. + * + * @param geom the geom to query + * @returns The geom class ID. + * @ingroup collide + */ +ODE_API int dGeomGetClass (dGeomID geom); + + +/** + * @brief Set the "category" bitfield for the given geom. + * + * The category bitfield is used by spaces to govern which geoms will + * interact with each other. The bitfield is guaranteed to be at least + * 32 bits wide. The default category values for newly created geoms + * have all bits set. + * + * @param geom the geom to set + * @param bits the new bitfield value + * @ingroup collide + */ +ODE_API void dGeomSetCategoryBits (dGeomID geom, unsigned long bits); + + +/** + * @brief Set the "collide" bitfield for the given geom. + * + * The collide bitfield is used by spaces to govern which geoms will + * interact with each other. The bitfield is guaranteed to be at least + * 32 bits wide. The default category values for newly created geoms + * have all bits set. + * + * @param geom the geom to set + * @param bits the new bitfield value + * @ingroup collide + */ +ODE_API void dGeomSetCollideBits (dGeomID geom, unsigned long bits); + + +/** + * @brief Get the "category" bitfield for the given geom. + * + * @param geom the geom to set + * @param bits the new bitfield value + * @sa dGeomSetCategoryBits + * @ingroup collide + */ +ODE_API unsigned long dGeomGetCategoryBits (dGeomID); + + +/** + * @brief Get the "collide" bitfield for the given geom. + * + * @param geom the geom to set + * @param bits the new bitfield value + * @sa dGeomSetCollideBits + * @ingroup collide + */ +ODE_API unsigned long dGeomGetCollideBits (dGeomID); + + +/** + * @brief Enable a geom. + * + * Disabled geoms are completely ignored by dSpaceCollide and dSpaceCollide2, + * although they can still be members of a space. New geoms are created in + * the enabled state. + * + * @param geom the geom to enable + * @sa dGeomDisable + * @sa dGeomIsEnabled + * @ingroup collide + */ +ODE_API void dGeomEnable (dGeomID geom); + + +/** + * @brief Disable a geom. + * + * Disabled geoms are completely ignored by dSpaceCollide and dSpaceCollide2, + * although they can still be members of a space. New geoms are created in + * the enabled state. + * + * @param geom the geom to disable + * @sa dGeomDisable + * @sa dGeomIsEnabled + * @ingroup collide + */ +ODE_API void dGeomDisable (dGeomID geom); + + +/** + * @brief Check to see if a geom is enabled. + * + * Disabled geoms are completely ignored by dSpaceCollide and dSpaceCollide2, + * although they can still be members of a space. New geoms are created in + * the enabled state. + * + * @param geom the geom to query + * @returns Non-zero if the geom is enabled, zero otherwise. + * @sa dGeomDisable + * @sa dGeomIsEnabled + * @ingroup collide + */ +ODE_API int dGeomIsEnabled (dGeomID geom); + + +enum +{ + dGeomCommonControlClass = 0, + dGeomColliderControlClass = 1 +}; + +enum +{ + dGeomCommonAnyControlCode = 0, + + dGeomColliderSetMergeSphereContactsControlCode = 1, + dGeomColliderGetMergeSphereContactsControlCode = 2 +}; + +enum +{ + dGeomColliderMergeContactsValue__Default = 0, /* Used with Set... to restore default value*/ + dGeomColliderMergeContactsValue_None = 1, + dGeomColliderMergeContactsValue_Normals = 2, + dGeomColliderMergeContactsValue_Full = 3 +}; + +/** + * @brief Execute low level control operation for geometry. + * + * The variable the dataSize points to must be initialized before the call. + * If the size does not match the one expected for the control class/code function + * changes it to the size expected and returns failure. This implies the function + * can be called with NULL data and zero size to test if control class/code is supported + * and obtain required data size for it. + * + * dGeomCommonAnyControlCode applies to any control class and returns success if + * at least one control code is available for the given class with given geom. + * + * Currently there are the folliwing control classes supported: + * @li dGeomColliderControlClass + * + * For dGeomColliderControlClass there are the following codes available: + * @li dGeomColliderSetMergeSphereContactsControlCode (arg of type int, dGeomColliderMergeContactsValue_*) + * @li dGeomColliderGetMergeSphereContactsControlCode (arg of type int, dGeomColliderMergeContactsValue_*) + * + * @param geom the geom to control + * @param controlClass the control class + * @param controlCode the control code for the class + * @param dataValue the control argument pointer + * @param dataSize the control argument size provided or expected + * @returns Boolean execution status + * @ingroup collide + */ +ODE_API int dGeomLowLevelControl (dGeomID geom, int controlClass, int controlCode, void *dataValue, int *dataSize); + + +/** + * @brief Get world position of a relative point on geom. + * + * Calling this function on a non-placeable geom results in the same point being + * returned. + * + * @ingroup collide + * @param result will contain the result. + */ +ODE_API void dGeomGetRelPointPos +( + dGeomID geom, dReal px, dReal py, dReal pz, + dVector3 result +); + +/** + * @brief takes a point in global coordinates and returns + * the point's position in geom-relative coordinates. + * + * Calling this function on a non-placeable geom results in the same point being + * returned. + * + * @remarks + * This is the inverse of dGeomGetRelPointPos() + * @ingroup collide + * @param result will contain the result. + */ +ODE_API void dGeomGetPosRelPoint +( + dGeomID geom, dReal px, dReal py, dReal pz, + dVector3 result +); + +/** + * @brief Convert from geom-local to world coordinates. + * + * Calling this function on a non-placeable geom results in the same vector being + * returned. + * + * @ingroup collide + * @param result will contain the result. + */ +ODE_API void dGeomVectorToWorld +( + dGeomID geom, dReal px, dReal py, dReal pz, + dVector3 result +); + +/** + * @brief Convert from world to geom-local coordinates. + * + * Calling this function on a non-placeable geom results in the same vector being + * returned. + * + * @ingroup collide + * @param result will contain the result. + */ +ODE_API void dGeomVectorFromWorld +( + dGeomID geom, dReal px, dReal py, dReal pz, + dVector3 result +); + + +/* ************************************************************************ */ +/* geom offset from body */ + +/** + * @brief Set the local offset position of a geom from its body. + * + * Sets the geom's positional offset in local coordinates. + * After this call, the geom will be at a new position determined from the + * body's position and the offset. + * The geom must be attached to a body. + * If the geom did not have an offset, it is automatically created. + * + * @param geom the geom to set. + * @param x the new X coordinate. + * @param y the new Y coordinate. + * @param z the new Z coordinate. + * @ingroup collide + */ +ODE_API void dGeomSetOffsetPosition (dGeomID geom, dReal x, dReal y, dReal z); + + +/** + * @brief Set the local offset rotation matrix of a geom from its body. + * + * Sets the geom's rotational offset in local coordinates. + * After this call, the geom will be at a new position determined from the + * body's position and the offset. + * The geom must be attached to a body. + * If the geom did not have an offset, it is automatically created. + * + * @param geom the geom to set. + * @param R the new rotation matrix. + * @ingroup collide + */ +ODE_API void dGeomSetOffsetRotation (dGeomID geom, const dMatrix3 R); + + +/** + * @brief Set the local offset rotation of a geom from its body. + * + * Sets the geom's rotational offset in local coordinates. + * After this call, the geom will be at a new position determined from the + * body's position and the offset. + * The geom must be attached to a body. + * If the geom did not have an offset, it is automatically created. + * + * @param geom the geom to set. + * @param Q the new rotation. + * @ingroup collide + */ +ODE_API void dGeomSetOffsetQuaternion (dGeomID geom, const dQuaternion Q); + + +/** + * @brief Set the offset position of a geom from its body. + * + * Sets the geom's positional offset to move it to the new world + * coordinates. + * After this call, the geom will be at the world position passed in, + * and the offset will be the difference from the current body position. + * The geom must be attached to a body. + * If the geom did not have an offset, it is automatically created. + * + * @param geom the geom to set. + * @param x the new X coordinate. + * @param y the new Y coordinate. + * @param z the new Z coordinate. + * @ingroup collide + */ +ODE_API void dGeomSetOffsetWorldPosition (dGeomID geom, dReal x, dReal y, dReal z); + + +/** + * @brief Set the offset rotation of a geom from its body. + * + * Sets the geom's rotational offset to orient it to the new world + * rotation matrix. + * After this call, the geom will be at the world orientation passed in, + * and the offset will be the difference from the current body orientation. + * The geom must be attached to a body. + * If the geom did not have an offset, it is automatically created. + * + * @param geom the geom to set. + * @param R the new rotation matrix. + * @ingroup collide + */ +ODE_API void dGeomSetOffsetWorldRotation (dGeomID geom, const dMatrix3 R); + + +/** + * @brief Set the offset rotation of a geom from its body. + * + * Sets the geom's rotational offset to orient it to the new world + * rotation matrix. + * After this call, the geom will be at the world orientation passed in, + * and the offset will be the difference from the current body orientation. + * The geom must be attached to a body. + * If the geom did not have an offset, it is automatically created. + * + * @param geom the geom to set. + * @param Q the new rotation. + * @ingroup collide + */ +ODE_API void dGeomSetOffsetWorldQuaternion (dGeomID geom, const dQuaternion); + + +/** + * @brief Clear any offset from the geom. + * + * If the geom has an offset, it is eliminated and the geom is + * repositioned at the body's position. If the geom has no offset, + * this function does nothing. + * This is more efficient than calling dGeomSetOffsetPosition(zero) + * and dGeomSetOffsetRotation(identiy), because this function actually + * eliminates the offset, rather than leaving it as the identity transform. + * + * @param geom the geom to have its offset destroyed. + * @ingroup collide + */ +ODE_API void dGeomClearOffset(dGeomID geom); + + +/** + * @brief Check to see whether the geom has an offset. + * + * This function will return non-zero if the offset has been created. + * Note that there is a difference between a geom with no offset, + * and a geom with an offset that is the identity transform. + * In the latter case, although the observed behaviour is identical, + * there is a unnecessary computation involved because the geom will + * be applying the transform whenever it needs to recalculate its world + * position. + * + * @param geom the geom to query. + * @returns Non-zero if the geom has an offset, zero otherwise. + * @ingroup collide + */ +ODE_API int dGeomIsOffset(dGeomID geom); + + +/** + * @brief Get the offset position vector of a geom. + * + * Returns the positional offset of the geom in local coordinates. + * If the geom has no offset, this function returns the zero vector. + * + * @param geom the geom to query. + * @returns A pointer to the geom's offset vector. + * @remarks The returned value is a pointer to the geom's internal + * data structure. It is valid until any changes are made + * to the geom. + * @ingroup collide + */ +ODE_API const dReal * dGeomGetOffsetPosition (dGeomID geom); + + +/** + * @brief Copy the offset position vector of a geom. + * + * Returns the positional offset of the geom in local coordinates. + * If the geom has no offset, this function returns the zero vector. + * + * @param geom the geom to query. + * @param pos returns the offset position + * @ingroup collide + */ +ODE_API void dGeomCopyOffsetPosition (dGeomID geom, dVector3 pos); + + +/** + * @brief Get the offset rotation matrix of a geom. + * + * Returns the rotational offset of the geom in local coordinates. + * If the geom has no offset, this function returns the identity + * matrix. + * + * @param geom the geom to query. + * @returns A pointer to the geom's offset rotation matrix. + * @remarks The returned value is a pointer to the geom's internal + * data structure. It is valid until any changes are made + * to the geom. + * @ingroup collide + */ +ODE_API const dReal * dGeomGetOffsetRotation (dGeomID geom); + + +/** + * @brief Copy the offset rotation matrix of a geom. + * + * Returns the rotational offset of the geom in local coordinates. + * If the geom has no offset, this function returns the identity + * matrix. + * + * @param geom the geom to query. + * @param R returns the rotation matrix. + * @ingroup collide + */ +ODE_API void dGeomCopyOffsetRotation (dGeomID geom, dMatrix3 R); + + +/** + * @brief Get the offset rotation quaternion of a geom. + * + * Returns the rotation offset of the geom as a quaternion. + * If the geom has no offset, the identity quaternion is returned. + * + * @param geom the geom to query. + * @param result a copy of the rotation quaternion. + * @ingroup collide + */ +ODE_API void dGeomGetOffsetQuaternion (dGeomID geom, dQuaternion result); + + +/* ************************************************************************ */ +/* collision detection */ + +/* + * Just generate any contacts (disables any contact refining). + */ +#define CONTACTS_UNIMPORTANT 0x80000000 + +/** + * + * @brief Given two geoms o1 and o2 that potentially intersect, + * generate contact information for them. + * + * Internally, this just calls the correct class-specific collision + * functions for o1 and o2. + * + * @param o1 The first geom to test. + * @param o2 The second geom to test. + * + * @param flags The flags specify how contacts should be generated if + * the geoms touch. The lower 16 bits of flags is an integer that + * specifies the maximum number of contact points to generate. You must + * ask for at least one contact. + * Additionally, following bits may be set: + * CONTACTS_UNIMPORTANT -- just generate any contacts (skip contact refining). + * All other bits in flags must be set to zero. In the future the other bits + * may be used to select from different contact generation strategies. + * + * @param contact Points to an array of dContactGeom structures. The array + * must be able to hold at least the maximum number of contacts. These + * dContactGeom structures may be embedded within larger structures in the + * array -- the skip parameter is the byte offset from one dContactGeom to + * the next in the array. If skip is sizeof(dContactGeom) then contact + * points to a normal (C-style) array. It is an error for skip to be smaller + * than sizeof(dContactGeom). + * + * @returns If the geoms intersect, this function returns the number of contact + * points generated (and updates the contact array), otherwise it returns 0 + * (and the contact array is not touched). + * + * @remarks If a space is passed as o1 or o2 then this function will collide + * all objects contained in o1 with all objects contained in o2, and return + * the resulting contact points. This method for colliding spaces with geoms + * (or spaces with spaces) provides no user control over the individual + * collisions. To get that control, use dSpaceCollide or dSpaceCollide2 instead. + * + * @remarks If o1 and o2 are the same geom then this function will do nothing + * and return 0. Technically speaking an object intersects with itself, but it + * is not useful to find contact points in this case. + * + * @remarks This function does not care if o1 and o2 are in the same space or not + * (or indeed if they are in any space at all). + * + * @ingroup collide + */ +ODE_API int dCollide (dGeomID o1, dGeomID o2, int flags, dContactGeom *contact, + int skip); + +/** + * @brief Determines which pairs of geoms in a space may potentially intersect, + * and calls the callback function for each candidate pair. + * + * @param space The space to test. + * + * @param data Passed from dSpaceCollide directly to the callback + * function. Its meaning is user defined. The o1 and o2 arguments are the + * geoms that may be near each other. + * + * @param callback A callback function is of type @ref dNearCallback. + * + * @remarks Other spaces that are contained within the colliding space are + * not treated specially, i.e. they are not recursed into. The callback + * function may be passed these contained spaces as one or both geom + * arguments. + * + * @remarks dSpaceCollide() is guaranteed to pass all intersecting geom + * pairs to the callback function, but may also pass close but + * non-intersecting pairs. The number of these calls depends on the + * internal algorithms used by the space. Thus you should not expect + * that dCollide will return contacts for every pair passed to the + * callback. + * + * @sa dSpaceCollide2 + * @ingroup collide + */ +ODE_API void dSpaceCollide (dSpaceID space, void *data, dNearCallback *callback); + + +/** + * @brief Determines which geoms from one space may potentially intersect with + * geoms from another space, and calls the callback function for each candidate + * pair. + * + * @param space1 The first space to test. + * + * @param space2 The second space to test. + * + * @param data Passed from dSpaceCollide directly to the callback + * function. Its meaning is user defined. The o1 and o2 arguments are the + * geoms that may be near each other. + * + * @param callback A callback function is of type @ref dNearCallback. + * + * @remarks This function can also test a single non-space geom against a + * space. This function is useful when there is a collision hierarchy, i.e. + * when there are spaces that contain other spaces. + * + * @remarks Other spaces that are contained within the colliding space are + * not treated specially, i.e. they are not recursed into. The callback + * function may be passed these contained spaces as one or both geom + * arguments. + * + * @remarks Sublevel value of space affects how the spaces are iterated. + * Both spaces are recursed only if their sublevels match. Otherwise, only + * the space with greater sublevel is recursed and the one with lesser sublevel + * is used as a geom itself. + * + * @remarks dSpaceCollide2() is guaranteed to pass all intersecting geom + * pairs to the callback function, but may also pass close but + * non-intersecting pairs. The number of these calls depends on the + * internal algorithms used by the space. Thus you should not expect + * that dCollide will return contacts for every pair passed to the + * callback. + * + * @sa dSpaceCollide + * @sa dSpaceSetSublevel + * @ingroup collide + */ +ODE_API void dSpaceCollide2 (dGeomID space1, dGeomID space2, void *data, dNearCallback *callback); + + +/* ************************************************************************ */ +/* standard classes */ + +/* the maximum number of user classes that are supported */ +enum { + dMaxUserClasses = 4 +}; + +/* class numbers - each geometry object needs a unique number */ +enum { + dSphereClass = 0, + dBoxClass, + dCapsuleClass, + dCylinderClass, + dPlaneClass, + dRayClass, + dConvexClass, + dGeomTransformClass, + dTriMeshClass, + dHeightfieldClass, + + dFirstSpaceClass, + dSimpleSpaceClass = dFirstSpaceClass, + dHashSpaceClass, + dSweepAndPruneSpaceClass, /* SAP */ + dQuadTreeSpaceClass, + dLastSpaceClass = dQuadTreeSpaceClass, + + dFirstUserClass, + dLastUserClass = dFirstUserClass + dMaxUserClasses - 1, + dGeomNumClasses +}; + + +/** + * @defgroup collide_sphere Sphere Class + * @ingroup collide + */ + +/** + * @brief Create a sphere geom of the given radius, and return its ID. + * + * @param space a space to contain the new geom. May be null. + * @param radius the radius of the sphere. + * + * @returns A new sphere geom. + * + * @remarks The point of reference for a sphere is its center. + * + * @sa dGeomDestroy + * @sa dGeomSphereSetRadius + * @ingroup collide_sphere + */ +ODE_API dGeomID dCreateSphere (dSpaceID space, dReal radius); + + +/** + * @brief Set the radius of a sphere geom. + * + * @param sphere the sphere to set. + * @param radius the new radius. + * + * @sa dGeomSphereGetRadius + * @ingroup collide_sphere + */ +ODE_API void dGeomSphereSetRadius (dGeomID sphere, dReal radius); + + +/** + * @brief Retrieves the radius of a sphere geom. + * + * @param sphere the sphere to query. + * + * @sa dGeomSphereSetRadius + * @ingroup collide_sphere + */ +ODE_API dReal dGeomSphereGetRadius (dGeomID sphere); + + +/** + * @brief Calculate the depth of the a given point within a sphere. + * + * @param sphere the sphere to query. + * @param x the X coordinate of the point. + * @param y the Y coordinate of the point. + * @param z the Z coordinate of the point. + * + * @returns The depth of the point. Points inside the sphere will have a + * positive depth, points outside it will have a negative depth, and points + * on the surface will have a depth of zero. + * + * @ingroup collide_sphere + */ +ODE_API dReal dGeomSpherePointDepth (dGeomID sphere, dReal x, dReal y, dReal z); + + +/*--> Convex Functions*/ +ODE_API dGeomID dCreateConvex (dSpaceID space, + const dReal *_planes, + unsigned int _planecount, + const dReal *_points, + unsigned int _pointcount, + const unsigned int *_polygons); + +ODE_API void dGeomSetConvex (dGeomID g, + const dReal *_planes, + unsigned int _count, + const dReal *_points, + unsigned int _pointcount, + const unsigned int *_polygons); +/*<-- Convex Functions*/ + +/** + * @defgroup collide_box Box Class + * @ingroup collide + */ + +/** + * @brief Create a box geom with the provided side lengths. + * + * @param space a space to contain the new geom. May be null. + * @param lx the length of the box along the X axis + * @param ly the length of the box along the Y axis + * @param lz the length of the box along the Z axis + * + * @returns A new box geom. + * + * @remarks The point of reference for a box is its center. + * + * @sa dGeomDestroy + * @sa dGeomBoxSetLengths + * @ingroup collide_box + */ +ODE_API dGeomID dCreateBox (dSpaceID space, dReal lx, dReal ly, dReal lz); + + +/** + * @brief Set the side lengths of the given box. + * + * @param box the box to set + * @param lx the length of the box along the X axis + * @param ly the length of the box along the Y axis + * @param lz the length of the box along the Z axis + * + * @sa dGeomBoxGetLengths + * @ingroup collide_box + */ +ODE_API void dGeomBoxSetLengths (dGeomID box, dReal lx, dReal ly, dReal lz); + + +/** + * @brief Get the side lengths of a box. + * + * @param box the box to query + * @param result the returned side lengths + * + * @sa dGeomBoxSetLengths + * @ingroup collide_box + */ +ODE_API void dGeomBoxGetLengths (dGeomID box, dVector3 result); + + +/** + * @brief Return the depth of a point in a box. + * + * @param box the box to query + * @param x the X coordinate of the point to test. + * @param y the Y coordinate of the point to test. + * @param z the Z coordinate of the point to test. + * + * @returns The depth of the point. Points inside the box will have a + * positive depth, points outside it will have a negative depth, and points + * on the surface will have a depth of zero. + */ +ODE_API dReal dGeomBoxPointDepth (dGeomID box, dReal x, dReal y, dReal z); + + +ODE_API dGeomID dCreatePlane (dSpaceID space, dReal a, dReal b, dReal c, dReal d); +ODE_API void dGeomPlaneSetParams (dGeomID plane, dReal a, dReal b, dReal c, dReal d); +ODE_API void dGeomPlaneGetParams (dGeomID plane, dVector4 result); +ODE_API dReal dGeomPlanePointDepth (dGeomID plane, dReal x, dReal y, dReal z); + +ODE_API dGeomID dCreateCapsule (dSpaceID space, dReal radius, dReal length); +ODE_API void dGeomCapsuleSetParams (dGeomID ccylinder, dReal radius, dReal length); +ODE_API void dGeomCapsuleGetParams (dGeomID ccylinder, dReal *radius, dReal *length); +ODE_API dReal dGeomCapsulePointDepth (dGeomID ccylinder, dReal x, dReal y, dReal z); + +/* For now we want to have a backwards compatible C-API, note: C++ API is not.*/ +#define dCreateCCylinder dCreateCapsule +#define dGeomCCylinderSetParams dGeomCapsuleSetParams +#define dGeomCCylinderGetParams dGeomCapsuleGetParams +#define dGeomCCylinderPointDepth dGeomCapsulePointDepth +#define dCCylinderClass dCapsuleClass + +ODE_API dGeomID dCreateCylinder (dSpaceID space, dReal radius, dReal length); +ODE_API void dGeomCylinderSetParams (dGeomID cylinder, dReal radius, dReal length); +ODE_API void dGeomCylinderGetParams (dGeomID cylinder, dReal *radius, dReal *length); + +ODE_API dGeomID dCreateRay (dSpaceID space, dReal length); +ODE_API void dGeomRaySetLength (dGeomID ray, dReal length); +ODE_API dReal dGeomRayGetLength (dGeomID ray); +ODE_API void dGeomRaySet (dGeomID ray, dReal px, dReal py, dReal pz, + dReal dx, dReal dy, dReal dz); +ODE_API void dGeomRayGet (dGeomID ray, dVector3 start, dVector3 dir); + +/* + * Set/get ray flags that influence ray collision detection. + * These flags are currently only noticed by the trimesh collider, because + * they can make a major differences there. + */ +ODE_API_DEPRECATED ODE_API void dGeomRaySetParams (dGeomID g, int FirstContact, int BackfaceCull); +ODE_API_DEPRECATED ODE_API void dGeomRayGetParams (dGeomID g, int *FirstContact, int *BackfaceCull); +ODE_API void dGeomRaySetFirstContact (dGeomID g, int firstContact); +ODE_API int dGeomRayGetFirstContact (dGeomID g); +ODE_API void dGeomRaySetBackfaceCull (dGeomID g, int backfaceCull); +ODE_API int dGeomRayGetBackfaceCull (dGeomID g); +ODE_API void dGeomRaySetClosestHit (dGeomID g, int closestHit); +ODE_API int dGeomRayGetClosestHit (dGeomID g); + +#include "collision_trimesh.h" + +ODE_API_DEPRECATED ODE_API dGeomID dCreateGeomTransform (dSpaceID space); +ODE_API_DEPRECATED ODE_API void dGeomTransformSetGeom (dGeomID g, dGeomID obj); +ODE_API_DEPRECATED ODE_API dGeomID dGeomTransformGetGeom (dGeomID g); +ODE_API_DEPRECATED ODE_API void dGeomTransformSetCleanup (dGeomID g, int mode); +ODE_API_DEPRECATED ODE_API int dGeomTransformGetCleanup (dGeomID g); +ODE_API_DEPRECATED ODE_API void dGeomTransformSetInfo (dGeomID g, int mode); +ODE_API_DEPRECATED ODE_API int dGeomTransformGetInfo (dGeomID g); + + +/* ************************************************************************ */ +/* heightfield functions */ + + +/* Data storage for heightfield data.*/ +struct dxHeightfieldData; +typedef struct dxHeightfieldData* dHeightfieldDataID; + + +/** + * @brief Callback prototype + * + * Used by the callback heightfield data type to sample a height for a + * given cell position. + * + * @param p_user_data User data specified when creating the dHeightfieldDataID + * @param x The index of a sample in the local x axis. It is a value + * in the range zero to ( nWidthSamples - 1 ). + * @param x The index of a sample in the local z axis. It is a value + * in the range zero to ( nDepthSamples - 1 ). + * + * @return The sample height which is then scaled and offset using the + * values specified when the heightfield data was created. + * + * @ingroup collide + */ +typedef dReal dHeightfieldGetHeight( void* p_user_data, int x, int z ); + + + +/** + * @brief Creates a heightfield geom. + * + * Uses the information in the given dHeightfieldDataID to construct + * a geom representing a heightfield in a collision space. + * + * @param space The space to add the geom to. + * @param data The dHeightfieldDataID created by dGeomHeightfieldDataCreate and + * setup by dGeomHeightfieldDataBuildCallback, dGeomHeightfieldDataBuildByte, + * dGeomHeightfieldDataBuildShort or dGeomHeightfieldDataBuildFloat. + * @param bPlaceable If non-zero this geom can be transformed in the world using the + * usual functions such as dGeomSetPosition and dGeomSetRotation. If the geom is + * not set as placeable, then it uses a fixed orientation where the global y axis + * represents the dynamic 'height' of the heightfield. + * + * @return A geom id to reference this geom in other calls. + * + * @ingroup collide + */ +ODE_API dGeomID dCreateHeightfield( dSpaceID space, + dHeightfieldDataID data, int bPlaceable ); + + +/** + * @brief Creates a new empty dHeightfieldDataID. + * + * Allocates a new dHeightfieldDataID and returns it. You must call + * dGeomHeightfieldDataDestroy to destroy it after the geom has been removed. + * The dHeightfieldDataID value is used when specifying a data format type. + * + * @return A dHeightfieldDataID for use with dGeomHeightfieldDataBuildCallback, + * dGeomHeightfieldDataBuildByte, dGeomHeightfieldDataBuildShort or + * dGeomHeightfieldDataBuildFloat. + * @ingroup collide + */ +ODE_API dHeightfieldDataID dGeomHeightfieldDataCreate(void); + + +/** + * @brief Destroys a dHeightfieldDataID. + * + * Deallocates a given dHeightfieldDataID and all managed resources. + * + * @param d A dHeightfieldDataID created by dGeomHeightfieldDataCreate + * @ingroup collide + */ +ODE_API void dGeomHeightfieldDataDestroy( dHeightfieldDataID d ); + + + +/** + * @brief Configures a dHeightfieldDataID to use a callback to + * retrieve height data. + * + * Before a dHeightfieldDataID can be used by a geom it must be + * configured to specify the format of the height data. + * This call specifies that the heightfield data is computed by + * the user and it should use the given callback when determining + * the height of a given element of it's shape. + * + * @param d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate + * + * @param width Specifies the total 'width' of the heightfield along + * the geom's local x axis. + * @param depth Specifies the total 'depth' of the heightfield along + * the geom's local z axis. + * + * @param widthSamples Specifies the number of vertices to sample + * along the width of the heightfield. Each vertex has a corresponding + * height value which forms the overall shape. + * Naturally this value must be at least two or more. + * @param depthSamples Specifies the number of vertices to sample + * along the depth of the heightfield. + * + * @param scale A uniform scale applied to all raw height data. + * @param offset An offset applied to the scaled height data. + * + * @param thickness A value subtracted from the lowest height + * value which in effect adds an additional cuboid to the base of the + * heightfield. This is used to prevent geoms from looping under the + * desired terrain and not registering as a collision. Note that the + * thickness is not affected by the scale or offset parameters. + * + * @param bWrap If non-zero the heightfield will infinitely tile in both + * directions along the local x and z axes. If zero the heightfield is + * bounded from zero to width in the local x axis, and zero to depth in + * the local z axis. + * + * @ingroup collide + */ +ODE_API void dGeomHeightfieldDataBuildCallback( dHeightfieldDataID d, + void* pUserData, dHeightfieldGetHeight* pCallback, + dReal width, dReal depth, int widthSamples, int depthSamples, + dReal scale, dReal offset, dReal thickness, int bWrap ); + +/** + * @brief Configures a dHeightfieldDataID to use height data in byte format. + * + * Before a dHeightfieldDataID can be used by a geom it must be + * configured to specify the format of the height data. + * This call specifies that the heightfield data is stored as a rectangular + * array of bytes (8 bit unsigned) representing the height at each sample point. + * + * @param d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate + * + * @param pHeightData A pointer to the height data. + * @param bCopyHeightData When non-zero the height data is copied to an + * internal store. When zero the height data is accessed by reference and + * so must persist throughout the lifetime of the heightfield. + * + * @param width Specifies the total 'width' of the heightfield along + * the geom's local x axis. + * @param depth Specifies the total 'depth' of the heightfield along + * the geom's local z axis. + * + * @param widthSamples Specifies the number of vertices to sample + * along the width of the heightfield. Each vertex has a corresponding + * height value which forms the overall shape. + * Naturally this value must be at least two or more. + * @param depthSamples Specifies the number of vertices to sample + * along the depth of the heightfield. + * + * @param scale A uniform scale applied to all raw height data. + * @param offset An offset applied to the scaled height data. + * + * @param thickness A value subtracted from the lowest height + * value which in effect adds an additional cuboid to the base of the + * heightfield. This is used to prevent geoms from looping under the + * desired terrain and not registering as a collision. Note that the + * thickness is not affected by the scale or offset parameters. + * + * @param bWrap If non-zero the heightfield will infinitely tile in both + * directions along the local x and z axes. If zero the heightfield is + * bounded from zero to width in the local x axis, and zero to depth in + * the local z axis. + * + * @ingroup collide + */ +ODE_API void dGeomHeightfieldDataBuildByte( dHeightfieldDataID d, + const unsigned char* pHeightData, int bCopyHeightData, + dReal width, dReal depth, int widthSamples, int depthSamples, + dReal scale, dReal offset, dReal thickness, int bWrap ); + +/** + * @brief Configures a dHeightfieldDataID to use height data in short format. + * + * Before a dHeightfieldDataID can be used by a geom it must be + * configured to specify the format of the height data. + * This call specifies that the heightfield data is stored as a rectangular + * array of shorts (16 bit signed) representing the height at each sample point. + * + * @param d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate + * + * @param pHeightData A pointer to the height data. + * @param bCopyHeightData When non-zero the height data is copied to an + * internal store. When zero the height data is accessed by reference and + * so must persist throughout the lifetime of the heightfield. + * + * @param width Specifies the total 'width' of the heightfield along + * the geom's local x axis. + * @param depth Specifies the total 'depth' of the heightfield along + * the geom's local z axis. + * + * @param widthSamples Specifies the number of vertices to sample + * along the width of the heightfield. Each vertex has a corresponding + * height value which forms the overall shape. + * Naturally this value must be at least two or more. + * @param depthSamples Specifies the number of vertices to sample + * along the depth of the heightfield. + * + * @param scale A uniform scale applied to all raw height data. + * @param offset An offset applied to the scaled height data. + * + * @param thickness A value subtracted from the lowest height + * value which in effect adds an additional cuboid to the base of the + * heightfield. This is used to prevent geoms from looping under the + * desired terrain and not registering as a collision. Note that the + * thickness is not affected by the scale or offset parameters. + * + * @param bWrap If non-zero the heightfield will infinitely tile in both + * directions along the local x and z axes. If zero the heightfield is + * bounded from zero to width in the local x axis, and zero to depth in + * the local z axis. + * + * @ingroup collide + */ +ODE_API void dGeomHeightfieldDataBuildShort( dHeightfieldDataID d, + const short* pHeightData, int bCopyHeightData, + dReal width, dReal depth, int widthSamples, int depthSamples, + dReal scale, dReal offset, dReal thickness, int bWrap ); + +/** + * @brief Configures a dHeightfieldDataID to use height data in + * single precision floating point format. + * + * Before a dHeightfieldDataID can be used by a geom it must be + * configured to specify the format of the height data. + * This call specifies that the heightfield data is stored as a rectangular + * array of single precision floats representing the height at each + * sample point. + * + * @param d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate + * + * @param pHeightData A pointer to the height data. + * @param bCopyHeightData When non-zero the height data is copied to an + * internal store. When zero the height data is accessed by reference and + * so must persist throughout the lifetime of the heightfield. + * + * @param width Specifies the total 'width' of the heightfield along + * the geom's local x axis. + * @param depth Specifies the total 'depth' of the heightfield along + * the geom's local z axis. + * + * @param widthSamples Specifies the number of vertices to sample + * along the width of the heightfield. Each vertex has a corresponding + * height value which forms the overall shape. + * Naturally this value must be at least two or more. + * @param depthSamples Specifies the number of vertices to sample + * along the depth of the heightfield. + * + * @param scale A uniform scale applied to all raw height data. + * @param offset An offset applied to the scaled height data. + * + * @param thickness A value subtracted from the lowest height + * value which in effect adds an additional cuboid to the base of the + * heightfield. This is used to prevent geoms from looping under the + * desired terrain and not registering as a collision. Note that the + * thickness is not affected by the scale or offset parameters. + * + * @param bWrap If non-zero the heightfield will infinitely tile in both + * directions along the local x and z axes. If zero the heightfield is + * bounded from zero to width in the local x axis, and zero to depth in + * the local z axis. + * + * @ingroup collide + */ +ODE_API void dGeomHeightfieldDataBuildSingle( dHeightfieldDataID d, + const float* pHeightData, int bCopyHeightData, + dReal width, dReal depth, int widthSamples, int depthSamples, + dReal scale, dReal offset, dReal thickness, int bWrap ); + +/** + * @brief Configures a dHeightfieldDataID to use height data in + * double precision floating point format. + * + * Before a dHeightfieldDataID can be used by a geom it must be + * configured to specify the format of the height data. + * This call specifies that the heightfield data is stored as a rectangular + * array of double precision floats representing the height at each + * sample point. + * + * @param d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate + * + * @param pHeightData A pointer to the height data. + * @param bCopyHeightData When non-zero the height data is copied to an + * internal store. When zero the height data is accessed by reference and + * so must persist throughout the lifetime of the heightfield. + * + * @param width Specifies the total 'width' of the heightfield along + * the geom's local x axis. + * @param depth Specifies the total 'depth' of the heightfield along + * the geom's local z axis. + * + * @param widthSamples Specifies the number of vertices to sample + * along the width of the heightfield. Each vertex has a corresponding + * height value which forms the overall shape. + * Naturally this value must be at least two or more. + * @param depthSamples Specifies the number of vertices to sample + * along the depth of the heightfield. + * + * @param scale A uniform scale applied to all raw height data. + * @param offset An offset applied to the scaled height data. + * + * @param thickness A value subtracted from the lowest height + * value which in effect adds an additional cuboid to the base of the + * heightfield. This is used to prevent geoms from looping under the + * desired terrain and not registering as a collision. Note that the + * thickness is not affected by the scale or offset parameters. + * + * @param bWrap If non-zero the heightfield will infinitely tile in both + * directions along the local x and z axes. If zero the heightfield is + * bounded from zero to width in the local x axis, and zero to depth in + * the local z axis. + * + * @ingroup collide + */ +ODE_API void dGeomHeightfieldDataBuildDouble( dHeightfieldDataID d, + const double* pHeightData, int bCopyHeightData, + dReal width, dReal depth, int widthSamples, int depthSamples, + dReal scale, dReal offset, dReal thickness, int bWrap ); + +/** + * @brief Manually set the minimum and maximum height bounds. + * + * This call allows you to set explicit min / max values after initial + * creation typically for callback heightfields which default to +/- infinity, + * or those whose data has changed. This must be set prior to binding with a + * geom, as the the AABB is not recomputed after it's first generation. + * + * @remarks The minimum and maximum values are used to compute the AABB + * for the heightfield which is used for early rejection of collisions. + * A close fit will yield a more efficient collision check. + * + * @param d A dHeightfieldDataID created by dGeomHeightfieldDataCreate + * @param min_height The new minimum height value. Scale, offset and thickness is then applied. + * @param max_height The new maximum height value. Scale and offset is then applied. + * @ingroup collide + */ +ODE_API void dGeomHeightfieldDataSetBounds( dHeightfieldDataID d, + dReal minHeight, dReal maxHeight ); + + +/** + * @brief Assigns a dHeightfieldDataID to a heightfield geom. + * + * Associates the given dHeightfieldDataID with a heightfield geom. + * This is done without affecting the GEOM_PLACEABLE flag. + * + * @param g A geom created by dCreateHeightfield + * @param d A dHeightfieldDataID created by dGeomHeightfieldDataCreate + * @ingroup collide + */ +ODE_API void dGeomHeightfieldSetHeightfieldData( dGeomID g, dHeightfieldDataID d ); + + +/** + * @brief Gets the dHeightfieldDataID bound to a heightfield geom. + * + * Returns the dHeightfieldDataID associated with a heightfield geom. + * + * @param g A geom created by dCreateHeightfield + * @return The dHeightfieldDataID which may be NULL if none was assigned. + * @ingroup collide + */ +ODE_API dHeightfieldDataID dGeomHeightfieldGetHeightfieldData( dGeomID g ); + + + +/* ************************************************************************ */ +/* utility functions */ + +ODE_API void dClosestLineSegmentPoints (const dVector3 a1, const dVector3 a2, + const dVector3 b1, const dVector3 b2, + dVector3 cp1, dVector3 cp2); + +ODE_API int dBoxTouchesBox (const dVector3 _p1, const dMatrix3 R1, + const dVector3 side1, const dVector3 _p2, + const dMatrix3 R2, const dVector3 side2); + +/* The meaning of flags parameter is the same as in dCollide()*/ +ODE_API int dBoxBox (const dVector3 p1, const dMatrix3 R1, + const dVector3 side1, const dVector3 p2, + const dMatrix3 R2, const dVector3 side2, + dVector3 normal, dReal *depth, int *return_code, + int flags, dContactGeom *contact, int skip); + +ODE_API void dInfiniteAABB (dGeomID geom, dReal aabb[6]); + + +/* ************************************************************************ */ +/* custom classes */ + +typedef void dGetAABBFn (dGeomID, dReal aabb[6]); +typedef int dColliderFn (dGeomID o1, dGeomID o2, + int flags, dContactGeom *contact, int skip); +typedef dColliderFn * dGetColliderFnFn (int num); +typedef void dGeomDtorFn (dGeomID o); +typedef int dAABBTestFn (dGeomID o1, dGeomID o2, dReal aabb[6]); + +typedef struct dGeomClass { + int bytes; + dGetColliderFnFn *collider; + dGetAABBFn *aabb; + dAABBTestFn *aabb_test; + dGeomDtorFn *dtor; +} dGeomClass; + +ODE_API int dCreateGeomClass (const dGeomClass *classptr); +ODE_API void * dGeomGetClassData (dGeomID); +ODE_API dGeomID dCreateGeom (int classnum); + +/** + * @brief Sets a custom collider function for two geom classes. + * + * @param i The first geom class handled by this collider + * @param j The second geom class handled by this collider + * @param fn The collider function to use to determine collisions. + * @ingroup collide + */ +ODE_API void dSetColliderOverride (int i, int j, dColliderFn *fn); + + +/* ************************************************************************ */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/ode-0.16.1/include/ode/collision_space.h b/libs/ode-0.16.1/include/ode/collision_space.h new file mode 100644 index 0000000..30cc536 --- /dev/null +++ b/libs/ode-0.16.1/include/ode/collision_space.h @@ -0,0 +1,182 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_COLLISION_SPACE_H_ +#define _ODE_COLLISION_SPACE_H_ + +#include <ode/common.h> + +#ifdef __cplusplus +extern "C" { +#endif + +struct dContactGeom; + +/** + * @brief User callback for geom-geom collision testing. + * + * @param data The user data object, as passed to dSpaceCollide. + * @param o1 The first geom being tested. + * @param o2 The second geom being test. + * + * @remarks The callback function can call dCollide on o1 and o2 to generate + * contact points between each pair. Then these contact points may be added + * to the simulation as contact joints. The user's callback function can of + * course chose not to call dCollide for any pair, e.g. if the user decides + * that those pairs should not interact. + * + * @ingroup collide + */ +typedef void dNearCallback (void *data, dGeomID o1, dGeomID o2); + + +ODE_API dSpaceID dSimpleSpaceCreate (dSpaceID space); +ODE_API dSpaceID dHashSpaceCreate (dSpaceID space); +ODE_API dSpaceID dQuadTreeSpaceCreate (dSpaceID space, const dVector3 Center, const dVector3 Extents, int Depth); + + +/* SAP */ +/* Order XZY or ZXY usually works best, if your Y is up. */ +#define dSAP_AXES_XYZ ((0)|(1<<2)|(2<<4)) +#define dSAP_AXES_XZY ((0)|(2<<2)|(1<<4)) +#define dSAP_AXES_YXZ ((1)|(0<<2)|(2<<4)) +#define dSAP_AXES_YZX ((1)|(2<<2)|(0<<4)) +#define dSAP_AXES_ZXY ((2)|(0<<2)|(1<<4)) +#define dSAP_AXES_ZYX ((2)|(1<<2)|(0<<4)) + +ODE_API dSpaceID dSweepAndPruneSpaceCreate( dSpaceID space, int axisorder ); + + + +ODE_API void dSpaceDestroy (dSpaceID); + +ODE_API void dHashSpaceSetLevels (dSpaceID space, int minlevel, int maxlevel); +ODE_API void dHashSpaceGetLevels (dSpaceID space, int *minlevel, int *maxlevel); + +ODE_API void dSpaceSetCleanup (dSpaceID space, int mode); +ODE_API int dSpaceGetCleanup (dSpaceID space); + +/** +* @brief Sets sublevel value for a space. +* +* Sublevel affects how the space is handled in dSpaceCollide2 when it is collided +* with another space. If sublevels of both spaces match, the function iterates +* geometries of both spaces and collides them with each other. If sublevel of one +* space is greater than the sublevel of another one, only the geometries of the +* space with greater sublevel are iterated, another space is passed into +* collision callback as a geometry itself. By default all the spaces are assigned +* zero sublevel. +* +* @note +* The space sublevel @e IS @e NOT automatically updated when one space is inserted +* into another or removed from one. It is a client's responsibility to update sublevel +* value if necessary. +* +* @param space the space to modify +* @param sublevel the sublevel value to be assigned +* @ingroup collide +* @see dSpaceGetSublevel +* @see dSpaceCollide2 +*/ +ODE_API void dSpaceSetSublevel (dSpaceID space, int sublevel); + +/** +* @brief Gets sublevel value of a space. +* +* Sublevel affects how the space is handled in dSpaceCollide2 when it is collided +* with another space. See @c dSpaceSetSublevel for more details. +* +* @param space the space to query +* @returns the sublevel value of the space +* @ingroup collide +* @see dSpaceSetSublevel +* @see dSpaceCollide2 +*/ +ODE_API int dSpaceGetSublevel (dSpaceID space); + + +/** +* @brief Sets manual cleanup flag for a space. +* +* Manual cleanup flag marks a space as eligible for manual thread data cleanup. +* This function should be called for every space object right after creation in +* case if ODE has been initialized with @c dInitFlagManualThreadCleanup flag. +* +* Failure to set manual cleanup flag for a space may lead to some resources +* remaining leaked until the program exit. +* +* @param space the space to modify +* @param mode 1 for manual cleanup mode and 0 for default cleanup mode +* @ingroup collide +* @see dSpaceGetManualCleanup +* @see dInitODE2 +*/ +ODE_API void dSpaceSetManualCleanup (dSpaceID space, int mode); + +/** +* @brief Get manual cleanup flag of a space. +* +* Manual cleanup flag marks a space space as eligible for manual thread data cleanup. +* See @c dSpaceSetManualCleanup for more details. +* +* @param space the space to query +* @returns 1 for manual cleanup mode and 0 for default cleanup mode of the space +* @ingroup collide +* @see dSpaceSetManualCleanup +* @see dInitODE2 +*/ +ODE_API int dSpaceGetManualCleanup (dSpaceID space); + +ODE_API void dSpaceAdd (dSpaceID, dGeomID); +ODE_API void dSpaceRemove (dSpaceID, dGeomID); +ODE_API int dSpaceQuery (dSpaceID, dGeomID); +ODE_API void dSpaceClean (dSpaceID); +ODE_API int dSpaceGetNumGeoms (dSpaceID); +ODE_API dGeomID dSpaceGetGeom (dSpaceID, int i); + +/** + * @brief Given a space, this returns its class. + * + * The ODE classes are: + * @li dSimpleSpaceClass + * @li dHashSpaceClass + * @li dSweepAndPruneSpaceClass + * @li dQuadTreeSpaceClass + * @li dFirstUserClass + * @li dLastUserClass + * + * The class id not defined by the user should be between + * dFirstSpaceClass and dLastSpaceClass. + * + * User-defined class will return their own number. + * + * @param space the space to query + * @returns The space class ID. + * @ingroup collide + */ +ODE_API int dSpaceGetClass(dSpaceID space); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/ode-0.16.1/include/ode/collision_trimesh.h b/libs/ode-0.16.1/include/ode/collision_trimesh.h new file mode 100644 index 0000000..aa8f624 --- /dev/null +++ b/libs/ode-0.16.1/include/ode/collision_trimesh.h @@ -0,0 +1,316 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * TriMesh code by Erwin de Vries. + * + * Trimesh data. + * This is where the actual vertexdata (pointers), and BV tree is stored. + * Vertices should be single precision! + * This should be more sophisticated, so that the user can easyly implement + * another collision library, but this is a lot of work, and also costs some + * performance because some data has to be copied. + */ + +#ifndef _ODE_COLLISION_TRIMESH_H_ +#define _ODE_COLLISION_TRIMESH_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Data storage for triangle meshes. + */ +struct dxTriMeshData; +typedef struct dxTriMeshData* dTriMeshDataID; + + +typedef enum +{ + dMTV__MIN, + + dMTV_FIRST = dMTV__MIN, + dMTV_SECOND, + dMTV_THIRD, + + dMTV__MAX, + +} dMeshTriangleVertex; + +/* + * These don't make much sense now, but they will later when we add more + * features. + */ +ODE_API dTriMeshDataID dGeomTriMeshDataCreate(void); +ODE_API void dGeomTriMeshDataDestroy(dTriMeshDataID g); + + +/* + * The values of data_id that can be used with dGeomTriMeshDataSet/dGeomTriMeshDataGet + */ +enum +{ + dTRIMESHDATA__MIN, + + dTRIMESHDATA_FACE_NORMALS = dTRIMESHDATA__MIN, + dTRIMESHDATA_USE_FLAGS, + + dTRIMESHDATA__MAX, + +#ifndef TRIMESH_FACE_NORMALS // Define this name during the header inclusion if you need it for something else + // Included for backward compatibility -- please use the corrected name above. Sorry. + TRIMESH_FACE_NORMALS = dTRIMESHDATA_FACE_NORMALS, +#endif +}; + +/* + * The flags of the dTRIMESHDATA_USE_FLAGS data elements + */ +enum +{ + dMESHDATAUSE_EDGE1 = 0x01, + dMESHDATAUSE_EDGE2 = 0x02, + dMESHDATAUSE_EDGE3 = 0x04, + dMESHDATAUSE_VERTEX1 = 0x08, + dMESHDATAUSE_VERTEX2 = 0x10, + dMESHDATAUSE_VERTEX3 = 0x20, +}; + +/* + * Set and get the TriMeshData additional data + * Note: The data is NOT COPIED on assignment + */ +ODE_API void dGeomTriMeshDataSet(dTriMeshDataID g, int data_id, void *in_data); +ODE_API void *dGeomTriMeshDataGet(dTriMeshDataID g, int data_id); +ODE_API void *dGeomTriMeshDataGet2(dTriMeshDataID g, int data_id, dsizeint *pout_size/*=NULL*/); + + + +/** + * We need to set the last transform after each time step for + * accurate collision response. These functions get and set that transform. + * It is stored per geom instance, rather than per dTriMeshDataID. + */ +ODE_API void dGeomTriMeshSetLastTransform( dGeomID g, const dMatrix4 last_trans ); +ODE_API const dReal* dGeomTriMeshGetLastTransform( dGeomID g ); + +/* + * Build a TriMesh data object with single precision vertex data. + */ +ODE_API void dGeomTriMeshDataBuildSingle(dTriMeshDataID g, + const void* Vertices, int VertexStride, int VertexCount, + const void* Indices, int IndexCount, int TriStride); +/* same again with a normals array (used as trimesh-trimesh optimization) */ +ODE_API void dGeomTriMeshDataBuildSingle1(dTriMeshDataID g, + const void* Vertices, int VertexStride, int VertexCount, + const void* Indices, int IndexCount, int TriStride, + const void* Normals); +/* +* Build a TriMesh data object with double precision vertex data. +*/ +ODE_API void dGeomTriMeshDataBuildDouble(dTriMeshDataID g, + const void* Vertices, int VertexStride, int VertexCount, + const void* Indices, int IndexCount, int TriStride); +/* same again with a normals array (used as trimesh-trimesh optimization) */ +ODE_API void dGeomTriMeshDataBuildDouble1(dTriMeshDataID g, + const void* Vertices, int VertexStride, int VertexCount, + const void* Indices, int IndexCount, int TriStride, + const void* Normals); + +/* + * Simple build. Single/double precision based on dSINGLE/dDOUBLE! + */ +ODE_API void dGeomTriMeshDataBuildSimple(dTriMeshDataID g, + const dReal* Vertices, int VertexCount, + const dTriIndex* Indices, int IndexCount); +/* same again with a normals array (used as trimesh-trimesh optimization) */ +ODE_API void dGeomTriMeshDataBuildSimple1(dTriMeshDataID g, + const dReal* Vertices, int VertexCount, + const dTriIndex* Indices, int IndexCount, + const int* Normals); + + +/* + * Data preprocessing build request flags. + */ +enum +{ + dTRIDATAPREPROCESS_BUILD__MIN, + + dTRIDATAPREPROCESS_BUILD_CONCAVE_EDGES = dTRIDATAPREPROCESS_BUILD__MIN, // Used to optimize OPCODE trimesh-capsule collisions; allocates 1 byte per triangle; no extra data associated + dTRIDATAPREPROCESS_BUILD_FACE_ANGLES, // Used to aid trimesh-convex collisions; memory requirements depend on extra data + + dTRIDATAPREPROCESS_BUILD__MAX, +}; + +/* + * Data preprocessing extra values for dTRIDATAPREPROCESS_BUILD_FACE_ANGLES. + */ +enum +{ + dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA__MIN, + + dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA_BYTE_POSITIVE = dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA__MIN, // Build angles for convex edges only and store as bytes; allocates 3 bytes per triangle; stores angles (0..180] in 1/254 fractions leaving two values for the flat and all the concaves + dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA_BYTE_ALL, // Build angles for all the edges and store in bytes; allocates 3 bytes per triangle; stores angles [-180..0) and (0..180] in 1/127 fractions plus a value for the flat angle + dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA_WORD_ALL, // Build angles for all the edges and store in words; allocates 6 bytes per triangle; stores angles [-180..0) and (0..180] in 1/32767 fractions plus a value for the flat angle + + dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA__MAX, + + dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA__DEFAULT = dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA_BYTE_POSITIVE, // The default value assumed if the extra data is not provided +}; + + +/* + * Pre-process the trimesh data according to the request flags. + * + * buildRequestFlags is a bitmask of 1U << dTRIDATAPREPROCESS_BUILD_... + * It is allowed to call the function multiple times provided the bitmasks are different each time. + * + * requestExtraData is an optional pointer to array of extra parameters per bitmask bits + * (only the elements indexed by positions of raised bits are examined; + * defaults are assumed if the pointer is NULL) + * + * The function returns a boolean status the only failure reason being insufficient memory. + */ +ODE_API int dGeomTriMeshDataPreprocess2(dTriMeshDataID g, unsigned int buildRequestFlags, const dintptr *requestExtraData/*=NULL | const dintptr (*)[dTRIDATAPREPROCESS_BUILD__MAX]*/); + +/* + * Obsolete. Equivalent to calling dGeomTriMeshDataPreprocess2(g, (1U << dTRIDATAPREPROCESS_BUILD_CONCAVE_EDGES), NULL) + */ +ODE_API int dGeomTriMeshDataPreprocess(dTriMeshDataID g); + + + +/* + * Get and set the internal preprocessed trimesh data buffer (see the enumerated type above), for loading and saving + * These functions are deprecated. Use dGeomTriMeshDataSet/dGeomTriMeshDataGet2 with dTRIMESHDATA_USE_FLAGS instead. + */ +ODE_API_DEPRECATED ODE_API void dGeomTriMeshDataGetBuffer(dTriMeshDataID g, unsigned char** buf, int* bufLen); +ODE_API_DEPRECATED ODE_API void dGeomTriMeshDataSetBuffer(dTriMeshDataID g, unsigned char* buf); + + +/* + * Per triangle callback. Allows the user to say if he wants a collision with + * a particular triangle. + */ +typedef int dTriCallback(dGeomID TriMesh, dGeomID RefObject, int TriangleIndex); +ODE_API void dGeomTriMeshSetCallback(dGeomID g, dTriCallback* Callback); +ODE_API dTriCallback* dGeomTriMeshGetCallback(dGeomID g); + +/* + * Per object callback. Allows the user to get the list of triangles in 1 + * shot. Maybe we should remove this one. + */ +typedef void dTriArrayCallback(dGeomID TriMesh, dGeomID RefObject, const int* TriIndices, int TriCount); +ODE_API void dGeomTriMeshSetArrayCallback(dGeomID g, dTriArrayCallback* ArrayCallback); +ODE_API dTriArrayCallback* dGeomTriMeshGetArrayCallback(dGeomID g); + +/* + * Ray callback. + * Allows the user to say if a ray collides with a triangle on barycentric + * coords. The user can for example sample a texture with alpha transparency + * to determine if a collision should occur. + */ +typedef int dTriRayCallback(dGeomID TriMesh, dGeomID Ray, int TriangleIndex, dReal u, dReal v); +ODE_API void dGeomTriMeshSetRayCallback(dGeomID g, dTriRayCallback* Callback); +ODE_API dTriRayCallback* dGeomTriMeshGetRayCallback(dGeomID g); + +/* + * Triangle merging callback. + * Allows the user to generate a fake triangle index for a new contact generated + * from merging of two other contacts. That index could later be used by the + * user to determine attributes of original triangles used as sources for a + * merged contact. + */ +typedef int dTriTriMergeCallback(dGeomID TriMesh, int FirstTriangleIndex, int SecondTriangleIndex); +ODE_API void dGeomTriMeshSetTriMergeCallback(dGeomID g, dTriTriMergeCallback* Callback); +ODE_API dTriTriMergeCallback* dGeomTriMeshGetTriMergeCallback(dGeomID g); + +/* + * Trimesh class + * Construction. Callbacks are optional. + */ +ODE_API dGeomID dCreateTriMesh(dSpaceID space, dTriMeshDataID Data, dTriCallback* Callback, dTriArrayCallback* ArrayCallback, dTriRayCallback* RayCallback); + +ODE_API void dGeomTriMeshSetData(dGeomID g, dTriMeshDataID Data); +ODE_API dTriMeshDataID dGeomTriMeshGetData(dGeomID g); + + +/* enable/disable/check temporal coherence*/ +ODE_API void dGeomTriMeshEnableTC(dGeomID g, int geomClass, int enable); +ODE_API int dGeomTriMeshIsTCEnabled(dGeomID g, int geomClass); + +/* + * Clears the internal temporal coherence caches. When a geom has its + * collision checked with a trimesh once, data is stored inside the trimesh. + * With large worlds with lots of seperate objects this list could get huge. + * We should be able to do this automagically. + */ +ODE_API void dGeomTriMeshClearTCCache(dGeomID g); + + +/* + * returns the TriMeshDataID + */ +ODE_API dTriMeshDataID dGeomTriMeshGetTriMeshDataID(dGeomID g); + +/* + * Gets a triangle. + */ +ODE_API void dGeomTriMeshGetTriangle(dGeomID g, int Index, dVector3* v0, dVector3* v1, dVector3* v2); + +/* + * Gets the point on the requested triangle and the given barycentric + * coordinates. + */ +ODE_API void dGeomTriMeshGetPoint(dGeomID g, int Index, dReal u, dReal v, dVector3 Out); + +/* + +This is how the strided data works: + +struct StridedVertex{ + dVector3 Vertex; + // Userdata +}; +int VertexStride = sizeof(StridedVertex); + +struct StridedTri{ + int Indices[3]; + // Userdata +}; +int TriStride = sizeof(StridedTri); + +*/ + + +ODE_API int dGeomTriMeshGetTriangleCount (dGeomID g); + +ODE_API void dGeomTriMeshDataUpdate(dTriMeshDataID g); + +#ifdef __cplusplus +} +#endif + +#endif /* _ODE_COLLISION_TRIMESH_H_ */ + diff --git a/libs/ode-0.16.1/include/ode/common.h b/libs/ode-0.16.1/include/ode/common.h new file mode 100644 index 0000000..b0a5793 --- /dev/null +++ b/libs/ode-0.16.1/include/ode/common.h @@ -0,0 +1,568 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_COMMON_H_ +#define _ODE_COMMON_H_ + +#include <ode/odeconfig.h> +#include <ode/error.h> + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* configuration stuff */ + +/* constants */ + +/* pi and 1/sqrt(2) are defined here if necessary because they don't get + * defined in <math.h> on some platforms (like MS-Windows) + */ + +#ifndef M_PI +#define M_PI REAL(3.1415926535897932384626433832795029) +#endif +#ifndef M_PI_2 +#define M_PI_2 REAL(1.5707963267948966192313216916398) +#endif +#ifndef M_SQRT1_2 +#define M_SQRT1_2 REAL(0.7071067811865475244008443621048490) +#endif + + +/* floating point data type, vector, matrix and quaternion types */ + +#if defined(dSINGLE) +typedef float dReal; +#ifdef dDOUBLE +#error You can only #define dSINGLE or dDOUBLE, not both. +#endif /* dDOUBLE */ +#elif defined(dDOUBLE) +typedef double dReal; +#else +#error You must #define dSINGLE or dDOUBLE +#endif + +/* Detect if we've got both trimesh engines enabled. */ +#if dTRIMESH_ENABLED +#if dTRIMESH_OPCODE && dTRIMESH_GIMPACT +#error You can only #define dTRIMESH_OPCODE or dTRIMESH_GIMPACT, not both. +#endif +#endif /* dTRIMESH_ENABLED */ + +/* + * Define a type for indices, either 16 or 32 bit, based on build option + * TODO: Currently GIMPACT only supports 32 bit indices. + */ +#if dTRIMESH_16BIT_INDICES +#if dTRIMESH_GIMPACT +typedef duint32 dTriIndex; +#else /* dTRIMESH_GIMPACT */ +typedef duint16 dTriIndex; +#endif /* dTRIMESH_GIMPACT */ +#else /* dTRIMESH_16BIT_INDICES */ +typedef duint32 dTriIndex; +#endif /* dTRIMESH_16BIT_INDICES */ + +/* round an integer up to a multiple of 4, except that 0 and 1 are unmodified + * (used to compute matrix leading dimensions) + */ +#define dPAD(a) (((a) > 1) ? (((a) + 3) & (int)(~3)) : (a)) + +typedef enum { + dSA__MIN, + + dSA_X = dSA__MIN, + dSA_Y, + dSA_Z, + + dSA__MAX, +} dSpaceAxis; + +typedef enum { + dMD__MIN, + + dMD_LINEAR = dMD__MIN, + dMD_ANGULAR, + + dMD__MAX, +} dMotionDynamics; + +typedef enum { + dDA__MIN, + + dDA__L_MIN = dDA__MIN + dMD_LINEAR * dSA__MAX, + + dDA_LX = dDA__L_MIN + dSA_X, + dDA_LY = dDA__L_MIN + dSA_Y, + dDA_LZ = dDA__L_MIN + dSA_Z, + + dDA__L_MAX = dDA__L_MIN + dSA__MAX, + + dDA__A_MIN = dDA__MIN + dMD_ANGULAR * dSA__MAX, + + dDA_AX = dDA__A_MIN + dSA_X, + dDA_AY = dDA__A_MIN + dSA_Y, + dDA_AZ = dDA__A_MIN + dSA_Z, + + dDA__A_MAX = dDA__A_MIN + dSA__MAX, + + dDA__MAX = dDA__MIN + dMD__MAX * dSA__MAX, +} dDynamicsAxis; + +typedef enum { + dV3E__MIN, + + dV3E__AXES_MIN = dV3E__MIN, + + dV3E_X = dV3E__AXES_MIN + dSA_X, + dV3E_Y = dV3E__AXES_MIN + dSA_Y, + dV3E_Z = dV3E__AXES_MIN + dSA_Z, + + dV3E__AXES_MAX = dV3E__AXES_MIN + dSA__MAX, + + dV3E_PAD = dV3E__AXES_MAX, + + dV3E__MAX, + + dV3E__AXES_COUNT = dV3E__AXES_MAX - dV3E__AXES_MIN, +} dVec3Element; + +typedef enum { + dV4E__MIN, + + dV4E_X = dV4E__MIN + dSA_X, + dV4E_Y = dV4E__MIN + dSA_Y, + dV4E_Z = dV4E__MIN + dSA_Z, + dV4E_O = dV4E__MIN + dSA__MAX, + + dV4E__MAX, +} dVec4Element; + +typedef enum { + dM3E__MIN, + + dM3E__X_MIN = dM3E__MIN + dSA_X * dV3E__MAX, + + dM3E__X_AXES_MIN = dM3E__X_MIN + dV3E__AXES_MIN, + + dM3E_XX = dM3E__X_MIN + dV3E_X, + dM3E_XY = dM3E__X_MIN + dV3E_Y, + dM3E_XZ = dM3E__X_MIN + dV3E_Z, + + dM3E__X_AXES_MAX = dM3E__X_MIN + dV3E__AXES_MAX, + + dM3E_XPAD = dM3E__X_MIN + dV3E_PAD, + + dM3E__X_MAX = dM3E__X_MIN + dV3E__MAX, + + dM3E__Y_MIN = dM3E__MIN + dSA_Y * dV3E__MAX, + + dM3E__Y_AXES_MIN = dM3E__Y_MIN + dV3E__AXES_MIN, + + dM3E_YX = dM3E__Y_MIN + dV3E_X, + dM3E_YY = dM3E__Y_MIN + dV3E_Y, + dM3E_YZ = dM3E__Y_MIN + dV3E_Z, + + dM3E__Y_AXES_MAX = dM3E__Y_MIN + dV3E__AXES_MAX, + + dM3E_YPAD = dM3E__Y_MIN + dV3E_PAD, + + dM3E__Y_MAX = dM3E__Y_MIN + dV3E__MAX, + + dM3E__Z_MIN = dM3E__MIN + dSA_Z * dV3E__MAX, + + dM3E__Z_AXES_MIN = dM3E__Z_MIN + dV3E__AXES_MIN, + + dM3E_ZX = dM3E__Z_MIN + dV3E_X, + dM3E_ZY = dM3E__Z_MIN + dV3E_Y, + dM3E_ZZ = dM3E__Z_MIN + dV3E_Z, + + dM3E__Z_AXES_MAX = dM3E__Z_MIN + dV3E__AXES_MAX, + + dM3E_ZPAD = dM3E__Z_MIN + dV3E_PAD, + + dM3E__Z_MAX = dM3E__Z_MIN + dV3E__MAX, + + dM3E__MAX = dM3E__MIN + dSA__MAX * dV3E__MAX, +} dMat3Element; + +typedef enum { + dM4E__MIN, + + dM4E__X_MIN = dM4E__MIN + dV4E_X * dV4E__MAX, + + dM4E_XX = dM4E__X_MIN + dV4E_X, + dM4E_XY = dM4E__X_MIN + dV4E_Y, + dM4E_XZ = dM4E__X_MIN + dV4E_Z, + dM4E_XO = dM4E__X_MIN + dV4E_O, + + dM4E__X_MAX = dM4E__X_MIN + dV4E__MAX, + + dM4E__Y_MIN = dM4E__MIN + dV4E_Y * dV4E__MAX, + + dM4E_YX = dM4E__Y_MIN + dV4E_X, + dM4E_YY = dM4E__Y_MIN + dV4E_Y, + dM4E_YZ = dM4E__Y_MIN + dV4E_Z, + dM4E_YO = dM4E__Y_MIN + dV4E_O, + + dM4E__Y_MAX = dM4E__Y_MIN + dV4E__MAX, + + dM4E__Z_MIN = dM4E__MIN + dV4E_Z * dV4E__MAX, + + dM4E_ZX = dM4E__Z_MIN + dV4E_X, + dM4E_ZY = dM4E__Z_MIN + dV4E_Y, + dM4E_ZZ = dM4E__Z_MIN + dV4E_Z, + dM4E_ZO = dM4E__Z_MIN + dV4E_O, + + dM4E__Z_MAX = dM4E__Z_MIN + dV4E__MAX, + + dM4E__O_MIN = dM4E__MIN + dV4E_O * dV4E__MAX, + + dM4E_OX = dM4E__O_MIN + dV4E_X, + dM4E_OY = dM4E__O_MIN + dV4E_Y, + dM4E_OZ = dM4E__O_MIN + dV4E_Z, + dM4E_OO = dM4E__O_MIN + dV4E_O, + + dM4E__O_MAX = dM4E__O_MIN + dV4E__MAX, + + dM4E__MAX = dM4E__MIN + dV4E__MAX * dV4E__MAX, +} dMat4Element; + +typedef enum { + dQUE__MIN, + + dQUE_R = dQUE__MIN, + + dQUE__AXIS_MIN, + + dQUE_I = dQUE__AXIS_MIN + dSA_X, + dQUE_J = dQUE__AXIS_MIN + dSA_Y, + dQUE_K = dQUE__AXIS_MIN + dSA_Z, + + dQUE__AXIS_MAX = dQUE__AXIS_MIN + dSA__MAX, + + dQUE__MAX = dQUE__AXIS_MAX, +} dQuatElement; + +/* these types are mainly just used in headers */ +typedef dReal dVector3[dV3E__MAX]; +typedef dReal dVector4[dV4E__MAX]; +typedef dReal dMatrix3[dM3E__MAX]; +typedef dReal dMatrix4[dM4E__MAX]; +typedef dReal dMatrix6[(dMD__MAX * dV3E__MAX) * (dMD__MAX * dSA__MAX)]; +typedef dReal dQuaternion[dQUE__MAX]; + + +/* precision dependent scalar math functions */ + +#if defined(dSINGLE) + +#define REAL(x) (x##f) /* form a constant */ +#define dRecip(x) ((1.0f/(x))) /* reciprocal */ +#define dSqrt(x) (sqrtf(x)) /* square root */ +#define dRecipSqrt(x) ((1.0f/sqrtf(x))) /* reciprocal square root */ +#define dSin(x) (sinf(x)) /* sine */ +#define dCos(x) (cosf(x)) /* cosine */ +#define dFabs(x) (fabsf(x)) /* absolute value */ +#define dAtan2(y,x) (atan2f(y,x)) /* arc tangent with 2 args */ +#define dAsin(x) (asinf(x)) +#define dAcos(x) (acosf(x)) +#define dFMod(a,b) (fmodf(a,b)) /* modulo */ +#define dFloor(x) floorf(x) /* floor */ +#define dCeil(x) ceilf(x) /* ceil */ +#define dCopySign(a,b) _ode_copysignf(a, b) /* copy value sign */ +#define dNextAfter(x, y) _ode_nextafterf(x, y) /* next value after */ + +#ifdef HAVE___ISNANF +#define dIsNan(x) (__isnanf(x)) +#elif defined(HAVE__ISNANF) +#define dIsNan(x) (_isnanf(x)) +#elif defined(HAVE_ISNANF) +#define dIsNan(x) (isnanf(x)) +#else + /* + fall back to _isnan which is the VC way, + this may seem redundant since we already checked + for _isnan before, but if isnan is detected by + configure but is not found during compilation + we should always make sure we check for __isnanf, + _isnanf and isnanf in that order before falling + back to a default + */ +#define dIsNan(x) (_isnan(x)) +#endif + +#elif defined(dDOUBLE) + +#define REAL(x) (x) +#define dRecip(x) (1.0/(x)) +#define dSqrt(x) sqrt(x) +#define dRecipSqrt(x) (1.0/sqrt(x)) +#define dSin(x) sin(x) +#define dCos(x) cos(x) +#define dFabs(x) fabs(x) +#define dAtan2(y,x) atan2((y),(x)) +#define dAsin(x) asin(x) +#define dAcos(x) acos(x) +#define dFMod(a,b) (fmod((a),(b))) +#define dFloor(x) floor(x) +#define dCeil(x) ceil(x) +#define dCopySign(a,b) _ode_copysign(a, b) +#define dNextAfter(x, y) _ode_nextafter(x, y) + +#ifdef HAVE___ISNAN +#define dIsNan(x) (__isnan(x)) +#elif defined(HAVE__ISNAN) +#define dIsNan(x) (_isnan(x)) +#elif defined(HAVE_ISNAN) +#define dIsNan(x) (isnan(x)) +#else +#define dIsNan(x) (_isnan(x)) +#endif + +#else +#error You must #define dSINGLE or dDOUBLE +#endif + +ODE_PURE_INLINE dReal dMin(dReal x, dReal y) { return x <= y ? x : y; } +ODE_PURE_INLINE dReal dMax(dReal x, dReal y) { return x <= y ? y : x; } + + +/* internal object types (all prefixed with `dx') */ + +struct dxWorld; /* dynamics world */ +struct dxSpace; /* collision space */ +struct dxBody; /* rigid body (dynamics object) */ +struct dxGeom; /* geometry (collision object) */ +struct dxJoint; /* joint */ +struct dxJointGroup;/* joint group */ + + +typedef struct dxWorld *dWorldID; +typedef struct dxSpace *dSpaceID; +typedef struct dxBody *dBodyID; +typedef struct dxGeom *dGeomID; +typedef struct dxJoint *dJointID; +typedef struct dxJointGroup *dJointGroupID; + + +/* error numbers */ + +enum { + d_ERR_UNKNOWN = 0, /* unknown error */ + d_ERR_IASSERT, /* internal assertion failed */ + d_ERR_UASSERT, /* user assertion failed */ + d_ERR_LCP /* user assertion failed */ +}; + + +/* joint type numbers */ + +typedef enum { + dJointTypeNone = 0, /* or "unknown" */ + dJointTypeBall, + dJointTypeHinge, + dJointTypeSlider, + dJointTypeContact, + dJointTypeUniversal, + dJointTypeHinge2, + dJointTypeFixed, + dJointTypeNull, + dJointTypeAMotor, + dJointTypeLMotor, + dJointTypePlane2D, + dJointTypePR, + dJointTypePU, + dJointTypePiston, + dJointTypeDBall, + dJointTypeDHinge, + dJointTypeTransmission, +} dJointType; + + +/* an alternative way of setting joint parameters, using joint parameter + * structures and member constants. we don't actually do this yet. + */ + +/* +typedef struct dLimot { + int mode; + dReal lostop, histop; + dReal vel, fmax; + dReal fudge_factor; + dReal bounce, soft; + dReal suspension_erp, suspension_cfm; +} dLimot; + +enum { + dLimotLoStop = 0x0001, + dLimotHiStop = 0x0002, + dLimotVel = 0x0004, + dLimotFMax = 0x0008, + dLimotFudgeFactor = 0x0010, + dLimotBounce = 0x0020, + dLimotSoft = 0x0040 +}; +*/ + + +/* standard joint parameter names. why are these here? - because we don't want + * to include all the joint function definitions in joint.cpp. hmmmm. + * MSVC complains if we call D_ALL_PARAM_NAMES_X with a blank second argument, + * which is why we have the D_ALL_PARAM_NAMES macro as well. please copy and + * paste between these two. + */ + +#define D_ALL_PARAM_NAMES(start) \ + /* parameters for limits and motors */ \ + dParamLoStop = start, \ + dParamHiStop, \ + dParamVel, \ + dParamLoVel, \ + dParamHiVel, \ + dParamFMax, \ + dParamFudgeFactor, \ + dParamBounce, \ + dParamCFM, \ + dParamStopERP, \ + dParamStopCFM, \ + /* parameters for suspension */ \ + dParamSuspensionERP, \ + dParamSuspensionCFM, \ + dParamERP, \ + + /* + * \enum D_ALL_PARAM_NAMES_X + * + * \var dParamGroup This is the starting value of the different group + * (i.e. dParamGroup1, dParamGroup2, dParamGroup3) + * It also helps in the use of parameter + * (dParamGroup2 | dParamFMax) == dParamFMax2 + */ +#define D_ALL_PARAM_NAMES_X(start,x) \ + dParamGroup ## x = start, \ + /* parameters for limits and motors */ \ + dParamLoStop ## x = start, \ + dParamHiStop ## x, \ + dParamVel ## x, \ + dParamLoVel ## x, \ + dParamHiVel ## x, \ + dParamFMax ## x, \ + dParamFudgeFactor ## x, \ + dParamBounce ## x, \ + dParamCFM ## x, \ + dParamStopERP ## x, \ + dParamStopCFM ## x, \ + /* parameters for suspension */ \ + dParamSuspensionERP ## x, \ + dParamSuspensionCFM ## x, \ + dParamERP ## x, + +enum { + D_ALL_PARAM_NAMES(0) + dParamsInGroup, /* < Number of parameter in a group */ + D_ALL_PARAM_NAMES_X(0x000,1) + D_ALL_PARAM_NAMES_X(0x100,2) + D_ALL_PARAM_NAMES_X(0x200,3) + + /* add a multiple of this constant to the basic parameter numbers to get + * the parameters for the second, third etc axes. + */ + dParamGroup=0x100 +}; + + +/* angular motor mode numbers */ + +enum { + dAMotorUser = 0, + dAMotorEuler = 1 +}; + +/* transmission joint mode numbers */ + +enum { + dTransmissionParallelAxes = 0, + dTransmissionIntersectingAxes = 1, + dTransmissionChainDrive = 2 +}; + + +/* joint force feedback information */ + +typedef struct dJointFeedback { + dVector3 f1; /* force applied to body 1 */ + dVector3 t1; /* torque applied to body 1 */ + dVector3 f2; /* force applied to body 2 */ + dVector3 t2; /* torque applied to body 2 */ +} dJointFeedback; + + +/* private functions that must be implemented by the collision library: + * (1) indicate that a geom has moved, (2) get the next geom in a body list. + * these functions are called whenever the position of geoms connected to a + * body have changed, e.g. with dBodySetPosition(), dBodySetRotation(), or + * when the ODE step function updates the body state. + */ + +void dGeomMoved (dGeomID); +dGeomID dGeomGetBodyNext (dGeomID); + +/** + * dGetConfiguration returns the specific ODE build configuration as + * a string of tokens. The string can be parsed in a similar way to + * the OpenGL extension mechanism, the naming convention should be + * familiar too. The following extensions are reported: + * + * ODE + * ODE_single_precision + * ODE_double_precision + * ODE_EXT_no_debug + * ODE_EXT_trimesh + * ODE_EXT_opcode + * ODE_EXT_gimpact + * ODE_OPC_16bit_indices + * ODE_OPC_new_collider + * ODE_EXT_mt_collisions + * ODE_EXT_threading + * ODE_THR_builtin_impl + */ +ODE_API const char* dGetConfiguration (void); + +/** + * Helper to check for a token in the ODE configuration string. + * Caution, this function is case sensitive. + * + * @param token A configuration token, see dGetConfiguration for details + * + * @return 1 if exact token is present, 0 if not present + */ +ODE_API int dCheckConfiguration( const char* token ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/ode-0.16.1/include/ode/compatibility.h b/libs/ode-0.16.1/include/ode/compatibility.h new file mode 100644 index 0000000..b370986 --- /dev/null +++ b/libs/ode-0.16.1/include/ode/compatibility.h @@ -0,0 +1,40 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_COMPATIBILITY_H_ +#define _ODE_COMPATIBILITY_H_ + +/* + * ODE's backward compatibility system ensures that as ODE's API + * evolves, user code will not break. + */ + +/* + * These new rotation function names are more consistent with the + * rest of the API. + */ +#define dQtoR(q,R) dRfromQ((R),(q)) +#define dRtoQ(R,q) dQfromR((q),(R)) +#define dWtoDQ(w,q,dq) dDQfromW((dq),(w),(q)) + + +#endif diff --git a/libs/ode-0.16.1/include/ode/contact.h b/libs/ode-0.16.1/include/ode/contact.h new file mode 100644 index 0000000..9756f26 --- /dev/null +++ b/libs/ode-0.16.1/include/ode/contact.h @@ -0,0 +1,110 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_CONTACT_H_ +#define _ODE_CONTACT_H_ + +#include <ode/common.h> + +#ifdef __cplusplus +extern "C" { +#endif + + +enum { + dContactMu2 = 0x001, /**< Use axis dependent friction */ + dContactAxisDep = 0x001, /**< Same as above */ + dContactFDir1 = 0x002, /**< Use FDir for the first friction value */ + dContactBounce = 0x004, /**< Restore collision energy anti-parallel to the normal */ + dContactSoftERP = 0x008, /**< Don't use global erp for penetration reduction */ + dContactSoftCFM = 0x010, /**< Don't use global cfm for penetration constraint */ + dContactMotion1 = 0x020, /**< Use a non-zero target velocity for the constraint */ + dContactMotion2 = 0x040, + dContactMotionN = 0x080, + dContactSlip1 = 0x100, /**< Force-dependent slip. */ + dContactSlip2 = 0x200, + dContactRolling = 0x400, /**< Rolling/Angular friction */ + + dContactApprox0 = 0x0000, + dContactApprox1_1 = 0x1000, + dContactApprox1_2 = 0x2000, + dContactApprox1_N = 0x4000, /**< For rolling friction */ + dContactApprox1 = 0x7000 +}; + + +typedef struct dSurfaceParameters { + /* must always be defined */ + int mode; + dReal mu; + + /* only defined if the corresponding flag is set in mode */ + dReal mu2; + dReal rho; /**< Rolling friction */ + dReal rho2; + dReal rhoN; /**< Spinning friction */ + dReal bounce; /**< Coefficient of restitution */ + dReal bounce_vel; /**< Bouncing threshold */ + dReal soft_erp; + dReal soft_cfm; + dReal motion1,motion2,motionN; + dReal slip1,slip2; +} dSurfaceParameters; + + +/** + * @brief Describe the contact point between two geoms. + * + * If two bodies touch, or if a body touches a static feature in its + * environment, the contact is represented by one or more "contact + * points", described by dContactGeom. + * + * The convention is that if body 1 is moved along the normal vector by + * a distance depth (or equivalently if body 2 is moved the same distance + * in the opposite direction) then the contact depth will be reduced to + * zero. This means that the normal vector points "in" to body 1. + * + * @ingroup collide + */ +typedef struct dContactGeom { + dVector3 pos; /*< contact position*/ + dVector3 normal; /*< normal vector*/ + dReal depth; /*< penetration depth*/ + dGeomID g1,g2; /*< the colliding geoms*/ + int side1,side2; /*< (to be documented)*/ +} dContactGeom; + + +/* contact info used by contact joint */ + +typedef struct dContact { + dSurfaceParameters surface; + dContactGeom geom; + dVector3 fdir1; +} dContact; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/ode-0.16.1/include/ode/cooperative.h b/libs/ode-0.16.1/include/ode/cooperative.h new file mode 100644 index 0000000..879477c --- /dev/null +++ b/libs/ode-0.16.1/include/ode/cooperative.h @@ -0,0 +1,229 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_COOPERATIVE_H_ +#define _ODE_COOPERATIVE_H_ + + +#include <ode/common.h> +#include <ode/threading.h> + + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup coop Cooperative Algorithms + * + * Algorithms implemented as multiple threads doing work cooperatively. + */ + + +struct dxCooperative; +struct dxResourceRequirements; +struct dxResourceContainer; + +/** + * @brief A container for cooperative algorithms shared context + * + * The Cooperative is a container for cooperative algorithms shared context. + * At present it contains threading object (either a real one or a defaulted + * self-threading). + * + * Cooperative use in functions performing computations must be serialized. That is, + * functions referring to a single instance of Cooperative object must not be called in + * parallel. + */ +typedef struct dxCooperative *dCooperativeID; + + +/** + * @brief A container for resource requirements information + * + * The ResourceRequirements object is a container for descriptive information + * regarding what resources (memory, synchronization objects, etc.) need to be + * allocated for particular computations. The object can be used for accumulating + * resource requirement maxima over multiple functions and then allocating resources + * that would suffice for any of those function calls. + * + * ResourceRequirements objects maintain relations to Cooperative objects since + * amounts of resources that could be required can depend on characteristics of + * shared context, e.g. on maximal number of threads in the threading object. + * + * @ingroup coop + * @see dCooperativeID + * @see dResourceContainerID + */ +typedef struct dxResourceRequirements *dResourceRequirementsID; + +/** + * @brief A container for algorithm allocated resources + * + * The ResourceContainer object can contain resources allocated according to information + * in a ResourceRequirements. The resources inherit link to the threading object + * from the requirements they are allocated according to. + * + * @ingroup coop + * @see dResourceRequirementsID + * @see dCooperativeID + */ +typedef struct dxResourceContainer *dResourceContainerID; + + + /** + * @brief Creates a Cooperative object related to the specified threading. + * + * NULL's are allowed for the threading. In this case the default (global) self-threading + * object will be used. + * + * Use @c dCooperativeDestroy to destroy the object. The Cooperative object must exist + * until after all the objects referencing it are destroyed. + * + * @param functionInfo The threading functions to use + * @param threadingImpl The threading implementation object to use + * @returns The Cooperative object instance or NULL if allocation fails. + * @ingroup coop + * @see dCooperativeDestroy + */ +ODE_API dCooperativeID dCooperativeCreate(const dThreadingFunctionsInfo *functionInfo/*=NULL*/, dThreadingImplementationID threadingImpl/*=NULL*/); + + /** + * @brief Destroys Cooperative object. + * + * The Cooperative object can only be destroyed after all the objects referencing it. + * + * @param cooperative A Cooperative object to be deleted (NULL is allowed) + * @ingroup coop + * @see dCooperativeCreate + */ +ODE_API void dCooperativeDestroy(dCooperativeID cooperative); + + + /** + * @brief Creates a ResourceRequirements object related to a Cooperative. + * + * The object is purely descriptive and does not contain any resources by itself. + * The actual resources are allocated by means of ResourceContainer object. + * + * The object is created with empty requirements. It can be then used to accumulate + * requirements for one or more function calls and can be cloned or merged with others. + * The actual requirements information is added to the object by computation related + * functions. + * + * Use @c dResourceRequirementsDestroy to delete the object when it is no longer needed. + * + * @param cooperative A Cooperative object to be used + * @returns The ResourceRequirements object instance or NULL if allocation fails + * @ingroup coop + * @see dResourceRequirementsDestroy + * @see dResourceRequirementsClone + * @see dResourceRequirementsMergeIn + * @see dCooperativeCreate + * @see dResourceContainerAcquire + */ +ODE_API dResourceRequirementsID dResourceRequirementsCreate(dCooperativeID cooperative); + + /** + * @brief Destroys ResourceRequirements object. + * + * The ResourceRequirements object can be destroyed at any time with no regards + * to other objects' lifetime. + * + * @param requirements A ResourceRequirements object to be deleted (NULL is allowed) + * @ingroup coop + * @see dResourceRequirementsCreate + */ +ODE_API void dResourceRequirementsDestroy(dResourceRequirementsID requirements); + + /** + * @brief Clones ResourceRequirements object. + * + * The function creates a copy of the ResourceRequirements object with all the + * contents and the relation to Cooperative matching. The object passed in + * the parameter is not changed. + * + * The object created with the function must later be destroyed with @c dResourceRequirementsDestroy. + * + * @param requirements A ResourceRequirements object to be cloned + * @returns A handle to the new object or NULL if allocation fails + * @ingroup coop + * @see dResourceRequirementsCreate + * @see dResourceRequirementsDestroy + * @see dResourceRequirementsMergeIn + */ +ODE_API dResourceRequirementsID dResourceRequirementsClone(/*const */dResourceRequirementsID requirements); + + /** + * @brief Merges one ResourceRequirements object into another ResourceRequirements object. + * + * The function updates @a summaryRequirements requirements to be also sufficient + * for the purposes @a extraRequirements could be used for. The @a extraRequirements + * object is not changed. The both objects should normally have had been created + * with the same Cooperative object. + * + * @param summaryRequirements A ResourceRequirements object to be changed + * @param extraRequirements A ResourceRequirements the requirements to be taken from + * @ingroup coop + * @see dResourceRequirementsCreate + * @see dResourceRequirementsDestroy + * @see dResourceRequirementsClone + */ +ODE_API void dResourceRequirementsMergeIn(dResourceRequirementsID summaryRequirements, /*const */dResourceRequirementsID extraRequirements); + + + /** + * @brief Allocates resources as specified in ResourceRequirements object. + * + * The ResourceContainer object can be used in cooperative computation algorithms. + * + * The same @a requirements object can be passed to many resource allocations + * (with or without modifications) and can be deleted immediately, without waiting + * for the ResourceContainer object destruction. + * + * Use @c dResourceContainerDestroy to delete the object and release the resources + * when they are no longer needed. + * + * @param requirements The ResourceRequirements object to allocate resources according to + * @returns A ResourceContainer object instance with the resources allocated or NULL if allocation fails + * @ingroup coop + * @see dResourceContainerDestroy + * @see dResourceRequirementsCreate + */ +ODE_API dResourceContainerID dResourceContainerAcquire(/*const */dResourceRequirementsID requirements); + + /** + * @brief Destroys ResourceContainer object and releases resources allocated in it. + * + * @param resources A ResourceContainer object to be deleted (NULL is allowed) + * @ingroup coop + * @see dResourceContainerAcquire + */ +ODE_API void dResourceContainerDestroy(dResourceContainerID resources); + + +#ifdef __cplusplus +} // extern "C" +#endif + + +#endif // #ifndef _ODE_COOPERATIVE_H_ diff --git a/libs/ode-0.16.1/include/ode/error.h b/libs/ode-0.16.1/include/ode/error.h new file mode 100644 index 0000000..ae511e7 --- /dev/null +++ b/libs/ode-0.16.1/include/ode/error.h @@ -0,0 +1,63 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* this comes from the `reuse' library. copy any changes back to the source */ + +#ifndef _ODE_ERROR_H_ +#define _ODE_ERROR_H_ + +#include <ode/odeconfig.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* all user defined error functions have this type. error and debug functions + * should not return. + */ +typedef void dMessageFunction (int errnum, const char *msg, va_list ap); + +/* set a new error, debug or warning handler. if fn is 0, the default handlers + * are used. + */ +ODE_API void dSetErrorHandler (dMessageFunction *fn); +ODE_API void dSetDebugHandler (dMessageFunction *fn); +ODE_API void dSetMessageHandler (dMessageFunction *fn); + +/* return the current error, debug or warning handler. if the return value is + * 0, the default handlers are in place. + */ +ODE_API dMessageFunction *dGetErrorHandler(void); +ODE_API dMessageFunction *dGetDebugHandler(void); +ODE_API dMessageFunction *dGetMessageHandler(void); + +/* generate a fatal error, debug trap or a message. */ +ODE_API void ODE_NORETURN dError (int num, const char *msg, ...); +ODE_API void ODE_NORETURN dDebug (int num, const char *msg, ...); +ODE_API void dMessage (int num, const char *msg, ...); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/ode-0.16.1/include/ode/export-dif.h b/libs/ode-0.16.1/include/ode/export-dif.h new file mode 100644 index 0000000..f6578ac --- /dev/null +++ b/libs/ode-0.16.1/include/ode/export-dif.h @@ -0,0 +1,40 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_EXPORT_DIF_ +#define _ODE_EXPORT_DIF_ + +#include <ode/common.h> + + +#ifdef __cplusplus +extern "C" { +#endif + +ODE_API void dWorldExportDIF (dWorldID w, FILE *file, const char *world_name); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/ode-0.16.1/include/ode/mass.h b/libs/ode-0.16.1/include/ode/mass.h new file mode 100644 index 0000000..af89cb1 --- /dev/null +++ b/libs/ode-0.16.1/include/ode/mass.h @@ -0,0 +1,144 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_MASS_H_ +#define _ODE_MASS_H_ + +#include <ode/common.h> + +#ifdef __cplusplus +extern "C" { +#endif + +struct dMass; +typedef struct dMass dMass; + +/** + * Check if a mass structure has valid value. + * The function check if the mass and innertia matrix are positive definits + * + * @param m A mass structure to check + * + * @return 1 if both codition are met + */ +ODE_API int dMassCheck(const dMass *m); + +ODE_API void dMassSetZero (dMass *); + +ODE_API void dMassSetParameters (dMass *, dReal themass, + dReal cgx, dReal cgy, dReal cgz, + dReal I11, dReal I22, dReal I33, + dReal I12, dReal I13, dReal I23); + +ODE_API void dMassSetSphere (dMass *, dReal density, dReal radius); +ODE_API void dMassSetSphereTotal (dMass *, dReal total_mass, dReal radius); + +ODE_API void dMassSetCapsule (dMass *, dReal density, int direction, + dReal radius, dReal length); +ODE_API void dMassSetCapsuleTotal (dMass *, dReal total_mass, int direction, + dReal radius, dReal length); + +ODE_API void dMassSetCylinder (dMass *, dReal density, int direction, + dReal radius, dReal length); +ODE_API void dMassSetCylinderTotal (dMass *, dReal total_mass, int direction, + dReal radius, dReal length); + +ODE_API void dMassSetBox (dMass *, dReal density, + dReal lx, dReal ly, dReal lz); +ODE_API void dMassSetBoxTotal (dMass *, dReal total_mass, + dReal lx, dReal ly, dReal lz); + +ODE_API void dMassSetTrimesh (dMass *, dReal density, dGeomID g); + +ODE_API void dMassSetTrimeshTotal (dMass *m, dReal total_mass, dGeomID g); + +ODE_API void dMassAdjust (dMass *, dReal newmass); + +ODE_API void dMassTranslate (dMass *, dReal x, dReal y, dReal z); + +ODE_API void dMassRotate (dMass *, const dMatrix3 R); + +ODE_API void dMassAdd (dMass *a, const dMass *b); + + +/* Backwards compatible API */ +ODE_API_DEPRECATED ODE_API void dMassSetCappedCylinder(dMass *a, dReal b, int c, dReal d, dReal e); +ODE_API_DEPRECATED ODE_API void dMassSetCappedCylinderTotal(dMass *a, dReal b, int c, dReal d, dReal e); + + +struct dMass { + dReal mass; + dVector3 c; + dMatrix3 I; + +#ifdef __cplusplus + dMass() + { dMassSetZero (this); } + void setZero() + { dMassSetZero (this); } + void setParameters (dReal themass, dReal cgx, dReal cgy, dReal cgz, + dReal I11, dReal I22, dReal I33, + dReal I12, dReal I13, dReal I23) + { dMassSetParameters (this,themass,cgx,cgy,cgz,I11,I22,I33,I12,I13,I23); } + + void setSphere (dReal density, dReal radius) + { dMassSetSphere (this,density,radius); } + void setSphereTotal (dReal total, dReal radius) + { dMassSetSphereTotal (this,total,radius); } + + void setCapsule (dReal density, int direction, dReal radius, dReal length) + { dMassSetCapsule (this,density,direction,radius,length); } + void setCapsuleTotal (dReal total, int direction, dReal radius, dReal length) + { dMassSetCapsule (this,total,direction,radius,length); } + + void setCylinder(dReal density, int direction, dReal radius, dReal length) + { dMassSetCylinder (this,density,direction,radius,length); } + void setCylinderTotal(dReal total, int direction, dReal radius, dReal length) + { dMassSetCylinderTotal (this,total,direction,radius,length); } + + void setBox (dReal density, dReal lx, dReal ly, dReal lz) + { dMassSetBox (this,density,lx,ly,lz); } + void setBoxTotal (dReal total, dReal lx, dReal ly, dReal lz) + { dMassSetBoxTotal (this,total,lx,ly,lz); } + + void setTrimesh(dReal density, dGeomID g) + { dMassSetTrimesh (this, density, g); } + void setTrimeshTotal(dReal total, dGeomID g) + { dMassSetTrimeshTotal (this, total, g); } + + void adjust (dReal newmass) + { dMassAdjust (this,newmass); } + void translate (dReal x, dReal y, dReal z) + { dMassTranslate (this,x,y,z); } + void rotate (const dMatrix3 R) + { dMassRotate (this,R); } + void add (const dMass *b) + { dMassAdd (this,b); } +#endif +}; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/ode-0.16.1/include/ode/matrix.h b/libs/ode-0.16.1/include/ode/matrix.h new file mode 100644 index 0000000..65939b4 --- /dev/null +++ b/libs/ode-0.16.1/include/ode/matrix.h @@ -0,0 +1,200 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* optimized and unoptimized vector and matrix functions */ + +#ifndef _ODE_MATRIX_H_ +#define _ODE_MATRIX_H_ + +#include <ode/common.h> + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* set a vector/matrix of size n to all zeros, or to a specific value. */ + +ODE_API void dSetZero (dReal *a, int n); +ODE_API void dSetValue (dReal *a, int n, dReal value); + + +/* get the dot product of two n*1 vectors. if n <= 0 then + * zero will be returned (in which case a and b need not be valid). + */ + +ODE_API dReal dDot (const dReal *a, const dReal *b, int n); + + +/* get the dot products of (a0,b), (a1,b), etc and return them in outsum. + * all vectors are n*1. if n <= 0 then zeroes will be returned (in which case + * the input vectors need not be valid). this function is somewhat faster + * than calling dDot() for all of the combinations separately. + */ + +/* NOT INCLUDED in the library for now. +void dMultidot2 (const dReal *a0, const dReal *a1, + const dReal *b, dReal *outsum, int n); +*/ + + +/* matrix multiplication. all matrices are stored in standard row format. + * the digit refers to the argument that is transposed: + * 0: A = B * C (sizes: A:p*r B:p*q C:q*r) + * 1: A = B' * C (sizes: A:p*r B:q*p C:q*r) + * 2: A = B * C' (sizes: A:p*r B:p*q C:r*q) + * case 1,2 are equivalent to saying that the operation is A=B*C but + * B or C are stored in standard column format. + */ + +ODE_API void dMultiply0 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r); +ODE_API void dMultiply1 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r); +ODE_API void dMultiply2 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r); + + +/* do an in-place cholesky decomposition on the lower triangle of the n*n + * symmetric matrix A (which is stored by rows). the resulting lower triangle + * will be such that L*L'=A. return 1 on success and 0 on failure (on failure + * the matrix is not positive definite). + */ + +ODE_API int dFactorCholesky (dReal *A, int n); + + +/* solve for x: L*L'*x = b, and put the result back into x. + * L is size n*n, b is size n*1. only the lower triangle of L is considered. + */ + +ODE_API void dSolveCholesky (const dReal *L, dReal *b, int n); + + +/* compute the inverse of the n*n positive definite matrix A and put it in + * Ainv. this is not especially fast. this returns 1 on success (A was + * positive definite) or 0 on failure (not PD). + */ + +ODE_API int dInvertPDMatrix (const dReal *A, dReal *Ainv, int n); + + +/* check whether an n*n matrix A is positive definite, return 1/0 (yes/no). + * positive definite means that x'*A*x > 0 for any x. this performs a + * cholesky decomposition of A. if the decomposition fails then the matrix + * is not positive definite. A is stored by rows. A is not altered. + */ + +ODE_API int dIsPositiveDefinite (const dReal *A, int n); + + +/* factorize a matrix A into L*D*L', where L is lower triangular with ones on + * the diagonal, and D is diagonal. + * A is an n*n matrix stored by rows, with a leading dimension of n rounded + * up to 4. L is written into the strict lower triangle of A (the ones are not + * written) and the reciprocal of the diagonal elements of D are written into + * d. + */ +ODE_API void dFactorLDLT (dReal *A, dReal *d, int n, int nskip); + + +/* solve L*x=b, where L is n*n lower triangular with ones on the diagonal, + * and x,b are n*1. b is overwritten with x. + * the leading dimension of L is `nskip'. + */ +ODE_API void dSolveL1 (const dReal *L, dReal *b, int n, int nskip); + + +/* solve L'*x=b, where L is n*n lower triangular with ones on the diagonal, + * and x,b are n*1. b is overwritten with x. + * the leading dimension of L is `nskip'. + */ +ODE_API void dSolveL1T (const dReal *L, dReal *b, int n, int nskip); + + +/* in matlab syntax: a(1:n) = a(1:n) .* d(1:n) + */ + +ODE_API void dScaleVector (dReal *a, const dReal *d, int n); + +/* The function is an alias for @c dScaleVector. + * It has been deprecated because of a wrong naming schema used. + */ +ODE_API_DEPRECATED ODE_API void dVectorScale (dReal *a, const dReal *d, int n); + + +/* given `L', a n*n lower triangular matrix with ones on the diagonal, + * and `d', a n*1 vector of the reciprocal diagonal elements of an n*n matrix + * D, solve L*D*L'*x=b where x,b are n*1. x overwrites b. + * the leading dimension of L is `nskip'. + */ + +ODE_API void dSolveLDLT (const dReal *L, const dReal *d, dReal *b, int n, int nskip); + + +/* given an L*D*L' factorization of an n*n matrix A, return the updated + * factorization L2*D2*L2' of A plus the following "top left" matrix: + * + * [ b a' ] <-- b is a[0] + * [ a 0 ] <-- a is a[1..n-1] + * + * - L has size n*n, its leading dimension is nskip. L is lower triangular + * with ones on the diagonal. only the lower triangle of L is referenced. + * - d has size n. d contains the reciprocal diagonal elements of D. + * - a has size n. + * the result is written into L, except that the left column of L and d[0] + * are not actually modified. see ldltaddTL.m for further comments. + */ +ODE_API void dLDLTAddTL (dReal *L, dReal *d, const dReal *a, int n, int nskip); + + +/* given an L*D*L' factorization of a permuted matrix A, produce a new + * factorization for row and column `r' removed. + * - A has size n1*n1, its leading dimension in nskip. A is symmetric and + * positive definite. only the lower triangle of A is referenced. + * A itself may actually be an array of row pointers. + * - L has size n2*n2, its leading dimension in nskip. L is lower triangular + * with ones on the diagonal. only the lower triangle of L is referenced. + * - d has size n2. d contains the reciprocal diagonal elements of D. + * - p is a permutation vector. it contains n2 indexes into A. each index + * must be in the range 0..n1-1. + * - r is the row/column of L to remove. + * the new L will be written within the old L, i.e. will have the same leading + * dimension. the last row and column of L, and the last element of d, are + * undefined on exit. + * + * a fast O(n^2) algorithm is used. see ldltremove.m for further comments. + */ +ODE_API void dLDLTRemove (dReal **A, const int *p, dReal *L, dReal *d, + int n1, int n2, int r, int nskip); + + +/* given an n*n matrix A (with leading dimension nskip), remove the r'th row + * and column by moving elements. the new matrix will have the same leading + * dimension. the last row and column of A are untouched on exit. + */ +ODE_API void dRemoveRowCol (dReal *A, int n, int nskip, int r); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/libs/ode-0.16.1/include/ode/matrix_coop.h b/libs/ode-0.16.1/include/ode/matrix_coop.h new file mode 100644 index 0000000..b38bf90 --- /dev/null +++ b/libs/ode-0.16.1/include/ode/matrix_coop.h @@ -0,0 +1,291 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_MATRIX_COOP_H_ +#define _ODE_MATRIX_COOP_H_ + + +#include <ode/common.h> +#include <ode/cooperative.h> +#include <ode/threading.h> + + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup matrix_coop Matrix Cooperative Algorithms + * + * Cooperative algorithms operating on matrices and vectors. + * + * @ingroup coop + */ + + +/** + * @brief Estimates resource requirements for a @c dCooperativelyFactorLDLT call + * + * The function updates the contents of @a requirements to also suffice for calling + * @c dCooperativelyFactorLDLT with the given parameters. + * + * Note: The requirements that could have already been in the @a requirements parameter + * are never decreased. + * + * @param requirements The ResourceRequirements object to update + * @param maximalAllowedThreadCount Maximal value of allowedThreadCount parameter that is going to be used + * @param maximalRowCount Maximal value of rowCount parameter that is going to be used + * @ingroup matrix_coop + * @see dCooperativelyFactorLDLT + * @see dResourceRequirementsCreate + */ +ODE_API void dEstimateCooperativelyFactorLDLTResourceRequirements(dResourceRequirementsID requirements, + unsigned maximalAllowedThreadCount, unsigned maximalRowCount); + +/** + * @brief Cooperatively factorizes a matrix `A' into L*D*L' + * + * The function factorizes a matrix `A' into L*D*L', where `L' is lower triangular with ones on + * the diagonal, and `D' is diagonal. + * @a A is a rowCount*rowCount matrix stored by rows, with a leading dimension of @a rowCount rounded + * up at least to 4 elements. `L; is written into the strict lower triangle of @a A + * (the ones are not written) and the reciprocal of the diagonal elements of `D' are written into @a d. + * + * The @a resources must have had been allocated from a ResourceRequirements object + * estimated in @c dEstimateCooperativelyFactorLDLTResourceRequirements. + * + * The operation is performed cooperatively by up to @a allowedThreadCount threads + * from thread pool available in @a resources. The threading must must not be simultaneously + * used (via other @c dResourceContainerID instances) in other calls that employ its features. + * + * @param resources The resources allocated for the function + * @param allowedThreadCount Maximum thread count to use (the actual thread count could be less, depending on other parameters) + * @param A The `A' matrix + * @param d The `d' vector + * @param rowCount The row count in @a A and @a d + * @param rowskip The actual number of elements to be added to skip to next row in @a A + * @ingroup matrix_coop + * @see dEstimateCooperativelyFactorLDLTResourceRequirements + * @see dResourceContainerAcquire + * @see dCooperativelySolveLDLT + */ +ODE_API void dCooperativelyFactorLDLT(dResourceContainerID resources, unsigned allowedThreadCount, + dReal *A, dReal *d, unsigned rowCount, unsigned rowSkip); + + +/** + * @brief Estimates resource requirements for a @c dCooperativelySolveLDLT call + * + * The function updates the contents of @a requirements to also suffice for calling + * @c dCooperativelySolveLDLT with the given parameters. + * + * Note: The requirements that could have already been in the @a requirements parameter + * are never decreased. + * + * @param requirements The ResourceRequirements object to update + * @param maximalAllowedThreadCount Maximal value of allowedThreadCount parameter that is going to be used + * @param maximalRowCount Maximal value of rowCount parameter that is going to be used + * @ingroup matrix_coop + * @see dCooperativelySolveLDLT + * @see dResourceRequirementsCreate + */ +ODE_API void dEstimateCooperativelySolveLDLTResourceRequirements(dResourceRequirementsID requirements, + unsigned maximalAllowedThreadCount, unsigned maximalRowCount); + +/** + * @brief Cooperatively solves L*D*L'*x=b + * + * Given `L', a rowCount*rowCount lower triangular matrix with ones on the diagonal, + * and `d', a rowCount*1 vector of the reciprocal diagonal elements of a rowCount*rowCount matrix + * D, the function solves L*D*L'*x=b where `x' and `b' are rowCount*1. + * The leading dimension of @a L is @a rowSkip. The resulting vector `x' overwrites @a b. + * + * The @a resources must have had been allocated from a ResourceRequirements object + * estimated in @c dEstimateCooperativelySolveLDLTResourceRequirements. + * + * The operation is performed cooperatively by up to @a allowedThreadCount threads + * from thread pool available in @a resources. The threading must must not be simultaneously + * used (via other @c dResourceContainerID instances) in other calls that employ its features. + * + * @param resources The resources allocated for the function + * @param allowedThreadCount Maximum thread count to use (the actual thread count could be less, depending on other parameters) + * @param L The `L' matrix + * @param d The `d' vector + * @param b The `b' vector; also the result is stored here + * @param rowCount The row count in @a L, @a d and @a b + * @param rowskip The actual number of elements to be added to skip to next row in @a L + * @ingroup matrix_coop + * @see dEstimateCooperativelySolveLDLTResourceRequirements + * @see dResourceContainerAcquire + * @see dCooperativelyFactorLDLT + */ +ODE_API void dCooperativelySolveLDLT(dResourceContainerID resources, unsigned allowedThreadCount, + const dReal *L, const dReal *d, dReal *b, unsigned rowCount, unsigned rowSkip); + + +/** + * @brief Estimates resource requirements for a @c dCooperativelySolveL1Straight call + * + * The function updates the contents of @a requirements to also suffice for calling + * @c dCooperativelySolveL1Straight with the given parameters. + * + * Note: The requirements that could have already been in the @a requirements parameter + * are never decreased. + * + * @param requirements The ResourceRequirements object to update + * @param maximalAllowedThreadCount Maximal value of allowedThreadCount parameter that is going to be used + * @param maximalRowCount Maximal value of rowCount parameter that is going to be used + * @ingroup matrix_coop + * @see dCooperativelySolveL1Straight + * @see dResourceRequirementsCreate + */ +ODE_API void dEstimateCooperativelySolveL1StraightResourceRequirements(dResourceRequirementsID requirements, + unsigned maximalAllowedThreadCount, unsigned maximalRowCount); + +/** + * @brief Cooperatively solves L*x=b + * + * The function solves L*x=b, where `L' is rowCount*rowCount lower triangular with ones on the diagonal, + * and `x', `b' are rowCount*1. The leading dimension of @a L is @a rowSkip. + * @a b is overwritten with `x'. + * + * The @a resources must have had been allocated from a ResourceRequirements object + * estimated in @c dEstimateCooperativelySolveL1StraightResourceRequirements. + * + * The operation is performed cooperatively by up to @a allowedThreadCount threads + * from thread pool available in @a resources. The threading must must not be simultaneously + * used (via other @c dResourceContainerID instances) in other calls that employ its features. + * + * @param resources The resources allocated for the function + * @param allowedThreadCount Maximum thread count to use (the actual thread count could be less, depending on other parameters) + * @param L The `L' matrix + * @param b The `b' vector; also the result is stored here + * @param rowCount The row count in @a L and @a b + * @param rowskip The actual number of elements to be added to skip to next row in @a L + * @ingroup matrix_coop + * @see dEstimateCooperativelySolveL1StraightResourceRequirements + * @see dResourceContainerAcquire + * @see dCooperativelyFactorLDLT + */ +ODE_API void dCooperativelySolveL1Straight(dResourceContainerID resources, unsigned allowedThreadCount, + const dReal *L, dReal *b, unsigned rowCount, unsigned rowSkip); + + +/** + * @brief Estimates resource requirements for a @c dCooperativelySolveL1Transposed call + * + * The function updates the contents of @a requirements to also suffice for calling + * @c dCooperativelySolveL1Transposed with the given parameters. + * + * Note: The requirements that could have already been in the @a requirements parameter + * are never decreased. + * + * @param requirements The ResourceRequirements object to update + * @param maximalAllowedThreadCount Maximal value of allowedThreadCount parameter that is going to be used + * @param maximalRowCount Maximal value of rowCount parameter that is going to be used + * @ingroup matrix_coop + * @see dCooperativelySolveL1Transposed + * @see dResourceRequirementsCreate + */ +ODE_API void dEstimateCooperativelySolveL1TransposedResourceRequirements(dResourceRequirementsID requirements, + unsigned maximalAllowedThreadCount, unsigned maximalRowCount); + +/** + * @brief Cooperatively solves L'*x=b + * + * The function solves L'*x=b, where `L' is rowCount*rowCount lower triangular with ones on the diagonal, + * and `x', b are rowCount*1. The leading dimension of @a L is @a rowSkip. + * @a b is overwritten with `x'. + * + * The @a resources must have had been allocated from a ResourceRequirements object + * estimated in @c dEstimateCooperativelySolveL1TransposedResourceRequirements. + * + * The operation is performed cooperatively by up to @a allowedThreadCount threads + * from thread pool available in @a resources. The threading must must not be simultaneously + * used (via other @c dResourceContainerID instances) in other calls that employ its features. + * + * @param resources The resources allocated for the function + * @param allowedThreadCount Maximum thread count to use (the actual thread count could be less, depending on other parameters) + * @param L The `L' matrix + * @param b The `b' vector; also the result is stored here + * @param rowCount The row count in @a L and @a b + * @param rowskip The actual number of elements to be added to skip to next row in @a L + * @ingroup matrix_coop + * @see dEstimateCooperativelySolveL1TransposedResourceRequirements + * @see dResourceContainerAcquire + * @see dCooperativelyFactorLDLT + */ +ODE_API void dCooperativelySolveL1Transposed(dResourceContainerID resources, unsigned allowedThreadCount, + const dReal *L, dReal *b, unsigned rowCount, unsigned rowSkip); + + +/** + * @brief Estimates resource requirements for a @c dCooperativelyScaleVector call + * + * The function updates the contents of @a requirements to also suffice for calling + * @c dCooperativelyScaleVector with the given parameters. + * + * Note: The requirements that could have already been in the @a requirements parameter + * are never decreased. + * + * @param requirements The ResourceRequirements object to update + * @param maximalAllowedThreadCount Maximal value of allowedThreadCount parameter that is going to be used + * @param maximalElementCount Maximal value of elementCount parameter that is going to be used + * @ingroup matrix_coop + * @see dCooperativelyScaleVector + * @see dResourceRequirementsCreate + */ +ODE_API void dEstimateCooperativelyScaleVectorResourceRequirements(dResourceRequirementsID requirements, + unsigned maximalAllowedThreadCount, unsigned maximalElementCount); + +/** + * @brief Multiplies elements of one vector by corresponding element of another one + * + * In matlab syntax, the operation performed is: dataVector(1:elementCount) = dataVector(1:elementCount) .* scaleVector(1:elementCount) + * + * The @a resources must have had been allocated from a ResourceRequirements object + * estimated in @c dEstimateCooperativelyScaleVectorResourceRequirements. + * + * The operation is performed cooperatively by up to @a allowedThreadCount threads + * from thread pool available in @a resources. The threading must must not be simultaneously + * used (via other @c dResourceContainerID instances) in other calls that employ its features. + * + * @param resources The resources allocated for the function + * @param allowedThreadCount Maximum thread count to use (the actual thread count could be less, depending on other parameters) + * @param dataVector The vector to be scaled in place + * @param scaleVector The scale vector + * @param elementCount The number of elements in @a dataVector and @a scaleVector + * @ingroup matrix_coop + * @see dEstimateCooperativelyScaleVectorResourceRequirements + * @see dResourceContainerAcquire + * @see dCooperativelyFactorLDLT + */ +ODE_API void dCooperativelyScaleVector(dResourceContainerID resources, unsigned allowedThreadCount, + dReal *dataVector, const dReal *scaleVector, unsigned elementCount); + + +#ifdef __cplusplus +} // extern "C" +#endif + + +#endif // #ifndef _ODE_MATRIX_COOP_H_ diff --git a/libs/ode-0.16.1/include/ode/memory.h b/libs/ode-0.16.1/include/ode/memory.h new file mode 100644 index 0000000..8e49202 --- /dev/null +++ b/libs/ode-0.16.1/include/ode/memory.h @@ -0,0 +1,59 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* this comes from the `reuse' library. copy any changes back to the source */ + +#ifndef _ODE_MEMORY_H_ +#define _ODE_MEMORY_H_ + +#include <ode/odeconfig.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* function types to allocate and free memory */ +typedef void * dAllocFunction (dsizeint size); +typedef void * dReallocFunction (void *ptr, dsizeint oldsize, dsizeint newsize); +typedef void dFreeFunction (void *ptr, dsizeint size); + +/* set new memory management functions. if fn is 0, the default handlers are + * used. */ +ODE_API void dSetAllocHandler (dAllocFunction *fn); +ODE_API void dSetReallocHandler (dReallocFunction *fn); +ODE_API void dSetFreeHandler (dFreeFunction *fn); + +/* get current memory management functions */ +ODE_API dAllocFunction *dGetAllocHandler (void); +ODE_API dReallocFunction *dGetReallocHandler (void); +ODE_API dFreeFunction *dGetFreeHandler (void); + +/* allocate and free memory. */ +ODE_API void * dAlloc (dsizeint size); +ODE_API void * dRealloc (void *ptr, dsizeint oldsize, dsizeint newsize); +ODE_API void dFree (void *ptr, dsizeint size); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/ode-0.16.1/include/ode/misc.h b/libs/ode-0.16.1/include/ode/misc.h new file mode 100644 index 0000000..01655ea --- /dev/null +++ b/libs/ode-0.16.1/include/ode/misc.h @@ -0,0 +1,86 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* miscellaneous math functions. these are mostly useful for testing */ + +#ifndef _ODE_MISC_H_ +#define _ODE_MISC_H_ + +#include <ode/common.h> + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* return 1 if the random number generator is working. */ +ODE_API int dTestRand(void); + +/* return next 32 bit random number. this uses a not-very-random linear + * congruential method. + */ +ODE_API unsigned long dRand(void); + +/* get and set the current random number seed. */ +ODE_API unsigned long dRandGetSeed(void); +ODE_API void dRandSetSeed (unsigned long s); + +/* return a random integer between 0..n-1. the distribution will get worse + * as n approaches 2^32. + */ +ODE_API int dRandInt (int n); + +/* return a random real number between 0..1 */ +ODE_API dReal dRandReal(void); + +/* print out a matrix */ +ODE_API void dPrintMatrix (const dReal *A, int n, int m, const char *fmt, FILE *f); + +/* make a random vector with entries between +/- range. A has n elements. */ +ODE_API void dMakeRandomVector (dReal *A, int n, dReal range); + +/* make a random matrix with entries between +/- range. A has size n*m. */ +ODE_API void dMakeRandomMatrix (dReal *A, int n, int m, dReal range); + +/* clear the upper triangle of a square matrix */ +ODE_API void dClearUpperTriangle (dReal *A, int n); + +/* return the maximum element difference between the two n*m matrices */ +ODE_API dReal dMaxDifference (const dReal *A, const dReal *B, int n, int m); + +/* return the maximum element difference between the lower triangle of two + * n*n matrices */ +ODE_API dReal dMaxDifferenceLowerTriangle (const dReal *A, const dReal *B, int n); + + +#ifdef __cplusplus +} +#endif + + +#ifdef __cplusplus +static inline void dPrintMatrix (const dReal *A, int n, int m, const char *fmt="%10.4f ") { dPrintMatrix(A, n, m, fmt, stdout); } +#endif + + +#endif diff --git a/libs/ode-0.16.1/include/ode/objects.h b/libs/ode-0.16.1/include/ode/objects.h new file mode 100644 index 0000000..4796d56 --- /dev/null +++ b/libs/ode-0.16.1/include/ode/objects.h @@ -0,0 +1,3396 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_OBJECTS_H_ +#define _ODE_OBJECTS_H_ + +#include <ode/common.h> +#include <ode/mass.h> +#include <ode/contact.h> +#include <ode/threading.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup world World + * + * The world object is a container for rigid bodies and joints. Objects in + * different worlds can not interact, for example rigid bodies from two + * different worlds can not collide. + * + * All the objects in a world exist at the same point in time, thus one + * reason to use separate worlds is to simulate systems at different rates. + * Most applications will only need one world. + */ + +/** + * @brief Create a new, empty world and return its ID number. + * @return an identifier + * @ingroup world + */ +ODE_API dWorldID dWorldCreate(void); + + +/** + * @brief Destroy a world and everything in it. + * + * This includes all bodies, and all joints that are not part of a joint + * group. Joints that are part of a joint group will be deactivated, and + * can be destroyed by calling, for example, dJointGroupEmpty(). + * @ingroup world + * @param world the identifier for the world the be destroyed. + */ +ODE_API void dWorldDestroy (dWorldID world); + + +/** + * @brief Set the user-data pointer + * @param world the world to set the data on + * @param data + * @ingroup world + */ +ODE_API void dWorldSetData (dWorldID world, void* data); + + +/** + * @brief Get the user-data pointer + * @param world the world to set the data on + * @param data + * @ingroup world + */ +ODE_API void* dWorldGetData (dWorldID world); + + +/** + * @brief Set the world's global gravity vector. + * + * The units are m/s^2, so Earth's gravity vector would be (0,0,-9.81), + * assuming that +z is up. The default is no gravity, i.e. (0,0,0). + * + * @ingroup world + */ +ODE_API void dWorldSetGravity (dWorldID, dReal x, dReal y, dReal z); + + +/** + * @brief Get the gravity vector for a given world. + * @ingroup world + */ +ODE_API void dWorldGetGravity (dWorldID, dVector3 gravity); + + +/** + * @brief Set the global ERP value, that controls how much error + * correction is performed in each time step. + * @ingroup world + * @param dWorldID the identifier of the world. + * @param erp Typical values are in the range 0.1--0.8. The default is 0.2. + */ +ODE_API void dWorldSetERP (dWorldID, dReal erp); + +/** + * @brief Get the error reduction parameter. + * @ingroup world + * @return ERP value + */ +ODE_API dReal dWorldGetERP (dWorldID); + + +/** + * @brief Set the global CFM (constraint force mixing) value. + * @ingroup world + * @param cfm Typical values are in the range @m{10^{-9}} -- 1. + * The default is 10^-5 if single precision is being used, or 10^-10 + * if double precision is being used. + */ +ODE_API void dWorldSetCFM (dWorldID, dReal cfm); + +/** + * @brief Get the constraint force mixing value. + * @ingroup world + * @return CFM value + */ +ODE_API dReal dWorldGetCFM (dWorldID); + + +#define dWORLDSTEP_THREADCOUNT_UNLIMITED dTHREADING_THREAD_COUNT_UNLIMITED + +/** + * @brief Set maximum threads to be used for island stepping + * + * The actual number of threads that is going to be used will be the minimum + * of this limit and number of threads in the threading pool. By default + * there is no limit (@c dWORLDSTEP_THREADCOUNT_UNLIMITED). + * + * @warning + * WARNING! Running island stepping in multiple threads requires allocating + * individual stepping memory buffer for each of those threads. The size of buffers + * allocated is the size needed to handle the largest island in the world. + * + * Note: Setting a limit for island stepping does not affect threading at lower + * levels in stepper functions. The sub-calls scheduled from them can be executed + * in as many threads as there are available in the pool. + * + * @param w The world affected + * @param count Thread count limit value for island stepping + * @ingroup world + * @see dWorldGetStepIslandsProcessingMaxThreadCount + */ +ODE_API void dWorldSetStepIslandsProcessingMaxThreadCount(dWorldID w, unsigned count); +/** + * @brief Get maximum threads that are allowed to be used for island stepping. + * + * Please read commentaries to @c dWorldSetStepIslandsProcessingMaxThreadCount for + * important information regarding the value returned. + * + * @param w The world queried + * @returns Current thread count limit value for island stepping + * @ingroup world + * @see dWorldSetStepIslandsProcessingMaxThreadCount + */ +ODE_API unsigned dWorldGetStepIslandsProcessingMaxThreadCount(dWorldID w); + +/** + * @brief Set the world to use shared working memory along with another world. + * + * The worlds allocate working memory internally for simulation stepping. This + * memory is cached among the calls to @c dWordStep and @c dWorldQuickStep. + * Similarly, several worlds can be set up to share this memory caches thus + * reducing overall memory usage by cost of making worlds inappropriate for + * simultaneous simulation in multiple threads. + * + * If null value is passed for @a from_world parameter the world is detached from + * sharing and returns to defaults for working memory, reservation policy and + * memory manager as if just created. This can also be used to enable use of shared + * memory for a world that has already had working memory allocated privately. + * Normally using shared memory after a world has its private working memory allocated + * is prohibited. + * + * Allocation policy used can only increase world's internal reserved memory size + * and never decreases it. @c dWorldCleanupWorkingMemory can be used to release + * working memory for a world in case if number of objects/joint decreases + * significantly in it. + * + * With sharing working memory worlds also automatically share memory reservation + * policy and memory manager. Thus, these parameters need to be customized for + * initial world to be used as sharing source only. + * + * If worlds share working memory they must also use compatible threading implementations + * (i.e. it is illegal for one world to perform stepping with self-threaded implementation + * when the other world is assigned a multi-threaded implementation). + * For more information read section about threading approaches in ODE. + * + * Failure result status means a memory allocation failure. + * + * @param w The world to use the shared memory with. + * @param from_world Null or the world the shared memory is to be used from. + * @returns 1 for success and 0 for failure. + * + * @ingroup world + * @see dWorldCleanupWorkingMemory + * @see dWorldSetStepMemoryReservationPolicy + * @see dWorldSetStepMemoryManager + */ +ODE_API int dWorldUseSharedWorkingMemory(dWorldID w, dWorldID from_world/*=NULL*/); + +/** + * @brief Release internal working memory allocated for world + * + * The worlds allocate working memory internally for simulation stepping. This + * function can be used to free world's internal memory cache in case if number of + * objects/joints in the world decreases significantly. By default, internal + * allocation policy is used to only increase cache size as necessary and never + * decrease it. + * + * If a world shares its working memory with other worlds the cache deletion + * affects all the linked worlds. However the shared status itself remains intact. + * + * The function call does affect neither memory reservation policy nor memory manager. + * + * @param w The world to release working memory for. + * + * @ingroup world + * @see dWorldUseSharedWorkingMemory + * @see dWorldSetStepMemoryReservationPolicy + * @see dWorldSetStepMemoryManager + */ +ODE_API void dWorldCleanupWorkingMemory(dWorldID w); + + +#define dWORLDSTEP_RESERVEFACTOR_DEFAULT 1.2f +#define dWORLDSTEP_RESERVESIZE_DEFAULT 65536U + +/** + * @struct dWorldStepReserveInfo + * @brief Memory reservation policy descriptor structure for world stepping functions. + * + * @c struct_size should be assigned the size of the structure. + * + * @c reserve_factor is a quotient that is multiplied by required memory size + * to allocate extra reserve whenever reallocation is needed. + * + * @c reserve_minimum is a minimum size that is checked against whenever reallocation + * is needed to allocate expected working memory minimum at once without extra + * reallocations as number of bodies/joints grows. + * + * @ingroup world + * @see dWorldSetStepMemoryReservationPolicy + */ +typedef struct +{ + unsigned struct_size; + float reserve_factor; /* Use float as precision does not matter here*/ + unsigned reserve_minimum; + +} dWorldStepReserveInfo; + +/** + * @brief Set memory reservation policy for world to be used with simulation stepping functions + * + * The function allows to customize reservation policy to be used for internal + * memory which is allocated to aid simulation for a world. By default, values + * of @c dWORLDSTEP_RESERVEFACTOR_DEFAULT and @c dWORLDSTEP_RESERVESIZE_DEFAULT + * are used. + * + * Passing @a policyinfo argument as NULL results in reservation policy being + * reset to defaults as if the world has been just created. The content of + * @a policyinfo structure is copied internally and does not need to remain valid + * after the call returns. + * + * If the world uses working memory sharing, changing memory reservation policy + * affects all the worlds linked together. + * + * Failure result status means a memory allocation failure. + * + * @param w The world to change memory reservation policy for. + * @param policyinfo Null or a pointer to policy descriptor structure. + * @returns 1 for success and 0 for failure. + * + * @ingroup world + * @see dWorldUseSharedWorkingMemory + */ +ODE_API int dWorldSetStepMemoryReservationPolicy(dWorldID w, const dWorldStepReserveInfo *policyinfo/*=NULL*/); + +/** +* @struct dWorldStepMemoryFunctionsInfo +* @brief World stepping memory manager descriptor structure +* +* This structure is intended to define the functions of memory manager to be used +* with world stepping functions. +* +* @c struct_size should be assigned the size of the structure +* +* @c alloc_block is a function to allocate memory block of given size. +* +* @c shrink_block is a function to shrink existing memory block to a smaller size. +* It must preserve the contents of block head while shrinking. The new block size +* is guaranteed to be always less than the existing one. +* +* @c free_block is a function to delete existing memory block. +* +* @ingroup init +* @see dWorldSetStepMemoryManager +*/ +typedef struct +{ + unsigned struct_size; + void *(*alloc_block)(dsizeint block_size); + void *(*shrink_block)(void *block_pointer, dsizeint block_current_size, dsizeint block_smaller_size); + void (*free_block)(void *block_pointer, dsizeint block_current_size); + +} dWorldStepMemoryFunctionsInfo; + +/** +* @brief Set memory manager for world to be used with simulation stepping functions +* +* The function allows to customize memory manager to be used for internal +* memory allocation during simulation for a world. By default, @c dAlloc/@c dRealloc/@c dFree +* based memory manager is used. +* +* Passing @a memfuncs argument as NULL results in memory manager being +* reset to default one as if the world has been just created. The content of +* @a memfuncs structure is copied internally and does not need to remain valid +* after the call returns. +* +* If the world uses working memory sharing, changing memory manager +* affects all the worlds linked together. +* +* Failure result status means a memory allocation failure. +* +* @param w The world to change memory reservation policy for. +* @param memfuncs Null or a pointer to memory manager descriptor structure. +* @returns 1 for success and 0 for failure. +* +* @ingroup world +* @see dWorldUseSharedWorkingMemory +*/ +ODE_API int dWorldSetStepMemoryManager(dWorldID w, const dWorldStepMemoryFunctionsInfo *memfuncs); + +/** + * @brief Assign threading implementation to be used for [quick]stepping the world. + * + * @warning It is not recommended to assign the same threading implementation to + * different worlds if they are going to be called in parallel. In particular this + * makes resources preallocation for threaded calls to lose its sense. + * Built-in threading implementation is likely to crash if misused this way. + * + * @param w The world to change threading implementation for. + * @param functions_info Pointer to threading functions structure + * @param threading_impl ID of threading implementation object + * + * @ingroup world + */ +ODE_API void dWorldSetStepThreadingImplementation(dWorldID w, const dThreadingFunctionsInfo *functions_info, dThreadingImplementationID threading_impl); + +/** + * @brief Step the world. + * + * This uses a "big matrix" method that takes time on the order of m^3 + * and memory on the order of m^2, where m is the total number of constraint + * rows. For large systems this will use a lot of memory and can be very slow, + * but this is currently the most accurate method. + * + * Failure result status means that the memory allocation has failed for operation. + * In such a case all the objects remain in unchanged state and simulation can be + * retried as soon as more memory is available. + * + * @param w The world to be stepped + * @param stepsize The number of seconds that the simulation has to advance. + * @returns 1 for success and 0 for failure + * + * @ingroup world + */ +ODE_API int dWorldStep (dWorldID w, dReal stepsize); + +/** + * @brief Quick-step the world. + * + * This uses an iterative method that takes time on the order of m*N + * and memory on the order of m, where m is the total number of constraint + * rows N is the number of iterations. + * For large systems this is a lot faster than dWorldStep(), + * but it is less accurate. + * + * QuickStep is great for stacks of objects especially when the + * auto-disable feature is used as well. + * However, it has poor accuracy for near-singular systems. + * Near-singular systems can occur when using high-friction contacts, motors, + * or certain articulated structures. For example, a robot with multiple legs + * sitting on the ground may be near-singular. + * + * There are ways to help overcome QuickStep's inaccuracy problems: + * + * \li Increase CFM. + * \li Reduce the number of contacts in your system (e.g. use the minimum + * number of contacts for the feet of a robot or creature). + * \li Don't use excessive friction in the contacts. + * \li Use contact slip if appropriate + * \li Avoid kinematic loops (however, kinematic loops are inevitable in + * legged creatures). + * \li Don't use excessive motor strength. + * \liUse force-based motors instead of velocity-based motors. + * + * Increasing the number of QuickStep iterations may help a little bit, but + * it is not going to help much if your system is really near singular. + * + * Failure result status means that the memory allocation has failed for operation. + * In such a case all the objects remain in unchanged state and simulation can be + * retried as soon as more memory is available. + * + * @param w The world to be stepped + * @param stepsize The number of seconds that the simulation has to advance. + * @returns 1 for success and 0 for failure + * + * @ingroup world + */ +ODE_API int dWorldQuickStep (dWorldID w, dReal stepsize); + + +/** +* @brief Converts an impulse to a force. +* @ingroup world +* @remarks +* If you want to apply a linear or angular impulse to a rigid body, +* instead of a force or a torque, then you can use this function to convert +* the desired impulse into a force/torque vector before calling the +* BodyAdd... function. +* The current algorithm simply scales the impulse by 1/stepsize, +* where stepsize is the step size for the next step that will be taken. +* This function is given a dWorldID because, in the future, the force +* computation may depend on integrator parameters that are set as +* properties of the world. +*/ +ODE_API void dWorldImpulseToForce +( + dWorldID, dReal stepsize, + dReal ix, dReal iy, dReal iz, dVector3 force + ); + + +/** + * @brief Set the number of iterations that the QuickStep method performs per + * step. + * @ingroup world + * @remarks + * More iterations will give a more accurate solution, but will take + * longer to compute. + * @param num The default is 20 iterations. + */ +ODE_API void dWorldSetQuickStepNumIterations (dWorldID, int num); + + +/** + * @brief Get the number of iterations that the QuickStep method performs per + * step. + * @ingroup world + * @return nr of iterations + */ +ODE_API int dWorldGetQuickStepNumIterations (dWorldID); + +/** + * @brief Set the SOR over-relaxation parameter + * @ingroup world + * @param over_relaxation value to use by SOR + */ +ODE_API void dWorldSetQuickStepW (dWorldID, dReal over_relaxation); + +/** + * @brief Get the SOR over-relaxation parameter + * @ingroup world + * @returns the over-relaxation setting + */ +ODE_API dReal dWorldGetQuickStepW (dWorldID); + +/* World contact parameter functions */ + +/** + * @brief Set the maximum correcting velocity that contacts are allowed + * to generate. + * @ingroup world + * @param vel The default value is infinity (i.e. no limit). + * @remarks + * Reducing this value can help prevent "popping" of deeply embedded objects. + */ +ODE_API void dWorldSetContactMaxCorrectingVel (dWorldID, dReal vel); + +/** + * @brief Get the maximum correcting velocity that contacts are allowed + * to generated. + * @ingroup world + */ +ODE_API dReal dWorldGetContactMaxCorrectingVel (dWorldID); + +/** + * @brief Set the depth of the surface layer around all geometry objects. + * @ingroup world + * @remarks + * Contacts are allowed to sink into the surface layer up to the given + * depth before coming to rest. + * @param depth The default value is zero. + * @remarks + * Increasing this to some small value (e.g. 0.001) can help prevent + * jittering problems due to contacts being repeatedly made and broken. + */ +ODE_API void dWorldSetContactSurfaceLayer (dWorldID, dReal depth); + +/** + * @brief Get the depth of the surface layer around all geometry objects. + * @ingroup world + * @returns the depth + */ +ODE_API dReal dWorldGetContactSurfaceLayer (dWorldID); + + +/** + * @defgroup disable Automatic Enabling and Disabling + * @ingroup world bodies + * + * Every body can be enabled or disabled. Enabled bodies participate in the + * simulation, while disabled bodies are turned off and do not get updated + * during a simulation step. New bodies are always created in the enabled state. + * + * A disabled body that is connected through a joint to an enabled body will be + * automatically re-enabled at the next simulation step. + * + * Disabled bodies do not consume CPU time, therefore to speed up the simulation + * bodies should be disabled when they come to rest. This can be done automatically + * with the auto-disable feature. + * + * If a body has its auto-disable flag turned on, it will automatically disable + * itself when + * @li It has been idle for a given number of simulation steps. + * @li It has also been idle for a given amount of simulation time. + * + * A body is considered to be idle when the magnitudes of both its + * linear average velocity and angular average velocity are below given thresholds. + * The sample size for the average defaults to one and can be disabled by setting + * to zero with + * + * Thus, every body has six auto-disable parameters: an enabled flag, a idle step + * count, an idle time, linear/angular average velocity thresholds, and the + * average samples count. + * + * Newly created bodies get these parameters from world. + */ + +/** + * @brief Get auto disable linear average threshold for newly created bodies. + * @ingroup disable + * @return the threshold + */ +ODE_API dReal dWorldGetAutoDisableLinearThreshold (dWorldID); + +/** + * @brief Set auto disable linear average threshold for newly created bodies. + * @param linear_average_threshold default is 0.01 + * @ingroup disable + */ +ODE_API void dWorldSetAutoDisableLinearThreshold (dWorldID, dReal linear_average_threshold); + +/** + * @brief Get auto disable angular average threshold for newly created bodies. + * @ingroup disable + * @return the threshold + */ +ODE_API dReal dWorldGetAutoDisableAngularThreshold (dWorldID); + +/** + * @brief Set auto disable angular average threshold for newly created bodies. + * @param linear_average_threshold default is 0.01 + * @ingroup disable + */ +ODE_API void dWorldSetAutoDisableAngularThreshold (dWorldID, dReal angular_average_threshold); + +/** + * @brief Get auto disable sample count for newly created bodies. + * @ingroup disable + * @return number of samples used + */ +ODE_API int dWorldGetAutoDisableAverageSamplesCount (dWorldID); + +/** + * @brief Set auto disable average sample count for newly created bodies. + * @ingroup disable + * @param average_samples_count Default is 1, meaning only instantaneous velocity is used. + * Set to zero to disable sampling and thus prevent any body from auto-disabling. + */ +ODE_API void dWorldSetAutoDisableAverageSamplesCount (dWorldID, unsigned int average_samples_count ); + +/** + * @brief Get auto disable steps for newly created bodies. + * @ingroup disable + * @return nr of steps + */ +ODE_API int dWorldGetAutoDisableSteps (dWorldID); + +/** + * @brief Set auto disable steps for newly created bodies. + * @ingroup disable + * @param steps default is 10 + */ +ODE_API void dWorldSetAutoDisableSteps (dWorldID, int steps); + +/** + * @brief Get auto disable time for newly created bodies. + * @ingroup disable + * @return nr of seconds + */ +ODE_API dReal dWorldGetAutoDisableTime (dWorldID); + +/** + * @brief Set auto disable time for newly created bodies. + * @ingroup disable + * @param time default is 0 seconds + */ +ODE_API void dWorldSetAutoDisableTime (dWorldID, dReal time); + +/** + * @brief Get auto disable flag for newly created bodies. + * @ingroup disable + * @return 0 or 1 + */ +ODE_API int dWorldGetAutoDisableFlag (dWorldID); + +/** + * @brief Set auto disable flag for newly created bodies. + * @ingroup disable + * @param do_auto_disable default is false. + */ +ODE_API void dWorldSetAutoDisableFlag (dWorldID, int do_auto_disable); + + +/** + * @defgroup damping Damping + * @ingroup bodies world + * + * Damping serves two purposes: reduce simulation instability, and to allow + * the bodies to come to rest (and possibly auto-disabling them). + * + * Bodies are constructed using the world's current damping parameters. Setting + * the scales to 0 disables the damping. + * + * Here is how it is done: after every time step linear and angular + * velocities are tested against the corresponding thresholds. If they + * are above, they are multiplied by (1 - scale). So a negative scale value + * will actually increase the speed, and values greater than one will + * make the object oscillate every step; both can make the simulation unstable. + * + * To disable damping just set the damping scale to zero. + * + * You can also limit the maximum angular velocity. In contrast to the damping + * functions, the angular velocity is affected before the body is moved. + * This means that it will introduce errors in joints that are forcing the body + * to rotate too fast. Some bodies have naturally high angular velocities + * (like cars' wheels), so you may want to give them a very high (like the default, + * dInfinity) limit. + * + * @note The velocities are damped after the stepper function has moved the + * object. Otherwise the damping could introduce errors in joints. First the + * joint constraints are processed by the stepper (moving the body), then + * the damping is applied. + * + * @note The damping happens right after the moved callback is called; this way + * it still possible use the exact velocities the body has acquired during the + * step. You can even use the callback to create your own customized damping. + */ + +/** + * @brief Get the world's linear damping threshold. + * @ingroup damping + */ +ODE_API dReal dWorldGetLinearDampingThreshold (dWorldID w); + +/** + * @brief Set the world's linear damping threshold. + * @param threshold The damping won't be applied if the linear speed is + * below this threshold. Default is 0.01. + * @ingroup damping + */ +ODE_API void dWorldSetLinearDampingThreshold(dWorldID w, dReal threshold); + +/** + * @brief Get the world's angular damping threshold. + * @ingroup damping + */ +ODE_API dReal dWorldGetAngularDampingThreshold (dWorldID w); + +/** + * @brief Set the world's angular damping threshold. + * @param threshold The damping won't be applied if the angular speed is + * below this threshold. Default is 0.01. + * @ingroup damping + */ +ODE_API void dWorldSetAngularDampingThreshold(dWorldID w, dReal threshold); + +/** + * @brief Get the world's linear damping scale. + * @ingroup damping + */ +ODE_API dReal dWorldGetLinearDamping (dWorldID w); + +/** + * @brief Set the world's linear damping scale. + * @param scale The linear damping scale that is to be applied to bodies. + * Default is 0 (no damping). Should be in the interval [0, 1]. + * @ingroup damping + */ +ODE_API void dWorldSetLinearDamping (dWorldID w, dReal scale); + +/** + * @brief Get the world's angular damping scale. + * @ingroup damping + */ +ODE_API dReal dWorldGetAngularDamping (dWorldID w); + +/** + * @brief Set the world's angular damping scale. + * @param scale The angular damping scale that is to be applied to bodies. + * Default is 0 (no damping). Should be in the interval [0, 1]. + * @ingroup damping + */ +ODE_API void dWorldSetAngularDamping(dWorldID w, dReal scale); + +/** + * @brief Convenience function to set body linear and angular scales. + * @param linear_scale The linear damping scale that is to be applied to bodies. + * @param angular_scale The angular damping scale that is to be applied to bodies. + * @ingroup damping + */ +ODE_API void dWorldSetDamping(dWorldID w, + dReal linear_scale, + dReal angular_scale); + +/** + * @brief Get the default maximum angular speed. + * @ingroup damping + * @sa dBodyGetMaxAngularSpeed() + */ +ODE_API dReal dWorldGetMaxAngularSpeed (dWorldID w); + + +/** + * @brief Set the default maximum angular speed for new bodies. + * @ingroup damping + * @sa dBodySetMaxAngularSpeed() + */ +ODE_API void dWorldSetMaxAngularSpeed (dWorldID w, dReal max_speed); + + + +/** + * @defgroup bodies Rigid Bodies + * + * A rigid body has various properties from the point of view of the + * simulation. Some properties change over time: + * + * @li Position vector (x,y,z) of the body's point of reference. + * Currently the point of reference must correspond to the body's center of mass. + * @li Linear velocity of the point of reference, a vector (vx,vy,vz). + * @li Orientation of a body, represented by a quaternion (qs,qx,qy,qz) or + * a 3x3 rotation matrix. + * @li Angular velocity vector (wx,wy,wz) which describes how the orientation + * changes over time. + * + * Other body properties are usually constant over time: + * + * @li Mass of the body. + * @li Position of the center of mass with respect to the point of reference. + * In the current implementation the center of mass and the point of + * reference must coincide. + * @li Inertia matrix. This is a 3x3 matrix that describes how the body's mass + * is distributed around the center of mass. Conceptually each body has an + * x-y-z coordinate frame embedded in it that moves and rotates with the body. + * + * The origin of this coordinate frame is the body's point of reference. Some values + * in ODE (vectors, matrices etc) are relative to the body coordinate frame, and others + * are relative to the global coordinate frame. + * + * Note that the shape of a rigid body is not a dynamical property (except insofar as + * it influences the various mass properties). It is only collision detection that cares + * about the detailed shape of the body. + */ + + +/** + * @brief Get auto disable linear average threshold. + * @ingroup bodies disable + * @return the threshold + */ +ODE_API dReal dBodyGetAutoDisableLinearThreshold (dBodyID); + +/** + * @brief Set auto disable linear average threshold. + * @ingroup bodies disable + * @return the threshold + */ +ODE_API void dBodySetAutoDisableLinearThreshold (dBodyID, dReal linear_average_threshold); + +/** + * @brief Get auto disable angular average threshold. + * @ingroup bodies disable + * @return the threshold + */ +ODE_API dReal dBodyGetAutoDisableAngularThreshold (dBodyID); + +/** + * @brief Set auto disable angular average threshold. + * @ingroup bodies disable + * @return the threshold + */ +ODE_API void dBodySetAutoDisableAngularThreshold (dBodyID, dReal angular_average_threshold); + +/** + * @brief Get auto disable average size (samples count). + * @ingroup bodies disable + * @return the nr of steps/size. + */ +ODE_API int dBodyGetAutoDisableAverageSamplesCount (dBodyID); + +/** + * @brief Set auto disable average buffer size (average steps). + * @ingroup bodies disable + * @param average_samples_count the nr of samples to review. + */ +ODE_API void dBodySetAutoDisableAverageSamplesCount (dBodyID, unsigned int average_samples_count); + + +/** + * @brief Get auto steps a body must be thought of as idle to disable + * @ingroup bodies disable + * @return the nr of steps + */ +ODE_API int dBodyGetAutoDisableSteps (dBodyID); + +/** + * @brief Set auto disable steps. + * @ingroup bodies disable + * @param steps the nr of steps. + */ +ODE_API void dBodySetAutoDisableSteps (dBodyID, int steps); + +/** + * @brief Get auto disable time. + * @ingroup bodies disable + * @return nr of seconds + */ +ODE_API dReal dBodyGetAutoDisableTime (dBodyID); + +/** + * @brief Set auto disable time. + * @ingroup bodies disable + * @param time nr of seconds. + */ +ODE_API void dBodySetAutoDisableTime (dBodyID, dReal time); + +/** + * @brief Get auto disable flag. + * @ingroup bodies disable + * @return 0 or 1 + */ +ODE_API int dBodyGetAutoDisableFlag (dBodyID); + +/** + * @brief Set auto disable flag. + * @ingroup bodies disable + * @param do_auto_disable 0 or 1 + */ +ODE_API void dBodySetAutoDisableFlag (dBodyID, int do_auto_disable); + +/** + * @brief Set auto disable defaults. + * @remarks + * Set the values for the body to those set as default for the world. + * @ingroup bodies disable + */ +ODE_API void dBodySetAutoDisableDefaults (dBodyID); + + +/** + * @brief Retrieves the world attached to te given body. + * @remarks + * + * @ingroup bodies + */ +ODE_API dWorldID dBodyGetWorld (dBodyID); + +/** + * @brief Create a body in given world. + * @remarks + * Default mass parameters are at position (0,0,0). + * @ingroup bodies + */ +ODE_API dBodyID dBodyCreate (dWorldID); + +/** + * @brief Destroy a body. + * @remarks + * All joints that are attached to this body will be put into limbo: + * i.e. unattached and not affecting the simulation, but they will NOT be + * deleted. + * @ingroup bodies + */ +ODE_API void dBodyDestroy (dBodyID); + +/** + * @brief Set the body's user-data pointer. + * @ingroup bodies + * @param data arbitraty pointer + */ +ODE_API void dBodySetData (dBodyID, void *data); + +/** + * @brief Get the body's user-data pointer. + * @ingroup bodies + * @return a pointer to the user's data. + */ +ODE_API void *dBodyGetData (dBodyID); + +/** + * @brief Set position of a body. + * @remarks + * After setting, the outcome of the simulation is undefined + * if the new configuration is inconsistent with the joints/constraints + * that are present. + * @ingroup bodies + */ +ODE_API void dBodySetPosition (dBodyID, dReal x, dReal y, dReal z); + +/** + * @brief Set the orientation of a body. + * @ingroup bodies + * @remarks + * After setting, the outcome of the simulation is undefined + * if the new configuration is inconsistent with the joints/constraints + * that are present. + */ +ODE_API void dBodySetRotation (dBodyID, const dMatrix3 R); + +/** + * @brief Set the orientation of a body. + * @ingroup bodies + * @remarks + * After setting, the outcome of the simulation is undefined + * if the new configuration is inconsistent with the joints/constraints + * that are present. + */ +ODE_API void dBodySetQuaternion (dBodyID, const dQuaternion q); + +/** + * @brief Set the linear velocity of a body. + * @ingroup bodies + */ +ODE_API void dBodySetLinearVel (dBodyID, dReal x, dReal y, dReal z); + +/** + * @brief Set the angular velocity of a body. + * @ingroup bodies + */ +ODE_API void dBodySetAngularVel (dBodyID, dReal x, dReal y, dReal z); + +/** + * @brief Get the position of a body. + * @ingroup bodies + * @remarks + * When getting, the returned values are pointers to internal data structures, + * so the vectors are valid until any changes are made to the rigid body + * system structure. + * @sa dBodyCopyPosition + */ +ODE_API const dReal * dBodyGetPosition (dBodyID); + + +/** + * @brief Copy the position of a body into a vector. + * @ingroup bodies + * @param body the body to query + * @param pos a copy of the body position + * @sa dBodyGetPosition + */ +ODE_API void dBodyCopyPosition (dBodyID body, dVector3 pos); + + +/** + * @brief Get the rotation of a body. + * @ingroup bodies + * @return pointer to a 4x3 rotation matrix. + */ +ODE_API const dReal * dBodyGetRotation (dBodyID); + + +/** + * @brief Copy the rotation of a body. + * @ingroup bodies + * @param body the body to query + * @param R a copy of the rotation matrix + * @sa dBodyGetRotation + */ +ODE_API void dBodyCopyRotation (dBodyID, dMatrix3 R); + + +/** + * @brief Get the rotation of a body. + * @ingroup bodies + * @return pointer to 4 scalars that represent the quaternion. + */ +ODE_API const dReal * dBodyGetQuaternion (dBodyID); + + +/** + * @brief Copy the orientation of a body into a quaternion. + * @ingroup bodies + * @param body the body to query + * @param quat a copy of the orientation quaternion + * @sa dBodyGetQuaternion + */ +ODE_API void dBodyCopyQuaternion(dBodyID body, dQuaternion quat); + + +/** + * @brief Get the linear velocity of a body. + * @ingroup bodies + */ +ODE_API const dReal * dBodyGetLinearVel (dBodyID); + +/** + * @brief Get the angular velocity of a body. + * @ingroup bodies + */ +ODE_API const dReal * dBodyGetAngularVel (dBodyID); + +/** + * @brief Set the mass of a body. + * @ingroup bodies + */ +ODE_API void dBodySetMass (dBodyID, const dMass *mass); + +/** + * @brief Get the mass of a body. + * @ingroup bodies + */ +ODE_API void dBodyGetMass (dBodyID, dMass *mass); + +/** + * @brief Add force at centre of mass of body in absolute coordinates. + * @ingroup bodies + */ +ODE_API void dBodyAddForce (dBodyID, dReal fx, dReal fy, dReal fz); + +/** + * @brief Add torque at centre of mass of body in absolute coordinates. + * @ingroup bodies + */ +ODE_API void dBodyAddTorque (dBodyID, dReal fx, dReal fy, dReal fz); + +/** + * @brief Add force at centre of mass of body in coordinates relative to body. + * @ingroup bodies + */ +ODE_API void dBodyAddRelForce (dBodyID, dReal fx, dReal fy, dReal fz); + +/** + * @brief Add torque at centre of mass of body in coordinates relative to body. + * @ingroup bodies + */ +ODE_API void dBodyAddRelTorque (dBodyID, dReal fx, dReal fy, dReal fz); + +/** + * @brief Add force at specified point in body in global coordinates. + * @ingroup bodies + */ +ODE_API void dBodyAddForceAtPos (dBodyID, dReal fx, dReal fy, dReal fz, + dReal px, dReal py, dReal pz); +/** + * @brief Add force at specified point in body in local coordinates. + * @ingroup bodies + */ +ODE_API void dBodyAddForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal fz, + dReal px, dReal py, dReal pz); +/** + * @brief Add force at specified point in body in global coordinates. + * @ingroup bodies + */ +ODE_API void dBodyAddRelForceAtPos (dBodyID, dReal fx, dReal fy, dReal fz, + dReal px, dReal py, dReal pz); +/** + * @brief Add force at specified point in body in local coordinates. + * @ingroup bodies + */ +ODE_API void dBodyAddRelForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal fz, + dReal px, dReal py, dReal pz); + +/** + * @brief Return the current accumulated force vector. + * @return points to an array of 3 reals. + * @remarks + * The returned values are pointers to internal data structures, so + * the vectors are only valid until any changes are made to the rigid + * body system. + * @ingroup bodies + */ +ODE_API const dReal * dBodyGetForce (dBodyID); + +/** + * @brief Return the current accumulated torque vector. + * @return points to an array of 3 reals. + * @remarks + * The returned values are pointers to internal data structures, so + * the vectors are only valid until any changes are made to the rigid + * body system. + * @ingroup bodies + */ +ODE_API const dReal * dBodyGetTorque (dBodyID); + +/** + * @brief Set the body force accumulation vector. + * @remarks + * This is mostly useful to zero the force and torque for deactivated bodies + * before they are reactivated, in the case where the force-adding functions + * were called on them while they were deactivated. + * @ingroup bodies + */ +ODE_API void dBodySetForce (dBodyID b, dReal x, dReal y, dReal z); + +/** + * @brief Set the body torque accumulation vector. + * @remarks + * This is mostly useful to zero the force and torque for deactivated bodies + * before they are reactivated, in the case where the force-adding functions + * were called on them while they were deactivated. + * @ingroup bodies + */ +ODE_API void dBodySetTorque (dBodyID b, dReal x, dReal y, dReal z); + +/** + * @brief Get world position of a relative point on body. + * @ingroup bodies + * @param result will contain the result. + */ +ODE_API void dBodyGetRelPointPos +( + dBodyID, dReal px, dReal py, dReal pz, + dVector3 result +); + +/** + * @brief Get velocity vector in global coords of a relative point on body. + * @ingroup bodies + * @param result will contain the result. + */ +ODE_API void dBodyGetRelPointVel +( + dBodyID, dReal px, dReal py, dReal pz, + dVector3 result +); + +/** + * @brief Get velocity vector in global coords of a globally + * specified point on a body. + * @ingroup bodies + * @param result will contain the result. + */ +ODE_API void dBodyGetPointVel +( + dBodyID, dReal px, dReal py, dReal pz, + dVector3 result +); + +/** + * @brief takes a point in global coordinates and returns + * the point's position in body-relative coordinates. + * @remarks + * This is the inverse of dBodyGetRelPointPos() + * @ingroup bodies + * @param result will contain the result. + */ +ODE_API void dBodyGetPosRelPoint +( + dBodyID, dReal px, dReal py, dReal pz, + dVector3 result +); + +/** + * @brief Convert from local to world coordinates. + * @ingroup bodies + * @param result will contain the result. + */ +ODE_API void dBodyVectorToWorld +( + dBodyID, dReal px, dReal py, dReal pz, + dVector3 result +); + +/** + * @brief Convert from world to local coordinates. + * @ingroup bodies + * @param result will contain the result. + */ +ODE_API void dBodyVectorFromWorld +( + dBodyID, dReal px, dReal py, dReal pz, + dVector3 result +); + +/** + * @brief controls the way a body's orientation is updated at each timestep. + * @ingroup bodies + * @param mode can be 0 or 1: + * \li 0: An ``infinitesimal'' orientation update is used. + * This is fast to compute, but it can occasionally cause inaccuracies + * for bodies that are rotating at high speed, especially when those + * bodies are joined to other bodies. + * This is the default for every new body that is created. + * \li 1: A ``finite'' orientation update is used. + * This is more costly to compute, but will be more accurate for high + * speed rotations. + * @remarks + * Note however that high speed rotations can result in many types of + * error in a simulation, and the finite mode will only fix one of those + * sources of error. + */ +ODE_API void dBodySetFiniteRotationMode (dBodyID, int mode); + +/** + * @brief sets the finite rotation axis for a body. + * @ingroup bodies + * @remarks + * This is axis only has meaning when the finite rotation mode is set + * If this axis is zero (0,0,0), full finite rotations are performed on + * the body. + * If this axis is nonzero, the body is rotated by performing a partial finite + * rotation along the axis direction followed by an infinitesimal rotation + * along an orthogonal direction. + * @remarks + * This can be useful to alleviate certain sources of error caused by quickly + * spinning bodies. For example, if a car wheel is rotating at high speed + * you can call this function with the wheel's hinge axis as the argument to + * try and improve its behavior. + */ +ODE_API void dBodySetFiniteRotationAxis (dBodyID, dReal x, dReal y, dReal z); + +/** + * @brief Get the way a body's orientation is updated each timestep. + * @ingroup bodies + * @return the mode 0 (infitesimal) or 1 (finite). + */ +ODE_API int dBodyGetFiniteRotationMode (dBodyID); + +/** + * @brief Get the finite rotation axis. + * @param result will contain the axis. + * @ingroup bodies + */ +ODE_API void dBodyGetFiniteRotationAxis (dBodyID, dVector3 result); + +/** + * @brief Get the number of joints that are attached to this body. + * @ingroup bodies + * @return nr of joints + */ +ODE_API int dBodyGetNumJoints (dBodyID b); + +/** + * @brief Return a joint attached to this body, given by index. + * @ingroup bodies + * @param index valid range is 0 to n-1 where n is the value returned by + * dBodyGetNumJoints(). + */ +ODE_API dJointID dBodyGetJoint (dBodyID, int index); + + + + +/** + * @brief Set rigid body to dynamic state (default). + * @param dBodyID identification of body. + * @ingroup bodies + */ +ODE_API void dBodySetDynamic (dBodyID); + +/** + * @brief Set rigid body to kinematic state. + * When in kinematic state the body isn't simulated as a dynamic + * body (it's "unstoppable", doesn't respond to forces), + * but can still affect dynamic bodies (e.g. in joints). + * Kinematic bodies can be controlled by position and velocity. + * @note A kinematic body has infinite mass. If you set its mass + * to something else, it loses the kinematic state and behaves + * as a normal dynamic body. + * @param dBodyID identification of body. + * @ingroup bodies + */ +ODE_API void dBodySetKinematic (dBodyID); + +/** + * @brief Check wether a body is in kinematic state. + * @ingroup bodies + * @return 1 if a body is kinematic or 0 if it is dynamic. + */ +ODE_API int dBodyIsKinematic (dBodyID); + +/** + * @brief Manually enable a body. + * @param dBodyID identification of body. + * @ingroup bodies + */ +ODE_API void dBodyEnable (dBodyID); + +/** + * @brief Manually disable a body. + * @ingroup bodies + * @remarks + * A disabled body that is connected through a joint to an enabled body will + * be automatically re-enabled at the next simulation step. + */ +ODE_API void dBodyDisable (dBodyID); + +/** + * @brief Check wether a body is enabled. + * @ingroup bodies + * @return 1 if a body is currently enabled or 0 if it is disabled. + */ +ODE_API int dBodyIsEnabled (dBodyID); + +/** + * @brief Set whether the body is influenced by the world's gravity or not. + * @ingroup bodies + * @param mode when nonzero gravity affects this body. + * @remarks + * Newly created bodies are always influenced by the world's gravity. + */ +ODE_API void dBodySetGravityMode (dBodyID b, int mode); + +/** + * @brief Get whether the body is influenced by the world's gravity or not. + * @ingroup bodies + * @return nonzero means gravity affects this body. + */ +ODE_API int dBodyGetGravityMode (dBodyID b); + +/** + * @brief Set the 'moved' callback of a body. + * + * Whenever a body has its position or rotation changed during the + * timestep, the callback will be called (with body as the argument). + * Use it to know which body may need an update in an external + * structure (like a 3D engine). + * + * @param b the body that needs to be watched. + * @param callback the callback to be invoked when the body moves. Set to zero + * to disable. + * @ingroup bodies + */ +ODE_API void dBodySetMovedCallback(dBodyID b, void (*callback)(dBodyID)); + + +/** + * @brief Return the first geom associated with the body. + * + * You can traverse through the geoms by repeatedly calling + * dBodyGetNextGeom(). + * + * @return the first geom attached to this body, or 0. + * @ingroup bodies + */ +ODE_API dGeomID dBodyGetFirstGeom (dBodyID b); + + +/** + * @brief returns the next geom associated with the same body. + * @param g a geom attached to some body. + * @return the next geom attached to the same body, or 0. + * @sa dBodyGetFirstGeom + * @ingroup bodies + */ +ODE_API dGeomID dBodyGetNextGeom (dGeomID g); + + +/** + * @brief Resets the damping settings to the current world's settings. + * @ingroup bodies damping + */ +ODE_API void dBodySetDampingDefaults(dBodyID b); + +/** + * @brief Get the body's linear damping scale. + * @ingroup bodies damping + */ +ODE_API dReal dBodyGetLinearDamping (dBodyID b); + +/** + * @brief Set the body's linear damping scale. + * @param scale The linear damping scale. Should be in the interval [0, 1]. + * @ingroup bodies damping + * @remarks From now on the body will not use the world's linear damping + * scale until dBodySetDampingDefaults() is called. + * @sa dBodySetDampingDefaults() + */ +ODE_API void dBodySetLinearDamping(dBodyID b, dReal scale); + +/** + * @brief Get the body's angular damping scale. + * @ingroup bodies damping + * @remarks If the body's angular damping scale was not set, this function + * returns the world's angular damping scale. + */ +ODE_API dReal dBodyGetAngularDamping (dBodyID b); + +/** + * @brief Set the body's angular damping scale. + * @param scale The angular damping scale. Should be in the interval [0, 1]. + * @ingroup bodies damping + * @remarks From now on the body will not use the world's angular damping + * scale until dBodyResetAngularDamping() is called. + * @sa dBodyResetAngularDamping() + */ +ODE_API void dBodySetAngularDamping(dBodyID b, dReal scale); + +/** + * @brief Convenience function to set linear and angular scales at once. + * @param linear_scale The linear damping scale. Should be in the interval [0, 1]. + * @param angular_scale The angular damping scale. Should be in the interval [0, 1]. + * @ingroup bodies damping + * @sa dBodySetLinearDamping() dBodySetAngularDamping() + */ +ODE_API void dBodySetDamping(dBodyID b, dReal linear_scale, dReal angular_scale); + +/** + * @brief Get the body's linear damping threshold. + * @ingroup bodies damping + */ +ODE_API dReal dBodyGetLinearDampingThreshold (dBodyID b); + +/** + * @brief Set the body's linear damping threshold. + * @param threshold The linear threshold to be used. Damping + * is only applied if the linear speed is above this limit. + * @ingroup bodies damping + */ +ODE_API void dBodySetLinearDampingThreshold(dBodyID b, dReal threshold); + +/** + * @brief Get the body's angular damping threshold. + * @ingroup bodies damping + */ +ODE_API dReal dBodyGetAngularDampingThreshold (dBodyID b); + +/** + * @brief Set the body's angular damping threshold. + * @param threshold The angular threshold to be used. Damping is + * only used if the angular speed is above this limit. + * @ingroup bodies damping + */ +ODE_API void dBodySetAngularDampingThreshold(dBodyID b, dReal threshold); + +/** + * @brief Get the body's maximum angular speed. + * @ingroup damping bodies + * @sa dWorldGetMaxAngularSpeed() + */ +ODE_API dReal dBodyGetMaxAngularSpeed (dBodyID b); + +/** + * @brief Set the body's maximum angular speed. + * @ingroup damping bodies + * @sa dWorldSetMaxAngularSpeed() dBodyResetMaxAngularSpeed() + * The default value is dInfinity, but it's a good idea to limit + * it at less than 500 if the body has the gyroscopic term + * enabled. + */ +ODE_API void dBodySetMaxAngularSpeed(dBodyID b, dReal max_speed); + + + +/** + * @brief Get the body's gyroscopic state. + * + * @return nonzero if gyroscopic term computation is enabled (default), + * zero otherwise. + * @ingroup bodies + */ +ODE_API int dBodyGetGyroscopicMode(dBodyID b); + + +/** + * @brief Enable/disable the body's gyroscopic term. + * + * Disabling the gyroscopic term of a body usually improves + * stability. It also helps turning spining objects, like cars' + * wheels. + * + * @param enabled nonzero (default) to enable gyroscopic term, 0 + * to disable. + * @ingroup bodies + */ +ODE_API void dBodySetGyroscopicMode(dBodyID b, int enabled); + + + + +/** + * @defgroup joints Joints + * + * In real life a joint is something like a hinge, that is used to connect two + * objects. + * In ODE a joint is very similar: It is a relationship that is enforced between + * two bodies so that they can only have certain positions and orientations + * relative to each other. + * This relationship is called a constraint -- the words joint and + * constraint are often used interchangeably. + * + * A joint has a set of parameters that can be set. These include: + * + * + * \li dParamLoStop Low stop angle or position. Setting this to + * -dInfinity (the default value) turns off the low stop. + * For rotational joints, this stop must be greater than -pi to be + * effective. + * \li dParamHiStop High stop angle or position. Setting this to + * dInfinity (the default value) turns off the high stop. + * For rotational joints, this stop must be less than pi to be + * effective. + * If the high stop is less than the low stop then both stops will + * be ineffective. + * \li dParamVel Desired motor velocity (this will be an angular or + * linear velocity). + * \li dParamFMax The maximum force or torque that the motor will use to + * achieve the desired velocity. + * This must always be greater than or equal to zero. + * Setting this to zero (the default value) turns off the motor. + * \li dParamFudgeFactor The current joint stop/motor implementation has + * a small problem: + * when the joint is at one stop and the motor is set to move it away + * from the stop, too much force may be applied for one time step, + * causing a ``jumping'' motion. + * This fudge factor is used to scale this excess force. + * It should have a value between zero and one (the default value). + * If the jumping motion is too visible in a joint, the value can be + * reduced. + * Making this value too small can prevent the motor from being able to + * move the joint away from a stop. + * \li dParamBounce The bouncyness of the stops. + * This is a restitution parameter in the range 0..1. + * 0 means the stops are not bouncy at all, 1 means maximum bouncyness. + * \li dParamCFM The constraint force mixing (CFM) value used when not + * at a stop. + * \li dParamStopERP The error reduction parameter (ERP) used by the + * stops. + * \li dParamStopCFM The constraint force mixing (CFM) value used by the + * stops. Together with the ERP value this can be used to get spongy or + * soft stops. + * Note that this is intended for unpowered joints, it does not really + * work as expected when a powered joint reaches its limit. + * \li dParamSuspensionERP Suspension error reduction parameter (ERP). + * Currently this is only implemented on the hinge-2 joint. + * \li dParamSuspensionCFM Suspension constraint force mixing (CFM) value. + * Currently this is only implemented on the hinge-2 joint. + * + * If a particular parameter is not implemented by a given joint, setting it + * will have no effect. + * These parameter names can be optionally followed by a digit (2 or 3) + * to indicate the second or third set of parameters, e.g. for the second axis + * in a hinge-2 joint, or the third axis in an AMotor joint. + */ + + +/** + * @brief Create a new joint of the ball type. + * @ingroup joints + * @remarks + * The joint is initially in "limbo" (i.e. it has no effect on the simulation) + * because it does not connect to any bodies. + * @param dJointGroupID set to 0 to allocate the joint normally. + * If it is nonzero the joint is allocated in the given joint group. + */ +ODE_API dJointID dJointCreateBall (dWorldID, dJointGroupID); + +/** + * @brief Create a new joint of the hinge type. + * @ingroup joints + * @param dJointGroupID set to 0 to allocate the joint normally. + * If it is nonzero the joint is allocated in the given joint group. + */ +ODE_API dJointID dJointCreateHinge (dWorldID, dJointGroupID); + +/** + * @brief Create a new joint of the slider type. + * @ingroup joints + * @param dJointGroupID set to 0 to allocate the joint normally. + * If it is nonzero the joint is allocated in the given joint group. + */ +ODE_API dJointID dJointCreateSlider (dWorldID, dJointGroupID); + +/** + * @brief Create a new joint of the contact type. + * @ingroup joints + * @param dJointGroupID set to 0 to allocate the joint normally. + * If it is nonzero the joint is allocated in the given joint group. + */ +ODE_API dJointID dJointCreateContact (dWorldID, dJointGroupID, const dContact *); + +/** + * @brief Create a new joint of the hinge2 type. + * @ingroup joints + * @param dJointGroupID set to 0 to allocate the joint normally. + * If it is nonzero the joint is allocated in the given joint group. + */ +ODE_API dJointID dJointCreateHinge2 (dWorldID, dJointGroupID); + +/** + * @brief Create a new joint of the universal type. + * @ingroup joints + * @param dJointGroupID set to 0 to allocate the joint normally. + * If it is nonzero the joint is allocated in the given joint group. + */ +ODE_API dJointID dJointCreateUniversal (dWorldID, dJointGroupID); + +/** + * @brief Create a new joint of the PR (Prismatic and Rotoide) type. + * @ingroup joints + * @param dJointGroupID set to 0 to allocate the joint normally. + * If it is nonzero the joint is allocated in the given joint group. + */ +ODE_API dJointID dJointCreatePR (dWorldID, dJointGroupID); + +/** + * @brief Create a new joint of the PU (Prismatic and Universal) type. + * @ingroup joints + * @param dJointGroupID set to 0 to allocate the joint normally. + * If it is nonzero the joint is allocated in the given joint group. + */ +ODE_API dJointID dJointCreatePU (dWorldID, dJointGroupID); + +/** + * @brief Create a new joint of the Piston type. + * @ingroup joints + * @param dJointGroupID set to 0 to allocate the joint normally. + * If it is nonzero the joint is allocated in the given + * joint group. + */ +ODE_API dJointID dJointCreatePiston (dWorldID, dJointGroupID); + +/** + * @brief Create a new joint of the fixed type. + * @ingroup joints + * @param dJointGroupID set to 0 to allocate the joint normally. + * If it is nonzero the joint is allocated in the given joint group. + */ +ODE_API dJointID dJointCreateFixed (dWorldID, dJointGroupID); + +ODE_API dJointID dJointCreateNull (dWorldID, dJointGroupID); + +/** + * @brief Create a new joint of the A-motor type. + * @ingroup joints + * @param dJointGroupID set to 0 to allocate the joint normally. + * If it is nonzero the joint is allocated in the given joint group. + */ +ODE_API dJointID dJointCreateAMotor (dWorldID, dJointGroupID); + +/** + * @brief Create a new joint of the L-motor type. + * @ingroup joints + * @param dJointGroupID set to 0 to allocate the joint normally. + * If it is nonzero the joint is allocated in the given joint group. + */ +ODE_API dJointID dJointCreateLMotor (dWorldID, dJointGroupID); + +/** + * @brief Create a new joint of the plane-2d type. + * @ingroup joints + * @param dJointGroupID set to 0 to allocate the joint normally. + * If it is nonzero the joint is allocated in the given joint group. + */ +ODE_API dJointID dJointCreatePlane2D (dWorldID, dJointGroupID); + +/** + * @brief Create a new joint of the double ball type. + * @ingroup joints + * @param dJointGroupID set to 0 to allocate the joint normally. + * If it is nonzero the joint is allocated in the given joint group. + */ +ODE_API dJointID dJointCreateDBall (dWorldID, dJointGroupID); + +/** + * @brief Create a new joint of the double hinge type. + * @ingroup joints + * @param dJointGroupID set to 0 to allocate the joint normally. + * If it is nonzero the joint is allocated in the given joint group. + */ +ODE_API dJointID dJointCreateDHinge (dWorldID, dJointGroupID); + +/** + * @brief Create a new joint of the Transmission type. + * @ingroup joints + * @param dJointGroupID set to 0 to allocate the joint normally. + * If it is nonzero the joint is allocated in the given joint group. + */ +ODE_API dJointID dJointCreateTransmission (dWorldID, dJointGroupID); + + +/** + * @brief Destroy a joint. + * @ingroup joints + * + * disconnects it from its attached bodies and removing it from the world. + * However, if the joint is a member of a group then this function has no + * effect - to destroy that joint the group must be emptied or destroyed. + */ +ODE_API void dJointDestroy (dJointID); + + +/** + * @brief Create a joint group + * @ingroup joints + * @param max_size deprecated. Set to 0. + */ +ODE_API dJointGroupID dJointGroupCreate (int max_size); + +/** + * @brief Destroy a joint group. + * @ingroup joints + * + * All joints in the joint group will be destroyed. + */ +ODE_API void dJointGroupDestroy (dJointGroupID); + +/** + * @brief Empty a joint group. + * @ingroup joints + * + * All joints in the joint group will be destroyed, + * but the joint group itself will not be destroyed. + */ +ODE_API void dJointGroupEmpty (dJointGroupID); + +/** + * @brief Return the number of bodies attached to the joint + * @ingroup joints + */ +ODE_API int dJointGetNumBodies(dJointID); + +/** + * @brief Attach the joint to some new bodies. + * @ingroup joints + * + * If the joint is already attached, it will be detached from the old bodies + * first. + * To attach this joint to only one body, set body1 or body2 to zero - a zero + * body refers to the static environment. + * Setting both bodies to zero puts the joint into "limbo", i.e. it will + * have no effect on the simulation. + * @remarks + * Some joints, like hinge-2 need to be attached to two bodies to work. + */ +ODE_API void dJointAttach (dJointID, dBodyID body1, dBodyID body2); + +/** + * @brief Manually enable a joint. + * @param dJointID identification of joint. + * @ingroup joints + */ +ODE_API void dJointEnable (dJointID); + +/** + * @brief Manually disable a joint. + * @ingroup joints + * @remarks + * A disabled joint will not affect the simulation, but will maintain the anchors and + * axes so it can be enabled later. + */ +ODE_API void dJointDisable (dJointID); + +/** + * @brief Check wether a joint is enabled. + * @ingroup joints + * @return 1 if a joint is currently enabled or 0 if it is disabled. + */ +ODE_API int dJointIsEnabled (dJointID); + +/** + * @brief Set the user-data pointer + * @ingroup joints + */ +ODE_API void dJointSetData (dJointID, void *data); + +/** + * @brief Get the user-data pointer + * @ingroup joints + */ +ODE_API void *dJointGetData (dJointID); + +/** + * @brief Get the type of the joint + * @ingroup joints + * @return the type, being one of these: + * \li dJointTypeBall + * \li dJointTypeHinge + * \li dJointTypeSlider + * \li dJointTypeContact + * \li dJointTypeUniversal + * \li dJointTypeHinge2 + * \li dJointTypeFixed + * \li dJointTypeNull + * \li dJointTypeAMotor + * \li dJointTypeLMotor + * \li dJointTypePlane2D + * \li dJointTypePR + * \li dJointTypePU + * \li dJointTypePiston + */ +ODE_API dJointType dJointGetType (dJointID); + +/** + * @brief Return the bodies that this joint connects. + * @ingroup joints + * @param index return the first (0) or second (1) body. + * @remarks + * If one of these returned body IDs is zero, the joint connects the other body + * to the static environment. + * If both body IDs are zero, the joint is in ``limbo'' and has no effect on + * the simulation. + */ +ODE_API dBodyID dJointGetBody (dJointID, int index); + +/** + * @brief Sets the datastructure that is to receive the feedback. + * + * The feedback can be used by the user, so that it is known how + * much force an individual joint exerts. + * @ingroup joints + */ +ODE_API void dJointSetFeedback (dJointID, dJointFeedback *); + +/** + * @brief Gets the datastructure that is to receive the feedback. + * @ingroup joints + */ +ODE_API dJointFeedback *dJointGetFeedback (dJointID); + +/** + * @brief Set the joint anchor point. + * @ingroup joints + * + * The joint will try to keep this point on each body + * together. The input is specified in world coordinates. + */ +ODE_API void dJointSetBallAnchor (dJointID, dReal x, dReal y, dReal z); + +/** + * @brief Set the joint anchor point. + * @ingroup joints + */ +ODE_API void dJointSetBallAnchor2 (dJointID, dReal x, dReal y, dReal z); + +/** + * @brief Param setting for Ball joints + * @ingroup joints + */ +ODE_API void dJointSetBallParam (dJointID, int parameter, dReal value); + +/** + * @brief Set hinge anchor parameter. + * @ingroup joints + */ +ODE_API void dJointSetHingeAnchor (dJointID, dReal x, dReal y, dReal z); + +ODE_API void dJointSetHingeAnchorDelta (dJointID, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az); + +/** + * @brief Set hinge axis. + * @ingroup joints + */ +ODE_API void dJointSetHingeAxis (dJointID, dReal x, dReal y, dReal z); + +/** + * @brief Set the Hinge axis as if the 2 bodies were already at angle appart. + * @ingroup joints + * + * This function initialize the Axis and the relative orientation of each body + * as if body1 was rotated around the axis by the angle value. \br + * Ex: + * <PRE> + * dJointSetHingeAxis(jId, 1, 0, 0); + * // If you request the position you will have: dJointGetHingeAngle(jId) == 0 + * dJointSetHingeAxisDelta(jId, 1, 0, 0, 0.23); + * // If you request the position you will have: dJointGetHingeAngle(jId) == 0.23 + * </PRE> + + * @param j The Hinge joint ID for which the axis will be set + * @param x The X component of the axis in world frame + * @param y The Y component of the axis in world frame + * @param z The Z component of the axis in world frame + * @param angle The angle for the offset of the relative orientation. + * As if body1 was rotated by angle when the Axis was set (see below). + * The rotation is around the new Hinge axis. + * + * @note Usually the function dJointSetHingeAxis set the current position of body1 + * and body2 as the zero angle position. This function set the current position + * as the if the 2 bodies where \b angle appart. + * @warning Calling dJointSetHingeAnchor or dJointSetHingeAxis will reset the "zero" + * angle position. + */ +ODE_API void dJointSetHingeAxisOffset (dJointID j, dReal x, dReal y, dReal z, dReal angle); + +/** + * @brief set joint parameter + * @ingroup joints + */ +ODE_API void dJointSetHingeParam (dJointID, int parameter, dReal value); + +/** + * @brief Applies the torque about the hinge axis. + * + * That is, it applies a torque with specified magnitude in the direction + * of the hinge axis, to body 1, and with the same magnitude but in opposite + * direction to body 2. This function is just a wrapper for dBodyAddTorque()} + * @ingroup joints + */ +ODE_API void dJointAddHingeTorque(dJointID joint, dReal torque); + +/** + * @brief set the joint axis + * @ingroup joints + */ +ODE_API void dJointSetSliderAxis (dJointID, dReal x, dReal y, dReal z); + +/** + * @ingroup joints + */ +ODE_API void dJointSetSliderAxisDelta (dJointID, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az); + +/** + * @brief set joint parameter + * @ingroup joints + */ +ODE_API void dJointSetSliderParam (dJointID, int parameter, dReal value); + +/** + * @brief Applies the given force in the slider's direction. + * + * That is, it applies a force with specified magnitude, in the direction of + * slider's axis, to body1, and with the same magnitude but opposite + * direction to body2. This function is just a wrapper for dBodyAddForce(). + * @ingroup joints + */ +ODE_API void dJointAddSliderForce(dJointID joint, dReal force); + +/** + * @brief set anchor + * @ingroup joints + */ +ODE_API void dJointSetHinge2Anchor (dJointID, dReal x, dReal y, dReal z); + +/** + * @brief set both axes (optionally) + * + * This can change both axes at once avoiding transitions via invalid states + * while changing axes one by one and having the first changed axis coincide + * with the other axis existing direction. + * + * At least one of the axes must be not NULL. If NULL is passed, the corresponding + * axis retains its existing value. + * + * @ingroup joints + */ +ODE_API void dJointSetHinge2Axes (dJointID j, const dReal *axis1/*=[dSA__MAX],=NULL*/, const dReal *axis2/*=[dSA__MAX],=NULL*/); + +/** + * @brief set axis + * + * Deprecated. Use @fn dJointSetHinge2Axes instead. + * + * @ingroup joints + * @see dJointSetHinge2Axes + */ +ODE_API_DEPRECATED ODE_API void dJointSetHinge2Axis1 (dJointID j, dReal x, dReal y, dReal z); + +/** + * @brief set axis + * + * Deprecated. Use @fn dJointSetHinge2Axes instead. + * + * @ingroup joints + * @see dJointSetHinge2Axes + */ +ODE_API_DEPRECATED ODE_API void dJointSetHinge2Axis2 (dJointID j, dReal x, dReal y, dReal z); + +/** + * @brief set joint parameter + * @ingroup joints + */ +ODE_API void dJointSetHinge2Param (dJointID, int parameter, dReal value); + +/** + * @brief Applies torque1 about the hinge2's axis 1, torque2 about the + * hinge2's axis 2. + * @remarks This function is just a wrapper for dBodyAddTorque(). + * @ingroup joints + */ +ODE_API void dJointAddHinge2Torques(dJointID joint, dReal torque1, dReal torque2); + +/** + * @brief set anchor + * @ingroup joints + */ +ODE_API void dJointSetUniversalAnchor (dJointID, dReal x, dReal y, dReal z); + +/** + * @brief set axis + * @ingroup joints + */ +ODE_API void dJointSetUniversalAxis1 (dJointID, dReal x, dReal y, dReal z); + +/** + * @brief Set the Universal axis1 as if the 2 bodies were already at + * offset1 and offset2 appart with respect to axis1 and axis2. + * @ingroup joints + * + * This function initialize the axis1 and the relative orientation of + * each body as if body1 was rotated around the new axis1 by the offset1 + * value and as if body2 was rotated around the axis2 by offset2. \br + * Ex: +* <PRE> + * dJointSetHuniversalAxis1(jId, 1, 0, 0); + * // If you request the position you will have: dJointGetUniversalAngle1(jId) == 0 + * // If you request the position you will have: dJointGetUniversalAngle2(jId) == 0 + * dJointSetHuniversalAxis1Offset(jId, 1, 0, 0, 0.2, 0.17); + * // If you request the position you will have: dJointGetUniversalAngle1(jId) == 0.2 + * // If you request the position you will have: dJointGetUniversalAngle2(jId) == 0.17 + * </PRE> + * + * @param j The Hinge joint ID for which the axis will be set + * @param x The X component of the axis in world frame + * @param y The Y component of the axis in world frame + * @param z The Z component of the axis in world frame + * @param angle The angle for the offset of the relative orientation. + * As if body1 was rotated by angle when the Axis was set (see below). + * The rotation is around the new Hinge axis. + * + * @note Usually the function dJointSetHingeAxis set the current position of body1 + * and body2 as the zero angle position. This function set the current position + * as the if the 2 bodies where \b offsets appart. + * + * @note Any previous offsets are erased. + * + * @warning Calling dJointSetUniversalAnchor, dJointSetUnivesalAxis1, + * dJointSetUniversalAxis2, dJointSetUniversalAxis2Offset + * will reset the "zero" angle position. + */ +ODE_API void dJointSetUniversalAxis1Offset (dJointID, dReal x, dReal y, dReal z, + dReal offset1, dReal offset2); + +/** + * @brief set axis + * @ingroup joints + */ +ODE_API void dJointSetUniversalAxis2 (dJointID, dReal x, dReal y, dReal z); + +/** + * @brief Set the Universal axis2 as if the 2 bodies were already at + * offset1 and offset2 appart with respect to axis1 and axis2. + * @ingroup joints + * + * This function initialize the axis2 and the relative orientation of + * each body as if body1 was rotated around the axis1 by the offset1 + * value and as if body2 was rotated around the new axis2 by offset2. \br + * Ex: + * <PRE> + * dJointSetHuniversalAxis2(jId, 0, 1, 0); + * // If you request the position you will have: dJointGetUniversalAngle1(jId) == 0 + * // If you request the position you will have: dJointGetUniversalAngle2(jId) == 0 + * dJointSetHuniversalAxis2Offset(jId, 0, 1, 0, 0.2, 0.17); + * // If you request the position you will have: dJointGetUniversalAngle1(jId) == 0.2 + * // If you request the position you will have: dJointGetUniversalAngle2(jId) == 0.17 + * </PRE> + + * @param j The Hinge joint ID for which the axis will be set + * @param x The X component of the axis in world frame + * @param y The Y component of the axis in world frame + * @param z The Z component of the axis in world frame + * @param angle The angle for the offset of the relative orientation. + * As if body1 was rotated by angle when the Axis was set (see below). + * The rotation is around the new Hinge axis. + * + * @note Usually the function dJointSetHingeAxis set the current position of body1 + * and body2 as the zero angle position. This function set the current position + * as the if the 2 bodies where \b offsets appart. + * + * @note Any previous offsets are erased. + * + * @warning Calling dJointSetUniversalAnchor, dJointSetUnivesalAxis1, + * dJointSetUniversalAxis2, dJointSetUniversalAxis2Offset + * will reset the "zero" angle position. + */ + + +ODE_API void dJointSetUniversalAxis2Offset (dJointID, dReal x, dReal y, dReal z, + dReal offset1, dReal offset2); + +/** + * @brief set joint parameter + * @ingroup joints + */ +ODE_API void dJointSetUniversalParam (dJointID, int parameter, dReal value); + +/** + * @brief Applies torque1 about the universal's axis 1, torque2 about the + * universal's axis 2. + * @remarks This function is just a wrapper for dBodyAddTorque(). + * @ingroup joints + */ +ODE_API void dJointAddUniversalTorques(dJointID joint, dReal torque1, dReal torque2); + + +/** + * @brief set anchor + * @ingroup joints + */ +ODE_API void dJointSetPRAnchor (dJointID, dReal x, dReal y, dReal z); + +/** + * @brief set the axis for the prismatic articulation + * @ingroup joints + */ +ODE_API void dJointSetPRAxis1 (dJointID, dReal x, dReal y, dReal z); + +/** + * @brief set the axis for the rotoide articulation + * @ingroup joints + */ +ODE_API void dJointSetPRAxis2 (dJointID, dReal x, dReal y, dReal z); + +/** + * @brief set joint parameter + * @ingroup joints + * + * @note parameterX where X equal 2 refer to parameter for the rotoide articulation + */ +ODE_API void dJointSetPRParam (dJointID, int parameter, dReal value); + +/** + * @brief Applies the torque about the rotoide axis of the PR joint + * + * That is, it applies a torque with specified magnitude in the direction + * of the rotoide axis, to body 1, and with the same magnitude but in opposite + * direction to body 2. This function is just a wrapper for dBodyAddTorque()} + * @ingroup joints + */ +ODE_API void dJointAddPRTorque (dJointID j, dReal torque); + + +/** +* @brief set anchor +* @ingroup joints +*/ +ODE_API void dJointSetPUAnchor (dJointID, dReal x, dReal y, dReal z); + +/** + * @brief set anchor + * @ingroup joints + */ +ODE_API_DEPRECATED ODE_API void dJointSetPUAnchorDelta (dJointID, dReal x, dReal y, dReal z, + dReal dx, dReal dy, dReal dz); + +/** + * @brief Set the PU anchor as if the 2 bodies were already at [dx, dy, dz] appart. + * @ingroup joints + * + * This function initialize the anchor and the relative position of each body + * as if the position between body1 and body2 was already the projection of [dx, dy, dz] + * along the Piston axis. (i.e as if the body1 was at its current position - [dx,dy,dy] when the + * axis is set). + * Ex: + * <PRE> + * dReal offset = 3; + * dVector3 axis; + * dJointGetPUAxis(jId, axis); + * dJointSetPUAnchor(jId, 0, 0, 0); + * // If you request the position you will have: dJointGetPUPosition(jId) == 0 + * dJointSetPUAnchorOffset(jId, 0, 0, 0, axis[X]*offset, axis[Y]*offset, axis[Z]*offset); + * // If you request the position you will have: dJointGetPUPosition(jId) == offset + * </PRE> + * @param j The PU joint for which the anchor point will be set + * @param x The X position of the anchor point in world frame + * @param y The Y position of the anchor point in world frame + * @param z The Z position of the anchor point in world frame + * @param dx A delta to be substracted to the X position as if the anchor was set + * when body1 was at current_position[X] - dx + * @param dx A delta to be substracted to the Y position as if the anchor was set + * when body1 was at current_position[Y] - dy + * @param dx A delta to be substracted to the Z position as if the anchor was set + * when body1 was at current_position[Z] - dz + */ +ODE_API void dJointSetPUAnchorOffset (dJointID, dReal x, dReal y, dReal z, + dReal dx, dReal dy, dReal dz); + +/** + * @brief set the axis for the first axis or the universal articulation + * @ingroup joints + */ +ODE_API void dJointSetPUAxis1 (dJointID, dReal x, dReal y, dReal z); + +/** + * @brief set the axis for the second axis or the universal articulation + * @ingroup joints + */ +ODE_API void dJointSetPUAxis2 (dJointID, dReal x, dReal y, dReal z); + +/** + * @brief set the axis for the prismatic articulation + * @ingroup joints + */ +ODE_API void dJointSetPUAxis3 (dJointID, dReal x, dReal y, dReal z); + +/** + * @brief set the axis for the prismatic articulation + * @ingroup joints + * @note This function was added for convenience it is the same as + * dJointSetPUAxis3 + */ +ODE_API void dJointSetPUAxisP (dJointID id, dReal x, dReal y, dReal z); + + + +/** + * @brief set joint parameter + * @ingroup joints + * + * @note parameterX where X equal 2 refer to parameter for second axis of the + * universal articulation + * @note parameterX where X equal 3 refer to parameter for prismatic + * articulation + */ +ODE_API void dJointSetPUParam (dJointID, int parameter, dReal value); + +/** + * @brief Applies the torque about the rotoide axis of the PU joint + * + * That is, it applies a torque with specified magnitude in the direction + * of the rotoide axis, to body 1, and with the same magnitude but in opposite + * direction to body 2. This function is just a wrapper for dBodyAddTorque()} + * @ingroup joints + */ +ODE_API void dJointAddPUTorque (dJointID j, dReal torque); + + + + +/** + * @brief set the joint anchor + * @ingroup joints + */ +ODE_API void dJointSetPistonAnchor (dJointID, dReal x, dReal y, dReal z); + +/** + * @brief Set the Piston anchor as if the 2 bodies were already at [dx,dy, dz] appart. + * @ingroup joints + * + * This function initialize the anchor and the relative position of each body + * as if the position between body1 and body2 was already the projection of [dx, dy, dz] + * along the Piston axis. (i.e as if the body1 was at its current position - [dx,dy,dy] when the + * axis is set). + * Ex: + * <PRE> + * dReal offset = 3; + * dVector3 axis; + * dJointGetPistonAxis(jId, axis); + * dJointSetPistonAnchor(jId, 0, 0, 0); + * // If you request the position you will have: dJointGetPistonPosition(jId) == 0 + * dJointSetPistonAnchorOffset(jId, 0, 0, 0, axis[X]*offset, axis[Y]*offset, axis[Z]*offset); + * // If you request the position you will have: dJointGetPistonPosition(jId) == offset + * </PRE> + * @param j The Piston joint for which the anchor point will be set + * @param x The X position of the anchor point in world frame + * @param y The Y position of the anchor point in world frame + * @param z The Z position of the anchor point in world frame + * @param dx A delta to be substracted to the X position as if the anchor was set + * when body1 was at current_position[X] - dx + * @param dx A delta to be substracted to the Y position as if the anchor was set + * when body1 was at current_position[Y] - dy + * @param dx A delta to be substracted to the Z position as if the anchor was set + * when body1 was at current_position[Z] - dz + */ +ODE_API void dJointSetPistonAnchorOffset(dJointID j, dReal x, dReal y, dReal z, + dReal dx, dReal dy, dReal dz); + + /** + * @brief set the joint axis + * @ingroup joints + */ +ODE_API void dJointSetPistonAxis (dJointID, dReal x, dReal y, dReal z); + +/** + * This function set prismatic axis of the joint and also set the position + * of the joint. + * + * @ingroup joints + * @param j The joint affected by this function + * @param x The x component of the axis + * @param y The y component of the axis + * @param z The z component of the axis + * @param dx The Initial position of the prismatic join in the x direction + * @param dy The Initial position of the prismatic join in the y direction + * @param dz The Initial position of the prismatic join in the z direction + */ +ODE_API_DEPRECATED ODE_API void dJointSetPistonAxisDelta (dJointID j, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az); + +/** + * @brief set joint parameter + * @ingroup joints + */ +ODE_API void dJointSetPistonParam (dJointID, int parameter, dReal value); + +/** + * @brief Applies the given force in the slider's direction. + * + * That is, it applies a force with specified magnitude, in the direction of + * prismatic's axis, to body1, and with the same magnitude but opposite + * direction to body2. This function is just a wrapper for dBodyAddForce(). + * @ingroup joints + */ +ODE_API void dJointAddPistonForce (dJointID joint, dReal force); + + +/** + * @brief Call this on the fixed joint after it has been attached to + * remember the current desired relative offset and desired relative + * rotation between the bodies. + * @ingroup joints + */ +ODE_API void dJointSetFixed (dJointID); + +/* + * @brief Sets joint parameter + * + * @ingroup joints + */ +ODE_API void dJointSetFixedParam (dJointID, int parameter, dReal value); + +/** + * @brief set the nr of axes + * @param num 0..3 + * @ingroup joints + */ +ODE_API void dJointSetAMotorNumAxes (dJointID, int num); + +/** + * @brief set axis + * @ingroup joints + */ +ODE_API void dJointSetAMotorAxis (dJointID, int anum, int rel, + dReal x, dReal y, dReal z); + +/** + * @brief Tell the AMotor what the current angle is along axis anum. + * + * This function should only be called in dAMotorUser mode, because in this + * mode the AMotor has no other way of knowing the joint angles. + * The angle information is needed if stops have been set along the axis, + * but it is not needed for axis motors. + * @ingroup joints + */ +ODE_API void dJointSetAMotorAngle (dJointID, int anum, dReal angle); + +/** + * @brief set joint parameter + * @ingroup joints + */ +ODE_API void dJointSetAMotorParam (dJointID, int parameter, dReal value); + +/** + * @brief set mode + * @ingroup joints + */ +ODE_API void dJointSetAMotorMode (dJointID, int mode); + +/** + * @brief Applies torque0 about the AMotor's axis 0, torque1 about the + * AMotor's axis 1, and torque2 about the AMotor's axis 2. + * @remarks + * If the motor has fewer than three axes, the higher torques are ignored. + * This function is just a wrapper for dBodyAddTorque(). + * @ingroup joints + */ +ODE_API void dJointAddAMotorTorques (dJointID, dReal torque1, dReal torque2, dReal torque3); + +/** + * @brief Set the number of axes that will be controlled by the LMotor. + * @param num can range from 0 (which effectively deactivates the joint) to 3. + * @ingroup joints + */ +ODE_API void dJointSetLMotorNumAxes (dJointID, int num); + +/** + * @brief Set the AMotor axes. + * @param anum selects the axis to change (0,1 or 2). + * @param rel Each axis can have one of three ``relative orientation'' modes + * \li 0: The axis is anchored to the global frame. + * \li 1: The axis is anchored to the first body. + * \li 2: The axis is anchored to the second body. + * @remarks The axis vector is always specified in global coordinates + * regardless of the setting of rel. + * @ingroup joints + */ +ODE_API void dJointSetLMotorAxis (dJointID, int anum, int rel, dReal x, dReal y, dReal z); + +/** + * @brief set joint parameter + * @ingroup joints + */ +ODE_API void dJointSetLMotorParam (dJointID, int parameter, dReal value); + +/** + * @ingroup joints + */ +ODE_API void dJointSetPlane2DXParam (dJointID, int parameter, dReal value); + +/** + * @ingroup joints + */ + +ODE_API void dJointSetPlane2DYParam (dJointID, int parameter, dReal value); + +/** + * @ingroup joints + */ +ODE_API void dJointSetPlane2DAngleParam (dJointID, int parameter, dReal value); + +/** + * @brief Get the joint anchor point, in world coordinates. + * + * This returns the point on body 1. If the joint is perfectly satisfied, + * this will be the same as the point on body 2. + */ +ODE_API void dJointGetBallAnchor (dJointID, dVector3 result); + +/** + * @brief Get the joint anchor point, in world coordinates. + * + * This returns the point on body 2. You can think of a ball and socket + * joint as trying to keep the result of dJointGetBallAnchor() and + * dJointGetBallAnchor2() the same. If the joint is perfectly satisfied, + * this function will return the same value as dJointGetBallAnchor() to + * within roundoff errors. dJointGetBallAnchor2() can be used, along with + * dJointGetBallAnchor(), to see how far the joint has come apart. + */ +ODE_API void dJointGetBallAnchor2 (dJointID, dVector3 result); + +/** + * @brief get joint parameter + * @ingroup joints + */ +ODE_API dReal dJointGetBallParam (dJointID, int parameter); + +/** + * @brief Get the hinge anchor point, in world coordinates. + * + * This returns the point on body 1. If the joint is perfectly satisfied, + * this will be the same as the point on body 2. + * @ingroup joints + */ +ODE_API void dJointGetHingeAnchor (dJointID, dVector3 result); + +/** + * @brief Get the joint anchor point, in world coordinates. + * @return The point on body 2. If the joint is perfectly satisfied, + * this will return the same value as dJointGetHingeAnchor(). + * If not, this value will be slightly different. + * This can be used, for example, to see how far the joint has come apart. + * @ingroup joints + */ +ODE_API void dJointGetHingeAnchor2 (dJointID, dVector3 result); + +/** + * @brief get axis + * @ingroup joints + */ +ODE_API void dJointGetHingeAxis (dJointID, dVector3 result); + +/** + * @brief get joint parameter + * @ingroup joints + */ +ODE_API dReal dJointGetHingeParam (dJointID, int parameter); + +/** + * @brief Get the hinge angle. + * + * The angle is measured between the two bodies, or between the body and + * the static environment. + * The angle will be between -pi..pi. + * Give the relative rotation with respect to the Hinge axis of Body 1 with + * respect to Body 2. + * When the hinge anchor or axis is set, the current position of the attached + * bodies is examined and that position will be the zero angle. + * @ingroup joints + */ +ODE_API dReal dJointGetHingeAngle (dJointID); + +/** + * @brief Get the hinge angle time derivative. + * @ingroup joints + */ +ODE_API dReal dJointGetHingeAngleRate (dJointID); + +/** + * @brief Get the slider linear position (i.e. the slider's extension) + * + * When the axis is set, the current position of the attached bodies is + * examined and that position will be the zero position. + + * The position is the distance, with respect to the zero position, + * along the slider axis of body 1 with respect to + * body 2. (A NULL body is replaced by the world). + * @ingroup joints + */ +ODE_API dReal dJointGetSliderPosition (dJointID); + +/** + * @brief Get the slider linear position's time derivative. + * @ingroup joints + */ +ODE_API dReal dJointGetSliderPositionRate (dJointID); + +/** + * @brief Get the slider axis + * @ingroup joints + */ +ODE_API void dJointGetSliderAxis (dJointID, dVector3 result); + +/** + * @brief get joint parameter + * @ingroup joints + */ +ODE_API dReal dJointGetSliderParam (dJointID, int parameter); + +/** + * @brief Get the joint anchor point, in world coordinates. + * @return the point on body 1. If the joint is perfectly satisfied, + * this will be the same as the point on body 2. + * @ingroup joints + */ +ODE_API void dJointGetHinge2Anchor (dJointID, dVector3 result); + +/** + * @brief Get the joint anchor point, in world coordinates. + * This returns the point on body 2. If the joint is perfectly satisfied, + * this will return the same value as dJointGetHinge2Anchor. + * If not, this value will be slightly different. + * This can be used, for example, to see how far the joint has come apart. + * @ingroup joints + */ +ODE_API void dJointGetHinge2Anchor2 (dJointID, dVector3 result); + +/** + * @brief Get joint axis + * @ingroup joints + */ +ODE_API void dJointGetHinge2Axis1 (dJointID, dVector3 result); + +/** + * @brief Get joint axis + * @ingroup joints + */ +ODE_API void dJointGetHinge2Axis2 (dJointID, dVector3 result); + +/** + * @brief get joint parameter + * @ingroup joints + */ +ODE_API dReal dJointGetHinge2Param (dJointID, int parameter); + +/** + * @brief Get angle + * @ingroup joints + */ +ODE_API dReal dJointGetHinge2Angle1 (dJointID); + +/** + * @brief Get angle + * @ingroup joints + */ +ODE_API dReal dJointGetHinge2Angle2 (dJointID); + +/** + * @brief Get time derivative of angle + * @ingroup joints + */ +ODE_API dReal dJointGetHinge2Angle1Rate (dJointID); + +/** + * @brief Get time derivative of angle + * @ingroup joints + */ +ODE_API dReal dJointGetHinge2Angle2Rate (dJointID); + +/** + * @brief Get the joint anchor point, in world coordinates. + * @return the point on body 1. If the joint is perfectly satisfied, + * this will be the same as the point on body 2. + * @ingroup joints + */ +ODE_API void dJointGetUniversalAnchor (dJointID, dVector3 result); + +/** + * @brief Get the joint anchor point, in world coordinates. + * @return This returns the point on body 2. + * @remarks + * You can think of the ball and socket part of a universal joint as + * trying to keep the result of dJointGetBallAnchor() and + * dJointGetBallAnchor2() the same. If the joint is + * perfectly satisfied, this function will return the same value + * as dJointGetUniversalAnchor() to within roundoff errors. + * dJointGetUniversalAnchor2() can be used, along with + * dJointGetUniversalAnchor(), to see how far the joint has come apart. + * @ingroup joints + */ +ODE_API void dJointGetUniversalAnchor2 (dJointID, dVector3 result); + +/** + * @brief Get axis + * @ingroup joints + */ +ODE_API void dJointGetUniversalAxis1 (dJointID, dVector3 result); + +/** + * @brief Get axis + * @ingroup joints + */ +ODE_API void dJointGetUniversalAxis2 (dJointID, dVector3 result); + + +/** + * @brief get joint parameter + * @ingroup joints + */ +ODE_API dReal dJointGetUniversalParam (dJointID, int parameter); + +/** + * @brief Get both angles at the same time. + * @ingroup joints + * + * @param joint The universal joint for which we want to calculate the angles + * @param angle1 The angle between the body1 and the axis 1 + * @param angle2 The angle between the body2 and the axis 2 + * + * @note This function combine getUniversalAngle1 and getUniversalAngle2 together + * and try to avoid redundant calculation + */ +ODE_API void dJointGetUniversalAngles (dJointID, dReal *angle1, dReal *angle2); + +/** + * @brief Get angle + * @ingroup joints + */ +ODE_API dReal dJointGetUniversalAngle1 (dJointID); + +/** + * @brief Get angle + * @ingroup joints + */ +ODE_API dReal dJointGetUniversalAngle2 (dJointID); + +/** + * @brief Get time derivative of angle + * @ingroup joints + */ +ODE_API dReal dJointGetUniversalAngle1Rate (dJointID); + +/** + * @brief Get time derivative of angle + * @ingroup joints + */ +ODE_API dReal dJointGetUniversalAngle2Rate (dJointID); + + + +/** + * @brief Get the joint anchor point, in world coordinates. + * @return the point on body 1. If the joint is perfectly satisfied, + * this will be the same as the point on body 2. + * @ingroup joints + */ +ODE_API void dJointGetPRAnchor (dJointID, dVector3 result); + +/** + * @brief Get the PR linear position (i.e. the prismatic's extension) + * + * When the axis is set, the current position of the attached bodies is + * examined and that position will be the zero position. + * + * The position is the "oriented" length between the + * position = (Prismatic axis) dot_product [(body1 + offset) - (body2 + anchor2)] + * + * @ingroup joints + */ +ODE_API dReal dJointGetPRPosition (dJointID); + +/** + * @brief Get the PR linear position's time derivative + * + * @ingroup joints + */ +ODE_API dReal dJointGetPRPositionRate (dJointID); + + +/** + * @brief Get the PR angular position (i.e. the twist between the 2 bodies) + * + * When the axis is set, the current position of the attached bodies is + * examined and that position will be the zero position. + * @ingroup joints + */ +ODE_API dReal dJointGetPRAngle (dJointID); + +/** + * @brief Get the PR angular position's time derivative + * + * @ingroup joints + */ +ODE_API dReal dJointGetPRAngleRate (dJointID); + + +/** + * @brief Get the prismatic axis + * @ingroup joints + */ +ODE_API void dJointGetPRAxis1 (dJointID, dVector3 result); + +/** + * @brief Get the Rotoide axis + * @ingroup joints + */ +ODE_API void dJointGetPRAxis2 (dJointID, dVector3 result); + +/** + * @brief get joint parameter + * @ingroup joints + */ +ODE_API dReal dJointGetPRParam (dJointID, int parameter); + + + +/** + * @brief Get the joint anchor point, in world coordinates. + * @return the point on body 1. If the joint is perfectly satisfied, + * this will be the same as the point on body 2. + * @ingroup joints + */ +ODE_API void dJointGetPUAnchor (dJointID, dVector3 result); + +/** + * @brief Get the PU linear position (i.e. the prismatic's extension) + * + * When the axis is set, the current position of the attached bodies is + * examined and that position will be the zero position. + * + * The position is the "oriented" length between the + * position = (Prismatic axis) dot_product [(body1 + offset) - (body2 + anchor2)] + * + * @ingroup joints + */ +ODE_API dReal dJointGetPUPosition (dJointID); + +/** + * @brief Get the PR linear position's time derivative + * + * @ingroup joints + */ +ODE_API dReal dJointGetPUPositionRate (dJointID); + +/** + * @brief Get the first axis of the universal component of the joint + * @ingroup joints + */ +ODE_API void dJointGetPUAxis1 (dJointID, dVector3 result); + +/** + * @brief Get the second axis of the Universal component of the joint + * @ingroup joints + */ +ODE_API void dJointGetPUAxis2 (dJointID, dVector3 result); + +/** + * @brief Get the prismatic axis + * @ingroup joints + */ +ODE_API void dJointGetPUAxis3 (dJointID, dVector3 result); + +/** + * @brief Get the prismatic axis + * @ingroup joints + * + * @note This function was added for convenience it is the same as + * dJointGetPUAxis3 + */ +ODE_API void dJointGetPUAxisP (dJointID id, dVector3 result); + + + + +/** + * @brief Get both angles at the same time. + * @ingroup joints + * + * @param joint The Prismatic universal joint for which we want to calculate the angles + * @param angle1 The angle between the body1 and the axis 1 + * @param angle2 The angle between the body2 and the axis 2 + * + * @note This function combine dJointGetPUAngle1 and dJointGetPUAngle2 together + * and try to avoid redundant calculation + */ +ODE_API void dJointGetPUAngles (dJointID, dReal *angle1, dReal *angle2); + +/** + * @brief Get angle + * @ingroup joints + */ +ODE_API dReal dJointGetPUAngle1 (dJointID); + +/** + * @brief * @brief Get time derivative of angle1 + * + * @ingroup joints + */ +ODE_API dReal dJointGetPUAngle1Rate (dJointID); + + +/** + * @brief Get angle + * @ingroup joints + */ +ODE_API dReal dJointGetPUAngle2 (dJointID); + +/** + * @brief * @brief Get time derivative of angle2 + * + * @ingroup joints + */ +ODE_API dReal dJointGetPUAngle2Rate (dJointID); + + /** + * @brief get joint parameter + * @ingroup joints + */ +ODE_API dReal dJointGetPUParam (dJointID, int parameter); + + + + + +/** + * @brief Get the Piston linear position (i.e. the piston's extension) + * + * When the axis is set, the current position of the attached bodies is + * examined and that position will be the zero position. + * @ingroup joints + */ +ODE_API dReal dJointGetPistonPosition (dJointID); + +/** + * @brief Get the piston linear position's time derivative. + * @ingroup joints + */ +ODE_API dReal dJointGetPistonPositionRate (dJointID); + +/** + * @brief Get the Piston angular position (i.e. the twist between the 2 bodies) + * + * When the axis is set, the current position of the attached bodies is + * examined and that position will be the zero position. + * @ingroup joints + */ +ODE_API dReal dJointGetPistonAngle (dJointID); + +/** + * @brief Get the piston angular position's time derivative. + * @ingroup joints + */ +ODE_API dReal dJointGetPistonAngleRate (dJointID); + + +/** + * @brief Get the joint anchor + * + * This returns the point on body 1. If the joint is perfectly satisfied, + * this will be the same as the point on body 2 in direction perpendicular + * to the prismatic axis. + * + * @ingroup joints + */ +ODE_API void dJointGetPistonAnchor (dJointID, dVector3 result); + +/** + * @brief Get the joint anchor w.r.t. body 2 + * + * This returns the point on body 2. You can think of a Piston + * joint as trying to keep the result of dJointGetPistonAnchor() and + * dJointGetPistonAnchor2() the same in the direction perpendicular to the + * pirsmatic axis. If the joint is perfectly satisfied, + * this function will return the same value as dJointGetPistonAnchor() to + * within roundoff errors. dJointGetPistonAnchor2() can be used, along with + * dJointGetPistonAnchor(), to see how far the joint has come apart. + * + * @ingroup joints + */ +ODE_API void dJointGetPistonAnchor2 (dJointID, dVector3 result); + +/** + * @brief Get the prismatic axis (This is also the rotoide axis. + * @ingroup joints + */ +ODE_API void dJointGetPistonAxis (dJointID, dVector3 result); + +/** + * @brief get joint parameter + * @ingroup joints + */ +ODE_API dReal dJointGetPistonParam (dJointID, int parameter); + + +/** + * @brief Get the number of angular axes that will be controlled by the + * AMotor. + * @param num can range from 0 (which effectively deactivates the + * joint) to 3. + * This is automatically set to 3 in dAMotorEuler mode. + * @ingroup joints + */ +ODE_API int dJointGetAMotorNumAxes (dJointID); + +/** + * @brief Get the AMotor axes. + * @param anum selects the axis to change (0,1 or 2). + * @param rel Each axis can have one of three ``relative orientation'' modes. + * \li 0: The axis is anchored to the global frame. + * \li 1: The axis is anchored to the first body. + * \li 2: The axis is anchored to the second body. + * @ingroup joints + */ +ODE_API void dJointGetAMotorAxis (dJointID, int anum, dVector3 result); + +/** + * @brief Get axis + * @remarks + * The axis vector is always specified in global coordinates regardless + * of the setting of rel. + * There are two GetAMotorAxis functions, one to return the axis and one to + * return the relative mode. + * + * For dAMotorEuler mode: + * \li Only axes 0 and 2 need to be set. Axis 1 will be determined + automatically at each time step. + * \li Axes 0 and 2 must be perpendicular to each other. + * \li Axis 0 must be anchored to the first body, axis 2 must be anchored + to the second body. + * @ingroup joints + */ +ODE_API int dJointGetAMotorAxisRel (dJointID, int anum); + +/** + * @brief Get the current angle for axis. + * @remarks + * In dAMotorUser mode this is simply the value that was set with + * dJointSetAMotorAngle(). + * In dAMotorEuler mode this is the corresponding euler angle. + * @ingroup joints + */ +ODE_API dReal dJointGetAMotorAngle (dJointID, int anum); + +/** + * @brief Get the current angle rate for axis anum. + * @remarks + * In dAMotorUser mode this is always zero, as not enough information is + * available. + * In dAMotorEuler mode this is the corresponding euler angle rate. + * @ingroup joints + */ +ODE_API dReal dJointGetAMotorAngleRate (dJointID, int anum); + +/** + * @brief get joint parameter + * @ingroup joints + */ +ODE_API dReal dJointGetAMotorParam (dJointID, int parameter); + +/** + * @brief Get the angular motor mode. + * @param mode must be one of the following constants: + * \li dAMotorUser The AMotor axes and joint angle settings are entirely + * controlled by the user. This is the default mode. + * \li dAMotorEuler Euler angles are automatically computed. + * The axis a1 is also automatically computed. + * The AMotor axes must be set correctly when in this mode, + * as described below. + * When this mode is initially set the current relative orientations + * of the bodies will correspond to all euler angles at zero. + * @ingroup joints + */ +ODE_API int dJointGetAMotorMode (dJointID); + +/** + * @brief Get nr of axes. + * @ingroup joints + */ +ODE_API int dJointGetLMotorNumAxes (dJointID); + +/** + * @brief Get axis. + * @ingroup joints + */ +ODE_API void dJointGetLMotorAxis (dJointID, int anum, dVector3 result); + +/** + * @brief get joint parameter + * @ingroup joints + */ +ODE_API dReal dJointGetLMotorParam (dJointID, int parameter); + +/** + * @brief get joint parameter + * @ingroup joints + */ +ODE_API dReal dJointGetFixedParam (dJointID, int parameter); + + +/** + * @brief get the contact point of the first wheel of the Transmission joint. + * @ingroup joints + */ +ODE_API void dJointGetTransmissionContactPoint1(dJointID, dVector3 result); + +/** + * @brief get contact point of the second wheel of the Transmission joint. + * @ingroup joints + */ +ODE_API void dJointGetTransmissionContactPoint2(dJointID, dVector3 result); + +/** + * @brief set the first axis for the Transmission joint + * @remarks This is the axis around which the first body is allowed to + * revolve and is attached to it. It is given in global coordinates + * and can only be set explicitly in intersecting-axes mode. For the + * parallel-axes and chain modes which share one common axis of + * revolution for both gears dJointSetTransmissionAxis should be used. + * @ingroup joints + */ +ODE_API void dJointSetTransmissionAxis1(dJointID, dReal x, dReal y, dReal z); + +/** + * @brief get first axis for the Transmission joint + * @remarks In parallel-axes and chain mode the common axis with + * respect to the first body is returned. If the joint constraint is + * satisfied it should be the same as the axis return with + * dJointGetTransmissionAxis2 or dJointGetTransmissionAxis. + * @ingroup joints + */ +ODE_API void dJointGetTransmissionAxis1(dJointID, dVector3 result); + +/** + * @brief set second axis for the Transmission joint + * @remarks This is the axis around which the second body is allowed + * to revolve and is attached to it. It is given in global + * coordinates and can only be set explicitly in intersecting-axes + * mode. For the parallel-axes and chain modes which share one common + * axis of revolution for both gears dJointSetTransmissionAxis should + * be used. + * @ingroup joints + */ +ODE_API void dJointSetTransmissionAxis2(dJointID, dReal x, dReal y, dReal z); + +/** + * @brief get second axis for the Transmission joint + * @remarks In parallel-axes and chain mode the common axis with + * respect to the second body is returned. If the joint constraint is + * satisfied it should be the same as the axis return with + * dJointGetTransmissionAxis1 or dJointGetTransmissionAxis. + * @ingroup joints + */ +ODE_API void dJointGetTransmissionAxis2(dJointID, dVector3 result); + +/** + * @brief set the first anchor for the Transmission joint + * @remarks This is the point of attachment of the wheel on the + * first body. It is given in global coordinates. + * @ingroup joints + */ +ODE_API void dJointSetTransmissionAnchor1(dJointID, dReal x, dReal y, dReal z); + +/** + * @brief get the first anchor of the Transmission joint + * @ingroup joints + */ +ODE_API void dJointGetTransmissionAnchor1(dJointID, dVector3 result); + +/** + * @brief set the second anchor for the Transmission joint + * @remarks This is the point of attachment of the wheel on the + * second body. It is given in global coordinates. + * @ingroup joints + */ +ODE_API void dJointSetTransmissionAnchor2(dJointID, dReal x, dReal y, dReal z); + +/** + * @brief get the second anchor for the Transmission joint + * @ingroup joints + */ +ODE_API void dJointGetTransmissionAnchor2(dJointID, dVector3 result); + +/** + * @brief set a Transmission joint parameter + * @ingroup joints + */ +ODE_API void dJointSetTransmissionParam(dJointID, int parameter, dReal value); + +/** + * @brief get a Transmission joint parameter + * @ingroup joints + */ +ODE_API dReal dJointGetTransmissionParam(dJointID, int parameter); + +/** + * @brief set the Transmission joint mode + * @remarks The mode can be one of dTransmissionParallelAxes, + * dTransmissionIntersectingAxes and dTransmissionChainDrive simulating a + * set of parallel-axes gears, intersecting-axes beveled gears or + * chain and sprockets respectively. + * @ingroup joints + */ +ODE_API void dJointSetTransmissionMode( dJointID j, int mode ); + +/** + * @brief get the Transmission joint mode + * @ingroup joints + */ +ODE_API int dJointGetTransmissionMode( dJointID j ); + +/** + * @brief set the Transmission ratio + * @remarks This is the ratio of the angular speed of the first gear + * to that of the second gear. It can only be set explicitly in + * parallel-axes mode. In intersecting-axes mode the ratio is defined + * implicitly by the initial configuration of the wheels and in chain + * mode it is defined implicitly be the wheel radii. + * @ingroup joints + */ +ODE_API void dJointSetTransmissionRatio( dJointID j, dReal ratio ); + +/** + * @brief get the Transmission joint ratio + * @ingroup joints + */ +ODE_API dReal dJointGetTransmissionRatio( dJointID j ); + +/** + * @brief set the common axis for both wheels of the Transmission joint + * @remarks This sets the common axis of revolution for both wheels + * and should only be used in parallel-axes or chain mode. For + * intersecting-axes mode where each wheel axis needs to be specified + * individually dJointSetTransmissionAxis1 and + * dJointSetTransmissionAxis2 should be used. The axis is given in + * global coordinates + * @ingroup joints + */ +ODE_API void dJointSetTransmissionAxis( dJointID j, dReal x, dReal y, dReal z ); + +/** + * @brief get the common axis for both wheels of the Transmission joint + * @ingroup joints + */ +ODE_API void dJointGetTransmissionAxis( dJointID j, dVector3 result ); + +/** + * @brief get the phase, that is the traversed angle for the first + * wheel of the Transmission joint + * @ingroup joints + */ +ODE_API dReal dJointGetTransmissionAngle1( dJointID j ); + +/** + * @brief get the phase, that is the traversed angle for the second + * wheel of the Transmission joint + * @ingroup joints + */ +ODE_API dReal dJointGetTransmissionAngle2( dJointID j ); + +/** + * @brief get the radius of the first wheel of the Transmission joint + * @ingroup joints + */ +ODE_API dReal dJointGetTransmissionRadius1( dJointID j ); + +/** + * @brief get the radius of the second wheel of the Transmission joint + * @ingroup joints + */ +ODE_API dReal dJointGetTransmissionRadius2( dJointID j ); + +/** + * @brief set the radius of the first wheel of the Transmission joint + * @remarks The wheel radii can only be set explicitly in chain mode. + * In the other modes they're defined implicitly by the initial + * configuration and ratio of the wheels. + * @ingroup joints + */ +ODE_API void dJointSetTransmissionRadius1( dJointID j, dReal radius ); + +/** + * @brief set the radius of the second wheel of the Transmission joint + * @remarks The wheel radii can only be set explicitly in chain mode. + * In the other modes they're defined implicitly by the initial + * configuration and ratio of the wheels. + * @ingroup joints + */ +ODE_API void dJointSetTransmissionRadius2( dJointID j, dReal radius ); + +/** + * @brief get the backlash of the Transmission joint + * @ingroup joints + */ +ODE_API dReal dJointGetTransmissionBacklash( dJointID j ); + +/** + * @brief set the backlash of the Transmission joint + * @remarks Backlash is the clearance in the mesh of the wheels of the + * transmission and is defined as the maximum distance that the + * geometric contact point can travel without any actual contact or + * transfer of power between the wheels. This can be converted in + * degrees of revolution for each wheel by dividing by the wheel's + * radius. To further illustrate this consider the situation where a + * wheel of radius r_1 is driving another wheel of radius r_2 and + * there is an amount of backlash equal to b in their mesh. If the + * driving wheel were to instantaneously stop there would be no + * contact and hence the driven wheel would continue to turn for + * another b / r_2 radians until all the backlash in the mesh was take + * up and contact restored with the relationship of driving and driven + * wheel reversed. The backlash is therefore given in untis of + * length. + * @ingroup joints + */ +ODE_API void dJointSetTransmissionBacklash( dJointID j, dReal backlash ); + +/** + * @brief set anchor1 for double ball joint + * @ingroup joints + */ +ODE_API void dJointSetDBallAnchor1(dJointID, dReal x, dReal y, dReal z); + +/** + * @brief set anchor2 for double ball joint + * @ingroup joints + */ +ODE_API void dJointSetDBallAnchor2(dJointID, dReal x, dReal y, dReal z); + +/** + * @brief get anchor1 from double ball joint + * @ingroup joints + */ +ODE_API void dJointGetDBallAnchor1(dJointID, dVector3 result); + +/** + * @brief get anchor2 from double ball joint + * @ingroup joints + */ +ODE_API void dJointGetDBallAnchor2(dJointID, dVector3 result); + +/** + * @brief get the target distance from double ball joint + * @ingroup joints + */ +ODE_API dReal dJointGetDBallDistance(dJointID); + +/** + * @brief set the target distance for the double ball joint + * @ingroup joints + */ +ODE_API void dJointSetDBallDistance(dJointID, dReal dist); + +/** + * @brief set double ball joint parameter + * @ingroup joints + */ +ODE_API void dJointSetDBallParam(dJointID, int parameter, dReal value); + +/** + * @brief get double ball joint parameter + * @ingroup joints + */ +ODE_API dReal dJointGetDBallParam(dJointID, int parameter); + +/** + * @brief set axis for double hinge joint + * @ingroup joints + */ +ODE_API void dJointSetDHingeAxis(dJointID, dReal x, dReal y, dReal z); + +/** + * @brief get axis for double hinge joint + * @ingroup joints + */ +ODE_API void dJointGetDHingeAxis(dJointID, dVector3 result); + +/** + * @brief set anchor1 for double hinge joint + * @ingroup joints + */ +ODE_API void dJointSetDHingeAnchor1(dJointID, dReal x, dReal y, dReal z); + +/** + * @brief set anchor2 for double hinge joint + * @ingroup joints + */ +ODE_API void dJointSetDHingeAnchor2(dJointID, dReal x, dReal y, dReal z); + +/** + * @brief get anchor1 from double hinge joint + * @ingroup joints + */ +ODE_API void dJointGetDHingeAnchor1(dJointID, dVector3 result); + +/** + * @brief get anchor2 from double hinge joint + * @ingroup joints + */ +ODE_API void dJointGetDHingeAnchor2(dJointID, dVector3 result); + +/** + * @brief get the set distance from double hinge joint + * @ingroup joints + */ +ODE_API dReal dJointGetDHingeDistance(dJointID); + +/** + * @brief set double hinge joint parameter + * @ingroup joints + */ +ODE_API void dJointSetDHingeParam(dJointID, int parameter, dReal value); + +/** + * @brief get double hinge joint parameter + * @ingroup joints + */ +ODE_API dReal dJointGetDHingeParam(dJointID, int parameter); + + + + +/** + * @ingroup joints + */ +ODE_API dJointID dConnectingJoint (dBodyID, dBodyID); + +/** + * @ingroup joints + */ +ODE_API int dConnectingJointList (dBodyID, dBodyID, dJointID*); + +/** + * @brief Utility function + * @return 1 if the two bodies are connected together by + * a joint, otherwise return 0. + * @ingroup joints + */ +ODE_API int dAreConnected (dBodyID, dBodyID); + +/** + * @brief Utility function + * @return 1 if the two bodies are connected together by + * a joint that does not have type @arg{joint_type}, otherwise return 0. + * @param body1 A body to check. + * @param body2 A body to check. + * @param joint_type is a dJointTypeXXX constant. + * This is useful for deciding whether to add contact joints between two bodies: + * if they are already connected by non-contact joints then it may not be + * appropriate to add contacts, however it is okay to add more contact between- + * bodies that already have contacts. + * @ingroup joints + */ +ODE_API int dAreConnectedExcluding (dBodyID body1, dBodyID body2, int joint_type); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/ode-0.16.1/include/ode/ode.h b/libs/ode-0.16.1/include/ode/ode.h new file mode 100644 index 0000000..a69f46a --- /dev/null +++ b/libs/ode-0.16.1/include/ode/ode.h @@ -0,0 +1,56 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_ODE_H_ +#define _ODE_ODE_H_ + +/* include *everything* here */ + +#include <ode/odeconfig.h> +#include <ode/compatibility.h> +#include <ode/common.h> +#include <ode/odeinit.h> +#include <ode/contact.h> +#include <ode/error.h> +#include <ode/memory.h> +#include <ode/odemath.h> +#include <ode/matrix.h> +#include <ode/matrix_coop.h> +#include <ode/timer.h> +#include <ode/rotation.h> +#include <ode/mass.h> +#include <ode/misc.h> +#include <ode/objects.h> +#include <ode/collision_space.h> +#include <ode/collision.h> +#include <ode/threading.h> +#include <ode/threading_impl.h> +#include <ode/cooperative.h> +#include <ode/export-dif.h> +#include <ode/version.h> + +#ifdef __cplusplus +# include <ode/odecpp.h> +# include <ode/odecpp_collision.h> +#endif + +#endif diff --git a/libs/ode-0.16.1/include/ode/odeconfig.h b/libs/ode-0.16.1/include/ode/odeconfig.h new file mode 100644 index 0000000..1a0c747 --- /dev/null +++ b/libs/ode-0.16.1/include/ode/odeconfig.h @@ -0,0 +1,218 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_ODECONFIG_H_ +#define _ODE_ODECONFIG_H_ + +/* Pull in the standard headers */ +#include <stddef.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <math.h> +#include <string.h> +#include <float.h> + + +#include <ode/precision.h> + + +#if defined(ODE_DLL) || defined(ODE_LIB) +#define __ODE__ +#endif + +/* Define a DLL export symbol for those platforms that need it */ +#if defined(_MSC_VER) || (defined(__GNUC__) && defined(_WIN32)) + #if defined(ODE_DLL) + #define ODE_API __declspec(dllexport) + #else + #define ODE_API + #endif +#endif + +#if !defined(ODE_API) + #define ODE_API +#endif + +#if defined(_MSC_VER) +# define ODE_API_DEPRECATED __declspec(deprecated) +#elif defined (__GNUC__) && ( (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)) ) +# define ODE_API_DEPRECATED __attribute__((__deprecated__)) +#else +# define ODE_API_DEPRECATED +#endif + +#define ODE_PURE_INLINE static __inline +#define ODE_INLINE __inline + +#if defined(__cplusplus) + #define ODE_EXTERN_C extern "C" +#else + #define ODE_EXTERN_C +#endif + +#if defined(__GNUC__) +#define ODE_NORETURN __attribute__((noreturn)) +#elif defined(_MSC_VER) +#define ODE_NORETURN __declspec(noreturn) +#else // #if !defined(_MSC_VER) +#define ODE_NORETURN +#endif // #if !defined(__GNUC__) + + +/* Well-defined common data types...need to be defined for 64 bit systems */ +#if defined(__aarch64__) || defined(__alpha__) || defined(__ppc64__) \ + || defined(__s390__) || defined(__s390x__) || defined(__zarch__) \ + || defined(__mips__) || defined(__powerpc64__) || defined(__riscv) \ + || (defined(__sparc__) && defined(__arch64__)) + #include <stdint.h> + typedef int64_t dint64; + typedef uint64_t duint64; + typedef int32_t dint32; + typedef uint32_t duint32; + typedef int16_t dint16; + typedef uint16_t duint16; + typedef int8_t dint8; + typedef uint8_t duint8; + + typedef intptr_t dintptr; + typedef uintptr_t duintptr; + typedef ptrdiff_t ddiffint; + typedef size_t dsizeint; + +#elif (defined(_M_IA64) || defined(__ia64__) || defined(_M_AMD64) || defined(__x86_64__)) && !defined(__ILP32__) && !defined(_ILP32) + #define X86_64_SYSTEM 1 +#if defined(_MSC_VER) + typedef __int64 dint64; + typedef unsigned __int64 duint64; +#else +#if defined(_LP64) || defined(__LP64__) +typedef long dint64; +typedef unsigned long duint64; +#else + typedef long long dint64; + typedef unsigned long long duint64; +#endif +#endif + typedef int dint32; + typedef unsigned int duint32; + typedef short dint16; + typedef unsigned short duint16; + typedef signed char dint8; + typedef unsigned char duint8; + + typedef dint64 dintptr; + typedef duint64 duintptr; + typedef dint64 ddiffint; + typedef duint64 dsizeint; + +#else +#if defined(_MSC_VER) + typedef __int64 dint64; + typedef unsigned __int64 duint64; +#else + typedef long long dint64; + typedef unsigned long long duint64; +#endif + typedef int dint32; + typedef unsigned int duint32; + typedef short dint16; + typedef unsigned short duint16; + typedef signed char dint8; + typedef unsigned char duint8; + + typedef dint32 dintptr; + typedef duint32 duintptr; + typedef dint32 ddiffint; + typedef duint32 dsizeint; + +#endif + + +/* Define the dInfinity macro */ +#ifdef INFINITY + #ifdef dSINGLE + #define dInfinity ((float)INFINITY) + #else + #define dInfinity ((double)INFINITY) + #endif +#elif defined(HUGE_VAL) + #ifdef dSINGLE + #ifdef HUGE_VALF + #define dInfinity HUGE_VALF + #else + #define dInfinity ((float)HUGE_VAL) + #endif + #else + #define dInfinity HUGE_VAL + #endif +#else + #ifdef dSINGLE + #define dInfinity ((float)(1.0/0.0)) + #else + #define dInfinity (1.0/0.0) + #endif +#endif + + +/* Define the dNaN macro */ +#if defined(NAN) + #define dNaN NAN +#elif defined(__GNUC__) + #define dNaN ({ union { duint32 m_ui; float m_f; } un; un.m_ui = 0x7FC00000; un.m_f; }) +#elif defined(__cplusplus) + union _dNaNUnion + { + _dNaNUnion(): m_ui(0x7FC00000) {} + duint32 m_ui; + float m_f; + }; + #define dNaN (_dNaNUnion().m_f) +#else + #ifdef dSINGLE + #define dNaN ((float)(dInfinity - dInfinity)) + #else + #define dNaN (dInfinity - dInfinity) + #endif +#endif + + + /* Visual C does not define these functions */ +#if defined(_MSC_VER) + #define _ode_copysignf(x, y) ((float)_copysign(x, y)) + #define _ode_copysign(x, y) _copysign(x, y) + #define _ode_nextafterf(x, y) _nextafterf(x, y) + #define _ode_nextafter(x, y) _nextafter(x, y) + #if !defined(_WIN64) && defined(dSINGLE) + #define _ODE__NEXTAFTERF_REQUIRED + ODE_EXTERN_C float _nextafterf(float x, float y); + #endif +#else + #define _ode_copysignf(x, y) copysignf(x, y) + #define _ode_copysign(x, y) copysign(x, y) + #define _ode_nextafterf(x, y) nextafterf(x, y) + #define _ode_nextafter(x, y) nextafter(x, y) +#endif + + +#endif diff --git a/libs/ode-0.16.1/include/ode/odecpp.h b/libs/ode-0.16.1/include/ode/odecpp.h new file mode 100644 index 0000000..f604d0d --- /dev/null +++ b/libs/ode-0.16.1/include/ode/odecpp.h @@ -0,0 +1,1355 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* C++ interface for non-collision stuff */ + + +#ifndef _ODE_ODECPP_H_ +#define _ODE_ODECPP_H_ +#ifdef __cplusplus + + + + +//namespace ode { + + +class dWorldSimpleIDContainer { +protected: + dWorldID _id; + + dWorldSimpleIDContainer(): _id(0) {} + ~dWorldSimpleIDContainer() { destroy(); } + + void destroy() { + if (_id) { + dWorldDestroy(_id); + _id = 0; + } + } +}; + +class dWorldDynamicIDContainer: public dWorldSimpleIDContainer { +protected: + virtual ~dWorldDynamicIDContainer() {} +}; + +template <class dWorldTemplateBase> +class dWorldTemplate: public dWorldTemplateBase { + // intentionally undefined, don't use these + dWorldTemplate (const dWorldTemplate<dWorldTemplateBase> &); + void operator= (const dWorldTemplate<dWorldTemplateBase> &); + +protected: + dWorldID get_id() const { return dWorldTemplateBase::_id; } + void set_id(dWorldID value) { dWorldTemplateBase::_id = value; } + +public: + dWorldTemplate() + { set_id(dWorldCreate()); } + + dWorldID id() const + { return get_id(); } + operator dWorldID() const + { return get_id(); } + + void setGravity (dReal x, dReal y, dReal z) + { dWorldSetGravity (get_id(), x, y, z); } + void setGravity (const dVector3 g) + { setGravity (g[0], g[1], g[2]); } + void getGravity (dVector3 g) const + { dWorldGetGravity (get_id(), g); } + + void setERP (dReal erp) + { dWorldSetERP(get_id(), erp); } + dReal getERP() const + { return dWorldGetERP(get_id()); } + + void setCFM (dReal cfm) + { dWorldSetCFM(get_id(), cfm); } + dReal getCFM() const + { return dWorldGetCFM(get_id()); } + + void step (dReal stepsize) + { dWorldStep (get_id(), stepsize); } + + void quickStep(dReal stepsize) + { dWorldQuickStep (get_id(), stepsize); } + void setQuickStepNumIterations(int num) + { dWorldSetQuickStepNumIterations (get_id(), num); } + int getQuickStepNumIterations() const + { return dWorldGetQuickStepNumIterations (get_id()); } + void setQuickStepW(dReal over_relaxation) + { dWorldSetQuickStepW (get_id(), over_relaxation); } + dReal getQuickStepW() const + { return dWorldGetQuickStepW (get_id()); } + + void setAutoDisableLinearThreshold (dReal threshold) + { dWorldSetAutoDisableLinearThreshold (get_id(), threshold); } + dReal getAutoDisableLinearThreshold() const + { return dWorldGetAutoDisableLinearThreshold (get_id()); } + void setAutoDisableAngularThreshold (dReal threshold) + { dWorldSetAutoDisableAngularThreshold (get_id(), threshold); } + dReal getAutoDisableAngularThreshold() const + { return dWorldGetAutoDisableAngularThreshold (get_id()); } + void setAutoDisableSteps (int steps) + { dWorldSetAutoDisableSteps (get_id(), steps); } + int getAutoDisableSteps() const + { return dWorldGetAutoDisableSteps (get_id()); } + void setAutoDisableTime (dReal time) + { dWorldSetAutoDisableTime (get_id(), time); } + dReal getAutoDisableTime() const + { return dWorldGetAutoDisableTime (get_id()); } + void setAutoDisableFlag (int do_auto_disable) + { dWorldSetAutoDisableFlag (get_id(), do_auto_disable); } + int getAutoDisableFlag() const + { return dWorldGetAutoDisableFlag (get_id()); } + + dReal getLinearDampingThreshold() const + { return dWorldGetLinearDampingThreshold(get_id()); } + void setLinearDampingThreshold(dReal threshold) + { dWorldSetLinearDampingThreshold(get_id(), threshold); } + dReal getAngularDampingThreshold() const + { return dWorldGetAngularDampingThreshold(get_id()); } + void setAngularDampingThreshold(dReal threshold) + { dWorldSetAngularDampingThreshold(get_id(), threshold); } + dReal getLinearDamping() const + { return dWorldGetLinearDamping(get_id()); } + void setLinearDamping(dReal scale) + { dWorldSetLinearDamping(get_id(), scale); } + dReal getAngularDamping() const + { return dWorldGetAngularDamping(get_id()); } + void setAngularDamping(dReal scale) + { dWorldSetAngularDamping(get_id(), scale); } + void setDamping(dReal linear_scale, dReal angular_scale) + { dWorldSetDamping(get_id(), linear_scale, angular_scale); } + + dReal getMaxAngularSpeed() const + { return dWorldGetMaxAngularSpeed(get_id()); } + void setMaxAngularSpeed(dReal max_speed) + { dWorldSetMaxAngularSpeed(get_id(), max_speed); } + + void setContactSurfaceLayer(dReal depth) + { dWorldSetContactSurfaceLayer (get_id(), depth); } + dReal getContactSurfaceLayer() const + { return dWorldGetContactSurfaceLayer (get_id()); } + + void impulseToForce (dReal stepsize, dReal ix, dReal iy, dReal iz, + dVector3 force) + { dWorldImpulseToForce (get_id(), stepsize, ix, iy, iz, force); } +}; + + +class dBodySimpleIDContainer { +protected: + dBodyID _id; + + dBodySimpleIDContainer(): _id(0) {} + ~dBodySimpleIDContainer() { destroy(); } + + void destroy() { + if (_id) { + dBodyDestroy(_id); + _id = 0; + } + } +}; + +class dBodyDynamicIDContainer: public dBodySimpleIDContainer { +protected: + virtual ~dBodyDynamicIDContainer() {} +}; + +template <class dBodyTemplateBase, class dWorldTemplateBase> +class dBodyTemplate: public dBodyTemplateBase { + // intentionally undefined, don't use these + dBodyTemplate (const dBodyTemplate<dBodyTemplateBase, dWorldTemplateBase> &); + void operator= (const dBodyTemplate<dBodyTemplateBase, dWorldTemplateBase> &); + +protected: + dBodyID get_id() const { return dBodyTemplateBase::_id; } + void set_id(dBodyID value) { dBodyTemplateBase::_id = value; } + + void destroy() { dBodyTemplateBase::destroy(); } + +public: + dBodyTemplate() + { } + dBodyTemplate (dWorldID world) + { set_id(dBodyCreate(world)); } + dBodyTemplate (dWorldTemplate<dWorldTemplateBase>& world) + { set_id(dBodyCreate(world.id())); } + + void create (dWorldID world) { + destroy(); + set_id(dBodyCreate(world)); + } + void create (dWorldTemplate<dWorldTemplateBase>& world) { + create(world.id()); + } + + dBodyID id() const + { return get_id(); } + operator dBodyID() const + { return get_id(); } + + void setData (void *data) + { dBodySetData (get_id(), data); } + void *getData() const + { return dBodyGetData (get_id()); } + + void setPosition (dReal x, dReal y, dReal z) + { dBodySetPosition (get_id(), x, y, z); } + void setPosition (const dVector3 p) + { setPosition(p[0], p[1], p[2]); } + + void setRotation (const dMatrix3 R) + { dBodySetRotation (get_id(), R); } + void setQuaternion (const dQuaternion q) + { dBodySetQuaternion (get_id(), q); } + void setLinearVel (dReal x, dReal y, dReal z) + { dBodySetLinearVel (get_id(), x, y, z); } + void setLinearVel (const dVector3 v) + { setLinearVel(v[0], v[1], v[2]); } + void setAngularVel (dReal x, dReal y, dReal z) + { dBodySetAngularVel (get_id(), x, y, z); } + void setAngularVel (const dVector3 v) + { setAngularVel (v[0], v[1], v[2]); } + + const dReal * getPosition() const + { return dBodyGetPosition (get_id()); } + const dReal * getRotation() const + { return dBodyGetRotation (get_id()); } + const dReal * getQuaternion() const + { return dBodyGetQuaternion (get_id()); } + const dReal * getLinearVel() const + { return dBodyGetLinearVel (get_id()); } + const dReal * getAngularVel() const + { return dBodyGetAngularVel (get_id()); } + + void setMass (const dMass *mass) + { dBodySetMass (get_id(), mass); } + void setMass (const dMass &mass) + { setMass (&mass); } + dMass getMass () const + { dMass mass; dBodyGetMass (get_id(), &mass); return mass; } + + void addForce (dReal fx, dReal fy, dReal fz) + { dBodyAddForce (get_id(), fx, fy, fz); } + void addForce (const dVector3 f) + { addForce (f[0], f[1], f[2]); } + void addTorque (dReal fx, dReal fy, dReal fz) + { dBodyAddTorque (get_id(), fx, fy, fz); } + void addTorque (const dVector3 t) + { addTorque(t[0], t[1], t[2]); } + + void addRelForce (dReal fx, dReal fy, dReal fz) + { dBodyAddRelForce (get_id(), fx, fy, fz); } + void addRelForce (const dVector3 f) + { addRelForce (f[0], f[1], f[2]); } + void addRelTorque (dReal fx, dReal fy, dReal fz) + { dBodyAddRelTorque (get_id(), fx, fy, fz); } + void addRelTorque (const dVector3 t) + { addRelTorque (t[0], t[1], t[2]); } + + void addForceAtPos (dReal fx, dReal fy, dReal fz, + dReal px, dReal py, dReal pz) + { dBodyAddForceAtPos (get_id(), fx, fy, fz, px, py, pz); } + void addForceAtPos (const dVector3 f, const dVector3 p) + { addForceAtPos (f[0], f[1], f[2], p[0], p[1], p[2]); } + + void addForceAtRelPos (dReal fx, dReal fy, dReal fz, + dReal px, dReal py, dReal pz) + { dBodyAddForceAtRelPos (get_id(), fx, fy, fz, px, py, pz); } + void addForceAtRelPos (const dVector3 f, const dVector3 p) + { addForceAtRelPos (f[0], f[1], f[2], p[0], p[1], p[2]); } + + void addRelForceAtPos (dReal fx, dReal fy, dReal fz, + dReal px, dReal py, dReal pz) + { dBodyAddRelForceAtPos (get_id(), fx, fy, fz, px, py, pz); } + void addRelForceAtPos (const dVector3 f, const dVector3 p) + { addRelForceAtPos (f[0], f[1], f[2], p[0], p[1], p[2]); } + + void addRelForceAtRelPos (dReal fx, dReal fy, dReal fz, + dReal px, dReal py, dReal pz) + { dBodyAddRelForceAtRelPos (get_id(), fx, fy, fz, px, py, pz); } + void addRelForceAtRelPos (const dVector3 f, const dVector3 p) + { addRelForceAtRelPos (f[0], f[1], f[2], p[0], p[1], p[2]); } + + const dReal * getForce() const + { return dBodyGetForce(get_id()); } + const dReal * getTorque() const + { return dBodyGetTorque(get_id()); } + void setForce (dReal x, dReal y, dReal z) + { dBodySetForce (get_id(), x, y, z); } + void setForce (const dVector3 f) + { setForce (f[0], f[1], f[2]); } + void setTorque (dReal x, dReal y, dReal z) + { dBodySetTorque (get_id(), x, y, z); } + void setTorque (const dVector3 t) + { setTorque (t[0], t[1], t[2]); } + + void setDynamic() + { dBodySetDynamic (get_id()); } + void setKinematic() + { dBodySetKinematic (get_id()); } + bool isKinematic() const + { return dBodyIsKinematic (get_id()) != 0; } + + void enable() + { dBodyEnable (get_id()); } + void disable() + { dBodyDisable (get_id()); } + bool isEnabled() const + { return dBodyIsEnabled (get_id()) != 0; } + + void getRelPointPos (dReal px, dReal py, dReal pz, dVector3 result) const + { dBodyGetRelPointPos (get_id(), px, py, pz, result); } + void getRelPointPos (const dVector3 p, dVector3 result) const + { getRelPointPos (p[0], p[1], p[2], result); } + + void getRelPointVel (dReal px, dReal py, dReal pz, dVector3 result) const + { dBodyGetRelPointVel (get_id(), px, py, pz, result); } + void getRelPointVel (const dVector3 p, dVector3 result) const + { getRelPointVel (p[0], p[1], p[2], result); } + + void getPointVel (dReal px, dReal py, dReal pz, dVector3 result) const + { dBodyGetPointVel (get_id(), px, py, pz, result); } + void getPointVel (const dVector3 p, dVector3 result) const + { getPointVel (p[0], p[1], p[2], result); } + + void getPosRelPoint (dReal px, dReal py, dReal pz, dVector3 result) const + { dBodyGetPosRelPoint (get_id(), px, py, pz, result); } + void getPosRelPoint (const dVector3 p, dVector3 result) const + { getPosRelPoint (p[0], p[1], p[2], result); } + + void vectorToWorld (dReal px, dReal py, dReal pz, dVector3 result) const + { dBodyVectorToWorld (get_id(), px, py, pz, result); } + void vectorToWorld (const dVector3 p, dVector3 result) const + { vectorToWorld (p[0], p[1], p[2], result); } + + void vectorFromWorld (dReal px, dReal py, dReal pz, dVector3 result) const + { dBodyVectorFromWorld (get_id(), px, py, pz, result); } + void vectorFromWorld (const dVector3 p, dVector3 result) const + { vectorFromWorld (p[0], p[1], p[2], result); } + + void setFiniteRotationMode (bool mode) + { dBodySetFiniteRotationMode (get_id(), mode); } + + void setFiniteRotationAxis (dReal x, dReal y, dReal z) + { dBodySetFiniteRotationAxis (get_id(), x, y, z); } + void setFiniteRotationAxis (const dVector3 a) + { setFiniteRotationAxis (a[0], a[1], a[2]); } + + bool getFiniteRotationMode() const + { return dBodyGetFiniteRotationMode (get_id()) != 0; } + void getFiniteRotationAxis (dVector3 result) const + { dBodyGetFiniteRotationAxis (get_id(), result); } + + int getNumJoints() const + { return dBodyGetNumJoints (get_id()); } + dJointID getJoint (int index) const + { return dBodyGetJoint (get_id(), index); } + + void setGravityMode (bool mode) + { dBodySetGravityMode (get_id(), mode); } + bool getGravityMode() const + { return dBodyGetGravityMode (get_id()) != 0; } + + bool isConnectedTo (dBodyID body) const + { return dAreConnected (get_id(), body) != 0; } + + void setAutoDisableLinearThreshold (dReal threshold) + { dBodySetAutoDisableLinearThreshold (get_id(), threshold); } + dReal getAutoDisableLinearThreshold() const + { return dBodyGetAutoDisableLinearThreshold (get_id()); } + void setAutoDisableAngularThreshold (dReal threshold) + { dBodySetAutoDisableAngularThreshold (get_id(), threshold); } + dReal getAutoDisableAngularThreshold() const + { return dBodyGetAutoDisableAngularThreshold (get_id()); } + void setAutoDisableSteps (int steps) + { dBodySetAutoDisableSteps (get_id(), steps); } + int getAutoDisableSteps() const + { return dBodyGetAutoDisableSteps (get_id()); } + void setAutoDisableTime (dReal time) + { dBodySetAutoDisableTime (get_id(), time); } + dReal getAutoDisableTime() const + { return dBodyGetAutoDisableTime (get_id()); } + void setAutoDisableFlag (bool do_auto_disable) + { dBodySetAutoDisableFlag (get_id(), do_auto_disable); } + bool getAutoDisableFlag() const + { return dBodyGetAutoDisableFlag (get_id()) != 0; } + + dReal getLinearDamping() const + { return dBodyGetLinearDamping(get_id()); } + void setLinearDamping(dReal scale) + { dBodySetLinearDamping(get_id(), scale); } + dReal getAngularDamping() const + { return dBodyGetAngularDamping(get_id()); } + void setAngularDamping(dReal scale) + { dBodySetAngularDamping(get_id(), scale); } + void setDamping(dReal linear_scale, dReal angular_scale) + { dBodySetDamping(get_id(), linear_scale, angular_scale); } + dReal getLinearDampingThreshold() const + { return dBodyGetLinearDampingThreshold(get_id()); } + void setLinearDampingThreshold(dReal threshold) const + { dBodySetLinearDampingThreshold(get_id(), threshold); } + dReal getAngularDampingThreshold() const + { return dBodyGetAngularDampingThreshold(get_id()); } + void setAngularDampingThreshold(dReal threshold) + { dBodySetAngularDampingThreshold(get_id(), threshold); } + void setDampingDefaults() + { dBodySetDampingDefaults(get_id()); } + + dReal getMaxAngularSpeed() const + { return dBodyGetMaxAngularSpeed(get_id()); } + void setMaxAngularSpeed(dReal max_speed) + { dBodySetMaxAngularSpeed(get_id(), max_speed); } + + bool getGyroscopicMode() const + { return dBodyGetGyroscopicMode(get_id()) != 0; } + void setGyroscopicMode(bool mode) + { dBodySetGyroscopicMode(get_id(), mode); } + +}; + + +class dJointGroupSimpleIDContainer { +protected: + dJointGroupID _id; + + dJointGroupSimpleIDContainer(): _id(0) {} + ~dJointGroupSimpleIDContainer() { destroy(); } + + void destroy() { + if (_id) { + dJointGroupDestroy(_id); + _id = 0; + } + } +}; + +class dJointGroupDynamicIDContainer: public dJointGroupSimpleIDContainer { +protected: + virtual ~dJointGroupDynamicIDContainer() {} +}; + +template <class dJointGroupTemplateBase> +class dJointGroupTemplate: public dJointGroupTemplateBase { + // intentionally undefined, don't use these + dJointGroupTemplate (const dJointGroupTemplate<dJointGroupTemplateBase> &); + void operator= (const dJointGroupTemplate<dJointGroupTemplateBase> &); + +protected: + dJointGroupID get_id() const { return dJointGroupTemplateBase::_id; } + void set_id(dJointGroupID value) { dJointGroupTemplateBase::_id = value; } + + void destroy() { dJointGroupTemplateBase::destroy(); } + +public: + dJointGroupTemplate () + { set_id(dJointGroupCreate(0)); } + + void create () { + destroy(); + set_id(dJointGroupCreate(0)); + } + + dJointGroupID id() const + { return get_id(); } + operator dJointGroupID() const + { return get_id(); } + + void empty() + { dJointGroupEmpty (get_id()); } + void clear() + { empty(); } +}; + + +class dJointSimpleIDContainer { +protected: + dJointID _id; + + dJointSimpleIDContainer(): _id(0) {} + ~dJointSimpleIDContainer() { destroy(); } + + void destroy() { + if (_id) { + dJointDestroy (_id); + _id = 0; + } + } +}; + +class dJointDynamicIDContainer: public dJointSimpleIDContainer { +protected: + virtual ~dJointDynamicIDContainer() {} +}; + +template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase> +class dJointTemplate: public dJointTemplateBase { +private: + // intentionally undefined, don't use these + dJointTemplate (const dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &) ; + void operator= (const dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &); + +protected: + dJointID get_id() const { return dJointTemplateBase::_id; } + void set_id(dJointID value) { dJointTemplateBase::_id = value; } + + void destroy() { dJointTemplateBase::destroy(); } + +protected: + dJointTemplate() // don't let user construct pure dJointTemplate objects + { } + +public: + dJointID id() const + { return get_id(); } + operator dJointID() const + { return get_id(); } + + int getNumBodies() const + { return dJointGetNumBodies(get_id()); } + + void attach (dBodyID body1, dBodyID body2) + { dJointAttach (get_id(), body1, body2); } + void attach (dBodyTemplate<dBodyTemplateBase, dWorldTemplateBase>& body1, dBodyTemplate<dBodyTemplateBase, dWorldTemplateBase>& body2) + { attach(body1.id(), body2.id()); } + + void enable() + { dJointEnable (get_id()); } + void disable() + { dJointDisable (get_id()); } + bool isEnabled() const + { return dJointIsEnabled (get_id()) != 0; } + + void setData (void *data) + { dJointSetData (get_id(), data); } + void *getData() const + { return dJointGetData (get_id()); } + + dJointType getType() const + { return dJointGetType (get_id()); } + + dBodyID getBody (int index) const + { return dJointGetBody (get_id(), index); } + + void setFeedback(dJointFeedback *fb) + { dJointSetFeedback(get_id(), fb); } + dJointFeedback *getFeedback() const + { return dJointGetFeedback(get_id()); } + + // If not implemented it will do nothing as describe in the doc + virtual void setParam (int, dReal) {}; + virtual dReal getParam (int) const { return 0; } +}; + + +template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase> +class dBallJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> { +private: + // intentionally undefined, don't use these + dBallJointTemplate (const dBallJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &); + void operator= (const dBallJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &); + +protected: + typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate; + + dJointID get_id() const { return dBaseTemplate::get_id(); } + void set_id(dJointID value) { dBaseTemplate::set_id(value); } + + void destroy() { dBaseTemplate::destroy(); } + +public: + dBallJointTemplate() { } + dBallJointTemplate (dWorldID world, dJointGroupID group=0) + { set_id(dJointCreateBall(world, group)); } + dBallJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0) + { set_id(dJointCreateBall(world.id(), group)); } + + void create (dWorldID world, dJointGroupID group=0) { + destroy(); + set_id(dJointCreateBall(world, group)); + } + void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0) + { create(world.id(), group); } + + void setAnchor (dReal x, dReal y, dReal z) + { dJointSetBallAnchor (get_id(), x, y, z); } + void setAnchor (const dVector3 a) + { setAnchor (a[0], a[1], a[2]); } + void getAnchor (dVector3 result) const + { dJointGetBallAnchor (get_id(), result); } + void getAnchor2 (dVector3 result) const + { dJointGetBallAnchor2 (get_id(), result); } + virtual void setParam (int parameter, dReal value) + { dJointSetBallParam (get_id(), parameter, value); } + virtual dReal getParam (int parameter) const + { return dJointGetBallParam (get_id(), parameter); } + // TODO: expose params through methods +} ; + + +template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase> +class dHingeJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> { +private: + // intentionally undefined, don't use these + dHingeJointTemplate (const dHingeJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &); + void operator = (const dHingeJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &); + +protected: + typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate; + + dJointID get_id() const { return dBaseTemplate::get_id(); } + void set_id(dJointID value) { dBaseTemplate::set_id(value); } + + void destroy() { dBaseTemplate::destroy(); } + +public: + dHingeJointTemplate() { } + dHingeJointTemplate (dWorldID world, dJointGroupID group=0) + { set_id(dJointCreateHinge(world, group)); } + dHingeJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0) + { set_id(dJointCreateHinge(world.id(), group)); } + + void create (dWorldID world, dJointGroupID group=0) { + destroy(); + set_id(dJointCreateHinge (world, group)); + } + void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0) + { create(world.id(), group); } + + void setAnchor (dReal x, dReal y, dReal z) + { dJointSetHingeAnchor (get_id(), x, y, z); } + void setAnchor (const dVector3 a) + { setAnchor (a[0], a[1], a[2]); } + void getAnchor (dVector3 result) const + { dJointGetHingeAnchor (get_id(), result); } + void getAnchor2 (dVector3 result) const + { dJointGetHingeAnchor2 (get_id(), result); } + + void setAxis (dReal x, dReal y, dReal z) + { dJointSetHingeAxis (get_id(), x, y, z); } + void setAxis (const dVector3 a) + { setAxis(a[0], a[1], a[2]); } + void getAxis (dVector3 result) const + { dJointGetHingeAxis (get_id(), result); } + + dReal getAngle() const + { return dJointGetHingeAngle (get_id()); } + dReal getAngleRate() const + { return dJointGetHingeAngleRate (get_id()); } + + virtual void setParam (int parameter, dReal value) + { dJointSetHingeParam (get_id(), parameter, value); } + virtual dReal getParam (int parameter) const + { return dJointGetHingeParam (get_id(), parameter); } + // TODO: expose params through methods + + void addTorque (dReal torque) + { dJointAddHingeTorque(get_id(), torque); } +}; + + +template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase> +class dSliderJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> { +private: + // intentionally undefined, don't use these + dSliderJointTemplate (const dSliderJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &); + void operator = (const dSliderJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &); + +protected: + typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate; + + dJointID get_id() const { return dBaseTemplate::get_id(); } + void set_id(dJointID value) { dBaseTemplate::set_id(value); } + + void destroy() { dBaseTemplate::destroy(); } + +public: + dSliderJointTemplate() { } + dSliderJointTemplate (dWorldID world, dJointGroupID group=0) + { set_id(dJointCreateSlider(world, group)); } + dSliderJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0) + { set_id(dJointCreateSlider(world.id(), group)); } + + void create (dWorldID world, dJointGroupID group=0) { + destroy(); + set_id(dJointCreateSlider(world, group)); + } + void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0) + { create(world.id(), group); } + + void setAxis (dReal x, dReal y, dReal z) + { dJointSetSliderAxis (get_id(), x, y, z); } + void setAxis (const dVector3 a) + { setAxis (a[0], a[1], a[2]); } + void getAxis (dVector3 result) const + { dJointGetSliderAxis (get_id(), result); } + + dReal getPosition() const + { return dJointGetSliderPosition (get_id()); } + dReal getPositionRate() const + { return dJointGetSliderPositionRate (get_id()); } + + virtual void setParam (int parameter, dReal value) + { dJointSetSliderParam (get_id(), parameter, value); } + virtual dReal getParam (int parameter) const + { return dJointGetSliderParam (get_id(), parameter); } + // TODO: expose params through methods + + void addForce (dReal force) + { dJointAddSliderForce(get_id(), force); } +}; + + +template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase> +class dUniversalJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> { +private: + // intentionally undefined, don't use these + dUniversalJointTemplate (const dUniversalJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &); + void operator = (const dUniversalJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &); + +protected: + typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate; + + dJointID get_id() const { return dBaseTemplate::get_id(); } + void set_id(dJointID value) { dBaseTemplate::set_id(value); } + + void destroy() { dBaseTemplate::destroy(); } + +public: + dUniversalJointTemplate() { } + dUniversalJointTemplate (dWorldID world, dJointGroupID group=0) + { set_id(dJointCreateUniversal(world, group)); } + dUniversalJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0) + { set_id(dJointCreateUniversal(world.id(), group)); } + + void create (dWorldID world, dJointGroupID group=0) { + destroy(); + set_id(dJointCreateUniversal(world, group)); + } + void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0) + { create(world.id(), group); } + + void setAnchor (dReal x, dReal y, dReal z) + { dJointSetUniversalAnchor (get_id(), x, y, z); } + void setAnchor (const dVector3 a) + { setAnchor(a[0], a[1], a[2]); } + void setAxis1 (dReal x, dReal y, dReal z) + { dJointSetUniversalAxis1 (get_id(), x, y, z); } + void setAxis1 (const dVector3 a) + { setAxis1 (a[0], a[1], a[2]); } + void setAxis2 (dReal x, dReal y, dReal z) + { dJointSetUniversalAxis2 (get_id(), x, y, z); } + void setAxis2 (const dVector3 a) + { setAxis2 (a[0], a[1], a[2]); } + + void getAnchor (dVector3 result) const + { dJointGetUniversalAnchor (get_id(), result); } + void getAnchor2 (dVector3 result) const + { dJointGetUniversalAnchor2 (get_id(), result); } + void getAxis1 (dVector3 result) const + { dJointGetUniversalAxis1 (get_id(), result); } + void getAxis2 (dVector3 result) const + { dJointGetUniversalAxis2 (get_id(), result); } + + virtual void setParam (int parameter, dReal value) + { dJointSetUniversalParam (get_id(), parameter, value); } + virtual dReal getParam (int parameter) const + { return dJointGetUniversalParam (get_id(), parameter); } + // TODO: expose params through methods + + void getAngles(dReal *angle1, dReal *angle2) const + { dJointGetUniversalAngles (get_id(), angle1, angle2); } + + dReal getAngle1() const + { return dJointGetUniversalAngle1 (get_id()); } + dReal getAngle1Rate() const + { return dJointGetUniversalAngle1Rate (get_id()); } + dReal getAngle2() const + { return dJointGetUniversalAngle2 (get_id()); } + dReal getAngle2Rate() const + { return dJointGetUniversalAngle2Rate (get_id()); } + + void addTorques (dReal torque1, dReal torque2) + { dJointAddUniversalTorques(get_id(), torque1, torque2); } +}; + + +template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase> +class dHinge2JointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> { +private: + // intentionally undefined, don't use these + dHinge2JointTemplate (const dHinge2JointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &); + void operator = (const dHinge2JointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &); + +protected: + typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate; + + dJointID get_id() const { return dBaseTemplate::get_id(); } + void set_id(dJointID value) { dBaseTemplate::set_id(value); } + + void destroy() { dBaseTemplate::destroy(); } + +public: + dHinge2JointTemplate() { } + dHinge2JointTemplate (dWorldID world, dJointGroupID group=0) + { set_id(dJointCreateHinge2(world, group)); } + dHinge2JointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0) + { set_id(dJointCreateHinge2(world.id(), group)); } + + void create (dWorldID world, dJointGroupID group=0) { + destroy(); + set_id(dJointCreateHinge2(world, group)); + } + void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0) + { create(world.id(), group); } + + void setAnchor (dReal x, dReal y, dReal z) + { dJointSetHinge2Anchor (get_id(), x, y, z); } + void setAnchor (const dVector3 a) + { setAnchor(a[0], a[1], a[2]); } + void setAxes (const dReal *axis1/*=NULL*/, const dReal *axis2/*=NULL*/) + { dJointSetHinge2Axes (get_id(), axis1, axis2); } + ODE_API_DEPRECATED void setAxis1 (dReal x, dReal y, dReal z) + { dVector3 a = { x, y, z }; dJointSetHinge2Axes (get_id(), a, NULL); } + ODE_API_DEPRECATED void setAxis1 (const dVector3 a) + { dJointSetHinge2Axes (get_id(), a, NULL); } + ODE_API_DEPRECATED void setAxis2 (dReal x, dReal y, dReal z) + { dVector3 a = { x, y, z }; dJointSetHinge2Axes (get_id(), NULL, a); } + ODE_API_DEPRECATED void setAxis2 (const dVector3 a) + { dJointSetHinge2Axes (get_id(), NULL, a); } + + void getAnchor (dVector3 result) const + { dJointGetHinge2Anchor (get_id(), result); } + void getAnchor2 (dVector3 result) const + { dJointGetHinge2Anchor2 (get_id(), result); } + void getAxis1 (dVector3 result) const + { dJointGetHinge2Axis1 (get_id(), result); } + void getAxis2 (dVector3 result) const + { dJointGetHinge2Axis2 (get_id(), result); } + + dReal getAngle1() const + { return dJointGetHinge2Angle1 (get_id()); } + dReal getAngle1Rate() const + { return dJointGetHinge2Angle1Rate (get_id()); } + dReal getAngle2Rate() const + { return dJointGetHinge2Angle2Rate (get_id()); } + + virtual void setParam (int parameter, dReal value) + { dJointSetHinge2Param (get_id(), parameter, value); } + virtual dReal getParam (int parameter) const + { return dJointGetHinge2Param (get_id(), parameter); } + // TODO: expose params through methods + + void addTorques(dReal torque1, dReal torque2) + { dJointAddHinge2Torques(get_id(), torque1, torque2); } +}; + + +template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase> +class dPRJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> { +private: + // intentionally undefined, don't use these + dPRJointTemplate (const dPRJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &); + void operator = (const dPRJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &); + +protected: + typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate; + + dJointID get_id() const { return dBaseTemplate::get_id(); } + void set_id(dJointID value) { dBaseTemplate::set_id(value); } + + void destroy() { dBaseTemplate::destroy(); } + +public: + dPRJointTemplate() { } + dPRJointTemplate (dWorldID world, dJointGroupID group=0) + { set_id(dJointCreatePR(world, group)); } + dPRJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0) + { set_id(dJointCreatePR(world.id(), group)); } + + void create (dWorldID world, dJointGroupID group=0) { + destroy(); + set_id(dJointCreatePR(world, group)); + } + void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0) + { create(world.id(), group); } + + void setAnchor (dReal x, dReal y, dReal z) + { dJointSetPRAnchor (get_id(), x, y, z); } + void setAnchor (const dVector3 a) + { setAnchor (a[0], a[1], a[2]); } + void setAxis1 (dReal x, dReal y, dReal z) + { dJointSetPRAxis1 (get_id(), x, y, z); } + void setAxis1 (const dVector3 a) + { setAxis1(a[0], a[1], a[2]); } + void setAxis2 (dReal x, dReal y, dReal z) + { dJointSetPRAxis2 (get_id(), x, y, z); } + void setAxis2 (const dVector3 a) + { setAxis2(a[0], a[1], a[2]); } + + void getAnchor (dVector3 result) const + { dJointGetPRAnchor (get_id(), result); } + void getAxis1 (dVector3 result) const + { dJointGetPRAxis1 (get_id(), result); } + void getAxis2 (dVector3 result) const + { dJointGetPRAxis2 (get_id(), result); } + + dReal getPosition() const + { return dJointGetPRPosition (get_id()); } + dReal getPositionRate() const + { return dJointGetPRPositionRate (get_id()); } + + dReal getAngle() const + { return dJointGetPRAngle (get_id()); } + dReal getAngleRate() const + { return dJointGetPRAngleRate (get_id()); } + + virtual void setParam (int parameter, dReal value) + { dJointSetPRParam (get_id(), parameter, value); } + virtual dReal getParam (int parameter) const + { return dJointGetPRParam (get_id(), parameter); } +}; + + + +template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase> +class dPUJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> +{ +private: + // intentionally undefined, don't use these + dPUJointTemplate (const dPUJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &); + void operator = (const dPUJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &); + +protected: + typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate; + + dJointID get_id() const { return dBaseTemplate::get_id(); } + void set_id(dJointID value) { dBaseTemplate::set_id(value); } + + void destroy() { dBaseTemplate::destroy(); } + +public: + dPUJointTemplate() { } + dPUJointTemplate (dWorldID world, dJointGroupID group=0) + { set_id(dJointCreatePU(world, group)); } + dPUJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0) + { set_id(dJointCreatePU(world.id(), group)); } + + void create (dWorldID world, dJointGroupID group=0) + { + destroy(); + set_id(dJointCreatePU(world, group)); + } + void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0) + { create(world.id(), group); } + + void setAnchor (dReal x, dReal y, dReal z) + { dJointSetPUAnchor (get_id(), x, y, z); } + void setAnchor (const dVector3 a) + { setAnchor (a[0], a[1], a[2]); } + void setAxis1 (dReal x, dReal y, dReal z) + { dJointSetPUAxis1 (get_id(), x, y, z); } + void setAxis1 (const dVector3 a) + { setAxis1(a[0], a[1], a[2]); } + void setAxis2 (dReal x, dReal y, dReal z) + { dJointSetPUAxis2 (get_id(), x, y, z); } + void setAxis3 (dReal x, dReal y, dReal z) + { dJointSetPUAxis3 (get_id(), x, y, z); } + void setAxis3 (const dVector3 a) + { setAxis3(a[0], a[1], a[2]); } + void setAxisP (dReal x, dReal y, dReal z) + { dJointSetPUAxis3 (get_id(), x, y, z); } + void setAxisP (const dVector3 a) + { setAxisP(a[0], a[1], a[2]); } + + virtual void getAnchor (dVector3 result) const + { dJointGetPUAnchor (get_id(), result); } + void getAxis1 (dVector3 result) const + { dJointGetPUAxis1 (get_id(), result); } + void getAxis2 (dVector3 result) const + { dJointGetPUAxis2 (get_id(), result); } + void getAxis3 (dVector3 result) const + { dJointGetPUAxis3 (get_id(), result); } + void getAxisP (dVector3 result) const + { dJointGetPUAxis3 (get_id(), result); } + + dReal getAngle1() const + { return dJointGetPUAngle1 (get_id()); } + dReal getAngle1Rate() const + { return dJointGetPUAngle1Rate (get_id()); } + dReal getAngle2() const + { return dJointGetPUAngle2 (get_id()); } + dReal getAngle2Rate() const + { return dJointGetPUAngle2Rate (get_id()); } + + dReal getPosition() const + { return dJointGetPUPosition (get_id()); } + dReal getPositionRate() const + { return dJointGetPUPositionRate (get_id()); } + + virtual void setParam (int parameter, dReal value) + { dJointSetPUParam (get_id(), parameter, value); } + virtual dReal getParam (int parameter) const + { return dJointGetPUParam (get_id(), parameter); } + // TODO: expose params through methods +}; + + + + + +template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase> +class dPistonJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> +{ +private: + // intentionally undefined, don't use these + dPistonJointTemplate (const dPistonJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &); + void operator = (const dPistonJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &); + +protected: + typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate; + + dJointID get_id() const { return dBaseTemplate::get_id(); } + void set_id(dJointID value) { dBaseTemplate::set_id(value); } + + void destroy() { dBaseTemplate::destroy(); } + +public: + dPistonJointTemplate() { } + dPistonJointTemplate (dWorldID world, dJointGroupID group=0) + { set_id(dJointCreatePiston(world, group)); } + dPistonJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0) + { set_id(dJointCreatePiston(world, group)); } + + void create (dWorldID world, dJointGroupID group=0) + { + destroy(); + set_id(dJointCreatePiston(world, group)); + } + void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0) + { create(world.id(), group); } + + void setAnchor (dReal x, dReal y, dReal z) + { dJointSetPistonAnchor (get_id(), x, y, z); } + void setAnchor (const dVector3 a) + { setAnchor (a[0], a[1], a[2]); } + void getAnchor (dVector3 result) const + { dJointGetPistonAnchor (get_id(), result); } + void getAnchor2 (dVector3 result) const + { dJointGetPistonAnchor2 (get_id(), result); } + + void setAxis (dReal x, dReal y, dReal z) + { dJointSetPistonAxis (get_id(), x, y, z); } + void setAxis (const dVector3 a) + { setAxis(a[0], a[1], a[2]); } + void getAxis (dVector3 result) const + { dJointGetPistonAxis (get_id(), result); } + + dReal getPosition() const + { return dJointGetPistonPosition (get_id()); } + dReal getPositionRate() const + { return dJointGetPistonPositionRate (get_id()); } + + virtual void setParam (int parameter, dReal value) + { dJointSetPistonParam (get_id(), parameter, value); } + virtual dReal getParam (int parameter) const + { return dJointGetPistonParam (get_id(), parameter); } + // TODO: expose params through methods + + void addForce (dReal force) + { dJointAddPistonForce (get_id(), force); } +}; + + + +template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase> +class dFixedJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> +{ +private: + // intentionally undefined, don't use these + dFixedJointTemplate (const dFixedJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &); + void operator = (const dFixedJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &); + +protected: + typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate; + + dJointID get_id() const { return dBaseTemplate::get_id(); } + void set_id(dJointID value) { dBaseTemplate::set_id(value); } + + void destroy() { dBaseTemplate::destroy(); } + +public: + dFixedJointTemplate() { } + dFixedJointTemplate (dWorldID world, dJointGroupID group=0) + { set_id(dJointCreateFixed(world, group)); } + dFixedJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0) + { set_id(dJointCreateFixed(world, group)); } + + void create (dWorldID world, dJointGroupID group=0) { + destroy(); + set_id(dJointCreateFixed(world, group)); + } + void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0) + { create(world.id(), group); } + + void set() + { dJointSetFixed (get_id()); } + + virtual void setParam (int parameter, dReal value) + { dJointSetFixedParam (get_id(), parameter, value); } + + virtual dReal getParam (int parameter) const + { return dJointGetFixedParam (get_id(), parameter); } + // TODO: expose params through methods +}; + + +template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase> +class dContactJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> { +private: + // intentionally undefined, don't use these + dContactJointTemplate (const dContactJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &); + void operator = (const dContactJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &); + +protected: + typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate; + + dJointID get_id() const { return dBaseTemplate::get_id(); } + void set_id(dJointID value) { dBaseTemplate::set_id(value); } + + void destroy() { dBaseTemplate::destroy(); } + +public: + dContactJointTemplate() { } + dContactJointTemplate (dWorldID world, dJointGroupID group, dContact *contact) + { set_id(dJointCreateContact(world, group, contact)); } + dContactJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group, dContact *contact) + { set_id(dJointCreateContact(world.id(), group, contact)); } + + void create (dWorldID world, dJointGroupID group, dContact *contact) { + destroy(); + set_id(dJointCreateContact(world, group, contact)); + } + + void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group, dContact *contact) + { create(world.id(), group, contact); } +}; + + +template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase> +class dNullJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> { +private: + // intentionally undefined, don't use these + dNullJointTemplate (const dNullJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &); + void operator = (const dNullJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &); + +protected: + typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate; + + dJointID get_id() const { return dBaseTemplate::get_id(); } + void set_id(dJointID value) { dBaseTemplate::set_id(value); } + + void destroy() { dBaseTemplate::destroy(); } + +public: + dNullJointTemplate() { } + dNullJointTemplate (dWorldID world, dJointGroupID group=0) + { set_id(dJointCreateNull(world, group)); } + dNullJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0) + { set_id(dJointCreateNull (world.id(), group)); } + + void create (dWorldID world, dJointGroupID group=0) { + destroy(); + set_id(dJointCreateNull(world, group)); + } + void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0) + { create(world.id(), group); } +}; + + +template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase> +class dAMotorJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> { +private: + // intentionally undefined, don't use these + dAMotorJointTemplate (const dAMotorJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &); + void operator = (const dAMotorJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &); + +protected: + typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate; + + dJointID get_id() const { return dBaseTemplate::get_id(); } + void set_id(dJointID value) { dBaseTemplate::set_id(value); } + + void destroy() { dBaseTemplate::destroy(); } + +public: + dAMotorJointTemplate() { } + dAMotorJointTemplate (dWorldID world, dJointGroupID group=0) + { set_id(dJointCreateAMotor(world, group)); } + dAMotorJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0) + { set_id(dJointCreateAMotor(world.id(), group)); } + + void create (dWorldID world, dJointGroupID group=0) { + destroy(); + set_id(dJointCreateAMotor(world, group)); + } + void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0) + { create(world.id(), group); } + + void setMode (int mode) + { dJointSetAMotorMode (get_id(), mode); } + int getMode() const + { return dJointGetAMotorMode (get_id()); } + + void setNumAxes (int num) + { dJointSetAMotorNumAxes (get_id(), num); } + int getNumAxes() const + { return dJointGetAMotorNumAxes (get_id()); } + + void setAxis (int anum, int rel, dReal x, dReal y, dReal z) + { dJointSetAMotorAxis (get_id(), anum, rel, x, y, z); } + void setAxis (int anum, int rel, const dVector3 a) + { setAxis(anum, rel, a[0], a[1], a[2]); } + void getAxis (int anum, dVector3 result) const + { dJointGetAMotorAxis (get_id(), anum, result); } + int getAxisRel (int anum) const + { return dJointGetAMotorAxisRel (get_id(), anum); } + + void setAngle (int anum, dReal angle) + { dJointSetAMotorAngle (get_id(), anum, angle); } + dReal getAngle (int anum) const + { return dJointGetAMotorAngle (get_id(), anum); } + dReal getAngleRate (int anum) + { return dJointGetAMotorAngleRate (get_id(), anum); } + + void setParam (int parameter, dReal value) + { dJointSetAMotorParam (get_id(), parameter, value); } + dReal getParam (int parameter) const + { return dJointGetAMotorParam (get_id(), parameter); } + // TODO: expose params through methods + + void addTorques(dReal torque1, dReal torque2, dReal torque3) + { dJointAddAMotorTorques(get_id(), torque1, torque2, torque3); } +}; + + +template <class dJointTemplateBase, class dWorldTemplateBase, class dBodyTemplateBase> +class dLMotorJointTemplate : public dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> { +private: + // intentionally undefined, don't use these + dLMotorJointTemplate (const dLMotorJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &); + void operator = (const dLMotorJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> &); + +protected: + typedef dJointTemplate<dJointTemplateBase, dWorldTemplateBase, dBodyTemplateBase> dBaseTemplate; + + dJointID get_id() const { return dBaseTemplate::get_id(); } + void set_id(dJointID value) { dBaseTemplate::set_id(value); } + + void destroy() { dBaseTemplate::destroy(); } + +public: + dLMotorJointTemplate() { } + dLMotorJointTemplate (dWorldID world, dJointGroupID group=0) + { set_id(dJointCreateLMotor(world, group)); } + dLMotorJointTemplate (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0) + { set_id(dJointCreateLMotor(world.id(), group)); } + + void create (dWorldID world, dJointGroupID group=0) { + destroy(); + set_id(dJointCreateLMotor(world, group)); + } + void create (dWorldTemplate<dWorldTemplateBase>& world, dJointGroupID group=0) + { create(world.id(), group); } + + void setNumAxes (int num) + { dJointSetLMotorNumAxes (get_id(), num); } + int getNumAxes() const + { return dJointGetLMotorNumAxes (get_id()); } + + void setAxis (int anum, int rel, dReal x, dReal y, dReal z) + { dJointSetLMotorAxis (get_id(), anum, rel, x, y, z); } + void setAxis (int anum, int rel, const dVector3 a) + { setAxis(anum, rel, a[0], a[1], a[2]); } + void getAxis (int anum, dVector3 result) const + { dJointGetLMotorAxis (get_id(), anum, result); } + + void setParam (int parameter, dReal value) + { dJointSetLMotorParam (get_id(), parameter, value); } + dReal getParam (int parameter) const + { return dJointGetLMotorParam (get_id(), parameter); } + // TODO: expose params through methods +}; + +//} + +#if !defined(dODECPP_WORLD_TEMPLATE_BASE) + +#if defined(dODECPP_BODY_TEMPLATE_BASE) || defined(dODECPP_JOINTGROUP_TEMPLATE_BASE) || defined(dODECPP_JOINT_TEMPLATE_BASE) +#error All the odecpp template bases must be defined or not defined together +#endif + +#define dODECPP_WORLD_TEMPLATE_BASE dWorldDynamicIDContainer +#define dODECPP_BODY_TEMPLATE_BASE dBodyDynamicIDContainer +#define dODECPP_JOINTGROUP_TEMPLATE_BASE dJointGroupDynamicIDContainer +#define dODECPP_JOINT_TEMPLATE_BASE dJointDynamicIDContainer + +#else // #if defined(dODECPP_WORLD_TEMPLATE_BASE) + +#if !defined(dODECPP_BODY_TEMPLATE_BASE) || !defined(dODECPP_JOINTGROUP_TEMPLATE_BASE) || !defined(dODECPP_JOINT_TEMPLATE_BASE) +#error All the odecpp template bases must be defined or not defined together +#endif + +#endif // #if defined(dODECPP_WORLD_TEMPLATE_BASE) + + +typedef dWorldTemplate<dODECPP_WORLD_TEMPLATE_BASE> dWorld; +typedef dBodyTemplate<dODECPP_BODY_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE> dBody; +typedef dJointGroupTemplate<dODECPP_JOINTGROUP_TEMPLATE_BASE> dJointGroup; +typedef dJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dJoint; +typedef dBallJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dBallJoint; +typedef dHingeJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dHingeJoint; +typedef dSliderJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dSliderJoint; +typedef dUniversalJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dUniversalJoint; +typedef dHinge2JointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dHinge2Joint; +typedef dPRJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dPRJoint; +typedef dPUJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dPUJoint; +typedef dPistonJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dPistonJoint; +typedef dFixedJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dFixedJoint; +typedef dContactJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dContactJoint; +typedef dNullJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dNullJoint; +typedef dAMotorJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dAMotorJoint; +typedef dLMotorJointTemplate<dODECPP_JOINT_TEMPLATE_BASE, dODECPP_WORLD_TEMPLATE_BASE, dODECPP_BODY_TEMPLATE_BASE> dLMotorJoint; + + +#endif +#endif + +// Local variables: +// mode:c++ +// c-basic-offset:2 +// End: diff --git a/libs/ode-0.16.1/include/ode/odecpp_collision.h b/libs/ode-0.16.1/include/ode/odecpp_collision.h new file mode 100644 index 0000000..f2c7725 --- /dev/null +++ b/libs/ode-0.16.1/include/ode/odecpp_collision.h @@ -0,0 +1,467 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* C++ interface for new collision API */ + + +#ifndef _ODE_ODECPP_COLLISION_H_ +#define _ODE_ODECPP_COLLISION_H_ +#ifdef __cplusplus + +//#include <ode/error.h> + +//namespace ode { + +class dGeom { + // intentionally undefined, don't use these + dGeom (dGeom &); + void operator= (dGeom &); + +protected: + dGeomID _id; + + dGeom() + { _id = 0; } +public: + ~dGeom() + { if (_id) dGeomDestroy (_id); } + + dGeomID id() const + { return _id; } + operator dGeomID() const + { return _id; } + + void destroy() { + if (_id) dGeomDestroy (_id); + _id = 0; + } + + int getClass() const + { return dGeomGetClass (_id); } + + dSpaceID getSpace() const + { return dGeomGetSpace (_id); } + + void setData (void *data) + { dGeomSetData (_id,data); } + void *getData() const + { return dGeomGetData (_id); } + + void setBody (dBodyID b) + { dGeomSetBody (_id,b); } + dBodyID getBody() const + { return dGeomGetBody (_id); } + + void setPosition (dReal x, dReal y, dReal z) + { dGeomSetPosition (_id,x,y,z); } + const dReal * getPosition() const + { return dGeomGetPosition (_id); } + + void setRotation (const dMatrix3 R) + { dGeomSetRotation (_id,R); } + const dReal * getRotation() const + { return dGeomGetRotation (_id); } + + void setQuaternion (const dQuaternion quat) + { dGeomSetQuaternion (_id,quat); } + void getQuaternion (dQuaternion quat) const + { dGeomGetQuaternion (_id,quat); } + + void getAABB (dReal aabb[6]) const + { dGeomGetAABB (_id, aabb); } + + int isSpace() + { return dGeomIsSpace (_id); } + + void setCategoryBits (unsigned long bits) + { dGeomSetCategoryBits (_id, bits); } + void setCollideBits (unsigned long bits) + { dGeomSetCollideBits (_id, bits); } + unsigned long getCategoryBits() + { return dGeomGetCategoryBits (_id); } + unsigned long getCollideBits() + { return dGeomGetCollideBits (_id); } + + void enable() + { dGeomEnable (_id); } + void disable() + { dGeomDisable (_id); } + int isEnabled() + { return dGeomIsEnabled (_id); } + + void getRelPointPos (dReal px, dReal py, dReal pz, dVector3 result) const + { dGeomGetRelPointPos (_id, px, py, pz, result); } + void getRelPointPos (const dVector3 p, dVector3 result) const + { getRelPointPos (p[0], p[1], p[2], result); } + + void getPosRelPoint (dReal px, dReal py, dReal pz, dVector3 result) const + { dGeomGetPosRelPoint (_id, px, py, pz, result); } + void getPosRelPoint (const dVector3 p, dVector3 result) const + { getPosRelPoint (p[0], p[1], p[2], result); } + + void vectorToWorld (dReal px, dReal py, dReal pz, dVector3 result) const + { dGeomVectorToWorld (_id, px, py, pz, result); } + void vectorToWorld (const dVector3 p, dVector3 result) const + { vectorToWorld (p[0], p[1], p[2], result); } + + void vectorFromWorld (dReal px, dReal py, dReal pz, dVector3 result) const + { dGeomVectorFromWorld (_id, px, py, pz, result); } + void vectorFromWorld (const dVector3 p, dVector3 result) const + { vectorFromWorld (p[0], p[1], p[2], result); } + + void collide2 (dGeomID g, void *data, dNearCallback *callback) + { dSpaceCollide2 (_id,g,data,callback); } +}; + + +class dSpace : public dGeom { + // intentionally undefined, don't use these + dSpace (dSpace &); + void operator= (dSpace &); + +protected: + // the default constructor is protected so that you + // can't instance this class. you must instance one + // of its subclasses instead. + dSpace () { _id = 0; } + +public: + dSpaceID id() const + { return (dSpaceID) _id; } + operator dSpaceID() const + { return (dSpaceID) _id; } + + void setCleanup (int mode) + { dSpaceSetCleanup (id(), mode); } + int getCleanup() + { return dSpaceGetCleanup (id()); } + + void add (dGeomID x) + { dSpaceAdd (id(), x); } + void remove (dGeomID x) + { dSpaceRemove (id(), x); } + int query (dGeomID x) + { return dSpaceQuery (id(),x); } + + int getNumGeoms() + { return dSpaceGetNumGeoms (id()); } + dGeomID getGeom (int i) + { return dSpaceGetGeom (id(),i); } + + void collide (void *data, dNearCallback *callback) + { dSpaceCollide (id(),data,callback); } +}; + + +class dSimpleSpace : public dSpace { + // intentionally undefined, don't use these + dSimpleSpace (dSimpleSpace &); + void operator= (dSimpleSpace &); + +public: + dSimpleSpace () + { _id = (dGeomID) dSimpleSpaceCreate (0); } + dSimpleSpace (dSpace &space) + { _id = (dGeomID) dSimpleSpaceCreate (space.id()); } + dSimpleSpace (dSpaceID space) + { _id = (dGeomID) dSimpleSpaceCreate (space); } +}; + + +class dHashSpace : public dSpace { + // intentionally undefined, don't use these + dHashSpace (dHashSpace &); + void operator= (dHashSpace &); + +public: + dHashSpace () + { _id = (dGeomID) dHashSpaceCreate (0); } + dHashSpace (dSpace &space) + { _id = (dGeomID) dHashSpaceCreate (space.id()); } + dHashSpace (dSpaceID space) + { _id = (dGeomID) dHashSpaceCreate (space); } + + void setLevels (int minlevel, int maxlevel) + { dHashSpaceSetLevels (id(),minlevel,maxlevel); } +}; + + +class dQuadTreeSpace : public dSpace { + // intentionally undefined, don't use these + dQuadTreeSpace (dQuadTreeSpace &); + void operator= (dQuadTreeSpace &); + +public: + dQuadTreeSpace (const dVector3 center, const dVector3 extents, int depth) + { _id = (dGeomID) dQuadTreeSpaceCreate (0,center,extents,depth); } + dQuadTreeSpace (dSpace &space, const dVector3 center, const dVector3 extents, int depth) + { _id = (dGeomID) dQuadTreeSpaceCreate (space.id(),center,extents,depth); } + dQuadTreeSpace (dSpaceID space, const dVector3 center, const dVector3 extents, int depth) + { _id = (dGeomID) dQuadTreeSpaceCreate (space,center,extents,depth); } +}; + + +class dSphere : public dGeom { + // intentionally undefined, don't use these + dSphere (dSphere &); + void operator= (dSphere &); + +public: + dSphere () { } + dSphere (dReal radius) + { _id = dCreateSphere (0, radius); } + dSphere (dSpace &space, dReal radius) + { _id = dCreateSphere (space.id(), radius); } + dSphere (dSpaceID space, dReal radius) + { _id = dCreateSphere (space, radius); } + + void create (dSpaceID space, dReal radius) { + if (_id) dGeomDestroy (_id); + _id = dCreateSphere (space, radius); + } + + void setRadius (dReal radius) + { dGeomSphereSetRadius (_id, radius); } + dReal getRadius() const + { return dGeomSphereGetRadius (_id); } +}; + + +class dBox : public dGeom { + // intentionally undefined, don't use these + dBox (dBox &); + void operator= (dBox &); + +public: + dBox () { } + dBox (dReal lx, dReal ly, dReal lz) + { _id = dCreateBox (0,lx,ly,lz); } + dBox (dSpace &space, dReal lx, dReal ly, dReal lz) + { _id = dCreateBox (space,lx,ly,lz); } + dBox (dSpaceID space, dReal lx, dReal ly, dReal lz) + { _id = dCreateBox (space,lx,ly,lz); } + + void create (dSpaceID space, dReal lx, dReal ly, dReal lz) { + if (_id) dGeomDestroy (_id); + _id = dCreateBox (space,lx,ly,lz); + } + + void setLengths (dReal lx, dReal ly, dReal lz) + { dGeomBoxSetLengths (_id, lx, ly, lz); } + void getLengths (dVector3 result) const + { dGeomBoxGetLengths (_id,result); } +}; + + +class dPlane : public dGeom { + // intentionally undefined, don't use these + dPlane (dPlane &); + void operator= (dPlane &); + +public: + dPlane() { } + dPlane (dReal a, dReal b, dReal c, dReal d) + { _id = dCreatePlane (0,a,b,c,d); } + dPlane (dSpace &space, dReal a, dReal b, dReal c, dReal d) + { _id = dCreatePlane (space.id(),a,b,c,d); } + dPlane (dSpaceID space, dReal a, dReal b, dReal c, dReal d) + { _id = dCreatePlane (space,a,b,c,d); } + + void create (dSpaceID space, dReal a, dReal b, dReal c, dReal d) { + if (_id) dGeomDestroy (_id); + _id = dCreatePlane (space,a,b,c,d); + } + + void setParams (dReal a, dReal b, dReal c, dReal d) + { dGeomPlaneSetParams (_id, a, b, c, d); } + void getParams (dVector4 result) const + { dGeomPlaneGetParams (_id,result); } +}; + + +class dCapsule : public dGeom { + // intentionally undefined, don't use these + dCapsule (dCapsule &); + void operator= (dCapsule &); + +public: + dCapsule() { } + dCapsule (dReal radius, dReal length) + { _id = dCreateCapsule (0,radius,length); } + dCapsule (dSpace &space, dReal radius, dReal length) + { _id = dCreateCapsule (space.id(),radius,length); } + dCapsule (dSpaceID space, dReal radius, dReal length) + { _id = dCreateCapsule (space,radius,length); } + + void create (dSpaceID space, dReal radius, dReal length) { + if (_id) dGeomDestroy (_id); + _id = dCreateCapsule (space,radius,length); + } + + void setParams (dReal radius, dReal length) + { dGeomCapsuleSetParams (_id, radius, length); } + void getParams (dReal *radius, dReal *length) const + { dGeomCapsuleGetParams (_id,radius,length); } +}; + + +class dCylinder : public dGeom { + // intentionally undefined, don't use these + dCylinder (dCylinder &); + void operator= (dCylinder &); + +public: + dCylinder() { } + dCylinder (dReal radius, dReal length) + { _id = dCreateCylinder (0,radius,length); } + dCylinder (dSpace &space, dReal radius, dReal length) + { _id = dCreateCylinder (space.id(),radius,length); } + dCylinder (dSpaceID space, dReal radius, dReal length) + { _id = dCreateCylinder (space,radius,length); } + + void create (dSpaceID space, dReal radius, dReal length) { + if (_id) dGeomDestroy (_id); + _id = dCreateCylinder (space,radius,length); + } + + void setParams (dReal radius, dReal length) + { dGeomCylinderSetParams (_id, radius, length); } + void getParams (dReal *radius, dReal *length) const + { dGeomCylinderGetParams (_id,radius,length); } +}; + + +class dRay : public dGeom { + // intentionally undefined, don't use these + dRay (dRay &); + void operator= (dRay &); + +public: + dRay() { } + dRay (dReal length) + { _id = dCreateRay (0,length); } + dRay (dSpace &space, dReal length) + { _id = dCreateRay (space.id(),length); } + dRay (dSpaceID space, dReal length) + { _id = dCreateRay (space,length); } + + void create (dSpaceID space, dReal length) { + if (_id) dGeomDestroy (_id); + _id = dCreateRay (space,length); + } + + void setLength (dReal length) + { dGeomRaySetLength (_id, length); } + dReal getLength() + { return dGeomRayGetLength (_id); } + + void set (dReal px, dReal py, dReal pz, dReal dx, dReal dy, dReal dz) + { dGeomRaySet (_id, px, py, pz, dx, dy, dz); } + void get (dVector3 start, dVector3 dir) + { dGeomRayGet (_id, start, dir); } + +#ifdef WIN32 +#pragma warning( push ) +#pragma warning( disable : 4996 ) +#else +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + ODE_API_DEPRECATED + void setParams (int firstContact, int backfaceCull) + { dGeomRaySetParams (_id, firstContact, backfaceCull); } + + ODE_API_DEPRECATED + void getParams (int *firstContact, int *backfaceCull) + { dGeomRayGetParams (_id, firstContact, backfaceCull); } +#ifdef WIN32 +#pragma warning( pop ) +#else +#pragma GCC diagnostic pop +#endif + void setBackfaceCull (int backfaceCull) + { dGeomRaySetBackfaceCull (_id, backfaceCull); } + int getBackfaceCull() + { return dGeomRayGetBackfaceCull (_id); } + + void setFirstContact (int firstContact) + { dGeomRaySetFirstContact (_id, firstContact); } + int getFirstContact() + { return dGeomRayGetFirstContact (_id); } + + void setClosestHit (int closestHit) + { dGeomRaySetClosestHit (_id, closestHit); } + int getClosestHit() + { return dGeomRayGetClosestHit (_id); } +}; + +#ifdef WIN32 +#pragma warning( push ) +#pragma warning( disable : 4996 ) +#else +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + +class ODE_API_DEPRECATED dGeomTransform : public dGeom { + // intentionally undefined, don't use these + dGeomTransform (dGeomTransform &); + void operator= (dGeomTransform &); + +public: + dGeomTransform() { } + dGeomTransform (dSpace &space) + { _id = dCreateGeomTransform (space.id()); } + dGeomTransform (dSpaceID space) + { _id = dCreateGeomTransform (space); } + + void create (dSpaceID space=0) { + if (_id) dGeomDestroy (_id); + _id = dCreateGeomTransform (space); + } + + void setGeom (dGeomID geom) + { dGeomTransformSetGeom (_id, geom); } + dGeomID getGeom() const + { return dGeomTransformGetGeom (_id); } + + void setCleanup (int mode) + { dGeomTransformSetCleanup (_id,mode); } + int getCleanup () + { return dGeomTransformGetCleanup (_id); } + + void setInfo (int mode) + { dGeomTransformSetInfo (_id,mode); } + int getInfo() + { return dGeomTransformGetInfo (_id); } +}; + +#ifdef WIN32 +#pragma warning( pop ) +#else +#pragma GCC diagnostic pop +#endif + +//} + +#endif +#endif diff --git a/libs/ode-0.16.1/include/ode/odeinit.h b/libs/ode-0.16.1/include/ode/odeinit.h new file mode 100644 index 0000000..645ca42 --- /dev/null +++ b/libs/ode-0.16.1/include/ode/odeinit.h @@ -0,0 +1,236 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* Library initialization/finalization functions. */ + +#ifndef _ODE_ODEINIT_H_ +#define _ODE_ODEINIT_H_ + +#include <ode/common.h> + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* ************************************************************************ */ +/* Library initialization */ + +/** + * @defgroup init Library Initialization + * + * Library initialization functions prepare ODE internal data structures for use + * and release allocated resources after ODE is not needed any more. + */ + + +/** + * @brief Library initialization flags. + * + * These flags define ODE library initialization options. + * + * @c dInitFlagManualThreadCleanup indicates that resources allocated in TLS for threads + * using ODE are to be cleared by library client with explicit call to @c dCleanupODEAllDataForThread. + * If this flag is not specified the automatic resource tracking algorithm is used. + * + * With automatic resource tracking, On Windows, memory allocated for a thread may + * remain not freed for some time after the thread exits. The resources may be + * released when one of other threads calls @c dAllocateODEDataForThread. Ultimately, + * the resources are released when library is closed with @c dCloseODE. On other + * operating systems resources are always released by the thread itself on its exit + * or on library closure with @c dCloseODE. + * + * With manual thread data cleanup mode every collision space object must be + * explicitly switched to manual cleanup mode with @c dSpaceSetManualCleanup + * after creation. See description of the function for more details. + * + * If @c dInitFlagManualThreadCleanup was not specified during initialization, + * calls to @c dCleanupODEAllDataForThread are not allowed. + * + * @see dInitODE2 + * @see dAllocateODEDataForThread + * @see dSpaceSetManualCleanup + * @see dCloseODE + * @ingroup init + */ +enum dInitODEFlags { + dInitFlagManualThreadCleanup = 0x00000001 /*@< Thread local data is to be cleared explicitly on @c dCleanupODEAllDataForThread function call*/ +}; + +/** + * @brief Initializes ODE library. + * + * @c dInitODE is obsolete. @c dInitODE2 is to be used for library initialization. + * + * A call to @c dInitODE is equal to the following initialization sequence + * @code + * dInitODE2(0); + * dAllocateODEDataForThread(dAllocateMaskAll); + * @endcode + * + * @see dInitODE2 + * @see dAllocateODEDataForThread + * @ingroup init + */ +ODE_API void dInitODE(void); + +/** + * @brief Initializes ODE library. + * @param uiInitFlags Initialization options bitmask + * @return A nonzero if initialization succeeded and zero otherwise. + * + * This function must be called to initialize ODE library before first use. If + * initialization succeeds the function may not be called again until library is + * closed with a call to @c dCloseODE. + * + * The @a uiInitFlags parameter specifies initialization options to be used. These + * can be combination of zero or more @c dInitODEFlags flags. + * + * @note + * If @c dInitFlagManualThreadCleanup flag is used for initialization, + * @c dSpaceSetManualCleanup must be called to set manual cleanup mode for every + * space object right after creation. Failure to do so may lead to resource leaks. + * + * @see dInitODEFlags + * @see dCloseODE + * @see dSpaceSetManualCleanup + * @ingroup init + */ +ODE_API int dInitODE2(unsigned int uiInitFlags/*=0*/); + + +/** + * @brief ODE data allocation flags. + * + * These flags are used to indicate which data is to be pre-allocated in call to + * @c dAllocateODEDataForThread. + * + * @c dAllocateFlagBasicData tells to allocate the basic data set required for + * normal library operation. This flag is equal to zero and is always implicitly + * included. + * + * @c dAllocateFlagCollisionData tells that collision detection data is to be allocated. + * Collision detection functions may not be called if the data has not be allocated + * in advance. If collision detection is not going to be used, it is not necessary + * to specify this flag. + * + * @c dAllocateMaskAll is a mask that can be used for for allocating all possible + * data in cases when it is not known what exactly features of ODE will be used. + * The mask may not be used in combination with other flags. It is guaranteed to + * include all the current and future legal allocation flags. However, mature + * applications should use explicit flags they need rather than allocating everything. + * + * @see dAllocateODEDataForThread + * @ingroup init + */ +enum dAllocateODEDataFlags { + dAllocateFlagBasicData = 0, /*@< Allocate basic data required for library to operate*/ + + dAllocateFlagCollisionData = 0x00000001, /*@< Allocate data for collision detection*/ + + dAllocateMaskAll = ~0 /*@< Allocate all the possible data that is currently defined or will be defined in the future.*/ +}; + +/** + * @brief Allocate thread local data to allow the thread calling ODE. + * @param uiAllocateFlags Allocation options bitmask. + * @return A nonzero if allocation succeeded and zero otherwise. + * + * The function is required to be called for every thread that is going to use + * ODE. This function allocates the data that is required for accessing ODE from + * current thread along with optional data required for particular ODE subsystems. + * + * @a uiAllocateFlags parameter can contain zero or more flags from @c dAllocateODEDataFlags + * enumerated type. Multiple calls with different allocation flags are allowed. + * The flags that are already allocated are ignored in subsequent calls. If zero + * is passed as the parameter, it means to only allocate the set of most important + * data the library can not operate without. + * + * If the function returns failure status it means that none of the requested + * data has been allocated. The client may retry allocation attempt with the same + * flags when more system resources are available. + * + * @see dAllocateODEDataFlags + * @see dCleanupODEAllDataForThread + * @ingroup init + */ +ODE_API int dAllocateODEDataForThread(unsigned int uiAllocateFlags); + +/** + * @brief Free thread local data that was allocated for current thread. + * + * If library was initialized with @c dInitFlagManualThreadCleanup flag the function + * is required to be called on exit of every thread that was calling @c dAllocateODEDataForThread. + * Failure to call @c dCleanupODEAllDataForThread may result in some resources remaining + * not freed until program exit. The function may also be called when ODE is still + * being used to release resources allocated for all the current subsystems and + * possibly proceed with data pre-allocation for other subsystems. + * + * The function can safely be called several times in a row. The function can be + * called without prior invocation of @c dAllocateODEDataForThread. The function + * may not be called before ODE is initialized with @c dInitODE2 or after library + * has been closed with @c dCloseODE. A call to @c dCloseODE implicitly releases + * all the thread local resources that might be allocated for all the threads that + * were using ODE. + * + * If library was initialized without @c dInitFlagManualThreadCleanup flag + * @c dCleanupODEAllDataForThread must not be called. + * + * @see dAllocateODEDataForThread + * @see dInitODE2 + * @see dCloseODE + * @ingroup init + */ +ODE_API void dCleanupODEAllDataForThread(); + + +/** + * @brief Close ODE after it is not needed any more. + * + * The function is required to be called when program does not need ODE features any more. + * The call to @c dCloseODE releases all the resources allocated for library + * including all the thread local data that might be allocated for all the threads + * that were using ODE. + * + * @c dCloseODE is a paired function for @c dInitODE2 and must only be called + * after successful library initialization. + * + * @note Important! + * Make sure that all the threads that were using ODE have already terminated + * before calling @c dCloseODE. In particular it is not allowed to call + * @c dCleanupODEAllDataForThread after @c dCloseODE. + * + * @see dInitODE2 + * @see dCleanupODEAllDataForThread + * @ingroup init + */ +ODE_API void dCloseODE(void); + + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* _ODE_ODEINIT_H_ */ diff --git a/libs/ode-0.16.1/include/ode/odemath.h b/libs/ode-0.16.1/include/ode/odemath.h new file mode 100644 index 0000000..d4461b3 --- /dev/null +++ b/libs/ode-0.16.1/include/ode/odemath.h @@ -0,0 +1,545 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_ODEMATH_H_ +#define _ODE_ODEMATH_H_ + +#include <ode/common.h> + +/* + * macro to access elements i,j in an NxM matrix A, independent of the + * matrix storage convention. + */ +#define dACCESS33(A,i,j) ((A)[(i)*4+(j)]) + +/* + * Macro to test for valid floating point values + */ +#define dVALIDVEC3(v) (!(dIsNan(v[0]) || dIsNan(v[1]) || dIsNan(v[2]))) +#define dVALIDVEC4(v) (!(dIsNan(v[0]) || dIsNan(v[1]) || dIsNan(v[2]) || dIsNan(v[3]))) +#define dVALIDMAT3(m) (!(dIsNan(m[0]) || dIsNan(m[1]) || dIsNan(m[2]) || dIsNan(m[3]) || dIsNan(m[4]) || dIsNan(m[5]) || dIsNan(m[6]) || dIsNan(m[7]) || dIsNan(m[8]) || dIsNan(m[9]) || dIsNan(m[10]) || dIsNan(m[11]))) +#define dVALIDMAT4(m) (!(dIsNan(m[0]) || dIsNan(m[1]) || dIsNan(m[2]) || dIsNan(m[3]) || dIsNan(m[4]) || dIsNan(m[5]) || dIsNan(m[6]) || dIsNan(m[7]) || dIsNan(m[8]) || dIsNan(m[9]) || dIsNan(m[10]) || dIsNan(m[11]) || dIsNan(m[12]) || dIsNan(m[13]) || dIsNan(m[14]) || dIsNan(m[15]) )) + + +ODE_PURE_INLINE void dZeroVector3(dVector3 res) +{ + res[dV3E_X] = REAL(0.0); + res[dV3E_Y] = REAL(0.0); + res[dV3E_Z] = REAL(0.0); +} + +ODE_PURE_INLINE void dAssignVector3(dVector3 res, dReal x, dReal y, dReal z) +{ + res[dV3E_X] = x; + res[dV3E_Y] = y; + res[dV3E_Z] = z; +} + +ODE_PURE_INLINE void dZeroMatrix3(dMatrix3 res) +{ + res[dM3E_XX] = REAL(0.0); res[dM3E_XY] = REAL(0.0); res[dM3E_XZ] = REAL(0.0); + res[dM3E_YX] = REAL(0.0); res[dM3E_YY] = REAL(0.0); res[dM3E_YZ] = REAL(0.0); + res[dM3E_ZX] = REAL(0.0); res[dM3E_ZY] = REAL(0.0); res[dM3E_ZZ] = REAL(0.0); +} + +ODE_PURE_INLINE void dZeroMatrix4(dMatrix4 res) +{ + res[dM4E_XX] = REAL(0.0); res[dM4E_XY] = REAL(0.0); res[dM4E_XZ] = REAL(0.0); res[dM4E_XO] = REAL(0.0); + res[dM4E_YX] = REAL(0.0); res[dM4E_YY] = REAL(0.0); res[dM4E_YZ] = REAL(0.0); res[dM4E_YO] = REAL(0.0); + res[dM4E_ZX] = REAL(0.0); res[dM4E_ZY] = REAL(0.0); res[dM4E_ZZ] = REAL(0.0); res[dM4E_ZO] = REAL(0.0); + res[dM4E_OX] = REAL(0.0); res[dM4E_OY] = REAL(0.0); res[dM4E_OZ] = REAL(0.0); res[dM4E_OO] = REAL(0.0); +} + +/* Some vector math */ +ODE_PURE_INLINE void dAddVectors3(dReal *res, const dReal *a, const dReal *b) +{ + const dReal res_0 = a[0] + b[0]; + const dReal res_1 = a[1] + b[1]; + const dReal res_2 = a[2] + b[2]; + /* Only assign after all the calculations are over to avoid incurring memory aliasing*/ + res[0] = res_0; res[1] = res_1; res[2] = res_2; +} + +ODE_PURE_INLINE void dSubtractVectors3(dReal *res, const dReal *a, const dReal *b) +{ + const dReal res_0 = a[0] - b[0]; + const dReal res_1 = a[1] - b[1]; + const dReal res_2 = a[2] - b[2]; + /* Only assign after all the calculations are over to avoid incurring memory aliasing*/ + res[0] = res_0; res[1] = res_1; res[2] = res_2; +} + +ODE_PURE_INLINE void dAddVectorScaledVector3(dReal *res, const dReal *a, const dReal *b, dReal b_scale) +{ + const dReal res_0 = a[0] + b_scale * b[0]; + const dReal res_1 = a[1] + b_scale * b[1]; + const dReal res_2 = a[2] + b_scale * b[2]; + /* Only assign after all the calculations are over to avoid incurring memory aliasing*/ + res[0] = res_0; res[1] = res_1; res[2] = res_2; +} + +ODE_PURE_INLINE void dAddScaledVectors3(dReal *res, const dReal *a, const dReal *b, dReal a_scale, dReal b_scale) +{ + const dReal res_0 = a_scale * a[0] + b_scale * b[0]; + const dReal res_1 = a_scale * a[1] + b_scale * b[1]; + const dReal res_2 = a_scale * a[2] + b_scale * b[2]; + /* Only assign after all the calculations are over to avoid incurring memory aliasing*/ + res[0] = res_0; res[1] = res_1; res[2] = res_2; +} + +ODE_PURE_INLINE void dAddThreeScaledVectors3(dReal *res, const dReal *a, const dReal *b, const dReal *c, dReal a_scale, dReal b_scale, dReal c_scale) +{ + const dReal res_0 = a_scale * a[0] + b_scale * b[0] + c_scale * c[0]; + const dReal res_1 = a_scale * a[1] + b_scale * b[1] + c_scale * c[1]; + const dReal res_2 = a_scale * a[2] + b_scale * b[2] + c_scale * c[2]; + /* Only assign after all the calculations are over to avoid incurring memory aliasing*/ + res[0] = res_0; res[1] = res_1; res[2] = res_2; +} + +ODE_PURE_INLINE void dScaleVector3(dReal *res, dReal nScale) +{ + res[0] *= nScale ; + res[1] *= nScale ; + res[2] *= nScale ; +} + +ODE_PURE_INLINE void dNegateVector3(dReal *res) +{ + res[0] = -res[0]; + res[1] = -res[1]; + res[2] = -res[2]; +} + +ODE_PURE_INLINE void dCopyVector3(dReal *res, const dReal *a) +{ + const dReal res_0 = a[0]; + const dReal res_1 = a[1]; + const dReal res_2 = a[2]; + /* Only assign after all the calculations are over to avoid incurring memory aliasing*/ + res[0] = res_0; res[1] = res_1; res[2] = res_2; +} + +ODE_PURE_INLINE void dCopyScaledVector3(dReal *res, const dReal *a, dReal nScale) +{ + const dReal res_0 = a[0] * nScale; + const dReal res_1 = a[1] * nScale; + const dReal res_2 = a[2] * nScale; + /* Only assign after all the calculations are over to avoid incurring memory aliasing*/ + res[0] = res_0; res[1] = res_1; res[2] = res_2; +} + +ODE_PURE_INLINE void dCopyNegatedVector3(dReal *res, const dReal *a) +{ + const dReal res_0 = -a[0]; + const dReal res_1 = -a[1]; + const dReal res_2 = -a[2]; + /* Only assign after all the calculations are over to avoid incurring memory aliasing*/ + res[0] = res_0; res[1] = res_1; res[2] = res_2; +} + +ODE_PURE_INLINE void dCopyVector4(dReal *res, const dReal *a) +{ + const dReal res_0 = a[0]; + const dReal res_1 = a[1]; + const dReal res_2 = a[2]; + const dReal res_3 = a[3]; + /* Only assign after all the calculations are over to avoid incurring memory aliasing*/ + res[0] = res_0; res[1] = res_1; res[2] = res_2; res[3] = res_3; +} + +ODE_PURE_INLINE void dCopyMatrix4x4(dReal *res, const dReal *a) +{ + dCopyVector4(res + 0, a + 0); + dCopyVector4(res + 4, a + 4); + dCopyVector4(res + 8, a + 8); +} + +ODE_PURE_INLINE void dCopyMatrix4x3(dReal *res, const dReal *a) +{ + dCopyVector3(res + 0, a + 0); + dCopyVector3(res + 4, a + 4); + dCopyVector3(res + 8, a + 8); +} + +ODE_PURE_INLINE void dGetMatrixColumn3(dReal *res, const dReal *a, unsigned n) +{ + const dReal res_0 = a[n + 0]; + const dReal res_1 = a[n + 4]; + const dReal res_2 = a[n + 8]; + /* Only assign after all the calculations are over to avoid incurring memory aliasing*/ + res[0] = res_0; res[1] = res_1; res[2] = res_2; +} + +ODE_PURE_INLINE dReal dCalcVectorLength3(const dReal *a) +{ + return dSqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]); +} + +ODE_PURE_INLINE dReal dCalcVectorLengthSquare3(const dReal *a) +{ + return (a[0] * a[0] + a[1] * a[1] + a[2] * a[2]); +} + +ODE_PURE_INLINE dReal dCalcPointDepth3(const dReal *test_p, const dReal *plane_p, const dReal *plane_n) +{ + return (plane_p[0] - test_p[0]) * plane_n[0] + (plane_p[1] - test_p[1]) * plane_n[1] + (plane_p[2] - test_p[2]) * plane_n[2]; +} + + +/* +* 3-way dot product. _dCalcVectorDot3 means that elements of `a' and `b' are spaced +* step_a and step_b indexes apart respectively. dCalcVectorDot3() means dDot311. +*/ + +ODE_PURE_INLINE dReal _dCalcVectorDot3(const dReal *a, const dReal *b, unsigned step_a, unsigned step_b) +{ + return a[0] * b[0] + a[step_a] * b[step_b] + a[2 * step_a] * b[2 * step_b]; +} + + +ODE_PURE_INLINE dReal dCalcVectorDot3 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,1,1); } +ODE_PURE_INLINE dReal dCalcVectorDot3_13 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,1,3); } +ODE_PURE_INLINE dReal dCalcVectorDot3_31 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,3,1); } +ODE_PURE_INLINE dReal dCalcVectorDot3_33 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,3,3); } +ODE_PURE_INLINE dReal dCalcVectorDot3_14 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,1,4); } +ODE_PURE_INLINE dReal dCalcVectorDot3_41 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,4,1); } +ODE_PURE_INLINE dReal dCalcVectorDot3_44 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,4,4); } + + +/* + * cross product, set res = a x b. _dCalcVectorCross3 means that elements of `res', `a' + * and `b' are spaced step_res, step_a and step_b indexes apart respectively. + * dCalcVectorCross3() means dCross3111. + */ + +ODE_PURE_INLINE void _dCalcVectorCross3(dReal *res, const dReal *a, const dReal *b, unsigned step_res, unsigned step_a, unsigned step_b) +{ + const dReal res_0 = a[ step_a]*b[2*step_b] - a[2*step_a]*b[ step_b]; + const dReal res_1 = a[2*step_a]*b[ 0] - a[ 0]*b[2*step_b]; + const dReal res_2 = a[ 0]*b[ step_b] - a[ step_a]*b[ 0]; + /* Only assign after all the calculations are over to avoid incurring memory aliasing*/ + res[ 0] = res_0; + res[ step_res] = res_1; + res[2*step_res] = res_2; +} + +ODE_PURE_INLINE void dCalcVectorCross3 (dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 1, 1); } +ODE_PURE_INLINE void dCalcVectorCross3_114(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 1, 4); } +ODE_PURE_INLINE void dCalcVectorCross3_141(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 4, 1); } +ODE_PURE_INLINE void dCalcVectorCross3_144(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 4, 4); } +ODE_PURE_INLINE void dCalcVectorCross3_411(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 1, 1); } +ODE_PURE_INLINE void dCalcVectorCross3_414(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 1, 4); } +ODE_PURE_INLINE void dCalcVectorCross3_441(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 4, 1); } +ODE_PURE_INLINE void dCalcVectorCross3_444(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 4, 4); } + +ODE_PURE_INLINE void dAddVectorCross3(dReal *res, const dReal *a, const dReal *b) +{ + dReal tmp[3]; + dCalcVectorCross3(tmp, a, b); + dAddVectors3(res, res, tmp); +} + +ODE_PURE_INLINE void dSubtractVectorCross3(dReal *res, const dReal *a, const dReal *b) +{ + dReal tmp[3]; + dCalcVectorCross3(tmp, a, b); + dSubtractVectors3(res, res, tmp); +} + + +/* + * set a 3x3 submatrix of A to a matrix such that submatrix(A)*b = a x b. + * A is stored by rows, and has `skip' elements per row. the matrix is + * assumed to be already zero, so this does not write zero elements! + * if (plus,minus) is (+,-) then a positive version will be written. + * if (plus,minus) is (-,+) then a negative version will be written. + */ + +ODE_PURE_INLINE void dSetCrossMatrixPlus(dReal *res, const dReal *a, unsigned skip) +{ + const dReal a_0 = a[0], a_1 = a[1], a_2 = a[2]; + res[1] = -a_2; + res[2] = +a_1; + res[skip+0] = +a_2; + res[skip+2] = -a_0; + res[2*skip+0] = -a_1; + res[2*skip+1] = +a_0; +} + +ODE_PURE_INLINE void dSetCrossMatrixMinus(dReal *res, const dReal *a, unsigned skip) +{ + const dReal a_0 = a[0], a_1 = a[1], a_2 = a[2]; + res[1] = +a_2; + res[2] = -a_1; + res[skip+0] = -a_2; + res[skip+2] = +a_0; + res[2*skip+0] = +a_1; + res[2*skip+1] = -a_0; +} + + +/* + * compute the distance between two 3D-vectors + */ + +ODE_PURE_INLINE dReal dCalcPointsDistance3(const dReal *a, const dReal *b) +{ + dReal res; + dReal tmp[3]; + dSubtractVectors3(tmp, a, b); + res = dCalcVectorLength3(tmp); + return res; +} + +/* + * special case matrix multiplication, with operator selection + */ + +ODE_PURE_INLINE void dMultiplyHelper0_331(dReal *res, const dReal *a, const dReal *b) +{ + const dReal res_0 = dCalcVectorDot3(a, b); + const dReal res_1 = dCalcVectorDot3(a + 4, b); + const dReal res_2 = dCalcVectorDot3(a + 8, b); + /* Only assign after all the calculations are over to avoid incurring memory aliasing*/ + res[0] = res_0; res[1] = res_1; res[2] = res_2; +} + +ODE_PURE_INLINE void dMultiplyHelper1_331(dReal *res, const dReal *a, const dReal *b) +{ + const dReal res_0 = dCalcVectorDot3_41(a, b); + const dReal res_1 = dCalcVectorDot3_41(a + 1, b); + const dReal res_2 = dCalcVectorDot3_41(a + 2, b); + /* Only assign after all the calculations are over to avoid incurring memory aliasing*/ + res[0] = res_0; res[1] = res_1; res[2] = res_2; +} + +ODE_PURE_INLINE void dMultiplyHelper0_133(dReal *res, const dReal *a, const dReal *b) +{ + dMultiplyHelper1_331(res, b, a); +} + +ODE_PURE_INLINE void dMultiplyHelper1_133(dReal *res, const dReal *a, const dReal *b) +{ + const dReal res_0 = dCalcVectorDot3_44(a, b); + const dReal res_1 = dCalcVectorDot3_44(a + 1, b); + const dReal res_2 = dCalcVectorDot3_44(a + 2, b); + /* Only assign after all the calculations are over to avoid incurring memory aliasing*/ + res[0] = res_0; res[1] = res_1; res[2] = res_2; +} + +/* +Note: NEVER call any of these functions/macros with the same variable for A and C, +it is not equivalent to A*=B. +*/ + +ODE_PURE_INLINE void dMultiply0_331(dReal *res, const dReal *a, const dReal *b) +{ + dMultiplyHelper0_331(res, a, b); +} + +ODE_PURE_INLINE void dMultiply1_331(dReal *res, const dReal *a, const dReal *b) +{ + dMultiplyHelper1_331(res, a, b); +} + +ODE_PURE_INLINE void dMultiply0_133(dReal *res, const dReal *a, const dReal *b) +{ + dMultiplyHelper0_133(res, a, b); +} + +ODE_PURE_INLINE void dMultiply0_333(dReal *res, const dReal *a, const dReal *b) +{ + dMultiplyHelper0_133(res + 0, a + 0, b); + dMultiplyHelper0_133(res + 4, a + 4, b); + dMultiplyHelper0_133(res + 8, a + 8, b); +} + +ODE_PURE_INLINE void dMultiply1_333(dReal *res, const dReal *a, const dReal *b) +{ + dMultiplyHelper1_133(res + 0, b, a + 0); + dMultiplyHelper1_133(res + 4, b, a + 1); + dMultiplyHelper1_133(res + 8, b, a + 2); +} + +ODE_PURE_INLINE void dMultiply2_333(dReal *res, const dReal *a, const dReal *b) +{ + dMultiplyHelper0_331(res + 0, b, a + 0); + dMultiplyHelper0_331(res + 4, b, a + 4); + dMultiplyHelper0_331(res + 8, b, a + 8); +} + +ODE_PURE_INLINE void dMultiplyAdd0_331(dReal *res, const dReal *a, const dReal *b) +{ + dReal tmp[3]; + dMultiplyHelper0_331(tmp, a, b); + dAddVectors3(res, res, tmp); +} + +ODE_PURE_INLINE void dMultiplyAdd1_331(dReal *res, const dReal *a, const dReal *b) +{ + dReal tmp[3]; + dMultiplyHelper1_331(tmp, a, b); + dAddVectors3(res, res, tmp); +} + +ODE_PURE_INLINE void dMultiplyAdd0_133(dReal *res, const dReal *a, const dReal *b) +{ + dReal tmp[3]; + dMultiplyHelper0_133(tmp, a, b); + dAddVectors3(res, res, tmp); +} + +ODE_PURE_INLINE void dMultiplyAdd0_333(dReal *res, const dReal *a, const dReal *b) +{ + dReal tmp[3]; + dMultiplyHelper0_133(tmp, a + 0, b); + dAddVectors3(res+ 0, res + 0, tmp); + dMultiplyHelper0_133(tmp, a + 4, b); + dAddVectors3(res + 4, res + 4, tmp); + dMultiplyHelper0_133(tmp, a + 8, b); + dAddVectors3(res + 8, res + 8, tmp); +} + +ODE_PURE_INLINE void dMultiplyAdd1_333(dReal *res, const dReal *a, const dReal *b) +{ + dReal tmp[3]; + dMultiplyHelper1_133(tmp, b, a + 0); + dAddVectors3(res + 0, res + 0, tmp); + dMultiplyHelper1_133(tmp, b, a + 1); + dAddVectors3(res + 4, res + 4, tmp); + dMultiplyHelper1_133(tmp, b, a + 2); + dAddVectors3(res + 8, res + 8, tmp); +} + +ODE_PURE_INLINE void dMultiplyAdd2_333(dReal *res, const dReal *a, const dReal *b) +{ + dReal tmp[3]; + dMultiplyHelper0_331(tmp, b, a + 0); + dAddVectors3(res + 0, res + 0, tmp); + dMultiplyHelper0_331(tmp, b, a + 4); + dAddVectors3(res + 4, res + 4, tmp); + dMultiplyHelper0_331(tmp, b, a + 8); + dAddVectors3(res + 8, res + 8, tmp); +} + +ODE_PURE_INLINE dReal dCalcMatrix3Det( const dReal* mat ) +{ + dReal det; + + det = mat[0] * ( mat[5]*mat[10] - mat[9]*mat[6] ) + - mat[1] * ( mat[4]*mat[10] - mat[8]*mat[6] ) + + mat[2] * ( mat[4]*mat[9] - mat[8]*mat[5] ); + + return( det ); +} + +/** + Closed form matrix inversion, copied from + collision_util.h for use in the stepper. + + Returns the determinant. + returns 0 and does nothing + if the matrix is singular. +*/ +ODE_PURE_INLINE dReal dInvertMatrix3(dReal *dst, const dReal *ma) +{ + dReal det; + dReal detRecip; + + det = dCalcMatrix3Det( ma ); + + + /* Setting an arbitrary non-zero threshold + for the determinant doesn't do anyone + any favors. The condition number is the + important thing. If all the eigen-values + of the matrix are small, so is the + determinant, but it can still be well + conditioned. + A single extremely large eigen-value could + push the determinant over threshold, but + produce a very unstable result if the other + eigen-values are small. So we just say that + the determinant must be non-zero and trust the + caller to provide well-conditioned matrices. + */ + if ( det == 0 ) + { + return 0; + } + + detRecip = dRecip(det); + + dst[0] = ( ma[5]*ma[10] - ma[6]*ma[9] ) * detRecip; + dst[1] = ( ma[9]*ma[2] - ma[1]*ma[10] ) * detRecip; + dst[2] = ( ma[1]*ma[6] - ma[5]*ma[2] ) * detRecip; + + dst[4] = ( ma[6]*ma[8] - ma[4]*ma[10] ) * detRecip; + dst[5] = ( ma[0]*ma[10] - ma[8]*ma[2] ) * detRecip; + dst[6] = ( ma[4]*ma[2] - ma[0]*ma[6] ) * detRecip; + + dst[8] = ( ma[4]*ma[9] - ma[8]*ma[5] ) * detRecip; + dst[9] = ( ma[8]*ma[1] - ma[0]*ma[9] ) * detRecip; + dst[10] = ( ma[0]*ma[5] - ma[1]*ma[4] ) * detRecip; + + return det; +} + + +/* Include legacy macros here */ +#include <ode/odemath_legacy.h> + + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * normalize 3x1 and 4x1 vectors (i.e. scale them to unit length) + */ + +/* For DLL export*/ +ODE_API int dSafeNormalize3 (dVector3 a); +ODE_API int dSafeNormalize4 (dVector4 a); +ODE_API void dNormalize3 (dVector3 a); /* Potentially asserts on zero vec*/ +ODE_API void dNormalize4 (dVector4 a); /* Potentially asserts on zero vec*/ + +/* + * given a unit length "normal" vector n, generate vectors p and q vectors + * that are an orthonormal basis for the plane space perpendicular to n. + * i.e. this makes p,q such that n,p,q are all perpendicular to each other. + * q will equal n x p. if n is not unit length then p will be unit length but + * q wont be. + */ + +ODE_API void dPlaneSpace (const dVector3 n, dVector3 p, dVector3 q); +/* Makes sure the matrix is a proper rotation, returns a boolean status */ +ODE_API int dOrthogonalizeR(dMatrix3 m); + + + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/libs/ode-0.16.1/include/ode/odemath_legacy.h b/libs/ode-0.16.1/include/ode/odemath_legacy.h new file mode 100644 index 0000000..a389588 --- /dev/null +++ b/libs/ode-0.16.1/include/ode/odemath_legacy.h @@ -0,0 +1,162 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_ODEMATH_LEGACY_H_ +#define _ODE_ODEMATH_LEGACY_H_ + + +/* + * These macros are not used any more inside of ODE + * They are kept for backward compatibility with external code that + * might still be using them. + */ + +/* + * General purpose vector operations with other vectors or constants. + */ + +#define dOP(a,op,b,c) do { \ + (a)[0] = ((b)[0]) op ((c)[0]); \ + (a)[1] = ((b)[1]) op ((c)[1]); \ + (a)[2] = ((b)[2]) op ((c)[2]); \ +} while (0) +#define dOPC(a,op,b,c) do { \ + (a)[0] = ((b)[0]) op (c); \ + (a)[1] = ((b)[1]) op (c); \ + (a)[2] = ((b)[2]) op (c); \ +} while (0) +#define dOPE(a,op,b) do {\ + (a)[0] op ((b)[0]); \ + (a)[1] op ((b)[1]); \ + (a)[2] op ((b)[2]); \ +} while (0) +#define dOPEC(a,op,c) do { \ + (a)[0] op (c); \ + (a)[1] op (c); \ + (a)[2] op (c); \ +} while (0) + +/* Define an equation with operators + * For example this function can be used to replace + * <PRE> + * for (int i=0; i<3; ++i) + * a[i] += b[i] + c[i]; + * </PRE> + */ +#define dOPE2(a,op1,b,op2,c) do { \ + (a)[0] op1 ((b)[0]) op2 ((c)[0]); \ + (a)[1] op1 ((b)[1]) op2 ((c)[1]); \ + (a)[2] op1 ((b)[2]) op2 ((c)[2]); \ +} while (0) + + +#define dLENGTHSQUARED(a) dCalcVectorLengthSquare3(a) +#define dLENGTH(a) dCalcVectorLength3(a) +#define dDISTANCE(a, b) dCalcPointsDistance3(a, b) + + +#define dDOT(a, b) dCalcVectorDot3(a, b) +#define dDOT13(a, b) dCalcVectorDot3_13(a, b) +#define dDOT31(a, b) dCalcVectorDot3_31(a, b) +#define dDOT33(a, b) dCalcVectorDot3_33(a, b) +#define dDOT14(a, b) dCalcVectorDot3_14(a, b) +#define dDOT41(a, b) dCalcVectorDot3_41(a, b) +#define dDOT44(a, b) dCalcVectorDot3_44(a, b) + + +/* + * cross product, set a = b x c. dCROSSpqr means that elements of `a', `b' + * and `c' are spaced p, q and r indexes apart respectively. + * dCROSS() means dCROSS111. `op' is normally `=', but you can set it to + * +=, -= etc to get other effects. + */ + +#define dCROSS(a,op,b,c) \ + do { \ + (a)[0] op ((b)[1]*(c)[2] - (b)[2]*(c)[1]); \ + (a)[1] op ((b)[2]*(c)[0] - (b)[0]*(c)[2]); \ + (a)[2] op ((b)[0]*(c)[1] - (b)[1]*(c)[0]); \ + } while(0) +#define dCROSSpqr(a,op,b,c,p,q,r) \ + do { \ + (a)[ 0] op ((b)[ q]*(c)[2*r] - (b)[2*q]*(c)[ r]); \ + (a)[ p] op ((b)[2*q]*(c)[ 0] - (b)[ 0]*(c)[2*r]); \ + (a)[2*p] op ((b)[ 0]*(c)[ r] - (b)[ q]*(c)[ 0]); \ + } while(0) +#define dCROSS114(a,op,b,c) dCROSSpqr(a,op,b,c,1,1,4) +#define dCROSS141(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,1) +#define dCROSS144(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,4) +#define dCROSS411(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,1) +#define dCROSS414(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,4) +#define dCROSS441(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,1) +#define dCROSS444(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,4) + + +/* +* set a 3x3 submatrix of A to a matrix such that submatrix(A)*b = a x b. +* A is stored by rows, and has `skip' elements per row. the matrix is +* assumed to be already zero, so this does not write zero elements! +* if (plus,minus) is (+,-) then a positive version will be written. +* if (plus,minus) is (-,+) then a negative version will be written. +*/ + +#define dCROSSMAT(A,a,skip,plus,minus) \ + do { \ + (A)[1] = minus (a)[2]; \ + (A)[2] = plus (a)[1]; \ + (A)[(skip)+0] = plus (a)[2]; \ + (A)[(skip)+2] = minus (a)[0]; \ + (A)[2*(skip)+0] = minus (a)[1]; \ + (A)[2*(skip)+1] = plus (a)[0]; \ + } while(0) + + + + +/* +Note: NEVER call any of these functions/macros with the same variable for A and C, +it is not equivalent to A*=B. +*/ + +#define dMULTIPLY0_331(A, B, C) dMultiply0_331(A, B, C) +#define dMULTIPLY1_331(A, B, C) dMultiply1_331(A, B, C) +#define dMULTIPLY0_133(A, B, C) dMultiply0_133(A, B, C) +#define dMULTIPLY0_333(A, B, C) dMultiply0_333(A, B, C) +#define dMULTIPLY1_333(A, B, C) dMultiply1_333(A, B, C) +#define dMULTIPLY2_333(A, B, C) dMultiply2_333(A, B, C) + +#define dMULTIPLYADD0_331(A, B, C) dMultiplyAdd0_331(A, B, C) +#define dMULTIPLYADD1_331(A, B, C) dMultiplyAdd1_331(A, B, C) +#define dMULTIPLYADD0_133(A, B, C) dMultiplyAdd0_133(A, B, C) +#define dMULTIPLYADD0_333(A, B, C) dMultiplyAdd0_333(A, B, C) +#define dMULTIPLYADD1_333(A, B, C) dMultiplyAdd1_333(A, B, C) +#define dMULTIPLYADD2_333(A, B, C) dMultiplyAdd2_333(A, B, C) + + +/* + * These macros are not used any more inside of ODE + * They are kept for backward compatibility with external code that + * might still be using them. + */ + + +#endif /* #ifndef _ODE_ODEMATH_LEGACY_H_ */ diff --git a/libs/ode-0.16.1/include/ode/precision.h b/libs/ode-0.16.1/include/ode/precision.h new file mode 100644 index 0000000..456fc36 --- /dev/null +++ b/libs/ode-0.16.1/include/ode/precision.h @@ -0,0 +1,16 @@ +#ifndef _ODE_PRECISION_H_ +#define _ODE_PRECISION_H_ + +/* Define dSINGLE for single precision, dDOUBLE for double precision, + * but never both! + */ + +#if defined(dIDESINGLE) +#define dSINGLE +#elif defined(dIDEDOUBLE) +#define dDOUBLE +#else +#define dSINGLE +#endif + +#endif diff --git a/libs/ode-0.16.1/include/ode/precision.h.in b/libs/ode-0.16.1/include/ode/precision.h.in new file mode 100644 index 0000000..47f3c95 --- /dev/null +++ b/libs/ode-0.16.1/include/ode/precision.h.in @@ -0,0 +1,16 @@ +#ifndef _ODE_PRECISION_H_ +#define _ODE_PRECISION_H_ + +/* Define dSINGLE for single precision, dDOUBLE for double precision, + * but never both! + */ + +#if defined(dIDESINGLE) +#define dSINGLE +#elif defined(dIDEDOUBLE) +#define dDOUBLE +#else +#define @ODE_PRECISION@ +#endif + +#endif diff --git a/libs/ode-0.16.1/include/ode/rotation.h b/libs/ode-0.16.1/include/ode/rotation.h new file mode 100644 index 0000000..a72be27 --- /dev/null +++ b/libs/ode-0.16.1/include/ode/rotation.h @@ -0,0 +1,70 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_ROTATION_H_ +#define _ODE_ROTATION_H_ + +#include <ode/common.h> +#include <ode/compatibility.h> + +#ifdef __cplusplus +extern "C" { +#endif + + +ODE_API void dRSetIdentity (dMatrix3 R); + +ODE_API void dRFromAxisAndAngle (dMatrix3 R, dReal ax, dReal ay, dReal az, + dReal angle); + +ODE_API void dRFromEulerAngles (dMatrix3 R, dReal phi, dReal theta, dReal psi); + +ODE_API void dRFrom2Axes (dMatrix3 R, dReal ax, dReal ay, dReal az, + dReal bx, dReal by, dReal bz); + +ODE_API void dRFromZAxis (dMatrix3 R, dReal ax, dReal ay, dReal az); + +ODE_API void dQSetIdentity (dQuaternion q); + +ODE_API void dQFromAxisAndAngle (dQuaternion q, dReal ax, dReal ay, dReal az, + dReal angle); + +/* Quaternion multiplication, analogous to the matrix multiplication routines. */ +/* qa = rotate by qc, then qb */ +ODE_API void dQMultiply0 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc); +/* qa = rotate by qc, then by inverse of qb */ +ODE_API void dQMultiply1 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc); +/* qa = rotate by inverse of qc, then by qb */ +ODE_API void dQMultiply2 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc); +/* qa = rotate by inverse of qc, then by inverse of qb */ +ODE_API void dQMultiply3 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc); + +ODE_API void dRfromQ (dMatrix3 R, const dQuaternion q); +ODE_API void dQfromR (dQuaternion q, const dMatrix3 R); +ODE_API void dDQfromW (dReal dq[4], const dVector3 w, const dQuaternion q); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/ode-0.16.1/include/ode/threading.h b/libs/ode-0.16.1/include/ode/threading.h new file mode 100644 index 0000000..9602b8f --- /dev/null +++ b/libs/ode-0.16.1/include/ode/threading.h @@ -0,0 +1,412 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * Threading support header file. * + * Copyright (C) 2011-2019 Oleh Derevenko. All rights reserved. * + * e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * ODE threading support interfaces + */ + + +#ifndef _ODE_THREADING_H_ +#define _ODE_THREADING_H_ + +#include <ode/odeconfig.h> +// Include <time.h> since time_t is used and it is not available by default in some OSes +#include <time.h> + + +#ifdef __cplusplus +extern "C" { +#endif + + +struct dxThreadingImplementation; +typedef struct dxThreadingImplementation *dThreadingImplementationID; + +typedef unsigned dmutexindex_t; +struct dxMutexGroup; +typedef struct dxMutexGroup *dMutexGroupID; + + +#define dTHREADING_THREAD_COUNT_UNLIMITED 0U + + + +/** + * @brief Allocates a group of muteces. + * + * The Mutex allocated do not need to support recursive locking. + * + * The Mutex names are provided to aid in debugging and thread state tracking. + * + * @param impl Threading implementation ID + * @param Mutex_count Number of Mutex to create + * @Mutex_names_ptr Pointer to optional Mutex names array to be associated with individual Mutex + * @returns MutexGroup ID or NULL if error occurred. + * + * @ingroup threading + * @see dMutexGroupFreeFunction + * @see dMutexGroupMutexLockFunction + * @see dMutexGroupMutexUnlockFunction + */ +typedef dMutexGroupID dMutexGroupAllocFunction (dThreadingImplementationID impl, dmutexindex_t Mutex_count, const char *const *Mutex_names_ptr/*=NULL*/); + +/** + * @brief Deletes a group of muteces. + * + * @param impl Threading implementation ID + * @param mutex_group Mutex group to deallocate + * + * @ingroup threading + * @see dMutexGroupAllocFunction + * @see dMutexGroupMutexLockFunction + * @see dMutexGroupMutexUnlockFunction + */ +typedef void dMutexGroupFreeFunction (dThreadingImplementationID impl, dMutexGroupID mutex_group); + +/** + * @brief Locks a mutex in a group of muteces. + * + * The function is to block execution until requested mutex can be locked. + * + * Note: Mutex provided may not support recursive locking. Calling this function + * while mutex is already locked by current thread will result in unpredictable behavior. + * + * @param impl Threading implementation ID + * @param mutex_group Mutex group to use for locking + * @param mutex_index The index of mutex to be locked (0..Mutex_count - 1) + * + * @ingroup threading + * @see dMutexGroupAllocFunction + * @see dMutexGroupFreeFunction + * @see dMutexGroupMutexUnlockFunction + */ +typedef void dMutexGroupMutexLockFunction (dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index); + +/** + * @brief Attempts to lock a mutex in a group of muteces. + * + * The function is to lock the requested mutex if it is unoccupied or + * immediately return failure if mutex is already locked by other thread. + * + * Note: Mutex provided may not support recursive locking. Calling this function + * while mutex is already locked by current thread will result in unpredictable behavior. + * + * @param impl Threading implementation ID + * @param mutex_group Mutex group to use for locking + * @param mutex_index The index of mutex to be locked (0..Mutex_count - 1) + * @returns 1 for success (mutex is locked) and 0 for failure (mutex is not locked) + * + * @ingroup threading + * @see dMutexGroupAllocFunction + * @see dMutexGroupFreeFunction + * @see dMutexGroupMutexLockFunction + * @see dMutexGroupMutexUnlockFunction + */ +/* typedef int dMutexGroupMutexTryLockFunction (dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index);*/ + +/** + * @brief Unlocks a mutex in a group of muteces. + * + * The function is to unlock the given mutex provided it had been locked before. + * + * @param impl Threading implementation ID + * @param mutex_group Mutex group to use for unlocking + * @param mutex_index The index of mutex to be unlocked (0..Mutex_count - 1) + * + * @ingroup threading + * @see dMutexGroupAllocFunction + * @see dMutexGroupFreeFunction + * @see dMutexGroupMutexLockFunction + */ +typedef void dMutexGroupMutexUnlockFunction (dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index); + + +struct dxCallReleasee; +typedef struct dxCallReleasee *dCallReleaseeID; + +struct dxCallWait; +typedef struct dxCallWait *dCallWaitID; + +typedef dsizeint ddependencycount_t; +typedef ddiffint ddependencychange_t; +typedef dsizeint dcallindex_t; +typedef int dThreadedCallFunction(void *call_context, dcallindex_t instance_index, + dCallReleaseeID this_releasee); + +typedef struct dxThreadedWaitTime +{ + time_t wait_sec; + unsigned long wait_nsec; + +} dThreadedWaitTime; + + +/** + * @brief Allocates a Wait ID that can be used to wait for a call. + * + * @param impl Threading implementation ID + * @returns Wait ID or NULL if error occurred + * + * @ingroup threading + * @see dThreadedCallWaitResetFunction + * @see dThreadedCallWaitFreeFunction + * @see dThreadedCallPostFunction + * @see dThreadedCallWaitFunction + */ +typedef dCallWaitID dThreadedCallWaitAllocFunction(dThreadingImplementationID impl); + +/** + * @brief Resets a Wait ID so that it could be used to wait for another call. + * + * @param impl Threading implementation ID + * @param call_wait Wait ID to reset + * + * @ingroup threading + * @see dThreadedCallWaitAllocFunction + * @see dThreadedCallWaitFreeFunction + * @see dThreadedCallPostFunction + * @see dThreadedCallWaitFunction + */ +typedef void dThreadedCallWaitResetFunction(dThreadingImplementationID impl, dCallWaitID call_wait); + +/** + * @brief Frees a Wait ID. + * + * @param impl Threading implementation ID + * @param call_wait Wait ID to delete + * + * @ingroup threading + * @see dThreadedCallWaitAllocFunction + * @see dThreadedCallPostFunction + * @see dThreadedCallWaitFunction + */ +typedef void dThreadedCallWaitFreeFunction(dThreadingImplementationID impl, dCallWaitID call_wait); + + +/** + * @brief Post a function to be called in another thread. + * + * A call is scheduled to be executed asynchronously. + * + * A @a out_summary_fault variable can be provided for call to accumulate any + * possible faults from its execution and execution of any possible sub-calls. + * This variable gets result that @a call_func returns. Also, if dependent calls + * are executed after the call already exits, the variable is also going to be + * updated with results of all those calls before control is released to master. + * + * @a out_post_releasee parameter receives a value of @c dCallReleaseeID that can + * later be used for @a dependent_releasee while scheduling sub-calls to make + * current call depend on them. The value is only returned if @a dependencies_count + * is not zero (i.e. if any dependencies are expected at all). The call is not going + * to start until all its dependencies complete. + * + * In case if number of dependencies is unknown in advance 1 can be passed on call + * scheduling. Then @c dThreadedCallDependenciesCountAlterFunction can be used to + * add one more extra dependencies before scheduling each subcall. And then, after + * all sub-calls had been scheduled, @c dThreadedCallDependenciesCountAlterFunction + * can be used again to subtract initial extra dependency from total number. + * Adding one dependency in advance is necessary to obtain releasee ID and to make + * sure the call will not start and will not terminate before all sub-calls are scheduled. + * + * Extra dependencies can also be added from the call itself after it has already + * been started (with parameter received in @c dThreadedCallFunction). + * In that case those dependencies will start immediately or after call returns + * but the call's master will not be released/notified until all additional + * dependencies complete. This can be used to schedule sub-calls from a call and + * then pass own job to another sub-call dependent on those initial sub-calls. + * + * By using @ call_wait it is possible to assign a Wait ID that can later + * be passed into @c dThreadedCallWaitFunction to wait for call completion. + * + * If @a call_name is available (and it should!) the string must remain valid until + * after call completion. In most cases this should be a static string literal. + * + * Since the function is an analogue of normal method call it is not supposed to fail. + * Any complications with resource allocation on call scheduling should be + * anticipated, avoided and worked around by implementation. + * + * @param impl Threading implementation ID + * @param out_summary_fault Optional pointer to variable to be set to 1 if function + * call (or any sub-call) fails internally, or 0 if all calls return success + * @param out_post_releasee Optional pointer to variable to receive releasee ID + * associated with the call + * @param dependencies_count Number of dependencies that are going to reference + * this call as dependent releasee + * @param dependent_releasee Optional releasee ID to reference with this call + * @param call_wait Optional Wait ID that can later be used to wait for the call + * @param call_func Pointer to function to be called + * @param call_context Context parameter to be passed into the call + * @param instance_index Index parameter to be passed into the call + * @param call_name Optional name to be associated with the call (for debugging and state tracking) + * + * @ingroup threading + * @see dThreadedCallWaitFunction + * @see dThreadedCallDependenciesCountAlterFunction + * @see dThreadingImplResourcesForCallsPreallocateFunction + */ +typedef void dThreadedCallPostFunction(dThreadingImplementationID impl, int *out_summary_fault/*=NULL*/, + dCallReleaseeID *out_post_releasee/*=NULL*/, ddependencycount_t dependencies_count, dCallReleaseeID dependent_releasee/*=NULL*/, + dCallWaitID call_wait/*=NULL*/, + dThreadedCallFunction *call_func, void *call_context, dcallindex_t instance_index, + const char *call_name/*=NULL*/); + +/** + * @brief Add or remove extra dependencies from call that has been scheduled + * or is in process of execution. + * + * Extra dependencies can be added to a call if exact number of sub-calls is + * not known in advance at the moment the call is scheduled. Also, some dependencies + * can be removed if sub-calls were planned but then dropped. + * + * In case if total dependency count of a call reaches zero by result of invoking + * this function, the call is free to start executing immediately. + * + * After the call execution had been started, any additional dependencies can only + * be added from the call function itself! + * + * @param impl Threading implementation ID + * @param target_releasee ID of releasee to apply dependencies count change to + * @param dependencies_count_change Number of dependencies to add or remove + * + * @ingroup threading + * @see dThreadedCallPostFunction + */ +typedef void dThreadedCallDependenciesCountAlterFunction(dThreadingImplementationID impl, dCallReleaseeID target_releasee, + ddependencychange_t dependencies_count_change); + +/** + * @brief Wait for a posted call to complete. + * + * Function blocks until a call identified by @a call_wait completes or + * timeout elapses. + * + * IT IS ILLEGAL TO INVOKE THIS FUNCTION FROM WITHIN A THREADED CALL! + * This is because doing so will block a physical thread and will require + * increasing worker thread count to avoid starvation. Use call dependencies + * if it is necessary make sure sub-calls have been completed instead! + * + * If @a timeout_time_ptr is NULL, the function waits without time limit. If @a timeout_time_ptr + * points to zero value, the function only checks status and does not block. + * + * If @a wait_name is available (and it should!) the string must remain valid for + * the duration of wait. In most cases this should be a static string literal. + * + * Function is not expected to return failures caused by system call faults as + * those are hardly ever possible to be handled in this case anyway. In event of + * system call fault the function is supposed to terminate application. + * + * @param impl Threading implementation ID + * @param out_wait_status Optional pointer to variable to receive 1 if waiting succeeded + * or 0 in case of timeout + * @param call_wait Wait ID that had been passed to scheduling a call that needs to be waited for + * @param timeout_time_ptr Optional pointer to time specification the wait must not + * last longer than (pass NULL for infinite timeout) + * @param wait_name Optional name to be associated with the wait (for debugging and state tracking) + * + * @ingroup threading + * @see dThreadedCallPostFunction + */ +typedef void dThreadedCallWaitFunction(dThreadingImplementationID impl, int *out_wait_status/*=NULL*/, + dCallWaitID call_wait, const dThreadedWaitTime *timeout_time_ptr/*=NULL*/, + const char *wait_name/*=NULL*/); + +/** + * @brief Retrieve number of active threads that serve the implementation. + * + * @param impl Threading implementation ID + * @returns Number of active threads + * + * @ingroup threading + */ +typedef unsigned dThreadingImplThreadCountRetrieveFunction(dThreadingImplementationID impl); + +/** + * @brief Preallocate resources to handle posted calls. + * + * The function is intended to make sure enough resources is preallocated for the + * implementation to be able to handle posted calls. Then @c max_simultaneous_calls_estimate + * is an estimate of how many posted calls can potentially be active or scheduled + * at the same time. The value is usually derived from the way the calls are posted + * in library code and dependencies between them. + * + * @warning While working on an implementation be prepared that the estimate provided + * yet rarely but theoretically can be exceeded due to unpredictability of thread execution. + * + * This function is normally going to be invoked by library each time it is entered + * from outside to do the job but before any threaded calls are going to be posted. + * + * @param impl Threading implementation ID + * @param max_simultaneous_calls_estimate An estimated number of calls that can be posted simultaneously + * @returns 1 or 0 to indicate success or failure + * + * @ingroup threading + * @see dThreadedCallPostFunction + */ +typedef int dThreadingImplResourcesForCallsPreallocateFunction(dThreadingImplementationID impl, + ddependencycount_t max_simultaneous_calls_estimate); + + +/** + * @brief An interface structure with function pointers to be provided by threading implementation. + */ +typedef struct dxThreadingFunctionsInfo +{ + unsigned struct_size; + + dMutexGroupAllocFunction *alloc_mutex_group; + dMutexGroupFreeFunction *free_mutex_group; + dMutexGroupMutexLockFunction *lock_group_mutex; + dMutexGroupMutexUnlockFunction *unlock_group_mutex; + + dThreadedCallWaitAllocFunction *alloc_call_wait; + dThreadedCallWaitResetFunction *reset_call_wait; + dThreadedCallWaitFreeFunction *free_call_wait; + + dThreadedCallPostFunction *post_call; + dThreadedCallDependenciesCountAlterFunction *alter_call_dependencies_count; + dThreadedCallWaitFunction *wait_call; + + dThreadingImplThreadCountRetrieveFunction *retrieve_thread_count; + dThreadingImplResourcesForCallsPreallocateFunction *preallocate_resources_for_calls; + + /* + * Beware of Jon Watte's anger if you dare to uncomment this! + * May cryptic text below be you a warning! + * Стародавні легенди розказують, що кожного ÑміливцÑ, хто наважитьÑÑ Ð¿Ð¾Ñ€ÑƒÑˆÐ¸Ñ‚Ð¸ табу + * Ñ– відкрити заборонений код, Ñпіткає Ñтрашне проклÑÑ‚Ñ‚Ñ Ñ– він відразу почне робити + * одні лиш помилки. + * + * dMutexGroupMutexTryLockFunction *trylock_group_mutex; + */ + +} dThreadingFunctionsInfo; + + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef _ODE_THREADING_H_ */ diff --git a/libs/ode-0.16.1/include/ode/threading_impl.h b/libs/ode-0.16.1/include/ode/threading_impl.h new file mode 100644 index 0000000..0781d6a --- /dev/null +++ b/libs/ode-0.16.1/include/ode/threading_impl.h @@ -0,0 +1,292 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * Builtin ODE threading implementation header. * + * Copyright (C) 2011-2019 Oleh Derevenko. All rights reserved. * + * e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * A threading implementation built into ODE for those who does not care to + * or can't implement an own one. + */ + +#ifndef _ODE_THREADING_IMPL_H_ +#define _ODE_THREADING_IMPL_H_ + + +#include <ode/odeconfig.h> +#include <ode/threading.h> + + +#ifdef __cplusplus +extern "C" { +#endif + + +struct dxThreadingThreadPool; +typedef struct dxThreadingThreadPool *dThreadingThreadPoolID; + + +/** + * @brief Allocates built-in self-threaded threading implementation object. + * + * A self-threaded implementation is a type of implementation that performs + * processing of posted calls by means of caller thread itself. This type of + * implementation does not need thread pool to serve it. + * + * Note that since May 9th, 2017 (rev. #2066) the Self-Threaded implementation + * returns 0 rather than 1 as available thread count to distinguish from + * thread pools with just one thread in them. + * + * The processing is arranged in a way to prevent call stack depth growth + * as more and more nested calls are posted. + * + * Note that it is not necessary to create and assign a self-threaded + * implementation to a world, as there is a global one used by default + * if no implementation is explicitly assigned. You should only assign + * each world an individual threading implementation instance if simulations + * need to be run in parallel in multiple threads for the worlds. + * + * @returns ID of object allocated or NULL on failure + * + * @ingroup threading + * @see dThreadingAllocateMultiThreadedImplementation + * @see dThreadingFreeImplementation + */ +ODE_API dThreadingImplementationID dThreadingAllocateSelfThreadedImplementation(); + +/** + * @brief Allocates built-in multi-threaded threading implementation object. + * + * A multi-threaded implementation is a type of implementation that has to be + * served with a thread pool. The thread pool can be either the built-in ODE object + * or set of external threads that dedicate themselves to this purpose and stay + * in ODE until implementation releases them. + * + * @returns ID of object allocated or NULL on failure + * + * @ingroup threading + * @see dThreadingThreadPoolServeMultiThreadedImplementation + * @see dExternalThreadingServeMultiThreadedImplementation + * @see dThreadingFreeImplementation + */ +ODE_API dThreadingImplementationID dThreadingAllocateMultiThreadedImplementation(); + +/** + * @brief Retrieves the functions record of a built-in threading implementation. + * + * The implementation can be the one allocated by ODE (from @c dThreadingAllocateMultiThreadedImplementation). + * Do not use this function with self-made custom implementations - + * they should be bundled with their own set of functions. + * + * @param impl Threading implementation ID + * @returns Pointer to associated functions structure + * + * @ingroup threading + * @see dThreadingAllocateMultiThreadedImplementation + */ +ODE_API const dThreadingFunctionsInfo *dThreadingImplementationGetFunctions(dThreadingImplementationID impl); + +/** + * @brief Requests a built-in implementation to release threads serving it. + * + * The function unblocks threads employed in implementation serving and lets them + * return to from where they originate. It's the responsibility of external code + * to make sure all the calls to ODE that might be dependent on given threading + * implementation object had already returned before this call is made. If threading + * implementation is still processing some posted calls while this function is + * invoked the behavior is implementation dependent. + * + * This call is to be used to request the threads to be released before waiting + * for them in host pool or before waiting for them to exit. Implementation object + * must not be destroyed before it is known that all the serving threads have already + * returned from it. If implementation needs to be reused after this function is called + * and all the threads have exited from it a call to @c dThreadingImplementationCleanupForRestart + * must be made to restore internal state of the object. + * + * If this function is called for self-threaded built-in threading implementation + * the call has no effect. + * + * @param impl Threading implementation ID + * + * @ingroup threading + * @see dThreadingAllocateMultiThreadedImplementation + * @see dThreadingImplementationCleanupForRestart + */ +ODE_API void dThreadingImplementationShutdownProcessing(dThreadingImplementationID impl); + +/** + * @brief Restores built-in implementation's state to let it be reused after shutdown. + * + * If a multi-threaded built-in implementation needs to be reused after a call + * to @c dThreadingImplementationShutdownProcessing this call is to be made to + * restore object's internal state. After that the implementation can be served again. + * + * If this function is called for self-threaded built-in threading implementation + * the call has no effect. + * + * @param impl Threading implementation ID + * + * @ingroup threading + * @see dThreadingAllocateMultiThreadedImplementation + * @see dThreadingImplementationShutdownProcessing + */ +ODE_API void dThreadingImplementationCleanupForRestart(dThreadingImplementationID impl); + +/** + * @brief Deletes an instance of built-in threading implementation. + * + * @warning A care must be taken to make sure the implementation is unassigned + * from all the objects it was assigned to and that there are no more threads + * serving it before attempting to call this function. + * + * @param impl Threading implementation ID + * + * @ingroup threading + * @see dThreadingAllocateMultiThreadedImplementation + */ +ODE_API void dThreadingFreeImplementation(dThreadingImplementationID impl); + + +typedef void (dThreadReadyToServeCallback)(void *callback_context); + +/** + * @brief An entry point for external threads that would like to serve a built-in + * threading implementation object. + * + * A thread that calls this function remains blocked in ODE and serves implementation + * object @p impl until being released with @c dThreadingImplementationShutdownProcessing call. + * This function can be used to provide external threads instead of ODE's built-in + * thread pools. + * + * The optional callback @readiness_callback is called after the thread has reached + * and has registered within the implementation. The implementation should not + * be used until all dedicated threads register within it as otherwise it will not + * have accurate view of the execution resources available. + * + * @param impl Threading implementation ID + * @param readiness_callback Optional readiness callback to be called after thread enters the implementation + * @param callback_context A value to be passed as parameter to readiness callback + * + * @ingroup threading + * @see dThreadingAllocateMultiThreadedImplementation + * @see dThreadingImplementationShutdownProcessing + */ +ODE_API void dExternalThreadingServeMultiThreadedImplementation(dThreadingImplementationID impl, + dThreadReadyToServeCallback *readiness_callback/*=NULL*/, void *callback_context/*=NULL*/); + + +/** + * @brief Creates an instance of built-in thread pool object that can be used to serve + * multi-threaded threading implementations. + * + * The threads allocated inherit priority of caller thread. Their affinity is not + * explicitly adjusted and gets the value the system assigns by default. Threads + * have their stack memory fully committed immediately on start. On POSIX platforms + * threads are started with all the possible signals blocked. Threads execute + * calls to @c dAllocateODEDataForThread with @p ode_data_allocate_flags + * on initialization. + * + * On POSIX platforms this function must be called with signals masked + * or other measures must be taken to prevent reception of signals by calling thread + * for the duration of the call. + * + * @param thread_count Number of threads to start in pool + * @param stack_size Size of stack to be used for every thread or 0 for system default value + * @param ode_data_allocate_flags Flags to be passed to @c dAllocateODEDataForThread on behalf of each thread + * @returns ID of object allocated or NULL on failure + * + * @ingroup threading + * @see dThreadingAllocateMultiThreadedImplementation + * @see dThreadingImplementationShutdownProcessing + * @see dThreadingFreeThreadPool + */ +ODE_API dThreadingThreadPoolID dThreadingAllocateThreadPool(unsigned thread_count, + dsizeint stack_size, unsigned int ode_data_allocate_flags, void *reserved/*=NULL*/); + +/** + * @brief Commands an instance of built-in thread pool to serve a built-in multi-threaded + * threading implementation. + * + * A pool can only serve one threading implementation at a time. + * Call @c dThreadingImplementationShutdownProcessing to release pool threads + * from implementation serving and make them idle. Pool threads must be released + * from any implementations before pool is attempted to be deleted. + * + * This function waits for threads to register within implementation before returning. + * So, after the function call exits the implementation can be used immediately. + * + * @param pool Thread pool ID to serve the implementation + * @param impl Implementation ID of implementation to be served + * + * @ingroup threading + * @see dThreadingAllocateThreadPool + * @see dThreadingAllocateMultiThreadedImplementation + * @see dThreadingImplementationShutdownProcessing + */ +ODE_API void dThreadingThreadPoolServeMultiThreadedImplementation(dThreadingThreadPoolID pool, dThreadingImplementationID impl); + +/** + * @brief Waits until all pool threads are released from threading implementation + * they might be serving. + * + * The function can be used after a call to @c dThreadingImplementationShutdownProcessing + * to make sure all the threads have already been released by threading implementation + * and it can be deleted or it can be cleaned up for restart and served by another pool + * or this pool's threads can be used to serve another threading implementation. + * + * Note that is it not necessary to call this function before pool destruction + * since @c dThreadingFreeThreadPool performs similar wait operation implicitly on its own. + * + * It is OK to call this function even if pool was not serving any threading implementation + * in which case the call exits immediately with minimal delay. + * + * @param pool Thread pool ID to wait for + * + * @ingroup threading + * @see dThreadingAllocateThreadPool + * @see dThreadingImplementationShutdownProcessing + * @see dThreadingFreeThreadPool + */ +ODE_API void dThreadingThreadPoolWaitIdleState(dThreadingThreadPoolID pool); + +/** + * @brief Deletes a built-in thread pool instance. + * + * The pool threads must be released from any implementations they might be serving + * before this function is called. Otherwise the call is going to block + * and wait until pool's threads return. + * + * @param pool Thread pool ID to delete + * + * @ingroup threading + * @see dThreadingAllocateThreadPool + * @see dThreadingImplementationShutdownProcessing + */ +ODE_API void dThreadingFreeThreadPool(dThreadingThreadPoolID pool); + + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef _ODE_THREADING_IMPL_H_ */ diff --git a/libs/ode-0.16.1/include/ode/timer.h b/libs/ode-0.16.1/include/ode/timer.h new file mode 100644 index 0000000..fe1483f --- /dev/null +++ b/libs/ode-0.16.1/include/ode/timer.h @@ -0,0 +1,76 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_TIMER_H_ +#define _ODE_TIMER_H_ + +#include <ode/odeconfig.h> + +#ifdef __cplusplus +extern "C" { +#endif + + +/* stop watch objects */ + +typedef struct dStopwatch { + double time; /* total clock count */ + unsigned long cc[2]; /* clock count since last `start' */ +} dStopwatch; + +ODE_API void dStopwatchReset (dStopwatch *); +ODE_API void dStopwatchStart (dStopwatch *); +ODE_API void dStopwatchStop (dStopwatch *); +ODE_API double dStopwatchTime (dStopwatch *); /* returns total time in secs */ + + +/* code timers */ + +ODE_API void dTimerStart (const char *description); /* pass a static string here */ +ODE_API void dTimerNow (const char *description); /* pass a static string here */ +ODE_API void dTimerEnd(void); + +/* print out a timer report. if `average' is nonzero, print out the average + * time for each slot (this is only meaningful if the same start-now-end + * calls are being made repeatedly. + */ +ODE_API void dTimerReport (FILE *fout, int average); + + +/* resolution */ + +/* returns the timer ticks per second implied by the timing hardware or API. + * the actual timer resolution may not be this great. + */ +ODE_API double dTimerTicksPerSecond(void); + +/* returns an estimate of the actual timer resolution, in seconds. this may + * be greater than 1/ticks_per_second. + */ +ODE_API double dTimerResolution(void); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/ode-0.16.1/include/ode/version.h b/libs/ode-0.16.1/include/ode/version.h new file mode 100644 index 0000000..980217e --- /dev/null +++ b/libs/ode-0.16.1/include/ode/version.h @@ -0,0 +1,6 @@ +#ifndef _ODE_VERSION_H_ +#define _ODE_VERSION_H_ + +#define dODE_VERSION "0.16.1" + +#endif diff --git a/libs/ode-0.16.1/include/ode/version.h.in b/libs/ode-0.16.1/include/ode/version.h.in new file mode 100644 index 0000000..b5d3c81 --- /dev/null +++ b/libs/ode-0.16.1/include/ode/version.h.in @@ -0,0 +1,6 @@ +#ifndef _ODE_VERSION_H_ +#define _ODE_VERSION_H_ + +#define dODE_VERSION "@ODE_VERSION@" + +#endif diff --git a/libs/ode-0.16.1/install-sh b/libs/ode-0.16.1/install-sh new file mode 100755 index 0000000..0b0fdcb --- /dev/null +++ b/libs/ode-0.16.1/install-sh @@ -0,0 +1,501 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2013-12-25.23; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# 'make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +tab=' ' +nl=' +' +IFS=" $tab$nl" + +# Set DOITPROG to "echo" to test this script. + +doit=${DOITPROG-} +doit_exec=${doit:-exec} + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +is_target_a_directory=possibly + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) + is_target_a_directory=always + dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) is_target_a_directory=never;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +# We allow the use of options -d and -T together, by making -d +# take the precedence; this is for compatibility with GNU install. + +if test -n "$dir_arg"; then + if test -n "$dst_arg"; then + echo "$0: target directory not allowed when installing a directory." >&2 + exit 1 + fi +fi + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call 'install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + if test $# -gt 1 || test "$is_target_a_directory" = always; then + if test ! -d "$dst_arg"; then + echo "$0: $dst_arg: Is not a directory." >&2 + exit 1 + fi + fi +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for 'test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test "$is_target_a_directory" = never; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + dstdir=`dirname "$dst"` + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + oIFS=$IFS + IFS=/ + set -f + set fnord $dstdir + shift + set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + set +f && + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/libs/ode-0.16.1/libccd/BSD-LICENSE b/libs/ode-0.16.1/libccd/BSD-LICENSE new file mode 100644 index 0000000..6d7fa23 --- /dev/null +++ b/libs/ode-0.16.1/libccd/BSD-LICENSE @@ -0,0 +1,44 @@ +libccd +------- + +Copyright (c)2010 Daniel Fiser <danfis@danfis.cz>, +Intelligent and Mobile Robotics Group, Department of Cybernetics, +Faculty of Electrical Engineering, Czech Technical University in Prague. +All rights reserved. + + +This work was supported by SYMBRION and REPLICATOR projects. +The SYMBRION project is funded by European Commission within the work +"Future and Emergent Technologies Proactive" under grant agreement no. +216342. +The REPLICATOR project is funded within the work programme "Cognitive +Systems, Interaction, Robotics" under grant agreement no. 216240. +http://www.symbrion.eu/ +http://www.replicators.eu/ + + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +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. diff --git a/libs/ode-0.16.1/libccd/Makefile.am b/libs/ode-0.16.1/libccd/Makefile.am new file mode 100644 index 0000000..c08c4b3 --- /dev/null +++ b/libs/ode-0.16.1/libccd/Makefile.am @@ -0,0 +1,6 @@ +SUBDIRS = src + +EXTRA_DIST = \ + bootstrap \ + BSD-LICENSE \ + README diff --git a/libs/ode-0.16.1/libccd/Makefile.in b/libs/ode-0.16.1/libccd/Makefile.in new file mode 100644 index 0000000..0973929 --- /dev/null +++ b/libs/ode-0.16.1/libccd/Makefile.in @@ -0,0 +1,804 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(am__DIST_COMMON) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/src/config.h +CONFIG_CLEAN_FILES = src/ccd/precision.h +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + cscope distdir dist dist-all distcheck +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +CSCOPE = cscope +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/../compile \ + $(top_srcdir)/../config.guess $(top_srcdir)/../config.sub \ + $(top_srcdir)/../install-sh $(top_srcdir)/../ltmain.sh \ + $(top_srcdir)/../missing $(top_srcdir)/src/ccd/precision.h.in \ + README +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +DIST_TARGETS = dist-gzip +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_PRECISION = @CCD_PRECISION@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = src +EXTRA_DIST = \ + bootstrap \ + BSD-LICENSE \ + README + +all: all-recursive + +.SUFFIXES: +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): +src/ccd/precision.h: $(top_builddir)/config.status $(top_srcdir)/src/ccd/precision.h.in + cd $(top_builddir) && $(SHELL) ./config.status $@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__post_remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + +dist-tarZ: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__post_remove_distdir) + +dist-shar: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__post_remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__post_remove_distdir) + +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build/sub \ + && ../../configure \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=../.. --prefix="$$dc_install_base" \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__post_remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--refresh check check-am clean clean-cscope clean-generic \ + clean-libtool cscope cscopelist-am ctags ctags-am dist \ + dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ + dist-xz dist-zip distcheck distclean distclean-generic \ + distclean-libtool distclean-tags distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/libccd/README b/libs/ode-0.16.1/libccd/README new file mode 100644 index 0000000..f363d6c --- /dev/null +++ b/libs/ode-0.16.1/libccd/README @@ -0,0 +1,72 @@ +libccd is library for a collision detection between two convex shapes. +libccd implements variation on Gilbert–Johnson–Keerthi algorithm plus Expand +Polytope Algorithm (EPA) and also implements algorithm Minkowski Portal +Refinement (MPR, a.k.a. XenoCollide) as described in Game Programming Gems 7. + +For more info see home of libccd: http://libccd.danfis.cz. + + +Dependencies +------------- +This library is currently based only on standard libraries. +The only exception are testsuites that are built on top of CU +(cu.danfis.cz) library licensed under LGPL, however only testing depends on +it and libccd library itself can be distributed without it. + + +License +-------- +libccd is licensed under OSI-approved 3-clause BSD License, text of license +is distributed along with source code in BSD-LICENSE file. +Each file should include license notice, the rest should be considered as +licensed under 3-clause BSD License. + + +Compile And Install +-------------------- +Simply type 'make' and 'make install' in src/ directory. + +Library libccd is by default compiled in double precision of floating point +numbers - you can controll this by options USE_SINGLE/USE_DOUBLE, i.e.: + $ make USE_SINGLE=yes +will compile library in single precision. + +Installation directory can be changed by options PREFIX, INCLUDEDIR and +LIBDIR. + +For more info type 'make help'. + + +Compile And Install Using Autotools +------------------------------------ +libccd also contains support for autotools: +1) Generate configure script etc.: $ ./bootstrap +2) Create new build/ directory: $ mkdir build && cd build +3) Run configure script: $ ../configure +4) Run make and make install: $ make && make install + +configure script can change the way libccd is compiled and installed, most +significant option is --enable-double-precision which enables double +precision (single is default in this case). + + +Usage +------ +See ccd.h for public API. +In your application include <ccd/ccd.h>, setup ccd_t structure and run some +of functions (all functions are reentrant). Then link with libccd.a. + + +Directories +------------ +src/ + - contains source files of libccd. +src/testsuites + - testsuites - libccd must be compiled before compiling this. +src/testsuites/cu + - CU unit testing framework +src/testsuites/regressions + - files ready for regression tests + +doc/ + - some documentation. diff --git a/libs/ode-0.16.1/libccd/aclocal.m4 b/libs/ode-0.16.1/libccd/aclocal.m4 new file mode 100644 index 0000000..f7ad092 --- /dev/null +++ b/libs/ode-0.16.1/libccd/aclocal.m4 @@ -0,0 +1,10200 @@ +# generated automatically by aclocal 1.15 -*- Autoconf -*- + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. + +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 2014 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool 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 2 of of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 <http://www.gnu.org/licenses/>. +]) + +# serial 58 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK +AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS=$ltmain + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_PREPARE_CC_BASENAME +# ----------------------- +m4_defun([_LT_PREPARE_CC_BASENAME], [ +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in @S|@*""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} +])# _LT_PREPARE_CC_BASENAME + + +# _LT_CC_BASENAME(CC) +# ------------------- +# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, +# but that macro is also expanded into generated libtool script, which +# arranges for $SED and $ECHO to be set by different means. +m4_defun([_LT_CC_BASENAME], +[m4_require([_LT_PREPARE_CC_BASENAME])dnl +AC_REQUIRE([_LT_DECL_SED])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl +func_cc_basename $1 +cc_basename=$func_cc_basename_result +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl + +_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl +dnl +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_WITH_SYSROOT])dnl +m4_require([_LT_CMD_TRUNCATE])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options that allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld=$lt_cv_prog_gnu_ld + +old_CC=$CC +old_CFLAGS=$CFLAGS + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. +m4_defun([_LT_PREPARE_SED_QUOTE_VARS], +[# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' +]) + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from 'configure', and 'config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# 'config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain=$ac_aux_dir/ltmain.sh +])# _LT_PROG_LTMAIN + + + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the 'libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to 'config.status' so that its +# declaration there will have the same value as in 'configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags='_LT_TAGS'dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into 'config.status', and then the shell code to quote escape them in +# for loops in 'config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$[]1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +_LT_OUTPUT_LIBTOOL_INIT +]) + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# Generate a child script FILE with all initialization necessary to +# reuse the environment learned by the parent script, and make the +# file executable. If COMMENT is supplied, it is inserted after the +# '#!' sequence but before initialization text begins. After this +# macro, additional text can be appended to FILE to form the body of +# the child script. The macro ends with non-zero status if the +# file could not be fully written (such as if the disk is full). +m4_ifdef([AS_INIT_GENERATED], +[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], +[m4_defun([_LT_GENERATED_FILE_INIT], +[m4_require([AS_PREPARE])]dnl +[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl +[lt_write_fail=0 +cat >$1 <<_ASEOF || lt_write_fail=1 +#! $SHELL +# Generated by $as_me. +$2 +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$1 <<\_ASEOF || lt_write_fail=1 +AS_SHELL_SANITIZE +_AS_PREPARE +exec AS_MESSAGE_FD>&1 +_ASEOF +test 0 = "$lt_write_fail" && chmod +x $1[]dnl +m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +'$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to <bug-libtool@gnu.org>." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2011 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test 0 != $[#] +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try '$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try '$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +lt_cl_success=: +test yes = "$silent" && + lt_config_lt_args="$lt_config_lt_args --quiet" +exec AS_MESSAGE_LOG_FD>/dev/null +$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options that allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST + fi + + cfgfile=${ofile}T + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL +# Generated automatically by $as_me ($PACKAGE) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + +_LT_COPYING +_LT_LIBTOOL_TAGS + +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +_LT_PREPARE_MUNGE_PATH_LIST +_LT_PREPARE_CC_BASENAME + +# ### END FUNCTIONS SHARED WITH CONFIGURE + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Go], [_LT_LANG(GO)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +m4_ifndef([AC_PROG_GO], [ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_GO. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +m4_defun([AC_PROG_GO], +[AC_LANG_PUSH(Go)dnl +AC_ARG_VAR([GOC], [Go compiler command])dnl +AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl +_AC_ARG_VAR_LDFLAGS()dnl +AC_CHECK_TOOL(GOC, gccgo) +if test -z "$GOC"; then + if test -n "$ac_tool_prefix"; then + AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) + fi +fi +if test -z "$GOC"; then + AC_CHECK_PROG(GOC, gccgo, gccgo, false) +fi +])#m4_defun +])#m4_ifndef + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([AC_PROG_GO], + [LT_LANG(GO)], + [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) +dnl AC_DEFUN([AC_LIBTOOL_RC], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "$LT_MULTI_MODULE"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS=$save_LDFLAGS + ]) + + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], + [lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD + echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD + $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + 10.[[012]][[,.]]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test yes = "$lt_cv_apple_cc_single_mod"; then + _lt_dar_single_mod='$single_module' + fi + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' + fi + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES([TAG]) +# --------------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + if test yes = "$lt_cv_ld_force_load"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], + [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + m4_if([$1], [CXX], +[ if test yes != "$lt_cv_apple_cc_single_mod"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) +# ---------------------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +# Store the results from the different compilers for each TAGNAME. +# Allow to override them for all tags through lt_cv_aix_libpath. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], + [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ + lt_aix_libpath_sed='[ + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }]' + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi],[]) + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib + fi + ]) + aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) +fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[m4_divert_text([M4SH-INIT], [$1 +])])# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Find how we can fake an echo command that does not interpret backslash. +# In particular, with Autoconf 2.60 or later we add some code to the start +# of the generated configure script that will find a shell with a builtin +# printf (that we can use as an echo command). +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +AC_MSG_CHECKING([how to print strings]) +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$[]1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +case $ECHO in + printf*) AC_MSG_RESULT([printf]) ;; + print*) AC_MSG_RESULT([print -r]) ;; + *) AC_MSG_RESULT([cat]) ;; +esac + +m4_ifdef([_AS_DETECT_SUGGESTED], +[_AS_DETECT_SUGGESTED([ + test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test "X`printf %s $ECHO`" = "X$ECHO" \ + || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) + +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_WITH_SYSROOT +# ---------------- +AC_DEFUN([_LT_WITH_SYSROOT], +[AC_MSG_CHECKING([for sysroot]) +AC_ARG_WITH([sysroot], +[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], + [Search for dependent libraries within DIR (or the compiler's sysroot + if not specified).])], +[], [with_sysroot=no]) + +dnl lt_sysroot will always be passed unquoted. We quote it here +dnl in case the user passed a directory name. +lt_sysroot= +case $with_sysroot in #( + yes) + if test yes = "$GCC"; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + AC_MSG_RESULT([$with_sysroot]) + AC_MSG_ERROR([The sysroot must be an absolute path.]) + ;; +esac + + AC_MSG_RESULT([${lt_sysroot:-no}]) +_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl +[dependent libraries, and where our libraries should be installed.])]) + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test no = "$enable_libtool_lock" || enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE=32 + ;; + *ELF-64*) + HPUX_IA64_MODE=64 + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test yes = "$lt_cv_prog_gnu_ld"; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test yes != "$lt_cv_cc_needs_belf"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS=$SAVE_CFLAGS + fi + ;; +*-*solaris*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*|x86_64-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD=${LD-ld}_sol2 + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks=$enable_libtool_lock +])# _LT_ENABLE_LOCK + + +# _LT_PROG_AR +# ----------- +m4_defun([_LT_PROG_AR], +[AC_CHECK_TOOLS(AR, [ar], false) +: ${AR=ar} +: ${AR_FLAGS=cru} +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], + [lt_cv_ar_at_file=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([lt_ar_try]) + if test 0 -eq "$ac_status"; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + AC_TRY_EVAL([lt_ar_try]) + if test 0 -ne "$ac_status"; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + ]) + ]) + +if test no = "$lt_cv_ar_at_file"; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi +_LT_DECL([], [archiver_list_spec], [1], + [How to feed a file listing to the archiver]) +])# _LT_PROG_AR + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[_LT_PROG_AR + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + bitrig* | openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +_LT_DECL([], [lock_old_archive_extraction], [0], + [Whether to use a lock for old archive extraction]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test yes = "[$]$2"; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS +]) + +if test yes = "[$]$2"; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring=ABCD + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test 17 != "$i" # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n "$lt_cv_sys_max_cmd_len"; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test yes = "$cross_compiling"; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test yes != "$enable_dlopen"; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen=load_add_on + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen=LoadLibrary + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ + lt_cv_dlopen=dyld + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen=shl_load], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen=dlopen], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test no = "$lt_cv_dlopen"; then + enable_dlopen=no + else + enable_dlopen=yes + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS=$LDFLAGS + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS=$LIBS + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test yes = "$lt_cv_dlopen_self"; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links=nottested +if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test no = "$hard_links"; then + AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", + [Define to the sub-directory where libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then + + # We can hardcode non-existent directories. + if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && + test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || + test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP"; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_PREPARE_MUNGE_PATH_LIST +# --------------------------- +# Make sure func_munge_path_list() is defined correctly. +m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], +[[# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x@S|@2 in + x) + ;; + *:) + eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" + ;; + x:*) + eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" + ;; + *) + eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" + ;; + esac +} +]])# _LT_PREPARE_PATH_LIST + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test yes = "$GCC"; then + case $host_os in + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary... + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo = "/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +AC_ARG_VAR([LT_SYS_LIBRARY_PATH], +[User-defined run-time library search path.]) + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[[4-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib<name>.so + # instead of lib<name>.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a[(]lib.so.V[)]' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[23]].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[[3-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], + [lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [lt_cv_shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + ]) + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [install_override_mode], [1], + [Permission mode override for installation of shared libraries]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], + [Detected run-time system search path for libraries]) +_LT_DECL([], [configure_time_lt_sys_library_path], [2], + [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program that can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$1"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac]) +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program that can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PROG_ECHO_BACKSLASH])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test no = "$withval" || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in + *GNU* | *'with BFD'*) + test no != "$with_gnu_ld" && break + ;; + *) + test yes != "$with_gnu_ld" && break + ;; + esac + fi + done + IFS=$lt_save_ifs +else + lt_cv_path_LD=$LD # Let the user override the test with a path. +fi]) +LD=$lt_cv_path_LD +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +_LT_PATH_LD_GNU +AC_SUBST([LD]) + +_LT_TAGDECL([], [LD], [1], [The linker used to build libraries]) +])# LT_PATH_LD + +# Old names: +AU_ALIAS([AM_PROG_LD], [LT_PATH_LD]) +AU_ALIAS([AC_PROG_LD], [LT_PATH_LD]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_LD], []) +dnl AC_DEFUN([AC_PROG_LD], []) + + +# _LT_PATH_LD_GNU +#- -------------- +m4_defun([_LT_PATH_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + lt_cv_prog_gnu_ld=yes + ;; +*) + lt_cv_prog_gnu_ld=no + ;; +esac]) +with_gnu_ld=$lt_cv_prog_gnu_ld +])# _LT_PATH_LD_GNU + + +# _LT_CMD_RELOAD +# -------------- +# find reload flag for linker +# -- PORTME Some linkers may need a different reload flag. +m4_defun([_LT_CMD_RELOAD], +[AC_CACHE_CHECK([for $LD option to reload object files], + lt_cv_ld_reload_flag, + [lt_cv_ld_reload_flag='-r']) +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test yes != "$GCC"; then + reload_cmds=false + fi + ;; + darwin*) + if test yes = "$GCC"; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac +_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl +_LT_TAGDECL([], [reload_cmds], [2])dnl +])# _LT_CMD_RELOAD + + +# _LT_PATH_DD +# ----------- +# find a working dd +m4_defun([_LT_PATH_DD], +[AC_CACHE_CHECK([for a working dd], [ac_cv_path_lt_DD], +[printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], +[if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi]) +rm -f conftest.i conftest2.i conftest.out]) +])# _LT_PATH_DD + + +# _LT_CMD_TRUNCATE +# ---------------- +# find command to truncate a binary pipe +m4_defun([_LT_CMD_TRUNCATE], +[m4_require([_LT_PATH_DD]) +AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], +[printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) +_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], + [Command to truncate a binary pipe]) +])# _LT_CMD_TRUNCATE + + +# _LT_CHECK_MAGIC_METHOD +# ---------------------- +# how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_MAGIC_METHOD], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +AC_CACHE_CHECK([how to recognize dependent libraries], +lt_cv_deplibs_check_method, +[lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# 'unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[[4-9]]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[[45]]*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method = "file_magic"]) +_LT_DECL([], [file_magic_glob], [1], + [How to find potential files when deplibs_check_method = "file_magic"]) +_LT_DECL([], [want_nocaseglob], [1], + [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM=$NM +else + lt_nm_to_check=${ac_tool_prefix}nm + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break 2 + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break 2 + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS=$lt_save_ifs + done + : ${lt_cv_path_NM=no} +fi]) +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols -headers" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test : != "$DUMPBIN"; then + NM=$DUMPBIN + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + +# _LT_CHECK_SHAREDLIB_FROM_LINKLIB +# -------------------------------- +# how to determine the name of the shared library +# associated with a specific link library. +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +m4_require([_LT_DECL_DLLTOOL]) +AC_CACHE_CHECK([how to associate runtime and link libraries], +lt_cv_sharedlib_from_linklib_cmd, +[lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd=$ECHO + ;; +esac +]) +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + +_LT_DECL([], [sharedlib_from_linklib_cmd], [1], + [Command to associate shared and link libraries]) +])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB + + +# _LT_PATH_MANIFEST_TOOL +# ---------------------- +# locate the manifest tool +m4_defun([_LT_PATH_MANIFEST_TOOL], +[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], + [lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&AS_MESSAGE_LOG_FD + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest*]) +if test yes != "$lt_cv_path_mainfest_tool"; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + + +# _LT_DLL_DEF_P([FILE]) +# --------------------- +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with func_dll_def_p in the libtool script +AC_DEFUN([_LT_DLL_DEF_P], +[dnl + test DEF = "`$SED -n dnl + -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace + -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments + -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl + -e q dnl Only consider the first "real" line + $1`" dnl +])# _LT_DLL_DEF_P + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM=-lm) + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test yes = "$GCC"; then + case $cc_basename in + nvcc*) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; + *) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; + esac + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test ia64 = "$host_cpu"; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS=conftstm.$ac_objext + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test yes = "$pipe_works"; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], + [Transform the output of nm into a list of symbols to manually relocate]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([nm_interface], [lt_cv_nm_interface], [1], + [The name lister interface]) +_LT_DECL([], [nm_file_list_spec], [1], + [Specify filename containing input files for $NM]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test yes = "$GXX"; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + if test ia64 != "$host_cpu"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64, which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test yes = "$GCC"; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' + if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + *Sun\ F* | *Sun*Fortran*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Intel*\ [[CF]]*Compiler*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + *Portland\ Group*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +AC_CACHE_CHECK([for $compiler option to produce PIC], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + ;; + esac + ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test yes != "$GCC"; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd* | bitrig*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test yes = "$with_gnu_ld"; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; + *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test yes = "$lt_use_gnu_ld_interface"; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='$wl' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test ia64 != "$host_cpu"; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test linux-dietlibc = "$host_os"; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test no = "$tmp_diet" + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; + xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + tcc*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' + ;; + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then + aix_use_runtimelinking=yes + break + fi + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + ;; + esac + + if test yes = "$GCC"; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + esac + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + ;; + + hpux10*) + if test yes,no = "$GCC,$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test yes,no = "$GCC,$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + m4_if($1, [], [ + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + _LT_LINKER_OPTION([if $CC understands -b], + _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + ;; + esac + fi + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], + [lt_cv_irix_exported_symbol], + [save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" + AC_LINK_IFELSE( + [AC_LANG_SOURCE( + [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], + [C++], [[int foo (void) { return 0; }]], + [Fortran 77], [[ + subroutine foo + end]], + [Fortran], [[ + subroutine foo + end]])])], + [lt_cv_irix_exported_symbol=yes], + [lt_cv_irix_exported_symbol=no]) + LDFLAGS=$save_LDFLAGS]) + if test yes = "$lt_cv_irix_exported_symbol"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' + fi + _LT_TAGVAR(link_all_deplibs, $1)=no + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(ld_shlibs, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + osf3*) + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test yes = "$GCC"; then + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. GCC discards it without '$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test yes = "$GCC"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test sequent = "$host_vendor"; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test sni = "$host_vendor"; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_CACHE_CHECK([whether -lc should be explicitly linked in], + [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), + [$RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + ]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting $shlibpath_var if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [postlink_cmds], [2], + [Commands necessary for finishing linking programs]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC=$CC +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report what library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC=$lt_save_CC +])# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +if test -n "$CXX" && ( test no != "$CXX" && + ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || + (test g++ != "$CXX"))); then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_caught_CXX_error"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test yes = "$GXX"; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test yes = "$GXX"; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test yes = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='$wl' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + ;; + esac + + if test yes = "$GXX"; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag=$shared_flag' $wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + # The "-G" linker flag allows undefined symbols. + _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared + # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require '-G' NOT '-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ + '"$_LT_TAGVAR(old_archive_cmds, $1)" + _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ + '"$_LT_TAGVAR(reload_cmds, $1)" + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no + + _LT_TAGVAR(GCC, $1)=$GXX + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test yes != "$_lt_caught_CXX_error" + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_FUNC_STRIPNAME_CNF +# ---------------------- +# func_stripname_cnf prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# +# This function is identical to the (non-XSI) version of func_stripname, +# except this one can be used by m4 code that may be executed by configure, +# rather than the libtool script. +m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl +AC_REQUIRE([_LT_DECL_SED]) +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) +func_stripname_cnf () +{ + case @S|@2 in + .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; + *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; + esac +} # func_stripname_cnf +])# _LT_FUNC_STRIPNAME_CNF + + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF +package foo +func foo() { +} +_LT_EOF +]) + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $prev$p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test x-L = "$p" || + test x-R = "$p"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test no = "$pre_test_object_deps_done"; then + case $prev in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)=$prev$p + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test no = "$pre_test_object_deps_done"; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)=$p + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)=$p + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_LANG_PUSH(Fortran 77) +if test -z "$F77" || test no = "$F77"; then + _lt_disable_F77=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_disable_F77"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${F77-"f77"} + CFLAGS=$FFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)=$G77 + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test yes != "$_lt_disable_F77" + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_LANG_PUSH(Fortran) + +if test -z "$FC" || test no = "$FC"; then + _lt_disable_FC=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_disable_FC"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${FC-"f95"} + CFLAGS=$FCFLAGS + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test yes != "$_lt_disable_FC" + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +CFLAGS=$GCJFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)=$LD +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_GO_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Go compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_GO_CONFIG], +[AC_REQUIRE([LT_PROG_GO])dnl +AC_LANG_SAVE + +# Source file extension for Go test sources. +ac_ext=go + +# Object file extension for compiled Go test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="package main; func main() { }" + +# Code to be used in simple link tests +lt_simple_link_test_code='package main; func main() { }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GOC-"gccgo"} +CFLAGS=$GOFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)=$LD +_LT_CC_BASENAME([$compiler]) + +# Go did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GO_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code=$lt_simple_compile_test_code + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +CFLAGS= +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_GO +# ---------- +AC_DEFUN([LT_PROG_GO], +[AC_CHECK_TOOL(GOC, gccgo,) +]) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + +# _LT_DECL_DLLTOOL +# ---------------- +# Ensure DLLTOOL variable is set. +m4_defun([_LT_DECL_DLLTOOL], +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) +AC_SUBST([DLLTOOL]) +]) + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f "$lt_ac_sed" && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test 10 -lt "$lt_ac_count" && break + lt_ac_count=`expr $lt_ac_count + 1` + if test "$lt_ac_count" -gt "$lt_ac_max"; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PATH_CONVERSION_FUNCTIONS +# ----------------------------- +# Determine what file name conversion functions should be used by +# func_to_host_file (and, implicitly, by func_to_host_path). These are needed +# for certain cross-compile configurations and native mingw. +m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_MSG_CHECKING([how to convert $build file names to $host format]) +AC_CACHE_VAL(lt_cv_to_host_file_cmd, +[case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac +]) +to_host_file_cmd=$lt_cv_to_host_file_cmd +AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) +_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], + [0], [convert $build file names to $host format])dnl + +AC_MSG_CHECKING([how to convert $build file names to toolchain format]) +AC_CACHE_VAL(lt_cv_to_tool_file_cmd, +[#assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac +]) +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) +_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], + [0], [convert $build files to toolchain format])dnl +])# _LT_PATH_CONVERSION_FUNCTIONS + +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software +# Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 8 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option '$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl 'shared' nor 'disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], + [_LT_WITH_AIX_SONAME([aix])]) + ]) +])# _LT_SET_OPTIONS + + + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [1], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the 'shared' and +# 'disable-shared' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the 'static' and +# 'disable-static' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the 'fast-install' +# and 'disable-fast-install' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the 'fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the 'disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_AIX_SONAME([DEFAULT]) +# ---------------------------------- +# implement the --with-aix-soname flag, and support the `aix-soname=aix' +# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT +# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. +m4_define([_LT_WITH_AIX_SONAME], +[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl +shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[[5-9]]*,yes) + AC_MSG_CHECKING([which variant of shared library versioning to provide]) + AC_ARG_WITH([aix-soname], + [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], + [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], + [case $withval in + aix|svr4|both) + ;; + *) + AC_MSG_ERROR([Unknown argument to --with-aix-soname]) + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname], + [AC_CACHE_VAL([lt_cv_with_aix_soname], + [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) + with_aix_soname=$lt_cv_with_aix_soname]) + AC_MSG_RESULT([$with_aix_soname]) + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + +_LT_DECL([], [shared_archive_member_spec], [0], + [Shared archive member basename, for filename based shared library versioning on AIX])dnl +])# _LT_WITH_AIX_SONAME + +LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) +LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) +LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the 'pic-only' and 'no-pic' +# LT_INIT options. +# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [pic_mode=m4_default([$1], [default])]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) + +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software +# Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59, which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) + +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# @configure_input@ + +# serial 4179 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.4.6]) +m4_define([LT_PACKAGE_REVISION], [2.4.6]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.4.6' +macro_revision='2.4.6' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) + +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software +# Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 5 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) +m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) +m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) +m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) +m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) +m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) +m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) + +# Copyright (C) 2002-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.15' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.15], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.15])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is '.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each '.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.65])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl +]) +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: <http://www.gnu.org/software/coreutils/>. + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi +dnl The trailing newline in this macro's definition is deliberate, for +dnl backward compatibility and to allow trailing 'dnl'-style comments +dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. +]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST([install_sh])]) + +# Copyright (C) 2003-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + AC_MSG_WARN(['missing' script is too old or missing]) +fi +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) + +# Copyright (C) 2009-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor 'install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in "make install-strip", and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +# +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' + +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar <conftest.tar]) + AM_RUN_LOG([cat conftest.dir/file]) + grep GrepMe conftest.dir/file >/dev/null 2>&1 && break + fi + done + rm -rf conftest.dir + + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + diff --git a/libs/ode-0.16.1/libccd/bootstrap b/libs/ode-0.16.1/libccd/bootstrap new file mode 100755 index 0000000..33795bf --- /dev/null +++ b/libs/ode-0.16.1/libccd/bootstrap @@ -0,0 +1,12 @@ +#!/bin/sh + +# on Mac libtoolize is called glibtoolize +LIBTOOLIZE=libtoolize +if [ `uname -s` = Darwin ]; then + LIBTOOLIZE=glibtoolize +fi +$LIBTOOLIZE -c --automake +aclocal +autoheader +autoconf +automake -a --foreign -c diff --git a/libs/ode-0.16.1/libccd/configure b/libs/ode-0.16.1/libccd/configure new file mode 100755 index 0000000..839345d --- /dev/null +++ b/libs/ode-0.16.1/libccd/configure @@ -0,0 +1,18785 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for libccd 1.0. +# +# Report bugs to <danfis@danfis.cz>. +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and danfis@danfis.cz +$0: about your system, including any error possibly output +$0: before this message. Then install a modern shell, or +$0: manually run the script under such a shell if you do +$0: have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 </dev/null +exec 6>&1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='libccd' +PACKAGE_TARNAME='libccd' +PACKAGE_VERSION='1.0' +PACKAGE_STRING='libccd 1.0' +PACKAGE_BUGREPORT='danfis@danfis.cz' +PACKAGE_URL='' + +ac_unique_file="src/ccd.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include <stdio.h> +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#ifdef STDC_HEADERS +# include <stdlib.h> +# include <stddef.h> +#else +# ifdef HAVE_STDLIB_H +# include <stdlib.h> +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include <memory.h> +# endif +# include <string.h> +#endif +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif +#ifdef HAVE_INTTYPES_H +# include <inttypes.h> +#endif +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +CCD_PRECISION +CXXCPP +CPP +LT_SYS_LIBRARY_PATH +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +RANLIB +ac_ct_AR +AR +DLLTOOL +OBJDUMP +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +EGREP +GREP +SED +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +LIBTOOL +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +ac_ct_CC +CFLAGS +CC +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CXX +CPPFLAGS +LDFLAGS +CXXFLAGS +CXX +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +runstatedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_silent_rules +enable_dependency_tracking +enable_shared +enable_static +with_pic +enable_fast_install +with_aix_soname +with_gnu_ld +with_sysroot +enable_libtool_lock +enable_double_precision +' + ac_precious_vars='build_alias +host_alias +target_alias +CXX +CXXFLAGS +LDFLAGS +LIBS +CPPFLAGS +CCC +CC +CFLAGS +LT_SYS_LIBRARY_PATH +CPP +CXXCPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir runstatedir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures libccd 1.0 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/libccd] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of libccd 1.0:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build + --enable-shared[=PKGS] build shared libraries [default=no] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + --enable-double-precision + enable double precision computations instead of + single precision + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use + both] + --with-aix-soname=aix|svr4|both + shared library versioning (aka "SONAME") variant to + provide on AIX, [default=aix]. + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-sysroot[=DIR] Search for dependent libraries within DIR (or the + compiler's sysroot if not specified). + +Some influential environment variables: + CXX C++ compiler command + CXXFLAGS C++ compiler flags + LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a + nonstandard directory <lib dir> + LIBS libraries to pass to the linker, e.g. -l<library> + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if + you have headers in a nonstandard directory <include dir> + CC C compiler command + CFLAGS C compiler flags + LT_SYS_LIBRARY_PATH + User-defined run-time library search path. + CPP C preprocessor + CXXCPP C++ preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to <danfis@danfis.cz>. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +libccd configure 1.0 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case <limits.h> declares $2. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_cxx_try_cpp LINENO +# ------------------------ +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_cpp + +# ac_fn_cxx_try_link LINENO +# ------------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_link + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## ------------------------------- ## +## Report this to danfis@danfis.cz ## +## ------------------------------- ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by libccd $as_me 1.0, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +ac_config_headers="$ac_config_headers src/config.h" + +am__api_version='1.15' + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='libccd' + VERSION='1.0' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: <http://www.gnu.org/software/coreutils/>. + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi + + +# Checks for programs. +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5 +$as_echo_n "checking whether the C++ compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C++ compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5 +$as_echo_n "checking for C++ compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C++ compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CXX_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdio.h> +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + +# Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_shared=no +fi + + + + + + + + + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4.6' +macro_revision='2.4.6' + + + + + + + + + + + + + +ltmain=$ac_aux_dir/ltmain.sh + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case $ECHO in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_FGREP" || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in + *GNU* | *'with BFD'*) + test no != "$with_gnu_ld" && break + ;; + *) + test yes != "$with_gnu_ld" && break + ;; + esac + fi + done + IFS=$lt_save_ifs +else + lt_cv_path_LD=$LD # Let the user override the test with a path. +fi +fi + +LD=$lt_cv_path_LD +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + lt_cv_prog_gnu_ld=yes + ;; +*) + lt_cv_prog_gnu_ld=no + ;; +esac +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM=$NM +else + lt_nm_to_check=${ac_tool_prefix}nm + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break 2 + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break 2 + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS=$lt_save_ifs + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols -headers" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test : != "$DUMPBIN"; then + NM=$DUMPBIN + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring=ABCD + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test 17 != "$i" # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n "$lt_cv_sys_max_cmd_len"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +$as_echo_n "checking how to convert $build file names to $host format... " >&6; } +if ${lt_cv_to_host_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +$as_echo "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } +if ${lt_cv_to_tool_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +$as_echo "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test yes != "$GCC"; then + reload_cmds=false + fi + ;; + darwin*) + if test yes = "$GCC"; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# 'unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +$as_echo_n "checking how to associate runtime and link libraries... " >&6; } +if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd=$ECHO + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cru} + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +$as_echo_n "checking for archiver @FILE support... " >&6; } +if ${lt_cv_ar_at_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -eq "$ac_status"; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -ne "$ac_status"; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +$as_echo "$lt_cv_ar_at_file" >&6; } + +if test no = "$lt_cv_ar_at_file"; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + bitrig* | openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test ia64 = "$host_cpu"; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS=conftstm.$ac_objext + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test yes = "$pipe_works"; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; +else + with_sysroot=no +fi + + +lt_sysroot= +case $with_sysroot in #( + yes) + if test yes = "$GCC"; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 +$as_echo "$with_sysroot" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +$as_echo "${lt_sysroot:-no}" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 +$as_echo_n "checking for a working dd... " >&6; } +if ${ac_cv_path_lt_DD+:} false; then : + $as_echo_n "(cached) " >&6 +else + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +if test -z "$lt_DD"; then + ac_path_lt_DD_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in dd; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_lt_DD" || continue +if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi + $ac_path_lt_DD_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_lt_DD"; then + : + fi +else + ac_cv_path_lt_DD=$lt_DD +fi + +rm -f conftest.i conftest2.i conftest.out +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 +$as_echo "$ac_cv_path_lt_DD" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 +$as_echo_n "checking how to truncate binary pipes... " >&6; } +if ${lt_cv_truncate_bin+:} false; then : + $as_echo_n "(cached) " >&6 +else + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 +$as_echo "$lt_cv_truncate_bin" >&6; } + + + + + + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test no = "$enable_libtool_lock" || enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE=32 + ;; + *ELF-64*) + HPUX_IA64_MODE=64 + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test yes = "$lt_cv_prog_gnu_ld"; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test yes != "$lt_cv_cc_needs_belf"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS=$SAVE_CFLAGS + fi + ;; +*-*solaris*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*|x86_64-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD=${LD-ld}_sol2 + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks=$enable_libtool_lock + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +$as_echo "$MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if ${lt_cv_path_mainfest_tool+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +$as_echo "$lt_cv_path_mainfest_tool" >&6; } +if test yes != "$lt_cv_path_mainfest_tool"; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "$LT_MULTI_MODULE"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&5 + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if ${lt_cv_ld_force_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&5 + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + 10.[012][,.]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test yes = "$lt_cv_apple_cc_single_mod"; then + _lt_dar_single_mod='$single_module' + fi + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' + fi + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <string.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ctype.h> +#include <stdlib.h> +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + + +func_stripname_cnf () +{ + case $2 in + .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;; + *) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;; + esac +} # func_stripname_cnf + + + + + +# Set options + + + + enable_dlopen=no + + + enable_win32_dll=no + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + pic_mode=default +fi + + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[5-9]*,yes) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 +$as_echo_n "checking which variant of shared library versioning to provide... " >&6; } + +# Check whether --with-aix-soname was given. +if test "${with_aix_soname+set}" = set; then : + withval=$with_aix_soname; case $withval in + aix|svr4|both) + ;; + *) + as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname +else + if ${lt_cv_with_aix_soname+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_with_aix_soname=aix +fi + + with_aix_soname=$lt_cv_with_aix_soname +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 +$as_echo "$with_aix_soname" >&6; } + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS=$ltmain + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld=$lt_cv_prog_gnu_ld + +old_CC=$CC +old_CFLAGS=$CFLAGS + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +func_cc_basename $compiler +cc_basename=$func_cc_basename_result + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/${ac_tool_prefix}file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC=$CC +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test yes = "$GCC"; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test yes = "$GCC"; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + lt_prog_compiler_pic='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +$as_echo "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works"; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works"; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test no = "$hard_links"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test yes != "$GCC"; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd* | bitrig*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test yes = "$with_gnu_ld"; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test yes = "$lt_use_gnu_ld_interface"; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='$wl' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + export_dynamic_flag_spec='$wl--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test ia64 != "$host_cpu"; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='$wl--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test linux-dietlibc = "$host_os"; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test no = "$tmp_diet" + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + tcc*) + export_dynamic_flag_spec='-rdynamic' + ;; + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test no = "$ld_shlibs"; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then + aix_use_runtimelinking=yes + break + fi + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + hardcode_direct=no + hardcode_direct_absolute=no + ;; + esac + + if test yes = "$GCC"; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + export_dynamic_flag_spec='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' $wl-bernotok' + allow_undefined_flag=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test yes = "$GCC"; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='$wl-E' + ;; + + hpux10*) + if test yes,no = "$GCC,$with_gnu_ld"; then + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test yes,no = "$GCC,$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if ${lt_cv_prog_compiler__b+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test yes = "$lt_cv_prog_compiler__b"; then + archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test yes = "$GCC"; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if ${lt_cv_irix_exported_symbol+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_irix_exported_symbol=yes +else + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +$as_echo "$lt_cv_irix_exported_symbol" >&6; } + if test yes = "$lt_cv_irix_exported_symbol"; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' + fi + link_all_deplibs=no + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + ld_shlibs=yes + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + else + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + osf3*) + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test yes = "$GCC"; then + wlarc='$wl' + archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='$wl' + archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. GCC discards it without '$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test yes = "$GCC"; then + whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test sequent = "$host_vendor"; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='$wl-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='$wl-z,text' + allow_undefined_flag='$wl-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test sni = "$host_vendor"; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='$wl-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test no = "$ld_shlibs" && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test yes = "$GCC"; then + case $host_os in + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary... + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo = "/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's|/\([A-Za-z]:\)|\1|g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + + + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib<name>.so + # instead of lib<name>.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a(lib.so.V)' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test yes = "$hardcode_automatic"; then + + # We can hardcode non-existent directories. + if test no != "$hardcode_direct" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && + test no != "$hardcode_minus_L"; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test relink = "$hardcode_action" || + test yes = "$inherit_rpath"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test yes != "$enable_dlopen"; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen=load_add_on + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen=LoadLibrary + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else + + lt_cv_dlopen=dyld + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + lt_cv_dlopen=shl_load +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + lt_cv_dlopen=dlopen +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test no = "$lt_cv_dlopen"; then + enable_dlopen=no + else + enable_dlopen=yes + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS=$LDFLAGS + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS=$LIBS + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test yes = "$lt_cv_dlopen_self"; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP"; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report what library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC=$lt_save_CC + + if test -n "$CXX" && ( test no != "$CXX" && + ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || + (test g++ != "$CXX"))); then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if ${ac_cv_prog_CXXCPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +else + _lt_caught_CXX_error=yes +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +compiler_needs_object_CXX=no +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_direct_absolute_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +inherit_rpath_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +reload_flag_CXX=$reload_flag +reload_cmds_CXX=$reload_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_caught_CXX_error"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + + # save warnings/boilerplate of simple test code + ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + + ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + compiler_CXX=$CC + func_cc_basename $compiler +cc_basename=$func_cc_basename_result + + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test yes = "$GXX"; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' + else + lt_prog_compiler_no_builtin_flag_CXX= + fi + + if test yes = "$GXX"; then + # Set up default GNU C++ configuration + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in + *GNU* | *'with BFD'*) + test no != "$with_gnu_ld" && break + ;; + *) + test yes != "$with_gnu_ld" && break + ;; + esac + fi + done + IFS=$lt_save_ifs +else + lt_cv_path_LD=$LD # Let the user override the test with a path. +fi +fi + +LD=$lt_cv_path_LD +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + lt_cv_prog_gnu_ld=yes + ;; +*) + lt_cv_prog_gnu_ld=no + ;; +esac +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test yes = "$with_gnu_ld"; then + archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='$wl' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + ld_shlibs_CXX=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix[4-9]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + file_list_spec_CXX='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + hardcode_direct_CXX=no + hardcode_direct_absolute_CXX=no + ;; + esac + + if test yes = "$GXX"; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag=$shared_flag' $wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + export_dynamic_flag_spec_CXX='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + always_export_symbols_CXX=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + # The "-G" linker flag allows undefined symbols. + no_undefined_flag_CXX='-bernotok' + # Determine the default libpath from the value encoded in an empty + # executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec_CXX='$wl-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' $wl-bernotok' + allow_undefined_flag_CXX=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + fi + archive_cmds_need_lc_CXX=yes + archive_expsym_cmds_CXX='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared + # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_CXX=' ' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=yes + file_list_spec_CXX='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' + enable_shared_with_static_runtimes_CXX=yes + # Don't use ranlib + old_postinstall_cmds_CXX='chmod 644 $oldlib' + postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + export_dynamic_flag_spec_CXX='$wl--export-all-symbols' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + + + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec_CXX='' + fi + link_all_deplibs_CXX=yes + allow_undefined_flag_CXX=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds_CXX="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + if test yes != "$lt_cv_apple_cc_single_mod"; then + archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" + archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" + fi + + else + ld_shlibs_CXX=no + fi + + ;; + + os2*) + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_minus_L_CXX=yes + allow_undefined_flag_CXX=unsupported + shrext_cmds=.dll + archive_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes_CXX=yes + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + ld_shlibs_CXX=no + ;; + + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + + haiku*) + archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + link_all_deplibs_CXX=yes + ;; + + hpux9*) + hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='$wl-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + export_dynamic_flag_spec_CXX='$wl-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + interix[3-9]*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + hardcode_libdir_separator_CXX=: + inherit_rpath_CXX=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [1-5].* | *pgcpp\ [1-5].*) + prelink_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + old_archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='$wl--rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + whole_archive_flag_spec_CXX='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' + hardcode_libdir_flag_spec_CXX='-R$libdir' + whole_archive_flag_spec_CXX='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object_CXX=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + ld_shlibs_CXX=yes + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + hardcode_direct_absolute_CXX=yes + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='$wl-E' + whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + ld_shlibs_CXX=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + case $host in + osf3*) + allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' + archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + ;; + *) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ + $RM $lib.exp' + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + ;; + esac + + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes,no = "$GXX,$with_gnu_ld"; then + allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' + case $host in + osf3*) + archive_cmds_CXX='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + *) + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test yes,no = "$GXX,$with_gnu_ld"; then + no_undefined_flag_CXX=' $wl-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require '-G' NOT '-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir' + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + whole_archive_flag_spec_CXX='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='$wl-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_CXX='$wl-z,text' + allow_undefined_flag_CXX='$wl-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-R,$libdir' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ + '"$old_archive_cmds_CXX" + reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ + '"$reload_cmds_CXX" + ;; + *) + archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } + test no = "$ld_shlibs_CXX" && can_build_shared=no + + GCC_CXX=$GXX + LD_CXX=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + # Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF + + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $prev$p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test x-L = "$p" || + test x-R = "$p"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test no = "$pre_test_object_deps_done"; then + case $prev in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX=$prev$p + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} $prev$p" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX=$prev$p + else + postdeps_CXX="${postdeps_CXX} $prev$p" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test no = "$pre_test_object_deps_done"; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX=$p + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX=$p + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +case $host_os in +interix[3-9]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; +esac + + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + compiler_lib_search_dirs_CXX= +if test -n "${compiler_lib_search_path_CXX}"; then + compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | $SED -e 's! -L! !g' -e 's!^ !!'` +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + + + # C++ specific cases for pic, static, wl, etc. + if test yes = "$GXX"; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + lt_prog_compiler_pic_CXX='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic_CXX='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static_CXX='$wl-static' + ;; + esac + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static_CXX= + ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix[4-9]*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='$wl-a ${wl}archive' + if test ia64 != "$host_cpu"; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='$wl-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64, which still supported -KPIC. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-qpic' + lt_prog_compiler_static_CXX='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } +lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } +if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_CXX=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works_CXX=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_CXX=yes + fi + else + lt_cv_prog_compiler_static_works_CXX=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then + : +else + lt_prog_compiler_static_CXX= +fi + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test no = "$hard_links"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + case $host_os in + aix[4-9]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX=$ltdll_cmds + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + ;; + esac + ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs_CXX=no + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } +test no = "$ld_shlibs_CXX" && can_build_shared=no + +with_gnu_ld_CXX=$with_gnu_ld + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc_CXX=no + else + lt_cv_archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } + archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + + + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib<name>.so + # instead of lib<name>.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a(lib.so.V)' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec_CXX='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || + test -n "$runpath_var_CXX" || + test yes = "$hardcode_automatic_CXX"; then + + # We can hardcode non-existent directories. + if test no != "$hardcode_direct_CXX" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" && + test no != "$hardcode_minus_L_CXX"; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 +$as_echo "$hardcode_action_CXX" >&6; } + +if test relink = "$hardcode_action_CXX" || + test yes = "$inherit_rpath_CXX"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test yes != "$_lt_caught_CXX_error" + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + + +# Checks for libraries. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lm" >&5 +$as_echo_n "checking for main in -lm... " >&6; } +if ${ac_cv_lib_m_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lm $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_m_main=yes +else + ac_cv_lib_m_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_main" >&5 +$as_echo "$ac_cv_lib_m_main" >&6; } +if test "x$ac_cv_lib_m_main" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBM 1 +_ACEOF + + LIBS="-lm $LIBS" + +fi + +# FIXME: Replace `main' with a function in `-lrt': +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lrt" >&5 +$as_echo_n "checking for main in -lrt... " >&6; } +if ${ac_cv_lib_rt_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lrt $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_rt_main=yes +else + ac_cv_lib_rt_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_main" >&5 +$as_echo "$ac_cv_lib_rt_main" >&6; } +if test "x$ac_cv_lib_rt_main" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBRT 1 +_ACEOF + + LIBS="-lrt $LIBS" + +fi + + +# Checks for header files. +for ac_header in float.h stdlib.h string.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +# Checks for typedefs, structures, and compiler characteristics. +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + + +# Checks for library functions. +ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" +if test "x$ac_cv_type_pid_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define pid_t int +_ACEOF + +fi + +for ac_header in vfork.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default" +if test "x$ac_cv_header_vfork_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_VFORK_H 1 +_ACEOF + +fi + +done + +for ac_func in fork vfork +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +if test "x$ac_cv_func_fork" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5 +$as_echo_n "checking for working fork... " >&6; } +if ${ac_cv_func_fork_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_fork_works=cross +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* By Ruediger Kuhlmann. */ + return fork () < 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_fork_works=yes +else + ac_cv_func_fork_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fork_works" >&5 +$as_echo "$ac_cv_func_fork_works" >&6; } + +else + ac_cv_func_fork_works=$ac_cv_func_fork +fi +if test "x$ac_cv_func_fork_works" = xcross; then + case $host in + *-*-amigaos* | *-*-msdosdjgpp*) + # Override, as these systems have only a dummy fork() stub + ac_cv_func_fork_works=no + ;; + *) + ac_cv_func_fork_works=yes + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5 +$as_echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;} +fi +ac_cv_func_vfork_works=$ac_cv_func_vfork +if test "x$ac_cv_func_vfork" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5 +$as_echo_n "checking for working vfork... " >&6; } +if ${ac_cv_func_vfork_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_vfork_works=cross +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Thanks to Paul Eggert for this test. */ +$ac_includes_default +#include <sys/wait.h> +#ifdef HAVE_VFORK_H +# include <vfork.h> +#endif +/* On some sparc systems, changes by the child to local and incoming + argument registers are propagated back to the parent. The compiler + is told about this with #include <vfork.h>, but some compilers + (e.g. gcc -O) don't grok <vfork.h>. Test for this by using a + static variable whose address is put into a register that is + clobbered by the vfork. */ +static void +#ifdef __cplusplus +sparc_address_test (int arg) +# else +sparc_address_test (arg) int arg; +#endif +{ + static pid_t child; + if (!child) { + child = vfork (); + if (child < 0) { + perror ("vfork"); + _exit(2); + } + if (!child) { + arg = getpid(); + write(-1, "", 0); + _exit (arg); + } + } +} + +int +main () +{ + pid_t parent = getpid (); + pid_t child; + + sparc_address_test (0); + + child = vfork (); + + if (child == 0) { + /* Here is another test for sparc vfork register problems. This + test uses lots of local variables, at least as many local + variables as main has allocated so far including compiler + temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris + 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should + reuse the register of parent for one of the local variables, + since it will think that parent can't possibly be used any more + in this routine. Assigning to the local variable will thus + munge parent in the parent process. */ + pid_t + p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(), + p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid(); + /* Convince the compiler that p..p7 are live; otherwise, it might + use the same hardware register for all 8 local variables. */ + if (p != p1 || p != p2 || p != p3 || p != p4 + || p != p5 || p != p6 || p != p7) + _exit(1); + + /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent + from child file descriptors. If the child closes a descriptor + before it execs or exits, this munges the parent's descriptor + as well. Test for this by closing stdout in the child. */ + _exit(close(fileno(stdout)) != 0); + } else { + int status; + struct stat st; + + while (wait(&status) != child) + ; + return ( + /* Was there some problem with vforking? */ + child < 0 + + /* Did the child fail? (This shouldn't happen.) */ + || status + + /* Did the vfork/compiler bug occur? */ + || parent != getpid() + + /* Did the file descriptor bug occur? */ + || fstat(fileno(stdout), &st) != 0 + ); + } +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_vfork_works=yes +else + ac_cv_func_vfork_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_vfork_works" >&5 +$as_echo "$ac_cv_func_vfork_works" >&6; } + +fi; +if test "x$ac_cv_func_fork_works" = xcross; then + ac_cv_func_vfork_works=$ac_cv_func_vfork + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5 +$as_echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;} +fi + +if test "x$ac_cv_func_vfork_works" = xyes; then + +$as_echo "#define HAVE_WORKING_VFORK 1" >>confdefs.h + +else + +$as_echo "#define vfork fork" >>confdefs.h + +fi +if test "x$ac_cv_func_fork_works" = xyes; then + +$as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h + +fi + +for ac_func in clock_gettime +do : + ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime" +if test "x$ac_cv_func_clock_gettime" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_CLOCK_GETTIME 1 +_ACEOF + +fi +done + + +use_double=no +# Check whether --enable-double-precision was given. +if test "${enable_double_precision+set}" = set; then : + enableval=$enable_double_precision; use_double=$enableval +fi + +if test x$use_double = xno +then + CCD_PRECISION=CCD_SINGLE +else + CCD_PRECISION=CCD_DOUBLE +fi + + +ac_config_files="$ac_config_files Makefile src/Makefile src/ccd/precision.h src/testsuites/Makefile src/testsuites/cu/Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by libccd $as_me 1.0, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to <danfis@danfis.cz>." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +libccd config.status 1.0 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' +configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' +predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' +postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' +predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' +postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' +LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' +reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' +reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' +GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' +inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' +link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' +always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' +exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' +predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' +postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' +predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' +postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in SHELL \ +ECHO \ +PATH_SEPARATOR \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +OBJDUMP \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +DLLTOOL \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_import \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +lt_cv_nm_interface \ +nm_file_list_spec \ +lt_cv_truncate_bin \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib \ +compiler_lib_search_dirs \ +predep_objects \ +postdep_objects \ +predeps \ +postdeps \ +compiler_lib_search_path \ +LD_CXX \ +reload_flag_CXX \ +compiler_CXX \ +lt_prog_compiler_no_builtin_flag_CXX \ +lt_prog_compiler_pic_CXX \ +lt_prog_compiler_wl_CXX \ +lt_prog_compiler_static_CXX \ +lt_cv_prog_compiler_c_o_CXX \ +export_dynamic_flag_spec_CXX \ +whole_archive_flag_spec_CXX \ +compiler_needs_object_CXX \ +with_gnu_ld_CXX \ +allow_undefined_flag_CXX \ +no_undefined_flag_CXX \ +hardcode_libdir_flag_spec_CXX \ +hardcode_libdir_separator_CXX \ +exclude_expsyms_CXX \ +include_expsyms_CXX \ +file_list_spec_CXX \ +compiler_lib_search_dirs_CXX \ +predep_objects_CXX \ +postdep_objects_CXX \ +predeps_CXX \ +postdeps_CXX \ +compiler_lib_search_path_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +configure_time_dlsearch_path \ +configure_time_lt_sys_library_path \ +reload_cmds_CXX \ +old_archive_cmds_CXX \ +old_archive_from_new_cmds_CXX \ +old_archive_from_expsyms_cmds_CXX \ +archive_cmds_CXX \ +archive_expsym_cmds_CXX \ +module_cmds_CXX \ +module_expsym_cmds_CXX \ +export_symbols_cmds_CXX \ +prelink_cmds_CXX \ +postlink_cmds_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' + +# See if we are running on zsh, and set the options that allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + RM='$RM' + ofile='$ofile' + + + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "src/config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "src/ccd/precision.h") CONFIG_FILES="$CONFIG_FILES src/ccd/precision.h" ;; + "src/testsuites/Makefile") CONFIG_FILES="$CONFIG_FILES src/testsuites/Makefile" ;; + "src/testsuites/cu/Makefile") CONFIG_FILES="$CONFIG_FILES src/testsuites/cu/Makefile" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' <conf$$subs.awk | sed ' +/^[^""]/{ + N + s/\n// +} +' >>$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' <confdefs.h | sed ' +s/'"$ac_delim"'/"\\\ +"/g' >>$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options that allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST + fi + + cfgfile=${ofile}T + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL +# Generated automatically by $as_me ($PACKAGE) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + +# Copyright (C) 2014 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool 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 2 of of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 <http://www.gnu.org/licenses/>. + + +# The names of the tagged configurations supported by this script. +available_tags='CXX ' + +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} + +# ### BEGIN LIBTOOL CONFIG + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shared archive member basename,for filename based shared library versioning on AIX. +shared_archive_member_spec=$shared_archive_member_spec + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The PATH separator for the build system. +PATH_SEPARATOR=$lt_PATH_SEPARATOR + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm into a list of symbols to manually relocate. +global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# The name lister interface. +nm_interface=$lt_lt_cv_nm_interface + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and where our libraries should be installed. +lt_sysroot=$lt_sysroot + +# Command to truncate a binary pipe. +lt_truncate_bin=$lt_lt_cv_truncate_bin + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Detected run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path + +# Explicit LT_SYS_LIBRARY_PATH set during ./configure time. +configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects +postdep_objects=$lt_postdep_objects +predeps=$lt_predeps +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + +# ### END LIBTOOL CONFIG + +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + + +# ### END FUNCTIONS SHARED WITH CONFIGURE + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain=$ac_aux_dir/ltmain.sh + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + + cat <<_LT_EOF >> "$ofile" + +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# How to create reloadable object files. +reload_flag=$lt_reload_flag_CXX +reload_cmds=$lt_reload_cmds_CXX + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds_CXX + +# A language specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU compiler? +with_gcc=$GCC_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object_CXX + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld_CXX + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute_CXX + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath_CXX + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds_CXX + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds_CXX + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec_CXX + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects_CXX +postdep_objects=$lt_postdep_objects_CXX +predeps=$lt_predeps_CXX +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_CXX + +# ### END LIBTOOL TAG CONFIG: CXX +_LT_EOF + + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/libs/ode-0.16.1/libccd/configure.ac b/libs/ode-0.16.1/libccd/configure.ac new file mode 100644 index 0000000..5a12836 --- /dev/null +++ b/libs/ode-0.16.1/libccd/configure.ac @@ -0,0 +1,50 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +#AC_PREREQ([2.65]) +AC_INIT([libccd], [1.0], [danfis@danfis.cz]) +AC_CONFIG_SRCDIR([src/ccd.c]) +AC_CONFIG_HEADERS([src/config.h]) +AM_INIT_AUTOMAKE(foreign) + +# Checks for programs. +AC_PROG_CXX +AC_PROG_CC +AC_PROG_INSTALL +AC_DISABLE_SHARED +LT_INIT + +# Checks for libraries. +AC_CHECK_LIB([m], [main]) +# FIXME: Replace `main' with a function in `-lrt': +AC_CHECK_LIB([rt], [main]) + +# Checks for header files. +AC_CHECK_HEADERS([float.h stdlib.h string.h unistd.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_TYPE_SIZE_T + +# Checks for library functions. +AC_FUNC_FORK +AC_CHECK_FUNCS([clock_gettime]) + +use_double=no +AC_ARG_ENABLE(double-precision, + AS_HELP_STRING([--enable-double-precision], + [enable double precision computations instead of single precision]), + [use_double=$enableval]) +if test x$use_double = xno +then + CCD_PRECISION=CCD_SINGLE +else + CCD_PRECISION=CCD_DOUBLE +fi +AC_SUBST(CCD_PRECISION) + +AC_CONFIG_FILES([Makefile + src/Makefile + src/ccd/precision.h + src/testsuites/Makefile + src/testsuites/cu/Makefile]) +AC_OUTPUT diff --git a/libs/ode-0.16.1/libccd/src/Makefile.am b/libs/ode-0.16.1/libccd/src/Makefile.am new file mode 100644 index 0000000..e8655ba --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/Makefile.am @@ -0,0 +1,22 @@ +SUBDIRS = testsuites + +AM_CPPFLAGS = -I$(top_srcdir)/src/custom +AM_CFLAGS = -std=c99 + +noinst_LTLIBRARIES = libccd.la + +libccd_la_SOURCES = alloc.c ccd/alloc.h \ + ccd/compiler.h \ + ccd/dbg.h \ + ccd.c ccd/ccd.h \ + ccd/list.h \ + polytope.c ccd/polytope.h \ + ccd/quat.h custom/ccdcustom/quat.h \ + ccd/simplex.h \ + support.c ccd/support.h \ + vec3.c ccd/vec3.h custom/ccdcustom/vec3.h \ + mpr.c + +nodist_libccd_la_SOURCES = ccd/precision.h + +EXTRA_DIST = ccd/precision.h.in diff --git a/libs/ode-0.16.1/libccd/src/Makefile.in b/libs/ode-0.16.1/libccd/src/Makefile.in new file mode 100644 index 0000000..bab323f --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/Makefile.in @@ -0,0 +1,744 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libccd_la_LIBADD = +am_libccd_la_OBJECTS = alloc.lo ccd.lo polytope.lo support.lo vec3.lo \ + mpr.lo +nodist_libccd_la_OBJECTS = +libccd_la_OBJECTS = $(am_libccd_la_OBJECTS) \ + $(nodist_libccd_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/../depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libccd_la_SOURCES) $(nodist_libccd_la_SOURCES) +DIST_SOURCES = $(libccd_la_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ + $(LISP)config.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(top_srcdir)/../depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_PRECISION = @CCD_PRECISION@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = testsuites +AM_CPPFLAGS = -I$(top_srcdir)/src/custom +AM_CFLAGS = -std=c99 +noinst_LTLIBRARIES = libccd.la +libccd_la_SOURCES = alloc.c ccd/alloc.h \ + ccd/compiler.h \ + ccd/dbg.h \ + ccd.c ccd/ccd.h \ + ccd/list.h \ + polytope.c ccd/polytope.h \ + ccd/quat.h custom/ccdcustom/quat.h \ + ccd/simplex.h \ + support.c ccd/support.h \ + vec3.c ccd/vec3.h custom/ccdcustom/vec3.h \ + mpr.c + +nodist_libccd_la_SOURCES = ccd/precision.h +EXTRA_DIST = ccd/precision.h.in +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status src/config.h +$(srcdir)/config.h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libccd.la: $(libccd_la_OBJECTS) $(libccd_la_DEPENDENCIES) $(EXTRA_libccd_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libccd_la_OBJECTS) $(libccd_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alloc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ccd.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polytope.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/support.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vec3.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(LTLIBRARIES) config.h +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) all install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libtool \ + clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am distclean \ + distclean-compile distclean-generic distclean-hdr \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/libccd/src/alloc.c b/libs/ode-0.16.1/libccd/src/alloc.c new file mode 100644 index 0000000..d3fb213 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/alloc.c @@ -0,0 +1,38 @@ +/*** + * libccd + * --------------------------------- + * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz> + * + * + * This file is part of libccd. + * + * Distributed under the OSI-approved BSD License (the "License"); + * see accompanying file BDS-LICENSE for details or see + * <http://www.opensource.org/licenses/bsd-license.php>. + * + * This software is distributed WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the License for more information. + */ + +#include <stdio.h> +#include <ccd/alloc.h> + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +void *ccdRealloc(void *ptr, size_t size) +{ + void *ret = realloc(ptr, size); + if (ret == NULL && size != 0){ + fprintf(stderr, "Fatal error: Allocation of memory failed!\n"); + fflush(stderr); + exit(-1); + } + + return ret; +} + + diff --git a/libs/ode-0.16.1/libccd/src/ccd.c b/libs/ode-0.16.1/libccd/src/ccd.c new file mode 100644 index 0000000..5221b8f --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/ccd.c @@ -0,0 +1,955 @@ +/*** + * libccd + * --------------------------------- + * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz> + * + * + * This file is part of libccd. + * + * Distributed under the OSI-approved BSD License (the "License"); + * see accompanying file BDS-LICENSE for details or see + * <http://www.opensource.org/licenses/bsd-license.php>. + * + * This software is distributed WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the License for more information. + */ + +#include <stdio.h> +#include <float.h> +#include <ccd/ccd.h> +#include <ccdcustom/vec3.h> +#include <ccd/simplex.h> +#include <ccd/polytope.h> +#include <ccd/alloc.h> +#include <ccd/dbg.h> + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +/** Performs GJK algorithm. Returns 0 if intersection was found and simplex + * is filled with resulting polytope. */ +static int __ccdGJK(const void *obj1, const void *obj2, + const ccd_t *ccd, ccd_simplex_t *simplex); + +/** Performs GJK+EPA algorithm. Returns 0 if intersection was found and + * pt is filled with resulting polytope and nearest with pointer to + * nearest element (vertex, edge, face) of polytope to origin. */ +static int __ccdGJKEPA(const void *obj1, const void *obj2, + const ccd_t *ccd, + ccd_pt_t *pt, ccd_pt_el_t **nearest); + + +/** Returns true if simplex contains origin. + * This function also alteres simplex and dir according to further + * processing of GJK algorithm. */ +static int doSimplex(ccd_simplex_t *simplex, ccd_vec3_t *dir); +static int doSimplex2(ccd_simplex_t *simplex, ccd_vec3_t *dir); +static int doSimplex3(ccd_simplex_t *simplex, ccd_vec3_t *dir); +static int doSimplex4(ccd_simplex_t *simplex, ccd_vec3_t *dir); + +/** d = a x b x c */ +_ccd_inline void tripleCross(const ccd_vec3_t *a, const ccd_vec3_t *b, + const ccd_vec3_t *c, ccd_vec3_t *d); + + +/** Transforms simplex to polytope. It is assumed that simplex has 4 + * vertices. */ +static int simplexToPolytope4(const void *obj1, const void *obj2, + const ccd_t *ccd, + ccd_simplex_t *simplex, + ccd_pt_t *pt, ccd_pt_el_t **nearest); + +/** Transforms simplex to polytope, three vertices required */ +static int simplexToPolytope3(const void *obj1, const void *obj2, + const ccd_t *ccd, + const ccd_simplex_t *simplex, + ccd_pt_t *pt, ccd_pt_el_t **nearest); + +/** Transforms simplex to polytope, two vertices required */ +static int simplexToPolytope2(const void *obj1, const void *obj2, + const ccd_t *ccd, + const ccd_simplex_t *simplex, + ccd_pt_t *pt, ccd_pt_el_t **nearest); + +/** Expands polytope using new vertex v. */ +static void expandPolytope(ccd_pt_t *pt, ccd_pt_el_t *el, + const ccd_support_t *newv); + +/** Finds next support point (at stores it in out argument). + * Returns 0 on success, -1 otherwise */ +static int nextSupport(const void *obj1, const void *obj2, const ccd_t *ccd, + const ccd_pt_el_t *el, + ccd_support_t *out); + + + +void ccdFirstDirDefault(const void *o1, const void *o2, ccd_vec3_t *dir) +{ + ccdVec3Set(dir, CCD_ONE, CCD_ZERO, CCD_ZERO); +} + +int ccdGJKIntersect(const void *obj1, const void *obj2, const ccd_t *ccd) +{ + ccd_simplex_t simplex; + return __ccdGJK(obj1, obj2, ccd, &simplex) == 0; +} + +int ccdGJKSeparate(const void *obj1, const void *obj2, const ccd_t *ccd, + ccd_vec3_t *sep) +{ + ccd_pt_t polytope; + ccd_pt_el_t *nearest; + int ret; + + ccdPtInit(&polytope); + + ret = __ccdGJKEPA(obj1, obj2, ccd, &polytope, &nearest); + + // set separation vector + if (nearest) + ccdVec3Copy(sep, &nearest->witness); + + ccdPtDestroy(&polytope); + + return ret; +} + + +static int penEPAPosCmp(const void *a, const void *b) +{ + ccd_pt_vertex_t *v1, *v2; + v1 = *(ccd_pt_vertex_t **)a; + v2 = *(ccd_pt_vertex_t **)b; + + if (ccdEq(v1->dist, v2->dist)){ + return 0; + }else if (v1->dist < v2->dist){ + return -1; + }else{ + return 1; + } +} + +static void penEPAPos(const ccd_pt_t *pt, const ccd_pt_el_t *nearest, + ccd_vec3_t *pos) +{ + ccd_pt_vertex_t *v; + ccd_pt_vertex_t **vs; + size_t i, len; + ccd_real_t scale; + + // compute median + len = 0; + ccdListForEachEntry(&pt->vertices, v, ccd_pt_vertex_t, list){ + len++; + } + + vs = CCD_ALLOC_ARR(ccd_pt_vertex_t *, len); + i = 0; + ccdListForEachEntry(&pt->vertices, v, ccd_pt_vertex_t, list){ + vs[i++] = v; + } + + qsort(vs, len, sizeof(ccd_pt_vertex_t *), penEPAPosCmp); + + ccdVec3Set(pos, CCD_ZERO, CCD_ZERO, CCD_ZERO); + scale = CCD_ZERO; + if (len % 2 == 1) + len++; + + for (i = 0; i < len / 2; i++){ + ccdVec3Add(pos, &vs[i]->v.v1); + ccdVec3Add(pos, &vs[i]->v.v2); + scale += CCD_REAL(2.); + } + ccdVec3Scale(pos, CCD_ONE / scale); + + free(vs); +} + +int ccdGJKPenetration(const void *obj1, const void *obj2, const ccd_t *ccd, + ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos) +{ + ccd_pt_t polytope; + ccd_pt_el_t *nearest; + int ret; + + ccdPtInit(&polytope); + + ret = __ccdGJKEPA(obj1, obj2, ccd, &polytope, &nearest); + + // set separation vector + if (ret == 0 && nearest){ + // store normalized direction vector + ccdVec3Copy(dir, &nearest->witness); + ret = ccdVec3SafeNormalize(dir); + + if (ret == 0) { + // compute depth of penetration + *depth = CCD_SQRT(nearest->dist); + // compute position + penEPAPos(&polytope, nearest, pos); + } + } + + ccdPtDestroy(&polytope); + + return ret; +} + + + + +static int __ccdGJK(const void *obj1, const void *obj2, + const ccd_t *ccd, ccd_simplex_t *simplex) +{ + unsigned long iterations; + ccd_vec3_t dir; // direction vector + ccd_support_t last; // last support point + int do_simplex_res; + + // initialize simplex struct + ccdSimplexInit(simplex); + + // get first direction + ccd->first_dir(obj1, obj2, &dir); + // get first support point + __ccdSupport(obj1, obj2, &dir, ccd, &last); + // and add this point to simplex as last one + ccdSimplexAdd(simplex, &last); + + // set up direction vector to as (O - last) which is exactly -last + ccdVec3Copy(&dir, &last.v); + ccdVec3Scale(&dir, -CCD_ONE); + + // start iterations + for (iterations = 0UL; iterations < ccd->max_iterations; ++iterations) { + // obtain support point + __ccdSupport(obj1, obj2, &dir, ccd, &last); + + // check if farthest point in Minkowski difference in direction dir + // isn't somewhere before origin (the test on negative dot product) + // - because if it is, objects are not intersecting at all. + if (ccdVec3Dot(&last.v, &dir) < CCD_ZERO){ + return -1; // intersection not found + } + + // add last support vector to simplex + ccdSimplexAdd(simplex, &last); + + // if doSimplex returns 1 if objects intersect, -1 if objects don't + // intersect and 0 if algorithm should continue + do_simplex_res = doSimplex(simplex, &dir); + if (do_simplex_res == 1){ + return 0; // intersection found + }else if (do_simplex_res == -1){ + return -1; // intersection not found + } + + if (ccdIsZero(ccdVec3Len2(&dir))){ + return -1; // intersection not found + } + } + + // intersection wasn't found + return -1; +} + +static int __ccdGJKEPA(const void *obj1, const void *obj2, + const ccd_t *ccd, + ccd_pt_t *polytope, ccd_pt_el_t **nearest) +{ + ccd_simplex_t simplex; + ccd_support_t supp; // support point + int ret, size; + + *nearest = NULL; + + // run GJK and obtain terminal simplex + ret = __ccdGJK(obj1, obj2, ccd, &simplex); + if (ret != 0) + return -1; + + // transform simplex to polytope - simplex won't be used anymore + size = ccdSimplexSize(&simplex); + if (size == 4){ + if (simplexToPolytope4(obj1, obj2, ccd, &simplex, polytope, nearest) != 0){ + return 0;// touch contact + } + }else if (size == 3){ + if (simplexToPolytope3(obj1, obj2, ccd, &simplex, polytope, nearest) != 0){ + return 0; // touch contact + } + }else{ // size == 2 + if (simplexToPolytope2(obj1, obj2, ccd, &simplex, polytope, nearest) != 0){ + return 0; // touch contact + } + } + + while (1){ + // get triangle nearest to origin + *nearest = ccdPtNearest(polytope); + + // get next support point + if (nextSupport(obj1, obj2, ccd, *nearest, &supp) != 0) + break; + + // expand nearest triangle using new point - supp + expandPolytope(polytope, *nearest, &supp); + } + + return 0; +} + + + +static int doSimplex2(ccd_simplex_t *simplex, ccd_vec3_t *dir) +{ + const ccd_support_t *A, *B; + ccd_vec3_t AB, AO, tmp; + ccd_real_t dot; + + // get last added as A + A = ccdSimplexLast(simplex); + // get the other point + B = ccdSimplexPoint(simplex, 0); + // compute AB oriented segment + ccdVec3Sub2(&AB, &B->v, &A->v); + // compute AO vector + ccdVec3Copy(&AO, &A->v); + ccdVec3Scale(&AO, -CCD_ONE); + + // dot product AB . AO + dot = ccdVec3Dot(&AB, &AO); + + // check if origin doesn't lie on AB segment + ccdVec3Cross(&tmp, &AB, &AO); + if (ccdIsZero(ccdVec3Len2(&tmp)) && dot > CCD_ZERO){ + return 1; + } + + // check if origin is in area where AB segment is + if (ccdIsZero(dot) || dot < CCD_ZERO){ + // origin is in outside are of A + ccdSimplexSet(simplex, 0, A); + ccdSimplexSetSize(simplex, 1); + ccdVec3Copy(dir, &AO); + }else{ + // origin is in area where AB segment is + + // keep simplex untouched and set direction to + // AB x AO x AB + tripleCross(&AB, &AO, &AB, dir); + } + + return 0; +} + +static int doSimplex3(ccd_simplex_t *simplex, ccd_vec3_t *dir) +{ + const ccd_support_t *A, *B, *C; + ccd_vec3_t AO, AB, AC, ABC, tmp; + ccd_real_t dot, dist; + + // get last added as A + A = ccdSimplexLast(simplex); + // get the other points + B = ccdSimplexPoint(simplex, 1); + C = ccdSimplexPoint(simplex, 0); + + // check touching contact + dist = ccdVec3PointTriDist2(ccd_vec3_origin, &A->v, &B->v, &C->v, NULL); + if (ccdIsZero(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 (ccdVec3Eq(&A->v, &B->v) || ccdVec3Eq(&A->v, &C->v)){ + return -1; + } + + // compute AO vector + ccdVec3Copy(&AO, &A->v); + ccdVec3Scale(&AO, -CCD_ONE); + + // compute AB and AC segments and ABC vector (perpendircular to triangle) + ccdVec3Sub2(&AB, &B->v, &A->v); + ccdVec3Sub2(&AC, &C->v, &A->v); + ccdVec3Cross(&ABC, &AB, &AC); + + ccdVec3Cross(&tmp, &ABC, &AC); + dot = ccdVec3Dot(&tmp, &AO); + if (ccdIsZero(dot) || dot > CCD_ZERO){ + dot = ccdVec3Dot(&AC, &AO); + if (ccdIsZero(dot) || dot > CCD_ZERO){ + // C is already in place + ccdSimplexSet(simplex, 1, A); + ccdSimplexSetSize(simplex, 2); + tripleCross(&AC, &AO, &AC, dir); + }else{ +ccd_do_simplex3_45: + dot = ccdVec3Dot(&AB, &AO); + if (ccdIsZero(dot) || dot > CCD_ZERO){ + ccdSimplexSet(simplex, 0, B); + ccdSimplexSet(simplex, 1, A); + ccdSimplexSetSize(simplex, 2); + tripleCross(&AB, &AO, &AB, dir); + }else{ + ccdSimplexSet(simplex, 0, A); + ccdSimplexSetSize(simplex, 1); + ccdVec3Copy(dir, &AO); + } + } + }else{ + ccdVec3Cross(&tmp, &AB, &ABC); + dot = ccdVec3Dot(&tmp, &AO); + if (ccdIsZero(dot) || dot > CCD_ZERO){ + goto ccd_do_simplex3_45; + }else{ + dot = ccdVec3Dot(&ABC, &AO); + if (ccdIsZero(dot) || dot > CCD_ZERO){ + ccdVec3Copy(dir, &ABC); + }else{ + ccd_support_t Ctmp; + ccdSupportCopy(&Ctmp, C); + ccdSimplexSet(simplex, 0, B); + ccdSimplexSet(simplex, 1, &Ctmp); + + ccdVec3Copy(dir, &ABC); + ccdVec3Scale(dir, -CCD_ONE); + } + } + } + + return 0; +} + +static int doSimplex4(ccd_simplex_t *simplex, ccd_vec3_t *dir) +{ + const ccd_support_t *A, *B, *C, *D; + ccd_vec3_t AO, AB, AC, AD, ABC, ACD, ADB; + int B_on_ACD, C_on_ADB, D_on_ABC; + int AB_O, AC_O, AD_O; + ccd_real_t dist; + + // get last added as A + A = ccdSimplexLast(simplex); + // get the other points + B = ccdSimplexPoint(simplex, 2); + C = ccdSimplexPoint(simplex, 1); + D = ccdSimplexPoint(simplex, 0); + + // check if tetrahedron is really tetrahedron (has volume > 0) + // if it is not simplex can't be expanded and thus no intersection is + // found + dist = ccdVec3PointTriDist2(&A->v, &B->v, &C->v, &D->v, NULL); + if (ccdIsZero(dist)){ + return -1; + } + + // check if origin lies on some of tetrahedron's face - if so objects + // intersect + dist = ccdVec3PointTriDist2(ccd_vec3_origin, &A->v, &B->v, &C->v, NULL); + if (ccdIsZero(dist)) + return 1; + dist = ccdVec3PointTriDist2(ccd_vec3_origin, &A->v, &C->v, &D->v, NULL); + if (ccdIsZero(dist)) + return 1; + dist = ccdVec3PointTriDist2(ccd_vec3_origin, &A->v, &B->v, &D->v, NULL); + if (ccdIsZero(dist)) + return 1; + dist = ccdVec3PointTriDist2(ccd_vec3_origin, &B->v, &C->v, &D->v, NULL); + if (ccdIsZero(dist)) + return 1; + + // compute AO, AB, AC, AD segments and ABC, ACD, ADB normal vectors + ccdVec3Copy(&AO, &A->v); + ccdVec3Scale(&AO, -CCD_ONE); + ccdVec3Sub2(&AB, &B->v, &A->v); + ccdVec3Sub2(&AC, &C->v, &A->v); + ccdVec3Sub2(&AD, &D->v, &A->v); + ccdVec3Cross(&ABC, &AB, &AC); + ccdVec3Cross(&ACD, &AC, &AD); + ccdVec3Cross(&ADB, &AD, &AB); + + // side (positive or negative) of B, C, D relative to planes ACD, ADB + // and ABC respectively + B_on_ACD = ccdSign(ccdVec3Dot(&ACD, &AB)); + C_on_ADB = ccdSign(ccdVec3Dot(&ADB, &AC)); + D_on_ABC = ccdSign(ccdVec3Dot(&ABC, &AD)); + + // whether origin is on same side of ACD, ADB, ABC as B, C, D + // respectively + AB_O = ccdSign(ccdVec3Dot(&ACD, &AO)) == B_on_ACD; + AC_O = ccdSign(ccdVec3Dot(&ADB, &AO)) == C_on_ADB; + AD_O = ccdSign(ccdVec3Dot(&ABC, &AO)) == D_on_ABC; + + if (AB_O && AC_O && AD_O){ + // origin is in tetrahedron + return 1; + + // rearrange simplex to triangle and call doSimplex3() + }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 + + // D and C are in place + ccdSimplexSet(simplex, 2, A); + ccdSimplexSetSize(simplex, 3); + }else if (!AC_O){ + // C is farthest + ccdSimplexSet(simplex, 1, D); + ccdSimplexSet(simplex, 0, B); + ccdSimplexSet(simplex, 2, A); + ccdSimplexSetSize(simplex, 3); + }else{ // (!AD_O) + ccdSimplexSet(simplex, 0, C); + ccdSimplexSet(simplex, 1, B); + ccdSimplexSet(simplex, 2, A); + ccdSimplexSetSize(simplex, 3); + } + + return doSimplex3(simplex, dir); +} + +static int doSimplex(ccd_simplex_t *simplex, ccd_vec3_t *dir) +{ + if (ccdSimplexSize(simplex) == 2){ + // simplex contains segment only one segment + return doSimplex2(simplex, dir); + }else if (ccdSimplexSize(simplex) == 3){ + // simplex contains triangle + return doSimplex3(simplex, dir); + }else{ // ccdSimplexSize(simplex) == 4 + // tetrahedron - this is the only shape which can encapsule origin + // so doSimplex4() also contains test on it + return doSimplex4(simplex, dir); + } +} + +_ccd_inline void tripleCross(const ccd_vec3_t *a, const ccd_vec3_t *b, + const ccd_vec3_t *c, ccd_vec3_t *d) +{ + ccd_vec3_t e; + ccdVec3Cross(&e, a, b); + ccdVec3Cross(d, &e, c); +} + + + +/** Transforms simplex to polytope. It is assumed that simplex has 4 + * vertices! */ +static int simplexToPolytope4(const void *obj1, const void *obj2, + const ccd_t *ccd, + ccd_simplex_t *simplex, + ccd_pt_t *pt, ccd_pt_el_t **nearest) +{ + const ccd_support_t *a, *b, *c, *d; + int use_polytope3; + ccd_real_t dist; + ccd_pt_vertex_t *v[4]; + ccd_pt_edge_t *e[6]; + size_t i; + + a = ccdSimplexPoint(simplex, 0); + b = ccdSimplexPoint(simplex, 1); + c = ccdSimplexPoint(simplex, 2); + d = ccdSimplexPoint(simplex, 3); + + // check if origin lies on some of tetrahedron's face - if so use + // simplexToPolytope3() + use_polytope3 = 0; + dist = ccdVec3PointTriDist2(ccd_vec3_origin, &a->v, &b->v, &c->v, NULL); + if (ccdIsZero(dist)){ + use_polytope3 = 1; + } + dist = ccdVec3PointTriDist2(ccd_vec3_origin, &a->v, &c->v, &d->v, NULL); + if (ccdIsZero(dist)){ + use_polytope3 = 1; + ccdSimplexSet(simplex, 1, c); + ccdSimplexSet(simplex, 2, d); + } + dist = ccdVec3PointTriDist2(ccd_vec3_origin, &a->v, &b->v, &d->v, NULL); + if (ccdIsZero(dist)){ + use_polytope3 = 1; + ccdSimplexSet(simplex, 2, d); + } + dist = ccdVec3PointTriDist2(ccd_vec3_origin, &b->v, &c->v, &d->v, NULL); + if (ccdIsZero(dist)){ + use_polytope3 = 1; + ccdSimplexSet(simplex, 0, b); + ccdSimplexSet(simplex, 1, c); + ccdSimplexSet(simplex, 2, d); + } + + if (use_polytope3){ + ccdSimplexSetSize(simplex, 3); + return simplexToPolytope3(obj1, obj2, ccd, simplex, pt, nearest); + } + + // no touching contact - simply create tetrahedron + for (i = 0; i < 4; i++){ + v[i] = ccdPtAddVertex(pt, ccdSimplexPoint(simplex, i)); + } + + e[0] = ccdPtAddEdge(pt, v[0], v[1]); + e[1] = ccdPtAddEdge(pt, v[1], v[2]); + e[2] = ccdPtAddEdge(pt, v[2], v[0]); + e[3] = ccdPtAddEdge(pt, v[3], v[0]); + e[4] = ccdPtAddEdge(pt, v[3], v[1]); + e[5] = ccdPtAddEdge(pt, v[3], v[2]); + + ccdPtAddFace(pt, e[0], e[1], e[2]); + ccdPtAddFace(pt, e[3], e[4], e[0]); + ccdPtAddFace(pt, e[4], e[5], e[1]); + ccdPtAddFace(pt, e[5], e[3], e[2]); + + return 0; +} + +/** Transforms simplex to polytope, three vertices required */ +static int simplexToPolytope3(const void *obj1, const void *obj2, + const ccd_t *ccd, + const ccd_simplex_t *simplex, + ccd_pt_t *pt, ccd_pt_el_t **nearest) +{ + const ccd_support_t *a, *b, *c; + ccd_support_t d, d2; + ccd_vec3_t ab, ac, dir; + ccd_pt_vertex_t *v[5]; + ccd_pt_edge_t *e[9]; + ccd_real_t dist, dist2; + + *nearest = NULL; + + a = ccdSimplexPoint(simplex, 0); + b = ccdSimplexPoint(simplex, 1); + c = ccdSimplexPoint(simplex, 2); + + // If only one triangle left from previous GJK run origin lies on this + // triangle. So it is necessary to expand triangle into two + // tetrahedrons connected with base (which is exactly abc triangle). + + // get next support point in direction of normal of triangle + ccdVec3Sub2(&ab, &b->v, &a->v); + ccdVec3Sub2(&ac, &c->v, &a->v); + ccdVec3Cross(&dir, &ab, &ac); + __ccdSupport(obj1, obj2, &dir, ccd, &d); + dist = ccdVec3PointTriDist2(&d.v, &a->v, &b->v, &c->v, NULL); + + // and second one take in opposite direction + ccdVec3Scale(&dir, -CCD_ONE); + __ccdSupport(obj1, obj2, &dir, ccd, &d2); + dist2 = ccdVec3PointTriDist2(&d2.v, &a->v, &b->v, &c->v, NULL); + + // check if face isn't already on edge of minkowski sum and thus we + // have touching contact + if (ccdIsZero(dist) || ccdIsZero(dist2)){ + v[0] = ccdPtAddVertex(pt, a); + v[1] = ccdPtAddVertex(pt, b); + v[2] = ccdPtAddVertex(pt, c); + e[0] = ccdPtAddEdge(pt, v[0], v[1]); + e[1] = ccdPtAddEdge(pt, v[1], v[2]); + e[2] = ccdPtAddEdge(pt, v[2], v[0]); + *nearest = (ccd_pt_el_t *)ccdPtAddFace(pt, e[0], e[1], e[2]); + + return -1; + } + + // form polyhedron + v[0] = ccdPtAddVertex(pt, a); + v[1] = ccdPtAddVertex(pt, b); + v[2] = ccdPtAddVertex(pt, c); + v[3] = ccdPtAddVertex(pt, &d); + v[4] = ccdPtAddVertex(pt, &d2); + + e[0] = ccdPtAddEdge(pt, v[0], v[1]); + e[1] = ccdPtAddEdge(pt, v[1], v[2]); + e[2] = ccdPtAddEdge(pt, v[2], v[0]); + + e[3] = ccdPtAddEdge(pt, v[3], v[0]); + e[4] = ccdPtAddEdge(pt, v[3], v[1]); + e[5] = ccdPtAddEdge(pt, v[3], v[2]); + + e[6] = ccdPtAddEdge(pt, v[4], v[0]); + e[7] = ccdPtAddEdge(pt, v[4], v[1]); + e[8] = ccdPtAddEdge(pt, v[4], v[2]); + + ccdPtAddFace(pt, e[3], e[4], e[0]); + ccdPtAddFace(pt, e[4], e[5], e[1]); + ccdPtAddFace(pt, e[5], e[3], e[2]); + + ccdPtAddFace(pt, e[6], e[7], e[0]); + ccdPtAddFace(pt, e[7], e[8], e[1]); + ccdPtAddFace(pt, e[8], e[6], e[2]); + + return 0; +} + +/** Transforms simplex to polytope, two vertices required */ +static int simplexToPolytope2(const void *obj1, const void *obj2, + const ccd_t *ccd, + const ccd_simplex_t *simplex, + ccd_pt_t *pt, ccd_pt_el_t **nearest) +{ + const ccd_support_t *a, *b; + ccd_vec3_t ab, ac, dir; + ccd_support_t supp[4]; + ccd_pt_vertex_t *v[6]; + ccd_pt_edge_t *e[12]; + size_t i; + int found; + + a = ccdSimplexPoint(simplex, 0); + b = ccdSimplexPoint(simplex, 1); + + // This situation is a bit tricky. If only one segment comes from + // previous run of GJK - it means that either this segment is on + // minkowski edge (and thus we have touch contact) or it it isn't and + // therefore segment is somewhere *inside* minkowski sum and it *must* + // be possible to fully enclose this segment with polyhedron formed by + // at least 8 triangle faces. + + // get first support point (any) + found = 0; + for (i = 0; i < ccd_points_on_sphere_len; i++){ + __ccdSupport(obj1, obj2, &ccd_points_on_sphere[i], ccd, &supp[0]); + if (!ccdVec3Eq(&a->v, &supp[0].v) && !ccdVec3Eq(&b->v, &supp[0].v)){ + found = 1; + break; + } + } + if (!found) + goto simplexToPolytope2_touching_contact; + + // get second support point in opposite direction than supp[0] + ccdVec3Copy(&dir, &supp[0].v); + ccdVec3Scale(&dir, -CCD_ONE); + __ccdSupport(obj1, obj2, &dir, ccd, &supp[1]); + if (ccdVec3Eq(&a->v, &supp[1].v) || ccdVec3Eq(&b->v, &supp[1].v)) + goto simplexToPolytope2_touching_contact; + + // next will be in direction of normal of triangle a,supp[0],supp[1] + ccdVec3Sub2(&ab, &supp[0].v, &a->v); + ccdVec3Sub2(&ac, &supp[1].v, &a->v); + ccdVec3Cross(&dir, &ab, &ac); + __ccdSupport(obj1, obj2, &dir, ccd, &supp[2]); + if (ccdVec3Eq(&a->v, &supp[2].v) || ccdVec3Eq(&b->v, &supp[2].v)) + goto simplexToPolytope2_touching_contact; + + // and last one will be in opposite direction + ccdVec3Scale(&dir, -CCD_ONE); + __ccdSupport(obj1, obj2, &dir, ccd, &supp[3]); + if (ccdVec3Eq(&a->v, &supp[3].v) || ccdVec3Eq(&b->v, &supp[3].v)) + goto simplexToPolytope2_touching_contact; + + goto simplexToPolytope2_not_touching_contact; +simplexToPolytope2_touching_contact: + v[0] = ccdPtAddVertex(pt, a); + v[1] = ccdPtAddVertex(pt, b); + *nearest = (ccd_pt_el_t *)ccdPtAddEdge(pt, v[0], v[1]); + return -1; + +simplexToPolytope2_not_touching_contact: + // form polyhedron + v[0] = ccdPtAddVertex(pt, a); + v[1] = ccdPtAddVertex(pt, &supp[0]); + v[2] = ccdPtAddVertex(pt, b); + v[3] = ccdPtAddVertex(pt, &supp[1]); + v[4] = ccdPtAddVertex(pt, &supp[2]); + v[5] = ccdPtAddVertex(pt, &supp[3]); + + e[0] = ccdPtAddEdge(pt, v[0], v[1]); + e[1] = ccdPtAddEdge(pt, v[1], v[2]); + e[2] = ccdPtAddEdge(pt, v[2], v[3]); + e[3] = ccdPtAddEdge(pt, v[3], v[0]); + + e[4] = ccdPtAddEdge(pt, v[4], v[0]); + e[5] = ccdPtAddEdge(pt, v[4], v[1]); + e[6] = ccdPtAddEdge(pt, v[4], v[2]); + e[7] = ccdPtAddEdge(pt, v[4], v[3]); + + e[8] = ccdPtAddEdge(pt, v[5], v[0]); + e[9] = ccdPtAddEdge(pt, v[5], v[1]); + e[10] = ccdPtAddEdge(pt, v[5], v[2]); + e[11] = ccdPtAddEdge(pt, v[5], v[3]); + + ccdPtAddFace(pt, e[4], e[5], e[0]); + ccdPtAddFace(pt, e[5], e[6], e[1]); + ccdPtAddFace(pt, e[6], e[7], e[2]); + ccdPtAddFace(pt, e[7], e[4], e[3]); + + ccdPtAddFace(pt, e[8], e[9], e[0]); + ccdPtAddFace(pt, e[9], e[10], e[1]); + ccdPtAddFace(pt, e[10], e[11], e[2]); + ccdPtAddFace(pt, e[11], e[8], e[3]); + + return 0; +} + +/** Expands polytope's tri by new vertex v. Triangle tri is replaced by + * three triangles each with one vertex in v. */ +static void expandPolytope(ccd_pt_t *pt, ccd_pt_el_t *el, + const ccd_support_t *newv) +{ + ccd_pt_vertex_t *v[5]; + ccd_pt_edge_t *e[8] = {0}; + ccd_pt_face_t *f[2]; + + + // element can be either segment or triangle + if (el->type == CCD_PT_EDGE){ + // In this case, segment should be replaced by new point. + // Simpliest case is when segment stands alone and in this case + // this segment is replaced by two other segments both connected to + // newv. + // Segment can be also connected to max two faces and in that case + // each face must be replaced by two other faces. To do this + // correctly it is necessary to have correctly ordered edges and + // vertices which is exactly what is done in following code. + // + + ccdPtEdgeVertices((const ccd_pt_edge_t *)el, &v[0], &v[2]); + + ccdPtEdgeFaces((ccd_pt_edge_t *)el, &f[0], &f[1]); + + if (f[0]){ + ccdPtFaceEdges(f[0], &e[0], &e[1], &e[2]); + if (e[0] == (ccd_pt_edge_t *)el){ + e[0] = e[2]; + }else if (e[1] == (ccd_pt_edge_t *)el){ + e[1] = e[2]; + } + ccdPtEdgeVertices(e[0], &v[1], &v[3]); + if (v[1] != v[0] && v[3] != v[0]){ + e[2] = e[0]; + e[0] = e[1]; + e[1] = e[2]; + if (v[1] == v[2]) + v[1] = v[3]; + }else{ + if (v[1] == v[0]) + v[1] = v[3]; + } + + if (f[1]){ + ccdPtFaceEdges(f[1], &e[2], &e[3], &e[4]); + if (e[2] == (ccd_pt_edge_t *)el){ + e[2] = e[4]; + }else if (e[3] == (ccd_pt_edge_t *)el){ + e[3] = e[4]; + } + ccdPtEdgeVertices(e[2], &v[3], &v[4]); + if (v[3] != v[2] && v[4] != v[2]){ + e[4] = e[2]; + e[2] = e[3]; + e[3] = e[4]; + if (v[3] == v[0]) + v[3] = v[4]; + }else{ + if (v[3] == v[2]) + v[3] = v[4]; + } + } + + + v[4] = ccdPtAddVertex(pt, newv); + + ccdPtDelFace(pt, f[0]); + if (f[1]){ + ccdPtDelFace(pt, f[1]); + ccdPtDelEdge(pt, (ccd_pt_edge_t *)el); + } + + e[4] = ccdPtAddEdge(pt, v[4], v[2]); + e[5] = ccdPtAddEdge(pt, v[4], v[0]); + e[6] = ccdPtAddEdge(pt, v[4], v[1]); + if (f[1]) + e[7] = ccdPtAddEdge(pt, v[4], v[3]); + + ccdPtAddFace(pt, e[1], e[4], e[6]); + ccdPtAddFace(pt, e[0], e[6], e[5]); + if (f[1]){ + ccdPtAddFace(pt, e[3], e[5], e[7]); + ccdPtAddFace(pt, e[4], e[7], e[2]); + }else{ + ccdPtAddFace(pt, e[4], e[5], (ccd_pt_edge_t *)el); + } + } + }else{ // el->type == CCD_PT_FACE + // replace triangle by tetrahedron without base (base would be the + // triangle that will be removed) + + // get triplet of surrounding edges and vertices of triangle face + ccdPtFaceEdges((const ccd_pt_face_t *)el, &e[0], &e[1], &e[2]); + ccdPtEdgeVertices(e[0], &v[0], &v[1]); + ccdPtEdgeVertices(e[1], &v[2], &v[3]); + + // following code sorts edges to have e[0] between vertices 0-1, + // e[1] between 1-2 and e[2] between 2-0 + if (v[2] != v[1] && v[3] != v[1]){ + // swap e[1] and e[2] + e[3] = e[1]; + e[1] = e[2]; + e[2] = e[3]; + } + if (v[3] != v[0] && v[3] != v[1]) + v[2] = v[3]; + + // remove triangle face + ccdPtDelFace(pt, (ccd_pt_face_t *)el); + + // expand triangle to tetrahedron + v[3] = ccdPtAddVertex(pt, newv); + e[3] = ccdPtAddEdge(pt, v[3], v[0]); + e[4] = ccdPtAddEdge(pt, v[3], v[1]); + e[5] = ccdPtAddEdge(pt, v[3], v[2]); + + ccdPtAddFace(pt, e[3], e[4], e[0]); + ccdPtAddFace(pt, e[4], e[5], e[1]); + ccdPtAddFace(pt, e[5], e[3], e[2]); + } +} + +/** Finds next support point (at stores it in out argument). + * Returns 0 on success, -1 otherwise */ +static int nextSupport(const void *obj1, const void *obj2, const ccd_t *ccd, + const ccd_pt_el_t *el, + ccd_support_t *out) +{ + ccd_vec3_t *a, *b, *c; + ccd_real_t dist; + + if (el->type == CCD_PT_VERTEX) + return -1; + + // touch contact + if (ccdIsZero(el->dist)) + return -1; + + __ccdSupport(obj1, obj2, &el->witness, ccd, out); + + if (el->type == CCD_PT_EDGE){ + // fetch end points of edge + ccdPtEdgeVec3((ccd_pt_edge_t *)el, &a, &b); + + // get distance from segment + dist = ccdVec3PointSegmentDist2(&out->v, a, b, NULL); + }else{ // el->type == CCD_PT_FACE + // fetch vertices of triangle face + ccdPtFaceVec3((ccd_pt_face_t *)el, &a, &b, &c); + + // check if new point can significantly expand polytope + dist = ccdVec3PointTriDist2(&out->v, a, b, c, NULL); + } + + if (dist < ccd->epa_tolerance) + return -1; + + return 0; +} diff --git a/libs/ode-0.16.1/libccd/src/ccd/alloc.h b/libs/ode-0.16.1/libccd/src/ccd/alloc.h new file mode 100644 index 0000000..7b92e3e --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/ccd/alloc.h @@ -0,0 +1,52 @@ +/*** + * libccd + * --------------------------------- + * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz> + * + * + * This file is part of libccd. + * + * Distributed under the OSI-approved BSD License (the "License"); + * see accompanying file BDS-LICENSE for details or see + * <http://www.opensource.org/licenses/bsd-license.php>. + * + * This software is distributed WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the License for more information. + */ + +#ifndef __CCD_ALLOC_H__ +#define __CCD_ALLOC_H__ + +#include <stdlib.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * Functions and macros required for memory allocation. + */ + +/* Memory allocation: */ +#define __CCD_ALLOC_MEMORY(type, ptr_old, size) \ + (type *)ccdRealloc((void *)ptr_old, (size)) + +/** Allocate memory for one element of type. */ +#define CCD_ALLOC(type) \ + __CCD_ALLOC_MEMORY(type, NULL, sizeof(type)) + +/** Allocate memory for array of elements of type type. */ +#define CCD_ALLOC_ARR(type, num_elements) \ + __CCD_ALLOC_MEMORY(type, NULL, sizeof(type) * (num_elements)) + +#define CCD_REALLOC_ARR(ptr, type, num_elements) \ + __CCD_ALLOC_MEMORY(type, ptr, sizeof(type) * (num_elements)) + +void *ccdRealloc(void *ptr, size_t size); + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* __CCD_ALLOC_H__ */ diff --git a/libs/ode-0.16.1/libccd/src/ccd/ccd.h b/libs/ode-0.16.1/libccd/src/ccd/ccd.h new file mode 100644 index 0000000..3aaba8a --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/ccd/ccd.h @@ -0,0 +1,148 @@ +/*** + * libccd + * --------------------------------- + * Copyright (c)2010,2011 Daniel Fiser <danfis@danfis.cz> + * + * + * This file is part of libccd. + * + * Distributed under the OSI-approved BSD License (the "License"); + * see accompanying file BDS-LICENSE for details or see + * <http://www.opensource.org/licenses/bsd-license.php>. + * + * This software is distributed WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the License for more information. + */ + +#ifndef __CCD_H__ +#define __CCD_H__ + +#include <ccd/precision.h> + +#include <ccd/vec3.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * Type of *support* function that takes pointer to 3D object and direction + * and returns (via vec argument) furthest point from object in specified + * direction. + */ +typedef void (*ccd_support_fn)(const void *obj, const ccd_vec3_t *dir, + ccd_vec3_t *vec); + +/** + * Returns (via dir argument) first direction vector that will be used in + * initialization of algorithm. + */ +typedef void (*ccd_first_dir_fn)(const void *obj1, const void *obj2, + ccd_vec3_t *dir); + + +/** + * Returns (via center argument) geometric center (some point near center) + * of given object. + */ +typedef void (*ccd_center_fn)(const void *obj1, ccd_vec3_t *center); + +/** + * Main structure of CCD algorithm. + */ +struct _ccd_t { + ccd_first_dir_fn first_dir; /*!< Returns initial direction where first + !< support point will be searched*/ + ccd_support_fn support1; /*!< Function that returns support point of + !< first object*/ + ccd_support_fn support2; /*!< Function that returns support point of + !< second object*/ + + ccd_center_fn center1; /*!< Function that returns geometric center of + !< first object*/ + ccd_center_fn center2; /*!< Function that returns geometric center of + !< second object*/ + + unsigned long max_iterations; /*!< Maximal number of iterations*/ + ccd_real_t epa_tolerance; + ccd_real_t mpr_tolerance; /*!< Boundary tolerance for MPR algorithm*/ +}; +typedef struct _ccd_t ccd_t; + +/** + * Default first direction. + */ +void ccdFirstDirDefault(const void *o1, const void *o2, ccd_vec3_t *dir); + +#define CCD_INIT(ccd) \ + do { \ + (ccd)->first_dir = ccdFirstDirDefault; \ + (ccd)->support1 = NULL; \ + (ccd)->support2 = NULL; \ + (ccd)->center1 = NULL; \ + (ccd)->center2 = NULL; \ + \ + (ccd)->max_iterations = (unsigned long)-1; \ + (ccd)->epa_tolerance = CCD_REAL(0.0001); \ + (ccd)->mpr_tolerance = CCD_REAL(0.0001); \ + } while(0) + + +/** + * Returns true if two given objects interest. + */ +int ccdGJKIntersect(const void *obj1, const void *obj2, const ccd_t *ccd); + +/** + * This function computes separation vector of two objects. Separation + * vector is minimal translation of obj2 to get obj1 and obj2 speparated + * (without intersection). + * Returns 0 if obj1 and obj2 intersect and sep is filled with translation + * vector. If obj1 and obj2 don't intersect -1 is returned. + */ +int ccdGJKSeparate(const void *obj1, const void *obj2, const ccd_t *ccd, + ccd_vec3_t *sep); + +/** + * Computes penetration of obj2 into obj1. + * Depth of penetration, direction and position is returned. It means that + * if obj2 is translated by distance depth in direction dir objects will + * have touching contact, pos should be position in global coordinates + * where force should take a place. + * + * CCD+EPA algorithm is used. + * + * Returns 0 if obj1 and obj2 intersect and depth, dir and pos are filled + * if given non-NULL pointers. + * If obj1 and obj2 don't intersect -1 is returned. + */ +int ccdGJKPenetration(const void *obj1, const void *obj2, const ccd_t *ccd, + ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos); + + +/** + * Returns true if two given objects intersect - MPR algorithm is used. + */ +int ccdMPRIntersect(const void *obj1, const void *obj2, const ccd_t *ccd); + +/** + * Computes penetration of obj2 into obj1. + * Depth of penetration, direction and position is returned, i.e. if obj2 + * is translated by computed depth in resulting direction obj1 and obj2 + * would have touching contact. Position is point in global coordinates + * where force should be take a place. + * + * Minkowski Portal Refinement algorithm is used (MPR, a.k.a. XenoCollide, + * see Game Programming Gem 7). + * + * Returns 0 if obj1 and obj2 intersect, otherwise -1 is returned. + */ +int ccdMPRPenetration(const void *obj1, const void *obj2, const ccd_t *ccd, + ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos); + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* __CCD_H__ */ diff --git a/libs/ode-0.16.1/libccd/src/ccd/compiler.h b/libs/ode-0.16.1/libccd/src/ccd/compiler.h new file mode 100644 index 0000000..380878f --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/ccd/compiler.h @@ -0,0 +1,61 @@ +/*** + * libccd + * --------------------------------- + * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz> + * + * + * This file is part of libccd. + * + * Distributed under the OSI-approved BSD License (the "License"); + * see accompanying file BDS-LICENSE for details or see + * <http://www.opensource.org/licenses/bsd-license.php>. + * + * This software is distributed WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the License for more information. + */ + +#ifndef __CCD_COMPILER_H__ +#define __CCD_COMPILER_H__ + +#include <stddef.h> + +#define ccd_offsetof(TYPE, MEMBER) offsetof(TYPE, MEMBER) + +#define ccd_container_of(ptr, type, member) \ + (type *)( (char *)ptr - ccd_offsetof(type, member)) + + +/** + * Marks inline function. + */ +#ifdef __GNUC__ +/*# define _ccd_inline static inline __attribute__((always_inline))*/ +# define _ccd_inline static inline +#else /* __GNUC__ */ +# define _ccd_inline static __inline +#endif /* __GNUC__ */ + + +/** + * __prefetch(x) - prefetches the cacheline at "x" for read + * __prefetchw(x) - prefetches the cacheline at "x" for write + */ +#ifdef __GNUC__ +# define _ccd_prefetch(x) __builtin_prefetch(x) +# define _ccd_prefetchw(x) __builtin_prefetch(x,1) +#else /* __GNUC__ */ +# define _ccd_prefetch(x) ((void)0) +# define _ccd_prefetchw(x) ((void)0) +#endif /* __GNUC__ */ + + +#ifdef __ICC +/* disable unused parameter warning */ +# pragma warning(disable:869) +/* disable annoying "operands are evaluated in unspecified order" warning */ +# pragma warning(disable:981) +#endif /* __ICC */ + +#endif /* __CCD_COMPILER_H__ */ + diff --git a/libs/ode-0.16.1/libccd/src/ccd/dbg.h b/libs/ode-0.16.1/libccd/src/ccd/dbg.h new file mode 100644 index 0000000..f4852c1 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/ccd/dbg.h @@ -0,0 +1,65 @@ +/*** + * libccd + * --------------------------------- + * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz> + * + * + * This file is part of libccd. + * + * Distributed under the OSI-approved BSD License (the "License"); + * see accompanying file BDS-LICENSE for details or see + * <http://www.opensource.org/licenses/bsd-license.php>. + * + * This software is distributed WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the License for more information. + */ + +#ifndef __CCD_DBG_H__ +#define __CCD_DBG_H__ + +/** + * Some macros which can be used for printing debug info to stderr if macro + * NDEBUG not defined. + * + * DBG_PROLOGUE can be specified as string and this string will be + * prepended to output text + */ +#ifndef NDEBUG + +#include <stdio.h> + +#ifndef DBG_PROLOGUE +# define DBG_PROLOGUE +#endif + +# define DBG(format, ...) do { \ + fprintf(stderr, DBG_PROLOGUE "%s :: " format "\n", __func__, ## __VA_ARGS__); \ + fflush(stderr); \ + } while (0) + +# define DBG2(str) do { \ + fprintf(stderr, DBG_PROLOGUE "%s :: " str "\n", __func__); \ + fflush(stderr); \ + } while (0) + +# define DBG_VEC3(vec, prefix) do {\ + fprintf(stderr, DBG_PROLOGUE "%s :: %s[%lf %lf %lf]\n", \ + __func__, prefix, ccdVec3X(vec), ccdVec3Y(vec), ccdVec3Z(vec)); \ + fflush(stderr); \ + } while (0) +/* +# define DBG_VEC3(vec, prefix) do {\ + fprintf(stderr, DBG_PROLOGUE "%s :: %s[%.20lf %.20lf %.20lf]\n", \ + __func__, prefix, ccdVec3X(vec), ccdVec3Y(vec), ccdVec3Z(vec)); \ + fflush(stderr); \ + } while (0) +*/ + +#else +# define DBG(format, ...) +# define DBG2(str) +# define DBG_VEC3(v, prefix) +#endif + +#endif /* __CCD_DBG_H__ */ diff --git a/libs/ode-0.16.1/libccd/src/ccd/list.h b/libs/ode-0.16.1/libccd/src/ccd/list.h new file mode 100644 index 0000000..54391ed --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/ccd/list.h @@ -0,0 +1,155 @@ +/*** + * libccd + * --------------------------------- + * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz> + * + * + * This file is part of libccd. + * + * Distributed under the OSI-approved BSD License (the "License"); + * see accompanying file BDS-LICENSE for details or see + * <http://www.opensource.org/licenses/bsd-license.php>. + * + * This software is distributed WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the License for more information. + */ + +#ifndef __CCD_LIST_H__ +#define __CCD_LIST_H__ + +#include <string.h> +#include <ccd/compiler.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +struct _ccd_list_t { + struct _ccd_list_t *next, *prev; +}; +typedef struct _ccd_list_t ccd_list_t; + + + +/** + * Get the struct for this entry. + * @ptr: the &ccd_list_t pointer. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + */ +#define ccdListEntry(ptr, type, member) \ + ccd_container_of(ptr, type, member) + +/** + * Iterates over list. + */ +#define ccdListForEach(list, item) \ + for (item = (list)->next; \ + _ccd_prefetch((item)->next), item != (list); \ + item = (item)->next) + +/** + * Iterates over list safe against remove of list entry + */ +#define ccdListForEachSafe(list, item, tmp) \ + for (item = (list)->next, tmp = (item)->next; \ + item != (list); \ + item = tmp, tmp = (item)->next) + +/** + * Iterates over list of given type. + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define ccdListForEachEntry(head, pos, postype, member) \ + for (pos = ccdListEntry((head)->next, postype, member); \ + _ccd_prefetch(pos->member.next), &pos->member != (head); \ + pos = ccdListEntry(pos->member.next, postype, member)) + +/** + * Iterates over list of given type safe against removal of list entry + * @pos: the type * to use as a loop cursor. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define ccdListForEachEntrySafe(head, pos, postype, n, ntype, member) \ + for (pos = ccdListEntry((head)->next, postype, member), \ + n = ccdListEntry(pos->member.next, postype, member); \ + &pos->member != (head); \ + pos = n, n = ccdListEntry(n->member.next, ntype, member)) + + +/** + * Initialize list. + */ +_ccd_inline void ccdListInit(ccd_list_t *l); + +_ccd_inline ccd_list_t *ccdListNext(ccd_list_t *l); +_ccd_inline ccd_list_t *ccdListPrev(ccd_list_t *l); + +/** + * Returns true if list is empty. + */ +_ccd_inline int ccdListEmpty(const ccd_list_t *head); + +/** + * Appends item to end of the list l. + */ +_ccd_inline void ccdListAppend(ccd_list_t *l, ccd_list_t *item); + +/** + * Removes item from list. + */ +_ccd_inline void ccdListDel(ccd_list_t *item); + + + +/// +/// INLINES: +/// + +_ccd_inline void ccdListInit(ccd_list_t *l) +{ + l->next = l; + l->prev = l; +} + +_ccd_inline ccd_list_t *ccdListNext(ccd_list_t *l) +{ + return l->next; +} + +_ccd_inline ccd_list_t *ccdListPrev(ccd_list_t *l) +{ + return l->prev; +} + +_ccd_inline int ccdListEmpty(const ccd_list_t *head) +{ + return head->next == head; +} + +_ccd_inline void ccdListAppend(ccd_list_t *l, ccd_list_t *newccd) +{ + newccd->prev = l->prev; + newccd->next = l; + l->prev->next = newccd; + l->prev = newccd; +} + +_ccd_inline void ccdListDel(ccd_list_t *item) +{ + item->next->prev = item->prev; + item->prev->next = item->next; + item->next = item; + item->prev = item; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* __CCD_LIST_H__ */ diff --git a/libs/ode-0.16.1/libccd/src/ccd/polytope.h b/libs/ode-0.16.1/libccd/src/ccd/polytope.h new file mode 100644 index 0000000..c9ee2ab --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/ccd/polytope.h @@ -0,0 +1,322 @@ +/*** + * libccd + * --------------------------------- + * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz> + * + * + * This file is part of libccd. + * + * Distributed under the OSI-approved BSD License (the "License"); + * see accompanying file BDS-LICENSE for details or see + * <http://www.opensource.org/licenses/bsd-license.php>. + * + * This software is distributed WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the License for more information. + */ + +#ifndef __CCD_POLYTOPE_H__ +#define __CCD_POLYTOPE_H__ + +#include <stdlib.h> +#include <stdio.h> +#include <ccd/support.h> +#include <ccd/list.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define CCD_PT_VERTEX 1 +#define CCD_PT_EDGE 2 +#define CCD_PT_FACE 3 + + +#define __CCD_PT_EL \ + int type; /*! type of element */ \ + ccd_real_t dist; /*! distance from origin */ \ + ccd_vec3_t witness; /*! witness point of projection of origin */ \ + ccd_list_t list; /*! list of elements of same type */ + +/** + * General polytope element. + * Could be vertex, edge or triangle. + */ +struct _ccd_pt_el_t { + __CCD_PT_EL +}; +typedef struct _ccd_pt_el_t ccd_pt_el_t; + +struct _ccd_pt_edge_t; +struct _ccd_pt_face_t; + +/** + * Polytope's vertex. + */ +struct _ccd_pt_vertex_t { + __CCD_PT_EL + + int id; + ccd_support_t v; + ccd_list_t edges; //!< List of edges +}; +typedef struct _ccd_pt_vertex_t ccd_pt_vertex_t; + +/** + * Polytope's edge. + */ +struct _ccd_pt_edge_t { + __CCD_PT_EL + + ccd_pt_vertex_t *vertex[2]; //!< Reference to vertices + struct _ccd_pt_face_t *faces[2]; //!< Reference to faces + + ccd_list_t vertex_list[2]; //!< List items in vertices' lists +}; +typedef struct _ccd_pt_edge_t ccd_pt_edge_t; + +/** + * Polytope's triangle faces. + */ +struct _ccd_pt_face_t { + __CCD_PT_EL + + ccd_pt_edge_t *edge[3]; //!< Reference to surrounding edges +}; +typedef struct _ccd_pt_face_t ccd_pt_face_t; + + +/** + * Struct containing polytope. + */ +struct _ccd_pt_t { + ccd_list_t vertices; //!< List of vertices + ccd_list_t edges; //!< List of edges + ccd_list_t faces; //!< List of faces + + ccd_pt_el_t *nearest; + ccd_real_t nearest_dist; + int nearest_type; +}; +typedef struct _ccd_pt_t ccd_pt_t; + + +void ccdPtInit(ccd_pt_t *pt); +void ccdPtDestroy(ccd_pt_t *pt); + +/** + * Returns vertices surrounding given triangle face. + */ +_ccd_inline void ccdPtFaceVec3(const ccd_pt_face_t *face, + ccd_vec3_t **a, + ccd_vec3_t **b, + ccd_vec3_t **c); +_ccd_inline void ccdPtFaceVertices(const ccd_pt_face_t *face, + ccd_pt_vertex_t **a, + ccd_pt_vertex_t **b, + ccd_pt_vertex_t **c); +_ccd_inline void ccdPtFaceEdges(const ccd_pt_face_t *f, + ccd_pt_edge_t **a, + ccd_pt_edge_t **b, + ccd_pt_edge_t **c); + +_ccd_inline void ccdPtEdgeVec3(const ccd_pt_edge_t *e, + ccd_vec3_t **a, + ccd_vec3_t **b); +_ccd_inline void ccdPtEdgeVertices(const ccd_pt_edge_t *e, + ccd_pt_vertex_t **a, + ccd_pt_vertex_t **b); +_ccd_inline void ccdPtEdgeFaces(const ccd_pt_edge_t *e, + ccd_pt_face_t **f1, + ccd_pt_face_t **f2); + + +/** + * Adds vertex to polytope and returns pointer to newly created vertex. + */ +ccd_pt_vertex_t *ccdPtAddVertex(ccd_pt_t *pt, const ccd_support_t *v); +_ccd_inline ccd_pt_vertex_t *ccdPtAddVertexCoords(ccd_pt_t *pt, + ccd_real_t x, ccd_real_t y, ccd_real_t z); + +/** + * Adds edge to polytope. + */ +ccd_pt_edge_t *ccdPtAddEdge(ccd_pt_t *pt, ccd_pt_vertex_t *v1, + ccd_pt_vertex_t *v2); + +/** + * Adds face to polytope. + */ +ccd_pt_face_t *ccdPtAddFace(ccd_pt_t *pt, ccd_pt_edge_t *e1, + ccd_pt_edge_t *e2, + ccd_pt_edge_t *e3); + +/** + * Deletes vertex from polytope. + * Returns 0 on success, -1 otherwise. + */ +_ccd_inline int ccdPtDelVertex(ccd_pt_t *pt, ccd_pt_vertex_t *); +_ccd_inline int ccdPtDelEdge(ccd_pt_t *pt, ccd_pt_edge_t *); +_ccd_inline int ccdPtDelFace(ccd_pt_t *pt, ccd_pt_face_t *); + + +/** + * Recompute distances from origin for all elements in pt. + */ +void ccdPtRecomputeDistances(ccd_pt_t *pt); + +/** + * Returns nearest element to origin. + */ +ccd_pt_el_t *ccdPtNearest(ccd_pt_t *pt); + + +void ccdPtDumpSVT(ccd_pt_t *pt, const char *fn); +void ccdPtDumpSVT2(ccd_pt_t *pt, FILE *); + + +/**** INLINES ****/ +_ccd_inline ccd_pt_vertex_t *ccdPtAddVertexCoords(ccd_pt_t *pt, + ccd_real_t x, ccd_real_t y, ccd_real_t z) +{ + ccd_support_t s; + ccdVec3Set(&s.v, x, y, z); + return ccdPtAddVertex(pt, &s); +} + +_ccd_inline int ccdPtDelVertex(ccd_pt_t *pt, ccd_pt_vertex_t *v) +{ + // test if any edge is connected to this vertex + if (!ccdListEmpty(&v->edges)) + return -1; + + // delete vertex from main list + ccdListDel(&v->list); + + if ((void *)pt->nearest == (void *)v){ + pt->nearest = NULL; + } + + free(v); + return 0; +} + +_ccd_inline int ccdPtDelEdge(ccd_pt_t *pt, ccd_pt_edge_t *e) +{ + // text if any face is connected to this edge (faces[] is always + // aligned to lower indices) + if (e->faces[0] != NULL) + return -1; + + // disconnect edge from lists of edges in vertex struct + ccdListDel(&e->vertex_list[0]); + ccdListDel(&e->vertex_list[1]); + + // disconnect edge from main list + ccdListDel(&e->list); + + if ((void *)pt->nearest == (void *)e){ + pt->nearest = NULL; + } + + free(e); + return 0; +} + +_ccd_inline int ccdPtDelFace(ccd_pt_t *pt, ccd_pt_face_t *f) +{ + ccd_pt_edge_t *e; + size_t i; + + // remove face from edges' recerence lists + for (i = 0; i < 3; i++){ + e = f->edge[i]; + if (e->faces[0] == f){ + e->faces[0] = e->faces[1]; + } + e->faces[1] = NULL; + } + + // remove face from list of all faces + ccdListDel(&f->list); + + if ((void *)pt->nearest == (void *)f){ + pt->nearest = NULL; + } + + free(f); + return 0; +} + +_ccd_inline void ccdPtFaceVec3(const ccd_pt_face_t *face, + ccd_vec3_t **a, + ccd_vec3_t **b, + ccd_vec3_t **c) +{ + *a = &face->edge[0]->vertex[0]->v.v; + *b = &face->edge[0]->vertex[1]->v.v; + + if (face->edge[1]->vertex[0] != face->edge[0]->vertex[0] + && face->edge[1]->vertex[0] != face->edge[0]->vertex[1]){ + *c = &face->edge[1]->vertex[0]->v.v; + }else{ + *c = &face->edge[1]->vertex[1]->v.v; + } +} + +_ccd_inline void ccdPtFaceVertices(const ccd_pt_face_t *face, + ccd_pt_vertex_t **a, + ccd_pt_vertex_t **b, + ccd_pt_vertex_t **c) +{ + *a = face->edge[0]->vertex[0]; + *b = face->edge[0]->vertex[1]; + + if (face->edge[1]->vertex[0] != face->edge[0]->vertex[0] + && face->edge[1]->vertex[0] != face->edge[0]->vertex[1]){ + *c = face->edge[1]->vertex[0]; + }else{ + *c = face->edge[1]->vertex[1]; + } +} + +_ccd_inline void ccdPtFaceEdges(const ccd_pt_face_t *f, + ccd_pt_edge_t **a, + ccd_pt_edge_t **b, + ccd_pt_edge_t **c) +{ + *a = f->edge[0]; + *b = f->edge[1]; + *c = f->edge[2]; +} + +_ccd_inline void ccdPtEdgeVec3(const ccd_pt_edge_t *e, + ccd_vec3_t **a, + ccd_vec3_t **b) +{ + *a = &e->vertex[0]->v.v; + *b = &e->vertex[1]->v.v; +} + +_ccd_inline void ccdPtEdgeVertices(const ccd_pt_edge_t *e, + ccd_pt_vertex_t **a, + ccd_pt_vertex_t **b) +{ + *a = e->vertex[0]; + *b = e->vertex[1]; +} + +_ccd_inline void ccdPtEdgeFaces(const ccd_pt_edge_t *e, + ccd_pt_face_t **f1, + ccd_pt_face_t **f2) +{ + *f1 = e->faces[0]; + *f2 = e->faces[1]; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* __CCD_POLYTOPE_H__ */ diff --git a/libs/ode-0.16.1/libccd/src/ccd/precision.h.in b/libs/ode-0.16.1/libccd/src/ccd/precision.h.in new file mode 100644 index 0000000..4f98509 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/ccd/precision.h.in @@ -0,0 +1,14 @@ +#ifndef __CCD_PRECISION_H__ +#define __CCD_PRECISION_H__ + +/* define either CCD_SINGLE or CCD_DOUBLE */ + +#if defined(CCD_IDESINGLE) +#define CCD_SINGLE +#elif defined(CCD_IDEDOUBLE) +#define CCD_DOUBLE +#else +#define @CCD_PRECISION@ +#endif + +#endif diff --git a/libs/ode-0.16.1/libccd/src/ccd/quat.h b/libs/ode-0.16.1/libccd/src/ccd/quat.h new file mode 100644 index 0000000..3929671 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/ccd/quat.h @@ -0,0 +1,231 @@ +/*** + * libccd + * --------------------------------- + * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz> + * + * + * This file is part of libccd. + * + * Distributed under the OSI-approved BSD License (the "License"); + * see accompanying file BDS-LICENSE for details or see + * <http://www.opensource.org/licenses/bsd-license.php>. + * + * This software is distributed WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the License for more information. + */ + +#ifndef __CCD_QUAT_H__ +#define __CCD_QUAT_H__ + +#include <ccd/compiler.h> +#include <ccd/vec3.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +struct _ccd_quat_t { + ccd_real_t q[4]; //!< x, y, z, w +}; +typedef struct _ccd_quat_t ccd_quat_t; + +#define CCD_QUAT(name, x, y, z, w) \ + ccd_quat_t name = { {x, y, z, w} } + +_ccd_inline ccd_real_t ccdQuatLen2(const ccd_quat_t *q); +_ccd_inline ccd_real_t ccdQuatLen(const ccd_quat_t *q); + +_ccd_inline void ccdQuatSet(ccd_quat_t *q, ccd_real_t x, ccd_real_t y, ccd_real_t z, ccd_real_t w); +_ccd_inline void ccdQuatCopy(ccd_quat_t *dest, const ccd_quat_t *src); + +_ccd_inline int ccdQuatNormalize(ccd_quat_t *q); + +_ccd_inline void ccdQuatSetAngleAxis(ccd_quat_t *q, + ccd_real_t angle, const ccd_vec3_t *axis); + +_ccd_inline void ccdQuatScale(ccd_quat_t *q, ccd_real_t k); + +/** + * q = q * q2 + */ +_ccd_inline void ccdQuatMul(ccd_quat_t *q, const ccd_quat_t *q2); + +/** + * q = a * b + */ +_ccd_inline void ccdQuatMul2(ccd_quat_t *q, + const ccd_quat_t *a, const ccd_quat_t *b); + +/** + * Inverts quaternion. + * Returns 0 on success. + */ +_ccd_inline int ccdQuatInvert(ccd_quat_t *q); +_ccd_inline int ccdQuatInvert2(ccd_quat_t *dest, const ccd_quat_t *src); + + +/** + * Rotate vector v by quaternion q. + */ +_ccd_inline void ccdQuatRotVec(ccd_vec3_t *v, const ccd_quat_t *q); + + +/**** INLINES ****/ +_ccd_inline ccd_real_t ccdQuatLen2(const ccd_quat_t *q) +{ + ccd_real_t len; + + len = q->q[0] * q->q[0]; + len += q->q[1] * q->q[1]; + len += q->q[2] * q->q[2]; + len += q->q[3] * q->q[3]; + + return len; +} + +_ccd_inline ccd_real_t ccdQuatLen(const ccd_quat_t *q) +{ + return CCD_SQRT(ccdQuatLen2(q)); +} + +_ccd_inline void ccdQuatSet(ccd_quat_t *q, ccd_real_t x, ccd_real_t y, ccd_real_t z, ccd_real_t w) +{ + q->q[0] = x; + q->q[1] = y; + q->q[2] = z; + q->q[3] = w; +} + +_ccd_inline void ccdQuatCopy(ccd_quat_t *dest, const ccd_quat_t *src) +{ + *dest = *src; +} + + +_ccd_inline int ccdQuatNormalize(ccd_quat_t *q) +{ + ccd_real_t len = ccdQuatLen(q); + if (len < CCD_EPS) + return 0; + + ccdQuatScale(q, CCD_ONE / len); + return 1; +} + +_ccd_inline void ccdQuatSetAngleAxis(ccd_quat_t *q, + ccd_real_t angle, const ccd_vec3_t *axis) +{ + ccd_real_t a, x, y, z, n, s; + + a = angle/2; + x = ccdVec3X(axis); + y = ccdVec3Y(axis); + z = ccdVec3Z(axis); + n = CCD_SQRT(x*x + y*y + z*z); + + // axis==0? (treat this the same as angle==0 with an arbitrary axis) + if (n < CCD_EPS){ + q->q[0] = q->q[1] = q->q[2] = CCD_ZERO; + q->q[3] = CCD_ONE; + }else{ + s = sin(a)/n; + + q->q[3] = cos(a); + q->q[0] = x*s; + q->q[1] = y*s; + q->q[2] = z*s; + + ccdQuatNormalize(q); + } +} + + +_ccd_inline void ccdQuatScale(ccd_quat_t *q, ccd_real_t k) +{ + size_t i; + for (i = 0; i < 4; i++) + q->q[i] *= k; +} + +_ccd_inline void ccdQuatMul(ccd_quat_t *q, const ccd_quat_t *q2) +{ + ccd_quat_t a; + ccdQuatCopy(&a, q); + ccdQuatMul2(q, &a, q2); +} + +_ccd_inline void ccdQuatMul2(ccd_quat_t *q, + const ccd_quat_t *a, const ccd_quat_t *b) +{ + q->q[0] = a->q[3] * b->q[0] + + a->q[0] * b->q[3] + + a->q[1] * b->q[2] + - a->q[2] * b->q[1]; + q->q[1] = a->q[3] * b->q[1] + + a->q[1] * b->q[3] + - a->q[0] * b->q[2] + + a->q[2] * b->q[0]; + q->q[2] = a->q[3] * b->q[2] + + a->q[2] * b->q[3] + + a->q[0] * b->q[1] + - a->q[1] * b->q[0]; + q->q[3] = a->q[3] * b->q[3] + - a->q[0] * b->q[0] + - a->q[1] * b->q[1] + - a->q[2] * b->q[2]; +} + +_ccd_inline int ccdQuatInvert(ccd_quat_t *q) +{ + ccd_real_t len2 = ccdQuatLen2(q); + if (len2 < CCD_EPS) + return -1; + + len2 = CCD_ONE / len2; + + q->q[0] = -q->q[0] * len2; + q->q[1] = -q->q[1] * len2; + q->q[2] = -q->q[2] * len2; + q->q[3] = q->q[3] * len2; + + return 0; +} +_ccd_inline int ccdQuatInvert2(ccd_quat_t *dest, const ccd_quat_t *src) +{ + ccdQuatCopy(dest, src); + return ccdQuatInvert(dest); +} + +_ccd_inline void ccdQuatRotVec(ccd_vec3_t *v, const ccd_quat_t *q)
+{
+ // original version: 31 mul + 21 add
+ // optimized version: 18 mul + 12 add
+ // formula: v = v + 2 * cross(q.xyz, cross(q.xyz, v) + q.w * v)
+ ccd_real_t cross1_x, cross1_y, cross1_z, cross2_x, cross2_y, cross2_z;
+ ccd_real_t x, y, z, w;
+ ccd_real_t vx, vy, vz;
+
+ vx = ccdVec3X(v);
+ vy = ccdVec3Y(v);
+ vz = ccdVec3Z(v);
+
+ w = q->q[3];
+ x = q->q[0];
+ y = q->q[1];
+ z = q->q[2];
+
+ cross1_x = y * vz - z * vy + w * vx;
+ cross1_y = z * vx - x * vz + w * vy;
+ cross1_z = x * vy - y * vx + w * vz;
+ cross2_x = y * cross1_z - z * cross1_y;
+ cross2_y = z * cross1_x - x * cross1_z;
+ cross2_z = x * cross1_y - y * cross1_x;
+ ccdVec3Set(v, vx + 2 * cross2_x, vy + 2 * cross2_y, vz + 2 * cross2_z);
+}
+ +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* __CCD_QUAT_H__ */ diff --git a/libs/ode-0.16.1/libccd/src/ccd/simplex.h b/libs/ode-0.16.1/libccd/src/ccd/simplex.h new file mode 100644 index 0000000..1d07e39 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/ccd/simplex.h @@ -0,0 +1,104 @@ +/*** + * libccd + * --------------------------------- + * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz> + * + * + * This file is part of libccd. + * + * Distributed under the OSI-approved BSD License (the "License"); + * see accompanying file BDS-LICENSE for details or see + * <http://www.opensource.org/licenses/bsd-license.php>. + * + * This software is distributed WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the License for more information. + */ + +#ifndef __CCD_SIMPLEX_H__ +#define __CCD_SIMPLEX_H__ + +#include <ccd/support.h> +#include <ccd/compiler.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +struct _ccd_simplex_t { + ccd_support_t ps[4]; + int last; /*!< index of last added point*/ +}; +typedef struct _ccd_simplex_t ccd_simplex_t; + + +_ccd_inline void ccdSimplexInit(ccd_simplex_t *s); +_ccd_inline int ccdSimplexSize(const ccd_simplex_t *s); +_ccd_inline const ccd_support_t *ccdSimplexLast(const ccd_simplex_t *s); +_ccd_inline const ccd_support_t *ccdSimplexPoint(const ccd_simplex_t *s, int idx); +_ccd_inline ccd_support_t *ccdSimplexPointW(ccd_simplex_t *s, int idx); + +_ccd_inline void ccdSimplexAdd(ccd_simplex_t *s, const ccd_support_t *v); +_ccd_inline void ccdSimplexSet(ccd_simplex_t *s, size_t pos, const ccd_support_t *a); +_ccd_inline void ccdSimplexSetSize(ccd_simplex_t *s, int size); +_ccd_inline void ccdSimplexSwap(ccd_simplex_t *s, size_t pos1, size_t pos2); + + +/**** INLINES ****/ + +_ccd_inline void ccdSimplexInit(ccd_simplex_t *s) +{ + s->last = -1; +} + +_ccd_inline int ccdSimplexSize(const ccd_simplex_t *s) +{ + return s->last + 1; +} + +_ccd_inline const ccd_support_t *ccdSimplexLast(const ccd_simplex_t *s) +{ + return ccdSimplexPoint(s, s->last); +} + +_ccd_inline const ccd_support_t *ccdSimplexPoint(const ccd_simplex_t *s, int idx) +{ + /* here is no check on boundaries */ + return &s->ps[idx]; +} +_ccd_inline ccd_support_t *ccdSimplexPointW(ccd_simplex_t *s, int idx) +{ + return &s->ps[idx]; +} + +_ccd_inline void ccdSimplexAdd(ccd_simplex_t *s, const ccd_support_t *v) +{ + /* here is no check on boundaries in sake of speed */ + ++s->last; + ccdSupportCopy(s->ps + s->last, v); +} + +_ccd_inline void ccdSimplexSet(ccd_simplex_t *s, size_t pos, const ccd_support_t *a) +{ + ccdSupportCopy(s->ps + pos, a); +} + +_ccd_inline void ccdSimplexSetSize(ccd_simplex_t *s, int size) +{ + s->last = size - 1; +} + +_ccd_inline void ccdSimplexSwap(ccd_simplex_t *s, size_t pos1, size_t pos2) +{ + ccd_support_t supp; + + ccdSupportCopy(&supp, &s->ps[pos1]); + ccdSupportCopy(&s->ps[pos1], &s->ps[pos2]); + ccdSupportCopy(&s->ps[pos2], &supp); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* __CCD_SIMPLEX_H__ */ diff --git a/libs/ode-0.16.1/libccd/src/ccd/support.h b/libs/ode-0.16.1/libccd/src/ccd/support.h new file mode 100644 index 0000000..0a21b3e --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/ccd/support.h @@ -0,0 +1,57 @@ +/*** + * libccd + * --------------------------------- + * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz> + * + * + * This file is part of libccd. + * + * Distributed under the OSI-approved BSD License (the "License"); + * see accompanying file BDS-LICENSE for details or see + * <http://www.opensource.org/licenses/bsd-license.php>. + * + * This software is distributed WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the License for more information. + */ + +#ifndef __CCD_SUPPORT_H__ +#define __CCD_SUPPORT_H__ + +#include <ccd/compiler.h> +#include <ccd/vec3.h> +#include <ccd/ccd.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +struct _ccd_support_t { + ccd_vec3_t v; /*!< Support point in minkowski sum*/ + ccd_vec3_t v1; /*!< Support point in obj1*/ + ccd_vec3_t v2; /*!< Support point in obj2*/ +}; +typedef struct _ccd_support_t ccd_support_t; + +_ccd_inline void ccdSupportCopy(ccd_support_t *, const ccd_support_t *s); + +/** + * Computes support point of obj1 and obj2 in direction dir. + * Support point is returned via supp. + */ +void __ccdSupport(const void *obj1, const void *obj2, + const ccd_vec3_t *dir, const ccd_t *ccd, + ccd_support_t *supp); + + +/**** INLINES ****/ +_ccd_inline void ccdSupportCopy(ccd_support_t *d, const ccd_support_t *s) +{ + *d = *s; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* __CCD_SUPPORT_H__ */ diff --git a/libs/ode-0.16.1/libccd/src/ccd/vec3.h b/libs/ode-0.16.1/libccd/src/ccd/vec3.h new file mode 100644 index 0000000..d9175ed --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/ccd/vec3.h @@ -0,0 +1,340 @@ +/*** + * libccd + * --------------------------------- + * Copyright (c)2010,2011 Daniel Fiser <danfis@danfis.cz> + * + * + * This file is part of libccd. + * + * Distributed under the OSI-approved BSD License (the "License"); + * see accompanying file BDS-LICENSE for details or see + * <http://www.opensource.org/licenses/bsd-license.php>. + * + * This software is distributed WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the License for more information. + */ + +#ifndef __CCD_VEC3_H__ +#define __CCD_VEC3_H__ + +#include <math.h> +#include <float.h> +#include <stdlib.h> + +#include <ccd/precision.h> +#include <ccd/compiler.h> + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#ifndef CCD_SINGLE +# ifndef CCD_DOUBLE +# error You must define CCD_SINGLE or CCD_DOUBLE +# endif /* CCD_DOUBLE */ +#endif /* CCD_SINGLE */ + + +#if defined(_MSC_VER) && _MSC_VER < 1700 +/* Define fmin, fmax, fminf, fmaxf which are missing from MSVC (up to VS2005 at least) */ +static __inline double fmin(double x, double y) { return __min(x, y); } +static __inline double fmax(double x, double y) { return __max(x, y); } +static __inline float fminf(float x, float y) { return __min(x, y); } +static __inline float fmaxf(float x, float y) { return __max(x, y); } + +#endif /* #if defined(_MSC_VER) */ + + +#ifdef CCD_SINGLE +# ifdef CCD_DOUBLE +# error You can define either CCD_SINGLE or CCD_DOUBLE, not both! +# endif /* CCD_DOUBLE */ + +typedef float ccd_real_t; + +/*# define CCD_EPS 1E-6*/ +# define CCD_EPS FLT_EPSILON + +# define CCD_REAL_MAX FLT_MAX + +# define CCD_REAL(x) (x ## f) /*!< form a constant */ +# define CCD_SQRT(x) (sqrtf(x)) /*!< square root */ +# define CCD_FABS(x) (fabsf(x)) /*!< absolute value */ +# define CCD_FMAX(x, y) (fmaxf((x), (y))) /*!< maximum of two floats */ +# define CCD_FMIN(x, y) (fminf((x), (y))) /*!< minimum of two floats */ +#endif /* CCD_SINGLE */ + +#ifdef CCD_DOUBLE +typedef double ccd_real_t; + +/*# define CCD_EPS 1E-10*/ +# define CCD_EPS DBL_EPSILON + +# define CCD_REAL_MAX DBL_MAX + +# define CCD_REAL(x) (x) /*!< form a constant */ +# define CCD_SQRT(x) (sqrt(x)) /*!< square root */ +# define CCD_FABS(x) (fabs(x)) /*!< absolute value */ +# define CCD_FMAX(x, y) (fmax((x), (y))) /*!< maximum of two floats */ +# define CCD_FMIN(x, y) (fmin((x), (y))) /*!< minimum of two floats */ +#endif /* CCD_DOUBLE */ + +#define CCD_ONE CCD_REAL(1.) +#define CCD_ZERO CCD_REAL(0.) + +struct _ccd_vec3_t { + ccd_real_t v[3]; +}; +typedef struct _ccd_vec3_t ccd_vec3_t; + + +/** + * Holds origin (0,0,0) - this variable is meant to be read-only! + */ +extern ccd_vec3_t *ccd_vec3_origin; + +/** + * Array of points uniformly distributed on unit sphere. + */ +extern ccd_vec3_t *ccd_points_on_sphere; +extern size_t ccd_points_on_sphere_len; + +/** Returns sign of value. */ +_ccd_inline int ccdSign(ccd_real_t val); +/** Returns true if val is zero. **/ +_ccd_inline int ccdIsZero(ccd_real_t val); +/** Returns true if a and b equal. **/ +_ccd_inline int ccdEq(ccd_real_t a, ccd_real_t b); + + +#define CCD_VEC3_STATIC(x, y, z) \ + { { (x), (y), (z) } } + +#define CCD_VEC3(name, x, y, z) \ + ccd_vec3_t name = CCD_VEC3_STATIC((x), (y), (z)) + +_ccd_inline ccd_real_t ccdVec3X(const ccd_vec3_t *v); +_ccd_inline ccd_real_t ccdVec3Y(const ccd_vec3_t *v); +_ccd_inline ccd_real_t ccdVec3Z(const ccd_vec3_t *v); + +/** + * Returns true if a and b equal. + */ +_ccd_inline int ccdVec3Eq(const ccd_vec3_t *a, const ccd_vec3_t *b); + +/** + * Returns squared length of vector. + */ +_ccd_inline ccd_real_t ccdVec3Len2(const ccd_vec3_t *v); + +/** + * Returns distance between a and b. + */ +_ccd_inline ccd_real_t ccdVec3Dist2(const ccd_vec3_t *a, const ccd_vec3_t *b); + + +_ccd_inline void ccdVec3Set(ccd_vec3_t *v, ccd_real_t x, ccd_real_t y, ccd_real_t z); + +/** + * v = w + */ +_ccd_inline void ccdVec3Copy(ccd_vec3_t *v, const ccd_vec3_t *w); + +/** + * Subtracts coordinates of vector w from vector v. v = v - w + */ +_ccd_inline void ccdVec3Sub(ccd_vec3_t *v, const ccd_vec3_t *w); + +/** + * Adds coordinates of vector w to vector v. v = v + w + */ +_ccd_inline void ccdVec3Add(ccd_vec3_t *v, const ccd_vec3_t *w); + +/** + * d = v - w + */ +_ccd_inline void ccdVec3Sub2(ccd_vec3_t *d, const ccd_vec3_t *v, const ccd_vec3_t *w); + +/** + * d = d * k; + */ +_ccd_inline void ccdVec3Scale(ccd_vec3_t *d, ccd_real_t k); + + +/** + * Normalizes given vector to unit length. + */ +_ccd_inline void ccdVec3Normalize(ccd_vec3_t *d); + + +/** + * Dot product of two vectors. + */ +_ccd_inline ccd_real_t ccdVec3Dot(const ccd_vec3_t *a, const ccd_vec3_t *b); + +/** + * Cross product: d = a x b. + */ +_ccd_inline void ccdVec3Cross(ccd_vec3_t *d, const ccd_vec3_t *a, const ccd_vec3_t *b); + + +/** + * Returns distance2 of point P to segment ab. + * If witness is non-NULL it is filled with coordinates of point from which + * was computed distance to point P. + */ +ccd_real_t ccdVec3PointSegmentDist2(const ccd_vec3_t *P, + const ccd_vec3_t *a, const ccd_vec3_t *b, + ccd_vec3_t *witness); + +/** + * Returns distance2 of point P from triangle formed by triplet a, b, c. + * If witness vector is provided it is filled with coordinates of point + * from which was computed distance to point P. + */ +ccd_real_t ccdVec3PointTriDist2(const ccd_vec3_t *P, + const ccd_vec3_t *a, const ccd_vec3_t *b, + const ccd_vec3_t *c, + ccd_vec3_t *witness); + + +/**** INLINES ****/ +_ccd_inline int ccdSign(ccd_real_t val) +{ + if (ccdIsZero(val)){ + return 0; + }else if (val < CCD_ZERO){ + return -1; + } + return 1; +} + +_ccd_inline int ccdIsZero(ccd_real_t val) +{ + return CCD_FABS(val) < CCD_EPS; +} + +_ccd_inline int ccdEq(ccd_real_t _a, ccd_real_t _b) +{ + ccd_real_t ab; + ccd_real_t a, b; + + ab = CCD_FABS(_a - _b); + if (CCD_FABS(ab) < CCD_EPS) + return 1; + + a = CCD_FABS(_a); + b = CCD_FABS(_b); + if (b > a){ + return ab < CCD_EPS * b; + }else{ + return ab < CCD_EPS * a; + } +} + + +_ccd_inline ccd_real_t ccdVec3X(const ccd_vec3_t *v) +{ + return v->v[0]; +} + +_ccd_inline ccd_real_t ccdVec3Y(const ccd_vec3_t *v) +{ + return v->v[1]; +} + +_ccd_inline ccd_real_t ccdVec3Z(const ccd_vec3_t *v) +{ + return v->v[2]; +} + +_ccd_inline int ccdVec3Eq(const ccd_vec3_t *a, const ccd_vec3_t *b) +{ + return ccdEq(ccdVec3X(a), ccdVec3X(b)) + && ccdEq(ccdVec3Y(a), ccdVec3Y(b)) + && ccdEq(ccdVec3Z(a), ccdVec3Z(b)); +} + +_ccd_inline ccd_real_t ccdVec3Len2(const ccd_vec3_t *v) +{ + return ccdVec3Dot(v, v); +} + +_ccd_inline ccd_real_t ccdVec3Dist2(const ccd_vec3_t *a, const ccd_vec3_t *b) +{ + ccd_vec3_t ab; + ccdVec3Sub2(&ab, a, b); + return ccdVec3Len2(&ab); +} + +_ccd_inline void ccdVec3Set(ccd_vec3_t *v, ccd_real_t x, ccd_real_t y, ccd_real_t z) +{ + v->v[0] = x; + v->v[1] = y; + v->v[2] = z; +} + +_ccd_inline void ccdVec3Copy(ccd_vec3_t *v, const ccd_vec3_t *w) +{ + *v = *w; +} + +_ccd_inline void ccdVec3Sub(ccd_vec3_t *v, const ccd_vec3_t *w) +{ + v->v[0] -= w->v[0]; + v->v[1] -= w->v[1]; + v->v[2] -= w->v[2]; +} + +_ccd_inline void ccdVec3Sub2(ccd_vec3_t *d, const ccd_vec3_t *v, const ccd_vec3_t *w) +{ + d->v[0] = v->v[0] - w->v[0]; + d->v[1] = v->v[1] - w->v[1]; + d->v[2] = v->v[2] - w->v[2]; +} + +_ccd_inline void ccdVec3Add(ccd_vec3_t *v, const ccd_vec3_t *w) +{ + v->v[0] += w->v[0]; + v->v[1] += w->v[1]; + v->v[2] += w->v[2]; +} + +_ccd_inline void ccdVec3Scale(ccd_vec3_t *d, ccd_real_t k) +{ + d->v[0] *= k; + d->v[1] *= k; + d->v[2] *= k; +} + +_ccd_inline void ccdVec3Normalize(ccd_vec3_t *d) +{ + ccd_real_t k = CCD_ONE / CCD_SQRT(ccdVec3Len2(d)); + ccdVec3Scale(d, k); +} + +_ccd_inline ccd_real_t ccdVec3Dot(const ccd_vec3_t *a, const ccd_vec3_t *b) +{ + ccd_real_t dot; + + dot = a->v[0] * b->v[0]; + dot += a->v[1] * b->v[1]; + dot += a->v[2] * b->v[2]; + return dot; +} + +_ccd_inline void ccdVec3Cross(ccd_vec3_t *d, const ccd_vec3_t *a, const ccd_vec3_t *b) +{ + d->v[0] = (a->v[1] * b->v[2]) - (a->v[2] * b->v[1]); + d->v[1] = (a->v[2] * b->v[0]) - (a->v[0] * b->v[2]); + d->v[2] = (a->v[0] * b->v[1]) - (a->v[1] * b->v[0]); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* __CCD_VEC3_H__ */ diff --git a/libs/ode-0.16.1/libccd/src/config.h.in b/libs/ode-0.16.1/libccd/src/config.h.in new file mode 100644 index 0000000..f928422 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/config.h.in @@ -0,0 +1,97 @@ +/* src/config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the `clock_gettime' function. */ +#undef HAVE_CLOCK_GETTIME + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the <float.h> header file. */ +#undef HAVE_FLOAT_H + +/* Define to 1 if you have the `fork' function. */ +#undef HAVE_FORK + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `m' library (-lm). */ +#undef HAVE_LIBM + +/* Define to 1 if you have the `rt' library (-lrt). */ +#undef HAVE_LIBRT + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `vfork' function. */ +#undef HAVE_VFORK + +/* Define to 1 if you have the <vfork.h> header file. */ +#undef HAVE_VFORK_H + +/* Define to 1 if `fork' works. */ +#undef HAVE_WORKING_FORK + +/* Define to 1 if `vfork' works. */ +#undef HAVE_WORKING_VFORK + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#undef LT_OBJDIR + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* Define to `int' if <sys/types.h> does not define. */ +#undef pid_t + +/* Define to `unsigned int' if <sys/types.h> does not define. */ +#undef size_t + +/* Define as `fork' if `vfork' does not work. */ +#undef vfork diff --git a/libs/ode-0.16.1/libccd/src/custom/ccdcustom/quat.h b/libs/ode-0.16.1/libccd/src/custom/ccdcustom/quat.h new file mode 100644 index 0000000..157dd85 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/custom/ccdcustom/quat.h @@ -0,0 +1,69 @@ +/*** + * libccd + * --------------------------------- + * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz> + * + * + * This file is part of libccd. + * + * Distributed under the OSI-approved BSD License (the "License"); + * see accompanying file BDS-LICENSE for details or see + * <http://www.opensource.org/licenses/bsd-license.php>. + * + * This software is distributed WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the License for more information. + */ + +#ifndef __CCD_CUSTOM_QUAT_H__ +#define __CCD_CUSTOM_QUAT_H__ + +#include <ccd/quat.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * Rotate vector s by quaternion q and put result into d. + */ +_ccd_inline void ccdQuatRotVec2(ccd_vec3_t *d, const ccd_vec3_t *s, const ccd_quat_t *q); + + +_ccd_inline void ccdQuatRotVec2(ccd_vec3_t *d, const ccd_vec3_t *s, const ccd_quat_t *q) +{ +#ifndef dLIBCCD_USE_SYSTEM + // original version: 31 mul + 21 add + // optimized version: 18 mul + 12 add + // formula: d = s + 2 * cross(q.xyz, cross(q.xyz, v) + q.w * s) + ccd_real_t cross1_x, cross1_y, cross1_z, cross2_x, cross2_y, cross2_z; + ccd_real_t x, y, z, w; + ccd_real_t vx, vy, vz; + + vx = ccdVec3X(s); + vy = ccdVec3Y(s); + vz = ccdVec3Z(s); + + w = q->q[3]; + x = q->q[0]; + y = q->q[1]; + z = q->q[2]; + + cross1_x = y * vz - z * vy + w * vx; + cross1_y = z * vx - x * vz + w * vy; + cross1_z = x * vy - y * vx + w * vz; + cross2_x = y * cross1_z - z * cross1_y; + cross2_y = z * cross1_x - x * cross1_z; + cross2_z = x * cross1_y - y * cross1_x; + ccdVec3Set(d, vx + 2 * cross2_x, vy + 2 * cross2_y, vz + 2 * cross2_z); +#else + ccdVec3Copy(d, s); + ccdQuatRotVec(d, q); +#endif +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* __CCD_QUAT_H__ */ diff --git a/libs/ode-0.16.1/libccd/src/custom/ccdcustom/vec3.h b/libs/ode-0.16.1/libccd/src/custom/ccdcustom/vec3.h new file mode 100644 index 0000000..2ac2f22 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/custom/ccdcustom/vec3.h @@ -0,0 +1,114 @@ +/*** + * libccd + * --------------------------------- + * Copyright (c)2010,2011 Daniel Fiser <danfis@danfis.cz> + * + * + * This file is part of libccd. + * + * Distributed under the OSI-approved BSD License (the "License"); + * see accompanying file BDS-LICENSE for details or see + * <http://www.opensource.org/licenses/bsd-license.php>. + * + * This software is distributed WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the License for more information. + */ + +#ifndef __CCD_CUSTOM_VEC3_H__ +#define __CCD_CUSTOM_VEC3_H__ + +#include <ccd/vec3.h> + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#ifdef CCD_SINGLE +# define CCD_ATAN2(x, y) (atan2f((x), (y))) /*!< atan2 of two floats */ +#endif /* CCD_SINGLE */ + +#ifdef CCD_DOUBLE +# define CCD_ATAN2(x, y) (atan2((x), (y))) /*!< atan2 of two floats */ +#endif /* CCD_DOUBLE */ + +/** + * d = v + w + */ +_ccd_inline void ccdVec3Add2(ccd_vec3_t *d, const ccd_vec3_t *v, const ccd_vec3_t *w); + +/** + * d = s * k; + */ +_ccd_inline void ccdVec3CopyScaled(ccd_vec3_t *d, const ccd_vec3_t *s, ccd_real_t k); + +/** + * d = v + s * k; + */ +_ccd_inline void ccdVec3AddScaled(ccd_vec3_t *d, const ccd_vec3_t *v, const ccd_vec3_t *s, ccd_real_t k); + + +/** + * Normalizes given vector to unit length. + */ +_ccd_inline int ccdVec3SafeNormalize(ccd_vec3_t *d); + + +_ccd_inline void ccdVec3Add2(ccd_vec3_t *d, const ccd_vec3_t *v, const ccd_vec3_t *w) +{ +#ifndef dLIBCCD_USE_SYSTEM + d->v[0] = v->v[0] + w->v[0]; + d->v[1] = v->v[1] + w->v[1]; + d->v[2] = v->v[2] + w->v[2]; +#else + ccdVec3Copy(d, v); + ccdVec3Add(d, w); +#endif +} + +_ccd_inline void ccdVec3CopyScaled(ccd_vec3_t *d, const ccd_vec3_t *s, ccd_real_t k) +{ +#ifndef dLIBCCD_USE_SYSTEM + d->v[0] = s->v[0] * k; + d->v[1] = s->v[1] * k; + d->v[2] = s->v[2] * k; +#else + ccdVec3Copy(d, s); + ccdVec3Scale(d, k); +#endif +} + +_ccd_inline void ccdVec3AddScaled(ccd_vec3_t *d, const ccd_vec3_t *v, const ccd_vec3_t *s, ccd_real_t k) +{ +#ifndef dLIBCCD_USE_SYSTEM + d->v[0] = v->v[0] + s->v[0] * k; + d->v[1] = v->v[1] + s->v[1] * k; + d->v[2] = v->v[2] + s->v[2] * k; +#else + ccdVec3Copy(d, s); + ccdVec3Scale(d, k); + ccdVec3Add(d, v); +#endif +} + +_ccd_inline int ccdVec3SafeNormalize(ccd_vec3_t *d) +{ + int result = -1; + + ccd_real_t len = CCD_SQRT(ccdVec3Len2(d)); + if (len >= CCD_EPS) { + ccdVec3Scale(d, CCD_ONE / len); + result = 0; + } + + return result; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* __CCD_CUSTOM_VEC3_H__ */ diff --git a/libs/ode-0.16.1/libccd/src/mpr.c b/libs/ode-0.16.1/libccd/src/mpr.c new file mode 100644 index 0000000..072a99b --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/mpr.c @@ -0,0 +1,572 @@ +/*** + * libccd + * --------------------------------- + * Copyright (c)2010,2011 Daniel Fiser <danfis@danfis.cz> + * + * + * This file is part of libccd. + * + * Distributed under the OSI-approved BSD License (the "License"); + * see accompanying file BDS-LICENSE for details or see + * <http://www.opensource.org/licenses/bsd-license.php>. + * + * This software is distributed WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the License for more information. + */ + +#include <stdlib.h> +#include <ccd/ccd.h> +#include <ccdcustom/vec3.h> +#include <ccd/simplex.h> +#include <ccd/dbg.h> + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/** Finds origin (center) of Minkowski difference (actually it can be any + * interior point of Minkowski difference. */ +_ccd_inline void findOrigin(const void *obj1, const void *obj2, const ccd_t *ccd, + ccd_support_t *center); + +/** Discovers initial portal - that is tetrahedron that intersects with + * origin ray (ray from center of Minkowski diff to (0,0,0). + * + * Returns -1 if already recognized that origin is outside Minkowski + * portal. + * Returns 1 if origin lies on v1 of simplex (only v0 and v1 are present + * in simplex). + * Returns 2 if origin lies on v0-v1 segment. + * Returns 0 if portal was built. + */ +static int discoverPortal(const void *obj1, const void *obj2, + const ccd_t *ccd, ccd_simplex_t *portal); + + +/** Expands portal towards origin and determine if objects intersect. + * Already established portal must be given as argument. + * If intersection is found 0 is returned, -1 otherwise */ +static int refinePortal(const void *obj1, const void *obj2, + const ccd_t *ccd, ccd_simplex_t *portal); + +/** Finds penetration info by expanding provided portal. */ +static int findPenetr(const void *obj1, const void *obj2, const ccd_t *ccd, + ccd_simplex_t *portal, + ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos); + +/** Finds penetration info if origin lies on portal's v1 */ +static void findPenetrTouch(const void *obj1, const void *obj2, const ccd_t *ccd, + ccd_simplex_t *portal, + ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos); + +/** Find penetration info if origin lies on portal's segment v0-v1 */ +static int findPenetrSegment(const void *obj1, const void *obj2, const ccd_t *ccd, + ccd_simplex_t *portal, + ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos); + +/** Finds position vector from fully established portal */ +static int findPos(const void *obj1, const void *obj2, const ccd_t *ccd, + const ccd_simplex_t *portal, ccd_vec3_t *pos); + +/** Extends portal with new support point. + * Portal must have face v1-v2-v3 arranged to face outside portal. */ +_ccd_inline void expandPortal(ccd_simplex_t *portal, + const ccd_support_t *v4); + +/** Fill dir with direction outside portal. Portal's v1-v2-v3 face must be + * arranged in correct order! */ +_ccd_inline int portalDir(const ccd_simplex_t *portal, ccd_vec3_t *dir); + +/** Returns true if portal encapsules origin (0,0,0), dir is direction of + * v1-v2-v3 face. */ +_ccd_inline int portalEncapsulesOrigin(const ccd_simplex_t *portal, + const ccd_vec3_t *dir); + +/** Returns true if portal with new point v4 would reach specified + * tolerance (i.e. returns true if portal can _not_ significantly expand + * within Minkowski difference). + * + * v4 is candidate for new point in portal, dir is direction in which v4 + * was obtained. */ +_ccd_inline int portalReachTolerance(const ccd_simplex_t *portal, + const ccd_support_t *v4, + const ccd_vec3_t *dir, + const ccd_t *ccd); + +/** Returns true if portal expanded by new point v4 could possibly contain + * origin, dir is direction in which v4 was obtained. */ +_ccd_inline int portalCanEncapsuleOrigin(const ccd_simplex_t *portal, + const ccd_support_t *v4, + const ccd_vec3_t *dir); + + +int ccdMPRIntersect(const void *obj1, const void *obj2, const ccd_t *ccd) +{ + ccd_simplex_t portal; + int res; + + // Phase 1: Portal discovery - find portal that intersects with origin + // ray (ray from center of Minkowski diff to origin of coordinates) + res = discoverPortal(obj1, obj2, ccd, &portal); + if (res < 0) + return 0; + if (res > 0) + return 1; + + // Phase 2: Portal refinement + res = refinePortal(obj1, obj2, ccd, &portal); + return (res == 0 ? 1 : 0); +} + +int ccdMPRPenetration(const void *obj1, const void *obj2, const ccd_t *ccd, + ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos) +{ + ccd_simplex_t portal; + int res; + + // Phase 1: Portal discovery + res = discoverPortal(obj1, obj2, ccd, &portal); + if (res < 0){ + // Origin isn't inside portal - no collision. + return -1; + + }else if (res == 1){ + // Touching contact on portal's v1. + findPenetrTouch(obj1, obj2, ccd, &portal, depth, dir, pos); + + }else if (res == 2){ + // Origin lies on v0-v1 segment. + if (findPenetrSegment(obj1, obj2, ccd, &portal, depth, dir, pos) != 0) { + return -1; + } + + }else if (res == 0){ + // Phase 2: Portal refinement + res = refinePortal(obj1, obj2, ccd, &portal); + if (res < 0) { + return -1; + } + + // Phase 3. Penetration info + if (findPenetr(obj1, obj2, ccd, &portal, depth, dir, pos) != 0) { + return -1; + } + } + + return 0; +} + + + +_ccd_inline void findOrigin(const void *obj1, const void *obj2, const ccd_t *ccd, + ccd_support_t *center) +{ + ccd->center1(obj1, ¢er->v1); + ccd->center2(obj2, ¢er->v2); + ccdVec3Sub2(¢er->v, ¢er->v1, ¢er->v2); +} + +static int discoverPortal(const void *obj1, const void *obj2, + const ccd_t *ccd, ccd_simplex_t *portal) +{ + ccd_vec3_t dir, va, vb; + ccd_real_t dot; + int cont; + + // vertex 0 is center of portal + findOrigin(obj1, obj2, ccd, ccdSimplexPointW(portal, 0)); + ccdSimplexSetSize(portal, 1); + + if (ccdVec3Eq(&ccdSimplexPoint(portal, 0)->v, ccd_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... + ccdVec3Set(&va, CCD_EPS * CCD_REAL(10.), CCD_ZERO, CCD_ZERO); + ccdVec3Add(&ccdSimplexPointW(portal, 0)->v, &va); + } + + + // vertex 1 = support in direction of origin + ccdVec3Copy(&dir, &ccdSimplexPoint(portal, 0)->v); + ccdVec3Scale(&dir, CCD_REAL(-1.)); + if (ccdVec3SafeNormalize(&dir) != 0) { + return -1; + } + __ccdSupport(obj1, obj2, &dir, ccd, ccdSimplexPointW(portal, 1)); + ccdSimplexSetSize(portal, 2); + + // test if origin isn't outside of v1 + dot = ccdVec3Dot(&ccdSimplexPoint(portal, 1)->v, &dir); + if (ccdIsZero(dot) || dot < CCD_ZERO) + return -1; + + + // vertex 2 + ccdVec3Cross(&dir, &ccdSimplexPoint(portal, 0)->v, + &ccdSimplexPoint(portal, 1)->v); + if (ccdIsZero(ccdVec3Len2(&dir))){ + if (ccdVec3Eq(&ccdSimplexPoint(portal, 1)->v, ccd_vec3_origin)){ + // origin lies on v1 + return 1; + }else{ + // origin lies on v0-v1 segment + return 2; + } + } + + if (ccdVec3SafeNormalize(&dir) != 0) { + return -1; + } + __ccdSupport(obj1, obj2, &dir, ccd, ccdSimplexPointW(portal, 2)); + dot = ccdVec3Dot(&ccdSimplexPoint(portal, 2)->v, &dir); + if (ccdIsZero(dot) || dot < CCD_ZERO) { + return -1; + } + + ccdSimplexSetSize(portal, 3); + + // vertex 3 direction + ccdVec3Sub2(&va, &ccdSimplexPoint(portal, 1)->v, + &ccdSimplexPoint(portal, 0)->v); + ccdVec3Sub2(&vb, &ccdSimplexPoint(portal, 2)->v, + &ccdSimplexPoint(portal, 0)->v); + ccdVec3Cross(&dir, &va, &vb); + if (ccdVec3SafeNormalize(&dir) != 0) { + return -1; + } + + // it is better to form portal faces to be oriented "outside" origin + dot = ccdVec3Dot(&dir, &ccdSimplexPoint(portal, 0)->v); + if (dot > CCD_ZERO){ + ccdSimplexSwap(portal, 1, 2); + ccdVec3Scale(&dir, CCD_REAL(-1.)); + } + + while (ccdSimplexSize(portal) < 4){ + __ccdSupport(obj1, obj2, &dir, ccd, ccdSimplexPointW(portal, 3)); + dot = ccdVec3Dot(&ccdSimplexPoint(portal, 3)->v, &dir); + if (ccdIsZero(dot) || dot < CCD_ZERO) { + return -1; + } + + cont = 0; + + // test if origin is outside (v1, v0, v3) - set v2 as v3 and + // continue + ccdVec3Cross(&va, &ccdSimplexPoint(portal, 1)->v, + &ccdSimplexPoint(portal, 3)->v); + dot = ccdVec3Dot(&va, &ccdSimplexPoint(portal, 0)->v); + if (dot < CCD_ZERO && !ccdIsZero(dot)){ + ccdSimplexSet(portal, 2, ccdSimplexPoint(portal, 3)); + cont = 1; + } + + if (!cont){ + // test if origin is outside (v3, v0, v2) - set v1 as v3 and + // continue + ccdVec3Cross(&va, &ccdSimplexPoint(portal, 3)->v, + &ccdSimplexPoint(portal, 2)->v); + dot = ccdVec3Dot(&va, &ccdSimplexPoint(portal, 0)->v); + if (dot < CCD_ZERO && !ccdIsZero(dot)){ + ccdSimplexSet(portal, 1, ccdSimplexPoint(portal, 3)); + cont = 1; + } + } + + if (cont){ + ccdVec3Sub2(&va, &ccdSimplexPoint(portal, 1)->v, + &ccdSimplexPoint(portal, 0)->v); + ccdVec3Sub2(&vb, &ccdSimplexPoint(portal, 2)->v, + &ccdSimplexPoint(portal, 0)->v); + ccdVec3Cross(&dir, &va, &vb); + if (ccdVec3SafeNormalize(&dir) != 0) { + return -1; + } + }else{ + ccdSimplexSetSize(portal, 4); + } + } + + return 0; +} + +static int refinePortal(const void *obj1, const void *obj2, + const ccd_t *ccd, ccd_simplex_t *portal) +{ + ccd_vec3_t dir; + ccd_support_t v4; + + while (1){ + // compute direction outside the portal (from v0 throught v1,v2,v3 + // face) + if (portalDir(portal, &dir) != 0) { + return -1; + } + + // test if origin is inside the portal + if (portalEncapsulesOrigin(portal, &dir)) + return 0; + + // get next support point + __ccdSupport(obj1, obj2, &dir, ccd, &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, ccd)){ + return -1; + } + + // v1-v2-v3 triangle must be rearranged to face outside Minkowski + // difference (direction from v0). + expandPortal(portal, &v4); + } + + return -1; +} + + +static int findPenetr(const void *obj1, const void *obj2, const ccd_t *ccd, + ccd_simplex_t *portal, + ccd_real_t *depth, ccd_vec3_t *pdir, ccd_vec3_t *pos) +{ + ccd_vec3_t dir; + ccd_support_t v4; + unsigned long iterations; + + iterations = 0UL; + while (1){ + // compute portal direction and obtain next support point + if (portalDir(portal, &dir) != 0) { + return -1; + } + + __ccdSupport(obj1, obj2, &dir, ccd, &v4); + + // reached tolerance -> find penetration info + if (portalReachTolerance(portal, &v4, &dir, ccd) + || iterations > ccd->max_iterations){ + *depth = ccdVec3PointTriDist2(ccd_vec3_origin, + &ccdSimplexPoint(portal, 1)->v, + &ccdSimplexPoint(portal, 2)->v, + &ccdSimplexPoint(portal, 3)->v, + pdir); + *depth = CCD_SQRT(*depth); + if (ccdVec3SafeNormalize(pdir) != 0) { + return -1; + } + + // barycentric coordinates: + if (findPos(obj1, obj2, ccd, portal, pos) != 0) { + return -1; + } + + return 0; + } + + expandPortal(portal, &v4); + + iterations++; + } +} + +static void findPenetrTouch(const void *obj1, const void *obj2, const ccd_t *ccd, + ccd_simplex_t *portal, + ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos) +{ + // Touching contact on portal's v1 - so depth is zero and direction + // is unimportant and pos can be guessed + *depth = CCD_REAL(0.); + ccdVec3Copy(dir, ccd_vec3_origin); + + ccdVec3Copy(pos, &ccdSimplexPoint(portal, 1)->v1); + ccdVec3Add(pos, &ccdSimplexPoint(portal, 1)->v2); + ccdVec3Scale(pos, 0.5); +} + +static int findPenetrSegment(const void *obj1, const void *obj2, const ccd_t *ccd, + ccd_simplex_t *portal, + ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos) +{ + /* + ccd_vec3_t vec; + ccd_real_t k; + */ + + // Origin lies on v0-v1 segment. + // Depth is distance to v1, direction also and position must be + // computed + + ccdVec3Copy(pos, &ccdSimplexPoint(portal, 1)->v1); + ccdVec3Add(pos, &ccdSimplexPoint(portal, 1)->v2); + ccdVec3Scale(pos, CCD_REAL(0.5)); + + /* + ccdVec3Sub2(&vec, &ccdSimplexPoint(portal, 1)->v, + &ccdSimplexPoint(portal, 0)->v); + k = CCD_SQRT(ccdVec3Len2(&ccdSimplexPoint(portal, 0)->v)); + k /= CCD_SQRT(ccdVec3Len2(&vec)); + ccdVec3Scale(&vec, -k); + ccdVec3Add(pos, &vec); + */ + + ccdVec3Copy(dir, &ccdSimplexPoint(portal, 1)->v); + *depth = CCD_SQRT(ccdVec3Len2(dir)); + if (ccdVec3SafeNormalize(dir) != 0) { + return -1; + } + return 0; +} + + +static int findPos(const void *obj1, const void *obj2, const ccd_t *ccd, + const ccd_simplex_t *portal, ccd_vec3_t *pos) +{ + ccd_vec3_t dir; + size_t i; + ccd_real_t b[4], sum, inv; + ccd_vec3_t vec, p1, p2; + + if (portalDir(portal, &dir) != 0) { + return -1; + } + + // use barycentric coordinates of tetrahedron to find origin + ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 1)->v, + &ccdSimplexPoint(portal, 2)->v); + b[0] = ccdVec3Dot(&vec, &ccdSimplexPoint(portal, 3)->v); + + ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 3)->v, + &ccdSimplexPoint(portal, 2)->v); + b[1] = ccdVec3Dot(&vec, &ccdSimplexPoint(portal, 0)->v); + + ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 0)->v, + &ccdSimplexPoint(portal, 1)->v); + b[2] = ccdVec3Dot(&vec, &ccdSimplexPoint(portal, 3)->v); + + ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 2)->v, + &ccdSimplexPoint(portal, 1)->v); + b[3] = ccdVec3Dot(&vec, &ccdSimplexPoint(portal, 0)->v); + + sum = b[0] + b[1] + b[2] + b[3]; + + if (ccdIsZero(sum) || sum < CCD_ZERO){ + b[0] = CCD_REAL(0.); + + ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 2)->v, + &ccdSimplexPoint(portal, 3)->v); + b[1] = ccdVec3Dot(&vec, &dir); + ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 3)->v, + &ccdSimplexPoint(portal, 1)->v); + b[2] = ccdVec3Dot(&vec, &dir); + ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 1)->v, + &ccdSimplexPoint(portal, 2)->v); + b[3] = ccdVec3Dot(&vec, &dir); + + sum = b[1] + b[2] + b[3]; + } + + inv = CCD_REAL(1.) / sum; + + ccdVec3Copy(&p1, ccd_vec3_origin); + ccdVec3Copy(&p2, ccd_vec3_origin); + for (i = 0; i < 4; i++){ + ccdVec3Copy(&vec, &ccdSimplexPoint(portal, i)->v1); + ccdVec3Scale(&vec, b[i]); + ccdVec3Add(&p1, &vec); + + ccdVec3Copy(&vec, &ccdSimplexPoint(portal, i)->v2); + ccdVec3Scale(&vec, b[i]); + ccdVec3Add(&p2, &vec); + } + ccdVec3Scale(&p1, inv); + ccdVec3Scale(&p2, inv); + + ccdVec3Copy(pos, &p1); + ccdVec3Add(pos, &p2); + ccdVec3Scale(pos, 0.5); + return 0; +} + +_ccd_inline void expandPortal(ccd_simplex_t *portal, + const ccd_support_t *v4) +{ + ccd_real_t dot; + ccd_vec3_t v4v0; + + ccdVec3Cross(&v4v0, &v4->v, &ccdSimplexPoint(portal, 0)->v); + dot = ccdVec3Dot(&ccdSimplexPoint(portal, 1)->v, &v4v0); + if (dot > CCD_ZERO){ + dot = ccdVec3Dot(&ccdSimplexPoint(portal, 2)->v, &v4v0); + if (dot > CCD_ZERO){ + ccdSimplexSet(portal, 1, v4); + }else{ + ccdSimplexSet(portal, 3, v4); + } + }else{ + dot = ccdVec3Dot(&ccdSimplexPoint(portal, 3)->v, &v4v0); + if (dot > CCD_ZERO){ + ccdSimplexSet(portal, 2, v4); + }else{ + ccdSimplexSet(portal, 1, v4); + } + } +} + +_ccd_inline int portalDir(const ccd_simplex_t *portal, ccd_vec3_t *dir) +{ + ccd_vec3_t v2v1, v3v1; + + ccdVec3Sub2(&v2v1, &ccdSimplexPoint(portal, 2)->v, + &ccdSimplexPoint(portal, 1)->v); + ccdVec3Sub2(&v3v1, &ccdSimplexPoint(portal, 3)->v, + &ccdSimplexPoint(portal, 1)->v); + ccdVec3Cross(dir, &v2v1, &v3v1); + if (ccdVec3SafeNormalize(dir) != 0) { + return -1; + } + return 0; +} + +_ccd_inline int portalEncapsulesOrigin(const ccd_simplex_t *portal, + const ccd_vec3_t *dir) +{ + ccd_real_t dot; + dot = ccdVec3Dot(dir, &ccdSimplexPoint(portal, 1)->v); + return ccdIsZero(dot) || dot > CCD_ZERO; +} + +_ccd_inline int portalReachTolerance(const ccd_simplex_t *portal, + const ccd_support_t *v4, + const ccd_vec3_t *dir, + const ccd_t *ccd) +{ + ccd_real_t dv1, dv2, dv3, dv4; + ccd_real_t dot1, dot2, dot3; + + // find the smallest dot product of dir and {v1-v4, v2-v4, v3-v4} + + dv1 = ccdVec3Dot(&ccdSimplexPoint(portal, 1)->v, dir); + dv2 = ccdVec3Dot(&ccdSimplexPoint(portal, 2)->v, dir); + dv3 = ccdVec3Dot(&ccdSimplexPoint(portal, 3)->v, dir); + dv4 = ccdVec3Dot(&v4->v, dir); + + dot1 = dv4 - dv1; + dot2 = dv4 - dv2; + dot3 = dv4 - dv3; + + dot1 = CCD_FMIN(dot1, dot2); + dot1 = CCD_FMIN(dot1, dot3); + + return ccdEq(dot1, ccd->mpr_tolerance) || dot1 < ccd->mpr_tolerance; +} + +_ccd_inline int portalCanEncapsuleOrigin(const ccd_simplex_t *portal, + const ccd_support_t *v4, + const ccd_vec3_t *dir) +{ + ccd_real_t dot; + dot = ccdVec3Dot(&v4->v, dir); + return ccdIsZero(dot) || dot > CCD_ZERO; +} diff --git a/libs/ode-0.16.1/libccd/src/polytope.c b/libs/ode-0.16.1/libccd/src/polytope.c new file mode 100644 index 0000000..c340b8c --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/polytope.c @@ -0,0 +1,287 @@ +/*** + * libccd + * --------------------------------- + * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz> + * + * + * This file is part of libccd. + * + * Distributed under the OSI-approved BSD License (the "License"); + * see accompanying file BDS-LICENSE for details or see + * <http://www.opensource.org/licenses/bsd-license.php>. + * + * This software is distributed WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the License for more information. + */ + +#include <stdio.h> +#include <float.h> +#include <ccd/polytope.h> +#include <ccd/alloc.h> + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +_ccd_inline void _ccdPtNearestUpdate(ccd_pt_t *pt, ccd_pt_el_t *el) +{ + if (ccdEq(pt->nearest_dist, el->dist)){ + if (el->type < pt->nearest_type){ + pt->nearest = el; + pt->nearest_dist = el->dist; + pt->nearest_type = el->type; + } + }else if (el->dist < pt->nearest_dist){ + pt->nearest = el; + pt->nearest_dist = el->dist; + pt->nearest_type = el->type; + } +} + +static void _ccdPtNearestRenew(ccd_pt_t *pt) +{ + ccd_pt_vertex_t *v; + ccd_pt_edge_t *e; + ccd_pt_face_t *f; + + pt->nearest_dist = CCD_REAL_MAX; + pt->nearest_type = 3; + pt->nearest = NULL; + + ccdListForEachEntry(&pt->vertices, v, ccd_pt_vertex_t, list){ + _ccdPtNearestUpdate(pt, (ccd_pt_el_t *)v); + } + + ccdListForEachEntry(&pt->edges, e, ccd_pt_edge_t, list){ + _ccdPtNearestUpdate(pt, (ccd_pt_el_t *)e); + } + + ccdListForEachEntry(&pt->faces, f, ccd_pt_face_t, list){ + _ccdPtNearestUpdate(pt, (ccd_pt_el_t *)f); + } +} + + + +void ccdPtInit(ccd_pt_t *pt) +{ + ccdListInit(&pt->vertices); + ccdListInit(&pt->edges); + ccdListInit(&pt->faces); + + pt->nearest = NULL; + pt->nearest_dist = CCD_REAL_MAX; + pt->nearest_type = 3; +} + +void ccdPtDestroy(ccd_pt_t *pt) +{ + ccd_pt_face_t *f, *f2; + ccd_pt_edge_t *e, *e2; + ccd_pt_vertex_t *v, *v2; + + // first delete all faces + ccdListForEachEntrySafe(&pt->faces, f, ccd_pt_face_t, f2, ccd_pt_face_t, list){ + ccdPtDelFace(pt, f); + } + + // delete all edges + ccdListForEachEntrySafe(&pt->edges, e, ccd_pt_edge_t, e2, ccd_pt_edge_t, list){ + ccdPtDelEdge(pt, e); + } + + // delete all vertices + ccdListForEachEntrySafe(&pt->vertices, v, ccd_pt_vertex_t, v2, ccd_pt_vertex_t, list){ + ccdPtDelVertex(pt, v); + } +} + + +ccd_pt_vertex_t *ccdPtAddVertex(ccd_pt_t *pt, const ccd_support_t *v) +{ + ccd_pt_vertex_t *vert; + + vert = CCD_ALLOC(ccd_pt_vertex_t); + vert->type = CCD_PT_VERTEX; + ccdSupportCopy(&vert->v, v); + + vert->dist = ccdVec3Len2(&vert->v.v); + ccdVec3Copy(&vert->witness, &vert->v.v); + + ccdListInit(&vert->edges); + + // add vertex to list + ccdListAppend(&pt->vertices, &vert->list); + + // update position in .nearest array + _ccdPtNearestUpdate(pt, (ccd_pt_el_t *)vert); + + return vert; +} + +ccd_pt_edge_t *ccdPtAddEdge(ccd_pt_t *pt, ccd_pt_vertex_t *v1, + ccd_pt_vertex_t *v2) +{ + const ccd_vec3_t *a, *b; + ccd_pt_edge_t *edge; + + edge = CCD_ALLOC(ccd_pt_edge_t); + edge->type = CCD_PT_EDGE; + edge->vertex[0] = v1; + edge->vertex[1] = v2; + edge->faces[0] = edge->faces[1] = NULL; + + a = &edge->vertex[0]->v.v; + b = &edge->vertex[1]->v.v; + edge->dist = ccdVec3PointSegmentDist2(ccd_vec3_origin, a, b, &edge->witness); + + ccdListAppend(&edge->vertex[0]->edges, &edge->vertex_list[0]); + ccdListAppend(&edge->vertex[1]->edges, &edge->vertex_list[1]); + + ccdListAppend(&pt->edges, &edge->list); + + // update position in .nearest array + _ccdPtNearestUpdate(pt, (ccd_pt_el_t *)edge); + + return edge; +} + +ccd_pt_face_t *ccdPtAddFace(ccd_pt_t *pt, ccd_pt_edge_t *e1, + ccd_pt_edge_t *e2, + ccd_pt_edge_t *e3) +{ + const ccd_vec3_t *a, *b, *c; + ccd_pt_face_t *face; + ccd_pt_edge_t *e; + size_t i; + + face = CCD_ALLOC(ccd_pt_face_t); + face->type = CCD_PT_FACE; + face->edge[0] = e1; + face->edge[1] = e2; + face->edge[2] = e3; + + // obtain triplet of vertices + a = &face->edge[0]->vertex[0]->v.v; + b = &face->edge[0]->vertex[1]->v.v; + e = face->edge[1]; + if (e->vertex[0] != face->edge[0]->vertex[0] + && e->vertex[0] != face->edge[0]->vertex[1]){ + c = &e->vertex[0]->v.v; + }else{ + c = &e->vertex[1]->v.v; + } + face->dist = ccdVec3PointTriDist2(ccd_vec3_origin, a, b, c, &face->witness); + + + for (i = 0; i < 3; i++){ + if (face->edge[i]->faces[0] == NULL){ + face->edge[i]->faces[0] = face; + }else{ + face->edge[i]->faces[1] = face; + } + } + + ccdListAppend(&pt->faces, &face->list); + + // update position in .nearest array + _ccdPtNearestUpdate(pt, (ccd_pt_el_t *)face); + + return face; +} + + +void ccdPtRecomputeDistances(ccd_pt_t *pt) +{ + ccd_pt_vertex_t *v; + ccd_pt_edge_t *e; + ccd_pt_face_t *f; + const ccd_vec3_t *a, *b, *c; + ccd_real_t dist; + + ccdListForEachEntry(&pt->vertices, v, ccd_pt_vertex_t, list){ + dist = ccdVec3Len2(&v->v.v); + v->dist = dist; + ccdVec3Copy(&v->witness, &v->v.v); + } + + ccdListForEachEntry(&pt->edges, e, ccd_pt_edge_t, list){ + a = &e->vertex[0]->v.v; + b = &e->vertex[1]->v.v; + dist = ccdVec3PointSegmentDist2(ccd_vec3_origin, a, b, &e->witness); + e->dist = dist; + } + + ccdListForEachEntry(&pt->faces, f, ccd_pt_face_t, list){ + // obtain triplet of vertices + a = &f->edge[0]->vertex[0]->v.v; + b = &f->edge[0]->vertex[1]->v.v; + e = f->edge[1]; + if (e->vertex[0] != f->edge[0]->vertex[0] + && e->vertex[0] != f->edge[0]->vertex[1]){ + c = &e->vertex[0]->v.v; + }else{ + c = &e->vertex[1]->v.v; + } + + dist = ccdVec3PointTriDist2(ccd_vec3_origin, a, b, c, &f->witness); + f->dist = dist; + } +} + +ccd_pt_el_t *ccdPtNearest(ccd_pt_t *pt) +{ + if (!pt->nearest){ + _ccdPtNearestRenew(pt); + } + return pt->nearest; +} + + +void ccdPtDumpSVT(ccd_pt_t *pt, const char *fn) +{ + FILE *fout; + + fout = fopen(fn, "a"); + if (fout == NULL) + return; + + ccdPtDumpSVT2(pt, fout); + + fclose(fout); +} + +void ccdPtDumpSVT2(ccd_pt_t *pt, FILE *fout) +{ + ccd_pt_vertex_t *v, *a, *b, *c; + ccd_pt_edge_t *e; + ccd_pt_face_t *f; + size_t i; + + fprintf(fout, "-----\n"); + + fprintf(fout, "Points:\n"); + i = 0; + ccdListForEachEntry(&pt->vertices, v, ccd_pt_vertex_t, list){ + v->id = i++; + fprintf(fout, "%lf %lf %lf\n", + ccdVec3X(&v->v.v), ccdVec3Y(&v->v.v), ccdVec3Z(&v->v.v)); + } + + fprintf(fout, "Edges:\n"); + ccdListForEachEntry(&pt->edges, e, ccd_pt_edge_t, list){ + fprintf(fout, "%d %d\n", e->vertex[0]->id, e->vertex[1]->id); + } + + fprintf(fout, "Faces:\n"); + ccdListForEachEntry(&pt->faces, f, ccd_pt_face_t, list){ + a = f->edge[0]->vertex[0]; + b = f->edge[0]->vertex[1]; + c = f->edge[1]->vertex[0]; + if (c == a || c == b){ + c = f->edge[1]->vertex[1]; + } + fprintf(fout, "%d %d %d\n", a->id, b->id, c->id); + } +} diff --git a/libs/ode-0.16.1/libccd/src/support.c b/libs/ode-0.16.1/libccd/src/support.c new file mode 100644 index 0000000..5ce3586 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/support.c @@ -0,0 +1,39 @@ +/*** + * libccd + * --------------------------------- + * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz> + * + * + * This file is part of libccd. + * + * Distributed under the OSI-approved BSD License (the "License"); + * see accompanying file BDS-LICENSE for details or see + * <http://www.opensource.org/licenses/bsd-license.php>. + * + * This software is distributed WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the License for more information. + */ + +#include <ccd/support.h> + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +void __ccdSupport(const void *obj1, const void *obj2, + const ccd_vec3_t *_dir, const ccd_t *ccd, + ccd_support_t *supp) +{ + ccd_vec3_t dir; + + ccdVec3Copy(&dir, _dir); + + ccd->support1(obj1, &dir, &supp->v1); + + ccdVec3Scale(&dir, -CCD_ONE); + ccd->support2(obj2, &dir, &supp->v2); + + ccdVec3Sub2(&supp->v, &supp->v1, &supp->v2); +} diff --git a/libs/ode-0.16.1/libccd/src/testsuites/Makefile.am b/libs/ode-0.16.1/libccd/src/testsuites/Makefile.am new file mode 100644 index 0000000..733fed3 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/Makefile.am @@ -0,0 +1,28 @@ +SUBDIRS = cu + +AM_CPPFLAGS = -I $(srcdir)/.. -I $(builddir)/.. -I $(srcdir)/cu + +LDADD = $(builddir)/cu/libcu.la $(builddir)/../libccd.la + + +check_PROGRAMS = test bench bench2 + +test_SOURCES = main.c \ + common.c common.h \ + support.c support.h \ + vec3.c vec3.h \ + polytope.c polytope.h \ + boxbox.c boxbox.h \ + spheresphere.c spheresphere.h \ + cylcyl.c cylcyl.h \ + boxcyl.c boxcyl.h \ + mpr_boxbox.c mpr_boxbox.h \ + mpr_cylcyl.c mpr_cylcyl.h \ + mpr_boxcyl.c mpr_boxcyl.h + +bench_SOURCES = bench.c \ + support.c support.h + +bench2_SOURCES = bench2.c \ + support.c support.h + diff --git a/libs/ode-0.16.1/libccd/src/testsuites/Makefile.in b/libs/ode-0.16.1/libccd/src/testsuites/Makefile.in new file mode 100644 index 0000000..40ff0ea --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/Makefile.in @@ -0,0 +1,753 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +check_PROGRAMS = test$(EXEEXT) bench$(EXEEXT) bench2$(EXEEXT) +subdir = src/testsuites +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am_bench_OBJECTS = bench.$(OBJEXT) support.$(OBJEXT) +bench_OBJECTS = $(am_bench_OBJECTS) +bench_LDADD = $(LDADD) +bench_DEPENDENCIES = $(builddir)/cu/libcu.la $(builddir)/../libccd.la +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +am_bench2_OBJECTS = bench2.$(OBJEXT) support.$(OBJEXT) +bench2_OBJECTS = $(am_bench2_OBJECTS) +bench2_LDADD = $(LDADD) +bench2_DEPENDENCIES = $(builddir)/cu/libcu.la $(builddir)/../libccd.la +am_test_OBJECTS = main.$(OBJEXT) common.$(OBJEXT) support.$(OBJEXT) \ + vec3.$(OBJEXT) polytope.$(OBJEXT) boxbox.$(OBJEXT) \ + spheresphere.$(OBJEXT) cylcyl.$(OBJEXT) boxcyl.$(OBJEXT) \ + mpr_boxbox.$(OBJEXT) mpr_cylcyl.$(OBJEXT) mpr_boxcyl.$(OBJEXT) +test_OBJECTS = $(am_test_OBJECTS) +test_LDADD = $(LDADD) +test_DEPENDENCIES = $(builddir)/cu/libcu.la $(builddir)/../libccd.la +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src +depcomp = $(SHELL) $(top_srcdir)/../depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(bench_SOURCES) $(bench2_SOURCES) $(test_SOURCES) +DIST_SOURCES = $(bench_SOURCES) $(bench2_SOURCES) $(test_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/../depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_PRECISION = @CCD_PRECISION@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = cu +AM_CPPFLAGS = -I $(srcdir)/.. -I $(builddir)/.. -I $(srcdir)/cu +LDADD = $(builddir)/cu/libcu.la $(builddir)/../libccd.la +test_SOURCES = main.c \ + common.c common.h \ + support.c support.h \ + vec3.c vec3.h \ + polytope.c polytope.h \ + boxbox.c boxbox.h \ + spheresphere.c spheresphere.h \ + cylcyl.c cylcyl.h \ + boxcyl.c boxcyl.h \ + mpr_boxbox.c mpr_boxbox.h \ + mpr_cylcyl.c mpr_cylcyl.h \ + mpr_boxcyl.c mpr_boxcyl.h + +bench_SOURCES = bench.c \ + support.c support.h + +bench2_SOURCES = bench2.c \ + support.c support.h + +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/testsuites/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/testsuites/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +bench$(EXEEXT): $(bench_OBJECTS) $(bench_DEPENDENCIES) $(EXTRA_bench_DEPENDENCIES) + @rm -f bench$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(bench_OBJECTS) $(bench_LDADD) $(LIBS) + +bench2$(EXEEXT): $(bench2_OBJECTS) $(bench2_DEPENDENCIES) $(EXTRA_bench2_DEPENDENCIES) + @rm -f bench2$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(bench2_OBJECTS) $(bench2_LDADD) $(LIBS) + +test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) $(EXTRA_test_DEPENDENCIES) + @rm -f test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_OBJECTS) $(test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bench.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bench2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/boxbox.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/boxcyl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cylcyl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpr_boxbox.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpr_boxcyl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpr_cylcyl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polytope.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spheresphere.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/support.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vec3.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) check-am install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-checkPROGRAMS clean-generic clean-libtool \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs installdirs-am \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/libccd/src/testsuites/bench.c b/libs/ode-0.16.1/libccd/src/testsuites/bench.c new file mode 100644 index 0000000..779a8ac --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/bench.c @@ -0,0 +1,257 @@ +#define CU_ENABLE_TIMER +#include <cu/cu.h> +#include <stdio.h> +#include <stdlib.h> +#include <ccd/ccd.h> +#include "support.h" + +TEST_SUITES { + TEST_SUITES_CLOSURE +}; + +static int bench_num = 1; +static size_t cycles = 10000; + +static void runBench(const void *o1, const void *o2, const ccd_t *ccd) +{ + ccd_real_t depth; + ccd_vec3_t dir, pos; + int res; + size_t i; + const struct timespec *timer; + + cuTimerStart(); + for (i = 0; i < cycles; i++){ + res = ccdGJKPenetration(o1, o2, ccd, &depth, &dir, &pos); + } + timer = cuTimerStop(); + fprintf(stdout, "%02d: %ld %ld\n", bench_num, + (long)timer->tv_sec, (long)timer->tv_nsec); + fflush(stdout); + + bench_num++; +} + +static void boxbox(void) +{ + fprintf(stdout, "%s:\n", __func__); + + ccd_t ccd; + CCD_BOX(box1); + CCD_BOX(box2); + ccd_vec3_t axis; + ccd_quat_t rot; + + box1.x = box1.y = box1.z = 1.; + box2.x = 0.5; + box2.y = 1.; + box2.z = 1.5; + + bench_num = 1; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + + runBench(&box1, &box2, &ccd); + runBench(&box2, &box1, &ccd); + + ccdVec3Set(&box1.pos, -0.3, 0.5, 1.); + runBench(&box1, &box2, &ccd); + runBench(&box2, &box1, &ccd); + + box1.x = box1.y = box1.z = 1.; + box2.x = box2.y = box2.z = 1.; + ccdVec3Set(&axis, 0., 0., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&box1.pos, 0., 0., 0.); + runBench(&box1, &box2, &ccd); + runBench(&box2, &box1, &ccd); + + box1.x = box1.y = box1.z = 1.; + box2.x = box2.y = box2.z = 1.; + ccdVec3Set(&axis, 0., 0., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&box1.pos, -0.5, 0., 0.); + runBench(&box1, &box2, &ccd); + runBench(&box2, &box1, &ccd); + + box1.x = box1.y = box1.z = 1.; + box2.x = box2.y = box2.z = 1.; + ccdVec3Set(&axis, 0., 0., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&box1.pos, -0.5, 0.5, 0.); + runBench(&box1, &box2, &ccd); + runBench(&box2, &box1, &ccd); + + box1.x = box1.y = box1.z = 1.; + ccdVec3Set(&axis, 0., 1., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&box1.pos, -0.5, 0.1, 0.4); + runBench(&box1, &box2, &ccd); + runBench(&box2, &box1, &ccd); + + box1.x = box1.y = box1.z = 1.; + ccdVec3Set(&axis, 0., 1., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&axis, 1., 1., 1.); + ccdQuatSetAngleAxis(&rot, M_PI / 4., &axis); + ccdQuatMul(&box1.quat, &rot); + ccdVec3Set(&box1.pos, -0.5, 0.1, 0.4); + runBench(&box1, &box2, &ccd); + runBench(&box2, &box1, &ccd); + + + box1.x = box1.y = box1.z = 1.; + box2.x = 0.2; box2.y = 0.5; box2.z = 1.; + box2.x = box2.y = box2.z = 1.; + + ccdVec3Set(&axis, 0., 0., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&axis, 1., 0., 0.); + ccdQuatSetAngleAxis(&rot, M_PI / 4., &axis); + ccdQuatMul(&box1.quat, &rot); + ccdVec3Set(&box1.pos, -1.3, 0., 0.); + + ccdVec3Set(&box2.pos, 0., 0., 0.); + runBench(&box1, &box2, &ccd); + runBench(&box2, &box1, &ccd); + + + fprintf(stdout, "\n----\n\n"); +} + +void cylcyl(void) +{ + fprintf(stdout, "%s:\n", __func__); + + ccd_t ccd; + CCD_CYL(cyl1); + CCD_CYL(cyl2); + ccd_vec3_t axis; + + cyl1.radius = 0.35; + cyl1.height = 0.5; + cyl2.radius = 0.5; + cyl2.height = 1.; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + + runBench(&cyl1, &cyl2, &ccd); + runBench(&cyl2, &cyl1, &ccd); + + ccdVec3Set(&cyl1.pos, 0.3, 0.1, 0.1); + runBench(&cyl1, &cyl2, &ccd); + runBench(&cyl2, &cyl1, &ccd); + + ccdVec3Set(&axis, 0., 1., 1.); + ccdQuatSetAngleAxis(&cyl2.quat, M_PI / 4., &axis); + ccdVec3Set(&cyl2.pos, 0., 0., 0.); + runBench(&cyl1, &cyl2, &ccd); + runBench(&cyl2, &cyl1, &ccd); + + ccdVec3Set(&axis, 0., 1., 1.); + ccdQuatSetAngleAxis(&cyl2.quat, M_PI / 4., &axis); + ccdVec3Set(&cyl2.pos, -0.2, 0.7, 0.2); + runBench(&cyl1, &cyl2, &ccd); + runBench(&cyl2, &cyl1, &ccd); + + ccdVec3Set(&axis, 0.567, 1.2, 1.); + ccdQuatSetAngleAxis(&cyl2.quat, M_PI / 4., &axis); + ccdVec3Set(&cyl2.pos, 0.6, -0.7, 0.2); + runBench(&cyl1, &cyl2, &ccd); + runBench(&cyl2, &cyl1, &ccd); + + ccdVec3Set(&axis, -4.567, 1.2, 0.); + ccdQuatSetAngleAxis(&cyl2.quat, M_PI / 3., &axis); + ccdVec3Set(&cyl2.pos, 0.6, -0.7, 0.2); + runBench(&cyl1, &cyl2, &ccd); + runBench(&cyl2, &cyl1, &ccd); + + fprintf(stdout, "\n----\n\n"); +} + +void boxcyl(void) +{ + fprintf(stdout, "%s:\n", __func__); + + ccd_t ccd; + CCD_BOX(box); + CCD_CYL(cyl); + ccd_vec3_t axis; + + box.x = 0.5; + box.y = 1.; + box.z = 1.5; + cyl.radius = 0.4; + cyl.height = 0.7; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + + runBench(&box, &cyl, &ccd); + runBench(&cyl, &box, &ccd); + + ccdVec3Set(&cyl.pos, .6, 0., 0.); + runBench(&box, &cyl, &ccd); + runBench(&cyl, &box, &ccd); + + ccdVec3Set(&cyl.pos, .6, 0.6, 0.); + runBench(&box, &cyl, &ccd); + runBench(&cyl, &box, &ccd); + + ccdVec3Set(&cyl.pos, .6, 0.6, 0.5); + runBench(&box, &cyl, &ccd); + runBench(&cyl, &box, &ccd); + + ccdVec3Set(&axis, 0., 1., 0.); + ccdQuatSetAngleAxis(&cyl.quat, M_PI / 3., &axis); + ccdVec3Set(&cyl.pos, .6, 0.6, 0.5); + runBench(&box, &cyl, &ccd); + runBench(&cyl, &box, &ccd); + + ccdVec3Set(&axis, 0.67, 1.1, 0.12); + ccdQuatSetAngleAxis(&cyl.quat, M_PI / 4., &axis); + ccdVec3Set(&cyl.pos, .6, 0., 0.5); + runBench(&box, &cyl, &ccd); + runBench(&cyl, &box, &ccd); + + ccdVec3Set(&axis, -0.1, 2.2, -1.); + ccdQuatSetAngleAxis(&cyl.quat, M_PI / 5., &axis); + ccdVec3Set(&cyl.pos, .6, 0., 0.5); + ccdVec3Set(&axis, 1., 1., 0.); + ccdQuatSetAngleAxis(&box.quat, -M_PI / 4., &axis); + ccdVec3Set(&box.pos, .6, 0., 0.5); + runBench(&box, &cyl, &ccd); + runBench(&cyl, &box, &ccd); + + ccdVec3Set(&axis, -0.1, 2.2, -1.); + ccdQuatSetAngleAxis(&cyl.quat, M_PI / 5., &axis); + ccdVec3Set(&cyl.pos, .6, 0., 0.5); + ccdVec3Set(&axis, 1., 1., 0.); + ccdQuatSetAngleAxis(&box.quat, -M_PI / 4., &axis); + ccdVec3Set(&box.pos, .9, 0.8, 0.5); + runBench(&box, &cyl, &ccd); + runBench(&cyl, &box, &ccd); + + fprintf(stdout, "\n----\n\n"); +} + +int main(int argc, char *argv[]) +{ + if (argc > 1){ + cycles = atol(argv[1]); + } + + fprintf(stdout, "Cycles: %zu\n", cycles); + fprintf(stdout, "\n"); + + boxbox(); + cylcyl(); + boxcyl(); + + return 0; +} diff --git a/libs/ode-0.16.1/libccd/src/testsuites/bench2.c b/libs/ode-0.16.1/libccd/src/testsuites/bench2.c new file mode 100644 index 0000000..8fb29df --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/bench2.c @@ -0,0 +1,263 @@ +#define CU_ENABLE_TIMER +#include <cu/cu.h> +#include <stdio.h> +#include <stdlib.h> +#include <ccd/ccd.h> +#include "support.h" + +TEST_SUITES { + TEST_SUITES_CLOSURE +}; + +static int bench_num = 1; +static size_t cycles = 10000; + +static void runBench(const void *o1, const void *o2, const ccd_t *ccd) +{ + ccd_real_t depth; + ccd_vec3_t dir, pos; + int res; + size_t i; + const struct timespec *timer; + + cuTimerStart(); + for (i = 0; i < cycles; i++){ + res = ccdMPRPenetration(o1, o2, ccd, &depth, &dir, &pos); + } + timer = cuTimerStop(); + fprintf(stdout, "%02d: %ld %ld\n", bench_num, + (long)timer->tv_sec, (long)timer->tv_nsec); + fflush(stdout); + + bench_num++; +} + +static void boxbox(void) +{ + fprintf(stdout, "%s:\n", __func__); + + ccd_t ccd; + CCD_BOX(box1); + CCD_BOX(box2); + ccd_vec3_t axis; + ccd_quat_t rot; + + box1.x = box1.y = box1.z = 1.; + box2.x = 0.5; + box2.y = 1.; + box2.z = 1.5; + + bench_num = 1; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + ccd.center1 = ccdObjCenter; + ccd.center2 = ccdObjCenter; + + runBench(&box1, &box2, &ccd); + runBench(&box2, &box1, &ccd); + + ccdVec3Set(&box1.pos, -0.3, 0.5, 1.); + runBench(&box1, &box2, &ccd); + runBench(&box2, &box1, &ccd); + + box1.x = box1.y = box1.z = 1.; + box2.x = box2.y = box2.z = 1.; + ccdVec3Set(&axis, 0., 0., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&box1.pos, 0., 0., 0.); + runBench(&box1, &box2, &ccd); + runBench(&box2, &box1, &ccd); + + box1.x = box1.y = box1.z = 1.; + box2.x = box2.y = box2.z = 1.; + ccdVec3Set(&axis, 0., 0., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&box1.pos, -0.5, 0., 0.); + runBench(&box1, &box2, &ccd); + runBench(&box2, &box1, &ccd); + + box1.x = box1.y = box1.z = 1.; + box2.x = box2.y = box2.z = 1.; + ccdVec3Set(&axis, 0., 0., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&box1.pos, -0.5, 0.5, 0.); + runBench(&box1, &box2, &ccd); + runBench(&box2, &box1, &ccd); + + box1.x = box1.y = box1.z = 1.; + ccdVec3Set(&axis, 0., 1., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&box1.pos, -0.5, 0.1, 0.4); + runBench(&box1, &box2, &ccd); + runBench(&box2, &box1, &ccd); + + box1.x = box1.y = box1.z = 1.; + ccdVec3Set(&axis, 0., 1., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&axis, 1., 1., 1.); + ccdQuatSetAngleAxis(&rot, M_PI / 4., &axis); + ccdQuatMul(&box1.quat, &rot); + ccdVec3Set(&box1.pos, -0.5, 0.1, 0.4); + runBench(&box1, &box2, &ccd); + runBench(&box2, &box1, &ccd); + + + box1.x = box1.y = box1.z = 1.; + box2.x = 0.2; box2.y = 0.5; box2.z = 1.; + box2.x = box2.y = box2.z = 1.; + + ccdVec3Set(&axis, 0., 0., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&axis, 1., 0., 0.); + ccdQuatSetAngleAxis(&rot, M_PI / 4., &axis); + ccdQuatMul(&box1.quat, &rot); + ccdVec3Set(&box1.pos, -1.3, 0., 0.); + + ccdVec3Set(&box2.pos, 0., 0., 0.); + runBench(&box1, &box2, &ccd); + runBench(&box2, &box1, &ccd); + + + fprintf(stdout, "\n----\n\n"); +} + +void cylcyl(void) +{ + fprintf(stdout, "%s:\n", __func__); + + ccd_t ccd; + CCD_CYL(cyl1); + CCD_CYL(cyl2); + ccd_vec3_t axis; + + cyl1.radius = 0.35; + cyl1.height = 0.5; + cyl2.radius = 0.5; + cyl2.height = 1.; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + ccd.center1 = ccdObjCenter; + ccd.center2 = ccdObjCenter; + + runBench(&cyl1, &cyl2, &ccd); + runBench(&cyl2, &cyl1, &ccd); + + ccdVec3Set(&cyl1.pos, 0.3, 0.1, 0.1); + runBench(&cyl1, &cyl2, &ccd); + runBench(&cyl2, &cyl1, &ccd); + + ccdVec3Set(&axis, 0., 1., 1.); + ccdQuatSetAngleAxis(&cyl2.quat, M_PI / 4., &axis); + ccdVec3Set(&cyl2.pos, 0., 0., 0.); + runBench(&cyl1, &cyl2, &ccd); + runBench(&cyl2, &cyl1, &ccd); + + ccdVec3Set(&axis, 0., 1., 1.); + ccdQuatSetAngleAxis(&cyl2.quat, M_PI / 4., &axis); + ccdVec3Set(&cyl2.pos, -0.2, 0.7, 0.2); + runBench(&cyl1, &cyl2, &ccd); + runBench(&cyl2, &cyl1, &ccd); + + ccdVec3Set(&axis, 0.567, 1.2, 1.); + ccdQuatSetAngleAxis(&cyl2.quat, M_PI / 4., &axis); + ccdVec3Set(&cyl2.pos, 0.6, -0.7, 0.2); + runBench(&cyl1, &cyl2, &ccd); + runBench(&cyl2, &cyl1, &ccd); + + ccdVec3Set(&axis, -4.567, 1.2, 0.); + ccdQuatSetAngleAxis(&cyl2.quat, M_PI / 3., &axis); + ccdVec3Set(&cyl2.pos, 0.6, -0.7, 0.2); + runBench(&cyl1, &cyl2, &ccd); + runBench(&cyl2, &cyl1, &ccd); + + fprintf(stdout, "\n----\n\n"); +} + +void boxcyl(void) +{ + fprintf(stdout, "%s:\n", __func__); + + ccd_t ccd; + CCD_BOX(box); + CCD_CYL(cyl); + ccd_vec3_t axis; + + box.x = 0.5; + box.y = 1.; + box.z = 1.5; + cyl.radius = 0.4; + cyl.height = 0.7; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + ccd.center1 = ccdObjCenter; + ccd.center2 = ccdObjCenter; + + runBench(&box, &cyl, &ccd); + runBench(&cyl, &box, &ccd); + + ccdVec3Set(&cyl.pos, .6, 0., 0.); + runBench(&box, &cyl, &ccd); + runBench(&cyl, &box, &ccd); + + ccdVec3Set(&cyl.pos, .6, 0.6, 0.); + runBench(&box, &cyl, &ccd); + runBench(&cyl, &box, &ccd); + + ccdVec3Set(&cyl.pos, .6, 0.6, 0.5); + runBench(&box, &cyl, &ccd); + runBench(&cyl, &box, &ccd); + + ccdVec3Set(&axis, 0., 1., 0.); + ccdQuatSetAngleAxis(&cyl.quat, M_PI / 3., &axis); + ccdVec3Set(&cyl.pos, .6, 0.6, 0.5); + runBench(&box, &cyl, &ccd); + runBench(&cyl, &box, &ccd); + + ccdVec3Set(&axis, 0.67, 1.1, 0.12); + ccdQuatSetAngleAxis(&cyl.quat, M_PI / 4., &axis); + ccdVec3Set(&cyl.pos, .6, 0., 0.5); + runBench(&box, &cyl, &ccd); + runBench(&cyl, &box, &ccd); + + ccdVec3Set(&axis, -0.1, 2.2, -1.); + ccdQuatSetAngleAxis(&cyl.quat, M_PI / 5., &axis); + ccdVec3Set(&cyl.pos, .6, 0., 0.5); + ccdVec3Set(&axis, 1., 1., 0.); + ccdQuatSetAngleAxis(&box.quat, -M_PI / 4., &axis); + ccdVec3Set(&box.pos, .6, 0., 0.5); + runBench(&box, &cyl, &ccd); + runBench(&cyl, &box, &ccd); + + ccdVec3Set(&axis, -0.1, 2.2, -1.); + ccdQuatSetAngleAxis(&cyl.quat, M_PI / 5., &axis); + ccdVec3Set(&cyl.pos, .6, 0., 0.5); + ccdVec3Set(&axis, 1., 1., 0.); + ccdQuatSetAngleAxis(&box.quat, -M_PI / 4., &axis); + ccdVec3Set(&box.pos, .9, 0.8, 0.5); + runBench(&box, &cyl, &ccd); + runBench(&cyl, &box, &ccd); + + fprintf(stdout, "\n----\n\n"); +} + +int main(int argc, char *argv[]) +{ + if (argc > 1){ + cycles = atol(argv[1]); + } + + fprintf(stdout, "Cycles: %zu\n", cycles); + fprintf(stdout, "\n"); + + boxbox(); + cylcyl(); + boxcyl(); + + return 0; +} diff --git a/libs/ode-0.16.1/libccd/src/testsuites/boxbox.c b/libs/ode-0.16.1/libccd/src/testsuites/boxbox.c new file mode 100644 index 0000000..3dfc965 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/boxbox.c @@ -0,0 +1,467 @@ +#include <stdio.h> +#include <cu/cu.h> + +#include <ccd/ccd.h> +#include "support.h" +#include <ccd/vec3.h> +#include <ccd/dbg.h> +#include "common.h" + + +TEST(boxboxSetUp) +{ +} + +TEST(boxboxTearDown) +{ +} + +TEST(boxboxAlignedX) +{ + size_t i; + ccd_t ccd; + CCD_BOX(box1); + CCD_BOX(box2); + int res; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + //ccd.max_iterations = 20; + + box1.x = 1; + box1.y = 2; + box1.z = 1; + box2.x = 2; + box2.y = 1; + box2.z = 2; + + ccdVec3Set(&box1.pos, -5., 0., 0.); + ccdVec3Set(&box2.pos, 0., 0., 0.); + ccdQuatSet(&box1.quat, 0., 0., 0., 1.); + ccdQuatSet(&box2.quat, 0., 0., 0., 1.); + for (i = 0; i < 100; i++){ + res = ccdGJKIntersect(&box1, &box2, &ccd); + if (i < 35 || i > 65){ + assertFalse(res); + }else if (i != 35 && i != 65){ + assertTrue(res); + } + + box1.pos.v[0] += 0.1; + } + + + box1.x = 0.1; + box1.y = 0.2; + box1.z = 0.1; + box2.x = 0.2; + box2.y = 0.1; + box2.z = 0.2; + + ccdVec3Set(&box1.pos, -0.5, 0., 0.); + ccdVec3Set(&box2.pos, 0., 0., 0.); + ccdQuatSet(&box1.quat, 0., 0., 0., 1.); + ccdQuatSet(&box2.quat, 0., 0., 0., 1.); + for (i = 0; i < 100; i++){ + res = ccdGJKIntersect(&box1, &box2, &ccd); + + if (i < 35 || i > 65){ + assertFalse(res); + }else if (i != 35 && i != 65){ + assertTrue(res); + } + + box1.pos.v[0] += 0.01; + } + + + box1.x = 1; + box1.y = 2; + box1.z = 1; + box2.x = 2; + box2.y = 1; + box2.z = 2; + + ccdVec3Set(&box1.pos, -5., -0.1, 0.); + ccdVec3Set(&box2.pos, 0., 0., 0.); + ccdQuatSet(&box1.quat, 0., 0., 0., 1.); + ccdQuatSet(&box2.quat, 0., 0., 0., 1.); + for (i = 0; i < 100; i++){ + res = ccdGJKIntersect(&box1, &box2, &ccd); + + if (i < 35 || i > 65){ + assertFalse(res); + }else if (i != 35 && i != 65){ + assertTrue(res); + } + + box1.pos.v[0] += 0.1; + } +} + +TEST(boxboxAlignedY) +{ + size_t i; + ccd_t ccd; + CCD_BOX(box1); + CCD_BOX(box2); + int res; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + + box1.x = 1; + box1.y = 2; + box1.z = 1; + box2.x = 2; + box2.y = 1; + box2.z = 2; + + ccdVec3Set(&box1.pos, 0., -5., 0.); + ccdVec3Set(&box2.pos, 0., 0., 0.); + ccdQuatSet(&box1.quat, 0., 0., 0., 1.); + ccdQuatSet(&box2.quat, 0., 0., 0., 1.); + for (i = 0; i < 100; i++){ + res = ccdGJKIntersect(&box1, &box2, &ccd); + + if (i < 35 || i > 65){ + assertFalse(res); + }else if (i != 35 && i != 65){ + assertTrue(res); + } + + box1.pos.v[1] += 0.1; + } +} + +TEST(boxboxAlignedZ) +{ + size_t i; + ccd_t ccd; + CCD_BOX(box1); + CCD_BOX(box2); + int res; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + + box1.x = 1; + box1.y = 2; + box1.z = 1; + box2.x = 2; + box2.y = 1; + box2.z = 2; + + ccdVec3Set(&box1.pos, 0., 0., -5.); + ccdVec3Set(&box2.pos, 0., 0., 0.); + ccdQuatSet(&box1.quat, 0., 0., 0., 1.); + ccdQuatSet(&box2.quat, 0., 0., 0., 1.); + for (i = 0; i < 100; i++){ + res = ccdGJKIntersect(&box1, &box2, &ccd); + + if (i < 35 || i > 65){ + assertFalse(res); + }else if (i != 35 && i != 65){ + assertTrue(res); + } + + box1.pos.v[2] += 0.1; + } +} + + +TEST(boxboxRot) +{ + size_t i; + ccd_t ccd; + CCD_BOX(box1); + CCD_BOX(box2); + int res; + ccd_vec3_t axis; + ccd_real_t angle; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + + box1.x = 1; + box1.y = 2; + box1.z = 1; + box2.x = 2; + box2.y = 1; + box2.z = 2; + + ccdVec3Set(&box1.pos, -5., 0.5, 0.); + ccdVec3Set(&box2.pos, 0., 0., 0.); + ccdQuatSet(&box2.quat, 0., 0., 0., 1.); + ccdVec3Set(&axis, 0., 1., 0.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + + for (i = 0; i < 100; i++){ + res = ccdGJKIntersect(&box1, &box2, &ccd); + + if (i < 33 || i > 67){ + assertFalse(res); + }else if (i != 33 && i != 67){ + assertTrue(res); + } + + box1.pos.v[0] += 0.1; + } + + box1.x = 1; + box1.y = 1; + box1.z = 1; + box2.x = 1; + box2.y = 1; + box2.z = 1; + + ccdVec3Set(&box1.pos, -1.01, 0., 0.); + ccdVec3Set(&box2.pos, 0., 0., 0.); + ccdQuatSet(&box1.quat, 0., 0., 0., 1.); + ccdQuatSet(&box2.quat, 0., 0., 0., 1.); + + ccdVec3Set(&axis, 0., 1., 0.); + angle = 0.; + for (i = 0; i < 30; i++){ + res = ccdGJKIntersect(&box1, &box2, &ccd); + + if (i != 0 && i != 10 && i != 20){ + assertTrue(res); + }else{ + assertFalse(res); + } + + angle += M_PI / 20.; + ccdQuatSetAngleAxis(&box1.quat, angle, &axis); + } + +} + + + +static void pConf(ccd_box_t *box1, ccd_box_t *box2, const ccd_vec3_t *v) +{ + fprintf(stdout, "# box1.pos: [%lf %lf %lf]\n", + ccdVec3X(&box1->pos), ccdVec3Y(&box1->pos), ccdVec3Z(&box1->pos)); + fprintf(stdout, "# box1->quat: [%lf %lf %lf %lf]\n", + box1->quat.q[0], box1->quat.q[1], box1->quat.q[2], box1->quat.q[3]); + fprintf(stdout, "# box2->pos: [%lf %lf %lf]\n", + ccdVec3X(&box2->pos), ccdVec3Y(&box2->pos), ccdVec3Z(&box2->pos)); + fprintf(stdout, "# box2->quat: [%lf %lf %lf %lf]\n", + box2->quat.q[0], box2->quat.q[1], box2->quat.q[2], box2->quat.q[3]); + fprintf(stdout, "# sep: [%lf %lf %lf]\n", + ccdVec3X(v), ccdVec3Y(v), ccdVec3Z(v)); + fprintf(stdout, "#\n"); +} + +TEST(boxboxSeparate) +{ + ccd_t ccd; + CCD_BOX(box1); + CCD_BOX(box2); + int res; + ccd_vec3_t sep, expsep, expsep2, axis; + + fprintf(stderr, "\n\n\n---- boxboxSeparate ----\n\n\n"); + + box1.x = box1.y = box1.z = 1.; + box2.x = 0.5; + box2.y = 1.; + box2.z = 1.5; + + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + + ccdVec3Set(&box1.pos, -0.5, 0.5, 0.2); + res = ccdGJKIntersect(&box1, &box2, &ccd); + assertTrue(res); + + res = ccdGJKSeparate(&box1, &box2, &ccd, &sep); + assertTrue(res == 0); + ccdVec3Set(&expsep, 0.25, 0., 0.); + assertTrue(ccdVec3Eq(&sep, &expsep)); + + ccdVec3Scale(&sep, -1.); + ccdVec3Add(&box1.pos, &sep); + res = ccdGJKSeparate(&box1, &box2, &ccd, &sep); + assertTrue(res == 0); + ccdVec3Set(&expsep, 0., 0., 0.); + assertTrue(ccdVec3Eq(&sep, &expsep)); + + + ccdVec3Set(&box1.pos, -0.3, 0.5, 1.); + res = ccdGJKSeparate(&box1, &box2, &ccd, &sep); + assertTrue(res == 0); + ccdVec3Set(&expsep, 0., 0., -0.25); + assertTrue(ccdVec3Eq(&sep, &expsep)); + + + + box1.x = box1.y = box1.z = 1.; + box2.x = box2.y = box2.z = 1.; + ccdVec3Set(&axis, 0., 0., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&box1.pos, 0., 0., 0.); + + res = ccdGJKSeparate(&box1, &box2, &ccd, &sep); + assertTrue(res == 0); + ccdVec3Set(&expsep, 0., 0., 1.); + ccdVec3Set(&expsep2, 0., 0., -1.); + assertTrue(ccdVec3Eq(&sep, &expsep) || ccdVec3Eq(&sep, &expsep2)); + + + + box1.x = box1.y = box1.z = 1.; + ccdVec3Set(&axis, 0., 0., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&box1.pos, -0.5, 0., 0.); + + res = ccdGJKSeparate(&box1, &box2, &ccd, &sep); + assertTrue(res == 0); + pConf(&box1, &box2, &sep); + + + + box1.x = box1.y = box1.z = 1.; + ccdVec3Set(&axis, 0., 1., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&box1.pos, -0.5, 0.1, 0.4); + + res = ccdGJKSeparate(&box1, &box2, &ccd, &sep); + assertTrue(res == 0); + pConf(&box1, &box2, &sep); +} + + +#define TOSVT() \ + svtObjPen(&box1, &box2, stdout, "Pen 1", depth, &dir, &pos); \ + ccdVec3Scale(&dir, depth); \ + ccdVec3Add(&box2.pos, &dir); \ + svtObjPen(&box1, &box2, stdout, "Pen 1", depth, &dir, &pos) + +TEST(boxboxPenetration) +{ + ccd_t ccd; + CCD_BOX(box1); + CCD_BOX(box2); + int res; + ccd_vec3_t axis; + ccd_quat_t rot; + ccd_real_t depth; + ccd_vec3_t dir, pos; + + fprintf(stderr, "\n\n\n---- boxboxPenetration ----\n\n\n"); + + box1.x = box1.y = box1.z = 1.; + box2.x = 0.5; + box2.y = 1.; + box2.z = 1.5; + + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + + ccdVec3Set(&box2.pos, 0.1, 0., 0.); + res = ccdGJKPenetration(&box1, &box2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 1"); + //TOSVT(); + + + ccdVec3Set(&box1.pos, -0.3, 0.5, 1.); + res = ccdGJKPenetration(&box1, &box2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 2"); + //TOSVT(); <<< + + + box1.x = box1.y = box1.z = 1.; + box2.x = box2.y = box2.z = 1.; + ccdVec3Set(&axis, 0., 0., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&box1.pos, 0.1, 0., 0.1); + + res = ccdGJKPenetration(&box1, &box2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 3"); + //TOSVT(); + + + box1.x = box1.y = box1.z = 1.; + box2.x = box2.y = box2.z = 1.; + ccdVec3Set(&axis, 0., 0., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&box1.pos, -0.5, 0., 0.); + + res = ccdGJKPenetration(&box1, &box2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 4"); + //TOSVT(); + + + box1.x = box1.y = box1.z = 1.; + box2.x = box2.y = box2.z = 1.; + ccdVec3Set(&axis, 0., 0., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&box1.pos, -0.5, 0.5, 0.); + + res = ccdGJKPenetration(&box1, &box2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 5"); + //TOSVT(); + + + box1.x = box1.y = box1.z = 1.; + box2.x = box2.y = box2.z = 1.; + ccdVec3Set(&box2.pos, 0.1, 0., 0.); + + box1.x = box1.y = box1.z = 1.; + ccdVec3Set(&axis, 0., 1., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&box1.pos, -0.5, 0.1, 0.4); + + res = ccdGJKPenetration(&box1, &box2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 6"); + //TOSVT(); + + + box1.x = box1.y = box1.z = 1.; + ccdVec3Set(&axis, 0., 1., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&axis, 1., 1., 1.); + ccdQuatSetAngleAxis(&rot, M_PI / 4., &axis); + ccdQuatMul(&box1.quat, &rot); + ccdVec3Set(&box1.pos, -0.5, 0.1, 0.4); + + res = ccdGJKPenetration(&box1, &box2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 7"); + //TOSVT(); <<< + + + box1.x = box1.y = box1.z = 1.; + box2.x = 0.2; box2.y = 0.5; box2.z = 1.; + box2.x = box2.y = box2.z = 1.; + + ccdVec3Set(&axis, 0., 0., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&axis, 1., 0., 0.); + ccdQuatSetAngleAxis(&rot, M_PI / 4., &axis); + ccdQuatMul(&box1.quat, &rot); + ccdVec3Set(&box1.pos, -1.3, 0., 0.); + + ccdVec3Set(&box2.pos, 0., 0., 0.); + + res = ccdGJKPenetration(&box1, &box2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 8"); + //TOSVT(); +} diff --git a/libs/ode-0.16.1/libccd/src/testsuites/boxbox.h b/libs/ode-0.16.1/libccd/src/testsuites/boxbox.h new file mode 100644 index 0000000..8127c7c --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/boxbox.h @@ -0,0 +1,32 @@ +#ifndef BOX_BOX +#define BOX_BOX + +#include <cu/cu.h> + +TEST(boxboxSetUp); +TEST(boxboxTearDown); + +TEST(boxboxAlignedX); +TEST(boxboxAlignedY); +TEST(boxboxAlignedZ); + +TEST(boxboxRot); + +TEST(boxboxSeparate); +TEST(boxboxPenetration); + +TEST_SUITE(TSBoxBox) { + TEST_ADD(boxboxSetUp), + + TEST_ADD(boxboxAlignedX), + TEST_ADD(boxboxAlignedY), + TEST_ADD(boxboxAlignedZ), + TEST_ADD(boxboxRot), + TEST_ADD(boxboxSeparate), + TEST_ADD(boxboxPenetration), + + TEST_ADD(boxboxTearDown), + TEST_SUITE_CLOSURE +}; + +#endif diff --git a/libs/ode-0.16.1/libccd/src/testsuites/boxcyl.c b/libs/ode-0.16.1/libccd/src/testsuites/boxcyl.c new file mode 100644 index 0000000..4a556cb --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/boxcyl.c @@ -0,0 +1,162 @@ +#include <cu/cu.h> +#include "common.h" +#include <ccd/ccd.h> +#include "support.h" + + +#define TOSVT() \ + svtObjPen(&box, &cyl, stdout, "Pen 1", depth, &dir, &pos); \ + ccdVec3Scale(&dir, depth); \ + ccdVec3Add(&cyl.pos, &dir); \ + svtObjPen(&box, &cyl, stdout, "Pen 1", depth, &dir, &pos) + + +TEST(boxcylIntersect) +{ + ccd_t ccd; + CCD_BOX(box); + CCD_CYL(cyl); + int res; + ccd_vec3_t axis; + + box.x = 0.5; + box.y = 1.; + box.z = 1.5; + cyl.radius = 0.4; + cyl.height = 0.7; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + + ccdVec3Set(&cyl.pos, 0.1, 0., 0.); + res = ccdGJKIntersect(&box, &cyl, &ccd); + assertTrue(res); + + ccdVec3Set(&cyl.pos, .6, 0., 0.); + res = ccdGJKIntersect(&box, &cyl, &ccd); + assertTrue(res); + + ccdVec3Set(&cyl.pos, .6, 0.6, 0.); + res = ccdGJKIntersect(&box, &cyl, &ccd); + assertTrue(res); + + ccdVec3Set(&cyl.pos, .6, 0.6, 0.5); + res = ccdGJKIntersect(&box, &cyl, &ccd); + assertTrue(res); + + ccdVec3Set(&axis, 0., 1., 0.); + ccdQuatSetAngleAxis(&cyl.quat, M_PI / 3., &axis); + ccdVec3Set(&cyl.pos, .6, 0.6, 0.5); + res = ccdGJKIntersect(&box, &cyl, &ccd); + assertTrue(res); + + ccdVec3Set(&axis, 0.67, 1.1, 0.12); + ccdQuatSetAngleAxis(&cyl.quat, M_PI / 4., &axis); + ccdVec3Set(&cyl.pos, .6, 0., 0.5); + res = ccdGJKIntersect(&box, &cyl, &ccd); + assertTrue(res); + + ccdVec3Set(&axis, -0.1, 2.2, -1.); + ccdQuatSetAngleAxis(&cyl.quat, M_PI / 5., &axis); + ccdVec3Set(&cyl.pos, .6, 0., 0.5); + ccdVec3Set(&axis, 1., 1., 0.); + ccdQuatSetAngleAxis(&box.quat, -M_PI / 4., &axis); + ccdVec3Set(&box.pos, .6, 0., 0.5); + res = ccdGJKIntersect(&box, &cyl, &ccd); + assertTrue(res); + + ccdVec3Set(&axis, -0.1, 2.2, -1.); + ccdQuatSetAngleAxis(&cyl.quat, M_PI / 5., &axis); + ccdVec3Set(&cyl.pos, .6, 0., 0.5); + ccdVec3Set(&axis, 1., 1., 0.); + ccdQuatSetAngleAxis(&box.quat, -M_PI / 4., &axis); + ccdVec3Set(&box.pos, .9, 0.8, 0.5); + res = ccdGJKIntersect(&box, &cyl, &ccd); + assertTrue(res); +} + + +TEST(boxcylPenEPA) +{ + ccd_t ccd; + CCD_BOX(box); + CCD_CYL(cyl); + int res; + ccd_vec3_t axis; + ccd_real_t depth; + ccd_vec3_t dir, pos; + + box.x = 0.5; + box.y = 1.; + box.z = 1.5; + cyl.radius = 0.4; + cyl.height = 0.7; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + + ccdVec3Set(&cyl.pos, 0.1, 0., 0.); + res = ccdGJKPenetration(&box, &cyl, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 1"); + //TOSVT(); + + ccdVec3Set(&cyl.pos, .6, 0., 0.); + res = ccdGJKPenetration(&box, &cyl, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 2"); + //TOSVT(); <<< + + ccdVec3Set(&cyl.pos, .6, 0.6, 0.); + res = ccdGJKPenetration(&box, &cyl, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 3"); + //TOSVT(); + + ccdVec3Set(&cyl.pos, .6, 0.6, 0.5); + res = ccdGJKPenetration(&box, &cyl, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 4"); + //TOSVT(); + + ccdVec3Set(&axis, 0., 1., 0.); + ccdQuatSetAngleAxis(&cyl.quat, M_PI / 3., &axis); + ccdVec3Set(&cyl.pos, .6, 0.6, 0.5); + res = ccdGJKPenetration(&box, &cyl, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 5"); + //TOSVT(); + + ccdVec3Set(&axis, 0.67, 1.1, 0.12); + ccdQuatSetAngleAxis(&cyl.quat, M_PI / 4., &axis); + ccdVec3Set(&cyl.pos, .6, 0., 0.5); + res = ccdGJKPenetration(&box, &cyl, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 6"); + //TOSVT(); + + ccdVec3Set(&axis, -0.1, 2.2, -1.); + ccdQuatSetAngleAxis(&cyl.quat, M_PI / 5., &axis); + ccdVec3Set(&cyl.pos, .6, 0., 0.5); + ccdVec3Set(&axis, 1., 1., 0.); + ccdQuatSetAngleAxis(&box.quat, -M_PI / 4., &axis); + ccdVec3Set(&box.pos, .6, 0., 0.5); + res = ccdGJKPenetration(&box, &cyl, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 7"); + //TOSVT(); + + ccdVec3Set(&axis, -0.1, 2.2, -1.); + ccdQuatSetAngleAxis(&cyl.quat, M_PI / 5., &axis); + ccdVec3Set(&cyl.pos, .6, 0., 0.5); + ccdVec3Set(&axis, 1., 1., 0.); + ccdQuatSetAngleAxis(&box.quat, -M_PI / 4., &axis); + ccdVec3Set(&box.pos, .9, 0.8, 0.5); + res = ccdGJKPenetration(&box, &cyl, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 8"); + //TOSVT(); +} + diff --git a/libs/ode-0.16.1/libccd/src/testsuites/boxcyl.h b/libs/ode-0.16.1/libccd/src/testsuites/boxcyl.h new file mode 100644 index 0000000..3d348d9 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/boxcyl.h @@ -0,0 +1,16 @@ +#ifndef TEST_BOXCYL_H +#define TEST_BOXCYL_H + +#include <cu/cu.h> + +TEST(boxcylIntersect); +TEST(boxcylPenEPA); + +TEST_SUITE(TSBoxCyl){ + TEST_ADD(boxcylIntersect), + TEST_ADD(boxcylPenEPA), + + TEST_SUITE_CLOSURE +}; + +#endif diff --git a/libs/ode-0.16.1/libccd/src/testsuites/common.c b/libs/ode-0.16.1/libccd/src/testsuites/common.c new file mode 100644 index 0000000..eca7776 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/common.c @@ -0,0 +1,174 @@ +#include "common.h" +#include <ccd/vec3.h> +#include <ccd/quat.h> +#include "support.h" + +static void svtCyl(ccd_cyl_t *c, FILE *out, const char *color, const char *name) +{ + ccd_vec3_t v[32]; + ccd_quat_t rot; + ccd_vec3_t axis, vpos, vpos2; + ccd_real_t angle, x, y; + unsigned int i; + + ccdVec3Set(&axis, 0., 0., 1.); + ccdVec3Set(&vpos, 0., c->radius, 0.); + angle = 0.; + for (i = 0; i < 16; i++){ + angle = (ccd_real_t)i * (2. * M_PI / 16.); + + ccdQuatSetAngleAxis(&rot, angle, &axis); + ccdVec3Copy(&vpos2, &vpos); + ccdQuatRotVec(&vpos2, &rot); + x = ccdVec3X(&vpos2); + y = ccdVec3Y(&vpos2); + + ccdVec3Set(&v[i], x, y, c->height / 2.); + ccdVec3Set(&v[i + 16], x, y, -c->height / 2.); + } + + for (i = 0; i < 32; i++){ + ccdQuatRotVec(&v[i], &c->quat); + ccdVec3Add(&v[i], &c->pos); + } + + fprintf(out, "-----\n"); + if (name) + fprintf(out, "Name: %s\n", name); + + fprintf(out, "Face color: %s\n", color); + fprintf(out, "Edge color: %s\n", color); + fprintf(out, "Point color: %s\n", color); + fprintf(out, "Points:\n"); + for (i = 0; i < 32; i++){ + fprintf(out, "%lf %lf %lf\n", ccdVec3X(&v[i]), ccdVec3Y(&v[i]), ccdVec3Z(&v[i])); + } + + fprintf(out, "Edges:\n"); + fprintf(out, "0 16\n"); + fprintf(out, "0 31\n"); + for (i = 1; i < 16; i++){ + fprintf(out, "0 %d\n", i); + fprintf(out, "16 %d\n", i + 16); + if (i != 0){ + fprintf(out, "%d %d\n", i - 1, i); + fprintf(out, "%d %d\n", i + 16 - 1, i + 16); + } + + fprintf(out, "%d %d\n", i, i + 16); + fprintf(out, "%d %d\n", i, i + 16 - 1); + } + + fprintf(out, "Faces:\n"); + for (i = 2; i < 16; i++){ + fprintf(out, "0 %d %d\n", i, i -1); + fprintf(out, "16 %d %d\n", i + 16, i + 16 -1); + + } + fprintf(out, "0 16 31\n"); + fprintf(out, "0 31 15\n"); + for (i = 1; i < 16; i++){ + fprintf(out, "%d %d %d\n", i, i + 16, i + 16 - 1); + fprintf(out, "%d %d %d\n", i, i + 16 - 1, i - 1); + } + fprintf(out, "-----\n"); +} + +static void svtBox(ccd_box_t *b, FILE *out, const char *color, const char *name) +{ + ccd_vec3_t v[8]; + size_t i; + + ccdVec3Set(&v[0], b->x * 0.5, b->y * 0.5, b->z * 0.5); + ccdVec3Set(&v[1], b->x * 0.5, b->y * -0.5, b->z * 0.5); + ccdVec3Set(&v[2], b->x * 0.5, b->y * 0.5, b->z * -0.5); + ccdVec3Set(&v[3], b->x * 0.5, b->y * -0.5, b->z * -0.5); + ccdVec3Set(&v[4], b->x * -0.5, b->y * 0.5, b->z * 0.5); + ccdVec3Set(&v[5], b->x * -0.5, b->y * -0.5, b->z * 0.5); + ccdVec3Set(&v[6], b->x * -0.5, b->y * 0.5, b->z * -0.5); + ccdVec3Set(&v[7], b->x * -0.5, b->y * -0.5, b->z * -0.5); + + for (i = 0; i < 8; i++){ + ccdQuatRotVec(&v[i], &b->quat); + ccdVec3Add(&v[i], &b->pos); + } + + fprintf(out, "-----\n"); + if (name) + fprintf(out, "Name: %s\n", name); + fprintf(out, "Face color: %s\n", color); + fprintf(out, "Edge color: %s\n", color); + fprintf(out, "Point color: %s\n", color); + fprintf(out, "Points:\n"); + for (i = 0; i < 8; i++){ + fprintf(out, "%lf %lf %lf\n", ccdVec3X(&v[i]), ccdVec3Y(&v[i]), ccdVec3Z(&v[i])); + } + + fprintf(out, "Edges:\n"); + fprintf(out, "0 1\n 0 2\n2 3\n3 1\n1 2\n6 2\n1 7\n1 5\n"); + fprintf(out, "5 0\n0 4\n4 2\n6 4\n6 5\n5 7\n6 7\n7 2\n7 3\n4 5\n"); + + fprintf(out, "Faces:\n"); + fprintf(out, "0 2 1\n1 2 3\n6 2 4\n4 2 0\n4 0 5\n5 0 1\n"); + fprintf(out, "5 1 7\n7 1 3\n6 4 5\n6 5 7\n2 6 7\n2 7 3\n"); + fprintf(out, "-----\n"); +} + + +void svtObj(void *_o, FILE *out, const char *color, const char *name) +{ + ccd_obj_t *o = (ccd_obj_t *)_o; + + if (o->type == CCD_OBJ_CYL){ + svtCyl((ccd_cyl_t *)o, out, color, name); + }else if (o->type == CCD_OBJ_BOX){ + svtBox((ccd_box_t *)o, out, color, name); + } +} + +void svtObjPen(void *o1, void *o2, + FILE *out, const char *name, + ccd_real_t depth, const ccd_vec3_t *dir, const ccd_vec3_t *pos) +{ + ccd_vec3_t sep; + char oname[500]; + + ccdVec3Copy(&sep, dir); + ccdVec3Scale(&sep, depth); + ccdVec3Add(&sep, pos); + + fprintf(out, "------\n"); + if (name) + fprintf(out, "Name: %s\n", name); + fprintf(out, "Point color: 0.1 0.1 0.9\n"); + fprintf(out, "Points:\n%lf %lf %lf\n", ccdVec3X(pos), ccdVec3Y(pos), ccdVec3Z(pos)); + fprintf(out, "------\n"); + fprintf(out, "Point color: 0.1 0.9 0.9\n"); + fprintf(out, "Edge color: 0.1 0.9 0.9\n"); + fprintf(out, "Points:\n%lf %lf %lf\n", ccdVec3X(pos), ccdVec3Y(pos), ccdVec3Z(pos)); + fprintf(out, "%lf %lf %lf\n", ccdVec3X(&sep), ccdVec3Y(&sep), ccdVec3Z(&sep)); + fprintf(out, "Edges: 0 1\n"); + + oname[0] = 0x0; + if (name) + sprintf(oname, "%s o1", name); + svtObj(o1, out, "0.9 0.1 0.1", oname); + + oname[0] = 0x0; + if (name) + sprintf(oname, "%s o1", name); + svtObj(o2, out, "0.1 0.9 0.1", oname); +} + + +void recPen(ccd_real_t depth, const ccd_vec3_t *dir, const ccd_vec3_t *pos, + FILE *out, const char *note) +{ + if (!note) + note = ""; + + fprintf(out, "# %s: depth: %lf\n", note, depth); + fprintf(out, "# %s: dir: [%lf %lf %lf]\n", note, ccdVec3X(dir), ccdVec3Y(dir), ccdVec3Z(dir)); + fprintf(out, "# %s: pos: [%lf %lf %lf]\n", note, ccdVec3X(pos), ccdVec3Y(pos), ccdVec3Z(pos)); + fprintf(out, "#\n"); +} diff --git a/libs/ode-0.16.1/libccd/src/testsuites/common.h b/libs/ode-0.16.1/libccd/src/testsuites/common.h new file mode 100644 index 0000000..a4de4c2 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/common.h @@ -0,0 +1,14 @@ +#ifndef TEST_COMMON +#define TEST_COMMON + +#include <stdio.h> +#include <ccd/vec3.h> + +void svtObj(void *o, FILE *out, const char *color, const char *name); +void svtObjPen(void *o1, void *o2, + FILE *out, const char *name, + ccd_real_t depth, const ccd_vec3_t *dir, const ccd_vec3_t *pos); +void recPen(ccd_real_t depth, const ccd_vec3_t *dir, const ccd_vec3_t *pos, + FILE *out, const char *note); + +#endif diff --git a/libs/ode-0.16.1/libccd/src/testsuites/cu/COPYING b/libs/ode-0.16.1/libccd/src/testsuites/cu/COPYING new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/cu/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + 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 <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/libs/ode-0.16.1/libccd/src/testsuites/cu/COPYING.LESSER b/libs/ode-0.16.1/libccd/src/testsuites/cu/COPYING.LESSER new file mode 100644 index 0000000..fc8a5de --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/cu/COPYING.LESSER @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/libs/ode-0.16.1/libccd/src/testsuites/cu/Makefile.am b/libs/ode-0.16.1/libccd/src/testsuites/cu/Makefile.am new file mode 100644 index 0000000..66d6daf --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/cu/Makefile.am @@ -0,0 +1,6 @@ +AM_CPPFLAGS = -DCU_ENABLE_TIMER + +check_LTLIBRARIES = libcu.la + +libcu_la_SOURCES = cu.c cu.h + diff --git a/libs/ode-0.16.1/libccd/src/testsuites/cu/Makefile.in b/libs/ode-0.16.1/libccd/src/testsuites/cu/Makefile.in new file mode 100644 index 0000000..6c6a3a0 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/cu/Makefile.in @@ -0,0 +1,587 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/testsuites/cu +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +libcu_la_LIBADD = +am_libcu_la_OBJECTS = cu.lo +libcu_la_OBJECTS = $(am_libcu_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src +depcomp = $(SHELL) $(top_srcdir)/../depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libcu_la_SOURCES) +DIST_SOURCES = $(libcu_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/../depcomp \ + COPYING COPYING.LESSER +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_PRECISION = @CCD_PRECISION@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = -DCU_ENABLE_TIMER +check_LTLIBRARIES = libcu.la +libcu_la_SOURCES = cu.c cu.h +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/testsuites/cu/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/testsuites/cu/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkLTLIBRARIES: + -test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES) + @list='$(check_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libcu.la: $(libcu_la_OBJECTS) $(libcu_la_DEPENDENCIES) $(EXTRA_libcu_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libcu_la_OBJECTS) $(libcu_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cu.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_LTLIBRARIES) +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkLTLIBRARIES clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ + clean-checkLTLIBRARIES clean-generic clean-libtool \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/libccd/src/testsuites/cu/cu.c b/libs/ode-0.16.1/libccd/src/testsuites/cu/cu.c new file mode 100644 index 0000000..7449b4b --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/cu/cu.c @@ -0,0 +1,387 @@ +/*** + * CU - C unit testing framework + * --------------------------------- + * Copyright (c)2007,2008,2009 Daniel Fiser <danfis@danfis.cz> + * + * + * This file is part of CU. + * + * CU is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * CU 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <sys/wait.h> + +#include "cu.h" + +/** Declared here, because I didn't find header file where it is declared */ +char *strsignal(int sig); + +const char *cu_current_test; +const char *cu_current_test_suite; +int cu_success_test_suites = 0; +int cu_fail_test_suites = 0; +int cu_success_tests = 0; +int cu_fail_tests = 0; +int cu_success_checks = 0; +int cu_fail_checks = 0; + +char cu_out_prefix[CU_OUT_PREFIX_LENGTH+1] = ""; + + +/* globally used file descriptor for reading/writing messages */ +int fd; + +/* indicate if test was failed */ +int test_failed; + +/* codes of messages */ +#define CHECK_FAILED '0' +#define CHECK_SUCCEED '1' +#define TEST_FAILED '2' +#define TEST_SUCCEED '3' +#define TEST_SUITE_FAILED '4' +#define TEST_SUITE_SUCCEED '5' +#define END '6' +#define TEST_NAME '7' + +/* predefined messages */ +#define MSG_CHECK_SUCCEED write(fd, "1\n", 2) +#define MSG_TEST_FAILED write(fd, "2\n", 2) +#define MSG_TEST_SUCCEED write(fd, "3\n", 2) +#define MSG_TEST_SUITE_FAILED write(fd, "4\n", 2) +#define MSG_TEST_SUITE_SUCCEED write(fd, "5\n", 2) +#define MSG_END write(fd, "6\n", 2) + +/* length of buffers */ +#define BUF_LEN 1000 +#define MSGBUF_LEN 300 + + +static void redirect_out_err(const char *testName); +static void close_out_err(void); +static void run_test_suite(const char *ts_name, cu_test_suite_t *ts); +static void receive_messages(void); + +static void cu_run_fork(const char *ts_name, cu_test_suite_t *test_suite); +static void cu_print_results(void); + +void cu_run(int argc, char *argv[]) +{ + cu_test_suites_t *tss; + int i; + char found = 0; + + if (argc > 1){ + for (i=1; i < argc; i++){ + tss = cu_test_suites; + while (tss->name != NULL && tss->test_suite != NULL){ + if (strcmp(argv[i], tss->name) == 0){ + found = 1; + cu_run_fork(tss->name, tss->test_suite); + break; + } + tss++; + } + + if (tss->name == NULL || tss->test_suite == NULL){ + fprintf(stderr, "ERROR: Could not find test suite '%s'\n", argv[i]); + } + } + + if (found == 1) + cu_print_results(); + + }else{ + tss = cu_test_suites; + while (tss->name != NULL && tss->test_suite != NULL){ + cu_run_fork(tss->name, tss->test_suite); + tss++; + } + cu_print_results(); + } + + +} + +static void cu_run_fork(const char *ts_name, cu_test_suite_t *ts) +{ + int pipefd[2]; + int pid; + int status; + + if (pipe(pipefd) == -1){ + perror("Pipe error"); + exit(-1); + } + + fprintf(stdout, " -> %s [IN PROGESS]\n", ts_name); + fflush(stdout); + + pid = fork(); + if (pid < 0){ + perror("Fork error"); + exit(-1); + } + + if (pid == 0){ + /* close read end of pipe */ + close(pipefd[0]); + + fd = pipefd[1]; + + /* run testsuite, messages go to fd */ + run_test_suite(ts_name, ts); + + MSG_END; + close(fd); + + /* stop process where running testsuite */ + exit(0); + }else{ + /* close write end of pipe */ + close(pipefd[1]); + + fd = pipefd[0]; + + /* receive and interpret all messages */ + receive_messages(); + + /* wait for children */ + wait(&status); + if (!WIFEXITED(status)){ /* if child process ends up abnormaly */ + if (WIFSIGNALED(status)){ + fprintf(stdout, "Test suite was terminated by signal %d (%s).\n", + WTERMSIG(status), strsignal(WTERMSIG(status))); + }else{ + fprintf(stdout, "Test suite terminated abnormaly!\n"); + } + + /* mark this test suite as failed, because was terminated + * prematurely */ + cu_fail_test_suites++; + } + + close(fd); + + fprintf(stdout, " -> %s [DONE]\n\n", ts_name); + fflush(stdout); + } + +} + +static void run_test_suite(const char *ts_name, cu_test_suite_t *ts) +{ + int test_suite_failed = 0; + char buffer[MSGBUF_LEN]; + int len; + + /* set up current test suite name for later messaging... */ + cu_current_test_suite = ts_name; + + /* redirect stdout and stderr */ + redirect_out_err(cu_current_test_suite); + + while (ts->name != NULL && ts->func != NULL){ + test_failed = 0; + + /* set up name of test for later messaging */ + cu_current_test = ts->name; + + /* send message what test is currently running */ + len = snprintf(buffer, MSGBUF_LEN, "%c --> Running %s...\n", + TEST_NAME, cu_current_test); + write(fd, buffer, len); + + /* run test */ + (*(ts->func))(); + + if (test_failed){ + MSG_TEST_FAILED; + test_suite_failed = 1; + }else{ + MSG_TEST_SUCCEED; + } + + ts++; /* next test in test suite */ + } + + if (test_suite_failed){ + MSG_TEST_SUITE_FAILED; + }else{ + MSG_TEST_SUITE_SUCCEED; + } + + /* close redirected stdout and stderr */ + close_out_err(); +} + + +static void receive_messages(void) +{ + char buf[BUF_LEN]; /* buffer */ + int buf_len; /* how many chars stored in buf */ + char bufout[MSGBUF_LEN]; /* buffer which can be printed out */ + int bufout_len; + int state = 0; /* 0 - waiting for code, 1 - copy msg to stdout */ + int i; + int end = 0; /* end of messages? */ + + bufout_len = 0; + while((buf_len = read(fd, buf, BUF_LEN)) > 0 && !end){ + for (i=0; i < buf_len; i++){ + + /* Prepare message for printing out */ + if (state == 1 || state == 2){ + if (bufout_len < MSGBUF_LEN) + bufout[bufout_len++] = buf[i]; + } + + /* reset state on '\n' in msg */ + if (buf[i] == '\n'){ + /* copy messages out */ + if (state == 1) + write(1, bufout, bufout_len); + if (state == 2) + write(2, bufout, bufout_len); + + state = 0; + bufout_len = 0; + continue; + } + + if (state == 0){ + if (buf[i] == CHECK_FAILED){ + cu_fail_checks++; + state = 2; + }else if (buf[i] == TEST_NAME){ + state = 1; + }else if (buf[i] == CHECK_SUCCEED){ + cu_success_checks++; + }else if (buf[i] == TEST_FAILED){ + cu_fail_tests++; + }else if (buf[i] == TEST_SUCCEED){ + cu_success_tests++; + }else if (buf[i] == TEST_SUITE_FAILED){ + cu_fail_test_suites++; + }else if (buf[i] == TEST_SUITE_SUCCEED){ + cu_success_test_suites++; + }else if (buf[i] == END){ + end = 1; + break; + } + } + } + } +} + +void cu_success_assertation(void) +{ + MSG_CHECK_SUCCEED; +} + +void cu_fail_assertation(const char *file, int line, const char *msg) +{ + char buf[MSGBUF_LEN]; + int len; + + len = snprintf(buf, MSGBUF_LEN, "%c%s:%d (%s::%s) :: %s\n", + CHECK_FAILED, + file, line, cu_current_test_suite, cu_current_test, msg); + write(fd, buf, len); + + /* enable test_failed flag */ + test_failed = 1; +} + +static void cu_print_results(void) +{ + fprintf(stdout, "\n"); + fprintf(stdout, "==================================================\n"); + fprintf(stdout, "| | failed | succeed | total |\n"); + fprintf(stdout, "|------------------------------------------------|\n"); + fprintf(stdout, "| assertations: | %6d | %7d | %5d |\n", + cu_fail_checks, cu_success_checks, + cu_success_checks+cu_fail_checks); + fprintf(stdout, "| tests: | %6d | %7d | %5d |\n", + cu_fail_tests, cu_success_tests, + cu_success_tests+cu_fail_tests); + fprintf(stdout, "| tests suites: | %6d | %7d | %5d |\n", + cu_fail_test_suites, cu_success_test_suites, + cu_success_test_suites+cu_fail_test_suites); + fprintf(stdout, "==================================================\n"); +} + +void cu_set_out_prefix(const char *str) +{ + strncpy(cu_out_prefix, str, CU_OUT_PREFIX_LENGTH); +} + +static void redirect_out_err(const char *test_name) +{ + char buf[100]; + + snprintf(buf, 99, "%stmp.%s.out", cu_out_prefix, test_name); + if (freopen(buf, "w", stdout) == NULL){ + perror("Redirecting of stdout failed"); + exit(-1); + } + + snprintf(buf, 99, "%stmp.%s.err", cu_out_prefix, test_name); + if (freopen(buf, "w", stderr) == NULL){ + perror("Redirecting of stderr failed"); + exit(-1); + } +} + +static void close_out_err(void) +{ + fclose(stdout); + fclose(stderr); +} + + +#ifdef CU_ENABLE_TIMER +/* global variables for timer functions */ +struct timespec __cu_timer; +static struct timespec __cu_timer_start, __cu_timer_stop; + +const struct timespec *cuTimer(void) +{ + return &__cu_timer; +} + +void cuTimerStart(void) +{ + clock_gettime(CLOCK_MONOTONIC, &__cu_timer_start); +} + +const struct timespec *cuTimerStop(void) +{ + clock_gettime(CLOCK_MONOTONIC, &__cu_timer_stop); + + /* store into t difference between time_start and time_end */ + if (__cu_timer_stop.tv_nsec > __cu_timer_start.tv_nsec){ + __cu_timer.tv_nsec = __cu_timer_stop.tv_nsec - __cu_timer_start.tv_nsec; + __cu_timer.tv_sec = __cu_timer_stop.tv_sec - __cu_timer_start.tv_sec; + }else{ + __cu_timer.tv_nsec = __cu_timer_stop.tv_nsec + 1000000000L - __cu_timer_start.tv_nsec; + __cu_timer.tv_sec = __cu_timer_stop.tv_sec - 1 - __cu_timer_start.tv_sec; + } + + return &__cu_timer; +} +#endif /* CU_ENABLE_TIMER */ diff --git a/libs/ode-0.16.1/libccd/src/testsuites/cu/cu.h b/libs/ode-0.16.1/libccd/src/testsuites/cu/cu.h new file mode 100644 index 0000000..06574cf --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/cu/cu.h @@ -0,0 +1,164 @@ +/*** + * CU - C unit testing framework + * --------------------------------- + * Copyright (c)2007,2008,2009 Daniel Fiser <danfis@danfis.cz> + * + * + * This file is part of CU. + * + * CU is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * CU 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _CU_H_ +#define _CU_H_ + +#ifdef CU_ENABLE_TIMER +# include <time.h> +#endif /* CU_ENABLE_TIMER */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/***** PUBLIC API *****/ +/** + * Define test + */ +#define TEST(name) \ + void name(void) + +/** + * Define testsuite + */ +#define TEST_SUITE(name) \ + cu_test_suite_t test_suite_##name[] = +/** + * Must be on the end of list of tests. + */ +#define TEST_SUITE_CLOSURE \ + { NULL, NULL } + +#define TEST_SUITES \ + cu_test_suites_t cu_test_suites[] = +#define TEST_SUITES_CLOSURE \ + { NULL, NULL } +#define TEST_SUITE_ADD(name) \ + { #name, test_suite_##name } + +/** + * Add test to testsuite + */ +#define TEST_ADD(name) \ + { #name, name } + +#define CU_RUN(argc, argv) \ + cu_run(argc, argv) + +/** + * Set prefix for files printed out. Must contain trailing /. + */ +#define CU_SET_OUT_PREFIX(str) \ + cu_set_out_prefix(str) + +/** + * Assertations + * Assertations with suffix 'M' (e.g. assertTrueM) is variation of macro + * where is possible to specify error message. + */ +#define assertTrueM(a, message) \ + if (a){ \ + cu_success_assertation(); \ + }else{ \ + cu_fail_assertation(__FILE__, __LINE__, message); \ + } +#define assertTrue(a) \ + assertTrueM((a), #a " is not true") + +#define assertFalseM(a, message) \ + assertTrueM(!(a), message) +#define assertFalse(a) \ + assertFalseM((a), #a " is not false") + +#define assertEqualsM(a,b,message) \ + assertTrueM((a) == (b), message) +#define assertEquals(a,b) \ + assertEqualsM((a), (b), #a " not equals " #b) + +#define assertNotEqualsM(a,b,message) \ + assertTrueM((a) != (b), message) +#define assertNotEquals(a,b) \ + assertNotEqualsM((a), (b), #a " equals " #b) +/***** PUBLIC API END *****/ + + +#include <unistd.h> + +#define CU_MAX_NAME_LENGTH 30 + +typedef void (*cu_test_func_t)(void); +typedef struct _cu_test_suite_t { + const char *name; + cu_test_func_t func; +} cu_test_suite_t; +typedef struct _cu_test_suites_t { + const char *name; + cu_test_suite_t *test_suite; +} cu_test_suites_t; + +extern cu_test_suites_t cu_test_suites[]; + +extern const char *cu_current_test; +extern const char *cu_current_test_suite; + +extern int cu_success_test_suites; +extern int cu_fail_test_suites; +extern int cu_success_tests; +extern int cu_fail_tests; +extern int cu_success_checks; +extern int cu_fail_checks; + +#define CU_OUT_PREFIX_LENGTH 30 +extern char cu_out_prefix[CU_OUT_PREFIX_LENGTH+1]; + +void cu_run(int argc, char *argv[]); +void cu_success_assertation(void); +void cu_fail_assertation(const char *file, int line, const char *msg); +void cu_set_out_prefix(const char *str); + +/** Timer **/ +#ifdef CU_ENABLE_TIMER +extern struct timespec __cu_timer; + +/** + * Returns value of timer. (as timespec struct) + */ +const struct timespec *cuTimer(void); + +/** + * Starts timer. + */ +void cuTimerStart(void); + +/** + * Stops timer and record elapsed time from last call of cuTimerStart(). + * Returns current value of timer. + */ +const struct timespec *cuTimerStop(void); +#endif /* CU_ENABLE_TIMER */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/libs/ode-0.16.1/libccd/src/testsuites/cylcyl.c b/libs/ode-0.16.1/libccd/src/testsuites/cylcyl.c new file mode 100644 index 0000000..6cd2124 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/cylcyl.c @@ -0,0 +1,180 @@ +#include <stdio.h> +#include <cu/cu.h> +#include <ccd/ccd.h> +#include "support.h" +#include "common.h" + + +TEST(cylcylSetUp) +{ +} + +TEST(cylcylTearDown) +{ +} + + +TEST(cylcylAlignedX) +{ + ccd_t ccd; + CCD_CYL(c1); + CCD_CYL(c2); + size_t i; + int res; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + + c1.radius = 0.35; + c1.height = 0.5; + c2.radius = 0.5; + c2.height = 1.; + + ccdVec3Set(&c1.pos, -5., 0., 0.); + for (i = 0; i < 100; i++){ + res = ccdGJKIntersect(&c1, &c2, &ccd); + + if (i < 42 || i > 58){ + assertFalse(res); + }else{ + assertTrue(res); + } + + c1.pos.v[0] += 0.1; + } +} + +TEST(cylcylAlignedY) +{ + ccd_t ccd; + CCD_CYL(c1); + CCD_CYL(c2); + size_t i; + int res; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + + c1.radius = 0.35; + c1.height = 0.5; + c2.radius = 0.5; + c2.height = 1.; + + ccdVec3Set(&c1.pos, 0., -5., 0.); + for (i = 0; i < 100; i++){ + res = ccdGJKIntersect(&c1, &c2, &ccd); + + if (i < 42 || i > 58){ + assertFalse(res); + }else{ + assertTrue(res); + } + + c1.pos.v[1] += 0.1; + } +} + +TEST(cylcylAlignedZ) +{ + ccd_t ccd; + CCD_CYL(c1); + CCD_CYL(c2); + size_t i; + int res; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + + c1.radius = 0.35; + c1.height = 0.5; + c2.radius = 0.5; + c2.height = 1.; + + ccdVec3Set(&c1.pos, 0., 0., -5.); + for (i = 0; i < 100; i++){ + res = ccdGJKIntersect(&c1, &c2, &ccd); + + if (i < 43 || i > 57){ + assertFalse(res); + }else{ + assertTrue(res); + } + + c1.pos.v[2] += 0.1; + } +} + +#define TOSVT() \ + svtObjPen(&cyl1, &cyl2, stdout, "Pen 1", depth, &dir, &pos); \ + ccdVec3Scale(&dir, depth); \ + ccdVec3Add(&cyl2.pos, &dir); \ + svtObjPen(&cyl1, &cyl2, stdout, "Pen 1", depth, &dir, &pos) + +TEST(cylcylPenetrationEPA) +{ + ccd_t ccd; + CCD_CYL(cyl1); + CCD_CYL(cyl2); + int res; + ccd_vec3_t axis; + ccd_real_t depth; + ccd_vec3_t dir, pos; + + fprintf(stderr, "\n\n\n---- cylcylPenetration ----\n\n\n"); + + cyl1.radius = 0.35; + cyl1.height = 0.5; + cyl2.radius = 0.5; + cyl2.height = 1.; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + + ccdVec3Set(&cyl2.pos, 0., 0., 0.3); + res = ccdGJKPenetration(&cyl1, &cyl2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 1"); + //TOSVT(); + + ccdVec3Set(&cyl1.pos, 0.3, 0.1, 0.1); + res = ccdGJKPenetration(&cyl1, &cyl2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 2"); + //TOSVT(); <<< + + ccdVec3Set(&axis, 0., 1., 1.); + ccdQuatSetAngleAxis(&cyl2.quat, M_PI / 4., &axis); + ccdVec3Set(&cyl2.pos, 0., 0., 0.); + res = ccdGJKPenetration(&cyl1, &cyl2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 3"); + //TOSVT(); + + ccdVec3Set(&axis, 0., 1., 1.); + ccdQuatSetAngleAxis(&cyl2.quat, M_PI / 4., &axis); + ccdVec3Set(&cyl2.pos, -0.2, 0.7, 0.2); + res = ccdGJKPenetration(&cyl1, &cyl2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 4"); + //TOSVT(); + + ccdVec3Set(&axis, 0.567, 1.2, 1.); + ccdQuatSetAngleAxis(&cyl2.quat, M_PI / 4., &axis); + ccdVec3Set(&cyl2.pos, 0.6, -0.7, 0.2); + res = ccdGJKPenetration(&cyl1, &cyl2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 5"); + //TOSVT(); + + ccdVec3Set(&axis, -4.567, 1.2, 0.); + ccdQuatSetAngleAxis(&cyl2.quat, M_PI / 3., &axis); + ccdVec3Set(&cyl2.pos, 0.6, -0.7, 0.2); + res = ccdGJKPenetration(&cyl1, &cyl2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 6"); + //TOSVT(); +} diff --git a/libs/ode-0.16.1/libccd/src/testsuites/cylcyl.h b/libs/ode-0.16.1/libccd/src/testsuites/cylcyl.h new file mode 100644 index 0000000..8cbbe07 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/cylcyl.h @@ -0,0 +1,29 @@ +#ifndef CYL_CYL +#define CYL_CYL + +#include <cu/cu.h> + +TEST(cylcylSetUp); +TEST(cylcylTearDown); + +TEST(cylcylAlignedX); +TEST(cylcylAlignedY); +TEST(cylcylAlignedZ); + +TEST(cylcylPenetrationEPA); + +TEST_SUITE(TSCylCyl) { + TEST_ADD(cylcylSetUp), + + TEST_ADD(cylcylAlignedX), + TEST_ADD(cylcylAlignedY), + TEST_ADD(cylcylAlignedZ), + + TEST_ADD(cylcylPenetrationEPA), + + TEST_ADD(cylcylTearDown), + TEST_SUITE_CLOSURE +}; + +#endif + diff --git a/libs/ode-0.16.1/libccd/src/testsuites/main.c b/libs/ode-0.16.1/libccd/src/testsuites/main.c new file mode 100644 index 0000000..a4585b0 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/main.c @@ -0,0 +1,32 @@ +#include "vec3.h" +#include "polytope.h" +#include "boxbox.h" +#include "spheresphere.h" +#include "cylcyl.h" +#include "boxcyl.h" + +#include "mpr_boxbox.h" +#include "mpr_cylcyl.h" +#include "mpr_boxcyl.h" + +TEST_SUITES { + TEST_SUITE_ADD(TSVec3), + TEST_SUITE_ADD(TSPt), + TEST_SUITE_ADD(TSBoxBox), + TEST_SUITE_ADD(TSSphereSphere), + TEST_SUITE_ADD(TSCylCyl), + TEST_SUITE_ADD(TSBoxCyl), + + TEST_SUITE_ADD(TSMPRBoxBox), + TEST_SUITE_ADD(TSMPRCylCyl), + TEST_SUITE_ADD(TSMPRBoxCyl), + + TEST_SUITES_CLOSURE +}; +int main(int argc, char *argv[]) +{ + CU_SET_OUT_PREFIX("regressions/"); + CU_RUN(argc, argv); + + return 0; +} diff --git a/libs/ode-0.16.1/libccd/src/testsuites/mpr_boxbox.c b/libs/ode-0.16.1/libccd/src/testsuites/mpr_boxbox.c new file mode 100644 index 0000000..2342850 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/mpr_boxbox.c @@ -0,0 +1,500 @@ +#include <stdio.h> +#include <cu/cu.h> + +#include <ccd/ccd.h> +#include "support.h" +#include <ccd/vec3.h> +#include <ccd/dbg.h> +#include "common.h" + + +TEST(mprBoxboxAlignedX) +{ + size_t i; + ccd_t ccd; + CCD_BOX(box1); + CCD_BOX(box2); + int res; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + ccd.center1 = ccdObjCenter; + ccd.center2 = ccdObjCenter; + + box1.x = 1; + box1.y = 2; + box1.z = 1; + box2.x = 2; + box2.y = 1; + box2.z = 2; + + ccdVec3Set(&box1.pos, -5., 0., 0.); + ccdVec3Set(&box2.pos, 0., 0., 0.); + ccdQuatSet(&box1.quat, 0., 0., 0., 1.); + ccdQuatSet(&box2.quat, 0., 0., 0., 1.); + for (i = 0; i < 100; i++){ + res = ccdMPRIntersect(&box1, &box2, &ccd); + if (i < 35 || i > 65){ + assertFalse(res); + }else if (i != 35 && i != 65){ + assertTrue(res); + } + + box1.pos.v[0] += 0.1; + } + + box1.x = 0.1; + box1.y = 0.2; + box1.z = 0.1; + box2.x = 0.2; + box2.y = 0.1; + box2.z = 0.2; + + ccdVec3Set(&box1.pos, -0.5, 0., 0.); + ccdVec3Set(&box2.pos, 0., 0., 0.); + ccdQuatSet(&box1.quat, 0., 0., 0., 1.); + ccdQuatSet(&box2.quat, 0., 0., 0., 1.); + for (i = 0; i < 100; i++){ + res = ccdMPRIntersect(&box1, &box2, &ccd); + + if (i < 35 || i > 65){ + assertFalse(res); + }else if (i != 35 && i != 65){ + assertTrue(res); + } + + box1.pos.v[0] += 0.01; + } + + + box1.x = 1; + box1.y = 2; + box1.z = 1; + box2.x = 2; + box2.y = 1; + box2.z = 2; + + ccdVec3Set(&box1.pos, -5., -0.1, 0.); + ccdVec3Set(&box2.pos, 0., 0., 0.); + ccdQuatSet(&box1.quat, 0., 0., 0., 1.); + ccdQuatSet(&box2.quat, 0., 0., 0., 1.); + for (i = 0; i < 100; i++){ + res = ccdMPRIntersect(&box1, &box2, &ccd); + + if (i < 35 || i > 65){ + assertFalse(res); + }else if (i != 35 && i != 65){ + assertTrue(res); + } + + box1.pos.v[0] += 0.1; + } +} + +TEST(mprBoxboxAlignedY) +{ + size_t i; + ccd_t ccd; + CCD_BOX(box1); + CCD_BOX(box2); + int res; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + ccd.center1 = ccdObjCenter; + ccd.center2 = ccdObjCenter; + + box1.x = 1; + box1.y = 2; + box1.z = 1; + box2.x = 2; + box2.y = 1; + box2.z = 2; + + ccdVec3Set(&box1.pos, 0., -5., 0.); + ccdVec3Set(&box2.pos, 0., 0., 0.); + ccdQuatSet(&box1.quat, 0., 0., 0., 1.); + ccdQuatSet(&box2.quat, 0., 0., 0., 1.); + for (i = 0; i < 100; i++){ + res = ccdMPRIntersect(&box1, &box2, &ccd); + + if (i < 35 || i > 65){ + assertFalse(res); + }else if (i != 35 && i != 65){ + assertTrue(res); + } + + box1.pos.v[1] += 0.1; + } +} + +TEST(mprBoxboxAlignedZ) +{ + size_t i; + ccd_t ccd; + CCD_BOX(box1); + CCD_BOX(box2); + int res; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + ccd.center1 = ccdObjCenter; + ccd.center2 = ccdObjCenter; + + box1.x = 1; + box1.y = 2; + box1.z = 1; + box2.x = 2; + box2.y = 1; + box2.z = 2; + + ccdVec3Set(&box1.pos, 0., 0., -5.); + ccdVec3Set(&box2.pos, 0., 0., 0.); + ccdQuatSet(&box1.quat, 0., 0., 0., 1.); + ccdQuatSet(&box2.quat, 0., 0., 0., 1.); + for (i = 0; i < 100; i++){ + res = ccdMPRIntersect(&box1, &box2, &ccd); + + if (i < 35 || i > 65){ + assertFalse(res); + }else if (i != 35 && i != 65){ + assertTrue(res); + } + + box1.pos.v[2] += 0.1; + } +} + + +TEST(mprBoxboxRot) +{ + size_t i; + ccd_t ccd; + CCD_BOX(box1); + CCD_BOX(box2); + int res; + ccd_vec3_t axis; + ccd_real_t angle; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + ccd.center1 = ccdObjCenter; + ccd.center2 = ccdObjCenter; + + box1.x = 1; + box1.y = 2; + box1.z = 1; + box2.x = 2; + box2.y = 1; + box2.z = 2; + + ccdVec3Set(&box1.pos, -5., 0.5, 0.); + ccdVec3Set(&box2.pos, 0., 0., 0.); + ccdQuatSet(&box2.quat, 0., 0., 0., 1.); + ccdVec3Set(&axis, 0., 1., 0.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + + for (i = 0; i < 100; i++){ + res = ccdMPRIntersect(&box1, &box2, &ccd); + + if (i < 33 || i > 67){ + assertFalse(res); + }else if (i != 33 && i != 67){ + assertTrue(res); + } + + box1.pos.v[0] += 0.1; + } + + box1.x = 1; + box1.y = 1; + box1.z = 1; + box2.x = 1; + box2.y = 1; + box2.z = 1; + + ccdVec3Set(&box1.pos, -1.01, 0., 0.); + ccdVec3Set(&box2.pos, 0., 0., 0.); + ccdQuatSet(&box1.quat, 0., 0., 0., 1.); + ccdQuatSet(&box2.quat, 0., 0., 0., 1.); + + ccdVec3Set(&axis, 0., 1., 0.); + angle = 0.; + for (i = 0; i < 30; i++){ + res = ccdMPRIntersect(&box1, &box2, &ccd); + + if (i != 0 && i != 10 && i != 20){ + assertTrue(res); + }else{ + assertFalse(res); + } + + angle += M_PI / 20.; + ccdQuatSetAngleAxis(&box1.quat, angle, &axis); + } + +} + + + +static void pConf(ccd_box_t *box1, ccd_box_t *box2, const ccd_vec3_t *v) +{ + fprintf(stdout, "# box1.pos: [%lf %lf %lf]\n", + ccdVec3X(&box1->pos), ccdVec3Y(&box1->pos), ccdVec3Z(&box1->pos)); + fprintf(stdout, "# box1->quat: [%lf %lf %lf %lf]\n", + box1->quat.q[0], box1->quat.q[1], box1->quat.q[2], box1->quat.q[3]); + fprintf(stdout, "# box2->pos: [%lf %lf %lf]\n", + ccdVec3X(&box2->pos), ccdVec3Y(&box2->pos), ccdVec3Z(&box2->pos)); + fprintf(stdout, "# box2->quat: [%lf %lf %lf %lf]\n", + box2->quat.q[0], box2->quat.q[1], box2->quat.q[2], box2->quat.q[3]); + fprintf(stdout, "# sep: [%lf %lf %lf]\n", + ccdVec3X(v), ccdVec3Y(v), ccdVec3Z(v)); + fprintf(stdout, "#\n"); +} + +TEST(mprBoxboxSeparate) +{ + ccd_t ccd; + CCD_BOX(box1); + CCD_BOX(box2); + int res; + ccd_vec3_t sep, expsep, expsep2, axis; + + fprintf(stderr, "\n\n\n---- boxboxSeparate ----\n\n\n"); + + box1.x = box1.y = box1.z = 1.; + box2.x = 0.5; + box2.y = 1.; + box2.z = 1.5; + + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + + ccdVec3Set(&box1.pos, -0.5, 0.5, 0.2); + res = ccdMPRIntersect(&box1, &box2, &ccd); + assertTrue(res); + + res = ccdGJKSeparate(&box1, &box2, &ccd, &sep); + assertTrue(res == 0); + ccdVec3Set(&expsep, 0.25, 0., 0.); + assertTrue(ccdVec3Eq(&sep, &expsep)); + + ccdVec3Scale(&sep, -1.); + ccdVec3Add(&box1.pos, &sep); + res = ccdGJKSeparate(&box1, &box2, &ccd, &sep); + assertTrue(res == 0); + ccdVec3Set(&expsep, 0., 0., 0.); + assertTrue(ccdVec3Eq(&sep, &expsep)); + + + ccdVec3Set(&box1.pos, -0.3, 0.5, 1.); + res = ccdGJKSeparate(&box1, &box2, &ccd, &sep); + assertTrue(res == 0); + ccdVec3Set(&expsep, 0., 0., -0.25); + assertTrue(ccdVec3Eq(&sep, &expsep)); + + + + box1.x = box1.y = box1.z = 1.; + box2.x = box2.y = box2.z = 1.; + ccdVec3Set(&axis, 0., 0., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&box1.pos, 0., 0., 0.); + + res = ccdGJKSeparate(&box1, &box2, &ccd, &sep); + assertTrue(res == 0); + ccdVec3Set(&expsep, 0., 0., 1.); + ccdVec3Set(&expsep2, 0., 0., -1.); + assertTrue(ccdVec3Eq(&sep, &expsep) || ccdVec3Eq(&sep, &expsep2)); + + + + box1.x = box1.y = box1.z = 1.; + ccdVec3Set(&axis, 0., 0., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&box1.pos, -0.5, 0., 0.); + + res = ccdGJKSeparate(&box1, &box2, &ccd, &sep); + assertTrue(res == 0); + pConf(&box1, &box2, &sep); + + + + box1.x = box1.y = box1.z = 1.; + ccdVec3Set(&axis, 0., 1., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&box1.pos, -0.5, 0.1, 0.4); + + res = ccdGJKSeparate(&box1, &box2, &ccd, &sep); + assertTrue(res == 0); + pConf(&box1, &box2, &sep); +} + + +#define TOSVT() \ + svtObjPen(&box1, &box2, stdout, "Pen 1", depth, &dir, &pos); \ + ccdVec3Scale(&dir, depth); \ + ccdVec3Add(&box2.pos, &dir); \ + svtObjPen(&box1, &box2, stdout, "Pen 1", depth, &dir, &pos) + +TEST(mprBoxboxPenetration) +{ + ccd_t ccd; + CCD_BOX(box1); + CCD_BOX(box2); + int res; + ccd_vec3_t axis; + ccd_quat_t rot; + ccd_real_t depth; + ccd_vec3_t dir, pos; + + fprintf(stderr, "\n\n\n---- boxboxPenetration ----\n\n\n"); + + box1.x = box1.y = box1.z = 1.; + box2.x = 0.5; + box2.y = 1.; + box2.z = 1.5; + + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + ccd.center1 = ccdObjCenter; + ccd.center2 = ccdObjCenter; + + /* + ccdVec3Set(&box2.pos, 0., 0., 0.); + res = ccdMPRPenetration(&box1, &box2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 1"); + TOSVT(); + */ + + ccdVec3Set(&box2.pos, 0.1, 0., 0.); + res = ccdMPRPenetration(&box1, &box2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 1"); + //TOSVT(); + + + ccdVec3Set(&box1.pos, -0.3, 0.5, 1.); + res = ccdMPRPenetration(&box1, &box2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 2"); + //TOSVT(); + + + box1.x = box1.y = box1.z = 1.; + box2.x = box2.y = box2.z = 1.; + ccdVec3Set(&axis, 0., 0., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&box1.pos, 0.1, 0., 0.1); + + res = ccdMPRPenetration(&box1, &box2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 3"); + //TOSVT(); + + + box1.x = box1.y = box1.z = 1.; + box2.x = box2.y = box2.z = 1.; + ccdVec3Set(&axis, 0., 0., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&box1.pos, -0.5, 0., 0.); + + res = ccdMPRPenetration(&box1, &box2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 4"); + //TOSVT(); + + + box1.x = box1.y = box1.z = 1.; + box2.x = box2.y = box2.z = 1.; + ccdVec3Set(&axis, 0., 0., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&box1.pos, -0.5, 0.5, 0.); + + res = ccdMPRPenetration(&box1, &box2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 5"); + //TOSVT(); + + + box1.x = box1.y = box1.z = 1.; + box2.x = box2.y = box2.z = 1.; + ccdVec3Set(&box2.pos, 0.1, 0., 0.); + + box1.x = box1.y = box1.z = 1.; + ccdVec3Set(&axis, 0., 1., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&box1.pos, -0.5, 0.1, 0.4); + + res = ccdMPRPenetration(&box1, &box2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 6"); + //TOSVT(); + + + box1.x = box1.y = box1.z = 1.; + ccdVec3Set(&axis, 0., 1., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&axis, 1., 1., 1.); + ccdQuatSetAngleAxis(&rot, M_PI / 4., &axis); + ccdQuatMul(&box1.quat, &rot); + ccdVec3Set(&box1.pos, -0.5, 0.1, 0.4); + + res = ccdMPRPenetration(&box1, &box2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 7"); + //TOSVT(); + + + box1.x = box1.y = box1.z = 1.; + box2.x = 0.2; box2.y = 0.5; box2.z = 1.; + box2.x = box2.y = box2.z = 1.; + + ccdVec3Set(&axis, 0., 0., 1.); + ccdQuatSetAngleAxis(&box1.quat, M_PI / 4., &axis); + ccdVec3Set(&axis, 1., 0., 0.); + ccdQuatSetAngleAxis(&rot, M_PI / 4., &axis); + ccdQuatMul(&box1.quat, &rot); + ccdVec3Set(&box1.pos, -1.3, 0., 0.); + + ccdVec3Set(&box2.pos, 0., 0., 0.); + + res = ccdMPRPenetration(&box1, &box2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 8"); + //TOSVT(); + + + box1.x = box1.y = box1.z = 1.; + box2.x = 0.5; box2.y = 0.5; box2.z = .5; + ccdVec3Set(&box1.pos, 0., 0., 0.); + ccdQuatSet(&box1.quat, 0., 0., 0., 1.); + ccdVec3Set(&box2.pos, 0., 0.73, 0.); + ccdQuatSet(&box2.quat, 0., 0., 0., 1.); + + res = ccdMPRPenetration(&box1, &box2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 9"); + //TOSVT(); + + box1.x = box1.y = box1.z = 1.; + box2.x = 0.5; box2.y = 0.5; box2.z = .5; + ccdVec3Set(&box1.pos, 0., 0., 0.); + ccdQuatSet(&box1.quat, 0., 0., 0., 1.); + ccdVec3Set(&box2.pos, 0.3, 0.738, 0.); + ccdQuatSet(&box2.quat, 0., 0., 0., 1.); + + res = ccdMPRPenetration(&box1, &box2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 10"); + //TOSVT(); +} diff --git a/libs/ode-0.16.1/libccd/src/testsuites/mpr_boxbox.h b/libs/ode-0.16.1/libccd/src/testsuites/mpr_boxbox.h new file mode 100644 index 0000000..e6922aa --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/mpr_boxbox.h @@ -0,0 +1,26 @@ +#ifndef MPR_BOX_BOX +#define MPR_BOX_BOX + +#include <cu/cu.h> + +TEST(mprBoxboxAlignedX); +TEST(mprBoxboxAlignedY); +TEST(mprBoxboxAlignedZ); + +TEST(mprBoxboxRot); + +TEST(mprBoxboxSeparate); +TEST(mprBoxboxPenetration); + +TEST_SUITE(TSMPRBoxBox) { + TEST_ADD(mprBoxboxAlignedX), + TEST_ADD(mprBoxboxAlignedY), + TEST_ADD(mprBoxboxAlignedZ), + TEST_ADD(mprBoxboxRot), + //TEST_ADD(mprBoxboxSeparate), + TEST_ADD(mprBoxboxPenetration), + + TEST_SUITE_CLOSURE +}; + +#endif diff --git a/libs/ode-0.16.1/libccd/src/testsuites/mpr_boxcyl.c b/libs/ode-0.16.1/libccd/src/testsuites/mpr_boxcyl.c new file mode 100644 index 0000000..7a1b7fa --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/mpr_boxcyl.c @@ -0,0 +1,165 @@ +#include <cu/cu.h> +#include "common.h" +#include <ccd/ccd.h> +#include "support.h" + +#define TOSVT() \ + svtObjPen(&box, &cyl, stdout, "Pen 1", depth, &dir, &pos); \ + ccdVec3Scale(&dir, depth); \ + ccdVec3Add(&cyl.pos, &dir); \ + svtObjPen(&box, &cyl, stdout, "Pen 1", depth, &dir, &pos) + +TEST(mprBoxcylIntersect) +{ + ccd_t ccd; + CCD_BOX(box); + CCD_CYL(cyl); + int res; + ccd_vec3_t axis; + + box.x = 0.5; + box.y = 1.; + box.z = 1.5; + cyl.radius = 0.4; + cyl.height = 0.7; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + ccd.center1 = ccdObjCenter; + ccd.center2 = ccdObjCenter; + + ccdVec3Set(&cyl.pos, 0.1, 0., 0.); + res = ccdMPRIntersect(&box, &cyl, &ccd); + assertTrue(res); + + ccdVec3Set(&cyl.pos, .6, 0., 0.); + res = ccdMPRIntersect(&box, &cyl, &ccd); + assertTrue(res); + + ccdVec3Set(&cyl.pos, .6, 0.6, 0.); + res = ccdMPRIntersect(&box, &cyl, &ccd); + assertTrue(res); + + ccdVec3Set(&cyl.pos, .6, 0.6, 0.5); + res = ccdMPRIntersect(&box, &cyl, &ccd); + assertTrue(res); + + ccdVec3Set(&axis, 0., 1., 0.); + ccdQuatSetAngleAxis(&cyl.quat, M_PI / 3., &axis); + ccdVec3Set(&cyl.pos, .6, 0.6, 0.5); + res = ccdMPRIntersect(&box, &cyl, &ccd); + assertTrue(res); + + ccdVec3Set(&axis, 0.67, 1.1, 0.12); + ccdQuatSetAngleAxis(&cyl.quat, M_PI / 4., &axis); + ccdVec3Set(&cyl.pos, .6, 0., 0.5); + res = ccdMPRIntersect(&box, &cyl, &ccd); + assertTrue(res); + + ccdVec3Set(&axis, -0.1, 2.2, -1.); + ccdQuatSetAngleAxis(&cyl.quat, M_PI / 5., &axis); + ccdVec3Set(&cyl.pos, .6, 0., 0.5); + ccdVec3Set(&axis, 1., 1., 0.); + ccdQuatSetAngleAxis(&box.quat, -M_PI / 4., &axis); + ccdVec3Set(&box.pos, .6, 0., 0.5); + res = ccdMPRIntersect(&box, &cyl, &ccd); + assertTrue(res); + + ccdVec3Set(&axis, -0.1, 2.2, -1.); + ccdQuatSetAngleAxis(&cyl.quat, M_PI / 5., &axis); + ccdVec3Set(&cyl.pos, .6, 0., 0.5); + ccdVec3Set(&axis, 1., 1., 0.); + ccdQuatSetAngleAxis(&box.quat, -M_PI / 4., &axis); + ccdVec3Set(&box.pos, .9, 0.8, 0.5); + res = ccdMPRIntersect(&box, &cyl, &ccd); + assertTrue(res); +} + + + +TEST(mprBoxcylPen) +{ + ccd_t ccd; + CCD_BOX(box); + CCD_CYL(cyl); + int res; + ccd_vec3_t axis; + ccd_real_t depth; + ccd_vec3_t dir, pos; + + box.x = 0.5; + box.y = 1.; + box.z = 1.5; + cyl.radius = 0.4; + cyl.height = 0.7; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + ccd.center1 = ccdObjCenter; + ccd.center2 = ccdObjCenter; + + ccdVec3Set(&cyl.pos, 0.1, 0., 0.); + res = ccdMPRPenetration(&box, &cyl, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 1"); + //TOSVT(); + + ccdVec3Set(&cyl.pos, .6, 0., 0.); + res = ccdMPRPenetration(&box, &cyl, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 2"); + //TOSVT(); + + ccdVec3Set(&cyl.pos, .6, 0.6, 0.); + res = ccdMPRPenetration(&box, &cyl, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 3"); + //TOSVT(); + + ccdVec3Set(&cyl.pos, .6, 0.6, 0.5); + res = ccdMPRPenetration(&box, &cyl, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 4"); + //TOSVT(); + + ccdVec3Set(&axis, 0., 1., 0.); + ccdQuatSetAngleAxis(&cyl.quat, M_PI / 3., &axis); + ccdVec3Set(&cyl.pos, .6, 0.6, 0.5); + res = ccdMPRPenetration(&box, &cyl, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 5"); + //TOSVT(); + + ccdVec3Set(&axis, 0.67, 1.1, 0.12); + ccdQuatSetAngleAxis(&cyl.quat, M_PI / 4., &axis); + ccdVec3Set(&cyl.pos, .6, 0., 0.5); + res = ccdMPRPenetration(&box, &cyl, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 6"); + //TOSVT(); + + ccdVec3Set(&axis, -0.1, 2.2, -1.); + ccdQuatSetAngleAxis(&cyl.quat, M_PI / 5., &axis); + ccdVec3Set(&cyl.pos, .6, 0., 0.5); + ccdVec3Set(&axis, 1., 1., 0.); + ccdQuatSetAngleAxis(&box.quat, -M_PI / 4., &axis); + ccdVec3Set(&box.pos, .6, 0., 0.5); + res = ccdMPRPenetration(&box, &cyl, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 7"); + //TOSVT(); + + ccdVec3Set(&axis, -0.1, 2.2, -1.); + ccdQuatSetAngleAxis(&cyl.quat, M_PI / 5., &axis); + ccdVec3Set(&cyl.pos, .6, 0., 0.5); + ccdVec3Set(&axis, 1., 1., 0.); + ccdQuatSetAngleAxis(&box.quat, -M_PI / 4., &axis); + ccdVec3Set(&box.pos, .9, 0.8, 0.5); + res = ccdMPRPenetration(&box, &cyl, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 8"); + //TOSVT(); +} + diff --git a/libs/ode-0.16.1/libccd/src/testsuites/mpr_boxcyl.h b/libs/ode-0.16.1/libccd/src/testsuites/mpr_boxcyl.h new file mode 100644 index 0000000..86f14e6 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/mpr_boxcyl.h @@ -0,0 +1,16 @@ +#ifndef MPR_TEST_BOXCYL_H +#define MPR_TEST_BOXCYL_H + +#include <cu/cu.h> + +TEST(mprBoxcylIntersect); +TEST(mprBoxcylPen); + +TEST_SUITE(TSMPRBoxCyl){ + TEST_ADD(mprBoxcylIntersect), + TEST_ADD(mprBoxcylPen), + + TEST_SUITE_CLOSURE +}; + +#endif diff --git a/libs/ode-0.16.1/libccd/src/testsuites/mpr_cylcyl.c b/libs/ode-0.16.1/libccd/src/testsuites/mpr_cylcyl.c new file mode 100644 index 0000000..ec0a3bc --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/mpr_cylcyl.c @@ -0,0 +1,179 @@ +#include <stdio.h> +#include <cu/cu.h> +#include <ccd/ccd.h> +#include "support.h" +#include "common.h" + + +TEST(mprCylcylAlignedX) +{ + ccd_t ccd; + CCD_CYL(c1); + CCD_CYL(c2); + size_t i; + int res; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + ccd.center1 = ccdObjCenter; + ccd.center2 = ccdObjCenter; + + c1.radius = 0.35; + c1.height = 0.5; + c2.radius = 0.5; + c2.height = 1.; + + ccdVec3Set(&c1.pos, -5., 0., 0.); + for (i = 0; i < 100; i++){ + res = ccdMPRIntersect(&c1, &c2, &ccd); + + if (i < 42 || i > 58){ + assertFalse(res); + }else{ + assertTrue(res); + } + + c1.pos.v[0] += 0.1; + } +} + +TEST(mprCylcylAlignedY) +{ + ccd_t ccd; + CCD_CYL(c1); + CCD_CYL(c2); + size_t i; + int res; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + ccd.center1 = ccdObjCenter; + ccd.center2 = ccdObjCenter; + + c1.radius = 0.35; + c1.height = 0.5; + c2.radius = 0.5; + c2.height = 1.; + + ccdVec3Set(&c1.pos, 0., -5., 0.); + for (i = 0; i < 100; i++){ + res = ccdMPRIntersect(&c1, &c2, &ccd); + + if (i < 42 || i > 58){ + assertFalse(res); + }else{ + assertTrue(res); + } + + c1.pos.v[1] += 0.1; + } +} + +TEST(mprCylcylAlignedZ) +{ + ccd_t ccd; + CCD_CYL(c1); + CCD_CYL(c2); + size_t i; + int res; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + ccd.center1 = ccdObjCenter; + ccd.center2 = ccdObjCenter; + + c1.radius = 0.35; + c1.height = 0.5; + c2.radius = 0.5; + c2.height = 1.; + + ccdVec3Set(&c1.pos, 0., 0., -5.); + for (i = 0; i < 100; i++){ + res = ccdMPRIntersect(&c1, &c2, &ccd); + + if (i < 43 || i > 57){ + assertFalse(res); + }else{ + assertTrue(res); + } + + c1.pos.v[2] += 0.1; + } +} + +#define TOSVT() \ + svtObjPen(&cyl1, &cyl2, stdout, "Pen 1", depth, &dir, &pos); \ + ccdVec3Scale(&dir, depth); \ + ccdVec3Add(&cyl2.pos, &dir); \ + svtObjPen(&cyl1, &cyl2, stdout, "Pen 1", depth, &dir, &pos) + +TEST(mprCylcylPenetration) +{ + ccd_t ccd; + CCD_CYL(cyl1); + CCD_CYL(cyl2); + int res; + ccd_vec3_t axis; + ccd_real_t depth; + ccd_vec3_t dir, pos; + + fprintf(stderr, "\n\n\n---- mprCylcylPenetration ----\n\n\n"); + + cyl1.radius = 0.35; + cyl1.height = 0.5; + cyl2.radius = 0.5; + cyl2.height = 1.; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + ccd.center1 = ccdObjCenter; + ccd.center2 = ccdObjCenter; + + ccdVec3Set(&cyl2.pos, 0., 0., 0.3); + res = ccdMPRPenetration(&cyl1, &cyl2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 1"); + //TOSVT(); + + ccdVec3Set(&cyl1.pos, 0.3, 0.1, 0.1); + res = ccdMPRPenetration(&cyl1, &cyl2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 2"); + //TOSVT(); + + ccdVec3Set(&axis, 0., 1., 1.); + ccdQuatSetAngleAxis(&cyl2.quat, M_PI / 4., &axis); + ccdVec3Set(&cyl2.pos, 0., 0., 0.); + res = ccdMPRPenetration(&cyl1, &cyl2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 3"); + //TOSVT(); + + ccdVec3Set(&axis, 0., 1., 1.); + ccdQuatSetAngleAxis(&cyl2.quat, M_PI / 4., &axis); + ccdVec3Set(&cyl2.pos, -0.2, 0.7, 0.2); + res = ccdMPRPenetration(&cyl1, &cyl2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 4"); + //TOSVT(); + + ccdVec3Set(&axis, 0.567, 1.2, 1.); + ccdQuatSetAngleAxis(&cyl2.quat, M_PI / 4., &axis); + ccdVec3Set(&cyl2.pos, 0.6, -0.7, 0.2); + res = ccdMPRPenetration(&cyl1, &cyl2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 5"); + //TOSVT(); + + ccdVec3Set(&axis, -4.567, 1.2, 0.); + ccdQuatSetAngleAxis(&cyl2.quat, M_PI / 3., &axis); + ccdVec3Set(&cyl2.pos, 0.6, -0.7, 0.2); + res = ccdMPRPenetration(&cyl1, &cyl2, &ccd, &depth, &dir, &pos); + assertTrue(res == 0); + recPen(depth, &dir, &pos, stdout, "Pen 6"); + //TOSVT(); +} diff --git a/libs/ode-0.16.1/libccd/src/testsuites/mpr_cylcyl.h b/libs/ode-0.16.1/libccd/src/testsuites/mpr_cylcyl.h new file mode 100644 index 0000000..2d2162b --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/mpr_cylcyl.h @@ -0,0 +1,23 @@ +#ifndef MPR_CYL_CYL +#define MPR_CYL_CYL + +#include <cu/cu.h> + +TEST(mprCylcylAlignedX); +TEST(mprCylcylAlignedY); +TEST(mprCylcylAlignedZ); + +TEST(mprCylcylPenetration); + +TEST_SUITE(TSMPRCylCyl) { + TEST_ADD(mprCylcylAlignedX), + TEST_ADD(mprCylcylAlignedY), + TEST_ADD(mprCylcylAlignedZ), + + TEST_ADD(mprCylcylPenetration), + + TEST_SUITE_CLOSURE +}; + +#endif + diff --git a/libs/ode-0.16.1/libccd/src/testsuites/polytope.c b/libs/ode-0.16.1/libccd/src/testsuites/polytope.c new file mode 100644 index 0000000..65686fb --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/polytope.c @@ -0,0 +1,398 @@ +//#undef NDEBUG +#include <cu/cu.h> +#include <ccd/polytope.h> +#include <ccd/dbg.h> + +TEST(ptSetUp) +{ +} + +TEST(ptTearDown) +{ +} + + +TEST(ptCreate1) +{ + ccd_pt_t pt; + ccd_pt_vertex_t *v[3]; + ccd_pt_edge_t *e[3]; + ccd_pt_face_t *f; + ccd_vec3_t u; + int res; + size_t i; + + DBG2("------"); + + ccdPtInit(&pt); + ccdPtDestroy(&pt); + + + ccdPtInit(&pt); + + ccdVec3Set(&u, -1., -1., 0.); + v[0] = ccdPtAddVertexCoords(&pt, -1., -1., 0.); + assertTrue(ccdVec3Eq(&u, &v[0]->v.v)); + + ccdVec3Set(&u, 1., 0., 0.); + v[1] = ccdPtAddVertexCoords(&pt, 1., 0., 0.); + assertTrue(ccdVec3Eq(&u, &v[1]->v.v)); + + ccdVec3Set(&u, 0., 0., 1.); + v[2] = ccdPtAddVertexCoords(&pt, 0., 0., 1.); + assertTrue(ccdVec3Eq(&u, &v[2]->v.v)); + + for (i = 0; i < 3; i++){ + assertTrue(ccdEq(v[i]->dist, ccdVec3Len2(&v[i]->v.v))); + } + + + e[0] = ccdPtAddEdge(&pt, v[0], v[1]); + e[1] = ccdPtAddEdge(&pt, v[1], v[2]); + e[2] = ccdPtAddEdge(&pt, v[2], v[0]); + for (i = 0; i < 3; i++){ + DBG("e[%d]->dist: %lf", i, e[i]->dist); + DBG_VEC3(&e[i]->witness, " ->witness: "); + } + + f = ccdPtAddFace(&pt, e[0], e[1], e[2]); + DBG("f->dist: %lf", f->dist); + DBG_VEC3(&f->witness, " ->witness: "); + + for (i = 0; i < 3; i++){ + res = ccdPtDelVertex(&pt, v[i]); + assertFalse(res == 0); + res = ccdPtDelEdge(&pt, e[i]); + assertFalse(res == 0); + } + + ccdPtDelFace(&pt, f); + for (i = 0; i < 3; i++){ + res = ccdPtDelVertex(&pt, v[i]); + assertFalse(res == 0); + } + for (i = 0; i < 3; i++){ + res = ccdPtDelEdge(&pt, e[i]); + assertTrue(res == 0); + } + for (i = 0; i < 3; i++){ + res = ccdPtDelVertex(&pt, v[i]); + assertTrue(res == 0); + } + + v[0] = ccdPtAddVertexCoords(&pt, -1., -1., 0.); + v[1] = ccdPtAddVertexCoords(&pt, 1., 0., 0.); + v[2] = ccdPtAddVertexCoords(&pt, 0., 0., 1.); + + e[0] = ccdPtAddEdge(&pt, v[0], v[1]); + e[1] = ccdPtAddEdge(&pt, v[1], v[2]); + e[2] = ccdPtAddEdge(&pt, v[2], v[0]); + + f = ccdPtAddFace(&pt, e[0], e[1], e[2]); + + ccdPtDestroy(&pt); +} + +TEST(ptCreate2) +{ + ccd_pt_t pt; + ccd_pt_vertex_t *v[4]; + ccd_pt_edge_t *e[6]; + ccd_pt_face_t *f[4]; + ccd_vec3_t u; + int res; + unsigned int i; + + DBG2("------"); + + ccdPtInit(&pt); + + ccdVec3Set(&u, -1., -1., 0.); + v[0] = ccdPtAddVertexCoords(&pt, -1., -1., 0.); + assertTrue(ccdVec3Eq(&u, &v[0]->v.v)); + + ccdVec3Set(&u, 1., 0., 0.); + v[1] = ccdPtAddVertexCoords(&pt, 1., 0., 0.); + assertTrue(ccdVec3Eq(&u, &v[1]->v.v)); + + ccdVec3Set(&u, 0., 0., 1.); + v[2] = ccdPtAddVertexCoords(&pt, 0., 0., 1.); + assertTrue(ccdVec3Eq(&u, &v[2]->v.v)); + + ccdVec3Set(&u, 0., 1., 0.); + v[3] = ccdPtAddVertexCoords(&pt, 0., 1., 0.); + assertTrue(ccdVec3Eq(&u, &v[3]->v.v)); + + for (i = 0; i < 4; i++){ + assertTrue(ccdEq(v[i]->dist, ccdVec3Len2(&v[i]->v.v))); + } + for (i = 0; i < 4; i++){ + DBG("v[%d]->dist: %lf", i, v[i]->dist); + DBG_VEC3(&v[i]->witness, " ->witness: "); + } + + e[0] = ccdPtAddEdge(&pt, v[0], v[1]); + e[1] = ccdPtAddEdge(&pt, v[1], v[2]); + e[2] = ccdPtAddEdge(&pt, v[2], v[0]); + e[3] = ccdPtAddEdge(&pt, v[3], v[0]); + e[4] = ccdPtAddEdge(&pt, v[3], v[1]); + e[5] = ccdPtAddEdge(&pt, v[3], v[2]); + for (i = 0; i < 6; i++){ + DBG("e[%d]->dist: %lf", i, e[i]->dist); + DBG_VEC3(&e[i]->witness, " ->witness: "); + } + + f[0] = ccdPtAddFace(&pt, e[0], e[1], e[2]); + f[1] = ccdPtAddFace(&pt, e[3], e[4], e[0]); + f[2] = ccdPtAddFace(&pt, e[4], e[5], e[1]); + f[3] = ccdPtAddFace(&pt, e[5], e[3], e[2]); + for (i = 0; i < 4; i++){ + DBG("f[%d]->dist: %lf", i, f[i]->dist); + DBG_VEC3(&f[i]->witness, " ->witness: "); + } + + for (i = 0; i < 4; i++){ + res = ccdPtDelVertex(&pt, v[i]); + assertFalse(res == 0); + } + for (i = 0; i < 6; i++){ + res = ccdPtDelEdge(&pt, e[i]); + assertFalse(res == 0); + } + + res = ccdPtDelFace(&pt, f[0]); + for (i = 0; i < 6; i++){ + res = ccdPtDelEdge(&pt, e[i]); + assertFalse(res == 0); + } + + res = ccdPtDelFace(&pt, f[1]); + assertTrue(ccdPtDelEdge(&pt, e[0]) == 0); + assertFalse(ccdPtDelEdge(&pt, e[1]) == 0); + assertFalse(ccdPtDelEdge(&pt, e[2]) == 0); + assertFalse(ccdPtDelEdge(&pt, e[3]) == 0); + assertFalse(ccdPtDelEdge(&pt, e[4]) == 0); + assertFalse(ccdPtDelEdge(&pt, e[5]) == 0); + for (i = 0; i < 4; i++){ + res = ccdPtDelVertex(&pt, v[i]); + assertFalse(res == 0); + } + + res = ccdPtDelFace(&pt, f[2]); + assertTrue(ccdPtDelEdge(&pt, e[1]) == 0); + assertTrue(ccdPtDelEdge(&pt, e[4]) == 0); + assertFalse(ccdPtDelEdge(&pt, e[2]) == 0); + assertFalse(ccdPtDelEdge(&pt, e[3]) == 0); + assertFalse(ccdPtDelEdge(&pt, e[5]) == 0); + + assertTrue(ccdPtDelVertex(&pt, v[1]) == 0); + assertFalse(ccdPtDelVertex(&pt, v[0]) == 0); + assertFalse(ccdPtDelVertex(&pt, v[2]) == 0); + assertFalse(ccdPtDelVertex(&pt, v[3]) == 0); + + res = ccdPtDelFace(&pt, f[3]); + assertTrue(ccdPtDelEdge(&pt, e[2]) == 0); + assertTrue(ccdPtDelEdge(&pt, e[3]) == 0); + assertTrue(ccdPtDelEdge(&pt, e[5]) == 0); + + assertTrue(ccdPtDelVertex(&pt, v[0]) == 0); + assertTrue(ccdPtDelVertex(&pt, v[2]) == 0); + assertTrue(ccdPtDelVertex(&pt, v[3]) == 0); + + + v[0] = ccdPtAddVertexCoords(&pt, -1., -1., 0.); + v[1] = ccdPtAddVertexCoords(&pt, 1., 0., 0.); + v[2] = ccdPtAddVertexCoords(&pt, 0., 0., 1.); + v[3] = ccdPtAddVertexCoords(&pt, 0., 1., 0.); + + e[0] = ccdPtAddEdge(&pt, v[0], v[1]); + e[1] = ccdPtAddEdge(&pt, v[1], v[2]); + e[2] = ccdPtAddEdge(&pt, v[2], v[0]); + e[3] = ccdPtAddEdge(&pt, v[3], v[0]); + e[4] = ccdPtAddEdge(&pt, v[3], v[1]); + e[5] = ccdPtAddEdge(&pt, v[3], v[2]); + + f[0] = ccdPtAddFace(&pt, e[0], e[1], e[2]); + f[1] = ccdPtAddFace(&pt, e[3], e[4], e[0]); + f[2] = ccdPtAddFace(&pt, e[4], e[5], e[1]); + f[3] = ccdPtAddFace(&pt, e[5], e[3], e[2]); + + ccdPtDestroy(&pt); +} + +TEST(ptNearest) +{ + ccd_pt_t pt; + ccd_pt_vertex_t *v[4]; + ccd_pt_edge_t *e[6]; + ccd_pt_face_t *f[4]; + ccd_pt_el_t *nearest; + + DBG2("------"); + + ccdPtInit(&pt); + + v[0] = ccdPtAddVertexCoords(&pt, -1., -1., 0.); + v[1] = ccdPtAddVertexCoords(&pt, 1., 0., 0.); + v[2] = ccdPtAddVertexCoords(&pt, 0., 0., 1.); + v[3] = ccdPtAddVertexCoords(&pt, 0., 1., 0.); + + e[0] = ccdPtAddEdge(&pt, v[0], v[1]); + e[1] = ccdPtAddEdge(&pt, v[1], v[2]); + e[2] = ccdPtAddEdge(&pt, v[2], v[0]); + e[3] = ccdPtAddEdge(&pt, v[3], v[0]); + e[4] = ccdPtAddEdge(&pt, v[3], v[1]); + e[5] = ccdPtAddEdge(&pt, v[3], v[2]); + + f[0] = ccdPtAddFace(&pt, e[0], e[1], e[2]); + f[1] = ccdPtAddFace(&pt, e[3], e[4], e[0]); + f[2] = ccdPtAddFace(&pt, e[4], e[5], e[1]); + f[3] = ccdPtAddFace(&pt, e[5], e[3], e[2]); + + nearest = ccdPtNearest(&pt); + //DBG("nearest->type: %d", nearest->type); + //DBG(" ->dist: %lf", nearest->dist); + //DBG_VEC3(&nearest->witness, " ->witness: "); + assertEquals(nearest->type, CCD_PT_FACE); + assertEquals(nearest, (ccd_pt_el_t *)f[1]); + assertTrue(ccdPtDelFace(&pt, f[1]) == 0); + + + nearest = ccdPtNearest(&pt); + //DBG("nearest->type: %d", nearest->type); + //DBG(" ->dist: %lf", nearest->dist); + //DBG_VEC3(&nearest->witness, " ->witness: "); + assertEquals(nearest->type, CCD_PT_FACE); + assertTrue(nearest == (ccd_pt_el_t *)f[0] + || nearest == (ccd_pt_el_t *)f[3]); + assertTrue(ccdPtDelFace(&pt, (ccd_pt_face_t *)nearest) == 0); + + + nearest = ccdPtNearest(&pt); + //DBG("nearest->type: %d", nearest->type); + //DBG(" ->dist: %lf", nearest->dist); + //DBG_VEC3(&nearest->witness, " ->witness: "); + assertEquals(nearest->type, CCD_PT_FACE); + assertTrue(nearest == (ccd_pt_el_t *)f[0] + || nearest == (ccd_pt_el_t *)f[3]); + assertTrue(ccdPtDelFace(&pt, (ccd_pt_face_t *)nearest) == 0); + + + nearest = ccdPtNearest(&pt); + //DBG("nearest->type: %d", nearest->type); + //DBG(" ->dist: %lf", nearest->dist); + //DBG_VEC3(&nearest->witness, " ->witness: "); + assertEquals(nearest->type, CCD_PT_EDGE); + assertTrue(nearest == (ccd_pt_el_t *)e[0] + || nearest == (ccd_pt_el_t *)e[3]); + assertTrue(ccdPtDelEdge(&pt, (ccd_pt_edge_t *)nearest) == 0); + + + nearest = ccdPtNearest(&pt); + //DBG("nearest->type: %d", nearest->type); + //DBG(" ->dist: %lf", nearest->dist); + //DBG_VEC3(&nearest->witness, " ->witness: "); + assertEquals(nearest->type, CCD_PT_EDGE); + assertTrue(nearest == (ccd_pt_el_t *)e[0] + || nearest == (ccd_pt_el_t *)e[3]); + assertTrue(ccdPtDelEdge(&pt, (ccd_pt_edge_t *)nearest) == 0); + + + nearest = ccdPtNearest(&pt); + //DBG("nearest->type: %d", nearest->type); + //DBG(" ->dist: %lf", nearest->dist); + //DBG_VEC3(&nearest->witness, " ->witness: "); + assertEquals(nearest->type, CCD_PT_FACE); + assertEquals(nearest, (ccd_pt_el_t *)f[2]); + assertTrue(ccdPtDelFace(&pt, f[2]) == 0); + + + nearest = ccdPtNearest(&pt); + //DBG("nearest->type: %d", nearest->type); + //DBG(" ->dist: %lf", nearest->dist); + //DBG_VEC3(&nearest->witness, " ->witness: "); + assertEquals(nearest->type, CCD_PT_EDGE); + assertTrue(nearest == (ccd_pt_el_t *)e[1] + || nearest == (ccd_pt_el_t *)e[4] + || nearest == (ccd_pt_el_t *)e[5]); + assertTrue(ccdPtDelEdge(&pt, (ccd_pt_edge_t *)nearest) == 0); + + + nearest = ccdPtNearest(&pt); + //DBG("nearest->type: %d", nearest->type); + //DBG(" ->dist: %lf", nearest->dist); + //DBG_VEC3(&nearest->witness, " ->witness: "); + assertEquals(nearest->type, CCD_PT_EDGE); + assertTrue(nearest == (ccd_pt_el_t *)e[1] + || nearest == (ccd_pt_el_t *)e[4] + || nearest == (ccd_pt_el_t *)e[5]); + assertTrue(ccdPtDelEdge(&pt, (ccd_pt_edge_t *)nearest) == 0); + + + nearest = ccdPtNearest(&pt); + //DBG("nearest->type: %d", nearest->type); + //DBG(" ->dist: %lf", nearest->dist); + //DBG_VEC3(&nearest->witness, " ->witness: "); + assertEquals(nearest->type, CCD_PT_EDGE); + assertTrue(nearest == (ccd_pt_el_t *)e[1] + || nearest == (ccd_pt_el_t *)e[4] + || nearest == (ccd_pt_el_t *)e[5]); + assertTrue(ccdPtDelEdge(&pt, (ccd_pt_edge_t *)nearest) == 0); + + + nearest = ccdPtNearest(&pt); + //DBG("nearest->type: %d", nearest->type); + //DBG(" ->dist: %lf", nearest->dist); + //DBG_VEC3(&nearest->witness, " ->witness: "); + assertEquals(nearest->type, CCD_PT_EDGE); + assertTrue(nearest == (ccd_pt_el_t *)e[2]); + assertTrue(ccdPtDelEdge(&pt, (ccd_pt_edge_t *)nearest) == 0); + + + nearest = ccdPtNearest(&pt); + //DBG("nearest->type: %d", nearest->type); + //DBG(" ->dist: %lf", nearest->dist); + //DBG_VEC3(&nearest->witness, " ->witness: "); + assertEquals(nearest->type, CCD_PT_VERTEX); + assertTrue(nearest == (ccd_pt_el_t *)v[1] + || nearest == (ccd_pt_el_t *)v[2] + || nearest == (ccd_pt_el_t *)v[3]); + assertTrue(ccdPtDelVertex(&pt, (ccd_pt_vertex_t *)nearest) == 0); + + + nearest = ccdPtNearest(&pt); + //DBG("nearest->type: %d", nearest->type); + //DBG(" ->dist: %lf", nearest->dist); + //DBG_VEC3(&nearest->witness, " ->witness: "); + assertEquals(nearest->type, CCD_PT_VERTEX); + assertTrue(nearest == (ccd_pt_el_t *)v[1] + || nearest == (ccd_pt_el_t *)v[2] + || nearest == (ccd_pt_el_t *)v[3]); + assertTrue(ccdPtDelVertex(&pt, (ccd_pt_vertex_t *)nearest) == 0); + + + nearest = ccdPtNearest(&pt); + //DBG("nearest->type: %d", nearest->type); + //DBG(" ->dist: %lf", nearest->dist); + //DBG_VEC3(&nearest->witness, " ->witness: "); + assertEquals(nearest->type, CCD_PT_VERTEX); + assertTrue(nearest == (ccd_pt_el_t *)v[1] + || nearest == (ccd_pt_el_t *)v[2] + || nearest == (ccd_pt_el_t *)v[3]); + assertTrue(ccdPtDelVertex(&pt, (ccd_pt_vertex_t *)nearest) == 0); + + + nearest = ccdPtNearest(&pt); + //DBG("nearest->type: %d", nearest->type); + //DBG(" ->dist: %lf", nearest->dist); + //DBG_VEC3(&nearest->witness, " ->witness: "); + assertEquals(nearest->type, CCD_PT_VERTEX); + assertTrue(nearest == (ccd_pt_el_t *)v[0]); + assertTrue(ccdPtDelVertex(&pt, (ccd_pt_vertex_t *)nearest) == 0); + + + nearest = ccdPtNearest(&pt); + assertTrue(nearest == NULL); + + ccdPtDestroy(&pt); +} diff --git a/libs/ode-0.16.1/libccd/src/testsuites/polytope.h b/libs/ode-0.16.1/libccd/src/testsuites/polytope.h new file mode 100644 index 0000000..cf31546 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/polytope.h @@ -0,0 +1,24 @@ +#ifndef TEST_POLYTOPE_H +#define TEST_POLYTOPE_H + +#include <cu/cu.h> + +TEST(ptSetUp); +TEST(ptTearDown); + +TEST(ptCreate1); +TEST(ptCreate2); +TEST(ptNearest); + +TEST_SUITE(TSPt) { + TEST_ADD(ptSetUp), + + TEST_ADD(ptCreate1), + TEST_ADD(ptCreate2), + TEST_ADD(ptNearest), + + TEST_ADD(ptTearDown), + TEST_SUITE_CLOSURE +}; + +#endif diff --git a/libs/ode-0.16.1/libccd/src/testsuites/spheresphere.c b/libs/ode-0.16.1/libccd/src/testsuites/spheresphere.c new file mode 100644 index 0000000..36628f6 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/spheresphere.c @@ -0,0 +1,99 @@ +#include <stdio.h> +#include <cu/cu.h> +#include "support.h" +#include <ccd/ccd.h> + +TEST(spheresphereSetUp) +{ +} + +TEST(spheresphereTearDown) +{ +} + +TEST(spheresphereAlignedX) +{ + ccd_t ccd; + CCD_SPHERE(s1); + CCD_SPHERE(s2); + size_t i; + int res; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + + s1.radius = 0.35; + s2.radius = .5; + + ccdVec3Set(&s1.pos, -5., 0., 0.); + for (i = 0; i < 100; i++){ + res = ccdGJKIntersect(&s1, &s2, &ccd); + + if (i < 42 || i > 58){ + assertFalse(res); + }else{ + assertTrue(res); + } + + s1.pos.v[0] += 0.1; + } +} + +TEST(spheresphereAlignedY) +{ + ccd_t ccd; + CCD_SPHERE(s1); + CCD_SPHERE(s2); + size_t i; + int res; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + + s1.radius = 0.35; + s2.radius = .5; + + ccdVec3Set(&s1.pos, 0., -5., 0.); + for (i = 0; i < 100; i++){ + res = ccdGJKIntersect(&s1, &s2, &ccd); + + if (i < 42 || i > 58){ + assertFalse(res); + }else{ + assertTrue(res); + } + + s1.pos.v[1] += 0.1; + } +} + +TEST(spheresphereAlignedZ) +{ + ccd_t ccd; + CCD_SPHERE(s1); + CCD_SPHERE(s2); + size_t i; + int res; + + CCD_INIT(&ccd); + ccd.support1 = ccdSupport; + ccd.support2 = ccdSupport; + + s1.radius = 0.35; + s2.radius = .5; + + ccdVec3Set(&s1.pos, 0., 0., -5.); + for (i = 0; i < 100; i++){ + res = ccdGJKIntersect(&s1, &s2, &ccd); + + if (i < 42 || i > 58){ + assertFalse(res); + }else{ + assertTrue(res); + } + + s1.pos.v[2] += 0.1; + } +} diff --git a/libs/ode-0.16.1/libccd/src/testsuites/spheresphere.h b/libs/ode-0.16.1/libccd/src/testsuites/spheresphere.h new file mode 100644 index 0000000..b032215 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/spheresphere.h @@ -0,0 +1,24 @@ +#ifndef SPHERE_SPHERE +#define SPHERE_SPHERE + +#include <cu/cu.h> + +TEST(spheresphereSetUp); +TEST(spheresphereTearDown); + +TEST(spheresphereAlignedX); +TEST(spheresphereAlignedY); +TEST(spheresphereAlignedZ); + +TEST_SUITE(TSSphereSphere) { + TEST_ADD(spheresphereSetUp), + + TEST_ADD(spheresphereAlignedX), + TEST_ADD(spheresphereAlignedY), + TEST_ADD(spheresphereAlignedZ), + + TEST_ADD(spheresphereTearDown), + TEST_SUITE_CLOSURE +}; + +#endif diff --git a/libs/ode-0.16.1/libccd/src/testsuites/support.c b/libs/ode-0.16.1/libccd/src/testsuites/support.c new file mode 100644 index 0000000..5f2b4c7 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/support.c @@ -0,0 +1,85 @@ +/*** + * libccd + * --------------------------------- + * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz> + * + * + * This file is part of libccd. + * + * Distributed under the OSI-approved BSD License (the "License"); + * see accompanying file BDS-LICENSE for details or see + * <http://www.opensource.org/licenses/bsd-license.php>. + * + * This software is distributed WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the License for more information. + */ + +#include <stdio.h> +#include <ccd/ccd.h> +#include <ccd/vec3.h> +#include "support.h" + +void ccdSupport(const void *_obj, const ccd_vec3_t *_dir, + ccd_vec3_t *v) +{ + // Support function is made according to Gino van den Bergen's paper + // A Fast and Robust CCD Implementation for Collision Detection of + // Convex Objects + + ccd_obj_t *obj = (ccd_obj_t *)_obj; + ccd_vec3_t dir; + ccd_quat_t qinv; + + ccdVec3Copy(&dir, _dir); + ccdQuatInvert2(&qinv, &obj->quat); + + ccdQuatRotVec(&dir, &qinv); + + if (obj->type == CCD_OBJ_BOX){ + ccd_box_t *box = (ccd_box_t *)obj; + ccdVec3Set(v, ccdSign(ccdVec3X(&dir)) * box->x * CCD_REAL(0.5), + ccdSign(ccdVec3Y(&dir)) * box->y * CCD_REAL(0.5), + ccdSign(ccdVec3Z(&dir)) * box->z * CCD_REAL(0.5)); + }else if (obj->type == CCD_OBJ_SPHERE){ + ccd_sphere_t *sphere = (ccd_sphere_t *)obj; + ccd_real_t len; + + len = ccdVec3Len2(&dir); + if (len - CCD_EPS > CCD_ZERO){ + ccdVec3Copy(v, &dir); + ccdVec3Scale(v, sphere->radius / CCD_SQRT(len)); + }else{ + ccdVec3Set(v, CCD_ZERO, CCD_ZERO, CCD_ZERO); + } + }else if (obj->type == CCD_OBJ_CYL){ + ccd_cyl_t *cyl = (ccd_cyl_t *)obj; + ccd_real_t zdist, rad; + + zdist = dir.v[0] * dir.v[0] + dir.v[1] * dir.v[1]; + zdist = CCD_SQRT(zdist); + if (ccdIsZero(zdist)){ + ccdVec3Set(v, CCD_ZERO, CCD_ZERO, + ccdSign(ccdVec3Z(&dir)) * cyl->height * CCD_REAL(0.5)); + }else{ + rad = cyl->radius / zdist; + + ccdVec3Set(v, rad * ccdVec3X(&dir), + rad * ccdVec3Y(&dir), + ccdSign(ccdVec3Z(&dir)) * cyl->height * CCD_REAL(0.5)); + } + } + + // transform support vertex + ccdQuatRotVec(v, &obj->quat); + ccdVec3Add(v, &obj->pos); +} + +void ccdObjCenter(const void *_obj, ccd_vec3_t *center) +{ + ccd_obj_t *obj = (ccd_obj_t *)_obj; + + ccdVec3Set(center, CCD_ZERO, CCD_ZERO, CCD_ZERO); + // rotation is not needed + ccdVec3Add(center, &obj->pos); +} diff --git a/libs/ode-0.16.1/libccd/src/testsuites/support.h b/libs/ode-0.16.1/libccd/src/testsuites/support.h new file mode 100644 index 0000000..e444296 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/support.h @@ -0,0 +1,102 @@ +/*** + * libccd + * --------------------------------- + * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz> + * + * + * This file is part of libccd. + * + * Distributed under the OSI-approved BSD License (the "License"); + * see accompanying file BDS-LICENSE for details or see + * <http://www.opensource.org/licenses/bsd-license.php>. + * + * This software is distributed WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the License for more information. + */ + +/*** + * Some support() functions for some convex shapes. + */ + +#ifndef __CCD_SUPPORT_H__ +#define __CCD_SUPPORT_H__ + +#include <ccd/quat.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define CCD_OBJ_BOX 1 +#define CCD_OBJ_SPHERE 2 +#define CCD_OBJ_CYL 3 + +#define __CCD_OBJ__ \ + int type; \ + ccd_vec3_t pos; \ + ccd_quat_t quat; + +struct _ccd_obj_t { + __CCD_OBJ__ +}; +typedef struct _ccd_obj_t ccd_obj_t; + +struct _ccd_box_t { + __CCD_OBJ__ + ccd_real_t x, y, z; //!< Lengths of box's edges +}; +typedef struct _ccd_box_t ccd_box_t; + +struct _ccd_sphere_t { + __CCD_OBJ__ + ccd_real_t radius; +}; +typedef struct _ccd_sphere_t ccd_sphere_t; + +struct _ccd_cyl_t { + __CCD_OBJ__ + ccd_real_t radius; + ccd_real_t height; +}; +typedef struct _ccd_cyl_t ccd_cyl_t; + + +#define CCD_BOX(name) \ + ccd_box_t name = { .type = CCD_OBJ_BOX, \ + .pos = { .v = { 0., 0., 0. } }, \ + .quat = { .q = { 0., 0., 0., 1. } }, \ + .x = 0., \ + .y = 0., \ + .z = 0. } + +#define CCD_SPHERE(name) \ + ccd_sphere_t name = { .type = CCD_OBJ_SPHERE, \ + .pos = { .v = { 0., 0., 0. } }, \ + .quat = { .q = { 0., 0., 0., 1. } }, \ + .radius = 0. } + +#define CCD_CYL(name) \ + ccd_cyl_t name = { .type = CCD_OBJ_CYL, \ + .pos = { .v = { 0., 0., 0. } }, \ + .quat = { .q = { 0., 0., 0., 1. } }, \ + .radius = 0., \ + .height = 0. } + +/** + * Returns supporting vertex via v. + * Supporting vertex is fathest vertex from object in direction dir. + */ +void ccdSupport(const void *obj, const ccd_vec3_t *dir, + ccd_vec3_t *v); + +/** + * Returns center of object. + */ +void ccdObjCenter(const void *obj, ccd_vec3_t *center); + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* __CCD_SUPPORT_H__ */ diff --git a/libs/ode-0.16.1/libccd/src/testsuites/vec3.c b/libs/ode-0.16.1/libccd/src/testsuites/vec3.c new file mode 100644 index 0000000..007f310 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/vec3.c @@ -0,0 +1,273 @@ +#include <stdio.h> +#include <cu/cu.h> +#include <ccd/vec3.h> + +TEST(vec3SetUp) +{ +} + +TEST(vec3TearDown) +{ +} + + +TEST(vec3PointSegmentDist) +{ + ccd_vec3_t P, a, b, w, ew; + ccd_real_t dist; + + ccdVec3Set(&a, 0., 0., 0.); + ccdVec3Set(&b, 1., 0., 0.); + + // extereme w == a + ccdVec3Set(&P, -1., 0., 0.); + dist = ccdVec3PointSegmentDist2(&P, &a, &b, &w); + assertTrue(ccdEq(dist, 1.)); + assertTrue(ccdVec3Eq(&w, &a)); + + ccdVec3Set(&P, -0.5, 0., 0.); + dist = ccdVec3PointSegmentDist2(&P, &a, &b, &w); + assertTrue(ccdEq(dist, 0.5 * 0.5)); + assertTrue(ccdVec3Eq(&w, &a)); + + ccdVec3Set(&P, -0.1, 0., 0.); + dist = ccdVec3PointSegmentDist2(&P, &a, &b, &w); + assertTrue(ccdEq(dist, .1 * .1)); + assertTrue(ccdVec3Eq(&w, &a)); + + ccdVec3Set(&P, 0., 0., 0.); + dist = ccdVec3PointSegmentDist2(&P, &a, &b, &w); + assertTrue(ccdEq(dist, 0.)); + assertTrue(ccdVec3Eq(&w, &a)); + + ccdVec3Set(&P, -1., 1., 0.); + dist = ccdVec3PointSegmentDist2(&P, &a, &b, &w); + assertTrue(ccdEq(dist, 2.)); + assertTrue(ccdVec3Eq(&w, &a)); + + ccdVec3Set(&P, -0.5, 0.5, 0.); + dist = ccdVec3PointSegmentDist2(&P, &a, &b, &w); + assertTrue(ccdEq(dist, 0.5)); + assertTrue(ccdVec3Eq(&w, &a)); + + ccdVec3Set(&P, -0.1, -1., 2.); + dist = ccdVec3PointSegmentDist2(&P, &a, &b, &w); + assertTrue(ccdEq(dist, 5.01)); + assertTrue(ccdVec3Eq(&w, &a)); + + + // extereme w == b + ccdVec3Set(&P, 2., 0., 0.); + dist = ccdVec3PointSegmentDist2(&P, &a, &b, &w); + assertTrue(ccdEq(dist, 1.)); + assertTrue(ccdVec3Eq(&w, &b)); + + ccdVec3Set(&P, 1.5, 0., 0.); + dist = ccdVec3PointSegmentDist2(&P, &a, &b, &w); + assertTrue(ccdEq(dist, 0.5 * 0.5)); + assertTrue(ccdVec3Eq(&w, &b)); + + ccdVec3Set(&P, 1.1, 0., 0.); + dist = ccdVec3PointSegmentDist2(&P, &a, &b, &w); + assertTrue(ccdEq(dist, .1 * .1)); + assertTrue(ccdVec3Eq(&w, &b)); + + ccdVec3Set(&P, 1., 0., 0.); + dist = ccdVec3PointSegmentDist2(&P, &a, &b, &w); + assertTrue(ccdEq(dist, 0.)); + assertTrue(ccdVec3Eq(&w, &b)); + + ccdVec3Set(&P, 2., 1., 0.); + dist = ccdVec3PointSegmentDist2(&P, &a, &b, &w); + assertTrue(ccdEq(dist, 2.)); + assertTrue(ccdVec3Eq(&w, &b)); + + ccdVec3Set(&P, 1.5, 0.5, 0.); + dist = ccdVec3PointSegmentDist2(&P, &a, &b, &w); + assertTrue(ccdEq(dist, 0.5)); + assertTrue(ccdVec3Eq(&w, &b)); + + ccdVec3Set(&P, 1.1, -1., 2.); + dist = ccdVec3PointSegmentDist2(&P, &a, &b, &w); + assertTrue(ccdEq(dist, 5.01)); + assertTrue(ccdVec3Eq(&w, &b)); + + // inside segment + ccdVec3Set(&P, .5, 0., 0.); + dist = ccdVec3PointSegmentDist2(&P, &a, &b, &w); + assertTrue(ccdEq(dist, 0.)); + assertTrue(ccdVec3Eq(&w, &P)); + + ccdVec3Set(&P, .9, 0., 0.); + dist = ccdVec3PointSegmentDist2(&P, &a, &b, &w); + assertTrue(ccdEq(dist, 0.)); + assertTrue(ccdVec3Eq(&w, &P)); + + ccdVec3Set(&P, .5, 1., 0.); + dist = ccdVec3PointSegmentDist2(&P, &a, &b, &w); + assertTrue(ccdEq(dist, 1.)); + ccdVec3Set(&ew, 0.5, 0., 0.); + assertTrue(ccdVec3Eq(&w, &ew)); + + ccdVec3Set(&P, .5, 1., 1.); + dist = ccdVec3PointSegmentDist2(&P, &a, &b, &w); + assertTrue(ccdEq(dist, 2.)); + ccdVec3Set(&ew, 0.5, 0., 0.); + assertTrue(ccdVec3Eq(&w, &ew)); + + + + ccdVec3Set(&a, -.5, 2., 1.); + ccdVec3Set(&b, 1., 1.5, 0.5); + + // extereme w == a + ccdVec3Set(&P, -10., 0., 0.); + dist = ccdVec3PointSegmentDist2(&P, &a, &b, &w); + assertTrue(ccdEq(dist, 9.5 * 9.5 + 2. * 2. + 1.)); + assertTrue(ccdVec3Eq(&w, &a)); + + ccdVec3Set(&P, -10., 9.2, 3.4); + dist = ccdVec3PointSegmentDist2(&P, &a, &b, &w); + assertTrue(ccdEq(dist, 9.5 * 9.5 + 7.2 * 7.2 + 2.4 * 2.4)); + assertTrue(ccdVec3Eq(&w, &a)); + + // extereme w == b + ccdVec3Set(&P, 10., 0., 0.); + dist = ccdVec3PointSegmentDist2(&P, &a, &b, &w); + assertTrue(ccdEq(dist, 9. * 9. + 1.5 * 1.5 + 0.5 * 0.5)); + assertTrue(ccdVec3Eq(&w, &b)); + + ccdVec3Set(&P, 10., 9.2, 3.4); + dist = ccdVec3PointSegmentDist2(&P, &a, &b, &w); + assertTrue(ccdEq(dist, 9. * 9. + 7.7 * 7.7 + 2.9 * 2.9)); + assertTrue(ccdVec3Eq(&w, &b)); + + // inside ab + ccdVec3Set(&a, -.1, 1., 1.); + ccdVec3Set(&b, 1., 1., 1.); + ccdVec3Set(&P, 0., 0., 0.); + dist = ccdVec3PointSegmentDist2(&P, &a, &b, &w); + assertTrue(ccdEq(dist, 2.)); + ccdVec3Set(&ew, 0., 1., 1.); + assertTrue(ccdVec3Eq(&w, &ew)); +} + + +TEST(vec3PointTriDist) +{ + ccd_vec3_t P, a, b, c, w, P0; + ccd_real_t dist; + + ccdVec3Set(&a, -1., 0., 0.); + ccdVec3Set(&b, 0., 1., 1.); + ccdVec3Set(&c, -1., 0., 1.); + + ccdVec3Set(&P, -1., 0., 0.); + dist = ccdVec3PointTriDist2(&P, &a, &b, &c, &w); + assertTrue(ccdEq(dist, 0.)); + assertTrue(ccdVec3Eq(&w, &a)); + + ccdVec3Set(&P, 0., 1., 1.); + dist = ccdVec3PointTriDist2(&P, &a, &b, &c, &w); + assertTrue(ccdEq(dist, 0.)); + assertTrue(ccdVec3Eq(&w, &b)); + + ccdVec3Set(&P, -1., 0., 1.); + dist = ccdVec3PointTriDist2(&P, &a, &b, &c, &w); + assertTrue(ccdEq(dist, 0.)); + assertTrue(ccdVec3Eq(&w, &c)); + + ccdVec3Set(&P, 0., 0., 0.); + dist = ccdVec3PointTriDist2(&P, &a, &b, &c, NULL); + assertTrue(ccdEq(dist, 2./3.)); + + + // region 4 + ccdVec3Set(&P, -2., 0., 0.); + dist = ccdVec3PointTriDist2(&P, &a, &b, &c, &w); + assertTrue(ccdEq(dist, ccdVec3Dist2(&P, &a))); + assertTrue(ccdVec3Eq(&w, &a)); + ccdVec3Set(&P, -2., 0.2, -1.); + dist = ccdVec3PointTriDist2(&P, &a, &b, &c, &w); + assertTrue(ccdEq(dist, ccdVec3Dist2(&P, &a))); + assertTrue(ccdVec3Eq(&w, &a)); + + // region 2 + ccdVec3Set(&P, -1.3, 0., 1.2); + dist = ccdVec3PointTriDist2(&P, &a, &b, &c, &w); + assertTrue(ccdEq(dist, ccdVec3Dist2(&P, &c))); + assertTrue(ccdVec3Eq(&w, &c)); + ccdVec3Set(&P, -1.2, 0.2, 1.1); + dist = ccdVec3PointTriDist2(&P, &a, &b, &c, &w); + assertTrue(ccdEq(dist, ccdVec3Dist2(&P, &c))); + assertTrue(ccdVec3Eq(&w, &c)); + + // region 6 + ccdVec3Set(&P, 0.3, 1., 1.); + dist = ccdVec3PointTriDist2(&P, &a, &b, &c, &w); + assertTrue(ccdEq(dist, ccdVec3Dist2(&P, &b))); + assertTrue(ccdVec3Eq(&w, &b)); + ccdVec3Set(&P, .1, 1., 1.); + dist = ccdVec3PointTriDist2(&P, &a, &b, &c, &w); + assertTrue(ccdEq(dist, ccdVec3Dist2(&P, &b))); + assertTrue(ccdVec3Eq(&w, &b)); + + // region 1 + ccdVec3Set(&P, 0., 1., 2.); + dist = ccdVec3PointTriDist2(&P, &a, &b, &c, &w); + assertTrue(ccdEq(dist, 1.)); + assertTrue(ccdVec3Eq(&w, &b)); + ccdVec3Set(&P, -1., 0., 2.); + dist = ccdVec3PointTriDist2(&P, &a, &b, &c, &w); + assertTrue(ccdEq(dist, 1.)); + assertTrue(ccdVec3Eq(&w, &c)); + ccdVec3Set(&P, -0.5, 0.5, 2.); + dist = ccdVec3PointTriDist2(&P, &a, &b, &c, &w); + assertTrue(ccdEq(dist, 1.)); + ccdVec3Set(&P0, -0.5, 0.5, 1.); + assertTrue(ccdVec3Eq(&w, &P0)); + + // region 3 + ccdVec3Set(&P, -2., -1., 0.7); + dist = ccdVec3PointTriDist2(&P, &a, &b, &c, &w); + assertTrue(ccdEq(dist, 2.)); + ccdVec3Set(&P0, -1., 0., 0.7); + assertTrue(ccdVec3Eq(&w, &P0)); + + // region 5 + ccdVec3Set(&P, 0., 0., 0.); + dist = ccdVec3PointTriDist2(&P, &a, &b, &c, &w); + assertTrue(ccdEq(dist, 2./3.)); + ccdVec3Set(&P0, -2./3., 1./3., 1./3.); + assertTrue(ccdVec3Eq(&w, &P0)); + + // region 0 + ccdVec3Set(&P, -0.5, 0.5, 0.5); + dist = ccdVec3PointTriDist2(&P, &a, &b, &c, &w); + assertTrue(ccdEq(dist, 0.)); + assertTrue(ccdVec3Eq(&w, &P)); + ccdVec3Set(&P, -0.5, 0.5, 0.7); + dist = ccdVec3PointTriDist2(&P, &a, &b, &c, &w); + assertTrue(ccdEq(dist, 0.)); + assertTrue(ccdVec3Eq(&w, &P)); + ccdVec3Set(&P, -0.5, 0.5, 0.9); + dist = ccdVec3PointTriDist2(&P, &a, &b, &c, &w); + assertTrue(ccdEq(dist, 0.)); + assertTrue(ccdVec3Eq(&w, &P)); + + ccdVec3Set(&P, 0., 0., 0.5); + dist = ccdVec3PointTriDist2(&P, &a, &b, &c, &w); + assertTrue(ccdEq(dist, 0.5)); + ccdVec3Set(&P0, -.5, .5, .5); + assertTrue(ccdVec3Eq(&w, &P0)); + + ccdVec3Set(&a, -1., 0., 0.); + ccdVec3Set(&b, 0., 1., -1.); + ccdVec3Set(&c, 0., 1., 1.); + ccdVec3Set(&P, 0., 0., 0.); + dist = ccdVec3PointTriDist2(&P, &a, &b, &c, &w); + assertTrue(ccdEq(dist, 0.5)); + ccdVec3Set(&P0, -.5, .5, 0.); + assertTrue(ccdVec3Eq(&w, &P0)); + //fprintf(stderr, "dist: %lf\n", dist); +} diff --git a/libs/ode-0.16.1/libccd/src/testsuites/vec3.h b/libs/ode-0.16.1/libccd/src/testsuites/vec3.h new file mode 100644 index 0000000..2055947 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/testsuites/vec3.h @@ -0,0 +1,20 @@ +#ifndef TEST_VEC3_H +#define TEST_VEC3_H + +#include <cu/cu.h> + +TEST(vec3SetUp); +TEST(vec3TearDown); +TEST(vec3PointSegmentDist); +TEST(vec3PointTriDist); + +TEST_SUITE(TSVec3) { + TEST_ADD(vec3SetUp), + + TEST_ADD(vec3PointSegmentDist), + TEST_ADD(vec3PointTriDist), + + TEST_ADD(vec3TearDown), + TEST_SUITE_CLOSURE +}; +#endif diff --git a/libs/ode-0.16.1/libccd/src/vec3.c b/libs/ode-0.16.1/libccd/src/vec3.c new file mode 100644 index 0000000..f1a0804 --- /dev/null +++ b/libs/ode-0.16.1/libccd/src/vec3.c @@ -0,0 +1,215 @@ +/*** + * libccd + * --------------------------------- + * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz> + * + * + * This file is part of libccd. + * + * Distributed under the OSI-approved BSD License (the "License"); + * see accompanying file BDS-LICENSE for details or see + * <http://www.opensource.org/licenses/bsd-license.php>. + * + * This software is distributed WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the License for more information. + */ + +#include <stdio.h> +#include <ccd/vec3.h> +#include <ccd/dbg.h> + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +static CCD_VEC3(__ccd_vec3_origin, CCD_ZERO, CCD_ZERO, CCD_ZERO); +ccd_vec3_t *ccd_vec3_origin = &__ccd_vec3_origin; + +static ccd_vec3_t points_on_sphere[] = { + CCD_VEC3_STATIC(CCD_REAL( 0.000000), CCD_REAL(-0.000000), CCD_REAL(-1.000000)), + CCD_VEC3_STATIC(CCD_REAL( 0.723608), CCD_REAL(-0.525725), CCD_REAL(-0.447219)), + CCD_VEC3_STATIC(CCD_REAL(-0.276388), CCD_REAL(-0.850649), CCD_REAL(-0.447219)), + CCD_VEC3_STATIC(CCD_REAL(-0.894426), CCD_REAL(-0.000000), CCD_REAL(-0.447216)), + CCD_VEC3_STATIC(CCD_REAL(-0.276388), CCD_REAL( 0.850649), CCD_REAL(-0.447220)), + CCD_VEC3_STATIC(CCD_REAL( 0.723608), CCD_REAL( 0.525725), CCD_REAL(-0.447219)), + CCD_VEC3_STATIC(CCD_REAL( 0.276388), CCD_REAL(-0.850649), CCD_REAL( 0.447220)), + CCD_VEC3_STATIC(CCD_REAL(-0.723608), CCD_REAL(-0.525725), CCD_REAL( 0.447219)), + CCD_VEC3_STATIC(CCD_REAL(-0.723608), CCD_REAL( 0.525725), CCD_REAL( 0.447219)), + CCD_VEC3_STATIC(CCD_REAL( 0.276388), CCD_REAL( 0.850649), CCD_REAL( 0.447219)), + CCD_VEC3_STATIC(CCD_REAL( 0.894426), CCD_REAL( 0.000000), CCD_REAL( 0.447216)), + CCD_VEC3_STATIC(CCD_REAL(-0.000000), CCD_REAL( 0.000000), CCD_REAL( 1.000000)), + CCD_VEC3_STATIC(CCD_REAL( 0.425323), CCD_REAL(-0.309011), CCD_REAL(-0.850654)), + CCD_VEC3_STATIC(CCD_REAL(-0.162456), CCD_REAL(-0.499995), CCD_REAL(-0.850654)), + CCD_VEC3_STATIC(CCD_REAL( 0.262869), CCD_REAL(-0.809012), CCD_REAL(-0.525738)), + CCD_VEC3_STATIC(CCD_REAL( 0.425323), CCD_REAL( 0.309011), CCD_REAL(-0.850654)), + CCD_VEC3_STATIC(CCD_REAL( 0.850648), CCD_REAL(-0.000000), CCD_REAL(-0.525736)), + CCD_VEC3_STATIC(CCD_REAL(-0.525730), CCD_REAL(-0.000000), CCD_REAL(-0.850652)), + CCD_VEC3_STATIC(CCD_REAL(-0.688190), CCD_REAL(-0.499997), CCD_REAL(-0.525736)), + CCD_VEC3_STATIC(CCD_REAL(-0.162456), CCD_REAL( 0.499995), CCD_REAL(-0.850654)), + CCD_VEC3_STATIC(CCD_REAL(-0.688190), CCD_REAL( 0.499997), CCD_REAL(-0.525736)), + CCD_VEC3_STATIC(CCD_REAL( 0.262869), CCD_REAL( 0.809012), CCD_REAL(-0.525738)), + CCD_VEC3_STATIC(CCD_REAL( 0.951058), CCD_REAL( 0.309013), CCD_REAL( 0.000000)), + CCD_VEC3_STATIC(CCD_REAL( 0.951058), CCD_REAL(-0.309013), CCD_REAL( 0.000000)), + CCD_VEC3_STATIC(CCD_REAL( 0.587786), CCD_REAL(-0.809017), CCD_REAL( 0.000000)), + CCD_VEC3_STATIC(CCD_REAL( 0.000000), CCD_REAL(-1.000000), CCD_REAL( 0.000000)), + CCD_VEC3_STATIC(CCD_REAL(-0.587786), CCD_REAL(-0.809017), CCD_REAL( 0.000000)), + CCD_VEC3_STATIC(CCD_REAL(-0.951058), CCD_REAL(-0.309013), CCD_REAL(-0.000000)), + CCD_VEC3_STATIC(CCD_REAL(-0.951058), CCD_REAL( 0.309013), CCD_REAL(-0.000000)), + CCD_VEC3_STATIC(CCD_REAL(-0.587786), CCD_REAL( 0.809017), CCD_REAL(-0.000000)), + CCD_VEC3_STATIC(CCD_REAL(-0.000000), CCD_REAL( 1.000000), CCD_REAL(-0.000000)), + CCD_VEC3_STATIC(CCD_REAL( 0.587786), CCD_REAL( 0.809017), CCD_REAL(-0.000000)), + CCD_VEC3_STATIC(CCD_REAL( 0.688190), CCD_REAL(-0.499997), CCD_REAL( 0.525736)), + CCD_VEC3_STATIC(CCD_REAL(-0.262869), CCD_REAL(-0.809012), CCD_REAL( 0.525738)), + CCD_VEC3_STATIC(CCD_REAL(-0.850648), CCD_REAL( 0.000000), CCD_REAL( 0.525736)), + CCD_VEC3_STATIC(CCD_REAL(-0.262869), CCD_REAL( 0.809012), CCD_REAL( 0.525738)), + CCD_VEC3_STATIC(CCD_REAL( 0.688190), CCD_REAL( 0.499997), CCD_REAL( 0.525736)), + CCD_VEC3_STATIC(CCD_REAL( 0.525730), CCD_REAL( 0.000000), CCD_REAL( 0.850652)), + CCD_VEC3_STATIC(CCD_REAL( 0.162456), CCD_REAL(-0.499995), CCD_REAL( 0.850654)), + CCD_VEC3_STATIC(CCD_REAL(-0.425323), CCD_REAL(-0.309011), CCD_REAL( 0.850654)), + CCD_VEC3_STATIC(CCD_REAL(-0.425323), CCD_REAL( 0.309011), CCD_REAL( 0.850654)), + CCD_VEC3_STATIC(CCD_REAL( 0.162456), CCD_REAL( 0.499995), CCD_REAL( 0.850654)) +}; +ccd_vec3_t *ccd_points_on_sphere = points_on_sphere; +size_t ccd_points_on_sphere_len = sizeof(points_on_sphere) / sizeof(ccd_vec3_t); + + +_ccd_inline ccd_real_t __ccdVec3PointSegmentDist2(const ccd_vec3_t *P, + const ccd_vec3_t *x0, + const ccd_vec3_t *b, + ccd_vec3_t *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. + + ccd_real_t dist, t; + ccd_vec3_t d, a; + + // direction of segment + ccdVec3Sub2(&d, b, x0); + + // precompute vector from P to x0 + ccdVec3Sub2(&a, x0, P); + + t = -CCD_REAL(1.) * ccdVec3Dot(&a, &d); + t /= ccdVec3Len2(&d); + + if (t < CCD_ZERO || ccdIsZero(t)){ + dist = ccdVec3Dist2(x0, P); + if (witness) + ccdVec3Copy(witness, x0); + }else if (t > CCD_ONE || ccdEq(t, CCD_ONE)){ + dist = ccdVec3Dist2(b, P); + if (witness) + ccdVec3Copy(witness, b); + }else{ + if (witness){ + ccdVec3Copy(witness, &d); + ccdVec3Scale(witness, t); + ccdVec3Add(witness, x0); + dist = ccdVec3Dist2(witness, P); + }else{ + // recycling variables + ccdVec3Scale(&d, t); + ccdVec3Add(&d, &a); + dist = ccdVec3Len2(&d); + } + } + + return dist; +} + +ccd_real_t ccdVec3PointSegmentDist2(const ccd_vec3_t *P, + const ccd_vec3_t *x0, const ccd_vec3_t *b, + ccd_vec3_t *witness) +{ + return __ccdVec3PointSegmentDist2(P, x0, b, witness); +} + +ccd_real_t ccdVec3PointTriDist2(const ccd_vec3_t *P, + const ccd_vec3_t *x0, const ccd_vec3_t *B, + const ccd_vec3_t *C, + ccd_vec3_t *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. + + ccd_vec3_t d1, d2, a; + ccd_real_t u, v, w, p, q, r; + ccd_real_t s, t, dist, dist2; + ccd_vec3_t witness2; + + ccdVec3Sub2(&d1, B, x0); + ccdVec3Sub2(&d2, C, x0); + ccdVec3Sub2(&a, x0, P); + + u = ccdVec3Dot(&a, &a); + v = ccdVec3Dot(&d1, &d1); + w = ccdVec3Dot(&d2, &d2); + p = ccdVec3Dot(&a, &d1); + q = ccdVec3Dot(&a, &d2); + r = ccdVec3Dot(&d1, &d2); + + s = (q * r - w * p) / (w * v - r * r); + t = (-s * r - q) / w; + + if ((ccdIsZero(s) || s > CCD_ZERO) + && (ccdEq(s, CCD_ONE) || s < CCD_ONE) + && (ccdIsZero(t) || t > CCD_ZERO) + && (ccdEq(t, CCD_ONE) || t < CCD_ONE) + && (ccdEq(t + s, CCD_ONE) || t + s < CCD_ONE)){ + + if (witness){ + ccdVec3Scale(&d1, s); + ccdVec3Scale(&d2, t); + ccdVec3Copy(witness, x0); + ccdVec3Add(witness, &d1); + ccdVec3Add(witness, &d2); + + dist = ccdVec3Dist2(witness, P); + }else{ + dist = s * s * v; + dist += t * t * w; + dist += CCD_REAL(2.) * s * t * r; + dist += CCD_REAL(2.) * s * p; + dist += CCD_REAL(2.) * t * q; + dist += u; + } + }else{ + dist = __ccdVec3PointSegmentDist2(P, x0, B, witness); + + dist2 = __ccdVec3PointSegmentDist2(P, x0, C, &witness2); + if (dist2 < dist){ + dist = dist2; + if (witness) + ccdVec3Copy(witness, &witness2); + } + + dist2 = __ccdVec3PointSegmentDist2(P, B, C, &witness2); + if (dist2 < dist){ + dist = dist2; + if (witness) + ccdVec3Copy(witness, &witness2); + } + } + + return dist; +} diff --git a/libs/ode-0.16.1/ltmain.sh b/libs/ode-0.16.1/ltmain.sh new file mode 100644 index 0000000..147d758 --- /dev/null +++ b/libs/ode-0.16.1/ltmain.sh @@ -0,0 +1,11156 @@ +#! /bin/sh +## DO NOT EDIT - This file generated from ./build-aux/ltmain.in +## by inline-source v2014-01-03.01 + +# libtool (GNU libtool) 2.4.6 +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 + +# Copyright (C) 1996-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool 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 2 of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 <http://www.gnu.org/licenses/>. + + +PROGRAM=libtool +PACKAGE=libtool +VERSION="2.4.6 Debian-2.4.6-0.1" +package_revision=2.4.6 + + +## ------ ## +## Usage. ## +## ------ ## + +# Run './libtool --help' for help with using this script from the +# command line. + + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# After configure completes, it has a better idea of some of the +# shell tools we need than the defaults used by the functions shared +# with bootstrap, so set those here where they can still be over- +# ridden by the user, but otherwise take precedence. + +: ${AUTOCONF="autoconf"} +: ${AUTOMAKE="automake"} + + +## -------------------------- ## +## Source external libraries. ## +## -------------------------- ## + +# Much of our low-level functionality needs to be sourced from external +# libraries, which are installed to $pkgauxdir. + +# Set a version string for this script. +scriptversion=2015-01-20.17; # UTC + +# General shell script boiler plate, and helper functions. +# Written by Gary V. Vaughan, 2004 + +# Copyright (C) 2004-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# 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. + +# As a special exception to the GNU General Public License, if you distribute +# this file as part of a program or library that is built using GNU Libtool, +# you may include this file under the same distribution terms that you use +# for the rest of that program. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNES 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 <http://www.gnu.org/licenses/>. + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# Evaluate this file near the top of your script to gain access to +# the functions and variables defined here: +# +# . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh +# +# If you need to override any of the default environment variable +# settings, do that before evaluating this file. + + +## -------------------- ## +## Shell normalisation. ## +## -------------------- ## + +# Some shells need a little help to be as Bourne compatible as possible. +# Before doing anything else, make sure all that help has been provided! + +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac +fi + +# NLS nuisances: We save the old values in case they are required later. +_G_user_locale= +_G_safe_locale= +for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test set = \"\${$_G_var+set}\"; then + save_$_G_var=\$$_G_var + $_G_var=C + export $_G_var + _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" + _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" + fi" +done + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Make sure IFS has a sensible default +sp=' ' +nl=' +' +IFS="$sp $nl" + +# There are apparently some retarded systems that use ';' as a PATH separator! +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + + +## ------------------------- ## +## Locate command utilities. ## +## ------------------------- ## + + +# func_executable_p FILE +# ---------------------- +# Check that FILE is an executable regular file. +func_executable_p () +{ + test -f "$1" && test -x "$1" +} + + +# func_path_progs PROGS_LIST CHECK_FUNC [PATH] +# -------------------------------------------- +# Search for either a program that responds to --version with output +# containing "GNU", or else returned by CHECK_FUNC otherwise, by +# trying all the directories in PATH with each of the elements of +# PROGS_LIST. +# +# CHECK_FUNC should accept the path to a candidate program, and +# set $func_check_prog_result if it truncates its output less than +# $_G_path_prog_max characters. +func_path_progs () +{ + _G_progs_list=$1 + _G_check_func=$2 + _G_PATH=${3-"$PATH"} + + _G_path_prog_max=0 + _G_path_prog_found=false + _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} + for _G_dir in $_G_PATH; do + IFS=$_G_save_IFS + test -z "$_G_dir" && _G_dir=. + for _G_prog_name in $_G_progs_list; do + for _exeext in '' .EXE; do + _G_path_prog=$_G_dir/$_G_prog_name$_exeext + func_executable_p "$_G_path_prog" || continue + case `"$_G_path_prog" --version 2>&1` in + *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; + *) $_G_check_func $_G_path_prog + func_path_progs_result=$func_check_prog_result + ;; + esac + $_G_path_prog_found && break 3 + done + done + done + IFS=$_G_save_IFS + test -z "$func_path_progs_result" && { + echo "no acceptable sed could be found in \$PATH" >&2 + exit 1 + } +} + + +# We want to be able to use the functions in this file before configure +# has figured out where the best binaries are kept, which means we have +# to search for them ourselves - except when the results are already set +# where we skip the searches. + +# Unless the user overrides by setting SED, search the path for either GNU +# sed, or the sed that truncates its output the least. +test -z "$SED" && { + _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for _G_i in 1 2 3 4 5 6 7; do + _G_sed_script=$_G_sed_script$nl$_G_sed_script + done + echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed + _G_sed_script= + + func_check_prog_sed () + { + _G_path_prog=$1 + + _G_count=0 + printf 0123456789 >conftest.in + while : + do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo '' >> conftest.nl + "$_G_path_prog" -f conftest.sed <conftest.nl >conftest.out 2>/dev/null || break + diff conftest.out conftest.nl >/dev/null 2>&1 || break + _G_count=`expr $_G_count + 1` + if test "$_G_count" -gt "$_G_path_prog_max"; then + # Best one so far, save it but keep looking for a better one + func_check_prog_result=$_G_path_prog + _G_path_prog_max=$_G_count + fi + # 10*(2^10) chars as input seems more than enough + test 10 -lt "$_G_count" && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out + } + + func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin + rm -f conftest.sed + SED=$func_path_progs_result +} + + +# Unless the user overrides by setting GREP, search the path for either GNU +# grep, or the grep that truncates its output the least. +test -z "$GREP" && { + func_check_prog_grep () + { + _G_path_prog=$1 + + _G_count=0 + _G_path_prog_max=0 + printf 0123456789 >conftest.in + while : + do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo 'GREP' >> conftest.nl + "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' <conftest.nl >conftest.out 2>/dev/null || break + diff conftest.out conftest.nl >/dev/null 2>&1 || break + _G_count=`expr $_G_count + 1` + if test "$_G_count" -gt "$_G_path_prog_max"; then + # Best one so far, save it but keep looking for a better one + func_check_prog_result=$_G_path_prog + _G_path_prog_max=$_G_count + fi + # 10*(2^10) chars as input seems more than enough + test 10 -lt "$_G_count" && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out + } + + func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin + GREP=$func_path_progs_result +} + + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# All uppercase variable names are used for environment variables. These +# variables can be overridden by the user before calling a script that +# uses them if a suitable command of that name is not already available +# in the command search PATH. + +: ${CP="cp -f"} +: ${ECHO="printf %s\n"} +: ${EGREP="$GREP -E"} +: ${FGREP="$GREP -F"} +: ${LN_S="ln -s"} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} + + +## -------------------- ## +## Useful sed snippets. ## +## -------------------- ## + +sed_dirname='s|/[^/]*$||' +sed_basename='s|^.*/||' + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='s|\([`"$\\]\)|\\\1|g' + +# Same as above, but do not quote variable references. +sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' + +# Sed substitution that converts a w32 file name or path +# that contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + +# Re-'\' parameter expansions in output of sed_double_quote_subst that +# were '\'-ed in input to the same. If an odd number of '\' preceded a +# '$' in input to sed_double_quote_subst, that '$' was protected from +# expansion. Since each input '\' is now two '\'s, look for any number +# of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. +_G_bs='\\' +_G_bs2='\\\\' +_G_bs4='\\\\\\\\' +_G_dollar='\$' +sed_double_backslash="\ + s/$_G_bs4/&\\ +/g + s/^$_G_bs2$_G_dollar/$_G_bs&/ + s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g + s/\n//g" + + +## ----------------- ## +## Global variables. ## +## ----------------- ## + +# Except for the global variables explicitly listed below, the following +# functions in the '^func_' namespace, and the '^require_' namespace +# variables initialised in the 'Resource management' section, sourcing +# this file will not pollute your global namespace with anything +# else. There's no portable way to scope variables in Bourne shell +# though, so actually running these functions will sometimes place +# results into a variable named after the function, and often use +# temporary variables in the '^_G_' namespace. If you are careful to +# avoid using those namespaces casually in your sourcing script, things +# should continue to work as you expect. And, of course, you can freely +# overwrite any of the functions or variables defined here before +# calling anything to customize them. + +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +# Allow overriding, eg assuming that you follow the convention of +# putting '$debug_cmd' at the start of all your functions, you can get +# bash to show function call trace with: +# +# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name +debug_cmd=${debug_cmd-":"} +exit_cmd=: + +# By convention, finish your script with: +# +# exit $exit_status +# +# so that you can set exit_status to non-zero if you want to indicate +# something went wrong during execution without actually bailing out at +# the point of failure. +exit_status=$EXIT_SUCCESS + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath=$0 + +# The name of this program. +progname=`$ECHO "$progpath" |$SED "$sed_basename"` + +# Make sure we have an absolute progpath for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` + progdir=`cd "$progdir" && pwd` + progpath=$progdir/$progname + ;; + *) + _G_IFS=$IFS + IFS=${PATH_SEPARATOR-:} + for progdir in $PATH; do + IFS=$_G_IFS + test -x "$progdir/$progname" && break + done + IFS=$_G_IFS + test -n "$progdir" || progdir=`pwd` + progpath=$progdir/$progname + ;; +esac + + +## ----------------- ## +## Standard options. ## +## ----------------- ## + +# The following options affect the operation of the functions defined +# below, and should be set appropriately depending on run-time para- +# meters passed on the command line. + +opt_dry_run=false +opt_quiet=false +opt_verbose=false + +# Categories 'all' and 'none' are always available. Append any others +# you will pass as the first argument to func_warning from your own +# code. +warning_categories= + +# By default, display warnings according to 'opt_warning_types'. Set +# 'warning_func' to ':' to elide all warnings, or func_fatal_error to +# treat the next displayed warning as a fatal error. +warning_func=func_warn_and_continue + +# Set to 'all' to display all warnings, 'none' to suppress all +# warnings, or a space delimited list of some subset of +# 'warning_categories' to display only the listed warnings. +opt_warning_types=all + + +## -------------------- ## +## Resource management. ## +## -------------------- ## + +# This section contains definitions for functions that each ensure a +# particular resource (a file, or a non-empty configuration variable for +# example) is available, and if appropriate to extract default values +# from pertinent package files. Call them using their associated +# 'require_*' variable to ensure that they are executed, at most, once. +# +# It's entirely deliberate that calling these functions can set +# variables that don't obey the namespace limitations obeyed by the rest +# of this file, in order that that they be as useful as possible to +# callers. + + +# require_term_colors +# ------------------- +# Allow display of bold text on terminals that support it. +require_term_colors=func_require_term_colors +func_require_term_colors () +{ + $debug_cmd + + test -t 1 && { + # COLORTERM and USE_ANSI_COLORS environment variables take + # precedence, because most terminfo databases neglect to describe + # whether color sequences are supported. + test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} + + if test 1 = "$USE_ANSI_COLORS"; then + # Standard ANSI escape sequences + tc_reset='[0m' + tc_bold='[1m'; tc_standout='[7m' + tc_red='[31m'; tc_green='[32m' + tc_blue='[34m'; tc_cyan='[36m' + else + # Otherwise trust the terminfo database after all. + test -n "`tput sgr0 2>/dev/null`" && { + tc_reset=`tput sgr0` + test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` + tc_standout=$tc_bold + test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` + test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` + test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` + test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` + test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` + } + fi + } + + require_term_colors=: +} + + +## ----------------- ## +## Function library. ## +## ----------------- ## + +# This section contains a variety of useful functions to call in your +# scripts. Take note of the portable wrappers for features provided by +# some modern shells, which will fall back to slower equivalents on +# less featureful shells. + + +# func_append VAR VALUE +# --------------------- +# Append VALUE onto the existing contents of VAR. + + # We should try to minimise forks, especially on Windows where they are + # unreasonably slow, so skip the feature probes when bash or zsh are + # being used: + if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then + : ${_G_HAVE_ARITH_OP="yes"} + : ${_G_HAVE_XSI_OPS="yes"} + # The += operator was introduced in bash 3.1 + case $BASH_VERSION in + [12].* | 3.0 | 3.0*) ;; + *) + : ${_G_HAVE_PLUSEQ_OP="yes"} + ;; + esac + fi + + # _G_HAVE_PLUSEQ_OP + # Can be empty, in which case the shell is probed, "yes" if += is + # useable or anything else if it does not work. + test -z "$_G_HAVE_PLUSEQ_OP" \ + && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ + && _G_HAVE_PLUSEQ_OP=yes + +if test yes = "$_G_HAVE_PLUSEQ_OP" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_append () + { + $debug_cmd + + eval "$1+=\$2" + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_append () + { + $debug_cmd + + eval "$1=\$$1\$2" + } +fi + + +# func_append_quoted VAR VALUE +# ---------------------------- +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +if test yes = "$_G_HAVE_PLUSEQ_OP"; then + eval 'func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1+=\\ \$func_quote_for_eval_result" + }' +else + func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1=\$$1\\ \$func_quote_for_eval_result" + } +fi + + +# func_append_uniq VAR VALUE +# -------------------------- +# Append unique VALUE onto the existing contents of VAR, assuming +# entries are delimited by the first character of VALUE. For example: +# +# func_append_uniq options " --another-option option-argument" +# +# will only append to $options if " --another-option option-argument " +# is not already present somewhere in $options already (note spaces at +# each end implied by leading space in second argument). +func_append_uniq () +{ + $debug_cmd + + eval _G_current_value='`$ECHO $'$1'`' + _G_delim=`expr "$2" : '\(.\)'` + + case $_G_delim$_G_current_value$_G_delim in + *"$2$_G_delim"*) ;; + *) func_append "$@" ;; + esac +} + + +# func_arith TERM... +# ------------------ +# Set func_arith_result to the result of evaluating TERMs. + test -z "$_G_HAVE_ARITH_OP" \ + && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ + && _G_HAVE_ARITH_OP=yes + +if test yes = "$_G_HAVE_ARITH_OP"; then + eval 'func_arith () + { + $debug_cmd + + func_arith_result=$(( $* )) + }' +else + func_arith () + { + $debug_cmd + + func_arith_result=`expr "$@"` + } +fi + + +# func_basename FILE +# ------------------ +# Set func_basename_result to FILE with everything up to and including +# the last / stripped. +if test yes = "$_G_HAVE_XSI_OPS"; then + # If this shell supports suffix pattern removal, then use it to avoid + # forking. Hide the definitions single quotes in case the shell chokes + # on unsupported syntax... + _b='func_basename_result=${1##*/}' + _d='case $1 in + */*) func_dirname_result=${1%/*}$2 ;; + * ) func_dirname_result=$3 ;; + esac' + +else + # ...otherwise fall back to using sed. + _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' + _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` + if test "X$func_dirname_result" = "X$1"; then + func_dirname_result=$3 + else + func_append func_dirname_result "$2" + fi' +fi + +eval 'func_basename () +{ + $debug_cmd + + '"$_b"' +}' + + +# func_dirname FILE APPEND NONDIR_REPLACEMENT +# ------------------------------------------- +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +eval 'func_dirname () +{ + $debug_cmd + + '"$_d"' +}' + + +# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT +# -------------------------------------------------------- +# Perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# For efficiency, we do not delegate to the functions above but instead +# duplicate the functionality here. +eval 'func_dirname_and_basename () +{ + $debug_cmd + + '"$_b"' + '"$_d"' +}' + + +# func_echo ARG... +# ---------------- +# Echo program name prefixed message. +func_echo () +{ + $debug_cmd + + _G_message=$* + + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $ECHO "$progname: $_G_line" + done + IFS=$func_echo_IFS +} + + +# func_echo_all ARG... +# -------------------- +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + + +# func_echo_infix_1 INFIX ARG... +# ------------------------------ +# Echo program name, followed by INFIX on the first line, with any +# additional lines not showing INFIX. +func_echo_infix_1 () +{ + $debug_cmd + + $require_term_colors + + _G_infix=$1; shift + _G_indent=$_G_infix + _G_prefix="$progname: $_G_infix: " + _G_message=$* + + # Strip color escape sequences before counting printable length + for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" + do + test -n "$_G_tc" && { + _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` + _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` + } + done + _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes + + func_echo_infix_1_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_infix_1_IFS + $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 + _G_prefix=$_G_indent + done + IFS=$func_echo_infix_1_IFS +} + + +# func_error ARG... +# ----------------- +# Echo program name prefixed message to standard error. +func_error () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 +} + + +# func_fatal_error ARG... +# ----------------------- +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + $debug_cmd + + func_error "$*" + exit $EXIT_FAILURE +} + + +# func_grep EXPRESSION FILENAME +# ----------------------------- +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $debug_cmd + + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_len STRING +# --------------- +# Set func_len_result to the length of STRING. STRING may not +# start with a hyphen. + test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_len () + { + $debug_cmd + + func_len_result=${#1} + }' +else + func_len () + { + $debug_cmd + + func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` + } +fi + + +# func_mkdir_p DIRECTORY-PATH +# --------------------------- +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + $debug_cmd + + _G_directory_path=$1 + _G_dir_list= + + if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then + + # Protect directory names starting with '-' + case $_G_directory_path in + -*) _G_directory_path=./$_G_directory_path ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$_G_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + _G_dir_list=$_G_directory_path:$_G_dir_list + + # If the last portion added has no slash in it, the list is done + case $_G_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` + done + _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` + + func_mkdir_p_IFS=$IFS; IFS=: + for _G_dir in $_G_dir_list; do + IFS=$func_mkdir_p_IFS + # mkdir can fail with a 'File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$_G_dir" 2>/dev/null || : + done + IFS=$func_mkdir_p_IFS + + # Bail out if we (or some other process) failed to create a directory. + test -d "$_G_directory_path" || \ + func_fatal_error "Failed to create '$1'" + fi +} + + +# func_mktempdir [BASENAME] +# ------------------------- +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, BASENAME is the basename for that directory. +func_mktempdir () +{ + $debug_cmd + + _G_template=${TMPDIR-/tmp}/${1-$progname} + + if test : = "$opt_dry_run"; then + # Return a directory name, but don't create it in dry-run mode + _G_tmpdir=$_G_template-$$ + else + + # If mktemp works, use that first and foremost + _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` + + if test ! -d "$_G_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + _G_tmpdir=$_G_template-${RANDOM-0}$$ + + func_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$_G_tmpdir" + umask $func_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$_G_tmpdir" || \ + func_fatal_error "cannot create temporary directory '$_G_tmpdir'" + fi + + $ECHO "$_G_tmpdir" +} + + +# func_normal_abspath PATH +# ------------------------ +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +func_normal_abspath () +{ + $debug_cmd + + # These SED scripts presuppose an absolute path with a trailing slash. + _G_pathcar='s|^/\([^/]*\).*$|\1|' + _G_pathcdr='s|^/[^/]*||' + _G_removedotparts=':dotsl + s|/\./|/|g + t dotsl + s|/\.$|/|' + _G_collapseslashes='s|/\{1,\}|/|g' + _G_finalslash='s|/*$|/|' + + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` + while :; do + # Processed it all yet? + if test / = "$func_normal_abspath_tpath"; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result"; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + + +# func_notquiet ARG... +# -------------------- +# Echo program name prefixed message only when not in quiet mode. +func_notquiet () +{ + $debug_cmd + + $opt_quiet || func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + + +# func_relative_path SRCDIR DSTDIR +# -------------------------------- +# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. +func_relative_path () +{ + $debug_cmd + + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=$func_dirname_result + if test -z "$func_relative_path_tlibdir"; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test -n "$func_stripname_result"; then + func_append func_relative_path_result "/$func_stripname_result" + fi + + # Normalisation. If bindir is libdir, return '.' else relative path. + if test -n "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + fi + + test -n "$func_relative_path_result" || func_relative_path_result=. + + : +} + + +# func_quote_for_eval ARG... +# -------------------------- +# Aesthetically quote ARGs to be evaled later. +# This function returns two values: +# i) func_quote_for_eval_result +# double-quoted, suitable for a subsequent eval +# ii) func_quote_for_eval_unquoted_result +# has all characters that are still active within double +# quotes backslashified. +func_quote_for_eval () +{ + $debug_cmd + + func_quote_for_eval_unquoted_result= + func_quote_for_eval_result= + while test 0 -lt $#; do + case $1 in + *[\\\`\"\$]*) + _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; + *) + _G_unquoted_arg=$1 ;; + esac + if test -n "$func_quote_for_eval_unquoted_result"; then + func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" + else + func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" + fi + + case $_G_unquoted_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and variable expansion + # for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_quoted_arg=\"$_G_unquoted_arg\" + ;; + *) + _G_quoted_arg=$_G_unquoted_arg + ;; + esac + + if test -n "$func_quote_for_eval_result"; then + func_append func_quote_for_eval_result " $_G_quoted_arg" + else + func_append func_quote_for_eval_result "$_G_quoted_arg" + fi + shift + done +} + + +# func_quote_for_expand ARG +# ------------------------- +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + $debug_cmd + + case $1 in + *[\\\`\"]*) + _G_arg=`$ECHO "$1" | $SED \ + -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; + *) + _G_arg=$1 ;; + esac + + case $_G_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_arg=\"$_G_arg\" + ;; + esac + + func_quote_for_expand_result=$_G_arg +} + + +# func_stripname PREFIX SUFFIX NAME +# --------------------------------- +# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_stripname () + { + $debug_cmd + + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary variable first. + func_stripname_result=$3 + func_stripname_result=${func_stripname_result#"$1"} + func_stripname_result=${func_stripname_result%"$2"} + }' +else + func_stripname () + { + $debug_cmd + + case $2 in + .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; + *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; + esac + } +fi + + +# func_show_eval CMD [FAIL_EXP] +# ----------------------------- +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + func_quote_for_expand "$_G_cmd" + eval "func_notquiet $func_quote_for_expand_result" + + $opt_dry_run || { + eval "$_G_cmd" + _G_status=$? + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_show_eval_locale CMD [FAIL_EXP] +# ------------------------------------ +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + $opt_quiet || { + func_quote_for_expand "$_G_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + $opt_dry_run || { + eval "$_G_user_locale + $_G_cmd" + _G_status=$? + eval "$_G_safe_locale" + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_tr_sh +# ---------- +# Turn $1 into a string suitable for a shell variable name. +# Result is stored in $func_tr_sh_result. All characters +# not in the set a-zA-Z0-9_ are replaced with '_'. Further, +# if $1 begins with a digit, a '_' is prepended as well. +func_tr_sh () +{ + $debug_cmd + + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac +} + + +# func_verbose ARG... +# ------------------- +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $debug_cmd + + $opt_verbose && func_echo "$*" + + : +} + + +# func_warn_and_continue ARG... +# ----------------------------- +# Echo program name prefixed warning message to standard error. +func_warn_and_continue () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 +} + + +# func_warning CATEGORY ARG... +# ---------------------------- +# Echo program name prefixed warning message to standard error. Warning +# messages can be filtered according to CATEGORY, where this function +# elides messages where CATEGORY is not listed in the global variable +# 'opt_warning_types'. +func_warning () +{ + $debug_cmd + + # CATEGORY must be in the warning_categories list! + case " $warning_categories " in + *" $1 "*) ;; + *) func_internal_error "invalid warning category '$1'" ;; + esac + + _G_category=$1 + shift + + case " $opt_warning_types " in + *" $_G_category "*) $warning_func ${1+"$@"} ;; + esac +} + + +# func_sort_ver VER1 VER2 +# ----------------------- +# 'sort -V' is not generally available. +# Note this deviates from the version comparison in automake +# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a +# but this should suffice as we won't be specifying old +# version formats or redundant trailing .0 in bootstrap.conf. +# If we did want full compatibility then we should probably +# use m4_version_compare from autoconf. +func_sort_ver () +{ + $debug_cmd + + printf '%s\n%s\n' "$1" "$2" \ + | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n +} + +# func_lt_ver PREV CURR +# --------------------- +# Return true if PREV and CURR are in the correct order according to +# func_sort_ver, otherwise false. Use it like this: +# +# func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." +func_lt_ver () +{ + $debug_cmd + + test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: +#! /bin/sh + +# Set a version string for this script. +scriptversion=2014-01-07.03; # UTC + +# A portable, pluggable option parser for Bourne shell. +# Written by Gary V. Vaughan, 2010 + +# Copyright (C) 2010-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# 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 <http://www.gnu.org/licenses/>. + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# This file is a library for parsing options in your shell scripts along +# with assorted other useful supporting features that you can make use +# of too. +# +# For the simplest scripts you might need only: +# +# #!/bin/sh +# . relative/path/to/funclib.sh +# . relative/path/to/options-parser +# scriptversion=1.0 +# func_options ${1+"$@"} +# eval set dummy "$func_options_result"; shift +# ...rest of your script... +# +# In order for the '--version' option to work, you will need to have a +# suitably formatted comment like the one at the top of this file +# starting with '# Written by ' and ending with '# warranty; '. +# +# For '-h' and '--help' to work, you will also need a one line +# description of your script's purpose in a comment directly above the +# '# Written by ' line, like the one at the top of this file. +# +# The default options also support '--debug', which will turn on shell +# execution tracing (see the comment above debug_cmd below for another +# use), and '--verbose' and the func_verbose function to allow your script +# to display verbose messages only when your user has specified +# '--verbose'. +# +# After sourcing this file, you can plug processing for additional +# options by amending the variables from the 'Configuration' section +# below, and following the instructions in the 'Option parsing' +# section further down. + +## -------------- ## +## Configuration. ## +## -------------- ## + +# You should override these variables in your script after sourcing this +# file so that they reflect the customisations you have added to the +# option parser. + +# The usage line for option parsing errors and the start of '-h' and +# '--help' output messages. You can embed shell variables for delayed +# expansion at the time the message is displayed, but you will need to +# quote other shell meta-characters carefully to prevent them being +# expanded when the contents are evaled. +usage='$progpath [OPTION]...' + +# Short help message in response to '-h' and '--help'. Add to this or +# override it after sourcing this library to reflect the full set of +# options your script accepts. +usage_message="\ + --debug enable verbose shell tracing + -W, --warnings=CATEGORY + report the warnings falling in CATEGORY [all] + -v, --verbose verbosely report processing + --version print version information and exit + -h, --help print short or long help message and exit +" + +# Additional text appended to 'usage_message' in response to '--help'. +long_help_message=" +Warning categories include: + 'all' show all warnings + 'none' turn off all the warnings + 'error' warnings are treated as fatal errors" + +# Help message printed before fatal option parsing errors. +fatal_help="Try '\$progname --help' for more information." + + + +## ------------------------- ## +## Hook function management. ## +## ------------------------- ## + +# This section contains functions for adding, removing, and running hooks +# to the main code. A hook is just a named list of of function, that can +# be run in order later on. + +# func_hookable FUNC_NAME +# ----------------------- +# Declare that FUNC_NAME will run hooks added with +# 'func_add_hook FUNC_NAME ...'. +func_hookable () +{ + $debug_cmd + + func_append hookable_fns " $1" +} + + +# func_add_hook FUNC_NAME HOOK_FUNC +# --------------------------------- +# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must +# first have been declared "hookable" by a call to 'func_hookable'. +func_add_hook () +{ + $debug_cmd + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not accept hook functions." ;; + esac + + eval func_append ${1}_hooks '" $2"' +} + + +# func_remove_hook FUNC_NAME HOOK_FUNC +# ------------------------------------ +# Remove HOOK_FUNC from the list of functions called by FUNC_NAME. +func_remove_hook () +{ + $debug_cmd + + eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' +} + + +# func_run_hooks FUNC_NAME [ARG]... +# --------------------------------- +# Run all hook functions registered to FUNC_NAME. +# It is assumed that the list of hook functions contains nothing more +# than a whitespace-delimited list of legal shell function names, and +# no effort is wasted trying to catch shell meta-characters or preserve +# whitespace. +func_run_hooks () +{ + $debug_cmd + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not support hook funcions.n" ;; + esac + + eval _G_hook_fns=\$$1_hooks; shift + + for _G_hook in $_G_hook_fns; do + eval $_G_hook '"$@"' + + # store returned options list back into positional + # parameters for next 'cmd' execution. + eval _G_hook_result=\$${_G_hook}_result + eval set dummy "$_G_hook_result"; shift + done + + func_quote_for_eval ${1+"$@"} + func_run_hooks_result=$func_quote_for_eval_result +} + + + +## --------------- ## +## Option parsing. ## +## --------------- ## + +# In order to add your own option parsing hooks, you must accept the +# full positional parameter list in your hook function, remove any +# options that you action, and then pass back the remaining unprocessed +# options in '<hooked_function_name>_result', escaped suitably for +# 'eval'. Like this: +# +# my_options_prep () +# { +# $debug_cmd +# +# # Extend the existing usage message. +# usage_message=$usage_message' +# -s, --silent don'\''t print informational messages +# ' +# +# func_quote_for_eval ${1+"$@"} +# my_options_prep_result=$func_quote_for_eval_result +# } +# func_add_hook func_options_prep my_options_prep +# +# +# my_silent_option () +# { +# $debug_cmd +# +# # Note that for efficiency, we parse as many options as we can +# # recognise in a loop before passing the remainder back to the +# # caller on the first unrecognised argument we encounter. +# while test $# -gt 0; do +# opt=$1; shift +# case $opt in +# --silent|-s) opt_silent=: ;; +# # Separate non-argument short options: +# -s*) func_split_short_opt "$_G_opt" +# set dummy "$func_split_short_opt_name" \ +# "-$func_split_short_opt_arg" ${1+"$@"} +# shift +# ;; +# *) set dummy "$_G_opt" "$*"; shift; break ;; +# esac +# done +# +# func_quote_for_eval ${1+"$@"} +# my_silent_option_result=$func_quote_for_eval_result +# } +# func_add_hook func_parse_options my_silent_option +# +# +# my_option_validation () +# { +# $debug_cmd +# +# $opt_silent && $opt_verbose && func_fatal_help "\ +# '--silent' and '--verbose' options are mutually exclusive." +# +# func_quote_for_eval ${1+"$@"} +# my_option_validation_result=$func_quote_for_eval_result +# } +# func_add_hook func_validate_options my_option_validation +# +# You'll alse need to manually amend $usage_message to reflect the extra +# options you parse. It's preferable to append if you can, so that +# multiple option parsing hooks can be added safely. + + +# func_options [ARG]... +# --------------------- +# All the functions called inside func_options are hookable. See the +# individual implementations for details. +func_hookable func_options +func_options () +{ + $debug_cmd + + func_options_prep ${1+"$@"} + eval func_parse_options \ + ${func_options_prep_result+"$func_options_prep_result"} + eval func_validate_options \ + ${func_parse_options_result+"$func_parse_options_result"} + + eval func_run_hooks func_options \ + ${func_validate_options_result+"$func_validate_options_result"} + + # save modified positional parameters for caller + func_options_result=$func_run_hooks_result +} + + +# func_options_prep [ARG]... +# -------------------------- +# All initialisations required before starting the option parse loop. +# Note that when calling hook functions, we pass through the list of +# positional parameters. If a hook function modifies that list, and +# needs to propogate that back to rest of this script, then the complete +# modified list must be put in 'func_run_hooks_result' before +# returning. +func_hookable func_options_prep +func_options_prep () +{ + $debug_cmd + + # Option defaults: + opt_verbose=false + opt_warning_types= + + func_run_hooks func_options_prep ${1+"$@"} + + # save modified positional parameters for caller + func_options_prep_result=$func_run_hooks_result +} + + +# func_parse_options [ARG]... +# --------------------------- +# The main option parsing loop. +func_hookable func_parse_options +func_parse_options () +{ + $debug_cmd + + func_parse_options_result= + + # this just eases exit handling + while test $# -gt 0; do + # Defer to hook functions for initial option parsing, so they + # get priority in the event of reusing an option name. + func_run_hooks func_parse_options ${1+"$@"} + + # Adjust func_parse_options positional parameters to match + eval set dummy "$func_run_hooks_result"; shift + + # Break out of the loop if we already parsed every option. + test $# -gt 0 || break + + _G_opt=$1 + shift + case $_G_opt in + --debug|-x) debug_cmd='set -x' + func_echo "enabling shell trace mode" + $debug_cmd + ;; + + --no-warnings|--no-warning|--no-warn) + set dummy --warnings none ${1+"$@"} + shift + ;; + + --warnings|--warning|-W) + test $# = 0 && func_missing_arg $_G_opt && break + case " $warning_categories $1" in + *" $1 "*) + # trailing space prevents matching last $1 above + func_append_uniq opt_warning_types " $1" + ;; + *all) + opt_warning_types=$warning_categories + ;; + *none) + opt_warning_types=none + warning_func=: + ;; + *error) + opt_warning_types=$warning_categories + warning_func=func_fatal_error + ;; + *) + func_fatal_error \ + "unsupported warning category: '$1'" + ;; + esac + shift + ;; + + --verbose|-v) opt_verbose=: ;; + --version) func_version ;; + -\?|-h) func_usage ;; + --help) func_help ;; + + # Separate optargs to long options (plugins may need this): + --*=*) func_split_equals "$_G_opt" + set dummy "$func_split_equals_lhs" \ + "$func_split_equals_rhs" ${1+"$@"} + shift + ;; + + # Separate optargs to short options: + -W*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-v*|-x*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) break ;; + -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; + *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + esac + done + + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + func_parse_options_result=$func_quote_for_eval_result +} + + +# func_validate_options [ARG]... +# ------------------------------ +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +func_hookable func_validate_options +func_validate_options () +{ + $debug_cmd + + # Display all warnings if -W was not given. + test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" + + func_run_hooks func_validate_options ${1+"$@"} + + # Bail if the options were screwed! + $exit_cmd $EXIT_FAILURE + + # save modified positional parameters for caller + func_validate_options_result=$func_run_hooks_result +} + + + +## ----------------- ## +## Helper functions. ## +## ----------------- ## + +# This section contains the helper functions used by the rest of the +# hookable option parser framework in ascii-betical order. + + +# func_fatal_help ARG... +# ---------------------- +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + $debug_cmd + + eval \$ECHO \""Usage: $usage"\" + eval \$ECHO \""$fatal_help"\" + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + + +# func_help +# --------- +# Echo long help message to standard output and exit. +func_help () +{ + $debug_cmd + + func_usage_message + $ECHO "$long_help_message" + exit 0 +} + + +# func_missing_arg ARGNAME +# ------------------------ +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + $debug_cmd + + func_error "Missing argument for '$1'." + exit_cmd=exit +} + + +# func_split_equals STRING +# ------------------------ +# Set func_split_equals_lhs and func_split_equals_rhs shell variables after +# splitting STRING at the '=' sign. +test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=${1%%=*} + func_split_equals_rhs=${1#*=} + test "x$func_split_equals_lhs" = "x$1" \ + && func_split_equals_rhs= + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` + func_split_equals_rhs= + test "x$func_split_equals_lhs" = "x$1" \ + || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` + } +fi #func_split_equals + + +# func_split_short_opt SHORTOPT +# ----------------------------- +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"} + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` + func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` + } +fi #func_split_short_opt + + +# func_usage +# ---------- +# Echo short help message to standard output and exit. +func_usage () +{ + $debug_cmd + + func_usage_message + $ECHO "Run '$progname --help |${PAGER-more}' for full usage" + exit 0 +} + + +# func_usage_message +# ------------------ +# Echo short help message to standard output. +func_usage_message () +{ + $debug_cmd + + eval \$ECHO \""Usage: $usage"\" + echo + $SED -n 's|^# || + /^Written by/{ + x;p;x + } + h + /^Written by/q' < "$progpath" + echo + eval \$ECHO \""$usage_message"\" +} + + +# func_version +# ------------ +# Echo version message to standard output and exit. +func_version () +{ + $debug_cmd + + printf '%s\n' "$progname $scriptversion" + $SED -n ' + /(C)/!b go + :more + /\./!{ + N + s|\n# | | + b more + } + :go + /^# Written by /,/# warranty; / { + s|^# || + s|^# *$|| + s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| + p + } + /^# Written by / { + s|^# || + p + } + /^warranty; /q' < "$progpath" + + exit $? +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: + +# Set a version string. +scriptversion='(GNU libtool) 2.4.6' + + +# func_echo ARG... +# ---------------- +# Libtool also displays the current mode in messages, so override +# funclib.sh func_echo with this custom definition. +func_echo () +{ + $debug_cmd + + _G_message=$* + + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" + done + IFS=$func_echo_IFS +} + + +# func_warning ARG... +# ------------------- +# Libtool warnings are not categorized, so override funclib.sh +# func_warning with this simpler definition. +func_warning () +{ + $debug_cmd + + $warning_func ${1+"$@"} +} + + +## ---------------- ## +## Options parsing. ## +## ---------------- ## + +# Hook in the functions to make sure our own options are parsed during +# the option parsing loop. + +usage='$progpath [OPTION]... [MODE-ARG]...' + +# Short help message in response to '-h'. +usage_message="Options: + --config show all configuration variables + --debug enable verbose shell tracing + -n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --mode=MODE use operation mode MODE + --no-warnings equivalent to '-Wnone' + --preserve-dup-deps don't remove duplicate dependency libraries + --quiet, --silent don't print informational messages + --tag=TAG use configuration variables from tag TAG + -v, --verbose print more informational messages than default + --version print version information + -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] + -h, --help, --help-all print short, long, or detailed help message +" + +# Additional text appended to 'usage_message' in response to '--help'. +func_help () +{ + $debug_cmd + + func_usage_message + $ECHO "$long_help_message + +MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. When passed as first option, +'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. +Try '$progname --help --mode=MODE' for a more detailed description of MODE. + +When reporting a bug, please describe a test case to reproduce it and +include the following information: + + host-triplet: $host + shell: $SHELL + compiler: $LTCC + compiler flags: $LTCFLAGS + linker: $LD (gnu? $with_gnu_ld) + version: $progname (GNU libtool) 2.4.6 + automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` + autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` + +Report bugs to <bug-libtool@gnu.org>. +GNU libtool home page: <http://www.gnu.org/s/libtool/>. +General help using GNU software: <http://www.gnu.org/gethelp/>." + exit 0 +} + + +# func_lo2o OBJECT-NAME +# --------------------- +# Transform OBJECT-NAME from a '.lo' suffix to the platform specific +# object suffix. + +lo2o=s/\\.lo\$/.$objext/ +o2lo=s/\\.$objext\$/.lo/ + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_lo2o () + { + case $1 in + *.lo) func_lo2o_result=${1%.lo}.$objext ;; + * ) func_lo2o_result=$1 ;; + esac + }' + + # func_xform LIBOBJ-OR-SOURCE + # --------------------------- + # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) + # suffix to a '.lo' libtool-object suffix. + eval 'func_xform () + { + func_xform_result=${1%.*}.lo + }' +else + # ...otherwise fall back to using sed. + func_lo2o () + { + func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` + } + + func_xform () + { + func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` + } +fi + + +# func_fatal_configuration ARG... +# ------------------------------- +# Echo program name prefixed message to standard error, followed by +# a configuration failure hint, and exit. +func_fatal_configuration () +{ + func__fatal_error ${1+"$@"} \ + "See the $PACKAGE documentation for more information." \ + "Fatal configuration error." +} + + +# func_config +# ----------- +# Display the configuration for all the tags in this script. +func_config () +{ + re_begincf='^# ### BEGIN LIBTOOL' + re_endcf='^# ### END LIBTOOL' + + # Default configuration. + $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" + + # Now print the configurations for the tags. + for tagname in $taglist; do + $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" + done + + exit $? +} + + +# func_features +# ------------- +# Display the features supported by this script. +func_features () +{ + echo "host: $host" + if test yes = "$build_libtool_libs"; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test yes = "$build_old_libs"; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + + exit $? +} + + +# func_enable_tag TAGNAME +# ----------------------- +# Verify that TAGNAME is valid, and either flag an error and exit, or +# enable the TAGNAME tag. We also add TAGNAME to the global $taglist +# variable here. +func_enable_tag () +{ + # Global variable: + tagname=$1 + + re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" + re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" + sed_extractcf=/$re_begincf/,/$re_endcf/p + + # Validate tagname. + case $tagname in + *[!-_A-Za-z0-9,/]*) + func_fatal_error "invalid tag name: $tagname" + ;; + esac + + # Don't test for the "default" C tag, as we know it's + # there but not specially marked. + case $tagname in + CC) ;; + *) + if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + + +# func_check_version_match +# ------------------------ +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +# libtool_options_prep [ARG]... +# ----------------------------- +# Preparation for options parsed by libtool. +libtool_options_prep () +{ + $debug_mode + + # Option defaults: + opt_config=false + opt_dlopen= + opt_dry_run=false + opt_help=false + opt_mode= + opt_preserve_dup_deps=false + opt_quiet=false + + nonopt= + preserve_args= + + # Shorthand for --mode=foo, only valid as the first argument + case $1 in + clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; + compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; + execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; + finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; + install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; + link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; + uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; + esac + + # Pass back the list of options. + func_quote_for_eval ${1+"$@"} + libtool_options_prep_result=$func_quote_for_eval_result +} +func_add_hook func_options_prep libtool_options_prep + + +# libtool_parse_options [ARG]... +# --------------------------------- +# Provide handling for libtool specific options. +libtool_parse_options () +{ + $debug_cmd + + # Perform our own loop to consume as many options as possible in + # each iteration. + while test $# -gt 0; do + _G_opt=$1 + shift + case $_G_opt in + --dry-run|--dryrun|-n) + opt_dry_run=: + ;; + + --config) func_config ;; + + --dlopen|-dlopen) + opt_dlopen="${opt_dlopen+$opt_dlopen +}$1" + shift + ;; + + --preserve-dup-deps) + opt_preserve_dup_deps=: ;; + + --features) func_features ;; + + --finish) set dummy --mode finish ${1+"$@"}; shift ;; + + --help) opt_help=: ;; + + --help-all) opt_help=': help-all' ;; + + --mode) test $# = 0 && func_missing_arg $_G_opt && break + opt_mode=$1 + case $1 in + # Valid mode arguments: + clean|compile|execute|finish|install|link|relink|uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $_G_opt" + exit_cmd=exit + break + ;; + esac + shift + ;; + + --no-silent|--no-quiet) + opt_quiet=false + func_append preserve_args " $_G_opt" + ;; + + --no-warnings|--no-warning|--no-warn) + opt_warning=false + func_append preserve_args " $_G_opt" + ;; + + --no-verbose) + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --silent|--quiet) + opt_quiet=: + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --tag) test $# = 0 && func_missing_arg $_G_opt && break + opt_tag=$1 + func_append preserve_args " $_G_opt $1" + func_enable_tag "$1" + shift + ;; + + --verbose|-v) opt_quiet=false + opt_verbose=: + func_append preserve_args " $_G_opt" + ;; + + # An option not handled by this hook function: + *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + esac + done + + + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + libtool_parse_options_result=$func_quote_for_eval_result +} +func_add_hook func_parse_options libtool_parse_options + + + +# libtool_validate_options [ARG]... +# --------------------------------- +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +libtool_validate_options () +{ + # save first non-option argument + if test 0 -lt $#; then + nonopt=$1 + shift + fi + + # preserve --debug + test : = "$debug_cmd" || func_append preserve_args " --debug" + + case $host in + # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 + # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 + *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps + ;; + esac + + $opt_help || { + # Sanity checks first: + func_check_version_match + + test yes != "$build_libtool_libs" \ + && test yes != "$build_old_libs" \ + && func_fatal_configuration "not configured to build any kind of library" + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$opt_dlopen" && test execute != "$opt_mode"; then + func_error "unrecognized option '-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help=$help + help="Try '$progname --help --mode=$opt_mode' for more information." + } + + # Pass back the unparsed argument list + func_quote_for_eval ${1+"$@"} + libtool_validate_options_result=$func_quote_for_eval_result +} +func_add_hook func_validate_options libtool_validate_options + + +# Process options as early as possible so that --help and --version +# can return quickly. +func_options ${1+"$@"} +eval set dummy "$func_options_result"; shift + + + +## ----------- ## +## Main. ## +## ----------- ## + +magic='%%%MAGIC variable%%%' +magic_exe='%%%MAGIC EXE variable%%%' + +# Global variables. +extracted_archives= +extracted_serial=0 + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + +# func_generated_by_libtool +# True iff stdin has been generated by Libtool. This function is only +# a basic sanity check; it will hardly flush out determined imposters. +func_generated_by_libtool_p () +{ + $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_p file +# True iff FILE is a libtool '.la' library or '.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool '.la' library or '.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if 'file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case $lalib_p_line in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test yes = "$lalib_p" +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + test -f "$1" && + $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $debug_cmd + + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$sp$nl + eval cmd=\"$cmd\" + IFS=$save_ifs + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# 'FILE.' does not work on cygwin managed mounts. +func_source () +{ + $debug_cmd + + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_resolve_sysroot PATH +# Replace a leading = in PATH with a sysroot. Store the result into +# func_resolve_sysroot_result +func_resolve_sysroot () +{ + func_resolve_sysroot_result=$1 + case $func_resolve_sysroot_result in + =*) + func_stripname '=' '' "$func_resolve_sysroot_result" + func_resolve_sysroot_result=$lt_sysroot$func_stripname_result + ;; + esac +} + +# func_replace_sysroot PATH +# If PATH begins with the sysroot, replace it with = and +# store the result into func_replace_sysroot_result. +func_replace_sysroot () +{ + case $lt_sysroot:$1 in + ?*:"$lt_sysroot"*) + func_stripname "$lt_sysroot" '' "$1" + func_replace_sysroot_result='='$func_stripname_result + ;; + *) + # Including no sysroot. + func_replace_sysroot_result=$1 + ;; + esac +} + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $debug_cmd + + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case "$@ " in + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with '--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=$1 + if test yes = "$build_libtool_libs"; then + write_lobj=\'$2\' + else + write_lobj=none + fi + + if test yes = "$build_old_libs"; then + write_oldobj=\'$3\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T <<EOF +# $write_libobj - a libtool object file +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# Name of the PIC object. +pic_object=$write_lobj + +# Name of the non-PIC object +non_pic_object=$write_oldobj + +EOF + $MV "${write_libobj}T" "$write_libobj" + } +} + + +################################################## +# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS # +################################################## + +# func_convert_core_file_wine_to_w32 ARG +# Helper function used by file name conversion functions when $build is *nix, +# and $host is mingw, cygwin, or some other w32 environment. Relies on a +# correctly configured wine environment available, with the winepath program +# in $build's $PATH. +# +# ARG is the $build file name to be converted to w32 format. +# Result is available in $func_convert_core_file_wine_to_w32_result, and will +# be empty on error (or when ARG is empty) +func_convert_core_file_wine_to_w32 () +{ + $debug_cmd + + func_convert_core_file_wine_to_w32_result=$1 + if test -n "$1"; then + # Unfortunately, winepath does not exit with a non-zero error code, so we + # are forced to check the contents of stdout. On the other hand, if the + # command is not found, the shell will set an exit code of 127 and print + # *an error message* to stdout. So we must check for both error code of + # zero AND non-empty stdout, which explains the odd construction: + func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null` + if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then + func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | + $SED -e "$sed_naive_backslashify"` + else + func_convert_core_file_wine_to_w32_result= + fi + fi +} +# end: func_convert_core_file_wine_to_w32 + + +# func_convert_core_path_wine_to_w32 ARG +# Helper function used by path conversion functions when $build is *nix, and +# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly +# configured wine environment available, with the winepath program in $build's +# $PATH. Assumes ARG has no leading or trailing path separator characters. +# +# ARG is path to be converted from $build format to win32. +# Result is available in $func_convert_core_path_wine_to_w32_result. +# Unconvertible file (directory) names in ARG are skipped; if no directory names +# are convertible, then the result may be empty. +func_convert_core_path_wine_to_w32 () +{ + $debug_cmd + + # unfortunately, winepath doesn't convert paths, only file names + func_convert_core_path_wine_to_w32_result= + if test -n "$1"; then + oldIFS=$IFS + IFS=: + for func_convert_core_path_wine_to_w32_f in $1; do + IFS=$oldIFS + func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" + if test -n "$func_convert_core_file_wine_to_w32_result"; then + if test -z "$func_convert_core_path_wine_to_w32_result"; then + func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result + else + func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" + fi + fi + done + IFS=$oldIFS + fi +} +# end: func_convert_core_path_wine_to_w32 + + +# func_cygpath ARGS... +# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when +# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) +# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or +# (2), returns the Cygwin file name or path in func_cygpath_result (input +# file name or path is assumed to be in w32 format, as previously converted +# from $build's *nix or MSYS format). In case (3), returns the w32 file name +# or path in func_cygpath_result (input file name or path is assumed to be in +# Cygwin format). Returns an empty string on error. +# +# ARGS are passed to cygpath, with the last one being the file name or path to +# be converted. +# +# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH +# environment variable; do not put it in $PATH. +func_cygpath () +{ + $debug_cmd + + if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then + func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` + if test "$?" -ne 0; then + # on failure, ensure result is empty + func_cygpath_result= + fi + else + func_cygpath_result= + func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" + fi +} +#end: func_cygpath + + +# func_convert_core_msys_to_w32 ARG +# Convert file name or path ARG from MSYS format to w32 format. Return +# result in func_convert_core_msys_to_w32_result. +func_convert_core_msys_to_w32 () +{ + $debug_cmd + + # awkward: cmd appends spaces to result + func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` +} +#end: func_convert_core_msys_to_w32 + + +# func_convert_file_check ARG1 ARG2 +# Verify that ARG1 (a file name in $build format) was converted to $host +# format in ARG2. Otherwise, emit an error message, but continue (resetting +# func_to_host_file_result to ARG1). +func_convert_file_check () +{ + $debug_cmd + + if test -z "$2" && test -n "$1"; then + func_error "Could not determine host file name corresponding to" + func_error " '$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_file_result=$1 + fi +} +# end func_convert_file_check + + +# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH +# Verify that FROM_PATH (a path in $build format) was converted to $host +# format in TO_PATH. Otherwise, emit an error message, but continue, resetting +# func_to_host_file_result to a simplistic fallback value (see below). +func_convert_path_check () +{ + $debug_cmd + + if test -z "$4" && test -n "$3"; then + func_error "Could not determine the host path corresponding to" + func_error " '$3'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This is a deliberately simplistic "conversion" and + # should not be "improved". See libtool.info. + if test "x$1" != "x$2"; then + lt_replace_pathsep_chars="s|$1|$2|g" + func_to_host_path_result=`echo "$3" | + $SED -e "$lt_replace_pathsep_chars"` + else + func_to_host_path_result=$3 + fi + fi +} +# end func_convert_path_check + + +# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG +# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT +# and appending REPL if ORIG matches BACKPAT. +func_convert_path_front_back_pathsep () +{ + $debug_cmd + + case $4 in + $1 ) func_to_host_path_result=$3$func_to_host_path_result + ;; + esac + case $4 in + $2 ) func_append func_to_host_path_result "$3" + ;; + esac +} +# end func_convert_path_front_back_pathsep + + +################################################## +# $build to $host FILE NAME CONVERSION FUNCTIONS # +################################################## +# invoked via '$to_host_file_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# Result will be available in $func_to_host_file_result. + + +# func_to_host_file ARG +# Converts the file name ARG from $build format to $host format. Return result +# in func_to_host_file_result. +func_to_host_file () +{ + $debug_cmd + + $to_host_file_cmd "$1" +} +# end func_to_host_file + + +# func_to_tool_file ARG LAZY +# converts the file name ARG from $build format to toolchain format. Return +# result in func_to_tool_file_result. If the conversion in use is listed +# in (the comma separated) LAZY, no conversion takes place. +func_to_tool_file () +{ + $debug_cmd + + case ,$2, in + *,"$to_tool_file_cmd",*) + func_to_tool_file_result=$1 + ;; + *) + $to_tool_file_cmd "$1" + func_to_tool_file_result=$func_to_host_file_result + ;; + esac +} +# end func_to_tool_file + + +# func_convert_file_noop ARG +# Copy ARG to func_to_host_file_result. +func_convert_file_noop () +{ + func_to_host_file_result=$1 +} +# end func_convert_file_noop + + +# func_convert_file_msys_to_w32 ARG +# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_file_result. +func_convert_file_msys_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_to_host_file_result=$func_convert_core_msys_to_w32_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_w32 + + +# func_convert_file_cygwin_to_w32 ARG +# Convert file name ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_file_cygwin_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + # because $build is cygwin, we call "the" cygpath in $PATH; no need to use + # LT_CYGPATH in this case. + func_to_host_file_result=`cygpath -m "$1"` + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_cygwin_to_w32 + + +# func_convert_file_nix_to_w32 ARG +# Convert file name ARG from *nix to w32 format. Requires a wine environment +# and a working winepath. Returns result in func_to_host_file_result. +func_convert_file_nix_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_file_wine_to_w32 "$1" + func_to_host_file_result=$func_convert_core_file_wine_to_w32_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_w32 + + +# func_convert_file_msys_to_cygwin ARG +# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_file_msys_to_cygwin () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_cygpath -u "$func_convert_core_msys_to_w32_result" + func_to_host_file_result=$func_cygpath_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_cygwin + + +# func_convert_file_nix_to_cygwin ARG +# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed +# in a wine environment, working winepath, and LT_CYGPATH set. Returns result +# in func_to_host_file_result. +func_convert_file_nix_to_cygwin () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. + func_convert_core_file_wine_to_w32 "$1" + func_cygpath -u "$func_convert_core_file_wine_to_w32_result" + func_to_host_file_result=$func_cygpath_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_cygwin + + +############################################# +# $build to $host PATH CONVERSION FUNCTIONS # +############################################# +# invoked via '$to_host_path_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# The result will be available in $func_to_host_path_result. +# +# Path separators are also converted from $build format to $host format. If +# ARG begins or ends with a path separator character, it is preserved (but +# converted to $host format) on output. +# +# All path conversion functions are named using the following convention: +# file name conversion function : func_convert_file_X_to_Y () +# path conversion function : func_convert_path_X_to_Y () +# where, for any given $build/$host combination the 'X_to_Y' value is the +# same. If conversion functions are added for new $build/$host combinations, +# the two new functions must follow this pattern, or func_init_to_host_path_cmd +# will break. + + +# func_init_to_host_path_cmd +# Ensures that function "pointer" variable $to_host_path_cmd is set to the +# appropriate value, based on the value of $to_host_file_cmd. +to_host_path_cmd= +func_init_to_host_path_cmd () +{ + $debug_cmd + + if test -z "$to_host_path_cmd"; then + func_stripname 'func_convert_file_' '' "$to_host_file_cmd" + to_host_path_cmd=func_convert_path_$func_stripname_result + fi +} + + +# func_to_host_path ARG +# Converts the path ARG from $build format to $host format. Return result +# in func_to_host_path_result. +func_to_host_path () +{ + $debug_cmd + + func_init_to_host_path_cmd + $to_host_path_cmd "$1" +} +# end func_to_host_path + + +# func_convert_path_noop ARG +# Copy ARG to func_to_host_path_result. +func_convert_path_noop () +{ + func_to_host_path_result=$1 +} +# end func_convert_path_noop + + +# func_convert_path_msys_to_w32 ARG +# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_path_result. +func_convert_path_msys_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # Remove leading and trailing path separator characters from ARG. MSYS + # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; + # and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result=$func_convert_core_msys_to_w32_result + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_msys_to_w32 + + +# func_convert_path_cygwin_to_w32 ARG +# Convert path ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_path_cygwin_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_cygwin_to_w32 + + +# func_convert_path_nix_to_w32 ARG +# Convert path ARG from *nix to w32 format. Requires a wine environment and +# a working winepath. Returns result in func_to_host_file_result. +func_convert_path_nix_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result=$func_convert_core_path_wine_to_w32_result + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_nix_to_w32 + + +# func_convert_path_msys_to_cygwin ARG +# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_path_msys_to_cygwin () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_msys_to_w32_result" + func_to_host_path_result=$func_cygpath_result + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_msys_to_cygwin + + +# func_convert_path_nix_to_cygwin ARG +# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a +# a wine environment, working winepath, and LT_CYGPATH set. Returns result in +# func_to_host_file_result. +func_convert_path_nix_to_cygwin () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" + func_to_host_path_result=$func_cygpath_result + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_nix_to_cygwin + + +# func_dll_def_p FILE +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with _LT_DLL_DEF_P in libtool.m4 +func_dll_def_p () +{ + $debug_cmd + + func_dll_def_p_tmp=`$SED -n \ + -e 's/^[ ]*//' \ + -e '/^\(;.*\)*$/d' \ + -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ + -e q \ + "$1"` + test DEF = "$func_dll_def_p_tmp" +} + + +# func_mode_compile arg... +func_mode_compile () +{ + $debug_cmd + + # Get the compilation command and the source file. + base_compile= + srcfile=$nonopt # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + pie_flag= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg=$arg + arg_mode=normal + ;; + + target ) + libobj=$arg + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + test -n "$libobj" && \ + func_fatal_error "you cannot specify '-o' more than once" + arg_mode=target + continue + ;; + + -pie | -fpie | -fPIE) + func_append pie_flag " $arg" + continue + ;; + + -shared | -static | -prefer-pic | -prefer-non-pic) + func_append later " $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + lastarg= + save_ifs=$IFS; IFS=, + for arg in $args; do + IFS=$save_ifs + func_append_quoted lastarg "$arg" + done + IFS=$save_ifs + func_stripname ' ' '' "$lastarg" + lastarg=$func_stripname_result + + # Add the arguments to base_compile. + func_append base_compile " $lastarg" + continue + ;; + + *) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg=$srcfile + srcfile=$arg + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + func_append_quoted base_compile "$lastarg" + done # for arg + + case $arg_mode in + arg) + func_fatal_error "you must specify an argument for -Xcompile" + ;; + target) + func_fatal_error "you must specify a target with '-o'" + ;; + *) + # Get the name of the library object. + test -z "$libobj" && { + func_basename "$srcfile" + libobj=$func_basename_result + } + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + case $libobj in + *.[cCFSifmso] | \ + *.ada | *.adb | *.ads | *.asm | \ + *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ + *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) + func_xform "$libobj" + libobj=$func_xform_result + ;; + esac + + case $libobj in + *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; + *) + func_fatal_error "cannot determine name of library object from '$libobj'" + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -shared) + test yes = "$build_libtool_libs" \ + || func_fatal_configuration "cannot build a shared library" + build_old_libs=no + continue + ;; + + -static) + build_libtool_libs=no + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + func_quote_for_eval "$libobj" + test "X$libobj" != "X$func_quote_for_eval_result" \ + && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && func_warning "libobj name '$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname=$func_basename_result + xdir=$func_dirname_result + lobj=$xdir$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test yes = "$build_old_libs"; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test no = "$compiler_c_o"; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext + lockfile=$output_obj.lock + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test yes = "$need_locks"; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test warn = "$need_locks"; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + func_append removelist " $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + func_append removelist " $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 + srcfile=$func_to_tool_file_result + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test yes = "$build_libtool_libs"; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test no != "$pic_mode"; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + func_append command " -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test warn = "$need_locks" && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test yes = "$suppress_opt"; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test yes = "$build_old_libs"; then + if test yes != "$pic_mode"; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test yes = "$compiler_c_o"; then + func_append command " -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + func_append command "$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test warn = "$need_locks" && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test no != "$need_locks"; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { + test compile = "$opt_mode" && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $opt_mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to build PIC objects only + -prefer-non-pic try to build non-PIC objects only + -shared do not build a '.o' file suitable for static linking + -static only build a '.o' file suitable for static linking + -Wc,FLAG pass FLAG directly to the compiler + +COMPILE-COMMAND is a command to be used in creating a 'standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix '.c' with the +library object suffix, '.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to '-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the '--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the 'install' or 'cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -bindir BINDIR specify path to binaries directory (for systems where + libraries must be found in the PATH setting at runtime) + -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE use a list of object files found in FILE to specify objects + -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + -Wc,FLAG + -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wl,FLAG + -Xlinker FLAG pass linker-specific FLAG directly to the linker + -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) + +All other options (arguments beginning with '-') are ignored. + +Every other argument is treated as a filename. Files ending in '.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in '.la', then a libtool library is created, +only library objects ('.lo' files) may be specified, and '-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created +using 'ar' and 'ranlib', or on Windows using 'lib'. + +If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode '$opt_mode'" + ;; + esac + + echo + $ECHO "Try '$progname --help' for more information about other modes." +} + +# Now that we've collected a possible --mode arg, show help if necessary +if $opt_help; then + if test : = "$opt_help"; then + func_mode_help + else + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + func_mode_help + done + } | $SED -n '1p; 2,$s/^Usage:/ or: /p' + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + echo + func_mode_help + done + } | + $SED '1d + /^When reporting/,/^Report/{ + H + d + } + $x + /information about other modes/d + /more detailed .*MODE/d + s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' + fi + exit $? +fi + + +# func_mode_execute arg... +func_mode_execute () +{ + $debug_cmd + + # The first argument is the command name. + cmd=$nonopt + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $opt_dlopen; do + test -f "$file" \ + || func_fatal_help "'$file' is not a file" + + dir= + case $file in + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "'$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "'$file' was not linked with '-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir=$func_dirname_result + + if test -f "$dir/$objdir/$dlname"; then + func_append dir "/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir=$func_dirname_result + ;; + + *) + func_warning "'-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir=$absdir + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic=$magic + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -* | *.la | *.lo ) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file=$progdir/$program + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file=$progdir/$program + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_append_quoted args "$file" + done + + if $opt_dry_run; then + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + echo "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + else + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd=\$cmd$args + fi +} + +test execute = "$opt_mode" && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $debug_cmd + + libs= + libdirs= + admincmds= + + for opt in "$nonopt" ${1+"$@"} + do + if test -d "$opt"; then + func_append libdirs " $opt" + + elif test -f "$opt"; then + if func_lalib_unsafe_p "$opt"; then + func_append libs " $opt" + else + func_warning "'$opt' is not a valid libtool archive" + fi + + else + func_fatal_error "invalid argument '$opt'" + fi + done + + if test -n "$libs"; then + if test -n "$lt_sysroot"; then + sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` + sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" + else + sysroot_cmd= + fi + + # Remove sysroot references + if $opt_dry_run; then + for lib in $libs; do + echo "removing references to $lt_sysroot and '=' prefixes from $lib" + done + else + tmpdir=`func_mktempdir` + for lib in $libs; do + $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ + > $tmpdir/tmp-la + mv -f $tmpdir/tmp-la $lib + done + ${RM}r "$tmpdir" + fi + fi + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || func_append admincmds " + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_quiet && exit $EXIT_SUCCESS + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the '-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the '$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the '$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $ECHO " - use the '$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" + fi + echo + + echo "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" + echo "pages." + ;; + *) + echo "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + echo "----------------------------------------------------------------------" + fi + exit $EXIT_SUCCESS +} + +test finish = "$opt_mode" && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $debug_cmd + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || + # Allow the use of GNU shtool's install command. + case $nonopt in *shtool*) :;; *) false;; esac + then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + func_append install_prog "$func_quote_for_eval_result" + install_shared_prog=$install_prog + case " $install_prog " in + *[\\\ /]cp\ *) install_cp=: ;; + *) install_cp=false ;; + esac + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=false + stripme= + no_mode=: + for arg + do + arg2= + if test -n "$dest"; then + func_append files " $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=: ;; + -f) + if $install_cp; then :; else + prev=$arg + fi + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + if test X-m = "X$prev" && test -n "$install_override_mode"; then + arg2=$install_override_mode + no_mode=false + fi + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + func_append install_prog " $func_quote_for_eval_result" + if test -n "$arg2"; then + func_quote_for_eval "$arg2" + fi + func_append install_shared_prog " $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the '$prev' option requires an argument" + + if test -n "$install_override_mode" && $no_mode; then + if $install_cp; then :; else + func_quote_for_eval "$install_override_mode" + func_append install_shared_prog " -m $func_quote_for_eval_result" + fi + fi + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=: + if $isdir; then + destdir=$dest + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir=$func_dirname_result + destname=$func_basename_result + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "'$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "'$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic=$magic + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + func_append staticlibs " $file" + ;; + + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "'$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) func_append current_libdirs " $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) func_append future_libdirs " $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir=$func_dirname_result + func_append dir "$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking '$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname=$1 + shift + + srcname=$realname + test -n "$relink_command" && srcname=${realname}T + + # Install the shared library and build the symlinks. + func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme=$stripme + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme= + ;; + esac + ;; + os2*) + case $realname in + *_dll.a) + tstripme= + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try 'ln -sf' first, because the 'ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib=$destdir/$realname + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name=$func_basename_result + instname=$dir/${name}i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && func_append staticlibs " $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile=$destdir/$destname + else + func_basename "$file" + destfile=$func_basename_result + destfile=$destdir/$destfile + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest=$destfile + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to '$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test yes = "$build_old_libs"; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile=$destdir/$destname + else + func_basename "$file" + destfile=$func_basename_result + destfile=$destdir/$destfile + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext= + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=.exe + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script '$wrapper'" + + finalize=: + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "'$lib' has not been installed in '$libdir'" + finalize=false + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test no = "$fast_install" && test -n "$relink_command"; then + $opt_dry_run || { + if $finalize; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file=$func_basename_result + outputname=$tmpdir/$file + # Replace the output file specification. + relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_quiet || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink '$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file=$outputname + else + func_warning "cannot relink '$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name=$func_basename_result + + # Set up the ranlib parameters. + oldlib=$destdir/$name + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $tool_oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run '$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test install = "$opt_mode" && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $debug_cmd + + my_outputname=$1 + my_originator=$2 + my_pic_p=${3-false} + my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms=${my_outputname}S.c + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist=$output_objdir/$my_outputname.nm + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" +#endif + +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + +/* External symbol declarations for the compiler. */\ +" + + if test yes = "$dlself"; then + func_verbose "generating symbol list for '$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_to_tool_file "$progfile" func_convert_file_msys_to_w32 + func_verbose "extracting global C symbols from '$func_to_tool_file_result'" + $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols=$output_objdir/$outputname.exp + $opt_dry_run || { + $RM $export_symbols + eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from '$dlprefile'" + func_basename "$dlprefile" + name=$func_basename_result + case $host in + *cygwin* | *mingw* | *cegcc* ) + # if an import library, we need to obtain dlname + if func_win32_import_lib_p "$dlprefile"; then + func_tr_sh "$dlprefile" + eval "curr_lafile=\$libfile_$func_tr_sh_result" + dlprefile_dlbasename= + if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then + # Use subshell, to avoid clobbering current variable values + dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` + if test -n "$dlprefile_dlname"; then + func_basename "$dlprefile_dlname" + dlprefile_dlbasename=$func_basename_result + else + # no lafile. user explicitly requested -dlpreopen <import library>. + $sharedlib_from_linklib_cmd "$dlprefile" + dlprefile_dlbasename=$sharedlib_from_linklib_result + fi + fi + $opt_dry_run || { + if test -n "$dlprefile_dlbasename"; then + eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' + else + func_warning "Could not compute DLL name from $name" + eval '$ECHO ": $name " >> "$nlist"' + fi + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + } + else # not an import lib + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + fi + ;; + *) + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + ;; + esac + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 </dev/null >/dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + func_show_eval '$RM "${nlist}I"' + if test -n "$global_symbol_to_import"; then + eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' + fi + + echo >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +extern LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[];\ +" + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ +static void lt_syminit(void) +{ + LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; + for (; symbol->name; ++symbol) + {" + $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" + echo >> "$output_objdir/$my_dlsyms" "\ + } +}" + fi + echo >> "$output_objdir/$my_dlsyms" "\ +LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{ {\"$my_originator\", (void *) 0}," + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ + {\"@INIT@\", (void *) <_syminit}," + fi + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + echo >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + $my_pic_p && pic_flag_for_symtable=" $pic_flag" + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) func_append symtab_cflags " $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' + + # Transform the symbol file into the correct name. + symfileobj=$output_objdir/${my_outputname}S.$objext + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for '$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` + fi +} + +# func_cygming_gnu_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is a GNU/binutils-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_gnu_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` + test -n "$func_cygming_gnu_implib_tmp" +} + +# func_cygming_ms_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is an MS-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_ms_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` + test -n "$func_cygming_ms_implib_tmp" +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +# Despite the name, also deal with 64 bit binaries. +func_win32_libid () +{ + $debug_cmd + + win32_libid_type=unknown + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then + case $nm_interface in + "MS dumpbin") + if func_cygming_ms_implib_p "$1" || + func_cygming_gnu_implib_p "$1" + then + win32_nmres=import + else + win32_nmres= + fi + ;; + *) + func_to_tool_file "$1" func_convert_file_msys_to_w32 + win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | + $SED -n -e ' + 1,100{ + / I /{ + s|.*|import| + p + q + } + }'` + ;; + esac + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + +# func_cygming_dll_for_implib ARG +# +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib () +{ + $debug_cmd + + sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` +} + +# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs +# +# The is the core of a fallback implementation of a +# platform-specific function to extract the name of the +# DLL associated with the specified import library LIBNAME. +# +# SECTION_NAME is either .idata$6 or .idata$7, depending +# on the platform and compiler that created the implib. +# +# Echos the name of the DLL associated with the +# specified import library. +func_cygming_dll_for_implib_fallback_core () +{ + $debug_cmd + + match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` + $OBJDUMP -s --section "$1" "$2" 2>/dev/null | + $SED '/^Contents of section '"$match_literal"':/{ + # Place marker at beginning of archive member dllname section + s/.*/====MARK====/ + p + d + } + # These lines can sometimes be longer than 43 characters, but + # are always uninteresting + /:[ ]*file format pe[i]\{,1\}-/d + /^In archive [^:]*:/d + # Ensure marker is printed + /^====MARK====/p + # Remove all lines with less than 43 characters + /^.\{43\}/!d + # From remaining lines, remove first 43 characters + s/^.\{43\}//' | + $SED -n ' + # Join marker and all lines until next marker into a single line + /^====MARK====/ b para + H + $ b para + b + :para + x + s/\n//g + # Remove the marker + s/^====MARK====// + # Remove trailing dots and whitespace + s/[\. \t]*$// + # Print + /./p' | + # we now have a list, one entry per line, of the stringified + # contents of the appropriate section of all members of the + # archive that possess that section. Heuristic: eliminate + # all those that have a first or second character that is + # a '.' (that is, objdump's representation of an unprintable + # character.) This should work for all archives with less than + # 0x302f exports -- but will fail for DLLs whose name actually + # begins with a literal '.' or a single character followed by + # a '.'. + # + # Of those that remain, print the first one. + $SED -e '/^\./d;/^.\./d;q' +} + +# func_cygming_dll_for_implib_fallback ARG +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# +# This fallback implementation is for use when $DLLTOOL +# does not support the --identify-strict option. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib_fallback () +{ + $debug_cmd + + if func_cygming_gnu_implib_p "$1"; then + # binutils import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` + elif func_cygming_ms_implib_p "$1"; then + # ms-generated import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` + else + # unknown + sharedlib_from_linklib_result= + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $debug_cmd + + f_ex_an_ar_dir=$1; shift + f_ex_an_ar_oldlib=$1 + if test yes = "$lock_old_archive_extraction"; then + lockfile=$f_ex_an_ar_oldlib.lock + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + fi + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ + 'stat=$?; rm -f "$lockfile"; exit $stat' + if test yes = "$lock_old_archive_extraction"; then + $opt_dry_run || rm -f "$lockfile" + fi + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $debug_cmd + + my_gentop=$1; shift + my_oldlibs=${1+"$@"} + my_oldobjs= + my_xlib= + my_xabs= + my_xdir= + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib=$func_basename_result + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir=$my_gentop/$my_xlib_u + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + func_basename "$darwin_archive" + darwin_base_archive=$func_basename_result + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches; do + func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" + $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" + cd "unfat-$$/$darwin_base_archive-$darwin_arch" + func_extract_an_archive "`pwd`" "$darwin_base_archive" + cd "$darwin_curdir" + $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` + done + + func_extract_archives_result=$my_oldobjs +} + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory where it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=${1-no} + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + file=\"\$0\"" + + qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + $ECHO "\ + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + ECHO=\"$qECHO\" + fi + +# Very basic option parsing. These options are (a) specific to +# the libtool wrapper, (b) are identical between the wrapper +# /script/ and the wrapper /executable/ that is used only on +# windows platforms, and (c) all begin with the string "--lt-" +# (application programs are unlikely to have options that match +# this pattern). +# +# There are only two supported options: --lt-debug and +# --lt-dump-script. There is, deliberately, no --lt-help. +# +# The first argument to this parsing function should be the +# script's $0 value, followed by "$@". +lt_option_debug= +func_parse_lt_options () +{ + lt_script_arg0=\$0 + shift + for lt_opt + do + case \"\$lt_opt\" in + --lt-debug) lt_option_debug=1 ;; + --lt-dump-script) + lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` + test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. + lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` + cat \"\$lt_dump_D/\$lt_dump_F\" + exit 0 + ;; + --lt-*) + \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 + exit 1 + ;; + esac + done + + # Print the debug banner immediately: + if test -n \"\$lt_option_debug\"; then + echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 + fi +} + +# Used when --lt-debug. Prints its arguments to stdout +# (redirection is the responsibility of the caller) +func_lt_dump_args () +{ + lt_dump_args_N=1; + for lt_arg + do + \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" + lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` + done +} + +# Core function for launching the target application +func_exec_program_core () +{ +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 +} + +# A function to encapsulate launching the target application +# Strips options in the --lt-* namespace from \$@ and +# launches target application with the remaining arguments. +func_exec_program () +{ + case \" \$* \" in + *\\ --lt-*) + for lt_wr_arg + do + case \$lt_wr_arg in + --lt-*) ;; + *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; + esac + shift + done ;; + esac + func_exec_program_core \${1+\"\$@\"} +} + + # Parse options + func_parse_lt_options \"\$0\" \${1+\"\$@\"} + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` + done + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test yes = "$fast_install"; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + \$ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # fixup the dll searchpath if we need to. + # + # Fix the DLL searchpath if we need to. Do this before prepending + # to shlibpath, because on Windows, both are PATH and uninstalled + # libraries must come first. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + # Export our shlibpath_var if we have one. + if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` + + export $shlibpath_var +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + func_exec_program \${1+\"\$@\"} + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} + + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat <<EOF + +/* $cwrappersource - temporary wrapper executable for $objdir/$outputname + Generated by $PROGRAM (GNU $PACKAGE) $VERSION + + The $output program cannot be directly executed until all the libtool + libraries that it depends on are installed. + + This wrapper executable should never be moved out of the build directory. + If it is, it will not operate correctly. +*/ +EOF + cat <<"EOF" +#ifdef _MSC_VER +# define _CRT_SECURE_NO_DEPRECATE 1 +#endif +#include <stdio.h> +#include <stdlib.h> +#ifdef _MSC_VER +# include <direct.h> +# include <process.h> +# include <io.h> +#else +# include <unistd.h> +# include <stdint.h> +# ifdef __CYGWIN__ +# include <io.h> +# endif +#endif +#include <malloc.h> +#include <stdarg.h> +#include <assert.h> +#include <string.h> +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/stat.h> + +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + +/* declarations of non-ANSI functions */ +#if defined __MINGW32__ +# ifdef __STRICT_ANSI__ +int _putenv (const char *); +# endif +#elif defined __CYGWIN__ +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +/* #elif defined other_platform || defined ... */ +#endif + +/* portability defines, excluding path handling macros */ +#if defined _MSC_VER +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +# define S_IXUSR _S_IEXEC +#elif defined __MINGW32__ +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +#elif defined __CYGWIN__ +# define HAVE_SETENV +# define FOPEN_WB "wb" +/* #elif defined other platforms ... */ +#endif + +#if defined PATH_MAX +# define LT_PATHMAX PATH_MAX +#elif defined MAXPATHLEN +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +/* path handling portability macros */ +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ + defined __OS2__ +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free (stale); stale = 0; } \ +} while (0) + +#if defined LT_DEBUGWRAPPER +static int lt_debug = 1; +#else +static int lt_debug = 0; +#endif + +const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_debugprintf (const char *file, int line, const char *fmt, ...); +void lt_fatal (const char *file, int line, const char *message, ...); +static const char *nonnull (const char *s); +static const char *nonempty (const char *s); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); +char **prepare_spawn (char **argv); +void lt_dump_script (FILE *f); +EOF + + cat <<EOF +#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) +# define externally_visible volatile +#else +# define externally_visible __attribute__((externally_visible)) volatile +#endif +externally_visible const char * MAGIC_EXE = "$magic_exe"; +const char * LIB_PATH_VARNAME = "$shlibpath_var"; +EOF + + if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + func_to_host_path "$temp_rpath" + cat <<EOF +const char * LIB_PATH_VALUE = "$func_to_host_path_result"; +EOF + else + cat <<"EOF" +const char * LIB_PATH_VALUE = ""; +EOF + fi + + if test -n "$dllsearchpath"; then + func_to_host_path "$dllsearchpath:" + cat <<EOF +const char * EXE_PATH_VARNAME = "PATH"; +const char * EXE_PATH_VALUE = "$func_to_host_path_result"; +EOF + else + cat <<"EOF" +const char * EXE_PATH_VARNAME = ""; +const char * EXE_PATH_VALUE = ""; +EOF + fi + + if test yes = "$fast_install"; then + cat <<EOF +const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */ +EOF + else + cat <<EOF +const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */ +EOF + fi + + + cat <<"EOF" + +#define LTWRAPPER_OPTION_PREFIX "--lt-" + +static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX; +static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script"; +static const char *debug_opt = LTWRAPPER_OPTION_PREFIX "debug"; + +int +main (int argc, char *argv[]) +{ + char **newargz; + int newargc; + char *tmp_pathspec; + char *actual_cwrapper_path; + char *actual_cwrapper_name; + char *target_name; + char *lt_argv_zero; + int rval = 127; + + int i; + + program_name = (char *) xstrdup (base_name (argv[0])); + newargz = XMALLOC (char *, (size_t) argc + 1); + + /* very simple arg parsing; don't want to rely on getopt + * also, copy all non cwrapper options to newargz, except + * argz[0], which is handled differently + */ + newargc=0; + for (i = 1; i < argc; i++) + { + if (STREQ (argv[i], dumpscript_opt)) + { +EOF + case $host in + *mingw* | *cygwin* ) + # make stdout use "unix" line endings + echo " setmode(1,_O_BINARY);" + ;; + esac + + cat <<"EOF" + lt_dump_script (stdout); + return 0; + } + if (STREQ (argv[i], debug_opt)) + { + lt_debug = 1; + continue; + } + if (STREQ (argv[i], ltwrapper_option_prefix)) + { + /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX + namespace, but it is not one of the ones we know about and + have already dealt with, above (inluding dump-script), then + report an error. Otherwise, targets might begin to believe + they are allowed to use options in the LTWRAPPER_OPTION_PREFIX + namespace. The first time any user complains about this, we'll + need to make LTWRAPPER_OPTION_PREFIX a configure-time option + or a configure.ac-settable value. + */ + lt_fatal (__FILE__, __LINE__, + "unrecognized %s option: '%s'", + ltwrapper_option_prefix, argv[i]); + } + /* otherwise ... */ + newargz[++newargc] = xstrdup (argv[i]); + } + newargz[++newargc] = NULL; + +EOF + cat <<EOF + /* The GNU banner must be the first non-error debug message */ + lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE) $VERSION\n"); +EOF + cat <<"EOF" + lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]); + lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name); + + tmp_pathspec = find_executable (argv[0]); + if (tmp_pathspec == NULL) + lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]); + lt_debugprintf (__FILE__, __LINE__, + "(main) found exe (before symlink chase) at: %s\n", + tmp_pathspec); + + actual_cwrapper_path = chase_symlinks (tmp_pathspec); + lt_debugprintf (__FILE__, __LINE__, + "(main) found exe (after symlink chase) at: %s\n", + actual_cwrapper_path); + XFREE (tmp_pathspec); + + actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path)); + strendzap (actual_cwrapper_path, actual_cwrapper_name); + + /* wrapper name transforms */ + strendzap (actual_cwrapper_name, ".exe"); + tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1); + XFREE (actual_cwrapper_name); + actual_cwrapper_name = tmp_pathspec; + tmp_pathspec = 0; + + /* target_name transforms -- use actual target program name; might have lt- prefix */ + target_name = xstrdup (base_name (TARGET_PROGRAM_NAME)); + strendzap (target_name, ".exe"); + tmp_pathspec = lt_extend_str (target_name, ".exe", 1); + XFREE (target_name); + target_name = tmp_pathspec; + tmp_pathspec = 0; + + lt_debugprintf (__FILE__, __LINE__, + "(main) libtool target name: %s\n", + target_name); +EOF + + cat <<EOF + newargz[0] = + XMALLOC (char, (strlen (actual_cwrapper_path) + + strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1)); + strcpy (newargz[0], actual_cwrapper_path); + strcat (newargz[0], "$objdir"); + strcat (newargz[0], "/"); +EOF + + cat <<"EOF" + /* stop here, and copy so we don't have to do this twice */ + tmp_pathspec = xstrdup (newargz[0]); + + /* do NOT want the lt- prefix here, so use actual_cwrapper_name */ + strcat (newargz[0], actual_cwrapper_name); + + /* DO want the lt- prefix here if it exists, so use target_name */ + lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1); + XFREE (tmp_pathspec); + tmp_pathspec = NULL; +EOF + + case $host_os in + mingw*) + cat <<"EOF" + { + char* p; + while ((p = strchr (newargz[0], '\\')) != NULL) + { + *p = '/'; + } + while ((p = strchr (lt_argv_zero, '\\')) != NULL) + { + *p = '/'; + } + } +EOF + ;; + esac + + cat <<"EOF" + XFREE (target_name); + XFREE (actual_cwrapper_path); + XFREE (actual_cwrapper_name); + + lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */ + lt_setenv ("DUALCASE", "1"); /* for MSK sh */ + /* Update the DLL searchpath. EXE_PATH_VALUE ($dllsearchpath) must + be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath) + because on Windows, both *_VARNAMEs are PATH but uninstalled + libraries must come first. */ + lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE); + lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE); + + lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n", + nonnull (lt_argv_zero)); + for (i = 0; i < newargc; i++) + { + lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n", + i, nonnull (newargz[i])); + } + +EOF + + case $host_os in + mingw*) + cat <<"EOF" + /* execv doesn't actually work on mingw as expected on unix */ + newargz = prepare_spawn (newargz); + rval = (int) _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz); + if (rval == -1) + { + /* failed to start process */ + lt_debugprintf (__FILE__, __LINE__, + "(main) failed to launch target \"%s\": %s\n", + lt_argv_zero, nonnull (strerror (errno))); + return 127; + } + return rval; +EOF + ;; + *) + cat <<"EOF" + execv (lt_argv_zero, newargz); + return rval; /* =127, but avoids unused variable warning */ +EOF + ;; + esac + + cat <<"EOF" +} + +void * +xmalloc (size_t num) +{ + void *p = (void *) malloc (num); + if (!p) + lt_fatal (__FILE__, __LINE__, "memory exhausted"); + + return p; +} + +char * +xstrdup (const char *string) +{ + return string ? strcpy ((char *) xmalloc (strlen (string) + 1), + string) : NULL; +} + +const char * +base_name (const char *name) +{ + const char *base; + +#if defined HAVE_DOS_BASED_FILE_SYSTEM + /* Skip over the disk name in MSDOS pathnames. */ + if (isalpha ((unsigned char) name[0]) && name[1] == ':') + name += 2; +#endif + + for (base = name; *name; name++) + if (IS_DIR_SEPARATOR (*name)) + base = name + 1; + return base; +} + +int +check_executable (const char *path) +{ + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if ((stat (path, &st) >= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + size_t tmp_len; + char *concat_name; + + lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", + nonempty (wrapper)); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined HAVE_DOS_BASED_FILE_SYSTEM + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined HAVE_DOS_BASED_FILE_SYSTEM + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = (size_t) (q - p); + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + lt_debugprintf (__FILE__, __LINE__, + "checking path component for symlinks: %s\n", + tmp_pathspec); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + lt_fatal (__FILE__, __LINE__, + "error accessing file \"%s\": %s", + tmp_pathspec, nonnull (strerror (errno))); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal (__FILE__, __LINE__, + "could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (STREQ (str, pat)) + *str = '\0'; + } + return str; +} + +void +lt_debugprintf (const char *file, int line, const char *fmt, ...) +{ + va_list args; + if (lt_debug) + { + (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); + } +} + +static void +lt_error_core (int exit_status, const char *file, + int line, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *file, int line, const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); + va_end (ap); +} + +static const char * +nonnull (const char *s) +{ + return s ? s : "(null)"; +} + +static const char * +nonempty (const char *s) +{ + return (s && !*s) ? "(empty)" : nonnull (s); +} + +void +lt_setenv (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_setenv) setting '%s' to '%s'\n", + nonnull (name), nonnull (value)); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + size_t len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + size_t orig_value_len = strlen (orig_value); + size_t add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + size_t len = strlen (new_value); + while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[--len] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +EOF + case $host_os in + mingw*) + cat <<"EOF" + +/* Prepares an argument vector before calling spawn(). + Note that spawn() does not by itself call the command interpreter + (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : + ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&v); + v.dwPlatformId == VER_PLATFORM_WIN32_NT; + }) ? "cmd.exe" : "command.com"). + Instead it simply concatenates the arguments, separated by ' ', and calls + CreateProcess(). We must quote the arguments since Win32 CreateProcess() + interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a + special way: + - Space and tab are interpreted as delimiters. They are not treated as + delimiters if they are surrounded by double quotes: "...". + - Unescaped double quotes are removed from the input. Their only effect is + that within double quotes, space and tab are treated like normal + characters. + - Backslashes not followed by double quotes are not special. + - But 2*n+1 backslashes followed by a double quote become + n backslashes followed by a double quote (n >= 0): + \" -> " + \\\" -> \" + \\\\\" -> \\" + */ +#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +char ** +prepare_spawn (char **argv) +{ + size_t argc; + char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + new_argv = XMALLOC (char *, argc + 1); + + /* Put quoted arguments into the new argument vector. */ + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + if (string[0] == '\0') + new_argv[i] = xstrdup ("\"\""); + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + { + int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + size_t length; + unsigned int backslashes; + const char *s; + char *quoted_string; + char *p; + + length = 0; + backslashes = 0; + if (quote_around) + length++; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + length += backslashes + 1; + length++; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + length += backslashes + 1; + + quoted_string = XMALLOC (char, length + 1); + + p = quoted_string; + backslashes = 0; + if (quote_around) + *p++ = '"'; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + { + unsigned int j; + for (j = backslashes + 1; j > 0; j--) + *p++ = '\\'; + } + *p++ = c; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + { + unsigned int j; + for (j = backslashes; j > 0; j--) + *p++ = '\\'; + *p++ = '"'; + } + *p = '\0'; + + new_argv[i] = quoted_string; + } + else + new_argv[i] = (char *) string; + } + new_argv[argc] = NULL; + + return new_argv; +} +EOF + ;; + esac + + cat <<"EOF" +void lt_dump_script (FILE* f) +{ +EOF + func_emit_wrapper yes | + $SED -n -e ' +s/^\(.\{79\}\)\(..*\)/\1\ +\2/ +h +s/\([\\"]\)/\\\1/g +s/$/\\n/ +s/\([^\n]*\).*/ fputs ("\1", f);/p +g +D' + cat <<"EOF" +} +EOF +} +# end: func_emit_cwrapperexe_src + +# func_win32_import_lib_p ARG +# True if ARG is an import lib, as indicated by $file_magic_cmd +func_win32_import_lib_p () +{ + $debug_cmd + + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in + *import*) : ;; + *) false ;; + esac +} + +# func_suncc_cstd_abi +# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! +# Several compiler flags select an ABI that is incompatible with the +# Cstd library. Avoid specifying it if any are in CXXFLAGS. +func_suncc_cstd_abi () +{ + $debug_cmd + + case " $compile_command " in + *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) + suncc_use_cstd_abi=no + ;; + *) + suncc_use_cstd_abi=yes + ;; + esac +} + +# func_mode_link arg... +func_mode_link () +{ + $debug_cmd + + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # what system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll that has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + bindir= + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + os2dllname= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=false + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module=$wl-single_module + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test yes != "$build_libtool_libs" \ + && func_fatal_configuration "cannot build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg=$1 + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + bindir) + bindir=$arg + prev= + continue + ;; + dlfiles|dlprefiles) + $preload || { + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=: + } + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test no = "$dlself"; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test dlprefiles = "$prev"; then + dlself=yes + elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test dlfiles = "$prev"; then + func_append dlfiles " $arg" + else + func_append dlprefiles " $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols=$arg + test -f "$arg" \ + || func_fatal_error "symbol file '$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex=$arg + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) func_append deplibs " $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir=$arg + prev= + continue + ;; + mllvm) + # Clang does not use LLVM to link, so we can simply discard any + # '-mllvm $arg' options when doing the link step. + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# func_append moreargs " $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + if test none != "$pic_object"; then + # Prepend the subdirectory the object is found in. + pic_object=$xdir$pic_object + + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test dlprefiles = "$prev"; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg=$pic_object + fi + + # Non-PIC object. + if test none != "$non_pic_object"; then + # Prepend the subdirectory the object is found in. + non_pic_object=$xdir$non_pic_object + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object=$pic_object + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "'$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file '$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + os2dllname) + os2dllname=$arg + prev= + continue + ;; + precious_regex) + precious_files_regex=$arg + prev= + continue + ;; + release) + release=-$arg + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test rpath = "$prev"; then + case "$rpath " in + *" $arg "*) ;; + *) func_append rpath " $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) func_append xrpath " $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds=$arg + prev= + continue + ;; + weak) + func_append weak_libs " $arg" + prev= + continue + ;; + xcclinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg=$arg + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "'-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -bindir) + prev=bindir + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test X-export-symbols = "X$arg"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname "-L" '' "$arg" + if test -z "$func_stripname_result"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between '-L' and '$1'" + else + func_fatal_error "need path for '-L' option" + fi + fi + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of '$dir'" + dir=$absdir + ;; + esac + case "$deplibs " in + *" -L$dir "* | *" $arg "*) + # Will only happen for absolute or sysroot arguments + ;; + *) + # Preserve sysroot, but never include relative directories + case $dir in + [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; + *) func_append deplibs " -L$dir" ;; + esac + func_append lib_search_path " $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) func_append dllsearchpath ":$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test X-lc = "X$arg" || test X-lm = "X$arg"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test X-lc = "X$arg" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + # Do not include libc due to us having libc/libc_r. + test X-lc = "X$arg" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + func_append deplibs " System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test X-lc = "X$arg" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test X-lc = "X$arg" && continue + ;; + esac + elif test X-lc_r = "X$arg"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + func_append deplibs " $arg" + continue + ;; + + -mllvm) + prev=mllvm + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot|--sysroot) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + continue + ;; + + -multi_module) + single_module=$wl-multi_module + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "'-no-install' is ignored for $host" + func_warning "assuming '-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -os2dllname) + prev=os2dllname + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + =*) + func_stripname '=' '' "$dir" + dir=$lt_sysroot$func_stripname_result + ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs=$IFS; IFS=, + for flag in $args; do + IFS=$save_ifs + func_quote_for_eval "$flag" + func_append arg " $func_quote_for_eval_result" + func_append compiler_flags " $func_quote_for_eval_result" + done + IFS=$save_ifs + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs=$IFS; IFS=, + for flag in $args; do + IFS=$save_ifs + func_quote_for_eval "$flag" + func_append arg " $wl$func_quote_for_eval_result" + func_append compiler_flags " $wl$func_quote_for_eval_result" + func_append linker_flags " $func_quote_for_eval_result" + done + IFS=$save_ifs + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + + # Flags to be passed through unchanged, with rationale: + # -64, -mips[0-9] enable 64-bit mode for the SGI compiler + # -r[0-9][0-9]* specify processor for the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler + # +DA*, +DD* enable 64-bit mode for the HP compiler + # -q* compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* architecture-specific flags for GCC + # -F/path path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* profiling flags for GCC + # -fstack-protector* stack protector flags for GCC + # @file GCC response files + # -tp=* Portland pgcc target processor selection + # --sysroot=* for sysroot support + # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + # -specs=* GCC specs files + # -stdlib=* select c++ std lib with clang + # -fsanitize=* Clang/GCC memory and address sanitizer + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ + -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \ + -specs=*|-fsanitize=*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + func_append compile_command " $arg" + func_append finalize_command " $arg" + func_append compiler_flags " $arg" + continue + ;; + + -Z*) + if test os2 = "`expr $host : '.*\(os2\)'`"; then + # OS/2 uses -Zxxx to specify OS/2-specific options + compiler_flags="$compiler_flags $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case $arg in + -Zlinker | -Zstack) + prev=xcompiler + ;; + esac + continue + else + # Otherwise treat like 'Some other compiler flag' below + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + fi + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + + *.$objext) + # A standard object. + func_append objs " $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + test none = "$pic_object" || { + # Prepend the subdirectory the object is found in. + pic_object=$xdir$pic_object + + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test dlprefiles = "$prev"; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg=$pic_object + } + + # Non-PIC object. + if test none != "$non_pic_object"; then + # Prepend the subdirectory the object is found in. + non_pic_object=$xdir$non_pic_object + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object=$pic_object + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "'$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + func_append deplibs " $arg" + func_append old_deplibs " $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + func_resolve_sysroot "$arg" + if test dlfiles = "$prev"; then + # This library was specified with -dlopen. + func_append dlfiles " $func_resolve_sysroot_result" + prev= + elif test dlprefiles = "$prev"; then + # The library was specified with -dlpreopen. + func_append dlprefiles " $func_resolve_sysroot_result" + prev= + else + func_append deplibs " $func_resolve_sysroot_result" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the '$prevarg' option requires an argument" + + if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname=$func_basename_result + libobjs_save=$libobjs + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + # Definition is injected by LT_CONFIG during libtool generation. + func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH" + + func_dirname "$output" "/" "" + output_objdir=$func_dirname_result$objdir + func_to_tool_file "$output_objdir/" + tool_output_objdir=$func_to_tool_file_result + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_preserve_dup_deps; then + case "$libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append libs " $deplib" + done + + if test lib = "$linkmode"; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; + esac + func_append pre_post_deps " $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=false + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test lib,link = "$linkmode,$pass"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs=$tmp_deplibs + fi + + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass"; then + libs=$deplibs + deplibs= + fi + if test prog = "$linkmode"; then + case $pass in + dlopen) libs=$dlfiles ;; + dlpreopen) libs=$dlprefiles ;; + link) + libs="$deplibs %DEPLIBS%" + test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" + ;; + esac + fi + if test lib,dlpreopen = "$linkmode,$pass"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + func_resolve_sysroot "$lib" + case $lib in + *.la) func_source "$func_resolve_sysroot_result" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + func_basename "$deplib" + deplib_base=$func_basename_result + case " $weak_libs " in + *" $deplib_base "*) ;; + *) func_append deplibs " $deplib" ;; + esac + done + done + libs=$dlprefiles + fi + if test dlopen = "$pass"; then + # Collect dlpreopened libraries + save_deplibs=$deplibs + deplibs= + fi + + for deplib in $libs; do + lib= + found=false + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append compiler_flags " $deplib" + if test lib = "$linkmode"; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test lib != "$linkmode" && test prog != "$linkmode"; then + func_warning "'-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test lib = "$linkmode"; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib=$searchdir/lib$name$search_ext + if test -f "$lib"; then + if test .la = "$search_ext"; then + found=: + else + found=false + fi + break 2 + fi + done + done + if $found; then + # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll=$l + done + if test "X$ll" = "X$old_library"; then # only static version available + found=false + func_dirname "$lib" "" "." + ladir=$func_dirname_result + lib=$ladir/$old_library + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + else + # deplib doesn't seem to be a libtool library + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + ;; # -l + *.ltframework) + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test lib = "$linkmode"; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test conv = "$pass" && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + prog) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + continue + fi + if test scan = "$pass"; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + *) + func_warning "'-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test link = "$pass"; then + func_stripname '-R' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) + func_resolve_sysroot "$deplib" + lib=$func_resolve_sysroot_result + ;; + *.$libext) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=false + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=: + fi + ;; + pass_all) + valid_a_lib=: + ;; + esac + if $valid_a_lib; then + echo + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + else + echo + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not use here." + fi + ;; + esac + continue + ;; + prog) + if test link != "$pass"; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + elif test prog = "$linkmode"; then + if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + func_append newdlprefiles " $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append newdlfiles " $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=: + continue + ;; + esac # case $deplib + + $found || test -f "$lib" \ + || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "'$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir=$func_dirname_result + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass" || + { test prog != "$linkmode" && test lib != "$linkmode"; }; then + test -n "$dlopen" && func_append dlfiles " $dlopen" + test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" + fi + + if test conv = "$pass"; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for '$lib'" + fi + # It is a libtool convenience library, so add in its objects. + func_append convenience " $ladir/$objdir/$old_library" + func_append old_convenience " $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done + elif test prog != "$linkmode" && test lib != "$linkmode"; then + func_fatal_error "'$lib' is not a convenience library" + fi + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + if test -n "$old_library" && + { test yes = "$prefer_static_libs" || + test built,no = "$prefer_static_libs,$installed"; }; then + linklib=$old_library + else + for l in $old_library $library_names; do + linklib=$l + done + fi + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for '$lib'" + fi + + # This library was specified with -dlopen. + if test dlopen = "$pass"; then + test -z "$libdir" \ + && func_fatal_error "cannot -dlopen a convenience library: '$lib'" + if test -z "$dlname" || + test yes != "$dlopen_support" || + test no = "$build_libtool_libs" + then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + func_append dlprefiles " $lib $dependency_libs" + else + func_append newdlfiles " $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of '$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir=$ladir + fi + ;; + esac + func_basename "$lib" + laname=$func_basename_result + + # Find the relevant object directory and library name. + if test yes = "$installed"; then + if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library '$lib' was moved." + dir=$ladir + absdir=$abs_ladir + libdir=$abs_ladir + else + dir=$lt_sysroot$libdir + absdir=$lt_sysroot$libdir + fi + test yes = "$hardcode_automatic" && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir=$ladir + absdir=$abs_ladir + # Remove this search path later + func_append notinst_path " $abs_ladir" + else + dir=$ladir/$objdir + absdir=$abs_ladir/$objdir + # Remove this search path later + func_append notinst_path " $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test dlpreopen = "$pass"; then + if test -z "$libdir" && test prog = "$linkmode"; then + func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" + fi + case $host in + # special handling for platforms with PE-DLLs. + *cygwin* | *mingw* | *cegcc* ) + # Linker will automatically link against shared library if both + # static and shared are present. Therefore, ensure we extract + # symbols from the import library if a shared library is present + # (otherwise, the dlopen module name will be incorrect). We do + # this by putting the import library name into $newdlprefiles. + # We recover the dlopen module name by 'saving' the la file + # name in a special purpose variable, and (later) extracting the + # dlname from the la file. + if test -n "$dlname"; then + func_tr_sh "$dir/$linklib" + eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" + func_append newdlprefiles " $dir/$linklib" + else + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + fi + ;; + * ) + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + func_append newdlprefiles " $dir/$dlname" + else + func_append newdlprefiles " $dir/$linklib" + fi + ;; + esac + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test lib = "$linkmode"; then + deplibs="$dir/$old_library $deplibs" + elif test prog,link = "$linkmode,$pass"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test prog = "$linkmode" && test link != "$pass"; then + func_append newlib_search_path " $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=false + if test no != "$link_all_deplibs" || test -z "$library_names" || + test no = "$build_libtool_libs"; then + linkalldeplibs=: + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + esac + # Need to link against all dependency_libs? + if $linkalldeplibs; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test prog,link = "$linkmode,$pass"; then + if test -n "$library_names" && + { { test no = "$prefer_static_libs" || + test built,yes = "$prefer_static_libs,$installed"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then + # Make sure the rpath contains only unique directories. + case $temp_rpath: in + *"$absdir:"*) ;; + *) func_append temp_rpath "$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if $alldeplibs && + { test pass_all = "$deplibs_check_method" || + { test yes = "$build_libtool_libs" && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test built = "$use_static_libs" && test yes = "$installed"; then + use_static_libs=no + fi + if test -n "$library_names" && + { test no = "$use_static_libs" || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc* | *os2*) + # No point in relinking DLLs because paths are not encoded + func_append notinst_deplibs " $lib" + need_relink=no + ;; + *) + if test no = "$installed"; then + func_append notinst_deplibs " $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule= + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule=$dlpremoduletest + break + fi + done + if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then + echo + if test prog = "$linkmode"; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test lib = "$linkmode" && + test yes = "$hardcode_into_libs"; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname=$1 + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname=$dlname + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc* | *os2*) + func_arith $current - $age + major=$func_arith_result + versuffix=-$major + ;; + esac + eval soname=\"$soname_spec\" + else + soname=$realname + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot=$soname + func_basename "$soroot" + soname=$func_basename_result + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from '$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for '$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test prog = "$linkmode" || test relink != "$opt_mode"; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test no = "$hardcode_direct"; then + add=$dir/$linklib + case $host in + *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; + *-*-sysv4*uw2*) add_dir=-L$dir ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir=-L$dir ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we cannot + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library"; then + echo + echo "*** And there doesn't seem to be a static archive available" + echo "*** The link will probably fail, sorry" + else + add=$dir/$old_library + fi + elif test -n "$old_library"; then + add=$dir/$old_library + fi + fi + esac + elif test no = "$hardcode_minus_L"; then + case $host in + *-*-sunos*) add_shlibpath=$dir ;; + esac + add_dir=-L$dir + add=-l$name + elif test no = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name + else + lib_linked=no + fi + ;; + relink) + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$dir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$absdir + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test yes != "$lib_linked"; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) func_append compile_shlibpath "$add_shlibpath:" ;; + esac + fi + if test prog = "$linkmode"; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test yes != "$hardcode_direct" && + test yes != "$hardcode_minus_L" && + test yes = "$hardcode_shlibpath_var"; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + fi + fi + fi + + if test prog = "$linkmode" || test relink = "$opt_mode"; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$libdir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$libdir + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + add=-l$name + elif test yes = "$hardcode_automatic"; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib"; then + add=$inst_prefix_dir$libdir/$linklib + else + add=$libdir/$linklib + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir=-L$libdir + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add=-l$name + fi + + if test prog = "$linkmode"; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test prog = "$linkmode"; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test unsupported != "$hardcode_direct"; then + test -n "$old_library" && linklib=$old_library + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test yes = "$build_libtool_libs"; then + # Not a shared library + if test pass_all != "$deplibs_check_method"; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + $ECHO "*** Warning: This system cannot link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test yes = "$module"; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** 'nm' from GNU binutils and a full rebuild may help." + fi + if test no = "$build_old_libs"; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test lib = "$linkmode"; then + if test -n "$dependency_libs" && + { test yes != "$hardcode_into_libs" || + test yes = "$build_old_libs" || + test yes = "$link_static"; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) func_append xrpath " $temp_xrpath";; + esac;; + *) func_append temp_deplibs " $libdir";; + esac + done + dependency_libs=$temp_deplibs + fi + + func_append newlib_search_path " $absdir" + # Link against this library + test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result";; + *) func_resolve_sysroot "$deplib" ;; + esac + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $func_resolve_sysroot_result "*) + func_append specialdeplibs " $func_resolve_sysroot_result" ;; + esac + fi + func_append tmp_libs " $func_resolve_sysroot_result" + done + + if test no != "$link_all_deplibs"; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + path= + case $deplib in + -L*) path=$deplib ;; + *.la) + func_resolve_sysroot "$deplib" + deplib=$func_resolve_sysroot_result + func_dirname "$deplib" "" "." + dir=$func_dirname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of '$dir'" + absdir=$dir + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names"; then + for tmp in $deplibrary_names; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl"; then + depdepl=$absdir/$objdir/$depdepl + darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" + func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" + path= + fi + fi + ;; + *) + path=-L$absdir/$objdir + ;; + esac + else + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "'$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "'$deplib' seems to be moved" + + path=-L$absdir + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test link = "$pass"; then + if test prog = "$linkmode"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs=$newdependency_libs + if test dlpreopen = "$pass"; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test dlopen != "$pass"; then + test conv = "$pass" || { + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) func_append lib_search_path " $dir" ;; + esac + done + newlib_search_path= + } + + if test prog,link = "$linkmode,$pass"; then + vars="compile_deplibs finalize_deplibs" + else + vars=deplibs + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) func_append tmp_libs " $deplib" ;; + esac + ;; + *) func_append tmp_libs " $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + + # Add Sun CC postdeps if required: + test CXX = "$tagname" && { + case $host_os in + linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C++ 5.9 + func_suncc_cstd_abi + + if test no != "$suncc_use_cstd_abi"; then + func_append postdeps ' -library=Cstd -library=Crun' + fi + ;; + esac + ;; + + solaris*) + func_cc_basename "$CC" + case $func_cc_basename_result in + CC* | sunCC*) + func_suncc_cstd_abi + + if test no != "$suncc_use_cstd_abi"; then + func_append postdeps ' -library=Cstd -library=Crun' + fi + ;; + esac + ;; + esac + } + + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i= + ;; + esac + if test -n "$i"; then + func_append tmp_libs " $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test prog = "$linkmode"; then + dlfiles=$newdlfiles + fi + if test prog = "$linkmode" || test lib = "$linkmode"; then + dlprefiles=$newdlprefiles + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "'-l' and '-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "'-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "'-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "'-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "'-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "'-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs=$output + func_append objs "$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form 'libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test no = "$module" \ + && func_fatal_help "libtool library '$output' must begin with 'lib'" + + if test no != "$need_lib_prefix"; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test pass_all != "$deplibs_check_method"; then + func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" + else + echo + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + func_append libobjs " $objs" + fi + fi + + test no = "$dlself" \ + || func_warning "'-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test 1 -lt "$#" \ + && func_warning "ignoring multiple '-rpath's for a libtool library" + + install_libdir=$1 + + oldlibs= + if test -z "$rpath"; then + if test yes = "$build_libtool_libs"; then + # Building a libtool convenience library. + # Some compilers have problems with a '.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "'-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "'-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs=$IFS; IFS=: + set dummy $vinfo 0 0 0 + shift + IFS=$save_ifs + + test -n "$7" && \ + func_fatal_help "too many parameters to '-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major=$1 + number_minor=$2 + number_revision=$3 + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # that has an extra 1 added just for fun + # + case $version_type in + # correct linux to gnu/linux during the next big refactor + darwin|freebsd-elf|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age=$number_minor + revision=$number_revision + ;; + freebsd-aout|qnx|sunos) + current=$number_major + revision=$number_minor + age=0 + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age=$number_minor + revision=$number_minor + lt_irix_increment=no + ;; + *) + func_fatal_configuration "$modename: unknown library version type '$version_type'" + ;; + esac + ;; + no) + current=$1 + revision=$2 + age=$3 + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT '$current' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION '$revision' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE '$age' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE '$age' is greater than the current interface number '$current'" + func_fatal_error "'$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + # On Darwin other compilers + case $CC in + nagfor*) + verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" + ;; + *) + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + esac + ;; + + freebsd-aout) + major=.$current + versuffix=.$current.$revision + ;; + + freebsd-elf) + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + ;; + + irix | nonstopux) + if test no = "$lt_irix_increment"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring=$verstring_prefix$major.$revision + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test 0 -ne "$loop"; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring=$verstring_prefix$major.$iface:$verstring + done + + # Before this point, $major must not contain '.'. + major=.$major + versuffix=$major.$revision + ;; + + linux) # correct to gnu/linux during the next big refactor + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=.$current.$age.$revision + verstring=$current.$age.$revision + + # Add in all the interfaces that we are compatible with. + loop=$age + while test 0 -ne "$loop"; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring=$verstring:$iface.0 + done + + # Make executables depend on our current version. + func_append verstring ":$current.0" + ;; + + qnx) + major=.$current + versuffix=.$current + ;; + + sco) + major=.$current + versuffix=.$current + ;; + + sunos) + major=.$current + versuffix=.$current.$revision + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 file systems. + func_arith $current - $age + major=$func_arith_result + versuffix=-$major + ;; + + *) + func_fatal_configuration "unknown library version type '$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring=0.0 + ;; + esac + if test no = "$need_version"; then + versuffix= + else + versuffix=.0.0 + fi + fi + + # Remove version info from name if versioning should be avoided + if test yes,no = "$avoid_version,$need_version"; then + major= + versuffix= + verstring= + fi + + # Check to see if the archive will have undefined symbols. + if test yes = "$allow_undefined"; then + if test unsupported = "$allow_undefined_flag"; then + if test yes = "$build_old_libs"; then + func_warning "undefined symbols not allowed in $host shared libraries; building static only" + build_libtool_libs=no + else + func_fatal_error "can't build $host shared library unless -no-undefined is specified" + fi + fi + else + # Don't allow undefined symbols. + allow_undefined_flag=$no_undefined_flag + fi + + fi + + func_generate_dlsyms "$libname" "$libname" : + func_append libobjs " $symfileobj" + test " " = "$libobjs" && libobjs= + + if test relink != "$opt_mode"; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) + if test -n "$precious_files_regex"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + func_append removelist " $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then + func_append oldlibs " $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` + # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` + # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + func_replace_sysroot "$libdir" + func_append temp_xrpath " -R$func_replace_sysroot_result" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles=$dlfiles + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) func_append dlfiles " $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles=$dlprefiles + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) func_append dlprefiles " $lib" ;; + esac + done + + if test yes = "$build_libtool_libs"; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + func_append deplibs " System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test yes = "$build_libtool_need_lc"; then + func_append deplibs " -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release= + versuffix= + major= + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c <<EOF + int main() { return 0; } +EOF + $opt_dry_run || $RM conftest + if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then + ldd_output=`ldd conftest` + for i in $deplibs; do + case $i in + -l*) + func_stripname -l '' "$i" + name=$func_stripname_result + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $i "*) + func_append newdeplibs " $i" + i= + ;; + esac + fi + if test -n "$i"; then + libname=`eval "\\$ECHO \"$libname_spec\""` + deplib_matches=`eval "\\$ECHO \"$library_names_spec\""` + set dummy $deplib_matches; shift + deplib_match=$1 + if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then + func_append newdeplibs " $i" + else + droppeddeps=yes + echo + $ECHO "*** Warning: dynamic linker does not accept needed library $i." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which I believe you do not have" + echo "*** because a test_compile did reveal that the linker did not use it for" + echo "*** its dynamic dependency list that programs get resolved with at runtime." + fi + fi + ;; + *) + func_append newdeplibs " $i" + ;; + esac + done + else + # Error occurred in the first compile. Let's try to salvage + # the situation: Compile a separate program for each library. + for i in $deplibs; do + case $i in + -l*) + func_stripname -l '' "$i" + name=$func_stripname_result + $opt_dry_run || $RM conftest + if $LTCC $LTCFLAGS -o conftest conftest.c $i; then + ldd_output=`ldd conftest` + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $i "*) + func_append newdeplibs " $i" + i= + ;; + esac + fi + if test -n "$i"; then + libname=`eval "\\$ECHO \"$libname_spec\""` + deplib_matches=`eval "\\$ECHO \"$library_names_spec\""` + set dummy $deplib_matches; shift + deplib_match=$1 + if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then + func_append newdeplibs " $i" + else + droppeddeps=yes + echo + $ECHO "*** Warning: dynamic linker does not accept needed library $i." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because a test_compile did reveal that the linker did not use this one" + echo "*** as a dynamic dependency that programs can get resolved with at runtime." + fi + fi + else + droppeddeps=yes + echo + $ECHO "*** Warning! Library $i is needed by this library but I was not able to" + echo "*** make it link in! You will probably need to install it or some" + echo "*** library that it depends on before this library will be fully" + echo "*** functional. Installing it before continuing would be even better." + fi + ;; + *) + func_append newdeplibs " $i" + ;; + esac + done + fi + ;; + file_magic*) + set dummy $deplibs_check_method; shift + file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib= + ;; + esac + fi + if test -n "$a_deplib"; then + libname=`eval "\\$ECHO \"$libname_spec\""` + if test -n "$file_magic_glob"; then + libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob` + else + libnameglob=$libname + fi + test yes = "$want_nocaseglob" && nocaseglob=`shopt -p nocaseglob` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + if test yes = "$want_nocaseglob"; then + shopt -s nocaseglob + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + $nocaseglob + else + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + fi + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib=$potent_lib + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | $SED 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; + *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib= + break 2 + fi + done + done + fi + if test -n "$a_deplib"; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib"; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib= + ;; + esac + fi + if test -n "$a_deplib"; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib=$potent_lib # see symlink-check above in file_magic test + if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib= + break 2 + fi + done + done + fi + if test -n "$a_deplib"; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib"; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs= + tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + for i in $predeps $postdeps; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` + done + fi + case $tmp_deplibs in + *[!\ \ ]*) + echo + if test none = "$deplibs_check_method"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + ;; + esac + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + if test yes = "$droppeddeps"; then + if test yes = "$module"; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** 'nm' from GNU binutils and a full rebuild may help." + fi + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test no = "$allow_undefined"; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + deplibs=$new_libs + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test yes = "$build_libtool_libs"; then + # Remove $wl instances when linking with ld. + # FIXME: should test the right _cmds variable. + case $archive_cmds in + *\$LD\ *) wl= ;; + esac + if test yes = "$hardcode_into_libs"; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath=$finalize_rpath + test relink = "$opt_mode" || rpath=$compile_rpath$rpath + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + func_replace_sysroot "$libdir" + libdir=$func_replace_sysroot_result + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append dep_rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath=$finalize_shlibpath + test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname=$1 + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname=$realname + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib=$output_objdir/$realname + linknames= + for link + do + func_append linknames " $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols=$output_objdir/$libname.uexp + func_append delfiles " $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + func_dll_def_p "$export_symbols" || { + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols=$export_symbols + export_symbols= + always_export_symbols=yes + } + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs=$IFS; IFS='~' + for cmd1 in $cmds; do + IFS=$save_ifs + # Take the normal branch if the nm_file_list_spec branch + # doesn't work or if tool conversion is not needed. + case $nm_file_list_spec~$to_tool_file_cmd in + *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) + try_normal_branch=yes + eval cmd=\"$cmd1\" + func_len " $cmd" + len=$func_len_result + ;; + *) + try_normal_branch=no + ;; + esac + if test yes = "$try_normal_branch" \ + && { test "$len" -lt "$max_cmd_len" \ + || test "$max_cmd_len" -le -1; } + then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + elif test -n "$nm_file_list_spec"; then + func_basename "$output" + output_la=$func_basename_result + save_libobjs=$libobjs + save_output=$output + output=$output_objdir/$output_la.nm + func_to_tool_file "$output" + libobjs=$nm_file_list_spec$func_to_tool_file_result + func_append delfiles " $output" + func_verbose "creating $NM input file list: $output" + for obj in $save_libobjs; do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > "$output" + eval cmd=\"$cmd1\" + func_show_eval "$cmd" 'exit $?' + output=$save_output + libobjs=$save_libobjs + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS=$save_ifs + if test -n "$export_symbols_regex" && test : != "$skipped_export"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test : != "$skipped_export" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands, which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + func_append tmp_deplibs " $test_deplib" + ;; + esac + done + deplibs=$tmp_deplibs + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test yes = "$compiler_needs_object" && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + func_append linker_flags " $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test relink = "$opt_mode"; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test yes = "$module" && test -n "$module_cmds"; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test : != "$skipped_export" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + func_basename "$output" + output_la=$func_basename_result + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then + output=$output_objdir/$output_la.lnkscript + func_verbose "creating GNU ld script: $output" + echo 'INPUT (' > $output + for obj in $save_libobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + echo ')' >> $output + func_append delfiles " $output" + func_to_tool_file "$output" + output=$func_to_tool_file_result + elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then + output=$output_objdir/$output_la.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test yes = "$compiler_needs_object"; then + firstobj="$1 " + shift + fi + for obj + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + func_append delfiles " $output" + func_to_tool_file "$output" + output=$firstobj\"$file_list_spec$func_to_tool_file_result\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-$k.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test -z "$objlist" || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test 1 -eq "$k"; then + # The first file doesn't have a previous command to add. + reload_objs=$objlist + eval concat_cmds=\"$reload_cmds\" + else + # All subsequent reloadable object files will link in + # the last one created. + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-$k.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-$k.$objext + objlist=" $obj" + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds$reload_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + func_append delfiles " $output" + + else + output= + fi + + ${skipped_export-false} && { + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + } + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs=$IFS; IFS='~' + for cmd in $concat_cmds; do + IFS=$save_ifs + $opt_quiet || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS=$save_ifs + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + ${skipped_export-false} && { + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands, which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + } + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test yes = "$module" && test -n "$module_cmds"; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs=$IFS; IFS='~' + for cmd in $cmds; do + IFS=$sp$nl + eval cmd=\"$cmd\" + IFS=$save_ifs + $opt_quiet || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS=$save_ifs + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test yes = "$module" || test yes = "$export_dynamic"; then + # On all known operating systems, these are identical. + dlname=$soname + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "'-l' and '-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "'-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "'-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "'-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "'-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object '$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj=$output + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # if reload_cmds runs $LD directly, get rid of -Wl from + # whole_archive_flag_spec and hope we can get by with turning comma + # into space. + case $reload_cmds in + *\$LD[\ \$]*) wl= ;; + esac + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` + reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags + else + gentop=$output_objdir/${obj}x + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # If we're not building shared, we need to use non_pic_objs + test yes = "$build_libtool_libs" || libobjs=$non_pic_objects + + # Create the old-style object. + reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs + + output=$obj + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + test yes = "$build_libtool_libs" || { + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + } + + if test -n "$pic_flag" || test default != "$pic_mode"; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output=$libobj + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "'-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "'-release' is ignored for programs" + + $preload \ + && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ + && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test CXX = "$tagname"; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + func_append compile_command " $wl-bind_at_load" + func_append finalize_command " $wl-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + compile_deplibs=$new_libs + + + func_append compile_command " $compile_deplibs" + func_append finalize_command " $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) func_append dllsearchpath ":$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath=$rpath + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) func_append finalize_perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath=$rpath + + if test -n "$libobjs" && test yes = "$build_old_libs"; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" false + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=: + case $host in + *cegcc* | *mingw32ce*) + # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. + wrappers_required=false + ;; + *cygwin* | *mingw* ) + test yes = "$build_libtool_libs" || wrappers_required=false + ;; + *) + if test no = "$need_relink" || test yes != "$build_libtool_libs"; then + wrappers_required=false + fi + ;; + esac + $wrappers_required || { + # Replace the output file specification. + compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + link_command=$compile_command$compile_rpath + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.$objext"; then + func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' + fi + + exit $exit_status + } + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + func_append rpath "$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test yes = "$no_install"; then + # We don't need to create a wrapper script. + link_command=$compile_var$compile_command$compile_rpath + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + exit $EXIT_SUCCESS + fi + + case $hardcode_action,$fast_install in + relink,*) + # Fast installation is not supported + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "'$output' will be relinked during installation" + ;; + *,yes) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` + ;; + *,no) + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath + ;; + *,needless) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command= + ;; + esac + + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output_objdir/$outputname" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource=$output_path/$objdir/lt-$output_name.c + cwrapper=$output_path/$output_name.exe + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host"; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + case $build_libtool_libs in + convenience) + oldobjs="$libobjs_save $symfileobj" + addlibs=$convenience + build_libtool_libs=no + ;; + module) + oldobjs=$libobjs_save + addlibs=$old_convenience + build_libtool_libs=no + ;; + *) + oldobjs="$old_deplibs $non_pic_objects" + $preload && test -f "$symfileobj" \ + && func_append oldobjs " $symfileobj" + addlibs=$old_convenience + ;; + esac + + if test -n "$addlibs"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $addlibs + func_append oldobjs " $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append oldobjs " $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + echo "copying selected object files to avoid basename conflicts..." + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase=$func_basename_result + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + func_append oldobjs " $gentop/$newobj" + ;; + *) func_append oldobjs " $obj" ;; + esac + done + fi + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + elif test -n "$archiver_list_spec"; then + func_verbose "using command file archive linking..." + for obj in $oldobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > $output_objdir/$libname.libcmd + func_to_tool_file "$output_objdir/$libname.libcmd" + oldobjs=" $archiver_list_spec$func_to_tool_file_result" + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj"; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test -z "$oldobjs"; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test yes = "$build_old_libs" && old_library=$libname.$libext + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + if test yes = "$hardcode_automatic"; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test yes = "$installed"; then + if test -z "$install_libdir"; then + break + fi + output=$output_objdir/${outputname}i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name=$func_basename_result + func_resolve_sysroot "$deplib" + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` + test -z "$libdir" && \ + func_fatal_error "'$deplib' is not a valid libtool archive" + func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" + ;; + -L*) + func_stripname -L '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -L$func_replace_sysroot_result" + ;; + -R*) + func_stripname -R '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -R$func_replace_sysroot_result" + ;; + *) func_append newdependency_libs " $deplib" ;; + esac + done + dependency_libs=$newdependency_libs + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "'$lib' is not a valid libtool archive" + func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" + ;; + *) func_append newdlfiles " $lib" ;; + esac + done + dlfiles=$newdlfiles + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "'$lib' is not a valid libtool archive" + func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" + ;; + esac + done + dlprefiles=$newdlprefiles + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlfiles " $abs" + done + dlfiles=$newdlfiles + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlprefiles " $abs" + done + dlprefiles=$newdlprefiles + fi + $RM $output + # place dlname in correct position for cygwin + # In fact, it would be nice if we could use this code for all target + # systems that can't hard-code library paths into their executables + # and that have no shared library path variable independent of PATH, + # but it turns out we can't easily determine that from inspecting + # libtool variables, so we have to hard-code the OSs to which it + # applies here; at the moment, that means platforms that use the PE + # object format with DLL files. See the long comment at the top of + # tests/bindir.at for full details. + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + # If a -bindir argument was supplied, place the dll there. + if test -n "$bindir"; then + func_relative_path "$install_libdir" "$bindir" + tdlname=$func_relative_path_result/$dlname + else + # Otherwise fall back on heuristic. + tdlname=../bin/$dlname + fi + ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that cannot go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test no,yes = "$installed,$need_relink"; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +if test link = "$opt_mode" || test relink = "$opt_mode"; then + func_mode_link ${1+"$@"} +fi + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $debug_cmd + + RM=$nonopt + files= + rmforce=false + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic=$magic + + for arg + do + case $arg in + -f) func_append RM " $arg"; rmforce=: ;; + -*) func_append RM " $arg" ;; + *) func_append files " $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + for file in $files; do + func_dirname "$file" "" "." + dir=$func_dirname_result + if test . = "$dir"; then + odir=$objdir + else + odir=$dir/$objdir + fi + func_basename "$file" + name=$func_basename_result + test uninstall = "$opt_mode" && odir=$dir + + # Remember odir for removal later, being careful to avoid duplicates + if test clean = "$opt_mode"; then + case " $rmdirs " in + *" $odir "*) ;; + *) func_append rmdirs " $odir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif $rmforce; then + continue + fi + + rmfiles=$file + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + func_append rmfiles " $odir/$n" + done + test -n "$old_library" && func_append rmfiles " $odir/$old_library" + + case $opt_mode in + clean) + case " $library_names " in + *" $dlname "*) ;; + *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; + esac + test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && test none != "$pic_object"; then + func_append rmfiles " $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && test none != "$non_pic_object"; then + func_append rmfiles " $dir/$non_pic_object" + fi + fi + ;; + + *) + if test clean = "$opt_mode"; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + func_append rmfiles " $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + func_append rmfiles " $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + func_append rmfiles " $odir/$name $odir/${name}S.$objext" + if test yes = "$fast_install" && test -n "$relink_command"; then + func_append rmfiles " $odir/lt-$name" + fi + if test "X$noexename" != "X$name"; then + func_append rmfiles " $odir/lt-$noexename.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + + # Try to remove the $objdir's in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then + func_mode_uninstall ${1+"$@"} +fi + +test -z "$opt_mode" && { + help=$generic_help + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode '$opt_mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# where we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/libs/ode-0.16.1/m4/libtool.m4 b/libs/ode-0.16.1/m4/libtool.m4 new file mode 100644 index 0000000..10ab284 --- /dev/null +++ b/libs/ode-0.16.1/m4/libtool.m4 @@ -0,0 +1,8388 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 2014 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool 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 2 of of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 <http://www.gnu.org/licenses/>. +]) + +# serial 58 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK +AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS=$ltmain + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_PREPARE_CC_BASENAME +# ----------------------- +m4_defun([_LT_PREPARE_CC_BASENAME], [ +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in @S|@*""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} +])# _LT_PREPARE_CC_BASENAME + + +# _LT_CC_BASENAME(CC) +# ------------------- +# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, +# but that macro is also expanded into generated libtool script, which +# arranges for $SED and $ECHO to be set by different means. +m4_defun([_LT_CC_BASENAME], +[m4_require([_LT_PREPARE_CC_BASENAME])dnl +AC_REQUIRE([_LT_DECL_SED])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl +func_cc_basename $1 +cc_basename=$func_cc_basename_result +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl + +_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl +dnl +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_WITH_SYSROOT])dnl +m4_require([_LT_CMD_TRUNCATE])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options that allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld=$lt_cv_prog_gnu_ld + +old_CC=$CC +old_CFLAGS=$CFLAGS + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. +m4_defun([_LT_PREPARE_SED_QUOTE_VARS], +[# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' +]) + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from 'configure', and 'config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# 'config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain=$ac_aux_dir/ltmain.sh +])# _LT_PROG_LTMAIN + + +## ------------------------------------- ## +## Accumulate code for creating libtool. ## +## ------------------------------------- ## + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the 'libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + +## ------------------------ ## +## FIXME: Eliminate VARNAME ## +## ------------------------ ## + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to 'config.status' so that its +# declaration there will have the same value as in 'configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags='_LT_TAGS'dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into 'config.status', and then the shell code to quote escape them in +# for loops in 'config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$[]1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +_LT_OUTPUT_LIBTOOL_INIT +]) + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# Generate a child script FILE with all initialization necessary to +# reuse the environment learned by the parent script, and make the +# file executable. If COMMENT is supplied, it is inserted after the +# '#!' sequence but before initialization text begins. After this +# macro, additional text can be appended to FILE to form the body of +# the child script. The macro ends with non-zero status if the +# file could not be fully written (such as if the disk is full). +m4_ifdef([AS_INIT_GENERATED], +[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], +[m4_defun([_LT_GENERATED_FILE_INIT], +[m4_require([AS_PREPARE])]dnl +[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl +[lt_write_fail=0 +cat >$1 <<_ASEOF || lt_write_fail=1 +#! $SHELL +# Generated by $as_me. +$2 +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$1 <<\_ASEOF || lt_write_fail=1 +AS_SHELL_SANITIZE +_AS_PREPARE +exec AS_MESSAGE_FD>&1 +_ASEOF +test 0 = "$lt_write_fail" && chmod +x $1[]dnl +m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +'$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to <bug-libtool@gnu.org>." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2011 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test 0 != $[#] +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try '$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try '$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +lt_cl_success=: +test yes = "$silent" && + lt_config_lt_args="$lt_config_lt_args --quiet" +exec AS_MESSAGE_LOG_FD>/dev/null +$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options that allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST + fi + + cfgfile=${ofile}T + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL +# Generated automatically by $as_me ($PACKAGE) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + +_LT_COPYING +_LT_LIBTOOL_TAGS + +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +_LT_PREPARE_MUNGE_PATH_LIST +_LT_PREPARE_CC_BASENAME + +# ### END FUNCTIONS SHARED WITH CONFIGURE + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Go], [_LT_LANG(GO)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +m4_ifndef([AC_PROG_GO], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_GO. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ +m4_defun([AC_PROG_GO], +[AC_LANG_PUSH(Go)dnl +AC_ARG_VAR([GOC], [Go compiler command])dnl +AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl +_AC_ARG_VAR_LDFLAGS()dnl +AC_CHECK_TOOL(GOC, gccgo) +if test -z "$GOC"; then + if test -n "$ac_tool_prefix"; then + AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) + fi +fi +if test -z "$GOC"; then + AC_CHECK_PROG(GOC, gccgo, gccgo, false) +fi +])#m4_defun +])#m4_ifndef + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([AC_PROG_GO], + [LT_LANG(GO)], + [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) +dnl AC_DEFUN([AC_LIBTOOL_RC], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "$LT_MULTI_MODULE"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS=$save_LDFLAGS + ]) + + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], + [lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD + echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD + $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + 10.[[012]][[,.]]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test yes = "$lt_cv_apple_cc_single_mod"; then + _lt_dar_single_mod='$single_module' + fi + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' + fi + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES([TAG]) +# --------------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + if test yes = "$lt_cv_ld_force_load"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], + [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + m4_if([$1], [CXX], +[ if test yes != "$lt_cv_apple_cc_single_mod"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) +# ---------------------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +# Store the results from the different compilers for each TAGNAME. +# Allow to override them for all tags through lt_cv_aix_libpath. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], + [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ + lt_aix_libpath_sed='[ + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }]' + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi],[]) + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib + fi + ]) + aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) +fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[m4_divert_text([M4SH-INIT], [$1 +])])# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Find how we can fake an echo command that does not interpret backslash. +# In particular, with Autoconf 2.60 or later we add some code to the start +# of the generated configure script that will find a shell with a builtin +# printf (that we can use as an echo command). +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +AC_MSG_CHECKING([how to print strings]) +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$[]1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +case $ECHO in + printf*) AC_MSG_RESULT([printf]) ;; + print*) AC_MSG_RESULT([print -r]) ;; + *) AC_MSG_RESULT([cat]) ;; +esac + +m4_ifdef([_AS_DETECT_SUGGESTED], +[_AS_DETECT_SUGGESTED([ + test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test "X`printf %s $ECHO`" = "X$ECHO" \ + || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) + +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_WITH_SYSROOT +# ---------------- +AC_DEFUN([_LT_WITH_SYSROOT], +[AC_MSG_CHECKING([for sysroot]) +AC_ARG_WITH([sysroot], +[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], + [Search for dependent libraries within DIR (or the compiler's sysroot + if not specified).])], +[], [with_sysroot=no]) + +dnl lt_sysroot will always be passed unquoted. We quote it here +dnl in case the user passed a directory name. +lt_sysroot= +case $with_sysroot in #( + yes) + if test yes = "$GCC"; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + AC_MSG_RESULT([$with_sysroot]) + AC_MSG_ERROR([The sysroot must be an absolute path.]) + ;; +esac + + AC_MSG_RESULT([${lt_sysroot:-no}]) +_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl +[dependent libraries, and where our libraries should be installed.])]) + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test no = "$enable_libtool_lock" || enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE=32 + ;; + *ELF-64*) + HPUX_IA64_MODE=64 + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test yes = "$lt_cv_prog_gnu_ld"; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test yes != "$lt_cv_cc_needs_belf"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS=$SAVE_CFLAGS + fi + ;; +*-*solaris*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*|x86_64-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD=${LD-ld}_sol2 + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks=$enable_libtool_lock +])# _LT_ENABLE_LOCK + + +# _LT_PROG_AR +# ----------- +m4_defun([_LT_PROG_AR], +[AC_CHECK_TOOLS(AR, [ar], false) +: ${AR=ar} +: ${AR_FLAGS=cru} +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], + [lt_cv_ar_at_file=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([lt_ar_try]) + if test 0 -eq "$ac_status"; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + AC_TRY_EVAL([lt_ar_try]) + if test 0 -ne "$ac_status"; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + ]) + ]) + +if test no = "$lt_cv_ar_at_file"; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi +_LT_DECL([], [archiver_list_spec], [1], + [How to feed a file listing to the archiver]) +])# _LT_PROG_AR + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[_LT_PROG_AR + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + bitrig* | openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +_LT_DECL([], [lock_old_archive_extraction], [0], + [Whether to use a lock for old archive extraction]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test yes = "[$]$2"; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS +]) + +if test yes = "[$]$2"; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring=ABCD + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test 17 != "$i" # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n "$lt_cv_sys_max_cmd_len"; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test yes = "$cross_compiling"; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test yes != "$enable_dlopen"; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen=load_add_on + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen=LoadLibrary + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ + lt_cv_dlopen=dyld + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen=shl_load], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen=dlopen], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test no = "$lt_cv_dlopen"; then + enable_dlopen=no + else + enable_dlopen=yes + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS=$LDFLAGS + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS=$LIBS + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test yes = "$lt_cv_dlopen_self"; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links=nottested +if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test no = "$hard_links"; then + AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", + [Define to the sub-directory where libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then + + # We can hardcode non-existent directories. + if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && + test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || + test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP"; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_PREPARE_MUNGE_PATH_LIST +# --------------------------- +# Make sure func_munge_path_list() is defined correctly. +m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], +[[# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x@S|@2 in + x) + ;; + *:) + eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" + ;; + x:*) + eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" + ;; + *) + eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" + ;; + esac +} +]])# _LT_PREPARE_PATH_LIST + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test yes = "$GCC"; then + case $host_os in + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary... + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo = "/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +AC_ARG_VAR([LT_SYS_LIBRARY_PATH], +[User-defined run-time library search path.]) + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[[4-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib<name>.so + # instead of lib<name>.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a[(]lib.so.V[)]' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[23]].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[[3-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], + [lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [lt_cv_shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + ]) + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [install_override_mode], [1], + [Permission mode override for installation of shared libraries]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], + [Detected run-time system search path for libraries]) +_LT_DECL([], [configure_time_lt_sys_library_path], [2], + [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program that can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$1"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac]) +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program that can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PROG_ECHO_BACKSLASH])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test no = "$withval" || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in + *GNU* | *'with BFD'*) + test no != "$with_gnu_ld" && break + ;; + *) + test yes != "$with_gnu_ld" && break + ;; + esac + fi + done + IFS=$lt_save_ifs +else + lt_cv_path_LD=$LD # Let the user override the test with a path. +fi]) +LD=$lt_cv_path_LD +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +_LT_PATH_LD_GNU +AC_SUBST([LD]) + +_LT_TAGDECL([], [LD], [1], [The linker used to build libraries]) +])# LT_PATH_LD + +# Old names: +AU_ALIAS([AM_PROG_LD], [LT_PATH_LD]) +AU_ALIAS([AC_PROG_LD], [LT_PATH_LD]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_LD], []) +dnl AC_DEFUN([AC_PROG_LD], []) + + +# _LT_PATH_LD_GNU +#- -------------- +m4_defun([_LT_PATH_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + lt_cv_prog_gnu_ld=yes + ;; +*) + lt_cv_prog_gnu_ld=no + ;; +esac]) +with_gnu_ld=$lt_cv_prog_gnu_ld +])# _LT_PATH_LD_GNU + + +# _LT_CMD_RELOAD +# -------------- +# find reload flag for linker +# -- PORTME Some linkers may need a different reload flag. +m4_defun([_LT_CMD_RELOAD], +[AC_CACHE_CHECK([for $LD option to reload object files], + lt_cv_ld_reload_flag, + [lt_cv_ld_reload_flag='-r']) +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test yes != "$GCC"; then + reload_cmds=false + fi + ;; + darwin*) + if test yes = "$GCC"; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac +_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl +_LT_TAGDECL([], [reload_cmds], [2])dnl +])# _LT_CMD_RELOAD + + +# _LT_PATH_DD +# ----------- +# find a working dd +m4_defun([_LT_PATH_DD], +[AC_CACHE_CHECK([for a working dd], [ac_cv_path_lt_DD], +[printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], +[if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi]) +rm -f conftest.i conftest2.i conftest.out]) +])# _LT_PATH_DD + + +# _LT_CMD_TRUNCATE +# ---------------- +# find command to truncate a binary pipe +m4_defun([_LT_CMD_TRUNCATE], +[m4_require([_LT_PATH_DD]) +AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], +[printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) +_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], + [Command to truncate a binary pipe]) +])# _LT_CMD_TRUNCATE + + +# _LT_CHECK_MAGIC_METHOD +# ---------------------- +# how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_MAGIC_METHOD], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +AC_CACHE_CHECK([how to recognize dependent libraries], +lt_cv_deplibs_check_method, +[lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# 'unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[[4-9]]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[[45]]*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method = "file_magic"]) +_LT_DECL([], [file_magic_glob], [1], + [How to find potential files when deplibs_check_method = "file_magic"]) +_LT_DECL([], [want_nocaseglob], [1], + [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM=$NM +else + lt_nm_to_check=${ac_tool_prefix}nm + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break 2 + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break 2 + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS=$lt_save_ifs + done + : ${lt_cv_path_NM=no} +fi]) +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols -headers" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test : != "$DUMPBIN"; then + NM=$DUMPBIN + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + +# _LT_CHECK_SHAREDLIB_FROM_LINKLIB +# -------------------------------- +# how to determine the name of the shared library +# associated with a specific link library. +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +m4_require([_LT_DECL_DLLTOOL]) +AC_CACHE_CHECK([how to associate runtime and link libraries], +lt_cv_sharedlib_from_linklib_cmd, +[lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd=$ECHO + ;; +esac +]) +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + +_LT_DECL([], [sharedlib_from_linklib_cmd], [1], + [Command to associate shared and link libraries]) +])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB + + +# _LT_PATH_MANIFEST_TOOL +# ---------------------- +# locate the manifest tool +m4_defun([_LT_PATH_MANIFEST_TOOL], +[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], + [lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&AS_MESSAGE_LOG_FD + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest*]) +if test yes != "$lt_cv_path_mainfest_tool"; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + + +# _LT_DLL_DEF_P([FILE]) +# --------------------- +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with func_dll_def_p in the libtool script +AC_DEFUN([_LT_DLL_DEF_P], +[dnl + test DEF = "`$SED -n dnl + -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace + -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments + -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl + -e q dnl Only consider the first "real" line + $1`" dnl +])# _LT_DLL_DEF_P + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM=-lm) + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test yes = "$GCC"; then + case $cc_basename in + nvcc*) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; + *) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; + esac + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test ia64 = "$host_cpu"; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS=conftstm.$ac_objext + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test yes = "$pipe_works"; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], + [Transform the output of nm into a list of symbols to manually relocate]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([nm_interface], [lt_cv_nm_interface], [1], + [The name lister interface]) +_LT_DECL([], [nm_file_list_spec], [1], + [Specify filename containing input files for $NM]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test yes = "$GXX"; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + if test ia64 != "$host_cpu"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64, which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test yes = "$GCC"; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' + if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + *Sun\ F* | *Sun*Fortran*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Intel*\ [[CF]]*Compiler*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + *Portland\ Group*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +AC_CACHE_CHECK([for $compiler option to produce PIC], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + ;; + esac + ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test yes != "$GCC"; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd* | bitrig*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test yes = "$with_gnu_ld"; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; + *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test yes = "$lt_use_gnu_ld_interface"; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='$wl' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test ia64 != "$host_cpu"; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test linux-dietlibc = "$host_os"; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test no = "$tmp_diet" + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; + xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + tcc*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' + ;; + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then + aix_use_runtimelinking=yes + break + fi + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + ;; + esac + + if test yes = "$GCC"; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + esac + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + ;; + + hpux10*) + if test yes,no = "$GCC,$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test yes,no = "$GCC,$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + m4_if($1, [], [ + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + _LT_LINKER_OPTION([if $CC understands -b], + _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + ;; + esac + fi + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], + [lt_cv_irix_exported_symbol], + [save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" + AC_LINK_IFELSE( + [AC_LANG_SOURCE( + [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], + [C++], [[int foo (void) { return 0; }]], + [Fortran 77], [[ + subroutine foo + end]], + [Fortran], [[ + subroutine foo + end]])])], + [lt_cv_irix_exported_symbol=yes], + [lt_cv_irix_exported_symbol=no]) + LDFLAGS=$save_LDFLAGS]) + if test yes = "$lt_cv_irix_exported_symbol"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' + fi + _LT_TAGVAR(link_all_deplibs, $1)=no + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(ld_shlibs, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + osf3*) + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test yes = "$GCC"; then + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. GCC discards it without '$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test yes = "$GCC"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test sequent = "$host_vendor"; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test sni = "$host_vendor"; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_CACHE_CHECK([whether -lc should be explicitly linked in], + [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), + [$RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + ]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting $shlibpath_var if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [postlink_cmds], [2], + [Commands necessary for finishing linking programs]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC=$CC +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report what library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC=$lt_save_CC +])# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +if test -n "$CXX" && ( test no != "$CXX" && + ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || + (test g++ != "$CXX"))); then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_caught_CXX_error"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test yes = "$GXX"; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test yes = "$GXX"; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test yes = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='$wl' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + ;; + esac + + if test yes = "$GXX"; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag=$shared_flag' $wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + # The "-G" linker flag allows undefined symbols. + _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared + # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require '-G' NOT '-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ + '"$_LT_TAGVAR(old_archive_cmds, $1)" + _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ + '"$_LT_TAGVAR(reload_cmds, $1)" + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no + + _LT_TAGVAR(GCC, $1)=$GXX + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test yes != "$_lt_caught_CXX_error" + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_FUNC_STRIPNAME_CNF +# ---------------------- +# func_stripname_cnf prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# +# This function is identical to the (non-XSI) version of func_stripname, +# except this one can be used by m4 code that may be executed by configure, +# rather than the libtool script. +m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl +AC_REQUIRE([_LT_DECL_SED]) +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) +func_stripname_cnf () +{ + case @S|@2 in + .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; + *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; + esac +} # func_stripname_cnf +])# _LT_FUNC_STRIPNAME_CNF + + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF +package foo +func foo() { +} +_LT_EOF +]) + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $prev$p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test x-L = "$p" || + test x-R = "$p"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test no = "$pre_test_object_deps_done"; then + case $prev in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)=$prev$p + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test no = "$pre_test_object_deps_done"; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)=$p + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)=$p + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_LANG_PUSH(Fortran 77) +if test -z "$F77" || test no = "$F77"; then + _lt_disable_F77=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_disable_F77"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${F77-"f77"} + CFLAGS=$FFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)=$G77 + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test yes != "$_lt_disable_F77" + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_LANG_PUSH(Fortran) + +if test -z "$FC" || test no = "$FC"; then + _lt_disable_FC=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_disable_FC"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${FC-"f95"} + CFLAGS=$FCFLAGS + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test yes != "$_lt_disable_FC" + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +CFLAGS=$GCJFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)=$LD +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_GO_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Go compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_GO_CONFIG], +[AC_REQUIRE([LT_PROG_GO])dnl +AC_LANG_SAVE + +# Source file extension for Go test sources. +ac_ext=go + +# Object file extension for compiled Go test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="package main; func main() { }" + +# Code to be used in simple link tests +lt_simple_link_test_code='package main; func main() { }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GOC-"gccgo"} +CFLAGS=$GOFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)=$LD +_LT_CC_BASENAME([$compiler]) + +# Go did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GO_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code=$lt_simple_compile_test_code + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +CFLAGS= +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_GO +# ---------- +AC_DEFUN([LT_PROG_GO], +[AC_CHECK_TOOL(GOC, gccgo,) +]) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + +# _LT_DECL_DLLTOOL +# ---------------- +# Ensure DLLTOOL variable is set. +m4_defun([_LT_DECL_DLLTOOL], +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) +AC_SUBST([DLLTOOL]) +]) + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f "$lt_ac_sed" && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test 10 -lt "$lt_ac_count" && break + lt_ac_count=`expr $lt_ac_count + 1` + if test "$lt_ac_count" -gt "$lt_ac_max"; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PATH_CONVERSION_FUNCTIONS +# ----------------------------- +# Determine what file name conversion functions should be used by +# func_to_host_file (and, implicitly, by func_to_host_path). These are needed +# for certain cross-compile configurations and native mingw. +m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_MSG_CHECKING([how to convert $build file names to $host format]) +AC_CACHE_VAL(lt_cv_to_host_file_cmd, +[case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac +]) +to_host_file_cmd=$lt_cv_to_host_file_cmd +AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) +_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], + [0], [convert $build file names to $host format])dnl + +AC_MSG_CHECKING([how to convert $build file names to toolchain format]) +AC_CACHE_VAL(lt_cv_to_tool_file_cmd, +[#assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac +]) +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) +_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], + [0], [convert $build files to toolchain format])dnl +])# _LT_PATH_CONVERSION_FUNCTIONS diff --git a/libs/ode-0.16.1/m4/ltoptions.m4 b/libs/ode-0.16.1/m4/ltoptions.m4 new file mode 100644 index 0000000..94b0829 --- /dev/null +++ b/libs/ode-0.16.1/m4/ltoptions.m4 @@ -0,0 +1,437 @@ +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software +# Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 8 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option '$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl 'shared' nor 'disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], + [_LT_WITH_AIX_SONAME([aix])]) + ]) +])# _LT_SET_OPTIONS + + +## --------------------------------- ## +## Macros to handle LT_INIT options. ## +## --------------------------------- ## + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [1], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the 'shared' and +# 'disable-shared' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the 'static' and +# 'disable-static' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the 'fast-install' +# and 'disable-fast-install' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the 'fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the 'disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_AIX_SONAME([DEFAULT]) +# ---------------------------------- +# implement the --with-aix-soname flag, and support the `aix-soname=aix' +# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT +# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. +m4_define([_LT_WITH_AIX_SONAME], +[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl +shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[[5-9]]*,yes) + AC_MSG_CHECKING([which variant of shared library versioning to provide]) + AC_ARG_WITH([aix-soname], + [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], + [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], + [case $withval in + aix|svr4|both) + ;; + *) + AC_MSG_ERROR([Unknown argument to --with-aix-soname]) + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname], + [AC_CACHE_VAL([lt_cv_with_aix_soname], + [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) + with_aix_soname=$lt_cv_with_aix_soname]) + AC_MSG_RESULT([$with_aix_soname]) + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + +_LT_DECL([], [shared_archive_member_spec], [0], + [Shared archive member basename, for filename based shared library versioning on AIX])dnl +])# _LT_WITH_AIX_SONAME + +LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) +LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) +LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the 'pic-only' and 'no-pic' +# LT_INIT options. +# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [pic_mode=m4_default([$1], [default])]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + +## ----------------- ## +## LTDL_INIT Options ## +## ----------------- ## + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/libs/ode-0.16.1/m4/ltsugar.m4 b/libs/ode-0.16.1/m4/ltsugar.m4 new file mode 100644 index 0000000..48bc934 --- /dev/null +++ b/libs/ode-0.16.1/m4/ltsugar.m4 @@ -0,0 +1,124 @@ +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software +# Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59, which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) diff --git a/libs/ode-0.16.1/m4/ltversion.m4 b/libs/ode-0.16.1/m4/ltversion.m4 new file mode 100644 index 0000000..fa04b52 --- /dev/null +++ b/libs/ode-0.16.1/m4/ltversion.m4 @@ -0,0 +1,23 @@ +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# @configure_input@ + +# serial 4179 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.4.6]) +m4_define([LT_PACKAGE_REVISION], [2.4.6]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.4.6' +macro_revision='2.4.6' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) diff --git a/libs/ode-0.16.1/m4/lt~obsolete.m4 b/libs/ode-0.16.1/m4/lt~obsolete.m4 new file mode 100644 index 0000000..c6b26f8 --- /dev/null +++ b/libs/ode-0.16.1/m4/lt~obsolete.m4 @@ -0,0 +1,99 @@ +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software +# Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 5 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) +m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) +m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) +m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) +m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) +m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) +m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) diff --git a/libs/ode-0.16.1/m4/pkg.m4 b/libs/ode-0.16.1/m4/pkg.m4 new file mode 100644 index 0000000..73973f7 --- /dev/null +++ b/libs/ode-0.16.1/m4/pkg.m4 @@ -0,0 +1,157 @@ +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 1 (pkg-config-0.24) +# +# Copyright © 2004 Scott James Remnant <scott@netsplit.com>. +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# PKG_PROG_PKG_CONFIG([MIN-VERSION]) +# ---------------------------------- +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])# PKG_PROG_PKG_CONFIG + +# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# +# Check to see whether a particular set of modules exists. Similar +# to PKG_CHECK_MODULES(), but does not set variables or print errors. +# +# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +# only at the first occurence in configure.ac, so if the first place +# it's called might be skipped (such as if it is within an "if", you +# have to call PKG_CHECK_EXISTS manually +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +# --------------------------------------------- +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])# _PKG_CONFIG + +# _PKG_SHORT_ERRORS_SUPPORTED +# ----------------------------- +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])# _PKG_SHORT_ERRORS_SUPPORTED + + +# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# +# +# Note that if there is a possibility the first call to +# PKG_CHECK_MODULES might not happen, you should be sure to include an +# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +# +# +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $1]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT]) + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see <http://pkg-config.freedesktop.org/>.]) + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])# PKG_CHECK_MODULES diff --git a/libs/ode-0.16.1/missing b/libs/ode-0.16.1/missing new file mode 100755 index 0000000..f62bbae --- /dev/null +++ b/libs/ode-0.16.1/missing @@ -0,0 +1,215 @@ +#! /bin/sh +# Common wrapper for a few potentially missing GNU programs. + +scriptversion=2013-10-28.13; # UTC + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. + +# 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 2, 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 <http://www.gnu.org/licenses/>. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try '$0 --help' for more information" + exit 1 +fi + +case $1 in + + --is-lightweight) + # Used by our autoconf macros to check whether the available missing + # script is modern enough. + exit 0 + ;; + + --run) + # Back-compat with the calling convention used by older automake. + shift + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due +to PROGRAM being missing or too old. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal autoconf autoheader autom4te automake makeinfo + bison yacc flex lex help2man + +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. + +Send bug reports to <bug-automake@gnu.org>." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" + exit 1 + ;; + +esac + +# Run the given program, remember its exit status. +"$@"; st=$? + +# If it succeeded, we are done. +test $st -eq 0 && exit 0 + +# Also exit now if we it failed (or wasn't found), and '--version' was +# passed; such an option is passed most likely to detect whether the +# program is present and works. +case $2 in --version|--help) exit $st;; esac + +# Exit code 63 means version mismatch. This often happens when the user +# tries to use an ancient version of a tool on a file that requires a +# minimum version. +if test $st -eq 63; then + msg="probably too old" +elif test $st -eq 127; then + # Program was missing. + msg="missing on your system" +else + # Program was found and executed, but failed. Give up. + exit $st +fi + +perl_URL=http://www.perl.org/ +flex_URL=http://flex.sourceforge.net/ +gnu_software_URL=http://www.gnu.org/software + +program_details () +{ + case $1 in + aclocal|automake) + echo "The '$1' program is part of the GNU Automake package:" + echo "<$gnu_software_URL/automake>" + echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/autoconf>" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + autoconf|autom4te|autoheader) + echo "The '$1' program is part of the GNU Autoconf package:" + echo "<$gnu_software_URL/autoconf/>" + echo "It also requires GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + esac +} + +give_advice () +{ + # Normalize program name to check for. + normalized_program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + + printf '%s\n' "'$1' is $msg." + + configure_deps="'configure.ac' or m4 files included by 'configure.ac'" + case $normalized_program in + autoconf*) + echo "You should only need it if you modified 'configure.ac'," + echo "or m4 files included by it." + program_details 'autoconf' + ;; + autoheader*) + echo "You should only need it if you modified 'acconfig.h' or" + echo "$configure_deps." + program_details 'autoheader' + ;; + automake*) + echo "You should only need it if you modified 'Makefile.am' or" + echo "$configure_deps." + program_details 'automake' + ;; + aclocal*) + echo "You should only need it if you modified 'acinclude.m4' or" + echo "$configure_deps." + program_details 'aclocal' + ;; + autom4te*) + echo "You might have modified some maintainer files that require" + echo "the 'autom4te' program to be rebuilt." + program_details 'autom4te' + ;; + bison*|yacc*) + echo "You should only need it if you modified a '.y' file." + echo "You may want to install the GNU Bison package:" + echo "<$gnu_software_URL/bison/>" + ;; + lex*|flex*) + echo "You should only need it if you modified a '.l' file." + echo "You may want to install the Fast Lexical Analyzer package:" + echo "<$flex_URL>" + ;; + help2man*) + echo "You should only need it if you modified a dependency" \ + "of a man page." + echo "You may want to install the GNU Help2man package:" + echo "<$gnu_software_URL/help2man/>" + ;; + makeinfo*) + echo "You should only need it if you modified a '.texi' file, or" + echo "any other file indirectly affecting the aspect of the manual." + echo "You might want to install the Texinfo package:" + echo "<$gnu_software_URL/texinfo/>" + echo "The spurious makeinfo call might also be the consequence of" + echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" + echo "want to install GNU make:" + echo "<$gnu_software_URL/make/>" + ;; + *) + echo "You might have modified some files without having the proper" + echo "tools for further handling them. Check the 'README' file, it" + echo "often tells you about the needed prerequisites for installing" + echo "this package. You may also peek at any GNU archive site, in" + echo "case some other package contains this missing '$1' program." + ;; + esac +} + +give_advice "$1" | sed -e '1s/^/WARNING: /' \ + -e '2,$s/^/ /' >&2 + +# Propagate the correct exit status (expected to be 127 for a program +# not found, 63 for a program that failed due to version mismatch). +exit $st + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/libs/ode-0.16.1/ode-config.cmake.in b/libs/ode-0.16.1/ode-config.cmake.in new file mode 100644 index 0000000..210b558 --- /dev/null +++ b/libs/ode-0.16.1/ode-config.cmake.in @@ -0,0 +1,13 @@ +set(ODE_VERSION "@VERSION@") +set(ODE_VERSION_MAJOR "@VERSION_MAJOR@") +set(ODE_VERSION_MINOR "@VERSION_MINOR@") +set(ODE_VERSION_PATCH "@VERSION_PATCH@") + +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/ode-export.cmake") + +set(ODE_DEFINITIONS "") +set(ODE_INCLUDE_DIRS "${PACKAGE_PREFIX_DIR}/include") +set(ODE_LIBRARY_DIRS "${PACKAGE_PREFIX_DIR}/lib") +set(ODE_LIBRARIES "ODE::ODE") diff --git a/libs/ode-0.16.1/ode-config.in b/libs/ode-0.16.1/ode-config.in new file mode 100644 index 0000000..78fa45e --- /dev/null +++ b/libs/ode-0.16.1/ode-config.in @@ -0,0 +1,53 @@ +#!/bin/sh + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +exec_prefix_set=no + +usage="\ +Usage: ode-config [--prefix[=DIR]] [--exec-prefix[=DIR]] [--version] [--cflags] [--libs]" + +if test $# -eq 0; then + echo "${usage}" 1>&2 + exit 1 +fi + +while test $# -gt 0; do + case "$1" in + -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + case $1 in + --prefix=*) + prefix=$optarg + if test $exec_prefix_set = no ; then + exec_prefix=$optarg + fi + ;; + --prefix) + echo $prefix + ;; + --exec-prefix=*) + exec_prefix=$optarg + exec_prefix_set=yes + ;; + --exec-prefix) + echo $exec_prefix + ;; + --version) + echo @ODE_VERSION@ + ;; + --cflags) + echo -I@includedir@ + ;; + --libs) + echo -L@libdir@ -lode + ;; + *) + echo "${usage}" 1>&2 + exit 1 + ;; + esac + shift +done diff --git a/libs/ode-0.16.1/ode.pc.in b/libs/ode-0.16.1/ode.pc.in new file mode 100644 index 0000000..9fa106a --- /dev/null +++ b/libs/ode-0.16.1/ode.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ +precision=@ODE_PRECISION@ + +Name: ode +Description: Open Dynamics Engine +Version: @ODE_VERSION@ +Libs: -L${libdir} -lode +Libs.private: -lstdc++ -lm +Cflags: -I${includedir} diff --git a/libs/ode-0.16.1/ode/Makefile.am b/libs/ode-0.16.1/ode/Makefile.am new file mode 100644 index 0000000..656e7a4 --- /dev/null +++ b/libs/ode-0.16.1/ode/Makefile.am @@ -0,0 +1,6 @@ +SUBDIRS = src doc +if ENABLE_DEMOS + SUBDIRS += demo +endif + +#EXTRA_DIST = doc diff --git a/libs/ode-0.16.1/ode/Makefile.in b/libs/ode-0.16.1/ode/Makefile.in new file mode 100644 index 0000000..eae84a5 --- /dev/null +++ b/libs/ode-0.16.1/ode/Makefile.in @@ -0,0 +1,643 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@ENABLE_DEMOS_TRUE@am__append_1 = demo +subdir = ode +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ode/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = src doc demo +am__DIST_COMMON = $(srcdir)/Makefile.in README TODO +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_CFLAGS = @CCD_CFLAGS@ +CCD_LIBS = @CCD_LIBS@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSTDCXX = @LIBSTDCXX@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ODE_PRECISION = @ODE_PRECISION@ +ODE_VERSION = @ODE_VERSION@ +ODE_VERSION_INFO = @ODE_VERSION_INFO@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = src doc $(am__append_1) +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign ode/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign ode/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +#EXTRA_DIST = doc + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/ode/README b/libs/ode-0.16.1/ode/README new file mode 100644 index 0000000..dd4596f --- /dev/null +++ b/libs/ode-0.16.1/ode/README @@ -0,0 +1,158 @@ +Dynamics Library. +================= + +CONVENTIONS +----------- + +matrix storage +-------------- + +matrix operations like factorization are expensive, so we must store the data +in a way that is most useful to the matrix code. we want the ability to update +the dynamics library without recompiling applications, e.g. so users can take +advantage of new floating point hardware. so we must settle on a single +format. because of the prevalence of 4-way SIMD, the format is this: store +the matrix by rows or columns, and each column is rounded up to a multiple of +4 elements. the extra "padding" elements at the end of each row/column are set +to 0. this is called the "standard format". to indicate if the data is stored +by rows or columns, we will say "standard row format" or "standard column +format". hopefully this decision will remain good in the future, as more and +more processors have 4-way SIMD, and 3D graphics always needs fast 4x4 +matrices. + +exception: matrices that have only one column or row (vectors), are always +stored as consecutive elements in standard row format, i.e. there is no +interior padding, only padding at the end. + +thus: all 3x1 floating point vectors are stored as 4x1 vectors: (x,x,x,0). +also: all 6x1 spatial velocities and accelerations are split into 3x1 position + and angular components, which are stored as contiguous 4x1 vectors. + +ALL matrices are stored by in standard row format. + + +arguments +--------- + +3x1 vector arguments to set() functions are supplied as x,y,z. +3x1 vector result arguments to get() function are pointers to arrays. +larger vectors are always supplied and returned as pointers. +all coordinates are in the global frame except where otherwise specified. +output-only arguments are usually supplied at the end. + + +memory allocation +----------------- + +with many C/C++ libraries memory allocation is a difficult problem to solve. +who allocates the memory? who frees it? must objects go on the heap or can +they go on the stack or in static storage? to provide the maximum flexibility, +the dynamics and collision libraries do not do their own memory allocation. +you must pass in pointers to externally allocated chunks of the right sizes. +the body, joint and colllision object structures are all exported, so you +can make instances of those structure and pass pointers to them. + +there are helper functions which allocate objects out of areans, in case you +need loots of dynamic creation and deletion. + +BUT!!! this ties us down to the body/joint/collision representation. + +a better approach is to supply custom memory allocation functions +(e.g. dlAlloc() etc). + + +C versus C++ ... ? +------------------ + +everything should be C linkable, and there should be C header files for +everything. but we want to develop in C++. so do this: + * all comments are "//". automatically convert to /**/ for distribution. + * structures derived from other structures --> automatically convert? + + +WORLDS +------ + +might want better terminology here. + +the dynamics world (DWorld) is a list of systems. each system corresponds to +one or more bodies, or perhaps some other kinds of physical object. +each system corresponds to one or more objects in the collision world +(there does not have to be a one-to-one correspondence between bodies and +collision objects). + +systems are simulated separately, perhaps using completely different +techniques. we must do something special when systems collide. +systems collide when collision objects belonging to system A touch +collision objects belonging to system B. + +for each collision point, the system must provide matrix equation data +that is used to compute collision forces. once those forces are computed, +the system must incorporate the forces into its timestep. +PROBLEM: what if we intertwine the LCP problems of the two systems - then +this simple approach wont work. + +the dynamics world contains two kinds of objects: bodies and joints. +joints connect two bodies together. + +the world contains one of more partitions. each partition is a collection of +bodies and joints such that each body is attached (through one or more joints) +to every other body. + +Joints +------ + +a joint can be connected to one or two bodies. +if the joint is only connected to one body, joint.node[1].body == 0. +joint.node[0].body is always valid. + + +Linkage +------- + +this library will always be statically linked with the app, for these reasons: + * collision space is selected at compile time, it adds data to the geom + objects. + + +Optimization +------------ + +doubles must be aligned on 8 byte boundaries! + + +MinGW on Windows issues +----------------------- + +* the .rc file for drawstuff needs a different include, try winresrc.h. + +* it seems we can't have both main() and WinMain() without the entry point + defaulting to main() and having resource loading problems. this screws up + what i was trying to do in the drawstuff library. perhaps main2() ? + +* remember to compile resources to COFF format RES files. + + + +Collision +--------- + +to plug in your own collision handling, replace (some of?) these functions +with your own. collision should be a separate library that you can link in +or not. your own library can call components in this collision library, e.g. +if you want polymorphic spaces instead of a single statically called space. + +creating an object will automatically register the appropriate +class (if necessary). how can we ensure that the minimum amount of code is +linked in? e.g. only one space handler, and sphere-sphere and sphere-box and +box-box collision code (if spheres and boxes instanced). + +the user creates a collision space, and for each dynamics object that is +created a collision object is inserted into the space. the collision +object's pos and R pointers are set to the corresponding dynamics +variables. + +there should be utility functions which create the dynamics and collision +objects at the same time, e.g. dMakeSphere(). + +collision objects and dynamics objects keep pointers to each other. diff --git a/libs/ode-0.16.1/ode/TODO b/libs/ode-0.16.1/ode/TODO new file mode 100644 index 0000000..cf6cdaa --- /dev/null +++ b/libs/ode-0.16.1/ode/TODO @@ -0,0 +1,698 @@ + +@@@'s + + +TODO for COLLISION +------------------ + +box-box collision: adjust generated face-face contact points by depth/2 to +be more fair. + +what happens when a GeomTransform's encapsulated object is manipulated, +e.g. position changed. should this be disallowed? should a GeomTransform +behave like a space and propagate dirtyness upwards? + +make sure that when we are using a large space for static environmental geoms, +that there is not excessive AABB computation when geoms are added/removed from +the space. the space AABB is pretty much guaranteed to cover everything, so +there's no need to compute/test the AABB in this case. + +hash space: implement collide2() efficiently instead of the current +simple-space-like brute-force approach. + +hash space: incremental scheme, so we dont have to rebuild the data structures +for geoms that don't move. + +disabled geoms (remove from all collision considerations) ... isn't this the +same as just taking it out of its enclosing group/space? + +integrate: + dRay + triangle collider - get latest tri collider code from erwin + erwin's quadtree space + +tests: + all aspects of collision API + + dGeomSetBody(0) maintains body-geom linked list properly. + + simple space: instantiate lots of non-moving geoms (i.e. environmental + geoms and make sure that we're still able to collide efficiently. + make sure AABB computation is efficient, or can be made efficient + through proper use of the API. + + test C interface support for making new classes. + make sure the dxGeom::aabbTest() function behaves as advertised. + + testing for contact point consistency: test for things that + would cause the dynamics to fail or become unstable + + test for: small adjustment in geom position causes a big jump in the + contact point set (bad for dynamics). + + test for: if contact constraints observed then it's impossible + (or hard) to move the objects so that the penetration is + increased. relax this when only a subset of the contact points are + returned. + + test for consistency, e.g. the boundary of geoms X and Y can + be defined by intersecting with a point, so test the intersection of X + and Y by comparing with the point tests. + + check that contact points are in the collision volume + + all existing space tests, and more. + +demos: + test_buggy: make a terrain out of non-moving geoms. use heirarchical + groups to get efficient collision, even with the simple space. + +go though the new collision docs and make sure the behavior that is described +there is actually implemented. + +multi-resolution hash table: + the current implementation rebuilds a new hash table each time + collide() is called. we don't keep any state between calls. this is + wasteful if there are unmoving objects in the space. + + make sure we prevent multiple collision callbacks for the same pair + + better virtual address function. + + the collision search can perhaps be optimized - as we search + chains we can come across other candidate intersections at + other levels, perhaps we should do the intersection check + straight away? --> save on list searching time only, which is + not too significant. + +collision docs: + optimization guide: whenever a single geom changes in a simple space, + the space AABB has to be recomputed by examining EVERY geom. + document this, or find a better behavior. + + + +TODO BEFORE NEXT RELEASE +------------------------ + +g++ needed for compiling tests using gcc 3.2 ? what is the problem? + +add joint feedback info from lambda, so that we can get motor forces etc. +need a way to map constraint indexes to what they mean. + +track down and fix the occasional popping/jumping problem in test_boxstack, +especially when boxes are piled on top of each other. find out if this is +caused by a configuration singularity or whether there is a bug in LCP. +i need to add some kind of diagnostic tool to help resolve these kinds of +problems. + +fixup ground plane jitter and shadow jumping in drawstuff. + +the inertias/COMs don't appear to be totally correct for the boxstack demo. +fix up, and add a mode that shows the effective mass box (for a given density). + +Improve box-box collision, especially for face-face contact (3 contact points). +Improve cylinder-box collision (2 contact points). + +windows DLL building and unix shared libs. libtool? +also MSVC project files. + +dBodyGetPointVel() + +contrib directory - all stuff in ~/3/ode + +functions to allow systems to be copied/cloned + dBodyTransplant (b, world) + dTransplantIsland (b, world) + dBodyCopy (bdest, bsrc) + dJointCopy (jdest, jsrc) -- what about body connections? + dCloneBody() + dCloneJoint() + dCloseBodyAndJointList() + dCloneIsland() + +this collision rule: + // no contacts if both geoms on the same body, and the body is not 0 + if (g1->body == g2->body && g1->body) return 0; +needs to be replaced. sometimes we want no collision when both bodies are 0, +but this wont work for geomgroup-to-environment. avoid stupid stuff like + dGeomSetBody (geom_group, (dBodyID) 1); +this also causes "failed-to-report" errors in the space test. + +Expose type-specific collision functions? + +Automatic code optimization process. + +joint limit spongyness: interacts with powered joints badly, because when the +limit is reached full power is applied. fix or doc. + +various hinge2 functions may not function correctly if axis1 and axis2 are not +perpendicular. in particular the getAngle() and getAngleRate() functions +probably will give bogus answers. + +slow step function will not respect the joint getinfo2 functions calling +addTorque() because it reads the force/torque accumulators before the +getinfo2 functions are called. + +spaces need multiple lists of objects that can never overlap. objects in these +lists are never tested against each other. + +deleting a body a joint is attached to should adjust the joint to only have +one body attached. currently the connected joints have *both* their body +attachments removed. BUT, dont do this if the dJOINT_TWOBODIES flag is set +on the joint. + +document error, mem and math functions. + +Web pages + credits section + projects using ODE + +update C++ interface? use SWIG? + +collision exclusion groups - exclude if obj1.n == obj2.n ? + +make sure the amotor joint can be used with just one body. at the moment it +only allows two-body attachments. + +implement dJointGetAMotorAngleRate() + +erwin says: Should the GeomGroup have a cleanupmode as the GeomTransform has? + +erwin says: http://q12.org/pipermail/ode/2002-January/000766.html + and http://q12.org/pipermail/ode/2001-December/000753.html + +rename duplicate filenames (object.h?) - some environments can't handle this. + +naming inconsistency: dCreateSphere() should be dSphereCreate() (etc...) to +match the rest of the API. + + +TODO +---- + +joint allocation in joint groups. allocation size should be rounded up using +dEFFICIENT_SIZE, to properly align all the data members. + +all dAlloc() allocations should be aligned using dEFFICIENT_SIZE() ??? + +automatic body & joint disabling / enabling. + +sometimes getting LCP infinite loops. + +function to get the entire island of bodies/joints + +joints: + hinge2 joint - implement trail, i.e. non-convergent steering and wheel + axes. + + erp individually settable for each joint? + + more joints: + angular3 (constrian full angle not position) + fixed path 1 (point must follow fixed path, etc etc) + - other fixed path joints. + linear a (point in 1 body fixed to plane of other) + linear b (point in 1 body fixed to line on other) + linear c (line in 1 body fixed to plane on other) + linear d (line in 1 body fixed to line on other) - like + prismatic but orientation along line can change + Relative-Path-Relative-Oriention Joint (set all dofs of 2 + bodies relative to each other) + spring (with natural length) + universal (2 kinds) + various angular relationships + + when attaching joints to static env, provision to move attachment + point (e.g. give it a linear/angular velocity). this can be used + instead of a FPFO joint on a body in many cases. + also do this with contacts to static env, to allow for contacts to + *moving* objects in the static env. + + interpretation of erp: is it (1) the error reduction per timestep, + (2) or a time constant independent of timestep?? if it's (2) then + perhaps this should be universal - this is already the meaning for + the suspension. + + hinge2 suspension: + suspension limits + suspension limit restitution and spongyness?? + +use autoconf? set paths in makefile? + +no-arg init functions, for andy + +explore: do joint parameters need to be set for the joint to be setup +correctly, or should set some proper body-dependent params when it is +attached? this is only really an issue for joints that have no parameters to +set, such as the fixed joint. + +dAlloc() should take an arena parameters which is stored in dWorld. + +debugging mode should use dASSERT2 that prints a descriptive error message +on error, not just the file:line or function. use dASSERT for internal +consistency checking. + +when vectors and matrices are initialized, we must ensure that the padding +elements are set to 0. this is going to be a problem everywhere! + +don't use 3-vectors anywhere. use SIMD friendly 4-vectors. + +make sure all data in body/joint etc objects is aligned well for single +precision SIMD (i.e. all vectors start on a 16 byte boundary). + +think about more complicated uses of collision, e.g. a single geom representing +an articulated structure. + +bodyGroup? (like joint group but for bodies). systemGroup? + +check the overhead of resizing Array<>s as elements are pushed on to them. + +replace alloca() with dPushFrame(), dPopFrame(), and dAlloca() ? allow for +the possibility of allocating in non-stack memory ? + +make sure that we can set mass parameters with non-zero center of mass. +if this is done after the body position is set, the position is adjusted. +if this is done before the body position is set, what do we do when the +pos is set? does the pos always refer to the center of mass from the user's +point of view? + +consider splitting solver into functions, which can be optimized separately. +might make things go faster. + +faster code for islands with a single body? faster code for dynamically +symmetric bodies? + +rotation.cpp functions that set matrices should also set padding elements. + +lcp solver must return (L,d) and some other information, so we can re-solve +for other right hand sides later on, but using the same complimentarity +solution so there are no integrator discontinuities. + +dSetZero() - make fast inline functions for fixed n e.g. (1-4). + +need proper `sticky' friction, i.e. compensation for numerical slip. + +on windows, make sure gcc-compiles libs can be linked with VC++ apps. need +to make sure some C++ runtime bits are present? + +kill all references to dArray<> (in geom.cpp). + +need testing code to test all joints with body-to-static-env + +copy stack.cpp, memory.cpp stuff to reuse + +dFactorLDLT() is not so efficient for matrix sizes < block size, e.g. +redundant calls, zero loads, adds etc + +contacts: cheaper friction: viscous friction? one step delay friction force. + +in geom.cpp, for objects that are never meant to collide, dCollide() will +always try to find the collider functions, which wastes a bit of time. + +geom.cpp:dCollideG() - handle special case of colliding 2 groups more +efficiently. + +timer reporting function: + void timerReport (void (*printFunction)(char *, ...)); + +disabled bodies stored in a separate list, so they are never traversed at all, +for speed when there are many disabled bodies. + + +MAYBE +----- + +new implementation for joint groups that is not so system dependent. +maybe individual contacts are reusable? in this case contact information +should be settable in the contact joints. max_size arg is really annoying. + +consider making anchor,axis, (everything) into a joint parameter and setting +them with a consistent interface. also consider overload the joint functions +so they are not distinguished by joint type?? + +collision memory optimizations? + +collision: support for persistent contact information? + +multiply reference tri list data so that it can be cloned + if the tri-list geoms could support rot/pos + transformations then we could have several tri-lists pointing to the + same vertex information. + +height fields + +pre-converted collision data -- Creating a hash space and associated +opcode tree structures may take significant amounts of time for a +large world with many 10s of thousands of triangles. Any chance of +pre-building that off-line and passing a memory block pointer to the +collision system? + +putting objects in multiple spaces -- If it was possible to add +objects to more than one space, you could do collision queries other +than 1vsN and NvsN. That flexibility might be useful when you want to +only collide against a subset of the space. For example, a camera +system may want to collide some rays with occlusion walls but the +occlusion walls may also need to be in the game-level space to bounce +against. + + +ALWAYS +------ + +make sure functions check their arguments in debug mode (e.g. using dASSERT). +make sure joint/geom functions check for the specific object type. + +vectors alloca()ed on the stack must have the correct alignment, use ALLOCA16. + +library should have no global constructors, as it might be used with C linkage. + +use `const' in function arguments. blah. + + + +DON'T BOTHER +------------ + +warning if user tries to set mass params with nonzero center of mass. + + + +DONE +---- + +check: when contact attached with (body1,0) and (0,body1), check that polarity +on depth and error info is okay for the two cases. + +set a better convention for which is the 1st and 2nd body in a joint, because +sometimes we get things swapped (because of the way the joint nodes are used). + +hinge and prismatic, attachment to static environment. + +turn macros into C++ inline functions? what about C users? + +remove `space' argument to geom creation functions? make user add it? +or just remove it from dCreateGeom() ? <-- did this one. + +test_chain should be in C, not C++. but first must remove global constructors. + +add more functionality to C++ interface - dMass, dSpace, dGeom + +there should be functions to delete groups of bodies/joints in one go - this +will be more efficient than deleting them one at a time, because less +partitioning tests will be needed. + +should we expose body and joint object structures so that the user can +explicitly allocate them locally, or e.g. on the stack? makes allocating +temporary contact constraints easier. NO --> helps data hiding and therefore +library binary compatability. + +joints: + hinge & slider - DONE + measure angle, rate - DONE + power - DONE + joint limits - DONE + mixed powered+limited joints, powering away from limit - DONE + + hinge2 - DONE + steering angle and rate measurement - DONE + steering limits - DONE + steering motor - DONE + wheel motor - DONE + wheel angle rate measurement - DONE + + optional hinge2 suspension: - DONE + alignment of B&S part to given axis - DONE + global framework for giving epsilon and gamma - DONE + + toss away r-motor, make power & stuff specific to joint - DONE + it's just easier that way + + joint code reuse: - DONE + use standard functions to set velocity (c), limits (lo,hi), + spongyness (epsilon) etc, this prevents these functions from + proliferating + + implicit spring framework - actually allow joints to return a value `k' + such that J*vnew = c + k*f, where f = force needed to achieve + vnew - DONE + + contact slip - DONE + contact erp & cfm parameters (not just "softness") - DONE + + hinge2: when we lock back wheels along the steering axis, there is no + error correction if they get out of alignment - DONE, just use high + and low limits. + + joint limit spongyness: erp and cfm for joint set from world (global) + values when joint created. - DONE + + joint limit restitution - DONE + +check inertia transformations, e.g. by applying steering torque to a thin +wheel --> actually, i made test_I + +more comprehensive random number comparisons between slow and fast methods. + - random PD inertia (not just diagonal). + - random velocity + - random joint error (make joints then move bodies a bit) + +check that J*vnew=c (slow step already does this, but it doesn't equal zero +for some reason! - actually, when LCP constraint limits are reached, it wont!) + +tons of things in lcp.cpp (@@@), especially speed optimizations. also, we +wanted to do index block switching and index block updates to take advantage +of the outer product trick ... but this is not worth the effort i think. + +lcp.cpp: if lo=hi=0, check operation. can we switch from NL <-> NH without +going through C? --> done. + +andy says: still having trouble with those resource files.. +drawstuff.res doesn't seem to build or be found under cygwin gcc. + +DOC how bodies and geoms associated then resolved in contact callback ... not +really necessary. + +fix the "memory leak" in geom.cpp + +library should have no global constructors, as it might be used with C linkage. + --> as long as test_chain1 works, there are none. + +DOC cfm, the derivation and what it means. + --> partially done, could be better + +joint "get type" function + +andy says: in ode/src/error.cpp _snprintf() and _vsnprintf() are missing +in testode: finite and isnan are missing. copysign is missing + russ: okay here's the problem: i have Makefile.platform files for + VC++, MinGW, but not Cygwin. Cygwin uses the unix-like functions + for everything, but the VC++/MinGW configs assumes the MS C-runtime + functions. this is easy to fix, except i need to install Cygwin + which is a pain to do over MinGW. argh. + +build on linux - assumptions made about location of X11 lib, opengl etc. + +implement: dBodyAddForceAtPos,dBodyAddRelForceAtPos,dBodyAddRelForceAtRelPos, + dBodyGetPointPos,dBodyGetPointVel,dBodyGetPointRelVel + +dJointAttach(), allow both bodies to be 0 to put the joint into limbo. + +space near-callback should be given potentially intersecting objects 100 at a +time instead of 1 at a time, to save on calling costs ... which are trivial, +so we don't bother to do this. + +doccer: @func{} also refs second etc function in function *list*. + +make sure joints can return 0 from GetInfo1, i.e. no constraints or "inactive" +joint, and the step functions will handle it. + +when attaching contact with (0,body), instead of setting the reverse flag +on the joint and checking it in getInfo2(), we should just reverse the normal +straight away ... ? + --> trouble is, dJointAttach() knows nothing about what kind of joint + it is attaching. + +hinge2 needs to be attached to two bodies for it to work, make sure this is +always the case. --> assertion added in dJointAttach(). + +if two joints connect to the same two bodies, check that the fast solver +works! -> it should. + +functions to get all the joints/bodies a body/joint is connected to. + +If I don't have the GCC libraries installed, HUGE_VALF is undefined. + +fix capped cylinder - capped cylinder collision so that two contacts can +be generated. + +transformation geometry object. + +joint groups should also be destroyed by destroying the world --> naaahhh. + +DONT DO THIS: body/joint creators with world = 0 --> not inserted into any +world. allow bodies/joints to be detached from a world (this is what happens +to grouped joints when a world is destroyed). + can bodies and joints be linked together when not attached to world?? + what happens when we have an island of b/j, some of which are not in + world? soln: dont keep lists of b/j in the world, just infer it from + the islands? + +body & joint disabling / enabling + +start a change log. + +collision flags - 0xffff mask. + +dBodyGetFiniteRotationMode() / ...Axis() + +dBodyAddForceAtRelPos() + +ball & socket joint limits and motors. + +auto-build env on windows: 3 compilers, debug/release, short/double = +12 combinations --> auto logs. + +handle infinities better: HUGE_VALF is not commanly defined, it seems. +get rid of the __USE_ISOC9X macro in common.h +perhaps just use a "big" number instead of the actual IEEE infinity, it's +more portable anyway. + --> new config system + +dCloseODE() - tidy up *all* allocated memory, esp in geom.cpp. used to keep +leak detectors happy. + +extra API to get lambda and J'*lambda from last timestep. + +better stack implementation that is not so system dependent. but how will +we do dynamic page allocation? do we even need to? + + +all collision files will now be collision_*, not geom_* + +check exported global symbols - no C++ mangling. + +rename dSphere etc to dxSphere etc. + +C interface support for making new classes. + +make sure DLL-ized stuff preserved ... but class numbers should no longer be +exported. + +point geom ( = sphere of radius 0 ) + +geoms stored in doubly linked lists in space (fast removal). + +bodies need to keep geoms pointers and call dGeomMoved() in dBodySetPosition() +etc and world step. PROBLEM: links dynamics and collision together too much, +makes it hard to extract ODE collision ... unless we say: dGeomMoved() and +dGeomID must be supplied by the new collision library! + +dCollide() should take spaces as arguments - it should call dSpaceCollide2() +with its own callback that puts all found contacts in the array, stopping +when there is no more space left in the array. + +dxSpace::getGeom() - the geom numbers will change as geoms are dirtied - find +some other numbering scheme, or document this behavior. + +the 'placeable' property - objects that should not ever be attached to bodies +should flag an error when setBody etc are called. + +dGeomSetBody(0) - DOC: the position and orientation of the body will be +preserved. in this case the geom should NOT be dirtied (dGeomMoved() should +not be called). + +DOC: dGeomGetBodyNext() as part of dynamics/collision interface + +groups/spaces are subclasses of geom. + +groups/spaces can contain other groups/spaces. geom can be owned by a +group/space. collision handling: + geom-geom : standard collision function + geom-group : special space code + group-group : n^2 tests (or n space tests) - hard to optimize because + of disjoint space representations. + group internal : normal space internal-collision code + +groups/spaces can be told that some objects never move, i.e. that the objects +are locked. should we lock the whole space? + locking: the AABB for the object is not recalculated + +groups/spaces can be told that the internal contents self-intersect or not. +actually an old ODE group is the equivalent of an old ODE simple space. + - just call dCollide() or not. + +the group doesn't get passed to the space callback any more ... only the +intersecting geoms get passed? maybe the callback can initiate the extra +intersection tests itself? (because we want programmable flexibility to +determine what gets intersected and what doesn't) + - NO + +infrastructure to indicate when an object has moved (and thus its AABB needs +to be recalculated) + +space enumeration functions. make sure that there are no additions or deletions +while enumeration is taking place. + - documented the behavior, didn't disallow it + +cache the AABB in the dxGeom? (for non-moving objects) - perhaps keep a +pointer to separately allocated space? ... no + +DOC: dGeomGetClass() is a first-class geom function, not in the "User +defined classes" section. it returns a constant that can be checked +against dSphereClass etc. + +remove dxGeom dependence on dBodyID? ... not yet + +dBase -> dxBase + +allow a geom to be inserted into multiple spaces? need this to optimize some +kinds of tests ... no + +update docs. + +make CHECK_NOT_LOCKED an assert. + +DOC: "Calling these functions on a non-placeable geom results in a +runtime error." ...in the debug build only? + +non-placeable geoms should not allocate dxPosR. perhaps pass a dGeom +constructor arg that says 'placeable' or not - this also sets the +GEOM_PLACEABLE flag. + +GeomTransform: + final_pos and final_R valid if no GEOM_AABB_BAD flag!!! + fix up this code, esp use of ComputeTX(). + +Space incompatibilities: no dSpaceDestroy(), dGeomDestroy() does not +take a dSpaceID ... dSpaceDestroy() added. + +GeomGroup incompatibilities: + dCollide() used to take a GeomGroup and would return all the contact + points for all the intersecting objects. now you have to call + dSpaceCollide2() and get a callback for each one. + need to provide old behavior. + +simple space optimization: we should keep the precomputed AABB for the +non-moving geoms around, so that when the other geoms move we can just +compute the AABBs for those geoms and then combine it with the non-moving AABB. + --> too hard! + +collision build options: old and new + +tidyups for collision: + * rationalize what stuff goes in what source files, and file names + * minimize set of header files that all collision* sources use - after + all changes. + * update ode-cpp stuff (C++ interface header files). + +porting guide: + ODE list email + + dGeomGetSpaceAABB() deleted + + dGeomGetClass (geom_group); used to return a unique type for + GeomGroups, but now it returns dSimpleSpaceID. + +tidyups: update DLL declarations. + diff --git a/libs/ode-0.16.1/ode/demo/Makefile.am b/libs/ode-0.16.1/ode/demo/Makefile.am new file mode 100644 index 0000000..5d02b87 --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/Makefile.am @@ -0,0 +1,75 @@ +AM_CPPFLAGS = -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ + -DDRAWSTUFF_TEXTURE_PATH="\"$(abs_top_srcdir)/drawstuff/textures\"" + +if X11 +AM_LDFLAGS = $(X_PRE_LIBS) $(X_LIBS) $(X_EXTRA_LIBS) +endif + +# On Windows, GL_LIBS must go after libdrawstuff.la. +LDADD = $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la @GL_LIBS@ + +noinst_HEADERS = basket_geom.h bunny_geom.h convex_bunny_geom.h convex_prism.h \ + icosahedron_geom.h halton235_geom.h texturepath.h world_geom3.h + +AM_DEFAULT_SOURCE_EXT = .cpp + +noinst_PROGRAMS = \ + demo_boxstack \ + demo_buggy \ + demo_cards \ + demo_chain1 \ + demo_chain2 \ + demo_collision \ + demo_convex \ + demo_crash \ + demo_cylvssphere \ + demo_dball \ + demo_dhinge \ + demo_transmission \ + demo_feedback \ + demo_friction \ + demo_gyroscopic \ + demo_gyro2 \ + demo_heightfield \ + demo_hinge \ + demo_I \ + demo_jointPR \ + demo_joints \ + demo_jointPU \ + demo_kinematic \ + demo_motion \ + demo_motor \ + demo_ode \ + demo_piston \ + demo_plane2d \ + demo_rfriction \ + demo_slider \ + demo_space \ + demo_space_stress \ + demo_step \ + demo_tracks + +demo_chain1_SOURCES = demo_chain1.c +demo_chain1_LDADD = $(LDADD) -lstdc++ + + +if TRIMESH +noinst_PROGRAMS += \ + demo_basket \ + demo_cyl \ + demo_moving_trimesh \ + demo_moving_convex \ + demo_trimesh + +AM_CPPFLAGS += -DdTRIMESH_ENABLED +endif + + + +if WIN32 +resources.o: $(top_srcdir)/drawstuff/src/resources.rc $(top_srcdir)/drawstuff/src/resource.h + @WINDRES@ $(top_srcdir)/drawstuff/src/resources.rc -o resources.o +LDADD += resources.o +endif diff --git a/libs/ode-0.16.1/ode/demo/Makefile.in b/libs/ode-0.16.1/ode/demo/Makefile.in new file mode 100644 index 0000000..368a5d1 --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/Makefile.in @@ -0,0 +1,1133 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +noinst_PROGRAMS = demo_boxstack$(EXEEXT) demo_buggy$(EXEEXT) \ + demo_cards$(EXEEXT) demo_chain1$(EXEEXT) demo_chain2$(EXEEXT) \ + demo_collision$(EXEEXT) demo_convex$(EXEEXT) \ + demo_crash$(EXEEXT) demo_cylvssphere$(EXEEXT) \ + demo_dball$(EXEEXT) demo_dhinge$(EXEEXT) \ + demo_transmission$(EXEEXT) demo_feedback$(EXEEXT) \ + demo_friction$(EXEEXT) demo_gyroscopic$(EXEEXT) \ + demo_gyro2$(EXEEXT) demo_heightfield$(EXEEXT) \ + demo_hinge$(EXEEXT) demo_I$(EXEEXT) demo_jointPR$(EXEEXT) \ + demo_joints$(EXEEXT) demo_jointPU$(EXEEXT) \ + demo_kinematic$(EXEEXT) demo_motion$(EXEEXT) \ + demo_motor$(EXEEXT) demo_ode$(EXEEXT) demo_piston$(EXEEXT) \ + demo_plane2d$(EXEEXT) demo_rfriction$(EXEEXT) \ + demo_slider$(EXEEXT) demo_space$(EXEEXT) \ + demo_space_stress$(EXEEXT) demo_step$(EXEEXT) \ + demo_tracks$(EXEEXT) $(am__EXEEXT_1) +@TRIMESH_TRUE@am__append_1 = \ +@TRIMESH_TRUE@ demo_basket \ +@TRIMESH_TRUE@ demo_cyl \ +@TRIMESH_TRUE@ demo_moving_trimesh \ +@TRIMESH_TRUE@ demo_moving_convex \ +@TRIMESH_TRUE@ demo_trimesh + +@TRIMESH_TRUE@am__append_2 = -DdTRIMESH_ENABLED +@WIN32_TRUE@am__append_3 = resources.o +subdir = ode/demo +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ode/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +@TRIMESH_TRUE@am__EXEEXT_1 = demo_basket$(EXEEXT) demo_cyl$(EXEEXT) \ +@TRIMESH_TRUE@ demo_moving_trimesh$(EXEEXT) \ +@TRIMESH_TRUE@ demo_moving_convex$(EXEEXT) \ +@TRIMESH_TRUE@ demo_trimesh$(EXEEXT) +PROGRAMS = $(noinst_PROGRAMS) +demo_I_SOURCES = demo_I.cpp +demo_I_OBJECTS = demo_I.$(OBJEXT) +demo_I_LDADD = $(LDADD) +demo_I_DEPENDENCIES = $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +demo_basket_SOURCES = demo_basket.cpp +demo_basket_OBJECTS = demo_basket.$(OBJEXT) +demo_basket_LDADD = $(LDADD) +demo_basket_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_boxstack_SOURCES = demo_boxstack.cpp +demo_boxstack_OBJECTS = demo_boxstack.$(OBJEXT) +demo_boxstack_LDADD = $(LDADD) +demo_boxstack_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_buggy_SOURCES = demo_buggy.cpp +demo_buggy_OBJECTS = demo_buggy.$(OBJEXT) +demo_buggy_LDADD = $(LDADD) +demo_buggy_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_cards_SOURCES = demo_cards.cpp +demo_cards_OBJECTS = demo_cards.$(OBJEXT) +demo_cards_LDADD = $(LDADD) +demo_cards_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +am_demo_chain1_OBJECTS = demo_chain1.$(OBJEXT) +demo_chain1_OBJECTS = $(am_demo_chain1_OBJECTS) +am__DEPENDENCIES_1 = $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_chain1_DEPENDENCIES = $(am__DEPENDENCIES_1) +demo_chain2_SOURCES = demo_chain2.cpp +demo_chain2_OBJECTS = demo_chain2.$(OBJEXT) +demo_chain2_LDADD = $(LDADD) +demo_chain2_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_collision_SOURCES = demo_collision.cpp +demo_collision_OBJECTS = demo_collision.$(OBJEXT) +demo_collision_LDADD = $(LDADD) +demo_collision_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_convex_SOURCES = demo_convex.cpp +demo_convex_OBJECTS = demo_convex.$(OBJEXT) +demo_convex_LDADD = $(LDADD) +demo_convex_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_crash_SOURCES = demo_crash.cpp +demo_crash_OBJECTS = demo_crash.$(OBJEXT) +demo_crash_LDADD = $(LDADD) +demo_crash_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_cyl_SOURCES = demo_cyl.cpp +demo_cyl_OBJECTS = demo_cyl.$(OBJEXT) +demo_cyl_LDADD = $(LDADD) +demo_cyl_DEPENDENCIES = $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_cylvssphere_SOURCES = demo_cylvssphere.cpp +demo_cylvssphere_OBJECTS = demo_cylvssphere.$(OBJEXT) +demo_cylvssphere_LDADD = $(LDADD) +demo_cylvssphere_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_dball_SOURCES = demo_dball.cpp +demo_dball_OBJECTS = demo_dball.$(OBJEXT) +demo_dball_LDADD = $(LDADD) +demo_dball_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_dhinge_SOURCES = demo_dhinge.cpp +demo_dhinge_OBJECTS = demo_dhinge.$(OBJEXT) +demo_dhinge_LDADD = $(LDADD) +demo_dhinge_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_feedback_SOURCES = demo_feedback.cpp +demo_feedback_OBJECTS = demo_feedback.$(OBJEXT) +demo_feedback_LDADD = $(LDADD) +demo_feedback_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_friction_SOURCES = demo_friction.cpp +demo_friction_OBJECTS = demo_friction.$(OBJEXT) +demo_friction_LDADD = $(LDADD) +demo_friction_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_gyro2_SOURCES = demo_gyro2.cpp +demo_gyro2_OBJECTS = demo_gyro2.$(OBJEXT) +demo_gyro2_LDADD = $(LDADD) +demo_gyro2_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_gyroscopic_SOURCES = demo_gyroscopic.cpp +demo_gyroscopic_OBJECTS = demo_gyroscopic.$(OBJEXT) +demo_gyroscopic_LDADD = $(LDADD) +demo_gyroscopic_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_heightfield_SOURCES = demo_heightfield.cpp +demo_heightfield_OBJECTS = demo_heightfield.$(OBJEXT) +demo_heightfield_LDADD = $(LDADD) +demo_heightfield_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_hinge_SOURCES = demo_hinge.cpp +demo_hinge_OBJECTS = demo_hinge.$(OBJEXT) +demo_hinge_LDADD = $(LDADD) +demo_hinge_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_jointPR_SOURCES = demo_jointPR.cpp +demo_jointPR_OBJECTS = demo_jointPR.$(OBJEXT) +demo_jointPR_LDADD = $(LDADD) +demo_jointPR_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_jointPU_SOURCES = demo_jointPU.cpp +demo_jointPU_OBJECTS = demo_jointPU.$(OBJEXT) +demo_jointPU_LDADD = $(LDADD) +demo_jointPU_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_joints_SOURCES = demo_joints.cpp +demo_joints_OBJECTS = demo_joints.$(OBJEXT) +demo_joints_LDADD = $(LDADD) +demo_joints_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_kinematic_SOURCES = demo_kinematic.cpp +demo_kinematic_OBJECTS = demo_kinematic.$(OBJEXT) +demo_kinematic_LDADD = $(LDADD) +demo_kinematic_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_motion_SOURCES = demo_motion.cpp +demo_motion_OBJECTS = demo_motion.$(OBJEXT) +demo_motion_LDADD = $(LDADD) +demo_motion_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_motor_SOURCES = demo_motor.cpp +demo_motor_OBJECTS = demo_motor.$(OBJEXT) +demo_motor_LDADD = $(LDADD) +demo_motor_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_moving_convex_SOURCES = demo_moving_convex.cpp +demo_moving_convex_OBJECTS = demo_moving_convex.$(OBJEXT) +demo_moving_convex_LDADD = $(LDADD) +demo_moving_convex_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_moving_trimesh_SOURCES = demo_moving_trimesh.cpp +demo_moving_trimesh_OBJECTS = demo_moving_trimesh.$(OBJEXT) +demo_moving_trimesh_LDADD = $(LDADD) +demo_moving_trimesh_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_ode_SOURCES = demo_ode.cpp +demo_ode_OBJECTS = demo_ode.$(OBJEXT) +demo_ode_LDADD = $(LDADD) +demo_ode_DEPENDENCIES = $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_piston_SOURCES = demo_piston.cpp +demo_piston_OBJECTS = demo_piston.$(OBJEXT) +demo_piston_LDADD = $(LDADD) +demo_piston_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_plane2d_SOURCES = demo_plane2d.cpp +demo_plane2d_OBJECTS = demo_plane2d.$(OBJEXT) +demo_plane2d_LDADD = $(LDADD) +demo_plane2d_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_rfriction_SOURCES = demo_rfriction.cpp +demo_rfriction_OBJECTS = demo_rfriction.$(OBJEXT) +demo_rfriction_LDADD = $(LDADD) +demo_rfriction_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_slider_SOURCES = demo_slider.cpp +demo_slider_OBJECTS = demo_slider.$(OBJEXT) +demo_slider_LDADD = $(LDADD) +demo_slider_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_space_SOURCES = demo_space.cpp +demo_space_OBJECTS = demo_space.$(OBJEXT) +demo_space_LDADD = $(LDADD) +demo_space_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_space_stress_SOURCES = demo_space_stress.cpp +demo_space_stress_OBJECTS = demo_space_stress.$(OBJEXT) +demo_space_stress_LDADD = $(LDADD) +demo_space_stress_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_step_SOURCES = demo_step.cpp +demo_step_OBJECTS = demo_step.$(OBJEXT) +demo_step_LDADD = $(LDADD) +demo_step_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_tracks_SOURCES = demo_tracks.cpp +demo_tracks_OBJECTS = demo_tracks.$(OBJEXT) +demo_tracks_LDADD = $(LDADD) +demo_tracks_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_transmission_SOURCES = demo_transmission.cpp +demo_transmission_OBJECTS = demo_transmission.$(OBJEXT) +demo_transmission_LDADD = $(LDADD) +demo_transmission_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +demo_trimesh_SOURCES = demo_trimesh.cpp +demo_trimesh_OBJECTS = demo_trimesh.$(OBJEXT) +demo_trimesh_LDADD = $(LDADD) +demo_trimesh_DEPENDENCIES = \ + $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la $(am__append_3) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +SOURCES = demo_I.cpp demo_basket.cpp demo_boxstack.cpp demo_buggy.cpp \ + demo_cards.cpp $(demo_chain1_SOURCES) demo_chain2.cpp \ + demo_collision.cpp demo_convex.cpp demo_crash.cpp demo_cyl.cpp \ + demo_cylvssphere.cpp demo_dball.cpp demo_dhinge.cpp \ + demo_feedback.cpp demo_friction.cpp demo_gyro2.cpp \ + demo_gyroscopic.cpp demo_heightfield.cpp demo_hinge.cpp \ + demo_jointPR.cpp demo_jointPU.cpp demo_joints.cpp \ + demo_kinematic.cpp demo_motion.cpp demo_motor.cpp \ + demo_moving_convex.cpp demo_moving_trimesh.cpp demo_ode.cpp \ + demo_piston.cpp demo_plane2d.cpp demo_rfriction.cpp \ + demo_slider.cpp demo_space.cpp demo_space_stress.cpp \ + demo_step.cpp demo_tracks.cpp demo_transmission.cpp \ + demo_trimesh.cpp +DIST_SOURCES = demo_I.cpp demo_basket.cpp demo_boxstack.cpp \ + demo_buggy.cpp demo_cards.cpp $(demo_chain1_SOURCES) \ + demo_chain2.cpp demo_collision.cpp demo_convex.cpp \ + demo_crash.cpp demo_cyl.cpp demo_cylvssphere.cpp \ + demo_dball.cpp demo_dhinge.cpp demo_feedback.cpp \ + demo_friction.cpp demo_gyro2.cpp demo_gyroscopic.cpp \ + demo_heightfield.cpp demo_hinge.cpp demo_jointPR.cpp \ + demo_jointPU.cpp demo_joints.cpp demo_kinematic.cpp \ + demo_motion.cpp demo_motor.cpp demo_moving_convex.cpp \ + demo_moving_trimesh.cpp demo_ode.cpp demo_piston.cpp \ + demo_plane2d.cpp demo_rfriction.cpp demo_slider.cpp \ + demo_space.cpp demo_space_stress.cpp demo_step.cpp \ + demo_tracks.cpp demo_transmission.cpp demo_trimesh.cpp +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +HEADERS = $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_CFLAGS = @CCD_CFLAGS@ +CCD_LIBS = @CCD_LIBS@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSTDCXX = @LIBSTDCXX@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ODE_PRECISION = @ODE_PRECISION@ +ODE_VERSION = @ODE_VERSION@ +ODE_VERSION_INFO = @ODE_VERSION_INFO@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include \ + -DDRAWSTUFF_TEXTURE_PATH="\"$(abs_top_srcdir)/drawstuff/textures\"" \ + $(am__append_2) +@X11_TRUE@AM_LDFLAGS = $(X_PRE_LIBS) $(X_LIBS) $(X_EXTRA_LIBS) + +# On Windows, GL_LIBS must go after libdrawstuff.la. +LDADD = $(top_builddir)/drawstuff/src/libdrawstuff.la \ + $(top_builddir)/ode/src/libode.la @GL_LIBS@ $(am__append_3) +noinst_HEADERS = basket_geom.h bunny_geom.h convex_bunny_geom.h convex_prism.h \ + icosahedron_geom.h halton235_geom.h texturepath.h world_geom3.h + +AM_DEFAULT_SOURCE_EXT = .cpp +demo_chain1_SOURCES = demo_chain1.c +demo_chain1_LDADD = $(LDADD) -lstdc++ +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign ode/demo/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign ode/demo/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +demo_I$(EXEEXT): $(demo_I_OBJECTS) $(demo_I_DEPENDENCIES) $(EXTRA_demo_I_DEPENDENCIES) + @rm -f demo_I$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_I_OBJECTS) $(demo_I_LDADD) $(LIBS) + +demo_basket$(EXEEXT): $(demo_basket_OBJECTS) $(demo_basket_DEPENDENCIES) $(EXTRA_demo_basket_DEPENDENCIES) + @rm -f demo_basket$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_basket_OBJECTS) $(demo_basket_LDADD) $(LIBS) + +demo_boxstack$(EXEEXT): $(demo_boxstack_OBJECTS) $(demo_boxstack_DEPENDENCIES) $(EXTRA_demo_boxstack_DEPENDENCIES) + @rm -f demo_boxstack$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_boxstack_OBJECTS) $(demo_boxstack_LDADD) $(LIBS) + +demo_buggy$(EXEEXT): $(demo_buggy_OBJECTS) $(demo_buggy_DEPENDENCIES) $(EXTRA_demo_buggy_DEPENDENCIES) + @rm -f demo_buggy$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_buggy_OBJECTS) $(demo_buggy_LDADD) $(LIBS) + +demo_cards$(EXEEXT): $(demo_cards_OBJECTS) $(demo_cards_DEPENDENCIES) $(EXTRA_demo_cards_DEPENDENCIES) + @rm -f demo_cards$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_cards_OBJECTS) $(demo_cards_LDADD) $(LIBS) + +demo_chain1$(EXEEXT): $(demo_chain1_OBJECTS) $(demo_chain1_DEPENDENCIES) $(EXTRA_demo_chain1_DEPENDENCIES) + @rm -f demo_chain1$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(demo_chain1_OBJECTS) $(demo_chain1_LDADD) $(LIBS) + +demo_chain2$(EXEEXT): $(demo_chain2_OBJECTS) $(demo_chain2_DEPENDENCIES) $(EXTRA_demo_chain2_DEPENDENCIES) + @rm -f demo_chain2$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_chain2_OBJECTS) $(demo_chain2_LDADD) $(LIBS) + +demo_collision$(EXEEXT): $(demo_collision_OBJECTS) $(demo_collision_DEPENDENCIES) $(EXTRA_demo_collision_DEPENDENCIES) + @rm -f demo_collision$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_collision_OBJECTS) $(demo_collision_LDADD) $(LIBS) + +demo_convex$(EXEEXT): $(demo_convex_OBJECTS) $(demo_convex_DEPENDENCIES) $(EXTRA_demo_convex_DEPENDENCIES) + @rm -f demo_convex$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_convex_OBJECTS) $(demo_convex_LDADD) $(LIBS) + +demo_crash$(EXEEXT): $(demo_crash_OBJECTS) $(demo_crash_DEPENDENCIES) $(EXTRA_demo_crash_DEPENDENCIES) + @rm -f demo_crash$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_crash_OBJECTS) $(demo_crash_LDADD) $(LIBS) + +demo_cyl$(EXEEXT): $(demo_cyl_OBJECTS) $(demo_cyl_DEPENDENCIES) $(EXTRA_demo_cyl_DEPENDENCIES) + @rm -f demo_cyl$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_cyl_OBJECTS) $(demo_cyl_LDADD) $(LIBS) + +demo_cylvssphere$(EXEEXT): $(demo_cylvssphere_OBJECTS) $(demo_cylvssphere_DEPENDENCIES) $(EXTRA_demo_cylvssphere_DEPENDENCIES) + @rm -f demo_cylvssphere$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_cylvssphere_OBJECTS) $(demo_cylvssphere_LDADD) $(LIBS) + +demo_dball$(EXEEXT): $(demo_dball_OBJECTS) $(demo_dball_DEPENDENCIES) $(EXTRA_demo_dball_DEPENDENCIES) + @rm -f demo_dball$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_dball_OBJECTS) $(demo_dball_LDADD) $(LIBS) + +demo_dhinge$(EXEEXT): $(demo_dhinge_OBJECTS) $(demo_dhinge_DEPENDENCIES) $(EXTRA_demo_dhinge_DEPENDENCIES) + @rm -f demo_dhinge$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_dhinge_OBJECTS) $(demo_dhinge_LDADD) $(LIBS) + +demo_feedback$(EXEEXT): $(demo_feedback_OBJECTS) $(demo_feedback_DEPENDENCIES) $(EXTRA_demo_feedback_DEPENDENCIES) + @rm -f demo_feedback$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_feedback_OBJECTS) $(demo_feedback_LDADD) $(LIBS) + +demo_friction$(EXEEXT): $(demo_friction_OBJECTS) $(demo_friction_DEPENDENCIES) $(EXTRA_demo_friction_DEPENDENCIES) + @rm -f demo_friction$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_friction_OBJECTS) $(demo_friction_LDADD) $(LIBS) + +demo_gyro2$(EXEEXT): $(demo_gyro2_OBJECTS) $(demo_gyro2_DEPENDENCIES) $(EXTRA_demo_gyro2_DEPENDENCIES) + @rm -f demo_gyro2$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_gyro2_OBJECTS) $(demo_gyro2_LDADD) $(LIBS) + +demo_gyroscopic$(EXEEXT): $(demo_gyroscopic_OBJECTS) $(demo_gyroscopic_DEPENDENCIES) $(EXTRA_demo_gyroscopic_DEPENDENCIES) + @rm -f demo_gyroscopic$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_gyroscopic_OBJECTS) $(demo_gyroscopic_LDADD) $(LIBS) + +demo_heightfield$(EXEEXT): $(demo_heightfield_OBJECTS) $(demo_heightfield_DEPENDENCIES) $(EXTRA_demo_heightfield_DEPENDENCIES) + @rm -f demo_heightfield$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_heightfield_OBJECTS) $(demo_heightfield_LDADD) $(LIBS) + +demo_hinge$(EXEEXT): $(demo_hinge_OBJECTS) $(demo_hinge_DEPENDENCIES) $(EXTRA_demo_hinge_DEPENDENCIES) + @rm -f demo_hinge$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_hinge_OBJECTS) $(demo_hinge_LDADD) $(LIBS) + +demo_jointPR$(EXEEXT): $(demo_jointPR_OBJECTS) $(demo_jointPR_DEPENDENCIES) $(EXTRA_demo_jointPR_DEPENDENCIES) + @rm -f demo_jointPR$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_jointPR_OBJECTS) $(demo_jointPR_LDADD) $(LIBS) + +demo_jointPU$(EXEEXT): $(demo_jointPU_OBJECTS) $(demo_jointPU_DEPENDENCIES) $(EXTRA_demo_jointPU_DEPENDENCIES) + @rm -f demo_jointPU$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_jointPU_OBJECTS) $(demo_jointPU_LDADD) $(LIBS) + +demo_joints$(EXEEXT): $(demo_joints_OBJECTS) $(demo_joints_DEPENDENCIES) $(EXTRA_demo_joints_DEPENDENCIES) + @rm -f demo_joints$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_joints_OBJECTS) $(demo_joints_LDADD) $(LIBS) + +demo_kinematic$(EXEEXT): $(demo_kinematic_OBJECTS) $(demo_kinematic_DEPENDENCIES) $(EXTRA_demo_kinematic_DEPENDENCIES) + @rm -f demo_kinematic$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_kinematic_OBJECTS) $(demo_kinematic_LDADD) $(LIBS) + +demo_motion$(EXEEXT): $(demo_motion_OBJECTS) $(demo_motion_DEPENDENCIES) $(EXTRA_demo_motion_DEPENDENCIES) + @rm -f demo_motion$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_motion_OBJECTS) $(demo_motion_LDADD) $(LIBS) + +demo_motor$(EXEEXT): $(demo_motor_OBJECTS) $(demo_motor_DEPENDENCIES) $(EXTRA_demo_motor_DEPENDENCIES) + @rm -f demo_motor$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_motor_OBJECTS) $(demo_motor_LDADD) $(LIBS) + +demo_moving_convex$(EXEEXT): $(demo_moving_convex_OBJECTS) $(demo_moving_convex_DEPENDENCIES) $(EXTRA_demo_moving_convex_DEPENDENCIES) + @rm -f demo_moving_convex$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_moving_convex_OBJECTS) $(demo_moving_convex_LDADD) $(LIBS) + +demo_moving_trimesh$(EXEEXT): $(demo_moving_trimesh_OBJECTS) $(demo_moving_trimesh_DEPENDENCIES) $(EXTRA_demo_moving_trimesh_DEPENDENCIES) + @rm -f demo_moving_trimesh$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_moving_trimesh_OBJECTS) $(demo_moving_trimesh_LDADD) $(LIBS) + +demo_ode$(EXEEXT): $(demo_ode_OBJECTS) $(demo_ode_DEPENDENCIES) $(EXTRA_demo_ode_DEPENDENCIES) + @rm -f demo_ode$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_ode_OBJECTS) $(demo_ode_LDADD) $(LIBS) + +demo_piston$(EXEEXT): $(demo_piston_OBJECTS) $(demo_piston_DEPENDENCIES) $(EXTRA_demo_piston_DEPENDENCIES) + @rm -f demo_piston$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_piston_OBJECTS) $(demo_piston_LDADD) $(LIBS) + +demo_plane2d$(EXEEXT): $(demo_plane2d_OBJECTS) $(demo_plane2d_DEPENDENCIES) $(EXTRA_demo_plane2d_DEPENDENCIES) + @rm -f demo_plane2d$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_plane2d_OBJECTS) $(demo_plane2d_LDADD) $(LIBS) + +demo_rfriction$(EXEEXT): $(demo_rfriction_OBJECTS) $(demo_rfriction_DEPENDENCIES) $(EXTRA_demo_rfriction_DEPENDENCIES) + @rm -f demo_rfriction$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_rfriction_OBJECTS) $(demo_rfriction_LDADD) $(LIBS) + +demo_slider$(EXEEXT): $(demo_slider_OBJECTS) $(demo_slider_DEPENDENCIES) $(EXTRA_demo_slider_DEPENDENCIES) + @rm -f demo_slider$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_slider_OBJECTS) $(demo_slider_LDADD) $(LIBS) + +demo_space$(EXEEXT): $(demo_space_OBJECTS) $(demo_space_DEPENDENCIES) $(EXTRA_demo_space_DEPENDENCIES) + @rm -f demo_space$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_space_OBJECTS) $(demo_space_LDADD) $(LIBS) + +demo_space_stress$(EXEEXT): $(demo_space_stress_OBJECTS) $(demo_space_stress_DEPENDENCIES) $(EXTRA_demo_space_stress_DEPENDENCIES) + @rm -f demo_space_stress$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_space_stress_OBJECTS) $(demo_space_stress_LDADD) $(LIBS) + +demo_step$(EXEEXT): $(demo_step_OBJECTS) $(demo_step_DEPENDENCIES) $(EXTRA_demo_step_DEPENDENCIES) + @rm -f demo_step$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_step_OBJECTS) $(demo_step_LDADD) $(LIBS) + +demo_tracks$(EXEEXT): $(demo_tracks_OBJECTS) $(demo_tracks_DEPENDENCIES) $(EXTRA_demo_tracks_DEPENDENCIES) + @rm -f demo_tracks$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_tracks_OBJECTS) $(demo_tracks_LDADD) $(LIBS) + +demo_transmission$(EXEEXT): $(demo_transmission_OBJECTS) $(demo_transmission_DEPENDENCIES) $(EXTRA_demo_transmission_DEPENDENCIES) + @rm -f demo_transmission$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_transmission_OBJECTS) $(demo_transmission_LDADD) $(LIBS) + +demo_trimesh$(EXEEXT): $(demo_trimesh_OBJECTS) $(demo_trimesh_DEPENDENCIES) $(EXTRA_demo_trimesh_DEPENDENCIES) + @rm -f demo_trimesh$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(demo_trimesh_OBJECTS) $(demo_trimesh_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_I.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_basket.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_boxstack.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_buggy.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_cards.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_chain1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_chain2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_collision.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_convex.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_crash.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_cyl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_cylvssphere.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_dball.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_dhinge.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_feedback.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_friction.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_gyro2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_gyroscopic.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_heightfield.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_hinge.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_jointPR.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_jointPU.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_joints.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_kinematic.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_motion.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_motor.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_moving_convex.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_moving_trimesh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_ode.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_piston.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_plane2d.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_rfriction.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_slider.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_space.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_space_stress.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_step.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_tracks.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_transmission.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_trimesh.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +.cpp.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) $(HEADERS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstPROGRAMS cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +@WIN32_TRUE@resources.o: $(top_srcdir)/drawstuff/src/resources.rc $(top_srcdir)/drawstuff/src/resource.h +@WIN32_TRUE@ @WINDRES@ $(top_srcdir)/drawstuff/src/resources.rc -o resources.o + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/ode/demo/basket_geom.h b/libs/ode-0.16.1/ode/demo/basket_geom.h new file mode 100644 index 0000000..ec88327 --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/basket_geom.h @@ -0,0 +1,599 @@ + +static float world_normals[] = { + 0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,-0,0,1,0,0,1,0,0,1,0,0,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,-0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,1,0,-0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,0,-0.948064f,0.318080f,0,-0.989482f,0.144655f,0,-0.983494f,0.180939f,0,-0.983494f,0.180939f,0,-0.908999f,0.416798f,0,-0.948064f,0.318080f,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,-1,0,-0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,-0.132460f,0.991188f,0,0.264920f,0.964270f,0,0.132460f,0.991188f,0,0.132460f,0.991188f,0,-0.264920f,0.964270f,0,-0.132460f,0.991188f,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,-0.687592f,-0.726097f,-0,-0.881727f,-0.471761f,0,-0.687592f,-0.726097f,-0,-0.881727f,-0.471761f,0,-0.881727f,-0.471761f,0,-0.687592f,-0.726097f,-0,0.687592f,-0.726097f,0,0.928375f,-0.371644f,0,0.824321f,-0.566123f,0,0.687592f,-0.726097f,0,0.824321f,-0.566123f,0,0.687592f,-0.726097f,0,-0.881727f,-0.471761f,0,-0.985594f,-0.169128f,0,-0.985594f,-0.169128f,0,-0.985594f,-0.169128f,0,-0.881727f,-0.471761f,0,-0.881727f,-0.471761f,0,0.928375f,-0.371644f,0,0.985594f,-0.169128f,0,0.985594f,-0.169128f,0,0.928375f,-0.371644f,0,0.985594f,-0.169128f,0,0.824321f,-0.566123f,0,-0.870167f,0.492758f,0,-0.870167f,0.492758f,0,-0.870167f,0.492758f,0,-0.870167f,0.492758f,0,-0.870167f,0.492758f,0,-0.870167f,0.492758f,0,0.870167f,0.492758f,0,0.870167f,0.492758f,0,0.870167f,0.492758f,0,0.870167f,0.492758f,0,0.870167f,0.492758f,0,0.870167f,0.492758f,-0,-0.390313f,0.920682f,0,-0.132460f,0.991188f,0,-0.264920f,0.964270f,0,-0.264920f,0.964270f,0,-0.390313f,0.920682f,0,-0.390313f,0.920682f,0,0.390313f,0.920682f,0,0.132460f,0.991188f,0,0.264920f,0.964270f,0,0.390313f,0.920682f,0,0.264920f,0.964270f,0,0.390313f,0.920682f,-0,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0.985594f,0.169128f,0,0.824321f,0.566123f,0,0.928375f,0.371644f,0,0.928375f,0.371644f,0,0.985594f,0.169128f,0,0.985594f,0.169128f,0,0.824321f,0.566123f,0,0.687592f,0.726097f,0,0.687592f,0.726097f,0,0.687592f,0.726097f,0,0.928375f,0.371644f,0,0.824321f,0.566123f,0,0,1,0,-0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,-0.687592f,0.726097f,0,-0.687592f,0.726097f,0,-0.881727f,0.471761f,0,-0.881727f,0.471761f,0,-0.881727f,0.471761f,0,-0.687592f,0.726097f,0,-0.881727f,0.471761f,0,-0.985594f,0.169128f,0,-0.985594f,0.169128f,0,-0.985594f,0.169128f,0,-0.881727f,0.471761f,0,-0.881727f,0.471761f,0,-0.870166f,-0.492758f,0,-0.870166f,-0.492758f,0,-0.870166f,-0.492758f,0,-0.870166f,-0.492758f,0,-0.870166f,-0.492758f,0,-0.870166f,-0.492758f,0,-0.390314f,-0.920682f,0,-0.132460f,-0.991188f,0,-0.264921f,-0.964270f,0,-0.264921f,-0.964270f,0,-0.390314f,-0.920682f,0,-0.390314f,-0.920682f,0,-0.132460f,-0.991188f,0,0.264921f,-0.964270f,0,0.132460f,-0.991188f,0,0.132460f,-0.991188f,0,-0.264921f,-0.964270f,0,-0.132460f,-0.991188f,0,0.264921f,-0.964270f,0,0.390314f,-0.920682f,0,0.390314f,-0.920682f,0,0.390314f,-0.920682f,0,0.132460f,-0.991188f,0,0.264921f,-0.964270f,0,0.870166f,-0.492758f,0,0.870166f,-0.492758f,0,0.870166f,-0.492758f,0,0.870166f,-0.492758f,0,0.870166f,-0.492758f,0,0.870166f,-0.492758f,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,-0.527606f,0.849489f,0,-0.793893f,0.608057f,0,-0.715135f,0.698986f,0,-0.715135f,0.698986f,0,-0.418249f,0.908332f,0,-0.527606f,0.849489f,0,-0.075284f,0.997162f,0,-0.253577f,0.967315f,0,-0.202069f,0.979371f,0,-0.202069f,0.979371f,0,-0.075284f,0.997162f,0,-0.075284f,0.997162f,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0.160137f,0.987095f,0,0.049305f,0.998784f,0,0.049305f,0.998784f,0,0.049305f,0.998784f,0,0.221401f,0.975183f,0,0.160137f,0.987095f,0,0.696124f,0.717921f,0,0.696124f,0.717921f,0,0.433340f,0.901230f,0,0.433340f,0.901230f,0,0.433340f,0.901230f,0,0.696124f,0.717921f,0,0.696124f,0.717921f,0,0.696124f,0.717921f,0,0.838308f,0.545197f,0,0.696124f,0.717921f,0,0.872167f,0.489208f,0,0.838308f,0.545197f,0,-0.994126f,0.108225f,0,-0.983494f,0.180939f,0,-0.989482f,0.144655f,0,-0.994126f,0.108225f,0,-0.989482f,0.144655f,0,-0.994126f,0.108225f,0,-0.948064f,0.318080f,0,-0.908999f,0.416798f,0,-0.793893f,0.608057f,0,-0.908999f,0.416798f,0,-0.715135f,0.698986f,0,-0.793893f,0.608057f,0,-0.527606f,0.849489f,0,-0.418249f,0.908332f,0,-0.253577f,0.967315f,0,-0.418249f,0.908332f,0,-0.202069f,0.979371f,0,-0.253577f,0.967315f,0,-0.075284f,0.997162f,0,-0.075284f,0.997162f,0,0,1,0,-0.075284f,0.997162f,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0.049305f,0.998784f,0,0,1,0,0.049305f,0.998784f,0,0.049305f,0.998784f,0,0.160137f,0.987095f,0,0.221401f,0.975183f,0,0.433340f,0.901230f,0,0.221401f,0.975183f,0,0.433340f,0.901230f,0,0.433340f,0.901230f,0,0.902172f,0.431376f,0,0.838308f,0.545197f,0,0.872167f,0.489208f,0,0.872167f,0.489208f,0,0.902172f,0.431376f,0,0.902172f,0.431376f, +}; + +static float world_vertices[] = { + -4,-4,-0.100000f, + 4,-4,-0.100000f, + 4,-4,0.100000f, + -4,-4,0.100000f, + 4,0,0.100000f, + 4,4,-0.100000f, + 4,4,0.100000f, + -4,4,-0.100000f, + 0.066000f,-2.060000f,2, + 0.066000f,-1.940000f,2, + -0.066000f,-2.060000f,2, + -0.066000f,-1.940000f,2, + -4,4,0.100000f, + -4,0,0.100000f, + 0.360000f,3.244444f,1.466974f, + 0.360000f,3.422222f,2.266974f, + -0.360000f,3.422222f,2.266974f, + -0.360000f,3.244444f,1.466974f, + 0.066000f,-2.060000f,0.100000f, + -0.066000f,-2.060000f,0.100000f, + 0.066000f,-1.940000f,0.100000f, + -0.066000f,-1.940000f,0.100000f, + 0.066000f,-1.940000f,1.950000f, + -0.052853f,-1.506390f,2, + 0.052853f,-1.506390f,2, + 0.052853f,-1.506390f,1.950000f, + -0.052853f,-1.506390f,1.950000f, + -0.066000f,-1.940000f,1.950000f, + -0.066000f,-1.840000f,1.950000f, + 0.066000f,-1.840000f,1.950000f, + -0.066000f,-1.840000f,2, + 0.066000f,-1.840000f,2, + -0.171600f,-1.740000f,2, + -0.171600f,-1.740000f,1.950000f, + 0.171600f,-1.740000f,1.950000f, + 0.171600f,-1.740000f,2, + -0.188760f,-1.640000f,2, + -0.188760f,-1.640000f,1.950000f, + 0.188760f,-1.640000f,1.950000f, + 0.188760f,-1.640000f,2, + -0.132132f,-1.540000f,2, + -0.132132f,-1.540000f,1.950000f, + 0.132132f,-1.540000f,1.950000f, + 0.132132f,-1.540000f,2, + 0.173397f,-1.642679f,1.950000f, + 0.121808f,-1.551577f,1.950000f, + 0.157950f,-1.732697f,1.950000f, + 0.060149f,-1.825311f,1.950000f, + -0.060149f,-1.825311f,1.950000f, + -0.157950f,-1.732697f,1.950000f, + -0.173397f,-1.642679f,1.950000f, + -0.121808f,-1.551577f,1.950000f, + -0.049868f,-1.521079f,1.950000f, + 0.049868f,-1.521079f,1.950000f, + -0.173397f,-1.642679f,2, + -0.121808f,-1.551577f,2, + -0.157950f,-1.732697f,2, + -0.060149f,-1.825311f,2, + 0.060149f,-1.825311f,2, + 0.157950f,-1.732697f,2, + 0.173397f,-1.642679f,2, + 0.121808f,-1.551577f,2, + 0.049868f,-1.521079f,2, + -0.049868f,-1.521079f,2, + -0.360000f,3.600000f,0.100000f, + 0.360000f,3.600000f,0.100000f, + -0.360000f,0.400000f,0.100000f, + 0.360000f,0.400000f,0.100000f, + 0.360000f,2.888889f,1.023752f, + 0.360000f,3.066667f,1.166974f, + -0.360000f,3.066667f,1.166974f, + -0.360000f,2.888889f,1.023752f, + 0.360000f,2.533333f,0.939976f, + 0.360000f,2.711111f,0.966974f, + -0.360000f,2.711111f,0.966974f, + -0.360000f,2.533333f,0.939976f, + -0.360000f,2.177778f,0.939976f, + 0.360000f,2.177778f,0.939976f, + 0.360000f,2.355556f,0.939976f, + -0.360000f,2.355556f,0.939976f, + -0.360000f,1.822222f,0.939976f, + 0.360000f,1.822222f,0.939976f, + 0.360000f,2,0.939976f, + -0.360000f,2,0.939976f, + -0.360000f,1.466667f,0.939976f, + 0.360000f,1.466667f,0.939976f, + 0.360000f,1.644444f,0.939976f, + -0.360000f,1.644444f,0.939976f, + 0.360000f,1.111111f,0.957571f, + 0.360000f,1.288889f,0.939976f, + -0.360000f,1.288889f,0.939976f, + -0.360000f,1.111111f,0.957571f, + -0.360000f,0.755556f,1.134246f, + 0.360000f,0.755556f,1.134246f, + 0.360000f,0.933333f,1.009739f, + -0.360000f,0.933333f,1.009739f, + 0.360000f,0.577778f,1.372130f, + -0.360000f,0.577778f,1.372130f, + -0.360000f,3.600000f,3.900000f, + 0.360000f,3.600000f,3.900000f, + 0.360000f,0.400000f,1.743932f, + -0.360000f,0.400000f,1.743932f, +}; + +static dTriIndex world_indices[] = { + 0, + 1, + 2, + 0, + 2, + 3, + 4, + 1, + 5, + 4, + 5, + 6, + 4, + 2, + 1, + 0, + 7, + 5, + 0, + 5, + 1, + 8, + 9, + 10, + 9, + 11, + 10, + 12, + 6, + 5, + 5, + 7, + 12, + 3, + 13, + 0, + 13, + 12, + 7, + 13, + 7, + 0, + 14, + 15, + 16, + 16, + 17, + 14, + 2, + 18, + 19, + 19, + 3, + 2, + 4, + 20, + 2, + 20, + 18, + 2, + 21, + 20, + 4, + 4, + 13, + 21, + 19, + 21, + 13, + 13, + 3, + 19, + 8, + 10, + 19, + 19, + 18, + 8, + 22, + 9, + 8, + 8, + 18, + 22, + 18, + 20, + 22, + 23, + 24, + 25, + 25, + 26, + 23, + 19, + 10, + 27, + 19, + 27, + 21, + 10, + 11, + 27, + 21, + 27, + 22, + 21, + 22, + 20, + 27, + 28, + 22, + 28, + 29, + 22, + 11, + 30, + 28, + 28, + 27, + 11, + 9, + 31, + 11, + 31, + 30, + 11, + 22, + 29, + 31, + 22, + 31, + 9, + 30, + 32, + 28, + 32, + 33, + 28, + 29, + 34, + 35, + 29, + 35, + 31, + 32, + 36, + 37, + 37, + 33, + 32, + 34, + 38, + 39, + 34, + 39, + 35, + 36, + 40, + 41, + 41, + 37, + 36, + 38, + 42, + 43, + 38, + 43, + 39, + 40, + 23, + 26, + 26, + 41, + 40, + 42, + 25, + 24, + 42, + 24, + 43, + 38, + 44, + 45, + 45, + 42, + 38, + 34, + 46, + 44, + 34, + 44, + 38, + 34, + 29, + 47, + 34, + 47, + 46, + 28, + 48, + 29, + 48, + 47, + 29, + 33, + 49, + 48, + 33, + 48, + 28, + 50, + 49, + 33, + 33, + 37, + 50, + 51, + 50, + 37, + 37, + 41, + 51, + 26, + 52, + 51, + 26, + 51, + 41, + 53, + 52, + 26, + 26, + 25, + 53, + 25, + 42, + 45, + 25, + 45, + 53, + 36, + 54, + 55, + 55, + 40, + 36, + 32, + 56, + 54, + 54, + 36, + 32, + 30, + 57, + 32, + 57, + 56, + 32, + 31, + 58, + 30, + 58, + 57, + 30, + 35, + 59, + 58, + 35, + 58, + 31, + 60, + 59, + 35, + 35, + 39, + 60, + 61, + 60, + 39, + 39, + 43, + 61, + 24, + 62, + 61, + 24, + 61, + 43, + 63, + 62, + 24, + 24, + 23, + 63, + 55, + 63, + 23, + 23, + 40, + 55, + 54, + 56, + 49, + 49, + 50, + 54, + 56, + 57, + 48, + 48, + 49, + 56, + 57, + 58, + 47, + 47, + 48, + 57, + 47, + 58, + 59, + 59, + 46, + 47, + 59, + 60, + 44, + 44, + 46, + 59, + 60, + 61, + 45, + 45, + 44, + 60, + 61, + 62, + 53, + 53, + 45, + 61, + 62, + 63, + 52, + 52, + 53, + 62, + 63, + 55, + 51, + 51, + 52, + 63, + 55, + 54, + 50, + 50, + 51, + 55, + 64, + 65, + 6, + 6, + 12, + 64, + 66, + 64, + 12, + 12, + 13, + 66, + 4, + 67, + 66, + 66, + 13, + 4, + 6, + 65, + 4, + 65, + 67, + 4, + 68, + 69, + 70, + 70, + 71, + 68, + 72, + 73, + 74, + 74, + 75, + 72, + 76, + 77, + 78, + 78, + 79, + 76, + 80, + 81, + 82, + 82, + 83, + 80, + 84, + 85, + 86, + 86, + 87, + 84, + 88, + 89, + 90, + 90, + 91, + 88, + 92, + 93, + 94, + 94, + 95, + 92, + 93, + 92, + 96, + 92, + 97, + 96, + 98, + 16, + 15, + 98, + 15, + 99, + 14, + 17, + 69, + 17, + 70, + 69, + 68, + 71, + 73, + 71, + 74, + 73, + 72, + 75, + 79, + 72, + 79, + 78, + 77, + 76, + 83, + 77, + 83, + 82, + 81, + 80, + 87, + 81, + 87, + 86, + 85, + 84, + 90, + 85, + 90, + 89, + 88, + 91, + 94, + 91, + 95, + 94, + 100, + 96, + 97, + 97, + 101, + 100, +}; + diff --git a/libs/ode-0.16.1/ode/demo/bunny_geom.h b/libs/ode-0.16.1/ode/demo/bunny_geom.h new file mode 100644 index 0000000..78f8eb0 --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/bunny_geom.h @@ -0,0 +1,1366 @@ +// Bunny mesh ripped from Opcode +const int VertexCount = 453; +const int IndexCount = 902 * 3; + + +float Vertices[VertexCount * 3] = { + -0.334392f, 0.133007f, 0.062259f, + -0.350189f, 0.150354f, -0.147769f, + -0.234201f, 0.343811f, -0.174307f, + -0.200259f, 0.285207f, 0.093749f, + 0.003520f, 0.475208f, -0.159365f, + 0.001856f, 0.419203f, 0.098582f, + -0.252802f, 0.093666f, 0.237538f, + -0.162901f, 0.237984f, 0.206905f, + 0.000865f, 0.318141f, 0.235370f, + -0.414624f, 0.164083f, -0.278254f, + -0.262213f, 0.357334f, -0.293246f, + 0.004628f, 0.482694f, -0.338626f, + -0.402162f, 0.133528f, -0.443247f, + -0.243781f, 0.324275f, -0.436763f, + 0.005293f, 0.437592f, -0.458332f, + -0.339884f, -0.041150f, -0.668211f, + -0.248382f, 0.255825f, -0.627493f, + 0.006261f, 0.376103f, -0.631506f, + -0.216201f, -0.126776f, -0.886936f, + -0.171075f, 0.011544f, -0.881386f, + -0.181074f, 0.098223f, -0.814779f, + -0.119891f, 0.218786f, -0.760153f, + -0.078895f, 0.276780f, -0.739281f, + 0.006801f, 0.310959f, -0.735661f, + -0.168842f, 0.102387f, -0.920381f, + -0.104072f, 0.177278f, -0.952530f, + -0.129704f, 0.211848f, -0.836678f, + -0.099875f, 0.310931f, -0.799381f, + 0.007237f, 0.361687f, -0.794439f, + -0.077913f, 0.258753f, -0.921640f, + 0.007957f, 0.282241f, -0.931680f, + -0.252222f, -0.550401f, -0.557810f, + -0.267633f, -0.603419f, -0.655209f, + -0.446838f, -0.118517f, -0.466159f, + -0.459488f, -0.093017f, -0.311341f, + -0.370645f, -0.100108f, -0.159454f, + -0.371984f, -0.091991f, -0.011044f, + -0.328945f, -0.098269f, 0.088659f, + -0.282452f, -0.018862f, 0.311501f, + -0.352403f, -0.131341f, 0.144902f, + -0.364126f, -0.200299f, 0.202388f, + -0.283965f, -0.231869f, 0.023668f, + -0.298943f, -0.155218f, 0.369716f, + -0.293787f, -0.121856f, 0.419097f, + -0.290163f, -0.290797f, 0.107824f, + -0.264165f, -0.272849f, 0.036347f, + -0.228567f, -0.372573f, 0.290309f, + -0.190431f, -0.286997f, 0.421917f, + -0.191039f, -0.240973f, 0.507118f, + -0.287272f, -0.276431f, -0.065444f, + -0.295675f, -0.280818f, -0.174200f, + -0.399537f, -0.313131f, -0.376167f, + -0.392666f, -0.488581f, -0.427494f, + -0.331669f, -0.570185f, -0.466054f, + -0.282290f, -0.618140f, -0.589220f, + -0.374238f, -0.594882f, -0.323298f, + -0.381071f, -0.629723f, -0.350777f, + -0.382112f, -0.624060f, -0.221577f, + -0.272701f, -0.566522f, 0.259157f, + -0.256702f, -0.663406f, 0.286079f, + -0.280948f, -0.428359f, 0.055790f, + -0.184974f, -0.508894f, 0.326265f, + -0.279971f, -0.526918f, 0.395319f, + -0.282599f, -0.663393f, 0.412411f, + -0.188329f, -0.475093f, 0.417954f, + -0.263384f, -0.663396f, 0.466604f, + -0.209063f, -0.663393f, 0.509344f, + -0.002044f, -0.319624f, 0.553078f, + -0.001266f, -0.371260f, 0.413296f, + -0.219753f, -0.339762f, -0.040921f, + -0.256986f, -0.282511f, -0.006349f, + -0.271706f, -0.260881f, 0.001764f, + -0.091191f, -0.419184f, -0.045912f, + -0.114944f, -0.429752f, -0.124739f, + -0.113970f, -0.382987f, -0.188540f, + -0.243012f, -0.464942f, -0.242850f, + -0.314815f, -0.505402f, -0.324768f, + 0.002774f, -0.437526f, -0.262766f, + -0.072625f, -0.417748f, -0.221440f, + -0.160112f, -0.476932f, -0.293450f, + 0.003859f, -0.453425f, -0.443916f, + -0.120363f, -0.581567f, -0.438689f, + -0.091499f, -0.584191f, -0.294511f, + -0.116469f, -0.599861f, -0.188308f, + -0.208032f, -0.513640f, -0.134649f, + -0.235749f, -0.610017f, -0.040939f, + -0.344916f, -0.622487f, -0.085380f, + -0.336401f, -0.531864f, -0.212298f, + 0.001961f, -0.459550f, -0.135547f, + -0.058296f, -0.430536f, -0.043440f, + 0.001378f, -0.449511f, -0.037762f, + -0.130135f, -0.510222f, 0.079144f, + 0.000142f, -0.477549f, 0.157064f, + -0.114284f, -0.453206f, 0.304397f, + -0.000592f, -0.443558f, 0.285401f, + -0.056215f, -0.663402f, 0.326073f, + -0.026248f, -0.568010f, 0.273318f, + -0.049261f, -0.531064f, 0.389854f, + -0.127096f, -0.663398f, 0.479316f, + -0.058384f, -0.663401f, 0.372891f, + -0.303961f, 0.054199f, 0.625921f, + -0.268594f, 0.193403f, 0.502766f, + -0.277159f, 0.126123f, 0.443289f, + -0.287605f, -0.005722f, 0.531844f, + -0.231396f, -0.121289f, 0.587387f, + -0.253475f, -0.081797f, 0.756541f, + -0.195164f, -0.137969f, 0.728011f, + -0.167673f, -0.156573f, 0.609388f, + -0.145917f, -0.169029f, 0.697600f, + -0.077776f, -0.214247f, 0.622586f, + -0.076873f, -0.214971f, 0.696301f, + -0.002341f, -0.233135f, 0.622859f, + -0.002730f, -0.213526f, 0.691267f, + -0.003136f, -0.192628f, 0.762731f, + -0.056136f, -0.201222f, 0.763806f, + -0.114589f, -0.166192f, 0.770723f, + -0.155145f, -0.129632f, 0.791738f, + -0.183611f, -0.058705f, 0.847012f, + -0.165562f, 0.001980f, 0.833386f, + -0.220084f, 0.019914f, 0.768935f, + -0.255730f, 0.090306f, 0.670782f, + -0.255594f, 0.113833f, 0.663389f, + -0.226380f, 0.212655f, 0.617740f, + -0.003367f, -0.195342f, 0.799680f, + -0.029743f, -0.210508f, 0.827180f, + -0.003818f, -0.194783f, 0.873636f, + -0.004116f, -0.157907f, 0.931268f, + -0.031280f, -0.184555f, 0.889476f, + -0.059885f, -0.184448f, 0.841330f, + -0.135333f, -0.164332f, 0.878200f, + -0.085574f, -0.170948f, 0.925547f, + -0.163833f, -0.094170f, 0.897114f, + -0.138444f, -0.104250f, 0.945975f, + -0.083497f, -0.084934f, 0.979607f, + -0.004433f, -0.146642f, 0.985872f, + -0.150715f, 0.032650f, 0.884111f, + -0.135892f, -0.035520f, 0.945455f, + -0.070612f, 0.036849f, 0.975733f, + -0.004458f, -0.042526f, 1.015670f, + -0.004249f, 0.046042f, 1.003240f, + -0.086969f, 0.133224f, 0.947633f, + -0.003873f, 0.161605f, 0.970499f, + -0.125544f, 0.140012f, 0.917678f, + -0.125651f, 0.250246f, 0.857602f, + -0.003127f, 0.284070f, 0.878870f, + -0.159174f, 0.125726f, 0.888878f, + -0.183807f, 0.196970f, 0.844480f, + -0.159890f, 0.291736f, 0.732480f, + -0.199495f, 0.207230f, 0.779864f, + -0.206182f, 0.164608f, 0.693257f, + -0.186315f, 0.160689f, 0.817193f, + -0.192827f, 0.166706f, 0.782271f, + -0.175112f, 0.110008f, 0.860621f, + -0.161022f, 0.057420f, 0.855111f, + -0.172319f, 0.036155f, 0.816189f, + -0.190318f, 0.064083f, 0.760605f, + -0.195072f, 0.129179f, 0.731104f, + -0.203126f, 0.410287f, 0.680536f, + -0.216677f, 0.309274f, 0.642272f, + -0.241515f, 0.311485f, 0.587832f, + -0.002209f, 0.366663f, 0.749413f, + -0.088230f, 0.396265f, 0.678635f, + -0.170147f, 0.109517f, 0.840784f, + -0.160521f, 0.067766f, 0.830650f, + -0.181546f, 0.139805f, 0.812146f, + -0.180495f, 0.148568f, 0.776087f, + -0.180255f, 0.129125f, 0.744192f, + -0.186298f, 0.078308f, 0.769352f, + -0.167622f, 0.060539f, 0.806675f, + -0.189876f, 0.102760f, 0.802582f, + -0.108340f, 0.455446f, 0.657174f, + -0.241585f, 0.527592f, 0.669296f, + -0.265676f, 0.513366f, 0.634594f, + -0.203073f, 0.478550f, 0.581526f, + -0.266772f, 0.642330f, 0.602061f, + -0.216961f, 0.564846f, 0.535435f, + -0.202210f, 0.525495f, 0.475944f, + -0.193888f, 0.467925f, 0.520606f, + -0.265837f, 0.757267f, 0.500933f, + -0.240306f, 0.653440f, 0.463215f, + -0.309239f, 0.776868f, 0.304726f, + -0.271009f, 0.683094f, 0.382018f, + -0.312111f, 0.671099f, 0.286687f, + -0.268791f, 0.624342f, 0.377231f, + -0.302457f, 0.533996f, 0.360289f, + -0.263656f, 0.529310f, 0.412564f, + -0.282311f, 0.415167f, 0.447666f, + -0.239201f, 0.442096f, 0.495604f, + -0.220043f, 0.569026f, 0.445877f, + -0.001263f, 0.395631f, 0.602029f, + -0.057345f, 0.442535f, 0.572224f, + -0.088927f, 0.506333f, 0.529106f, + -0.125738f, 0.535076f, 0.612913f, + -0.126251f, 0.577170f, 0.483159f, + -0.149594f, 0.611520f, 0.557731f, + -0.163188f, 0.660791f, 0.491080f, + -0.172482f, 0.663387f, 0.415416f, + -0.160464f, 0.591710f, 0.370659f, + -0.156445f, 0.536396f, 0.378302f, + -0.136496f, 0.444358f, 0.425226f, + -0.095564f, 0.373768f, 0.473659f, + -0.104146f, 0.315912f, 0.498104f, + -0.000496f, 0.384194f, 0.473817f, + -0.000183f, 0.297770f, 0.401486f, + -0.129042f, 0.270145f, 0.434495f, + 0.000100f, 0.272963f, 0.349138f, + -0.113060f, 0.236984f, 0.385554f, + 0.007260f, 0.016311f, -0.883396f, + 0.007865f, 0.122104f, -0.956137f, + -0.032842f, 0.115282f, -0.953252f, + -0.089115f, 0.108449f, -0.950317f, + -0.047440f, 0.014729f, -0.882756f, + -0.104458f, 0.013137f, -0.882070f, + -0.086439f, -0.584866f, -0.608343f, + -0.115026f, -0.662605f, -0.436732f, + -0.071683f, -0.665372f, -0.606385f, + -0.257884f, -0.665381f, -0.658052f, + -0.272542f, -0.665381f, -0.592063f, + -0.371322f, -0.665382f, -0.353620f, + -0.372362f, -0.665381f, -0.224420f, + -0.335166f, -0.665380f, -0.078623f, + -0.225999f, -0.665375f, -0.038981f, + -0.106719f, -0.665374f, -0.186351f, + -0.081749f, -0.665372f, -0.292554f, + 0.006943f, -0.091505f, -0.858354f, + 0.006117f, -0.280985f, -0.769967f, + 0.004495f, -0.502360f, -0.559799f, + -0.198638f, -0.302135f, -0.845816f, + -0.237395f, -0.542544f, -0.587188f, + -0.270001f, -0.279489f, -0.669861f, + -0.134547f, -0.119852f, -0.959004f, + -0.052088f, -0.122463f, -0.944549f, + -0.124463f, -0.293508f, -0.899566f, + -0.047616f, -0.289643f, -0.879292f, + -0.168595f, -0.529132f, -0.654931f, + -0.099793f, -0.515719f, -0.645873f, + -0.186168f, -0.605282f, -0.724690f, + -0.112970f, -0.583097f, -0.707469f, + -0.108152f, -0.665375f, -0.700408f, + -0.183019f, -0.665378f, -0.717630f, + -0.349529f, -0.334459f, -0.511985f, + -0.141182f, -0.437705f, -0.798194f, + -0.212670f, -0.448725f, -0.737447f, + -0.261111f, -0.414945f, -0.613835f, + -0.077364f, -0.431480f, -0.778113f, + 0.005174f, -0.425277f, -0.651592f, + 0.089236f, -0.431732f, -0.777093f, + 0.271006f, -0.415749f, -0.610577f, + 0.223981f, -0.449384f, -0.734774f, + 0.153275f, -0.438150f, -0.796391f, + 0.358414f, -0.335529f, -0.507649f, + 0.193434f, -0.665946f, -0.715325f, + 0.118363f, -0.665717f, -0.699021f, + 0.123515f, -0.583454f, -0.706020f, + 0.196851f, -0.605860f, -0.722345f, + 0.109788f, -0.516035f, -0.644590f, + 0.178656f, -0.529656f, -0.652804f, + 0.061157f, -0.289807f, -0.878626f, + 0.138234f, -0.293905f, -0.897958f, + 0.066933f, -0.122643f, -0.943820f, + 0.149571f, -0.120281f, -0.957264f, + 0.280989f, -0.280321f, -0.666487f, + 0.246581f, -0.543275f, -0.584224f, + 0.211720f, -0.302754f, -0.843303f, + 0.086966f, -0.665627f, -0.291520f, + 0.110634f, -0.665702f, -0.185021f, + 0.228099f, -0.666061f, -0.036201f, + 0.337743f, -0.666396f, -0.074503f, + 0.376722f, -0.666513f, -0.219833f, + 0.377265f, -0.666513f, -0.349036f, + 0.281411f, -0.666217f, -0.588670f, + 0.267564f, -0.666174f, -0.654834f, + 0.080745f, -0.665602f, -0.605452f, + 0.122016f, -0.662963f, -0.435280f, + 0.095767f, -0.585141f, -0.607228f, + 0.118944f, 0.012799f, -0.880702f, + 0.061944f, 0.014564f, -0.882086f, + 0.104725f, 0.108156f, -0.949130f, + 0.048513f, 0.115159f, -0.952753f, + 0.112696f, 0.236643f, 0.386937f, + 0.128177f, 0.269757f, 0.436071f, + 0.102643f, 0.315600f, 0.499370f, + 0.094535f, 0.373481f, 0.474824f, + 0.136270f, 0.443946f, 0.426895f, + 0.157071f, 0.535923f, 0.380222f, + 0.161350f, 0.591224f, 0.372630f, + 0.173035f, 0.662865f, 0.417531f, + 0.162808f, 0.660299f, 0.493077f, + 0.148250f, 0.611070f, 0.559555f, + 0.125719f, 0.576790f, 0.484702f, + 0.123489f, 0.534699f, 0.614440f, + 0.087621f, 0.506066f, 0.530188f, + 0.055321f, 0.442365f, 0.572915f, + 0.219936f, 0.568361f, 0.448571f, + 0.238099f, 0.441375f, 0.498528f, + 0.281711f, 0.414315f, 0.451121f, + 0.263833f, 0.528513f, 0.415794f, + 0.303284f, 0.533081f, 0.363998f, + 0.269687f, 0.623528f, 0.380528f, + 0.314255f, 0.670153f, 0.290524f, + 0.272023f, 0.682273f, 0.385343f, + 0.311480f, 0.775931f, 0.308527f, + 0.240239f, 0.652714f, 0.466159f, + 0.265619f, 0.756464f, 0.504187f, + 0.192562f, 0.467341f, 0.522972f, + 0.201605f, 0.524885f, 0.478417f, + 0.215743f, 0.564193f, 0.538084f, + 0.264969f, 0.641527f, 0.605317f, + 0.201031f, 0.477940f, 0.584002f, + 0.263086f, 0.512567f, 0.637832f, + 0.238615f, 0.526867f, 0.672237f, + 0.105309f, 0.455123f, 0.658482f, + 0.183993f, 0.102195f, 0.804872f, + 0.161563f, 0.060042f, 0.808692f, + 0.180748f, 0.077754f, 0.771600f, + 0.175168f, 0.128588f, 0.746368f, + 0.175075f, 0.148030f, 0.778264f, + 0.175658f, 0.139265f, 0.814333f, + 0.154191f, 0.067291f, 0.832578f, + 0.163818f, 0.109013f, 0.842830f, + 0.084760f, 0.396004f, 0.679695f, + 0.238888f, 0.310760f, 0.590775f, + 0.213380f, 0.308625f, 0.644905f, + 0.199666f, 0.409678f, 0.683003f, + 0.190143f, 0.128597f, 0.733463f, + 0.184833f, 0.063516f, 0.762902f, + 0.166070f, 0.035644f, 0.818261f, + 0.154361f, 0.056943f, 0.857042f, + 0.168542f, 0.109489f, 0.862725f, + 0.187387f, 0.166131f, 0.784599f, + 0.180428f, 0.160135f, 0.819438f, + 0.201823f, 0.163991f, 0.695756f, + 0.194206f, 0.206635f, 0.782275f, + 0.155438f, 0.291260f, 0.734412f, + 0.177696f, 0.196424f, 0.846693f, + 0.152305f, 0.125256f, 0.890786f, + 0.119546f, 0.249876f, 0.859104f, + 0.118369f, 0.139643f, 0.919173f, + 0.079410f, 0.132973f, 0.948652f, + 0.062419f, 0.036648f, 0.976547f, + 0.127847f, -0.035919f, 0.947070f, + 0.143624f, 0.032206f, 0.885913f, + 0.074888f, -0.085173f, 0.980577f, + 0.130184f, -0.104656f, 0.947620f, + 0.156201f, -0.094653f, 0.899074f, + 0.077366f, -0.171194f, 0.926545f, + 0.127722f, -0.164729f, 0.879810f, + 0.052670f, -0.184618f, 0.842019f, + 0.023477f, -0.184638f, 0.889811f, + 0.022626f, -0.210587f, 0.827500f, + 0.223089f, 0.211976f, 0.620493f, + 0.251444f, 0.113067f, 0.666494f, + 0.251419f, 0.089540f, 0.673887f, + 0.214360f, 0.019258f, 0.771595f, + 0.158999f, 0.001490f, 0.835374f, + 0.176696f, -0.059249f, 0.849218f, + 0.148696f, -0.130091f, 0.793599f, + 0.108290f, -0.166528f, 0.772088f, + 0.049820f, -0.201382f, 0.764454f, + 0.071341f, -0.215195f, 0.697209f, + 0.073148f, -0.214475f, 0.623510f, + 0.140502f, -0.169461f, 0.699354f, + 0.163374f, -0.157073f, 0.611416f, + 0.189466f, -0.138550f, 0.730366f, + 0.247593f, -0.082554f, 0.759610f, + 0.227468f, -0.121982f, 0.590197f, + 0.284702f, -0.006586f, 0.535347f, + 0.275741f, 0.125287f, 0.446676f, + 0.266650f, 0.192594f, 0.506044f, + 0.300086f, 0.053287f, 0.629620f, + 0.055450f, -0.663935f, 0.375065f, + 0.122854f, -0.664138f, 0.482323f, + 0.046520f, -0.531571f, 0.391918f, + 0.024824f, -0.568450f, 0.275106f, + 0.053855f, -0.663931f, 0.328224f, + 0.112829f, -0.453549f, 0.305788f, + 0.131265f, -0.510617f, 0.080746f, + 0.061174f, -0.430716f, -0.042710f, + 0.341019f, -0.532887f, -0.208150f, + 0.347705f, -0.623533f, -0.081139f, + 0.238040f, -0.610732f, -0.038037f, + 0.211764f, -0.514274f, -0.132078f, + 0.120605f, -0.600219f, -0.186856f, + 0.096985f, -0.584476f, -0.293357f, + 0.127621f, -0.581941f, -0.437170f, + 0.165902f, -0.477425f, -0.291453f, + 0.077720f, -0.417975f, -0.220519f, + 0.320892f, -0.506363f, -0.320874f, + 0.248214f, -0.465684f, -0.239842f, + 0.118764f, -0.383338f, -0.187114f, + 0.118816f, -0.430106f, -0.123307f, + 0.094131f, -0.419464f, -0.044777f, + 0.274526f, -0.261706f, 0.005110f, + 0.259842f, -0.283292f, -0.003185f, + 0.222861f, -0.340431f, -0.038210f, + 0.204445f, -0.664380f, 0.513353f, + 0.259286f, -0.664547f, 0.471281f, + 0.185402f, -0.476020f, 0.421718f, + 0.279163f, -0.664604f, 0.417328f, + 0.277157f, -0.528122f, 0.400208f, + 0.183069f, -0.509812f, 0.329995f, + 0.282599f, -0.429210f, 0.059242f, + 0.254816f, -0.664541f, 0.290687f, + 0.271436f, -0.567707f, 0.263966f, + 0.386561f, -0.625221f, -0.216870f, + 0.387086f, -0.630883f, -0.346073f, + 0.380021f, -0.596021f, -0.318679f, + 0.291269f, -0.619007f, -0.585707f, + 0.339280f, -0.571198f, -0.461946f, + 0.400045f, -0.489778f, -0.422640f, + 0.406817f, -0.314349f, -0.371230f, + 0.300588f, -0.281718f, -0.170549f, + 0.290866f, -0.277304f, -0.061905f, + 0.187735f, -0.241545f, 0.509437f, + 0.188032f, -0.287569f, 0.424234f, + 0.227520f, -0.373262f, 0.293102f, + 0.266526f, -0.273650f, 0.039597f, + 0.291592f, -0.291676f, 0.111386f, + 0.291914f, -0.122741f, 0.422683f, + 0.297574f, -0.156119f, 0.373368f, + 0.286603f, -0.232731f, 0.027162f, + 0.364663f, -0.201399f, 0.206850f, + 0.353855f, -0.132408f, 0.149228f, + 0.282208f, -0.019715f, 0.314960f, + 0.331187f, -0.099266f, 0.092701f, + 0.375463f, -0.093120f, -0.006467f, + 0.375917f, -0.101236f, -0.154882f, + 0.466635f, -0.094416f, -0.305669f, + 0.455805f, -0.119881f, -0.460632f, + 0.277465f, -0.604242f, -0.651871f, + 0.261022f, -0.551176f, -0.554667f, + 0.093627f, 0.258494f, -0.920589f, + 0.114248f, 0.310608f, -0.798070f, + 0.144232f, 0.211434f, -0.835001f, + 0.119916f, 0.176940f, -0.951159f, + 0.184061f, 0.101854f, -0.918220f, + 0.092431f, 0.276521f, -0.738231f, + 0.133504f, 0.218403f, -0.758602f, + 0.194987f, 0.097655f, -0.812476f, + 0.185542f, 0.011005f, -0.879202f, + 0.230315f, -0.127450f, -0.884202f, + 0.260471f, 0.255056f, -0.624378f, + 0.351567f, -0.042194f, -0.663976f, + 0.253742f, 0.323524f, -0.433716f, + 0.411612f, 0.132299f, -0.438264f, + 0.270513f, 0.356530f, -0.289984f, + 0.422146f, 0.162819f, -0.273130f, + 0.164724f, 0.237490f, 0.208912f, + 0.253806f, 0.092900f, 0.240640f, + 0.203608f, 0.284597f, 0.096223f, + 0.241006f, 0.343093f, -0.171396f, + 0.356076f, 0.149288f, -0.143443f, + 0.337656f, 0.131992f, 0.066374f +}; + +dTriIndex Indices[IndexCount / 3][3] = { + {126,134,133}, + {342,138,134}, + {133,134,138}, + {126,342,134}, + {312,316,317}, + {169,163,162}, + {312,317,319}, + {312,319,318}, + {169,162,164}, + {169,168,163}, + {312,314,315}, + {169,164,165}, + {169,167,168}, + {312,315,316}, + {312,313,314}, + {169,165,166}, + {169,166,167}, + {312,318,313}, + {308,304,305}, + {308,305,306}, + {179,181,188}, + {177,173,175}, + {177,175,176}, + {302,293,300}, + {322,294,304}, + {188,176,175}, + {188,175,179}, + {158,177,187}, + {305,293,302}, + {305,302,306}, + {322,304,308}, + {188,181,183}, + {158,173,177}, + {293,298,300}, + {304,294,296}, + {304,296,305}, + {185,176,188}, + {185,188,183}, + {187,177,176}, + {187,176,185}, + {305,296,298}, + {305,298,293}, + {436,432, 28}, + {436, 28, 23}, + {434,278,431}, + { 30,208,209}, + { 30,209, 29}, + { 19, 20, 24}, + {208,207,211}, + {208,211,209}, + { 19,210,212}, + {433,434,431}, + {433,431,432}, + {433,432,436}, + {436,437,433}, + {277,275,276}, + {277,276,278}, + {209,210, 25}, + { 21, 26, 24}, + { 21, 24, 20}, + { 25, 26, 27}, + { 25, 27, 29}, + {435,439,277}, + {439,275,277}, + {432,431, 30}, + {432, 30, 28}, + {433,437,438}, + {433,438,435}, + {434,277,278}, + { 24, 25,210}, + { 24, 26, 25}, + { 29, 27, 28}, + { 29, 28, 30}, + { 19, 24,210}, + {208, 30,431}, + {208,431,278}, + {435,434,433}, + {435,277,434}, + { 25, 29,209}, + { 27, 22, 23}, + { 27, 23, 28}, + { 26, 22, 27}, + { 26, 21, 22}, + {212,210,209}, + {212,209,211}, + {207,208,278}, + {207,278,276}, + {439,435,438}, + { 12, 9, 10}, + { 12, 10, 13}, + { 2, 3, 5}, + { 2, 5, 4}, + { 16, 13, 14}, + { 16, 14, 17}, + { 22, 21, 16}, + { 13, 10, 11}, + { 13, 11, 14}, + { 1, 0, 3}, + { 1, 3, 2}, + { 15, 12, 16}, + { 19, 18, 15}, + { 19, 15, 16}, + { 19, 16, 20}, + { 9, 1, 2}, + { 9, 2, 10}, + { 3, 7, 8}, + { 3, 8, 5}, + { 16, 17, 23}, + { 16, 23, 22}, + { 21, 20, 16}, + { 10, 2, 4}, + { 10, 4, 11}, + { 0, 6, 7}, + { 0, 7, 3}, + { 12, 13, 16}, + {451,446,445}, + {451,445,450}, + {442,440,439}, + {442,439,438}, + {442,438,441}, + {421,420,422}, + {412,411,426}, + {412,426,425}, + {408,405,407}, + {413, 67, 68}, + {413, 68,414}, + {391,390,412}, + { 80,384,386}, + {404,406,378}, + {390,391,377}, + {390,377, 88}, + {400,415,375}, + {398,396,395}, + {398,395,371}, + {398,371,370}, + {112,359,358}, + {112,358,113}, + {351,352,369}, + {125,349,348}, + {345,343,342}, + {342,340,339}, + {341,335,337}, + {328,341,327}, + {331,323,333}, + {331,322,323}, + {327,318,319}, + {327,319,328}, + {315,314,324}, + {302,300,301}, + {302,301,303}, + {320,311,292}, + {285,284,289}, + {310,307,288}, + {310,288,290}, + {321,350,281}, + {321,281,282}, + {423,448,367}, + {272,273,384}, + {272,384,274}, + {264,265,382}, + {264,382,383}, + {440,442,261}, + {440,261,263}, + {252,253,254}, + {252,254,251}, + {262,256,249}, + {262,249,248}, + {228,243,242}, + {228, 31,243}, + {213,215,238}, + {213,238,237}, + { 19,212,230}, + {224,225,233}, + {224,233,231}, + {217,218, 56}, + {217, 56, 54}, + {217,216,239}, + {217,239,238}, + {217,238,215}, + {218,217,215}, + {218,215,214}, + { 6,102,206}, + {186,199,200}, + {197,182,180}, + {170,171,157}, + {201,200,189}, + {170,190,191}, + {170,191,192}, + {175,174,178}, + {175,178,179}, + {168,167,155}, + {122,149,158}, + {122,158,159}, + {135,153,154}, + {135,154,118}, + {143,140,141}, + {143,141,144}, + {132,133,136}, + {130,126,133}, + {124,125,127}, + {122,101,100}, + {122,100,121}, + {110,108,107}, + {110,107,109}, + { 98, 99, 97}, + { 98, 97, 64}, + { 98, 64, 66}, + { 87, 55, 57}, + { 83, 82, 79}, + { 83, 79, 84}, + { 78, 74, 50}, + { 49, 71, 41}, + { 49, 41, 37}, + { 49, 37, 36}, + { 58, 44, 60}, + { 60, 59, 58}, + { 51, 34, 33}, + { 39, 40, 42}, + { 39, 42, 38}, + {243,240, 33}, + {243, 33,229}, + { 39, 38, 6}, + { 44, 46, 40}, + { 55, 56, 57}, + { 64, 62, 65}, + { 64, 65, 66}, + { 41, 71, 45}, + { 75, 50, 51}, + { 81, 79, 82}, + { 77, 88, 73}, + { 93, 92, 94}, + { 68, 47, 46}, + { 96, 97, 99}, + { 96, 99, 95}, + {110,109,111}, + {111,112,110}, + {114,113,123}, + {114,123,124}, + {132,131,129}, + {133,137,136}, + {135,142,145}, + {145,152,135}, + {149,147,157}, + {157,158,149}, + {164,150,151}, + {153,163,168}, + {153,168,154}, + {185,183,182}, + {185,182,184}, + {161,189,190}, + {200,199,191}, + {200,191,190}, + {180,178,195}, + {180,195,196}, + {102,101,204}, + {102,204,206}, + { 43, 48,104}, + { 43,104,103}, + {216,217, 54}, + {216, 54, 32}, + {207,224,231}, + {230,212,211}, + {230,211,231}, + {227,232,241}, + {227,241,242}, + {235,234,241}, + {235,241,244}, + {430,248,247}, + {272,274,253}, + {272,253,252}, + {439,260,275}, + {225,224,259}, + {225,259,257}, + {269,270,407}, + {269,407,405}, + {270,269,273}, + {270,273,272}, + {273,269,268}, + {273,268,267}, + {273,267,266}, + {273,266,265}, + {273,265,264}, + {448,279,367}, + {281,350,368}, + {285,286,301}, + {290,323,310}, + {290,311,323}, + {282,281,189}, + {292,311,290}, + {292,290,291}, + {307,306,302}, + {307,302,303}, + {316,315,324}, + {316,324,329}, + {331,351,350}, + {330,334,335}, + {330,335,328}, + {341,337,338}, + {344,355,354}, + {346,345,348}, + {346,348,347}, + {364,369,352}, + {364,352,353}, + {365,363,361}, + {365,361,362}, + {376,401,402}, + {373,372,397}, + {373,397,400}, + {376, 92,377}, + {381,378,387}, + {381,387,385}, + {386, 77, 80}, + {390,389,412}, + {416,417,401}, + {403,417,415}, + {408,429,430}, + {419,423,418}, + {427,428,444}, + {427,444,446}, + {437,436,441}, + {450,445, 11}, + {450, 11, 4}, + {447,449, 5}, + {447, 5, 8}, + {441,438,437}, + {425,426,451}, + {425,451,452}, + {417,421,415}, + {408,407,429}, + {399,403,400}, + {399,400,397}, + {394,393,416}, + {389,411,412}, + {386,383,385}, + {408,387,378}, + {408,378,406}, + {377,391,376}, + { 94,375,415}, + {372,373,374}, + {372,374,370}, + {359,111,360}, + {359,112,111}, + {113,358,349}, + {113,349,123}, + {346,343,345}, + {343,340,342}, + {338,336,144}, + {338,144,141}, + {327,341,354}, + {327,354,326}, + {331,350,321}, + {331,321,322}, + {314,313,326}, + {314,326,325}, + {300,298,299}, + {300,299,301}, + {288,287,289}, + {189,292,282}, + {287,288,303}, + {284,285,297}, + {368,280,281}, + {448,447,279}, + {274,226,255}, + {267,268,404}, + {267,404,379}, + {429,262,430}, + {439,440,260}, + {257,258,249}, + {257,249,246}, + {430,262,248}, + {234,228,242}, + {234,242,241}, + {237,238,239}, + {237,239,236}, + { 15, 18,227}, + { 15,227,229}, + {222,223, 82}, + {222, 82, 83}, + {214,215,213}, + {214,213, 81}, + { 38,102, 6}, + {122,159,200}, + {122,200,201}, + {174,171,192}, + {174,192,194}, + {197,193,198}, + {190,170,161}, + {181,179,178}, + {181,178,180}, + {166,156,155}, + {163,153,152}, + {163,152,162}, + {120,156,149}, + {120,149,121}, + {152,153,135}, + {140,143,142}, + {135,131,132}, + {135,132,136}, + {130,129,128}, + {130,128,127}, + {100,105,119}, + {100,119,120}, + {106,104,107}, + {106,107,108}, + { 91, 95, 59}, + { 93, 94, 68}, + { 91, 89, 92}, + { 76, 53, 55}, + { 76, 55, 87}, + { 81, 78, 79}, + { 74, 73, 49}, + { 69, 60, 45}, + { 58, 62, 64}, + { 58, 64, 61}, + { 53, 31, 32}, + { 32, 54, 53}, + { 42, 43, 38}, + { 35, 36, 0}, + { 35, 0, 1}, + { 34, 35, 1}, + { 34, 1, 9}, + { 44, 40, 41}, + { 44, 41, 45}, + { 33,240, 51}, + { 63, 62, 58}, + { 63, 58, 59}, + { 45, 71, 70}, + { 76, 75, 51}, + { 76, 51, 52}, + { 86, 85, 84}, + { 86, 84, 87}, + { 89, 72, 73}, + { 89, 73, 88}, + { 91, 92, 96}, + { 91, 96, 95}, + { 72, 91, 60}, + { 72, 60, 69}, + {104,106,105}, + {119,105,117}, + {119,117,118}, + {124,127,128}, + {117,116,129}, + {117,129,131}, + {118,117,131}, + {135,140,142}, + {146,150,152}, + {146,152,145}, + {149,122,121}, + {166,165,151}, + {166,151,156}, + {158,172,173}, + {161,160,189}, + {199,198,193}, + {199,193,191}, + {204,201,202}, + {178,174,194}, + {200,159,186}, + {109, 48, 67}, + { 48,107,104}, + {216, 32,236}, + {216,236,239}, + {223,214, 81}, + {223, 81, 82}, + { 33, 12, 15}, + { 32,228,234}, + { 32,234,236}, + {240, 31, 52}, + {256,255,246}, + {256,246,249}, + {258,263,248}, + {258,248,249}, + {275,260,259}, + {275,259,276}, + {207,276,259}, + {270,271,429}, + {270,429,407}, + {413,418,366}, + {413,366,365}, + {368,367,279}, + {368,279,280}, + {303,301,286}, + {303,286,287}, + {283,282,292}, + {283,292,291}, + {320,292,189}, + {298,296,297}, + {298,297,299}, + {318,327,326}, + {318,326,313}, + {329,330,317}, + {336,333,320}, + {326,354,353}, + {334,332,333}, + {334,333,336}, + {342,339,139}, + {342,139,138}, + {345,342,126}, + {347,357,356}, + {369,368,351}, + {363,356,357}, + {363,357,361}, + {366,367,368}, + {366,368,369}, + {375,373,400}, + { 92, 90,377}, + {409,387,408}, + {386,385,387}, + {386,387,388}, + {412,394,391}, + {396,398,399}, + {408,406,405}, + {415,421,419}, + {415,419,414}, + {425,452,448}, + {425,448,424}, + {444,441,443}, + {448,452,449}, + {448,449,447}, + {446,444,443}, + {446,443,445}, + {250,247,261}, + {250,261,428}, + {421,422,423}, + {421,423,419}, + {427,410,250}, + {417,403,401}, + {403,402,401}, + {420,392,412}, + {420,412,425}, + {420,425,424}, + {386,411,389}, + {383,382,381}, + {383,381,385}, + {378,379,404}, + {372,371,395}, + {372,395,397}, + {371,372,370}, + {361,359,360}, + {361,360,362}, + {368,350,351}, + {349,347,348}, + {356,355,344}, + {356,344,346}, + {344,341,340}, + {344,340,343}, + {338,337,336}, + {328,335,341}, + {324,352,351}, + {324,351,331}, + {320,144,336}, + {314,325,324}, + {322,308,309}, + {310,309,307}, + {287,286,289}, + {203,280,279}, + {203,279,205}, + {297,295,283}, + {297,283,284}, + {447,205,279}, + {274,384, 80}, + {274, 80,226}, + {266,267,379}, + {266,379,380}, + {225,257,246}, + {225,246,245}, + {256,254,253}, + {256,253,255}, + {430,247,250}, + {226,235,244}, + {226,244,245}, + {232,233,244}, + {232,244,241}, + {230, 18, 19}, + { 32, 31,228}, + {219,220, 86}, + {219, 86, 57}, + {226,213,235}, + {206, 7, 6}, + {122,201,101}, + {201,204,101}, + {180,196,197}, + {170,192,171}, + {200,190,189}, + {194,193,195}, + {183,181,180}, + {183,180,182}, + {155,154,168}, + {149,156,151}, + {149,151,148}, + {155,156,120}, + {145,142,143}, + {145,143,146}, + {136,137,140}, + {133,132,130}, + {128,129,116}, + {100,120,121}, + {110,112,113}, + {110,113,114}, + { 66, 65, 63}, + { 66, 63, 99}, + { 66, 99, 98}, + { 96, 46, 61}, + { 89, 88, 90}, + { 86, 87, 57}, + { 80, 78, 81}, + { 72, 69, 49}, + { 67, 48, 47}, + { 67, 47, 68}, + { 56, 55, 53}, + { 50, 49, 36}, + { 50, 36, 35}, + { 40, 39, 41}, + {242,243,229}, + {242,229,227}, + { 6, 37, 39}, + { 42, 47, 48}, + { 42, 48, 43}, + { 61, 46, 44}, + { 45, 70, 69}, + { 69, 70, 71}, + { 69, 71, 49}, + { 74, 78, 77}, + { 83, 84, 85}, + { 73, 74, 77}, + { 93, 96, 92}, + { 68, 46, 93}, + { 95, 99, 63}, + { 95, 63, 59}, + {115,108,110}, + {115,110,114}, + {125,126,127}, + {129,130,132}, + {137,133,138}, + {137,138,139}, + {148,146,143}, + {148,143,147}, + {119,118,154}, + {161,147,143}, + {165,164,151}, + {158,157,171}, + {158,171,172}, + {159,158,187}, + {159,187,186}, + {194,192,191}, + {194,191,193}, + {189,202,201}, + {182,197,184}, + {205, 8, 7}, + { 48,109,107}, + {218,219, 57}, + {218, 57, 56}, + {207,231,211}, + {232,230,231}, + {232,231,233}, + { 53, 52, 31}, + {388,411,386}, + {409,430,250}, + {262,429,254}, + {262,254,256}, + {442,444,428}, + {273,264,383}, + {273,383,384}, + {429,271,251}, + {429,251,254}, + {413,365,362}, + { 67,413,360}, + {282,283,295}, + {285,301,299}, + {202,281,280}, + {284,283,291}, + {284,291,289}, + {320,189,160}, + {308,306,307}, + {307,309,308}, + {319,317,330}, + {319,330,328}, + {353,352,324}, + {332,331,333}, + {340,341,338}, + {354,341,344}, + {349,358,357}, + {349,357,347}, + {364,355,356}, + {364,356,363}, + {364,365,366}, + {364,366,369}, + {374,376,402}, + {375, 92,373}, + { 77,389,390}, + {382,380,381}, + {389, 77,386}, + {393,394,412}, + {393,412,392}, + {401,394,416}, + {415,400,403}, + {411,410,427}, + {411,427,426}, + {422,420,424}, + {247,248,263}, + {247,263,261}, + {445,443, 14}, + {445, 14, 11}, + {449,450, 4}, + {449, 4, 5}, + {443,441, 17}, + {443, 17, 14}, + {436, 23, 17}, + {436, 17,441}, + {424,448,422}, + {448,423,422}, + {414,419,418}, + {414,418,413}, + {406,404,405}, + {399,397,395}, + {399,395,396}, + {420,416,392}, + {388,410,411}, + {386,384,383}, + {390, 88, 77}, + {375, 94, 92}, + {415,414, 68}, + {415, 68, 94}, + {370,374,402}, + {370,402,398}, + {361,357,358}, + {361,358,359}, + {125,348,126}, + {346,344,343}, + {340,338,339}, + {337,335,334}, + {337,334,336}, + {325,353,324}, + {324,331,332}, + {324,332,329}, + {323,322,309}, + {323,309,310}, + {294,295,297}, + {294,297,296}, + {289,286,285}, + {202,280,203}, + {288,307,303}, + {282,295,321}, + { 67,360,111}, + {418,423,367}, + {418,367,366}, + {272,252,251}, + {272,251,271}, + {272,271,270}, + {255,253,274}, + {265,266,380}, + {265,380,382}, + {442,428,261}, + {440,263,258}, + {440,258,260}, + {409,250,410}, + {255,226,245}, + {255,245,246}, + { 31,240,243}, + {236,234,235}, + {236,235,237}, + {233,225,245}, + {233,245,244}, + {220,221, 85}, + {220, 85, 86}, + { 81,213,226}, + { 81,226, 80}, + { 7,206,205}, + {186,184,198}, + {186,198,199}, + {204,203,205}, + {204,205,206}, + {195,193,196}, + {171,174,172}, + {173,174,175}, + {173,172,174}, + {155,167,166}, + {160,161,143}, + {160,143,144}, + {119,154,155}, + {148,151,150}, + {148,150,146}, + {140,137,139}, + {140,139,141}, + {127,126,130}, + {114,124,128}, + {114,128,115}, + {117,105,106}, + {117,106,116}, + {104,105,100}, + {104,100,103}, + { 59, 60, 91}, + { 97, 96, 61}, + { 97, 61, 64}, + { 91, 72, 89}, + { 87, 84, 79}, + { 87, 79, 76}, + { 78, 80, 77}, + { 49, 50, 74}, + { 60, 44, 45}, + { 61, 44, 58}, + { 51, 50, 35}, + { 51, 35, 34}, + { 39, 37, 41}, + { 33, 34, 9}, + { 33, 9, 12}, + { 0, 36, 37}, + { 0, 37, 6}, + { 40, 46, 47}, + { 40, 47, 42}, + { 53, 54, 56}, + { 65, 62, 63}, + { 72, 49, 73}, + { 79, 78, 75}, + { 79, 75, 76}, + { 52, 53, 76}, + { 92, 89, 90}, + { 96, 93, 46}, + {102,103,100}, + {102,100,101}, + {116,106,108}, + {116,108,115}, + {123,125,124}, + {116,115,128}, + {118,131,135}, + {140,135,136}, + {148,147,149}, + {120,119,155}, + {164,162,152}, + {164,152,150}, + {157,147,161}, + {157,161,170}, + {186,187,185}, + {186,185,184}, + {193,197,196}, + {202,203,204}, + {194,195,178}, + {198,184,197}, + { 67,111,109}, + { 38, 43,103}, + { 38,103,102}, + {214,223,222}, + {214,222,221}, + {214,221,220}, + {214,220,219}, + {214,219,218}, + {213,237,235}, + {221,222, 83}, + {221, 83, 85}, + { 15,229, 33}, + {227, 18,230}, + {227,230,232}, + { 52, 51,240}, + { 75, 78, 50}, + {408,430,409}, + {260,258,257}, + {260,257,259}, + {224,207,259}, + {268,269,405}, + {268,405,404}, + {413,362,360}, + {447, 8,205}, + {299,297,285}, + {189,281,202}, + {290,288,289}, + {290,289,291}, + {322,321,295}, + {322,295,294}, + {333,323,311}, + {333,311,320}, + {317,316,329}, + {320,160,144}, + {353,325,326}, + {329,332,334}, + {329,334,330}, + {339,338,141}, + {339,141,139}, + {348,345,126}, + {347,356,346}, + {123,349,125}, + {364,353,354}, + {364,354,355}, + {365,364,363}, + {376,391,394}, + {376,394,401}, + { 92,376,374}, + { 92,374,373}, + {377, 90, 88}, + {380,379,378}, + {380,378,381}, + {388,387,409}, + {388,409,410}, + {416,393,392}, + {399,398,402}, + {399,402,403}, + {250,428,427}, + {421,417,416}, + {421,416,420}, + {426,427,446}, + {426,446,451}, + {444,442,441}, + {452,451,450}, + {452,450,449} +}; + diff --git a/libs/ode-0.16.1/ode/demo/convex_bunny_geom.h b/libs/ode-0.16.1/ode/demo/convex_bunny_geom.h new file mode 100644 index 0000000..09fe6de --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/convex_bunny_geom.h @@ -0,0 +1,468 @@ +const unsigned int convexBunnyPlaneCount = 176; +dReal convexBunnyPlanes[] = +{ + 0.986167, -0.0612533, -0.154021, 0.399481, + 0.982735, -0.0691036, -0.171628, 0.409884, + -0.984387, -0.0582774, -0.166089, 0.403079, + 0.985044, -0.172279, 0.00302105, 0.437531, + 0.976915, -0.184361, 0.107929, 0.465334, + 0.951478, -0.281619, 0.124019, 0.475223, + 0.798136, -0.502214, 0.332805, 0.535555, + 0.949728, -0.211128, -0.231176, 0.528156, + -0.000894561, -0.995066, -0.0992088, 0.80299, + -0.000896015, -0.995066, -0.0992131, 0.802991, + -0.0035709, -0.935822, 0.352454, 0.618504, + -0.291551, -0.828515, 0.478081, 0.681579, + -0.978715, -0.181408, 0.0959605, 0.468907, + -0.985523, -0.169302, -0.00904739, 0.441129, + -0.953768, -0.278749, 0.11236, 0.478704, + 0.372745, -0.827499, 0.419888, 0.630174, + 0.976911, -0.18316, 0.109991, 0.466086, + 0.817827, -0.387738, 0.425227, 0.569153, + -0.978732, -0.180211, 0.0980152, 0.469656, + 0.662794, -0.0277654, 0.748287, 0.803459, + 0.00359857, -0.660581, -0.750746, 0.877267, + 0.00359952, -0.660579, -0.750748, 0.877266, + -0.947456, -0.208272, -0.242797, 0.531628, + -0.980764, -0.0661375, -0.18365, 0.413468, + -0.940835, -0.0698657, -0.331585, 0.494827, + 0.983751, 0.0529367, -0.171556, 0.403533, + 0.981839, 0.0996302, -0.16145, 0.410144, + 0.977938, 0.0857834, -0.190468, 0.411823, + 0.959636, 0.106068, -0.260476, 0.44898, + 0.85334, -0.0495414, -0.518996, 0.60489, + -0.803667, -0.499793, 0.322995, 0.538478, + -0.689742, -0.615484, 0.381361, 0.574754, + -0.380353, -0.826364, 0.415277, 0.63155, + -0.39985, -0.817283, 0.414933, 0.630682, + -0.380309, -0.826285, 0.415473, 0.631677, + -0.981411, 0.0559147, -0.183592, 0.407121, + -0.979526, 0.101914, -0.173615, 0.413635, + -0.975381, 0.0881975, -0.202119, 0.415257, + 0.988445, 0.140182, 0.0576755, 0.485174, + 0.876515, 0.0408992, 0.479634, 0.620093, + 0.848907, -0.0996824, 0.519057, 0.631268, + 0.895754, -0.195088, 0.399457, 0.563346, + 0.861448, -0.256989, 0.438023, 0.574909, + 0.775672, -0.447481, 0.445076, 0.586422, + 0.683157, -0.617557, 0.389768, 0.572247, + 0.391755, -0.818722, 0.419789, 0.629264, + 0.28317, -0.829384, 0.481599, 0.680529, + 0.3727, -0.827422, 0.420079, 0.630298, + -0.824143, -0.385255, 0.415171, 0.57215, + -0.782413, -0.445128, 0.435536, 0.589267, + 0.00152876, 0.999994, -0.00308275, 0.665646, + 0.00242466, 0.999989, -0.0038994, 0.665879, + -0.979892, 0.121321, -0.158406, 0.420287, + 0.767537, -0.190214, -0.612132, 0.695479, + 0.372649, -0.42747, -0.823652, 0.869878, + 0.537245, -0.335515, -0.77382, 0.82472, + 0.0263648, -0.598975, -0.800334, 0.873623, + 0.00393345, -0.60959, -0.792707, 0.869865, + -0.0183706, -0.598907, -0.800608, 0.873704, + 0.00875728, 0.676014, -0.736836, 0.825597, + 0.852333, -0.0355955, -0.521786, 0.607886, + 0.392036, 0.534934, -0.748434, 0.818042, + 0.847696, -0.122973, -0.516033, 0.615814, + 0.884763, -0.0760716, -0.45979, 0.565893, + 0.9446, -0.0727144, -0.320069, 0.491401, + 0.904971, -0.0675211, -0.420081, 0.541673, + -0.899959, -0.0647928, -0.431134, 0.544968, + -0.955972, 0.108494, -0.272667, 0.452769, + -0.363823, -0.426358, -0.828161, 0.871222, + -0.528689, -0.333936, -0.780368, 0.826685, + 0.982068, 0.118277, -0.146811, 0.416542, + 0.98951, 0.144455, 0.00164104, 0.468616, + 0.50797, -0.0708041, 0.85846, 0.883126, + 0.748614, -0.431275, 0.503565, 0.634026, + 0.214863, -0.405791, 0.888351, 0.94048, + -0.901162, -0.192379, 0.388455, 0.566627, + -0.867521, -0.254376, 0.427435, 0.578065, + -0.226957, -0.405135, 0.885639, 0.941284, + -0.756029, -0.429007, 0.494341, 0.636765, + -0.00629553, -0.188362, 0.982079, 0.968197, + 0.0165684, 0.999846, -0.00581961, 0.670373, + 0.00313267, 0.999987, -0.00405124, 0.666103, + 0.545069, 0.472158, -0.692796, 0.780052, + 0.932011, 0.148856, -0.330451, 0.498417, + 0.844043, 0.227673, -0.485547, 0.599903, + -0.019033, 0.999801, -0.00590978, 0.672252, + -0.959662, 0.239262, -0.147656, 0.488538, + 0.00151234, 0.999999, -0.000399466, 0.665855, + -0.988649, 0.143168, 0.0455675, 0.488784, + -0.989015, 0.147444, -0.01048, 0.472227, + -0.972439, 0.232727, -0.01415, 0.518344, + 0.587681, -0.160147, -0.793085, 0.823999, + 0.640479, -0.269179, -0.719256, 0.778142, + 0.541109, -0.332896, -0.772257, 0.823226, + 0.546185, -0.14771, -0.824538, 0.84854, + 0.528519, -0.026044, -0.848522, 0.873136, + 0.447231, -0.0756684, -0.891212, 0.903953, + 0.490619, -0.0795123, -0.867739, 0.884255, + 0.279393, 0.264257, -0.923097, 0.950045, + 0.374653, 0.39486, -0.83888, 0.886593, + 0.00050174, 0.999994, -0.00331563, 0.665976, + -0.0103777, 0.999934, -0.00487936, 0.669494, + -0.927571, 0.150741, -0.341889, 0.501807, + -0.267268, 0.265084, -0.926444, 0.951043, + -0.845984, -0.0330207, -0.532184, 0.610986, + -0.518165, -0.0244575, -0.854931, 0.875047, + -0.83753, 0.228953, -0.496108, 0.603116, + -0.535666, 0.472122, -0.700116, 0.78259, + -0.381083, 0.534649, -0.754272, 0.820328, + -0.363157, 0.395975, -0.843398, 0.88794, + -0.326829, -0.256634, -0.909572, 0.922946, + 0.394875, -0.128601, -0.90969, 0.920236, + 0.337169, -0.257642, -0.905504, 0.921733, + 0.398433, -0.193767, -0.896496, 0.910015, + -0.536477, -0.146072, -0.831177, 0.850523, + -0.436512, -0.0743406, -0.896622, 0.905564, + -0.480187, -0.0780522, -0.873687, 0.886029, + -0.384093, -0.127432, -0.914458, 0.921656, + -0.388009, -0.192572, -0.901313, 0.911451, + 0.977045, 0.15796, 0.14294, 0.521934, + 0.930035, 0.231515, 0.28537, 0.600301, + -0.855499, -0.0971121, 0.508616, 0.634376, + -0.875419, 0.136849, 0.463589, 0.62897, + -0.882196, 0.0435387, 0.468864, 0.623303, + 0.0204398, -0.0238739, 0.999506, 0.958419, + -0.0062197, -0.0777937, 0.99695, 0.962769, + 0.907123, 0.250746, 0.338015, 0.623205, + 0.902358, 0.173321, 0.394601, 0.607696, + 0.870085, 0.134211, 0.474278, 0.625782, + 0.0015108, 0.999999, 6.34978e-06, 0.665945, + 0.00150567, 0.999999, 0.000568537, 0.666143, + 0.00150738, 0.999999, 0.000565012, 0.666141, + -0.963954, 0.266039, -0.00405118, 0.539571, + 0.0015136, 0.999999, -0.000393102, 0.665856, + 0.00151117, 0.999999, 4.32104e-06, 0.665944, + 0.0272711, 0.999604, -0.00696439, 0.673709, + 0.962047, 0.236383, -0.136341, 0.484917, + 0.973236, 0.229796, -0.00223071, 0.514797, + 0.964728, 0.263133, 0.00776342, 0.536054, + -0.906596, 0.176056, 0.383521, 0.610999, + -0.978237, 0.160918, 0.130987, 0.525513, + -0.910434, 0.253486, 0.326887, 0.626522, + -0.932759, 0.234321, 0.27396, 0.603697, + 0.800621, -0.0921333, -0.592045, 0.665278, + 0.679569, -0.15358, -0.717356, 0.765121, + 0.684928, -0.199829, -0.700672, 0.756959, + -0.532604, -0.33128, -0.778837, 0.82519, + -0.578395, -0.158384, -0.800234, 0.826134, + -0.671209, -0.151537, -0.725613, 0.767576, + -0.00530287, 0.323551, 0.946196, 0.94547, + -0.719766, 0.229227, 0.655281, 0.774388, + -0.604194, 0.29171, 0.741522, 0.841564, + -0.544989, 0.302925, 0.781808, 0.866398, + -0.518662, -0.0692529, 0.85217, 0.884999, + -0.671987, -0.0257512, 0.740115, 0.805898, + -0.00613626, -0.00823685, 0.999947, 0.957141, + -0.032747, -0.0237908, 0.99918, 0.958516, + -0.00530611, 0.323546, 0.946198, 0.945471, + -0.545061, 0.302657, 0.781861, 0.866377, + -0.639902, 0.23832, 0.730568, 0.823722, + 0.00149706, 0.999997, 0.00193434, 0.667038, + 0.00149731, 0.999997, 0.00193252, 0.667037, + -0.0048341, 0.44008, 0.897946, 0.936327, + -0.00483143, 0.440078, 0.897947, 0.936327, + -0.632454, -0.267241, -0.727039, 0.780455, + -0.67691, -0.197765, -0.709, 0.759436, + -0.841667, -0.120432, -0.526396, 0.618913, + -0.760706, -0.187792, -0.621337, 0.698143, + -0.87929, -0.0734062, -0.470597, 0.569116, + -0.847068, -0.0469762, -0.529405, 0.607991, + -0.793572, -0.0897399, -0.601823, 0.668201, + 0.536355, 0.301024, 0.788485, 0.864403, + 0.536284, 0.301291, 0.788431, 0.864424, + 0.595945, 0.289897, 0.748872, 0.839373, + 0.631626, 0.236397, 0.738353, 0.8214, + 0.712378, 0.227061, 0.664049, 0.771772, +}; +const unsigned int convexBunnyPointCount = 105; +dReal convexBunnyPoints[] = +{ + -0.459488, -0.093017, -0.311341, + 0.466635, -0.094416, -0.305669, + -0.309239, 0.776868, 0.304726, + -0.004458, -0.042526, 1.01567, + 8.40779e-45, 3.00321e-39, 2.8026e-44, + 0.007957, 0.282241, -0.93168, + 0.204445, -0.66438, 0.513353, + -0.303961, 0.054199, 0.625921, + 0.265619, 0.756464, 0.504187, + -0.402162, 0.133528, -0.443247, + 8.40779e-45, 3.00321e-39, 2.8026e-44, + -0.266772, 0.64233, 0.602061, + 8.40779e-45, 3.00321e-39, 2.8026e-44, + 8.40779e-45, 3.00321e-39, 2.8026e-44, + 0.411612, 0.132299, -0.438264, + 0.31148, 0.775931, 0.308527, + 0.300086, 0.053287, 0.62962, + -0.414624, 0.164083, -0.278254, + -0.248382, 0.255825, -0.627493, + -0.216201, -0.126776, -0.886936, + 0.267564, -0.666174, -0.654834, + -0.135892, -0.03552, 0.945455, + -0.265837, 0.757267, 0.500933, + -0.003873, 0.161605, 0.970499, + 8.40779e-45, 3.00321e-39, 2.8026e-44, + -0.282599, -0.663393, 0.412411, + 0.007237, 0.361687, -0.794439, + 0.093627, 0.258494, -0.920589, + 0.422146, 0.162819, -0.27313, + 0.279163, -0.664604, 0.417328, + 0.263086, 0.512567, 0.637832, + -0.099875, 0.310931, -0.799381, + -0.446838, -0.118517, -0.466159, + -0.168842, 0.102387, -0.920381, + 0.455805, -0.119881, -0.460632, + 0.337743, -0.666396, -0.074503, + -0.134547, -0.119852, -0.959004, + -0.183807, 0.19697, 0.84448, + 0.264969, 0.641527, 0.605317, + -0.209063, -0.663393, 0.509344, + -0.364126, -0.200299, 0.202388, + -0.253475, -0.081797, 0.756541, + 0.260471, 0.255056, -0.624378, + 0.114248, 0.310608, -0.79807, + 0.364663, -0.201399, 0.20685, + 0.127847, -0.035919, 0.94707, + 8.40779e-45, 3.00321e-39, 2.8026e-44, + -0.381071, -0.629723, -0.350777, + -0.339884, -0.04115, -0.668211, + -0.077913, 0.258753, -0.92164, + 0.184061, 0.101854, -0.91822, + -0.335166, -0.66538, -0.078623, + 0.386561, -0.625221, -0.21687, + 8.40779e-45, 3.00321e-39, 2.8026e-44, + -0.241585, 0.527592, 0.669296, + -0.086969, 0.133224, 0.947633, + -0.003127, 0.28407, 0.87887, + -0.004433, -0.146642, 0.985872, + 8.40779e-45, 3.00321e-39, 2.8026e-44, + -0.138444, -0.10425, 0.945975, + -0.265676, 0.513366, 0.634594, + 8.40779e-45, 3.00321e-39, 2.8026e-44, + 0.247593, -0.082554, 0.75961, + 0.07941, 0.132973, 0.948652, + 0.238615, 0.526867, 0.672237, + 8.40779e-45, 3.00321e-39, 2.8026e-44, + 8.40779e-45, 3.00321e-39, 2.8026e-44, + -0.382112, -0.62406, -0.221577, + -0.104072, 0.177278, -0.95253, + 0.351567, -0.042194, -0.663976, + 0.138234, -0.293905, -0.897958, + 0.119916, 0.17694, -0.951159, + -0.371322, -0.665382, -0.35362, + -0.263384, -0.663396, 0.466604, + 0.376722, -0.666513, -0.219833, + 0.387086, -0.630883, -0.346073, + -0.125544, 0.140012, 0.917678, + -0.070612, 0.036849, 0.975733, + -0.083497, -0.084934, 0.979607, + 0.259286, -0.664547, 0.471281, + 8.40779e-45, 3.00321e-39, 2.8026e-44, + 0.074888, -0.085173, 0.980577, + 0.152305, 0.125256, 0.890786, + 0.130184, -0.104656, 0.94762, + -0.004249, 0.046042, 1.00324, + 0.062419, 0.036648, 0.976547, + 8.40779e-45, 3.00321e-39, 2.8026e-44, + -0.392666, -0.488581, -0.427494, + 0.230315, -0.12745, -0.884202, + 8.40779e-45, 3.00321e-39, 2.8026e-44, + 0.193434, -0.665946, -0.715325, + 0.007865, 0.122104, -0.956137, + 8.40779e-45, 3.00321e-39, 2.8026e-44, + -0.257884, -0.665381, -0.658052, + 0.377265, -0.666513, -0.349036, + -0.372362, -0.665381, -0.22442, + 0.400045, -0.489778, -0.42264, + -0.159174, 0.125726, 0.888878, + 0.118369, 0.139643, 0.919173, + -0.124463, -0.293508, -0.899566, + 0.21172, -0.302754, -0.843303, + 0.149571, -0.120281, -0.957264, + -0.183019, -0.665378, -0.71763, + 0.177696, 0.196424, 0.846693, + -0.198638, -0.302135, -0.845816, +}; +unsigned int convexBunnyPolygons[] = +{ + 3, 7, 2, 0, + 3, 2, 7, 11, + 3, 1, 15, 16, + 3, 0, 2, 17, + 3, 17, 9, 0, + 3, 2, 9, 17, + 3, 18, 9, 2, + 3, 2, 11, 22, + 3, 22, 15, 2, + 3, 8, 15, 22, + 3, 2, 15, 26, + 3, 5, 26, 27, + 3, 1, 14, 28, + 3, 28, 15, 1, + 3, 14, 15, 28, + 3, 2, 26, 31, + 3, 0, 9, 32, + 3, 9, 18, 33, + 3, 34, 14, 1, + 3, 19, 33, 36, + 3, 8, 22, 38, + 3, 38, 22, 11, + 3, 38, 15, 8, + 3, 38, 16, 15, + 3, 38, 30, 16, + 3, 40, 7, 0, + 3, 0, 25, 40, + 3, 40, 25, 7, + 3, 7, 25, 41, + 3, 21, 37, 41, + 3, 42, 15, 14, + 3, 42, 27, 15, + 3, 43, 26, 15, + 3, 15, 27, 43, + 3, 43, 27, 26, + 3, 1, 16, 44, + 3, 44, 29, 1, + 3, 16, 29, 44, + 3, 0, 32, 47, + 3, 19, 32, 48, + 3, 48, 33, 19, + 3, 48, 32, 9, + 3, 9, 33, 48, + 3, 49, 33, 18, + 3, 49, 18, 2, + 3, 2, 31, 49, + 3, 49, 26, 5, + 3, 49, 31, 26, + 3, 50, 42, 14, + 3, 27, 42, 50, + 3, 51, 35, 6, + 3, 6, 39, 51, + 3, 1, 29, 52, + 3, 11, 37, 54, + 3, 55, 23, 11, + 3, 11, 54, 55, + 3, 11, 23, 56, + 3, 56, 38, 11, + 3, 23, 38, 56, + 3, 57, 39, 6, + 3, 21, 41, 59, + 3, 39, 57, 59, + 3, 60, 37, 11, + 3, 60, 41, 37, + 3, 60, 11, 7, + 3, 7, 41, 60, + 3, 16, 30, 62, + 3, 62, 29, 16, + 3, 63, 38, 23, + 3, 38, 63, 64, + 3, 67, 25, 0, + 3, 0, 47, 67, + 3, 68, 36, 33, + 3, 33, 49, 68, + 3, 68, 49, 5, + 3, 14, 34, 69, + 3, 69, 50, 14, + 3, 5, 27, 71, + 3, 27, 50, 71, + 3, 71, 68, 5, + 3, 25, 51, 73, + 3, 73, 51, 39, + 3, 39, 59, 73, + 3, 73, 41, 25, + 3, 73, 59, 41, + 3, 29, 35, 74, + 3, 74, 52, 29, + 3, 35, 51, 74, + 3, 75, 34, 1, + 3, 1, 52, 75, + 3, 52, 74, 75, + 3, 21, 55, 76, + 3, 76, 54, 37, + 3, 76, 55, 54, + 3, 77, 55, 21, + 3, 21, 59, 78, + 3, 3, 77, 78, + 3, 78, 77, 21, + 3, 78, 57, 3, + 3, 78, 59, 57, + 3, 6, 35, 79, + 3, 79, 35, 29, + 3, 29, 62, 79, + 3, 3, 57, 81, + 3, 83, 62, 45, + 3, 45, 81, 83, + 3, 83, 79, 62, + 3, 6, 79, 83, + 3, 83, 57, 6, + 3, 83, 81, 57, + 3, 84, 63, 23, + 3, 84, 77, 3, + 3, 23, 55, 84, + 3, 55, 77, 84, + 3, 45, 63, 85, + 3, 3, 81, 85, + 3, 85, 81, 45, + 3, 85, 84, 3, + 3, 63, 84, 85, + 3, 87, 47, 32, + 3, 87, 72, 47, + 3, 50, 69, 88, + 3, 88, 34, 20, + 3, 88, 69, 34, + 3, 36, 68, 91, + 3, 68, 71, 91, + 3, 72, 87, 93, + 3, 93, 87, 32, + 3, 93, 32, 19, + 3, 94, 74, 72, + 3, 94, 93, 20, + 3, 72, 93, 94, + 3, 94, 75, 74, + 3, 95, 74, 51, + 3, 72, 74, 95, + 3, 95, 51, 25, + 3, 25, 67, 95, + 3, 95, 67, 47, + 3, 47, 72, 95, + 3, 20, 34, 96, + 3, 34, 75, 96, + 3, 96, 94, 20, + 3, 75, 94, 96, + 3, 97, 37, 21, + 3, 21, 76, 97, + 3, 97, 76, 37, + 3, 98, 64, 63, + 3, 98, 63, 45, + 3, 45, 82, 98, + 3, 36, 70, 99, + 3, 100, 88, 20, + 3, 20, 90, 100, + 3, 100, 90, 70, + 3, 101, 71, 50, + 3, 50, 88, 101, + 3, 36, 91, 101, + 3, 101, 91, 71, + 3, 101, 70, 36, + 3, 101, 100, 70, + 3, 88, 100, 101, + 3, 102, 90, 20, + 3, 20, 93, 102, + 3, 70, 90, 102, + 3, 102, 99, 70, + 3, 64, 98, 103, + 3, 103, 98, 82, + 3, 30, 38, 103, + 3, 38, 64, 103, + 3, 103, 62, 30, + 3, 45, 62, 103, + 3, 103, 82, 45, + 3, 36, 99, 104, + 3, 99, 102, 104, + 3, 104, 102, 93, + 3, 19, 36, 104, + 3, 104, 93, 19, +}; diff --git a/libs/ode-0.16.1/ode/demo/convex_prism.h b/libs/ode-0.16.1/ode/demo/convex_prism.h new file mode 100644 index 0000000..1ee7fcb --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/convex_prism.h @@ -0,0 +1,28 @@ +unsigned int prism_pointcount = 8;
+unsigned int prism_planecount = 6;
+dReal prism_points[24]={
+ 10.0, 1.0,-1.0,
+ 10.0,-1.0,-1.0,
+-10.0,-1.0,-1.0,
+-10.0, 1.0,-1.0,
+ 10.0, 1.0, 1.0,
+ 10.0,-1.0, 1.0,
+-10.0,-1.0, 1.0,
+-10.0, 1.0, 1.0
+};
+unsigned int prism_polygons[]={
+4,0,1,2,3,
+4,4,7,6,5,
+4,0,4,5,1,
+4,1,5,6,2,
+4,2,6,7,3,
+4,4,0,3,7,
+};
+dReal prism_planes[]={
+0.0,0.0,-1.0,1.0,
+0.0,0.0,1.0,1.0,
+1.0,0.0,0.0,10.0,
+0.0,-1.0,0.0,1.0,
+-1.0,0.0,-0.0,10.0,
+0.0,1.0,0.0,1.0,
+};
diff --git a/libs/ode-0.16.1/ode/demo/demo_I.cpp b/libs/ode-0.16.1/ode/demo/demo_I.cpp new file mode 100644 index 0000000..156a4ad --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_I.cpp @@ -0,0 +1,253 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +test that the rotational physics is correct. + +an "anchor body" has a number of other randomly positioned bodies +("particles") attached to it by ball-and-socket joints, giving it some +random effective inertia tensor. the effective inertia matrix is calculated, +and then this inertia is assigned to another "test" body. a random torque is +applied to both bodies and the difference in angular velocity and orientation +is observed after a number of iterations. + +typical errors for each test cycle are about 1e-5 ... 1e-4. + +*/ + + +#include <time.h> +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + +// select correct drawing functions + +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#define dsDrawSphere dsDrawSphereD +#define dsDrawCylinder dsDrawCylinderD +#define dsDrawCapsule dsDrawCapsuleD +#endif + + +// some constants + +#define NUM 10 // number of particles +#define SIDE 0.1 // visual size of the particles + + +// dynamics objects an globals + +static dWorldID world=0; +static dBodyID anchor_body,particle[NUM],test_body; +static dJointID particle_joint[NUM]; +static dReal torque[3]; +static int iteration; + + +// start simulation - set viewpoint + +static void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + static float xyz[3] = {1.5572f,-1.8886f,1.5700f}; + static float hpr[3] = {118.5000f,-17.0000f,0.0000f}; + dsSetViewpoint (xyz,hpr); +} + + +// compute the mass parameters of a particle set. q = particle positions, +// pm = particle masses + +#define _I(i,j) I[(i)*4+(j)] + +void computeMassParams (dMass *m, dReal q[NUM][3], dReal pm[NUM]) +{ + int i,j; + dMassSetZero (m); + for (i=0; i<NUM; i++) { + m->mass += pm[i]; + for (j=0; j<3; j++) m->c[j] += pm[i]*q[i][j]; + m->_I(0,0) += pm[i]*(q[i][1]*q[i][1] + q[i][2]*q[i][2]); + m->_I(1,1) += pm[i]*(q[i][0]*q[i][0] + q[i][2]*q[i][2]); + m->_I(2,2) += pm[i]*(q[i][0]*q[i][0] + q[i][1]*q[i][1]); + m->_I(0,1) -= pm[i]*(q[i][0]*q[i][1]); + m->_I(0,2) -= pm[i]*(q[i][0]*q[i][2]); + m->_I(1,2) -= pm[i]*(q[i][1]*q[i][2]); + } + for (j=0; j<3; j++) m->c[j] /= m->mass; + m->_I(1,0) = m->_I(0,1); + m->_I(2,0) = m->_I(0,2); + m->_I(2,1) = m->_I(1,2); +} + + +void reset_test() +{ + int i; + dMass m,anchor_m; + dReal q[NUM][3], pm[NUM]; // particle positions and masses + dReal pos1[3] = {1,0,1}; // point of reference (POR) + dReal pos2[3] = {-1,0,1}; // point of reference (POR) + + // make random particle positions (relative to POR) and masses + for (i=0; i<NUM; i++) { + pm[i] = dRandReal()+0.1; + q[i][0] = dRandReal()-0.5; + q[i][1] = dRandReal()-0.5; + q[i][2] = dRandReal()-0.5; + } + + // adjust particle positions so centor of mass = POR + computeMassParams (&m,q,pm); + for (i=0; i<NUM; i++) { + q[i][0] -= m.c[0]; + q[i][1] -= m.c[1]; + q[i][2] -= m.c[2]; + } + + if (world) dWorldDestroy (world); + world = dWorldCreate(); + + anchor_body = dBodyCreate (world); + dBodySetPosition (anchor_body,pos1[0],pos1[1],pos1[2]); + dMassSetBox (&anchor_m,1,SIDE,SIDE,SIDE); + dMassAdjust (&anchor_m,0.1); + dBodySetMass (anchor_body,&anchor_m); + + for (i=0; i<NUM; i++) { + particle[i] = dBodyCreate (world); + dBodySetPosition (particle[i], + pos1[0]+q[i][0],pos1[1]+q[i][1],pos1[2]+q[i][2]); + dMassSetBox (&m,1,SIDE,SIDE,SIDE); + dMassAdjust (&m,pm[i]); + dBodySetMass (particle[i],&m); + } + + for (i=0; i < NUM; i++) { + particle_joint[i] = dJointCreateBall (world,0); + dJointAttach (particle_joint[i],anchor_body,particle[i]); + const dReal *p = dBodyGetPosition (particle[i]); + dJointSetBallAnchor (particle_joint[i],p[0],p[1],p[2]); + } + + // make test_body with the same mass and inertia of the anchor_body plus + // all the particles + + test_body = dBodyCreate (world); + dBodySetPosition (test_body,pos2[0],pos2[1],pos2[2]); + computeMassParams (&m,q,pm); + m.mass += anchor_m.mass; + for (i=0; i<12; i++) m.I[i] = m.I[i] + anchor_m.I[i]; + dBodySetMass (test_body,&m); + + // rotate the test and anchor bodies by a random amount + dQuaternion qrot; + for (i=0; i<4; i++) qrot[i] = dRandReal()-0.5; + dNormalize4 (qrot); + dBodySetQuaternion (anchor_body,qrot); + dBodySetQuaternion (test_body,qrot); + dMatrix3 R; + dQtoR (qrot,R); + for (i=0; i<NUM; i++) { + dVector3 v; + dMultiply0 (v,R,&q[i][0],3,3,1); + dBodySetPosition (particle[i],pos1[0]+v[0],pos1[1]+v[1],pos1[2]+v[2]); + } + + // set random torque + for (i=0; i<3; i++) torque[i] = (dRandReal()-0.5) * 0.1; + + + iteration=0; +} + + +// simulation loop + +static void simLoop (int pause) +{ + if (!pause) { + dBodyAddTorque (anchor_body,torque[0],torque[1],torque[2]); + dBodyAddTorque (test_body,torque[0],torque[1],torque[2]); + dWorldStep (world,0.03); + + iteration++; + if (iteration >= 100) { + // measure the difference between the anchor and test bodies + const dReal *w1 = dBodyGetAngularVel (anchor_body); + const dReal *w2 = dBodyGetAngularVel (test_body); + const dReal *q1 = dBodyGetQuaternion (anchor_body); + const dReal *q2 = dBodyGetQuaternion (test_body); + dReal maxdiff = dMaxDifference (w1,w2,1,3); + printf ("w-error = %.4e (%.2f,%.2f,%.2f) and (%.2f,%.2f,%.2f)\n", + maxdiff,w1[0],w1[1],w1[2],w2[0],w2[1],w2[2]); + maxdiff = dMaxDifference (q1,q2,1,4); + printf ("q-error = %.4e\n",maxdiff); + reset_test(); + } + } + + dReal sides[3] = {SIDE,SIDE,SIDE}; + dReal sides2[3] = {6*SIDE,6*SIDE,6*SIDE}; + dReal sides3[3] = {3*SIDE,3*SIDE,3*SIDE}; + dsSetColor (1,1,1); + dsDrawBox (dBodyGetPosition(anchor_body), dBodyGetRotation(anchor_body), + sides3); + dsSetColor (1,0,0); + dsDrawBox (dBodyGetPosition(test_body), dBodyGetRotation(test_body), sides2); + dsSetColor (1,1,0); + for (int i=0; i<NUM; i++) + dsDrawBox (dBodyGetPosition (particle[i]), + dBodyGetRotation (particle[i]), sides); +} + + +int main (int argc, char **argv) +{ + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = 0; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + dInitODE2(0); + dRandSetSeed (time(0)); + reset_test(); + + // run simulation + dsSimulationLoop (argc,argv,352,288,&fn); + + dWorldDestroy (world); + dCloseODE(); + return 0; +} diff --git a/libs/ode-0.16.1/ode/demo/demo_basket.cpp b/libs/ode-0.16.1/ode/demo/demo_basket.cpp new file mode 100644 index 0000000..ab6a5c8 --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_basket.cpp @@ -0,0 +1,276 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// Basket ball demo. +// Serves as a test for the sphere vs trimesh collider +// By Bram Stolk. +// Press the spacebar to reset the position of the ball. + +#include <assert.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" +#include "basket_geom.h" // this is our world mesh + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + +// some constants + +#define RADIUS 0.14 + +// dynamics and collision objects (chassis, 3 wheels, environment) + +static dWorldID world; +static dSpaceID space; + +static dBodyID sphbody; +static dGeomID sphgeom; + +static dJointGroupID contactgroup; +static dGeomID world_mesh; + + +// this is called by dSpaceCollide when two objects in space are +// potentially colliding. + +static void nearCallback (void *data, dGeomID o1, dGeomID o2) +{ + assert(o1); + assert(o2); + + if (dGeomIsSpace(o1) || dGeomIsSpace(o2)) + { + fprintf(stderr,"testing space %p %p\n", (void*)o1, (void*)o2); + // colliding a space with something + dSpaceCollide2(o1,o2,data,&nearCallback); + // Note we do not want to test intersections within a space, + // only between spaces. + return; + } + +// fprintf(stderr,"testing geoms %p %p\n", o1, o2); + + const int N = 32; + dContact contact[N]; + int n = dCollide (o1,o2,N,&(contact[0].geom),sizeof(dContact)); + if (n > 0) + { + for (int i=0; i<n; i++) + { + // Paranoia <-- not working for some people, temporarily removed for 0.6 + //dIASSERT(dVALIDVEC3(contact[i].geom.pos)); + //dIASSERT(dVALIDVEC3(contact[i].geom.normal)); + //dIASSERT(!dIsNan(contact[i].geom.depth)); + contact[i].surface.slip1 = 0.7; + contact[i].surface.slip2 = 0.7; + contact[i].surface.mode = dContactSoftERP | dContactSoftCFM | dContactApprox1 | dContactSlip1 | dContactSlip2; + contact[i].surface.mu = 50.0; // was: dInfinity + contact[i].surface.soft_erp = 0.96; + contact[i].surface.soft_cfm = 0.04; + dJointID c = dJointCreateContact (world,contactgroup,&contact[i]); + dJointAttach (c, + dGeomGetBody(contact[i].geom.g1), + dGeomGetBody(contact[i].geom.g2)); + } + } +} + + +// start simulation - set viewpoint + +static void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + static float xyz[3] = {-8,0,5}; + static float hpr[3] = {0.0f,-29.5000f,0.0000f}; + dsSetViewpoint (xyz,hpr); +} + + + +static void reset_ball(void) +{ + float sx=0.0f, sy=3.40f, sz=7.15; + + dQuaternion q; + dQSetIdentity(q); + dBodySetPosition (sphbody, sx, sy, sz); + dBodySetQuaternion(sphbody, q); + dBodySetLinearVel (sphbody, 0,0,0); + dBodySetAngularVel (sphbody, 0,0,0); +} + + +// called when a key pressed + +static void command (int cmd) +{ + switch (cmd) + { + case ' ': + reset_ball(); + break; + } +} + + +// simulation loop + +static void simLoop (int pause) +{ + double simstep = 0.001; // 1ms simulation steps + double dt = dsElapsedTime(); + + int nrofsteps = (int) ceilf(dt/simstep); +// fprintf(stderr, "dt=%f, nr of steps = %d\n", dt, nrofsteps); + + for (int i=0; i<nrofsteps && !pause; i++) + { + dSpaceCollide (space,0,&nearCallback); + dWorldQuickStep (world, simstep); + dJointGroupEmpty (contactgroup); + } + + dsSetColor (1,1,1); + const dReal *SPos = dBodyGetPosition(sphbody); + const dReal *SRot = dBodyGetRotation(sphbody); + float spos[3] = {SPos[0], SPos[1], SPos[2]}; + float srot[12] = { SRot[0], SRot[1], SRot[2], SRot[3], SRot[4], SRot[5], SRot[6], SRot[7], SRot[8], SRot[9], SRot[10], SRot[11] }; + dsDrawSphere + ( + spos, + srot, + RADIUS + ); + + // draw world trimesh + dsSetColor(0.4,0.7,0.9); + dsSetTexture (DS_NONE); + + const dReal* Pos = dGeomGetPosition(world_mesh); + //dIASSERT(dVALIDVEC3(Pos)); + float pos[3] = { Pos[0], Pos[1], Pos[2] }; + + const dReal* Rot = dGeomGetRotation(world_mesh); + //dIASSERT(dVALIDMAT3(Rot)); + float rot[12] = { Rot[0], Rot[1], Rot[2], Rot[3], Rot[4], Rot[5], Rot[6], Rot[7], Rot[8], Rot[9], Rot[10], Rot[11] }; + + int numi = sizeof(world_indices) / sizeof(dTriIndex); + + for (int i=0; i<numi/3; i++) + { + int i0 = world_indices[i*3+0]; + int i1 = world_indices[i*3+1]; + int i2 = world_indices[i*3+2]; + float *v0 = world_vertices+i0*3; + float *v1 = world_vertices+i1*3; + float *v2 = world_vertices+i2*3; + dsDrawTriangle(pos, rot, v0,v1,v2, true); // single precision draw + } +} + + +int main (int argc, char **argv) +{ + dMass m; + dMatrix3 R; + + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + // create world + dInitODE2(0); + world = dWorldCreate(); + space = dHashSpaceCreate (0); + + contactgroup = dJointGroupCreate (0); + dWorldSetGravity (world,0,0,-9.8); + dWorldSetQuickStepNumIterations (world, 64); + + // Create a static world using a triangle mesh that we can collide with. + int numv = sizeof(world_vertices)/(3*sizeof(float)); + int numi = sizeof(world_indices)/ sizeof(dTriIndex); + printf("numv=%d, numi=%d\n", numv, numi); + dTriMeshDataID Data = dGeomTriMeshDataCreate(); + +// fprintf(stderr,"Building Single Precision Mesh\n"); + + dGeomTriMeshDataBuildSingle + ( + Data, + world_vertices, + 3 * sizeof(float), + numv, + world_indices, + numi, + 3 * sizeof(dTriIndex) + ); + + world_mesh = dCreateTriMesh(space, Data, 0, 0, 0); + dGeomTriMeshEnableTC(world_mesh, dSphereClass, false); + dGeomTriMeshEnableTC(world_mesh, dBoxClass, false); + dGeomSetPosition(world_mesh, 0, 0, 0.5); + dRSetIdentity(R); + //dIASSERT(dVALIDMAT3(R)); + + dGeomSetRotation (world_mesh, R); + + //float sx=0.0, sy=3.40, sz=6.80; + (void)world_normals; // get rid of compiler warning + sphbody = dBodyCreate (world); + dMassSetSphere (&m,1,RADIUS); + dBodySetMass (sphbody,&m); + sphgeom = dCreateSphere(0, RADIUS); + dGeomSetBody (sphgeom,sphbody); + reset_ball(); + dSpaceAdd (space, sphgeom); + + // run simulation + dsSimulationLoop (argc,argv,352,288,&fn); + + // Causes segm violation? Why? + // (because dWorldDestroy() destroys body connected to geom; must call first!) + dGeomDestroy(sphgeom); + dGeomDestroy (world_mesh); + + dJointGroupEmpty (contactgroup); + dJointGroupDestroy (contactgroup); + dSpaceDestroy (space); + dWorldDestroy (world); + dCloseODE(); + return 0; +} + + + diff --git a/libs/ode-0.16.1/ode/demo/demo_boxstack.cpp b/libs/ode-0.16.1/ode/demo/demo_boxstack.cpp new file mode 100644 index 0000000..ac46fcf --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_boxstack.cpp @@ -0,0 +1,619 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + +#include "icosahedron_geom.h" + + +//<---- Convex Object +dReal planes[]= // planes for a cube, these should coincide with the face array + { + 1.0f ,0.0f ,0.0f ,0.25f, + 0.0f ,1.0f ,0.0f ,0.25f, + 0.0f ,0.0f ,1.0f ,0.25f, + -1.0f,0.0f ,0.0f ,0.25f, + 0.0f ,-1.0f,0.0f ,0.25f, + 0.0f ,0.0f ,-1.0f,0.25f + /* + 1.0f ,0.0f ,0.0f ,2.0f, + 0.0f ,1.0f ,0.0f ,1.0f, + 0.0f ,0.0f ,1.0f ,1.0f, + 0.0f ,0.0f ,-1.0f,1.0f, + 0.0f ,-1.0f,0.0f ,1.0f, + -1.0f,0.0f ,0.0f ,0.0f + */ + }; +const unsigned int planecount=6; + +dReal points[]= // points for a cube + { + 0.25f,0.25f,0.25f, // point 0 + -0.25f,0.25f,0.25f, // point 1 + + 0.25f,-0.25f,0.25f, // point 2 + -0.25f,-0.25f,0.25f,// point 3 + + 0.25f,0.25f,-0.25f, // point 4 + -0.25f,0.25f,-0.25f,// point 5 + + 0.25f,-0.25f,-0.25f,// point 6 + -0.25f,-0.25f,-0.25f,// point 7 + }; +const unsigned int pointcount=8; +unsigned int polygons[] = //Polygons for a cube (6 squares) + { + 4,0,2,6,4, // positive X + 4,1,0,4,5, // positive Y + 4,0,1,3,2, // positive Z + 4,3,1,5,7, // negative X + 4,2,3,7,6, // negative Y + 4,5,4,6,7, // negative Z + }; +//----> Convex Object + +// select correct drawing functions + +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#define dsDrawSphere dsDrawSphereD +#define dsDrawCylinder dsDrawCylinderD +#define dsDrawCapsule dsDrawCapsuleD +#define dsDrawConvex dsDrawConvexD +#endif + + +// some constants + +#define NUM 100 // max number of objects +#define DENSITY (5.0) // density of all objects +#define GPB 3 // maximum number of geometries per body +#define MAX_CONTACTS 8 // maximum number of contact points per body +#define MAX_FEEDBACKNUM 20 +#define GRAVITY REAL(0.5) + +// dynamics and collision objects + +struct MyObject { + dBodyID body; // the body + dGeomID geom[GPB]; // geometries representing this body +}; + +static int num=0; // number of objects in simulation +static int nextobj=0; // next object to recycle if num==NUM +static dWorldID world; +static dSpaceID space; +static MyObject obj[NUM]; +static dJointGroupID contactgroup; +static int selected = -1; // selected object +static int show_aabb = 0; // show geom AABBs? +static int show_contacts = 0; // show contact points? +static int random_pos = 1; // drop objects from random position? +static int write_world = 0; +static int show_body = 0; + +struct MyFeedback { + dJointFeedback fb; + bool first; +}; +static int doFeedback=0; +static MyFeedback feedbacks[MAX_FEEDBACKNUM]; +static int fbnum=0; + +// this is called by dSpaceCollide when two objects in space are +// potentially colliding. + +static void nearCallback (void *, dGeomID o1, dGeomID o2) +{ + int i; + // if (o1->body && o2->body) return; + + // exit without doing anything if the two bodies are connected by a joint + dBodyID b1 = dGeomGetBody(o1); + dBodyID b2 = dGeomGetBody(o2); + + if (b1 && b2 && dAreConnectedExcluding(b1,b2,dJointTypeContact)) + return; + + dContact contact[MAX_CONTACTS]; // up to MAX_CONTACTS contacts per box-box + for (i=0; i<MAX_CONTACTS; i++) { + contact[i].surface.mode = dContactBounce | dContactSoftCFM; + contact[i].surface.mu = dInfinity; + contact[i].surface.mu2 = 0; + contact[i].surface.bounce = 0.1; + contact[i].surface.bounce_vel = 0.1; + contact[i].surface.soft_cfm = 0.01; + } + if (int numc = dCollide(o1,o2,MAX_CONTACTS,&contact[0].geom, + sizeof(dContact))) { + dMatrix3 RI; + dRSetIdentity (RI); + const dReal ss[3] = {0.02,0.02,0.02}; + for (i=0; i<numc; i++) { + dJointID c = dJointCreateContact (world,contactgroup,contact+i); + dJointAttach (c,b1,b2); + if (show_contacts) { + dsSetColor(0,0,1); + dsDrawBox(contact[i].geom.pos,RI,ss); + } + if (doFeedback && (b1==obj[selected].body || b2==obj[selected].body)) { + if (fbnum<MAX_FEEDBACKNUM) { + feedbacks[fbnum].first = b1==obj[selected].body; + dJointSetFeedback(c,&feedbacks[fbnum++].fb); + } + else fbnum++; + } + } + } +} + + +// start simulation - set viewpoint + +static void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + static float xyz[3] = {2.1640f,-1.3079f,1.7600f}; + static float hpr[3] = {125.5000f,-17.0000f,0.0000f}; + dsSetViewpoint (xyz,hpr); + printf ("To drop another object, press:\n"); + printf (" b for box.\n"); + printf (" s for sphere.\n"); + printf (" c for capsule.\n"); + printf (" y for cylinder.\n"); + printf (" v for a convex object.\n"); + printf (" x for a composite object.\n"); + printf ("To select an object, press space.\n"); + printf ("To disable the selected object, press d.\n"); + printf ("To enable the selected object, press e.\n"); + printf ("To dump transformation data for the selected object, press p.\n"); + printf ("To toggle showing the geom AABBs, press a.\n"); + printf ("To toggle showing the contact points, press t.\n"); + printf ("To toggle dropping from random position/orientation, press r.\n"); + printf ("To save the current state to 'state.dif', press 1.\n"); + printf ("To show joint feedbacks of selected object, press f.\n"); +} + + +static char locase(char c) +{ + if (c >= 'A' && c <= 'Z') return c - ('a'-'A'); + else return c; +} + + +// called when a key pressed + +static void command(int cmd) +{ + dsizeint i; + int j,k; + dReal sides[3]; + dMass m; + bool setBody = false; + + cmd = locase(cmd); + if (cmd == 'b' || cmd == 's' || cmd == 'c' || cmd == 'x' || cmd == 'y' || cmd == 'v') { + if (num < NUM) { + // new object to be created + i = num; + num++; + } else { + // recycle existing object + i = nextobj++; + nextobj %= num; // wrap-around if needed + + // destroy the body and geoms for slot i + dBodyDestroy (obj[i].body); + obj[i].body = 0; + + for (k=0; k < GPB; k++) + if (obj[i].geom[k]) { + dGeomDestroy(obj[i].geom[k]); + obj[i].geom[k] = 0; + } + } + + obj[i].body = dBodyCreate(world); + + for (k=0; k<3; k++) + sides[k] = dRandReal()*0.5+0.1; + + dMatrix3 R; + if (random_pos) { + dBodySetPosition(obj[i].body, + dRandReal()*2-1,dRandReal()*2-1,dRandReal()+2); + dRFromAxisAndAngle(R,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, + dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); + } else { + // higher than highest body position + dReal maxheight = 0; + for (k=0; k<num; k++) { + const dReal *pos = dBodyGetPosition(obj[k].body); + if (pos[2] > maxheight) + maxheight = pos[2]; + } + dBodySetPosition(obj[i].body, 0,0,maxheight+1); + dRSetIdentity(R); + //dRFromAxisAndAngle (R,0,0,1,/*dRandReal()*10.0-5.0*/0); + } + + dBodySetRotation(obj[i].body,R); + + if (cmd == 'b') { + + dMassSetBox(&m,DENSITY,sides[0],sides[1],sides[2]); + obj[i].geom[0] = dCreateBox(space,sides[0],sides[1],sides[2]); + + } else if (cmd == 'c') { + + sides[0] *= 0.5; + dMassSetCapsule(&m,DENSITY,3,sides[0],sides[1]); + obj[i].geom[0] = dCreateCapsule (space,sides[0],sides[1]); + + } else if (cmd == 'v') { + + dMassSetBox(&m,DENSITY,0.25,0.25,0.25); +#if 0 + obj[i].geom[0] = dCreateConvex(space, + planes, + planecount, + points, + pointcount, + polygons); +#else + obj[i].geom[0] = dCreateConvex(space, + Sphere_planes, + Sphere_planecount, + Sphere_points, + Sphere_pointcount, + Sphere_polygons); +#endif + + } else if (cmd == 'y') { + + dMassSetCylinder(&m,DENSITY,3,sides[0],sides[1]); + obj[i].geom[0] = dCreateCylinder(space,sides[0],sides[1]); + + } else if (cmd == 's') { + + sides[0] *= 0.5; + dMassSetSphere (&m,DENSITY,sides[0]); + obj[i].geom[0] = dCreateSphere (space,sides[0]); + + } else if (cmd == 'x') { + + setBody = true; + // start accumulating masses for the composite geometries + dMass m2; + dMassSetZero (&m); + + dReal dpos[GPB][3]; // delta-positions for composite geometries + dMatrix3 drot[GPB]; + + // set random delta positions + for (j=0; j<GPB; j++) + for (k=0; k<3; k++) + dpos[j][k] = dRandReal()*0.3-0.15; + + for (k=0; k<GPB; k++) { + if (k==0) { + dReal radius = dRandReal()*0.25+0.05; + obj[i].geom[k] = dCreateSphere (space,radius); + dMassSetSphere (&m2,DENSITY,radius); + } else if (k==1) { + obj[i].geom[k] = dCreateBox(space,sides[0],sides[1],sides[2]); + dMassSetBox(&m2,DENSITY,sides[0],sides[1],sides[2]); + } else { + dReal radius = dRandReal()*0.1+0.05; + dReal length = dRandReal()*1.0+0.1; + obj[i].geom[k] = dCreateCapsule(space,radius,length); + dMassSetCapsule(&m2,DENSITY,3,radius,length); + } + + dRFromAxisAndAngle(drot[k],dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, + dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); + dMassRotate(&m2,drot[k]); + + dMassTranslate(&m2,dpos[k][0],dpos[k][1],dpos[k][2]); + + // add to the total mass + dMassAdd(&m,&m2); + + } + for (k=0; k<GPB; k++) { + dGeomSetBody(obj[i].geom[k],obj[i].body); + dGeomSetOffsetPosition(obj[i].geom[k], + dpos[k][0]-m.c[0], + dpos[k][1]-m.c[1], + dpos[k][2]-m.c[2]); + dGeomSetOffsetRotation(obj[i].geom[k], drot[k]); + } + dMassTranslate(&m,-m.c[0],-m.c[1],-m.c[2]); + dBodySetMass(obj[i].body,&m); + + } + + if (!setBody) { // avoid calling for composite geometries + for (k=0; k < GPB; k++) + if (obj[i].geom[k]) + dGeomSetBody(obj[i].geom[k],obj[i].body); + + dBodySetMass(obj[i].body,&m); + } + } + + if (cmd == ' ') { + + selected++; + if (selected >= num) + selected = 0; + if (selected == -1) + selected = 0; + + } else if (cmd == 'd' && selected >= 0 && selected < num) { + + dBodyDisable(obj[selected].body); + + } else if (cmd == 'e' && selected >= 0 && selected < num) { + + dBodyEnable(obj[selected].body); + + } else if (cmd == 'a') { + + show_aabb = !show_aabb; + + } else if (cmd == 't') { + + show_contacts = !show_contacts; + + } else if (cmd == 'r') { + + random_pos = !random_pos; + } else if (cmd == '1') { + + write_world = 1; + + } else if (cmd == 'p'&& selected >= 0) { + + const dReal* pos = dGeomGetPosition(obj[selected].geom[0]); + const dReal* rot = dGeomGetRotation(obj[selected].geom[0]); + printf("POSITION:\n\t[%f,%f,%f]\n\n",pos[0],pos[1],pos[2]); + printf("ROTATION:\n\t[%f,%f,%f,%f]\n\t[%f,%f,%f,%f]\n\t[%f,%f,%f,%f]\n\n", + rot[0],rot[1],rot[2],rot[3], + rot[4],rot[5],rot[6],rot[7], + rot[8],rot[9],rot[10],rot[11]); + + } else if (cmd == 'f' && selected >= 0 && selected < num) { + + if (dBodyIsEnabled(obj[selected].body)) + doFeedback = 1; + + } +} + + +// draw a geom + +void drawGeom(dGeomID g, const dReal *pos, const dReal *R, int show_aabb) +{ + int i; + + if (!g) + return; + if (!pos) + pos = dGeomGetPosition(g); + if (!R) + R = dGeomGetRotation(g); + + int type = dGeomGetClass(g); + if (type == dBoxClass) { + + dVector3 sides; + dGeomBoxGetLengths (g,sides); + dsDrawBox(pos,R,sides); + + } else if (type == dSphereClass) { + + dsDrawSphere(pos,R,dGeomSphereGetRadius(g)); + + } else if (type == dCapsuleClass) { + + dReal radius,length; + dGeomCapsuleGetParams(g,&radius,&length); + dsDrawCapsule(pos,R,length,radius); + + } else if (type == dConvexClass) { + +#if 0 + dsDrawConvex(pos,R,planes, + planecount, + points, + pointcount, + polygons); +#else + dsDrawConvex(pos,R, + Sphere_planes, + Sphere_planecount, + Sphere_points, + Sphere_pointcount, + Sphere_polygons); +#endif + + } else if (type == dCylinderClass) { + + dReal radius,length; + dGeomCylinderGetParams(g,&radius,&length); + dsDrawCylinder(pos,R,length,radius); + + } + + if (show_body) { + dBodyID body = dGeomGetBody(g); + if (body) { + const dReal *bodypos = dBodyGetPosition(body); + const dReal *bodyr = dBodyGetRotation(body); + dReal bodySides[3] = { 0.1, 0.1, 0.1 }; + dsSetColorAlpha(0,1,0,1); + dsDrawBox(bodypos,bodyr,bodySides); + } + } + + if (show_aabb) { + // draw the bounding box for this geom + dReal aabb[6]; + dGeomGetAABB(g,aabb); + dVector3 bbpos; + for (i=0; i<3; i++) + bbpos[i] = 0.5*(aabb[i*2] + aabb[i*2+1]); + dVector3 bbsides; + for (i=0; i<3; i++) + bbsides[i] = aabb[i*2+1] - aabb[i*2]; + dMatrix3 RI; + dRSetIdentity (RI); + dsSetColorAlpha(1,0,0,0.5); + dsDrawBox(bbpos,RI,bbsides); + } +} + + +// simulation loop + +static void simLoop(int pause) +{ + dSpaceCollide(space, 0, &nearCallback); + + if (!pause) + dWorldQuickStep(world, 0.02); + + if (write_world) { + FILE *f = fopen("state.dif","wt"); + if (f) { + dWorldExportDIF(world,f,"X"); + fclose (f); + } + write_world = 0; + } + + + if (doFeedback) { + if (fbnum>MAX_FEEDBACKNUM) + printf("joint feedback buffer overflow!\n"); + else { + dVector3 sum = {0, 0, 0}; + printf("\n"); + for (int i=0; i<fbnum; i++) { + dReal* f = feedbacks[i].first?feedbacks[i].fb.f1:feedbacks[i].fb.f2; + printf("%f %f %f\n", f[0], f[1], f[2]); + sum[0] += f[0]; + sum[1] += f[1]; + sum[2] += f[2]; + } + printf("Sum: %f %f %f\n", sum[0], sum[1], sum[2]); + dMass m; + dBodyGetMass(obj[selected].body, &m); + printf("Object G=%f\n", GRAVITY*m.mass); + } + doFeedback = 0; + fbnum = 0; + } + + // remove all contact joints + dJointGroupEmpty(contactgroup); + + dsSetTexture(DS_WOOD); + for (int i=0; i<num; i++) { + for (int j=0; j < GPB; j++) { + if (i==selected) { + dsSetColor(0,0.7,1); + } else if (!dBodyIsEnabled(obj[i].body)) { + dsSetColor(1,0.8,0); + } else { + dsSetColor(1,1,0); + } + drawGeom(obj[i].geom[j],0,0,show_aabb); + } + } +} + + +int main (int argc, char **argv) +{ + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + // create world + dInitODE2(0); + world = dWorldCreate(); + space = dHashSpaceCreate(0); + contactgroup = dJointGroupCreate(0); + dWorldSetGravity(world,0,0,-GRAVITY); + dWorldSetCFM(world,1e-5); + dWorldSetAutoDisableFlag(world,1); + +#if 1 + + dWorldSetAutoDisableAverageSamplesCount( world, 10 ); + +#endif + + dWorldSetLinearDamping(world, 0.00001); + dWorldSetAngularDamping(world, 0.005); + dWorldSetMaxAngularSpeed(world, 200); + + dWorldSetContactMaxCorrectingVel(world,0.1); + dWorldSetContactSurfaceLayer(world,0.001); + dCreatePlane(space,0,0,1,0); + memset(obj,0,sizeof(obj)); + + dThreadingImplementationID threading = dThreadingAllocateMultiThreadedImplementation(); + dThreadingThreadPoolID pool = dThreadingAllocateThreadPool(4, 0, dAllocateFlagBasicData, NULL); + dThreadingThreadPoolServeMultiThreadedImplementation(pool, threading); + // dWorldSetStepIslandsProcessingMaxThreadCount(world, 1); + dWorldSetStepThreadingImplementation(world, dThreadingImplementationGetFunctions(threading), threading); + + // run simulation + dsSimulationLoop(argc,argv,640,480,&fn); + + dThreadingImplementationShutdownProcessing(threading); + dThreadingFreeThreadPool(pool); + dWorldSetStepThreadingImplementation(world, NULL, NULL); + dThreadingFreeImplementation(threading); + + dJointGroupDestroy(contactgroup); + dSpaceDestroy(space); + dWorldDestroy(world); + dCloseODE(); +} diff --git a/libs/ode-0.16.1/ode/demo/demo_buggy.cpp b/libs/ode-0.16.1/ode/demo/demo_buggy.cpp new file mode 100644 index 0000000..b96d93f --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_buggy.cpp @@ -0,0 +1,308 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +buggy with suspension. +this also shows you how to use geom groups. + +*/ + + +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + +// select correct drawing functions + +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#define dsDrawSphere dsDrawSphereD +#define dsDrawCylinder dsDrawCylinderD +#define dsDrawCapsule dsDrawCapsuleD +#endif + + +// some constants + +#define LENGTH 0.7 // chassis length +#define WIDTH 0.5 // chassis width +#define HEIGHT 0.2 // chassis height +#define RADIUS 0.18 // wheel radius +#define STARTZ 0.5 // starting height of chassis +#define CMASS 1 // chassis mass +#define WMASS 0.2 // wheel mass + +static const dVector3 yunit = { 0, 1, 0 }, zunit = { 0, 0, 1 }; + + +// dynamics and collision objects (chassis, 3 wheels, environment) + +static dWorldID world; +static dSpaceID space; +static dBodyID body[4]; +static dJointID joint[3]; // joint[0] is the front wheel +static dJointGroupID contactgroup; +static dGeomID ground; +static dSpaceID car_space; +static dGeomID box[1]; +static dGeomID sphere[3]; +static dGeomID ground_box; + + +// things that the user controls + +static dReal speed=0,steer=0; // user commands + + +// this is called by dSpaceCollide when two objects in space are +// potentially colliding. + +static void nearCallback (void *, dGeomID o1, dGeomID o2) +{ + int i,n; + + // only collide things with the ground + int g1 = (o1 == ground || o1 == ground_box); + int g2 = (o2 == ground || o2 == ground_box); + if (!(g1 ^ g2)) return; + + const int N = 10; + dContact contact[N]; + n = dCollide (o1,o2,N,&contact[0].geom,sizeof(dContact)); + if (n > 0) { + for (i=0; i<n; i++) { + contact[i].surface.mode = dContactSlip1 | dContactSlip2 | + dContactSoftERP | dContactSoftCFM | dContactApprox1; + contact[i].surface.mu = dInfinity; + contact[i].surface.slip1 = 0.1; + contact[i].surface.slip2 = 0.1; + contact[i].surface.soft_erp = 0.5; + contact[i].surface.soft_cfm = 0.3; + dJointID c = dJointCreateContact (world,contactgroup,&contact[i]); + dJointAttach (c, + dGeomGetBody(contact[i].geom.g1), + dGeomGetBody(contact[i].geom.g2)); + } + } +} + + +// start simulation - set viewpoint + +static void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + static float xyz[3] = {0.8317f,-0.9817f,0.8000f}; + static float hpr[3] = {121.0000f,-27.5000f,0.0000f}; + dsSetViewpoint (xyz,hpr); + printf ("Press:\t'a' to increase speed.\n" + "\t'z' to decrease speed.\n" + "\t',' to steer left.\n" + "\t'.' to steer right.\n" + "\t' ' to reset speed and steering.\n" + "\t'1' to save the current state to 'state.dif'.\n"); +} + + +// called when a key pressed + +static void command (int cmd) +{ + switch (cmd) { + case 'a': case 'A': + speed += 0.3; + break; + case 'z': case 'Z': + speed -= 0.3; + break; + case ',': + steer -= 0.5; + break; + case '.': + steer += 0.5; + break; + case ' ': + speed = 0; + steer = 0; + break; + case '1': { + FILE *f = fopen ("state.dif","wt"); + if (f) { + dWorldExportDIF (world,f,""); + fclose (f); + } + } + } +} + + +// simulation loop + +static void simLoop (int pause) +{ + int i; + if (!pause) { + // motor + dJointSetHinge2Param (joint[0],dParamVel2,-speed); + dJointSetHinge2Param (joint[0],dParamFMax2,0.1); + + // steering + dReal v = steer - dJointGetHinge2Angle1 (joint[0]); + if (v > 0.1) v = 0.1; + if (v < -0.1) v = -0.1; + v *= 10.0; + dJointSetHinge2Param (joint[0],dParamVel,v); + dJointSetHinge2Param (joint[0],dParamFMax,0.2); + dJointSetHinge2Param (joint[0],dParamLoStop,-0.75); + dJointSetHinge2Param (joint[0],dParamHiStop,0.75); + dJointSetHinge2Param (joint[0],dParamFudgeFactor,0.1); + + dSpaceCollide (space,0,&nearCallback); + dWorldStep (world,0.05); + + // remove all contact joints + dJointGroupEmpty (contactgroup); + + } + + dsSetColor (0,1,1); + dsSetTexture (DS_WOOD); + dReal sides[3] = {LENGTH,WIDTH,HEIGHT}; + dsDrawBox (dBodyGetPosition(body[0]),dBodyGetRotation(body[0]),sides); + dsSetColor (1,1,1); + for (i=1; i<=3; i++) dsDrawCylinder (dBodyGetPosition(body[i]), + dBodyGetRotation(body[i]),0.02f,RADIUS); + + dVector3 ss; + dGeomBoxGetLengths (ground_box,ss); + dsDrawBox (dGeomGetPosition(ground_box),dGeomGetRotation(ground_box),ss); + +} + + +int main (int argc, char **argv) +{ + int i; + dMass m; + + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + // create world + dInitODE2(0); + world = dWorldCreate(); + space = dHashSpaceCreate (0); + contactgroup = dJointGroupCreate (0); + dWorldSetGravity (world,0,0,-0.5); + ground = dCreatePlane (space,0,0,1,0); + + // chassis body + body[0] = dBodyCreate (world); + dBodySetPosition (body[0],0,0,STARTZ); + dMassSetBox (&m,1,LENGTH,WIDTH,HEIGHT); + dMassAdjust (&m,CMASS); + dBodySetMass (body[0],&m); + box[0] = dCreateBox (0,LENGTH,WIDTH,HEIGHT); + dGeomSetBody (box[0],body[0]); + + // wheel bodies + for (i=1; i<=3; i++) { + body[i] = dBodyCreate (world); + dQuaternion q; + dQFromAxisAndAngle (q,1,0,0,M_PI*0.5); + dBodySetQuaternion (body[i],q); + dMassSetSphere (&m,1,RADIUS); + dMassAdjust (&m,WMASS); + dBodySetMass (body[i],&m); + sphere[i-1] = dCreateSphere (0,RADIUS); + dGeomSetBody (sphere[i-1],body[i]); + } + dBodySetPosition (body[1],0.5*LENGTH,0,STARTZ-HEIGHT*0.5); + dBodySetPosition (body[2],-0.5*LENGTH, WIDTH*0.5,STARTZ-HEIGHT*0.5); + dBodySetPosition (body[3],-0.5*LENGTH,-WIDTH*0.5,STARTZ-HEIGHT*0.5); + + // front and back wheel hinges + for (i=0; i<3; i++) { + joint[i] = dJointCreateHinge2 (world,0); + dJointAttach (joint[i],body[0],body[i+1]); + const dReal *a = dBodyGetPosition (body[i+1]); + dJointSetHinge2Anchor (joint[i],a[0],a[1],a[2]); + dJointSetHinge2Axes (joint[i], zunit, yunit); + } + + // set joint suspension + for (i=0; i<3; i++) { + dJointSetHinge2Param (joint[i],dParamSuspensionERP,0.4); + dJointSetHinge2Param (joint[i],dParamSuspensionCFM,0.8); + } + + // lock back wheels along the steering axis + for (i=1; i<3; i++) { + // set stops to make sure wheels always stay in alignment + dJointSetHinge2Param (joint[i],dParamLoStop,0); + dJointSetHinge2Param (joint[i],dParamHiStop,0); + // the following alternative method is no good as the wheels may get out + // of alignment: + // dJointSetHinge2Param (joint[i],dParamVel,0); + // dJointSetHinge2Param (joint[i],dParamFMax,dInfinity); + } + + // create car space and add it to the top level space + car_space = dSimpleSpaceCreate (space); + dSpaceSetCleanup (car_space,0); + dSpaceAdd (car_space,box[0]); + dSpaceAdd (car_space,sphere[0]); + dSpaceAdd (car_space,sphere[1]); + dSpaceAdd (car_space,sphere[2]); + + // environment + ground_box = dCreateBox (space,2,1.5,1); + dMatrix3 R; + dRFromAxisAndAngle (R,0,1,0,-0.15); + dGeomSetPosition (ground_box,2,0,-0.34); + dGeomSetRotation (ground_box,R); + + // run simulation + dsSimulationLoop (argc,argv,352,288,&fn); + + dGeomDestroy (box[0]); + dGeomDestroy (sphere[0]); + dGeomDestroy (sphere[1]); + dGeomDestroy (sphere[2]); + dJointGroupDestroy (contactgroup); + dSpaceDestroy (space); + dWorldDestroy (world); + dCloseODE(); + return 0; +} diff --git a/libs/ode-0.16.1/ode/demo/demo_cards.cpp b/libs/ode-0.16.1/ode/demo/demo_cards.cpp new file mode 100644 index 0000000..17284ba --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_cards.cpp @@ -0,0 +1,237 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <vector> +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#endif + +static int levels = 5; +static int ncards = 0; + +static dSpaceID space; +static dWorldID world; +static dJointGroupID contactgroup; + +struct Card { + dBodyID body; + dGeomID geom; + static const dReal sides[3]; + + Card() + { + body = dBodyCreate(world); + geom = dCreateBox(space, sides[0], sides[1], sides[2]); + dGeomSetBody(geom, body); + dGeomSetData(geom, this); + dMass mass; + mass.setBox(1, sides[0], sides[1], sides[2]); + dBodySetMass(body, &mass); + } + + ~Card() + { + dBodyDestroy(body); + dGeomDestroy(geom); + } + + void draw() const + { + dsDrawBox(dBodyGetPosition(body), + dBodyGetRotation(body), sides); + } +}; +static const dReal cwidth=.5, cthikness=.02, clength=1; +const dReal Card::sides[3] = { cwidth, cthikness, clength }; + + +std::vector<Card*> cards; + +int getncards(int levels) +{ + return (3*levels*levels + levels) / 2; +} + +void place_cards() +{ + ncards = getncards(levels); + // destroy removed cards (if any) + int oldcards = cards.size(); + for (int i=ncards; i<oldcards; ++i) + delete cards[i]; + cards.resize(ncards); + // construct new cards (if any) + for (int i=oldcards; i<ncards; ++i) + cards[i] = new Card; + + // for each level + int c = 0; + dMatrix3 right, left, hrot; + dReal angle = 20*M_PI/180.; + dRFromAxisAndAngle(right, 1, 0, 0, -angle); + dRFromAxisAndAngle(left, 1, 0, 0, angle); + + dRFromAxisAndAngle(hrot, 1, 0, 0, 91*M_PI/180.); + + dReal eps = 0.05; + dReal vstep = cos(angle)*clength + eps; + dReal hstep = sin(angle)*clength + eps; + + for (int lvl=0; lvl<levels; ++lvl) { + // there are 3*(levels-lvl)-1 cards in each level, except last + int n = (levels-lvl); + dReal height = (lvl)*vstep + vstep/2; + // inclined cards + for (int i=0; i<2*n; ++i, ++c) { + dBodySetPosition(cards[c]->body, + 0, + -n*hstep + hstep*i, + height + ); + if (i%2) + dBodySetRotation(cards[c]->body, left); + else + dBodySetRotation(cards[c]->body, right); + } + + if (n==1) // top of the house + break; + + // horizontal cards + for (int i=0; i<n-1; ++i, ++c) { + dBodySetPosition(cards[c]->body, + 0, + -(n-1 - (clength-hstep)/2)*hstep + 2*hstep*i, + height + vstep/2); + dBodySetRotation(cards[c]->body, hrot); + } + } + +} + + +void start() +{ + puts("Controls:"); + puts(" SPACE - reposition cards"); + puts(" - - one less level"); + puts(" = - one more level"); +} + +static void nearCallback (void *, dGeomID o1, dGeomID o2) +{ + // exit without doing anything if the two bodies are connected by a joint + dBodyID b1 = dGeomGetBody(o1); + dBodyID b2 = dGeomGetBody(o2); + + const int MAX_CONTACTS = 8; + dContact contact[MAX_CONTACTS]; + + int numc = dCollide (o1, o2, MAX_CONTACTS, + &contact[0].geom, + sizeof(dContact)); + + for (int i=0; i<numc; i++) { + contact[i].surface.mode = dContactApprox1; + contact[i].surface.mu = 5; + dJointID c = dJointCreateContact (world, contactgroup, contact+i); + dJointAttach (c, b1, b2); + } +} + + +void simLoop(int pause) +{ + if (!pause) { + dSpaceCollide (space, 0, &nearCallback); + dWorldQuickStep(world, 0.01); + dJointGroupEmpty(contactgroup); + } + + dsSetColor (1,1,0); + for (int i=0; i<ncards; ++i) { + dsSetColor (1, dReal(i)/ncards, 0); + cards[i]->draw(); + } + +} + +void command(int c) +{ + switch (c) { + case '=': + levels++; + place_cards(); + break; + case '-': + levels--; + if (levels <= 0) + levels++; + place_cards(); + break; + case ' ': + place_cards(); + break; + } +} + +int main(int argc, char **argv) +{ + dInitODE(); + + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + + world = dWorldCreate(); + dWorldSetGravity(world, 0, 0, -0.5); + dWorldSetQuickStepNumIterations(world, 50); // <-- increase for more stability + + space = dSimpleSpaceCreate(0); + contactgroup = dJointGroupCreate(0); + dGeomID ground = dCreatePlane(space, 0, 0, 1, 0); + + place_cards(); + + // run simulation + dsSimulationLoop (argc, argv, 640, 480, &fn); + + levels = 0; + place_cards(); + + dJointGroupDestroy(contactgroup); + dWorldDestroy(world); + dGeomDestroy(ground); + dSpaceDestroy(space); + + dCloseODE(); +} diff --git a/libs/ode-0.16.1/ode/demo/demo_chain1.c b/libs/ode-0.16.1/ode/demo/demo_chain1.c new file mode 100644 index 0000000..a6d7b38 --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_chain1.c @@ -0,0 +1,171 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* exercise the C interface */ + +#include <stdio.h> +#include "ode/ode.h" +#include "drawstuff/drawstuff.h" +#include "texturepath.h" + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) /* for VC++, no precision loss complaints */ +#endif + +/* select correct drawing functions */ + +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#define dsDrawSphere dsDrawSphereD +#define dsDrawCylinder dsDrawCylinderD +#define dsDrawCapsule dsDrawCapsuleD +#endif + + +/* some constants */ + +#define NUM 10 /* number of boxes */ +#define SIDE (0.2) /* side length of a box */ +#define MASS (1.0) /* mass of a box */ +#define RADIUS (0.1732f) /* sphere radius */ + + +/* dynamics and collision objects */ + +static dWorldID world; +static dSpaceID space; +static dBodyID body[NUM]; +static dJointID joint[NUM-1]; +static dJointGroupID contactgroup; +static dGeomID sphere[NUM]; + + +/* this is called by dSpaceCollide when two objects in space are + * potentially colliding. + */ + +static void nearCallback (void *data, dGeomID o1, dGeomID o2) +{ + /* exit without doing anything if the two bodies are connected by a joint */ + dBodyID b1,b2; + dContact contact; + (void)data; + + b1 = dGeomGetBody(o1); + b2 = dGeomGetBody(o2); + if (b1 && b2 && dAreConnected (b1,b2)) return; + + contact.surface.mode = 0; + contact.surface.mu = 0.1; + contact.surface.mu2 = 0; + if (dCollide (o1,o2,1,&contact.geom,sizeof(dContactGeom))) { + dJointID c = dJointCreateContact (world,contactgroup,&contact); + dJointAttach (c,b1,b2); + } +} + + +/* start simulation - set viewpoint */ + +static void start() +{ + static float xyz[3] = {2.1640f,-1.3079f,1.7600f}; + static float hpr[3] = {125.5000f,-17.0000f,0.0000f}; + + dAllocateODEDataForThread(dAllocateMaskAll); + dsSetViewpoint (xyz,hpr); +} + + +/* simulation loop */ + +static void simLoop (int pause) +{ + int i; + if (!pause) { + static double angle = 0; + angle += 0.05; + dBodyAddForce (body[NUM-1],0,0,1.5*(sin(angle)+1.0)); + + dSpaceCollide (space,0,&nearCallback); + dWorldStep (world,0.05); + + /* remove all contact joints */ + dJointGroupEmpty (contactgroup); + } + + dsSetColor (1,1,0); + dsSetTexture (DS_WOOD); + for (i=0; i<NUM; i++) dsDrawSphere (dBodyGetPosition(body[i]), + dBodyGetRotation(body[i]),RADIUS); +} + + +int main (int argc, char **argv) +{ + int i; + dReal k; + dMass m; + + /* setup pointers to drawstuff callback functions */ + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = 0; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + /* create world */ + dInitODE2(0); + world = dWorldCreate(); + space = dHashSpaceCreate (0); + contactgroup = dJointGroupCreate (1000000); + dWorldSetGravity (world,0,0,-0.5); + dCreatePlane (space,0,0,1,0); + + for (i=0; i<NUM; i++) { + body[i] = dBodyCreate (world); + k = i*SIDE; + dBodySetPosition (body[i],k,k,k+0.4); + dMassSetBox (&m,1,SIDE,SIDE,SIDE); + dMassAdjust (&m,MASS); + dBodySetMass (body[i],&m); + sphere[i] = dCreateSphere (space,RADIUS); + dGeomSetBody (sphere[i],body[i]); + } + for (i=0; i<(NUM-1); i++) { + joint[i] = dJointCreateBall (world,0); + dJointAttach (joint[i],body[i],body[i+1]); + k = (i+0.5)*SIDE; + dJointSetBallAnchor (joint[i],k,k,k+0.4); + } + + /* run simulation */ + dsSimulationLoop (argc,argv,352,288,&fn); + + dJointGroupDestroy (contactgroup); + dSpaceDestroy (space); + dWorldDestroy (world); + dCloseODE(); + return 0; +} diff --git a/libs/ode-0.16.1/ode/demo/demo_chain2.cpp b/libs/ode-0.16.1/ode/demo/demo_chain2.cpp new file mode 100644 index 0000000..3dec131 --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_chain2.cpp @@ -0,0 +1,165 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* exercise the C++ interface */ + +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + +// select correct drawing functions + +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#define dsDrawSphere dsDrawSphereD +#define dsDrawCylinder dsDrawCylinderD +#define dsDrawCapsule dsDrawCapsuleD +#endif + + +// some constants + +#define NUM 10 // number of boxes +#define SIDE (0.2) // side length of a box +#define MASS (1.0) // mass of a box +#define RADIUS (0.1732f) // sphere radius + +//using namespace ode; + +// dynamics and collision objects + +static dWorld world; +static dSimpleSpace space (0); +static dBody body[NUM]; +static dBallJoint joint[NUM-1]; +static dJointGroup contactgroup; +static dBox box[NUM]; + + +// this is called by space.collide when two objects in space are +// potentially colliding. + +static void nearCallback (void *, dGeomID o1, dGeomID o2) +{ + // exit without doing anything if the two bodies are connected by a joint + dBodyID b1 = dGeomGetBody(o1); + dBodyID b2 = dGeomGetBody(o2); + if (b1 && b2 && dAreConnected (b1,b2)) return; + + // @@@ it's still more convenient to use the C interface here. + + dContact contact; + contact.surface.mode = 0; + contact.surface.mu = dInfinity; + if (dCollide (o1,o2,1,&contact.geom,sizeof(dContactGeom))) { + dJointID c = dJointCreateContact (world.id(),contactgroup.id(),&contact); + dJointAttach (c,b1,b2); + } +} + + +// start simulation - set viewpoint + +static void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + static float xyz[3] = {2.1640f,-1.3079f,1.7600f}; + static float hpr[3] = {125.5000f,-17.0000f,0.0000f}; + dsSetViewpoint (xyz,hpr); +} + + +// simulation loop + +static void simLoop (int pause) +{ + if (!pause) { + static double angle = 0; + angle += 0.05; + body[NUM-1].addForce (0,0,1.5*(sin(angle)+1.0)); + + space.collide (0,&nearCallback); + world.step (0.05); + + // remove all contact joints + contactgroup.empty(); + } + + dReal sides[3] = {SIDE,SIDE,SIDE}; + dsSetColor (1,1,0); + dsSetTexture (DS_WOOD); + for (int i=0; i<NUM; i++) + dsDrawBox (body[i].getPosition(),body[i].getRotation(),sides); +} + + +int main (int argc, char **argv) +{ + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = 0; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + // create world + dInitODE2(0); + + int i; + contactgroup.create (); + world.setGravity (0,0,-0.5); + dWorldSetCFM (world.id(),1e-5); + dPlane plane (space,0,0,1,0); + + for (i=0; i<NUM; i++) { + body[i].create (world); + dReal k = i*SIDE; + body[i].setPosition (k,k,k+0.4); + dMass m; + m.setBox (1,SIDE,SIDE,SIDE); + m.adjust (MASS); + body[i].setMass (&m); + body[i].setData ((void*)(dsizeint)i); + + box[i].create (space,SIDE,SIDE,SIDE); + box[i].setBody (body[i]); + } + for (i=0; i<(NUM-1); i++) { + joint[i].create (world); + joint[i].attach (body[i],body[i+1]); + dReal k = (i+0.5)*SIDE; + joint[i].setAnchor (k,k,k+0.4); + } + + // run simulation + dsSimulationLoop (argc,argv,352,288,&fn); + + dCloseODE(); + return 0; +} diff --git a/libs/ode-0.16.1/ode/demo/demo_collision.cpp b/libs/ode-0.16.1/ode/demo/demo_collision.cpp new file mode 100644 index 0000000..e45d106 --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_collision.cpp @@ -0,0 +1,1463 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +collision tests. if this program is run without any arguments it will +perform all the tests multiple times, with different random data for each +test. if this program is given a test number it will run that test +graphically/interactively, in which case the space bar can be used to +change the random test conditions. + +*/ + + +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif +// select correct drawing functions +#ifdef dDOUBLE +#define dsDrawSphere dsDrawSphereD +#define dsDrawBox dsDrawBoxD +#define dsDrawLine dsDrawLineD +#define dsDrawCapsule dsDrawCapsuleD +#define dsDrawCylinder dsDrawCylinderD +#endif + +//**************************************************************************** +// test infrastructure, including constants and macros + +#define TEST_REPS1 1000 // run each test this many times (first batch) +#define TEST_REPS2 10000 // run each test this many times (second batch) +const dReal tol = 1e-8; // tolerance used for numerical checks +#define MAX_TESTS 1000 // maximum number of test slots +#define Z_OFFSET 2 // z offset for drawing (to get above ground) + +//using namespace ode; + +// test function. returns 1 if the test passed or 0 if it failed +typedef int test_function_t(); + +struct TestSlot { + int number; // number of test + const char *name; // name of test + int failcount; + test_function_t *test_fn; + int last_failed_line; +}; +TestSlot testslot[MAX_TESTS]; + + +// globals used by the test functions +int graphical_test=0; // show graphical results of this test, 0=none +int current_test; // currently execiting test +int draw_all_objects_called; + + +#define MAKE_TEST(number,function) \ + if (testslot[number].name) dDebug (0,"test number already used"); \ + if (number <= 0 || number >= MAX_TESTS) dDebug (0,"bad test number"); \ + testslot[number].name = # function; \ + testslot[number].test_fn = function; + +#define FAILED() { if (graphical_test==0) { \ + testslot[current_test].last_failed_line=__LINE__; return 0; } } +#define PASSED() { return 1; } + +//**************************************************************************** +// globals + +/* int dBoxBox (const dVector3 p1, const dMatrix3 R1, + const dVector3 side1, const dVector3 p2, + const dMatrix3 R2, const dVector3 side2, + dVector3 normal, dReal *depth, int *code, + int maxc, dContactGeom *contact, int skip); */ + +void dLineClosestApproach (const dVector3 pa, const dVector3 ua, + const dVector3 pb, const dVector3 ub, + dReal *alpha, dReal *beta); + +//**************************************************************************** +// draw all objects in a space, and draw all the collision contact points + +void nearCallback (void *, dGeomID o1, dGeomID o2) +{ + int i,j,n; + const int N = 100; + dContactGeom contact[N]; + + if (dGeomGetClass (o2) == dRayClass) { + n = dCollide (o2,o1,N,&contact[0],sizeof(dContactGeom)); + } + else { + n = dCollide (o1,o2,N,&contact[0],sizeof(dContactGeom)); + } + if (n > 0) { + dMatrix3 RI; + dRSetIdentity (RI); + const dReal ss[3] = {0.01,0.01,0.01}; + for (i=0; i<n; i++) { + contact[i].pos[2] += Z_OFFSET; + dsDrawBox (contact[i].pos,RI,ss); + dVector3 n; + for (j=0; j<3; j++) n[j] = contact[i].pos[j] + 0.1*contact[i].normal[j]; + dsDrawLine (contact[i].pos,n); + } + } +} + + +void draw_all_objects (dSpaceID space) +{ + int i, j; + + draw_all_objects_called = 1; + if (!graphical_test) return; + int n = dSpaceGetNumGeoms (space); + + // draw all contact points + dsSetColor (0,1,1); + dSpaceCollide (space,0,&nearCallback); + + // draw all rays + for (i=0; i<n; i++) { + dGeomID g = dSpaceGetGeom (space,i); + if (dGeomGetClass (g) == dRayClass) { + dsSetColor (1,1,1); + dVector3 origin,dir; + dGeomRayGet (g,origin,dir); + origin[2] += Z_OFFSET; + dReal length = dGeomRayGetLength (g); + for (j=0; j<3; j++) dir[j] = dir[j]*length + origin[j]; + dsDrawLine (origin,dir); + dsSetColor (0,0,1); + dsDrawSphere (origin,dGeomGetRotation(g),0.01); + } + } + + // draw all other objects + for (i=0; i<n; i++) { + dGeomID g = dSpaceGetGeom (space,i); + dVector3 pos; + if (dGeomGetClass (g) != dPlaneClass) { + memcpy (pos,dGeomGetPosition(g),sizeof(pos)); + pos[2] += Z_OFFSET; + } + + switch (dGeomGetClass (g)) { + + case dSphereClass: { + dsSetColorAlpha (1,0,0,0.8); + dReal radius = dGeomSphereGetRadius (g); + dsDrawSphere (pos,dGeomGetRotation(g),radius); + break; + } + + case dBoxClass: { + dsSetColorAlpha (1,1,0,0.8); + dVector3 sides; + dGeomBoxGetLengths (g,sides); + dsDrawBox (pos,dGeomGetRotation(g),sides); + break; + } + + case dCapsuleClass: { + dsSetColorAlpha (0,1,0,0.8); + dReal radius,length; + dGeomCapsuleGetParams (g,&radius,&length); + dsDrawCapsule (pos,dGeomGetRotation(g),length,radius); + break; + } + case dCylinderClass: { + dsSetColorAlpha (0,1,0,0.8); + dReal radius,length; + dGeomCylinderGetParams (g,&radius,&length); + dsDrawCylinder (pos,dGeomGetRotation(g),length,radius); + break; + } + + case dPlaneClass: { + dVector4 n; + dMatrix3 R,sides; + dVector3 pos2; + dGeomPlaneGetParams (g,n); + dRFromZAxis (R,n[0],n[1],n[2]); + for (j=0; j<3; j++) pos[j] = n[j]*n[3]; + pos[2] += Z_OFFSET; + sides[0] = 2; + sides[1] = 2; + sides[2] = 0.001; + dsSetColor (1,0,1); + for (j=0; j<3; j++) pos2[j] = pos[j] + 0.1*n[j]; + dsDrawLine (pos,pos2); + dsSetColorAlpha (1,0,1,0.8); + dsDrawBox (pos,R,sides); + break; + } + + } + } +} + +//**************************************************************************** +// point depth tests + +int test_sphere_point_depth() +{ + int j; + dVector3 p,q; + dMatrix3 R; + dReal r,d; + + dSimpleSpace space(0); + dGeomID sphere = dCreateSphere (0,1); + dSpaceAdd (space,sphere); + + // ********** make a random sphere of radius r at position p + + r = dRandReal()+0.1; + dGeomSphereSetRadius (sphere,r); + dMakeRandomVector (p,3,1.0); + dGeomSetPosition (sphere,p[0],p[1],p[2]); + dRFromAxisAndAngle (R,dRandReal()*2-1,dRandReal()*2-1, + dRandReal()*2-1,dRandReal()*10-5); + dGeomSetRotation (sphere,R); + + // ********** test center point has depth r + + if (dFabs(dGeomSpherePointDepth (sphere,p[0],p[1],p[2]) - r) > tol) FAILED(); + + // ********** test point on surface has depth 0 + + for (j=0; j<3; j++) q[j] = dRandReal()-0.5; + dNormalize3 (q); + for (j=0; j<3; j++) q[j] = q[j]*r + p[j]; + if (dFabs(dGeomSpherePointDepth (sphere,q[0],q[1],q[2])) > tol) FAILED(); + + // ********** test point at random depth + + d = (dRandReal()*2-1) * r; + for (j=0; j<3; j++) q[j] = dRandReal()-0.5; + dNormalize3 (q); + for (j=0; j<3; j++) q[j] = q[j]*(r-d) + p[j]; + if (dFabs(dGeomSpherePointDepth (sphere,q[0],q[1],q[2])-d) > tol) FAILED(); + + PASSED(); +} + + +int test_box_point_depth() +{ + int i,j; + dVector3 s,p,q,q2; // s = box sides + dMatrix3 R; + dReal ss,d; // ss = smallest side + + dSimpleSpace space(0); + dGeomID box = dCreateBox (0,1,1,1); + dSpaceAdd (space,box); + + // ********** make a random box + + for (j=0; j<3; j++) s[j] = dRandReal() + 0.1; + dGeomBoxSetLengths (box,s[0],s[1],s[2]); + dMakeRandomVector (p,3,1.0); + dGeomSetPosition (box,p[0],p[1],p[2]); + dRFromAxisAndAngle (R,dRandReal()*2-1,dRandReal()*2-1, + dRandReal()*2-1,dRandReal()*10-5); + dGeomSetRotation (box,R); + + // ********** test center point has depth of smallest side + + ss = 1e9; + for (j=0; j<3; j++) if (s[j] < ss) ss = s[j]; + if (dFabs(dGeomBoxPointDepth (box,p[0],p[1],p[2]) - 0.5*ss) > tol) + FAILED(); + + // ********** test point on surface has depth 0 + + for (j=0; j<3; j++) q[j] = (dRandReal()-0.5)*s[j]; + i = dRandInt (3); + if (dRandReal() > 0.5) q[i] = 0.5*s[i]; else q[i] = -0.5*s[i]; + dMultiply0 (q2,dGeomGetRotation(box),q,3,3,1); + for (j=0; j<3; j++) q2[j] += p[j]; + if (dFabs(dGeomBoxPointDepth (box,q2[0],q2[1],q2[2])) > tol) FAILED(); + + // ********** test points outside box have -ve depth + + for (j=0; j<3; j++) { + q[j] = 0.5*s[j] + dRandReal() + 0.01; + if (dRandReal() > 0.5) q[j] = -q[j]; + } + dMultiply0 (q2,dGeomGetRotation(box),q,3,3,1); + for (j=0; j<3; j++) q2[j] += p[j]; + if (dGeomBoxPointDepth (box,q2[0],q2[1],q2[2]) >= 0) FAILED(); + + // ********** test points inside box have +ve depth + + for (j=0; j<3; j++) q[j] = s[j] * 0.99 * (dRandReal()-0.5); + dMultiply0 (q2,dGeomGetRotation(box),q,3,3,1); + for (j=0; j<3; j++) q2[j] += p[j]; + if (dGeomBoxPointDepth (box,q2[0],q2[1],q2[2]) <= 0) FAILED(); + + // ********** test random depth of point aligned along axis (up to ss deep) + + i = dRandInt (3); + for (j=0; j<3; j++) q[j] = 0; + d = (dRandReal()*(ss*0.5+1)-1); + q[i] = s[i]*0.5 - d; + if (dRandReal() > 0.5) q[i] = -q[i]; + dMultiply0 (q2,dGeomGetRotation(box),q,3,3,1); + for (j=0; j<3; j++) q2[j] += p[j]; + if (dFabs(dGeomBoxPointDepth (box,q2[0],q2[1],q2[2]) - d) >= tol) FAILED(); + + PASSED(); +} + + +int test_ccylinder_point_depth() +{ + int j; + dVector3 p,a; + dMatrix3 R; + dReal r,l,beta,x,y,d; + + dSimpleSpace space(0); + dGeomID ccyl = dCreateCapsule (0,1,1); + dSpaceAdd (space,ccyl); + + // ********** make a random ccyl + + r = dRandReal()*0.5 + 0.01; + l = dRandReal()*1 + 0.01; + dGeomCapsuleSetParams (ccyl,r,l); + dMakeRandomVector (p,3,1.0); + dGeomSetPosition (ccyl,p[0],p[1],p[2]); + dRFromAxisAndAngle (R,dRandReal()*2-1,dRandReal()*2-1, + dRandReal()*2-1,dRandReal()*10-5); + dGeomSetRotation (ccyl,R); + + // ********** test point on axis has depth of 'radius' + + beta = dRandReal()-0.5; + for (j=0; j<3; j++) a[j] = p[j] + l*beta*R[j*4+2]; + if (dFabs(dGeomCapsulePointDepth (ccyl,a[0],a[1],a[2]) - r) >= tol) + FAILED(); + + // ********** test point on surface (excluding caps) has depth 0 + + beta = dRandReal()*2*M_PI; + x = r*sin(beta); + y = r*cos(beta); + beta = dRandReal()-0.5; + for (j=0; j<3; j++) a[j] = p[j] + x*R[j*4+0] + y*R[j*4+1] + l*beta*R[j*4+2]; + if (dFabs(dGeomCapsulePointDepth (ccyl,a[0],a[1],a[2])) >= tol) FAILED(); + + // ********** test point on surface of caps has depth 0 + + for (j=0; j<3; j++) a[j] = dRandReal()-0.5; + dNormalize3 (a); + if (dCalcVectorDot3_14(a,R+2) > 0) { + for (j=0; j<3; j++) a[j] = p[j] + a[j]*r + l*0.5*R[j*4+2]; + } + else { + for (j=0; j<3; j++) a[j] = p[j] + a[j]*r - l*0.5*R[j*4+2]; + } + if (dFabs(dGeomCapsulePointDepth (ccyl,a[0],a[1],a[2])) >= tol) FAILED(); + + // ********** test point inside ccyl has positive depth + + for (j=0; j<3; j++) a[j] = dRandReal()-0.5; + dNormalize3 (a); + beta = dRandReal()-0.5; + for (j=0; j<3; j++) a[j] = p[j] + a[j]*r*0.99 + l*beta*R[j*4+2]; + if (dGeomCapsulePointDepth (ccyl,a[0],a[1],a[2]) < 0) FAILED(); + + // ********** test point depth (1) + + d = (dRandReal()*2-1) * r; + beta = dRandReal()*2*M_PI; + x = (r-d)*sin(beta); + y = (r-d)*cos(beta); + beta = dRandReal()-0.5; + for (j=0; j<3; j++) a[j] = p[j] + x*R[j*4+0] + y*R[j*4+1] + l*beta*R[j*4+2]; + if (dFabs(dGeomCapsulePointDepth (ccyl,a[0],a[1],a[2]) - d) >= tol) + FAILED(); + + // ********** test point depth (2) + + d = (dRandReal()*2-1) * r; + for (j=0; j<3; j++) a[j] = dRandReal()-0.5; + dNormalize3 (a); + if (dCalcVectorDot3_14(a,R+2) > 0) { + for (j=0; j<3; j++) a[j] = p[j] + a[j]*(r-d) + l*0.5*R[j*4+2]; + } + else { + for (j=0; j<3; j++) a[j] = p[j] + a[j]*(r-d) - l*0.5*R[j*4+2]; + } + if (dFabs(dGeomCapsulePointDepth (ccyl,a[0],a[1],a[2]) - d) >= tol) + FAILED(); + + PASSED(); +} + + +int test_plane_point_depth() +{ + int j; + dVector3 n,p,q,a,b; // n = plane normal + dReal d; + + dSimpleSpace space(0); + dGeomID plane = dCreatePlane (0,0,0,1,0); + dSpaceAdd (space,plane); + + // ********** make a random plane + + for (j=0; j<3; j++) n[j] = dRandReal() - 0.5; + dNormalize3 (n); + d = dRandReal() - 0.5; + dGeomPlaneSetParams (plane,n[0],n[1],n[2],d); + dPlaneSpace (n,p,q); + + // ********** test point on plane has depth 0 + + a[0] = dRandReal() - 0.5; + a[1] = dRandReal() - 0.5; + a[2] = 0; + for (j=0; j<3; j++) b[j] = a[0]*p[j] + a[1]*q[j] + (a[2]+d)*n[j]; + if (dFabs(dGeomPlanePointDepth (plane,b[0],b[1],b[2])) >= tol) FAILED(); + + // ********** test arbitrary depth point + + a[0] = dRandReal() - 0.5; + a[1] = dRandReal() - 0.5; + a[2] = dRandReal() - 0.5; + for (j=0; j<3; j++) b[j] = a[0]*p[j] + a[1]*q[j] + (a[2]+d)*n[j]; + if (dFabs(dGeomPlanePointDepth (plane,b[0],b[1],b[2]) + a[2]) >= tol) + FAILED(); + + // ********** test depth-1 point + + a[0] = dRandReal() - 0.5; + a[1] = dRandReal() - 0.5; + a[2] = -1; + for (j=0; j<3; j++) b[j] = a[0]*p[j] + a[1]*q[j] + (a[2]+d)*n[j]; + if (dFabs(dGeomPlanePointDepth (plane,b[0],b[1],b[2]) - 1) >= tol) FAILED(); + + PASSED(); +} + +//**************************************************************************** +// ray tests + +int test_ray_and_sphere() +{ + int j; + dContactGeom contact; + dVector3 p,q,q2,n,v1; + dMatrix3 R; + dReal r,k; + + dSimpleSpace space(0); + dGeomID ray = dCreateRay (0,0); + dGeomID sphere = dCreateSphere (0,1); + dSpaceAdd (space,ray); + dSpaceAdd (space,sphere); + + // ********** make a random sphere of radius r at position p + + r = dRandReal()+0.1; + dGeomSphereSetRadius (sphere,r); + dMakeRandomVector (p,3,1.0); + dGeomSetPosition (sphere,p[0],p[1],p[2]); + dRFromAxisAndAngle (R,dRandReal()*2-1,dRandReal()*2-1, + dRandReal()*2-1,dRandReal()*10-5); + dGeomSetRotation (sphere,R); + + // ********** test zero length ray just inside sphere + + dGeomRaySetLength (ray,0); + dMakeRandomVector (q,3,1.0); + dNormalize3 (q); + for (j=0; j<3; j++) q[j] = 0.99*r * q[j] + p[j]; + dGeomSetPosition (ray,q[0],q[1],q[2]); + dRFromAxisAndAngle (R,dRandReal()*2-1,dRandReal()*2-1, + dRandReal()*2-1,dRandReal()*10-5); + dGeomSetRotation (ray,R); + if (dCollide (ray,sphere,1,&contact,sizeof(dContactGeom)) != 0) FAILED(); + + // ********** test zero length ray just outside that sphere + + dGeomRaySetLength (ray,0); + dMakeRandomVector (q,3,1.0); + dNormalize3 (q); + for (j=0; j<3; j++) q[j] = 1.01*r * q[j] + p[j]; + dGeomSetPosition (ray,q[0],q[1],q[2]); + dRFromAxisAndAngle (R,dRandReal()*2-1,dRandReal()*2-1, + dRandReal()*2-1,dRandReal()*10-5); + dGeomSetRotation (ray,R); + if (dCollide (ray,sphere,1,&contact,sizeof(dContactGeom)) != 0) FAILED(); + + // ********** test finite length ray totally contained inside the sphere + + dMakeRandomVector (q,3,1.0); + dNormalize3 (q); + k = dRandReal(); + for (j=0; j<3; j++) q[j] = k*r*0.99 * q[j] + p[j]; + dMakeRandomVector (q2,3,1.0); + dNormalize3 (q2); + k = dRandReal(); + for (j=0; j<3; j++) q2[j] = k*r*0.99 * q2[j] + p[j]; + for (j=0; j<3; j++) n[j] = q2[j] - q[j]; + dNormalize3 (n); + dGeomRaySet (ray,q[0],q[1],q[2],n[0],n[1],n[2]); + dGeomRaySetLength (ray,dCalcPointsDistance3(q,q2)); + if (dCollide (ray,sphere,1,&contact,sizeof(dContactGeom)) != 0) FAILED(); + + // ********** test finite length ray totally outside the sphere + + dMakeRandomVector (q,3,1.0); + dNormalize3 (q); + do { + dMakeRandomVector (n,3,1.0); + dNormalize3 (n); + } + while (dCalcVectorDot3(n,q) < 0); // make sure normal goes away from sphere + for (j=0; j<3; j++) q[j] = 1.01*r * q[j] + p[j]; + dGeomRaySet (ray,q[0],q[1],q[2],n[0],n[1],n[2]); + dGeomRaySetLength (ray,100); + if (dCollide (ray,sphere,1,&contact,sizeof(dContactGeom)) != 0) FAILED(); + + // ********** test ray from outside to just above surface + + dMakeRandomVector (q,3,1.0); + dNormalize3 (q); + for (j=0; j<3; j++) n[j] = -q[j]; + for (j=0; j<3; j++) q2[j] = 2*r * q[j] + p[j]; + dGeomRaySet (ray,q2[0],q2[1],q2[2],n[0],n[1],n[2]); + dGeomRaySetLength (ray,0.99*r); + if (dCollide (ray,sphere,1,&contact,sizeof(dContactGeom)) != 0) FAILED(); + + // ********** test ray from outside to just below surface + + dGeomRaySetLength (ray,1.01*r); + if (dCollide (ray,sphere,1,&contact,sizeof(dContactGeom)) != 1) FAILED(); + for (j=0; j<3; j++) q2[j] = r * q[j] + p[j]; + if (dCalcPointsDistance3 (contact.pos,q2) > tol) FAILED(); + + // ********** test contact point distance for random rays + + dMakeRandomVector (q,3,1.0); + dNormalize3 (q); + k = dRandReal()+0.5; + for (j=0; j<3; j++) q[j] = k*r * q[j] + p[j]; + dMakeRandomVector (n,3,1.0); + dNormalize3 (n); + dGeomRaySet (ray,q[0],q[1],q[2],n[0],n[1],n[2]); + dGeomRaySetLength (ray,100); + if (dCollide (ray,sphere,1,&contact,sizeof(dContactGeom))) { + k = dCalcPointsDistance3 (contact.pos,dGeomGetPosition(sphere)); + if (dFabs(k - r) > tol) FAILED(); + // also check normal signs + if (dCalcVectorDot3 (n,contact.normal) > 0) FAILED(); + // also check depth of contact point + if (dFabs (dGeomSpherePointDepth + (sphere,contact.pos[0],contact.pos[1],contact.pos[2])) > tol) + FAILED(); + + draw_all_objects (space); + } + + // ********** test tangential grazing - miss + + dMakeRandomVector (q,3,1.0); + dNormalize3 (q); + dPlaneSpace (q,n,v1); + for (j=0; j<3; j++) q[j] = 1.01*r * q[j] + p[j]; + for (j=0; j<3; j++) q[j] -= n[j]; + dGeomRaySet (ray,q[0],q[1],q[2],n[0],n[1],n[2]); + dGeomRaySetLength (ray,2); + if (dCollide (ray,sphere,1,&contact,sizeof(dContactGeom)) != 0) FAILED(); + + // ********** test tangential grazing - hit + + dMakeRandomVector (q,3,1.0); + dNormalize3 (q); + dPlaneSpace (q,n,v1); + for (j=0; j<3; j++) q[j] = 0.99*r * q[j] + p[j]; + for (j=0; j<3; j++) q[j] -= n[j]; + dGeomRaySet (ray,q[0],q[1],q[2],n[0],n[1],n[2]); + dGeomRaySetLength (ray,2); + if (dCollide (ray,sphere,1,&contact,sizeof(dContactGeom)) != 1) FAILED(); + + PASSED(); +} + + +int test_ray_and_box() +{ + int i,j; + dContactGeom contact; + dVector3 s,p,q,n,q2,q3,q4; // s = box sides + dMatrix3 R; + dReal k; + + dSimpleSpace space(0); + dGeomID ray = dCreateRay (0,0); + dGeomID box = dCreateBox (0,1,1,1); + dSpaceAdd (space,ray); + dSpaceAdd (space,box); + + // ********** make a random box + + for (j=0; j<3; j++) s[j] = dRandReal() + 0.1; + dGeomBoxSetLengths (box,s[0],s[1],s[2]); + dMakeRandomVector (p,3,1.0); + dGeomSetPosition (box,p[0],p[1],p[2]); + dRFromAxisAndAngle (R,dRandReal()*2-1,dRandReal()*2-1, + dRandReal()*2-1,dRandReal()*10-5); + dGeomSetRotation (box,R); + + // ********** test zero length ray just inside box + + dGeomRaySetLength (ray,0); + for (j=0; j<3; j++) q[j] = (dRandReal()-0.5)*s[j]; + i = dRandInt (3); + if (dRandReal() > 0.5) q[i] = 0.99*0.5*s[i]; else q[i] = -0.99*0.5*s[i]; + dMultiply0 (q2,dGeomGetRotation(box),q,3,3,1); + for (j=0; j<3; j++) q2[j] += p[j]; + dGeomSetPosition (ray,q2[0],q2[1],q2[2]); + dRFromAxisAndAngle (R,dRandReal()*2-1,dRandReal()*2-1, + dRandReal()*2-1,dRandReal()*10-5); + dGeomSetRotation (ray,R); + if (dCollide (ray,box,1,&contact,sizeof(dContactGeom)) != 0) FAILED(); + + // ********** test zero length ray just outside box + + dGeomRaySetLength (ray,0); + for (j=0; j<3; j++) q[j] = (dRandReal()-0.5)*s[j]; + i = dRandInt (3); + if (dRandReal() > 0.5) q[i] = 1.01*0.5*s[i]; else q[i] = -1.01*0.5*s[i]; + dMultiply0 (q2,dGeomGetRotation(box),q,3,3,1); + for (j=0; j<3; j++) q2[j] += p[j]; + dGeomSetPosition (ray,q2[0],q2[1],q2[2]); + dRFromAxisAndAngle (R,dRandReal()*2-1,dRandReal()*2-1, + dRandReal()*2-1,dRandReal()*10-5); + dGeomSetRotation (ray,R); + if (dCollide (ray,box,1,&contact,sizeof(dContactGeom)) != 0) FAILED(); + + // ********** test finite length ray totally contained inside the box + + for (j=0; j<3; j++) q[j] = (dRandReal()-0.5)*0.99*s[j]; + dMultiply0 (q2,dGeomGetRotation(box),q,3,3,1); + for (j=0; j<3; j++) q2[j] += p[j]; + for (j=0; j<3; j++) q3[j] = (dRandReal()-0.5)*0.99*s[j]; + dMultiply0 (q4,dGeomGetRotation(box),q3,3,3,1); + for (j=0; j<3; j++) q4[j] += p[j]; + for (j=0; j<3; j++) n[j] = q4[j] - q2[j]; + dNormalize3 (n); + dGeomRaySet (ray,q2[0],q2[1],q2[2],n[0],n[1],n[2]); + dGeomRaySetLength (ray,dCalcPointsDistance3(q2,q4)); + if (dCollide (ray,box,1,&contact,sizeof(dContactGeom)) != 0) FAILED(); + + // ********** test finite length ray totally outside the box + + for (j=0; j<3; j++) q[j] = (dRandReal()-0.5)*s[j]; + i = dRandInt (3); + if (dRandReal() > 0.5) q[i] = 1.01*0.5*s[i]; else q[i] = -1.01*0.5*s[i]; + dMultiply0 (q2,dGeomGetRotation(box),q,3,3,1); + for (j=0; j<3; j++) q3[j] = q2[j] + p[j]; + dNormalize3 (q2); + dGeomRaySet (ray,q3[0],q3[1],q3[2],q2[0],q2[1],q2[2]); + dGeomRaySetLength (ray,10); + if (dCollide (ray,box,1,&contact,sizeof(dContactGeom)) != 0) FAILED(); + + // ********** test ray from outside to just above surface + + for (j=0; j<3; j++) q[j] = (dRandReal()-0.5)*s[j]; + i = dRandInt (3); + if (dRandReal() > 0.5) q[i] = 1.01*0.5*s[i]; else q[i] = -1.01*0.5*s[i]; + dMultiply0 (q2,dGeomGetRotation(box),q,3,3,1); + for (j=0; j<3; j++) q3[j] = 2*q2[j] + p[j]; + k = dSqrt(q2[0]*q2[0] + q2[1]*q2[1] + q2[2]*q2[2]); + for (j=0; j<3; j++) q2[j] = -q2[j]; + dGeomRaySet (ray,q3[0],q3[1],q3[2],q2[0],q2[1],q2[2]); + dGeomRaySetLength (ray,k*0.99); + if (dCollide (ray,box,1,&contact,sizeof(dContactGeom)) != 0) FAILED(); + + // ********** test ray from outside to just below surface + + dGeomRaySetLength (ray,k*1.01); + if (dCollide (ray,box,1,&contact,sizeof(dContactGeom)) != 1) FAILED(); + + // ********** test contact point position for random rays + + for (j=0; j<3; j++) q[j] = dRandReal()*s[j]; + dMultiply0 (q2,dGeomGetRotation(box),q,3,3,1); + for (j=0; j<3; j++) q2[j] += p[j]; + for (j=0; j<3; j++) q3[j] = dRandReal()-0.5; + dNormalize3 (q3); + dGeomRaySet (ray,q2[0],q2[1],q2[2],q3[0],q3[1],q3[2]); + dGeomRaySetLength (ray,10); + if (dCollide (ray,box,1,&contact,sizeof(dContactGeom))) { + // check depth of contact point + if (dFabs (dGeomBoxPointDepth + (box,contact.pos[0],contact.pos[1],contact.pos[2])) > tol) + FAILED(); + // check position of contact point + for (j=0; j<3; j++) contact.pos[j] -= p[j]; + dMultiply1 (q,dGeomGetRotation(box),contact.pos,3,3,1); + if ( dFabs(dFabs (q[0]) - 0.5*s[0]) > tol && + dFabs(dFabs (q[1]) - 0.5*s[1]) > tol && + dFabs(dFabs (q[2]) - 0.5*s[2]) > tol) { + FAILED(); + } + // also check normal signs + if (dCalcVectorDot3 (q3,contact.normal) > 0) FAILED(); + + draw_all_objects (space); + } + + PASSED(); +} + + +int test_ray_and_ccylinder() +{ + int j; + dContactGeom contact; + dVector3 p,a,b,n; + dMatrix3 R; + dReal r,l,k,x,y; + + dSimpleSpace space(0); + dGeomID ray = dCreateRay (0,0); + dGeomID ccyl = dCreateCapsule (0,1,1); + dSpaceAdd (space,ray); + dSpaceAdd (space,ccyl); + + // ********** make a random capped cylinder + + r = dRandReal()*0.5 + 0.01; + l = dRandReal()*1 + 0.01; + dGeomCapsuleSetParams (ccyl,r,l); + dMakeRandomVector (p,3,1.0); + dGeomSetPosition (ccyl,p[0],p[1],p[2]); + dRFromAxisAndAngle (R,dRandReal()*2-1,dRandReal()*2-1, + dRandReal()*2-1,dRandReal()*10-5); + dGeomSetRotation (ccyl,R); + + // ********** test ray completely within ccyl + + for (j=0; j<3; j++) a[j] = dRandReal()-0.5; + dNormalize3 (a); + k = (dRandReal()-0.5)*l; + for (j=0; j<3; j++) a[j] = p[j] + r*0.99*a[j] + k*0.99*R[j*4+2]; + for (j=0; j<3; j++) b[j] = dRandReal()-0.5; + dNormalize3 (b); + k = (dRandReal()-0.5)*l; + for (j=0; j<3; j++) b[j] = p[j] + r*0.99*b[j] + k*0.99*R[j*4+2]; + dGeomRaySetLength (ray,dCalcPointsDistance3(a,b)); + for (j=0; j<3; j++) b[j] -= a[j]; + dNormalize3 (b); + dGeomRaySet (ray,a[0],a[1],a[2],b[0],b[1],b[2]); + if (dCollide (ray,ccyl,1,&contact,sizeof(dContactGeom)) != 0) FAILED(); + + // ********** test ray outside ccyl that just misses (between caps) + + k = dRandReal()*2*M_PI; + x = sin(k); + y = cos(k); + for (j=0; j<3; j++) a[j] = x*R[j*4+0] + y*R[j*4+1]; + k = (dRandReal()-0.5)*l; + for (j=0; j<3; j++) b[j] = -a[j]*r*2 + k*R[j*4+2] + p[j]; + dGeomRaySet (ray,b[0],b[1],b[2],a[0],a[1],a[2]); + dGeomRaySetLength (ray,r*0.99); + if (dCollide (ray,ccyl,1,&contact,sizeof(dContactGeom)) != 0) FAILED(); + + // ********** test ray outside ccyl that just hits (between caps) + + dGeomRaySetLength (ray,r*1.01); + if (dCollide (ray,ccyl,1,&contact,sizeof(dContactGeom)) != 1) FAILED(); + // check depth of contact point + if (dFabs (dGeomCapsulePointDepth + (ccyl,contact.pos[0],contact.pos[1],contact.pos[2])) > tol) + FAILED(); + + // ********** test ray outside ccyl that just misses (caps) + + for (j=0; j<3; j++) a[j] = dRandReal()-0.5; + dNormalize3 (a); + if (dCalcVectorDot3_14(a,R+2) < 0) { + for (j=0; j<3; j++) b[j] = p[j] - a[j]*2*r + l*0.5*R[j*4+2]; + } + else { + for (j=0; j<3; j++) b[j] = p[j] - a[j]*2*r - l*0.5*R[j*4+2]; + } + dGeomRaySet (ray,b[0],b[1],b[2],a[0],a[1],a[2]); + dGeomRaySetLength (ray,r*0.99); + if (dCollide (ray,ccyl,1,&contact,sizeof(dContactGeom)) != 0) FAILED(); + + // ********** test ray outside ccyl that just hits (caps) + + dGeomRaySetLength (ray,r*1.01); + if (dCollide (ray,ccyl,1,&contact,sizeof(dContactGeom)) != 1) FAILED(); + // check depth of contact point + if (dFabs (dGeomCapsulePointDepth + (ccyl,contact.pos[0],contact.pos[1],contact.pos[2])) > tol) + FAILED(); + + // ********** test random rays + + for (j=0; j<3; j++) a[j] = dRandReal()-0.5; + for (j=0; j<3; j++) n[j] = dRandReal()-0.5; + dNormalize3 (n); + dGeomRaySet (ray,a[0],a[1],a[2],n[0],n[1],n[2]); + dGeomRaySetLength (ray,10); + + if (dCollide (ray,ccyl,1,&contact,sizeof(dContactGeom))) { + // check depth of contact point + if (dFabs (dGeomCapsulePointDepth + (ccyl,contact.pos[0],contact.pos[1],contact.pos[2])) > tol) + FAILED(); + + // check normal signs + if (dCalcVectorDot3 (n,contact.normal) > 0) FAILED(); + + draw_all_objects (space); + } + + PASSED(); +} + +/* + Test rays within the cylinder + -completely inside + -exiting through side + -exiting through cap + -exiting through corner + Test rays outside the cylinder +*/ +int test_ray_and_cylinder() +{ + dVector3 a,b; + + dSimpleSpace space(0); + dGeomID ray = dCreateRay(space,4); + + // The first thing that happens is the ray is + // rotated into cylinder coordinates. We'll trust that's + // done right. The major axis is in the z-dir. + + + // Random tests + /*b[0]=4*dRandReal()-2; + b[1]=4*dRandReal()-2; + b[2]=4*dRandReal()-2; + a[0]=2*dRandReal()-1; + a[1]=2*dRandReal()-1; + a[2]=2*dRandReal()-1;*/ + + // Inside out + b[0]=dRandReal()-0.5; + b[1]=dRandReal()-0.5; + b[2]=dRandReal()-0.5; + a[0]=2*dRandReal()-1; + a[1]=2*dRandReal()-1; + a[2]=2*dRandReal()-1; + + // Outside in + /*b[0]=4*dRandReal()-2; + b[1]=4*dRandReal()-2; + b[2]=4*dRandReal()-2; + a[0]=-b[0]; + a[1]=-b[1]; + a[2]=-b[2];*/ + + + dGeomRaySet (ray,b[0],b[1],b[2],a[0],a[1],a[2]); + // This is just for visual inspection right now. + //if (dCollide (ray,cyl,1,&contact,sizeof(dContactGeom)) != 1) FAILED(); + + draw_all_objects (space); + + PASSED(); +} + + +int test_ray_and_plane() +{ + int j; + dContactGeom contact; + dVector3 n,p,q,a,b,g,h; // n,d = plane parameters + dMatrix3 R; + dReal d; + + dSimpleSpace space(0); + dGeomID ray = dCreateRay (0,0); + dGeomID plane = dCreatePlane (0,0,0,1,0); + dSpaceAdd (space,ray); + dSpaceAdd (space,plane); + + // ********** make a random plane + + for (j=0; j<3; j++) n[j] = dRandReal() - 0.5; + dNormalize3 (n); + d = dRandReal() - 0.5; + dGeomPlaneSetParams (plane,n[0],n[1],n[2],d); + dPlaneSpace (n,p,q); + + // ********** test finite length ray below plane + + dGeomRaySetLength (ray,0.09); + a[0] = dRandReal()-0.5; + a[1] = dRandReal()-0.5; + a[2] = -dRandReal()*0.5 - 0.1; + for (j=0; j<3; j++) b[j] = a[0]*p[j] + a[1]*q[j] + (a[2]+d)*n[j]; + dGeomSetPosition (ray,b[0],b[1],b[2]); + dRFromAxisAndAngle (R,dRandReal()*2-1,dRandReal()*2-1, + dRandReal()*2-1,dRandReal()*10-5); + dGeomSetRotation (ray,R); + if (dCollide (ray,plane,1,&contact,sizeof(dContactGeom)) != 0) FAILED(); + + // ********** test finite length ray above plane + + a[0] = dRandReal()-0.5; + a[1] = dRandReal()-0.5; + a[2] = dRandReal()*0.5 + 0.01; + for (j=0; j<3; j++) b[j] = a[0]*p[j] + a[1]*q[j] + (a[2]+d)*n[j]; + g[0] = dRandReal()-0.5; + g[1] = dRandReal()-0.5; + g[2] = dRandReal() + 0.01; + for (j=0; j<3; j++) h[j] = g[0]*p[j] + g[1]*q[j] + g[2]*n[j]; + dNormalize3 (h); + dGeomRaySet (ray,b[0],b[1],b[2],h[0],h[1],h[2]); + dGeomRaySetLength (ray,10); + if (dCollide (ray,plane,1,&contact,sizeof(dContactGeom)) != 0) FAILED(); + + // ********** test finite length ray that intersects plane + + a[0] = dRandReal()-0.5; + a[1] = dRandReal()-0.5; + a[2] = dRandReal()-0.5; + for (j=0; j<3; j++) b[j] = a[0]*p[j] + a[1]*q[j] + (a[2]+d)*n[j]; + g[0] = dRandReal()-0.5; + g[1] = dRandReal()-0.5; + g[2] = dRandReal()-0.5; + for (j=0; j<3; j++) h[j] = g[0]*p[j] + g[1]*q[j] + g[2]*n[j]; + dNormalize3 (h); + dGeomRaySet (ray,b[0],b[1],b[2],h[0],h[1],h[2]); + dGeomRaySetLength (ray,10); + if (dCollide (ray,plane,1,&contact,sizeof(dContactGeom))) { + // test that contact is on plane surface + if (dFabs (dCalcVectorDot3(contact.pos,n) - d) > tol) FAILED(); + // also check normal signs + if (dCalcVectorDot3 (h,contact.normal) > 0) FAILED(); + // also check contact point depth + if (dFabs (dGeomPlanePointDepth + (plane,contact.pos[0],contact.pos[1],contact.pos[2])) > tol) + FAILED(); + + draw_all_objects (space); + } + + // ********** test ray that just misses + + for (j=0; j<3; j++) b[j] = (1+d)*n[j]; + for (j=0; j<3; j++) h[j] = -n[j]; + dGeomRaySet (ray,b[0],b[1],b[2],h[0],h[1],h[2]); + dGeomRaySetLength (ray,0.99); + if (dCollide (ray,plane,1,&contact,sizeof(dContactGeom)) != 0) FAILED(); + + // ********** test ray that just hits + + dGeomRaySetLength (ray,1.01); + if (dCollide (ray,plane,1,&contact,sizeof(dContactGeom)) != 1) FAILED(); + + // ********** test polarity with typical ground plane + + dGeomPlaneSetParams (plane,0,0,1,0); + for (j=0; j<3; j++) a[j] = 0.1; + for (j=0; j<3; j++) b[j] = 0; + a[2] = 1; + b[2] = -1; + dGeomRaySet (ray,a[0],a[1],a[2],b[0],b[1],b[2]); + dGeomRaySetLength (ray,2); + if (dCollide (ray,plane,1,&contact,sizeof(dContactGeom)) != 1) FAILED(); + if (dFabs (contact.depth - 1) > tol) FAILED(); + a[2] = -1; + b[2] = 1; + dGeomRaySet (ray,a[0],a[1],a[2],b[0],b[1],b[2]); + if (dCollide (ray,plane,1,&contact,sizeof(dContactGeom)) != 1) FAILED(); + if (dFabs (contact.depth - 1) > tol) FAILED(); + + PASSED(); +} + +//**************************************************************************** +// a really inefficient, but hopefully correct implementation of +// dBoxTouchesBox(), that does 144 edge-face tests. + +// return 1 if edge v1 -> v2 hits the rectangle described by p1,p2,p3 + +static int edgeIntersectsRect (dVector3 v1, dVector3 v2, + dVector3 p1, dVector3 p2, dVector3 p3) +{ + int k; + dVector3 u1, u2, n, tmp; + + for (k=0; k < 3; k++) u1[k] = p3[k] - p1[k]; + for (k=0; k < 3; k++) u2[k] = p2[k] - p1[k]; + + dReal d1 = dSqrt(dCalcVectorDot3(u1, u1)); + dReal d2 = dSqrt(dCalcVectorDot3(u2, u2)); + dNormalize3(u1); + dNormalize3(u2); + + dReal error; +#ifdef dSINGLE + const dReal uEpsilon = 1e-5, pEpsilon = 1e-6, tmpEpsilon = 1.5e-4; +#else + const dReal uEpsilon = 1e-6, pEpsilon = 1e-8, tmpEpsilon = 1e-6; +#endif + + error = dFabs(dCalcVectorDot3(u1, u2)); + if (error > uEpsilon) dDebug(0, "bad u1/u2"); + + dCalcVectorCross3(n, u1, u2); + + for (k=0; k < 3; k++) tmp[k] = v2[k] - v1[k]; + + dReal d = -dCalcVectorDot3(n, p1); + + error = dFabs(dCalcVectorDot3(n, p1) + d); + if (error > pEpsilon) dDebug(0, "bad n wrt p1"); + + error = dFabs(dCalcVectorDot3(n, p2) + d); + if (error > pEpsilon) dDebug(0, "bad n wrt p2"); + + error = dFabs(dCalcVectorDot3(n, p3) + d); + if (error > pEpsilon) dDebug(0, "bad n wrt p3"); + + dReal alpha = -(d + dCalcVectorDot3(n, v1)) / dCalcVectorDot3(n, tmp); + for (k=0; k < 3; k++) tmp[k] = v1[k] + alpha * (v2[k] - v1[k]); + + error = dFabs(dCalcVectorDot3(n, tmp) + d); + if (error > tmpEpsilon) dDebug(0, "bad tmp"); + + if (alpha < 0) return 0; + if (alpha > 1) return 0; + + for (k=0; k < 3; k++) tmp[k] -= p1[k]; + dReal a1 = dCalcVectorDot3(u1, tmp); + dReal a2 = dCalcVectorDot3(u2, tmp); + if (a1 < 0 || a2 < 0 || a1 > d1 || a2 > d2) return 0; + + return 1; +} + + +// return 1 if box 1 is completely inside box 2 + +static int box1inside2 (const dVector3 p1, const dMatrix3 R1, + const dVector3 side1, const dVector3 p2, + const dMatrix3 R2, const dVector3 side2) +{ + for (int i=-1; i<=1; i+=2) { + for (int j=-1; j<=1; j+=2) { + for (int k=-1; k<=1; k+=2) { + dVector3 v,vv; + v[0] = i*0.5*side1[0]; + v[1] = j*0.5*side1[1]; + v[2] = k*0.5*side1[2]; + dMultiply0_331 (vv,R1,v); + vv[0] += p1[0] - p2[0]; + vv[1] += p1[1] - p2[1]; + vv[2] += p1[2] - p2[2]; + for (int axis=0; axis < 3; axis++) { + dReal z = dCalcVectorDot3_14(vv,R2+axis); + if (z < (-side2[axis]*0.5) || z > (side2[axis]*0.5)) return 0; + } + } + } + } + return 1; +} + + +// test if any edge from box 1 hits a face from box 2 + +static int testBoxesTouch2 (const dVector3 p1, const dMatrix3 R1, + const dVector3 side1, const dVector3 p2, + const dMatrix3 R2, const dVector3 side2) +{ + int j,k,j1,j2; + + // for 6 faces from box 2 + for (int fd=0; fd<3; fd++) { // direction for face + + for (int fo=0; fo<2; fo++) { // offset of face + // get four points on the face. first get 2 indexes that are not fd + int k1=0,k2=0; + if (fd==0) { k1 = 1; k2 = 2; } + if (fd==1) { k1 = 0; k2 = 2; } + if (fd==2) { k1 = 0; k2 = 1; } + dVector3 fp[4],tmp; + k=0; + for (j1=-1; j1<=1; j1+=2) { + for (j2=-1; j2<=1; j2+=2) { + fp[k][k1] = j1; + fp[k][k2] = j2; + fp[k][fd] = fo*2-1; + k++; + } + } + for (j=0; j<4; j++) { + for (k=0; k<3; k++) fp[j][k] *= 0.5*side2[k]; + dMultiply0_331 (tmp,R2,fp[j]); + for (k=0; k<3; k++) fp[j][k] = tmp[k] + p2[k]; + } + + // for 8 vertices + dReal v1[3]; + for (v1[0]=-1; v1[0] <= 1; v1[0] += 2) { + for (v1[1]=-1; v1[1] <= 1; v1[1] += 2) { + for (v1[2]=-1; v1[2] <= 1; v1[2] += 2) { + // for all possible +ve leading edges from those vertices + for (int ei=0; ei < 3; ei ++) { + if (v1[ei] < 0) { + // get vertex1 -> vertex2 = an edge from box 1 + dVector3 vv1,vv2; + for (k=0; k<3; k++) vv1[k] = v1[k] * 0.5*side1[k]; + for (k=0; k<3; k++) vv2[k] = (v1[k] + (k==ei)*2)*0.5*side1[k]; + dVector3 vertex1,vertex2; + dMultiply0_331 (vertex1,R1,vv1); + dMultiply0_331 (vertex2,R1,vv2); + for (k=0; k<3; k++) vertex1[k] += p1[k]; + for (k=0; k<3; k++) vertex2[k] += p1[k]; + + // see if vertex1 -> vertex2 interesects face + if (edgeIntersectsRect (vertex1,vertex2,fp[0],fp[1],fp[2])) + return 1; + } + } + } + } + } + } + } + + if (box1inside2 (p1,R1,side1,p2,R2,side2)) return 1; + if (box1inside2 (p2,R2,side2,p1,R1,side1)) return 1; + + return 0; +} + +//**************************************************************************** +// dBoxTouchesBox() test + +int test_dBoxTouchesBox() +{ + int k,bt1,bt2; + dVector3 p1,p2,side1,side2; + dMatrix3 R1,R2; + + dSimpleSpace space(0); + dGeomID box1 = dCreateBox (0,1,1,1); + dSpaceAdd (space,box1); + dGeomID box2 = dCreateBox (0,1,1,1); + dSpaceAdd (space,box2); + + dMakeRandomVector (p1,3,0.5); + dMakeRandomVector (p2,3,0.5); + for (k=0; k<3; k++) side1[k] = dRandReal() + 0.01; + for (k=0; k<3; k++) side2[k] = dRandReal() + 0.01; + dRFromAxisAndAngle (R1,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, + dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); + dRFromAxisAndAngle (R2,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, + dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); + + dGeomBoxSetLengths (box1,side1[0],side1[1],side1[2]); + dGeomBoxSetLengths (box2,side2[0],side2[1],side2[2]); + dGeomSetPosition (box1,p1[0],p1[1],p1[2]); + dGeomSetRotation (box1,R1); + dGeomSetPosition (box2,p2[0],p2[1],p2[2]); + dGeomSetRotation (box2,R2); + draw_all_objects (space); + + int t1 = testBoxesTouch2 (p1,R1,side1,p2,R2,side2); + int t2 = testBoxesTouch2 (p2,R2,side2,p1,R1,side1); + bt1 = t1 || t2; + bt2 = dBoxTouchesBox (p1,R1,side1,p2,R2,side2); + + if (bt1 != bt2) FAILED(); + + /* + // some more debugging info if necessary + if (bt1 && bt2) printf ("agree - boxes touch\n"); + if (!bt1 && !bt2) printf ("agree - boxes don't touch\n"); + if (bt1 && !bt2) printf ("disagree - boxes touch but dBoxTouchesBox " + "says no\n"); + if (!bt1 && bt2) printf ("disagree - boxes don't touch but dBoxTouchesBox " + "says yes\n"); + */ + + PASSED(); +} + +//**************************************************************************** +// test box-box collision + +int test_dBoxBox() +{ + int k,bt; + dVector3 p1,p2,side1,side2,normal,normal2; + dMatrix3 R1,R2; + dReal depth,depth2; + int code; + dContactGeom contact[48]; + + dSimpleSpace space(0); + dGeomID box1 = dCreateBox (0,1,1,1); + dSpaceAdd (space,box1); + dGeomID box2 = dCreateBox (0,1,1,1); + dSpaceAdd (space,box2); + + dMakeRandomVector (p1,3,0.5); + dMakeRandomVector (p2,3,0.5); + for (k=0; k<3; k++) side1[k] = dRandReal() + 0.01; + for (k=0; k<3; k++) side2[k] = dRandReal() + 0.01; + + dRFromAxisAndAngle (R1,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, + dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); + dRFromAxisAndAngle (R2,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, + dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); + + // dRSetIdentity (R1); // we can also try this + // dRSetIdentity (R2); + + dGeomBoxSetLengths (box1,side1[0],side1[1],side1[2]); + dGeomBoxSetLengths (box2,side2[0],side2[1],side2[2]); + dGeomSetPosition (box1,p1[0],p1[1],p1[2]); + dGeomSetRotation (box1,R1); + dGeomSetPosition (box2,p2[0],p2[1],p2[2]); + dGeomSetRotation (box2,R2); + + code = 0; + depth = 0; + bt = dBoxBox (p1,R1,side1,p2,R2,side2,normal,&depth,&code,8,contact, + sizeof(dContactGeom)); + if (bt==1) { + p2[0] += normal[0] * 0.96 * depth; + p2[1] += normal[1] * 0.96 * depth; + p2[2] += normal[2] * 0.96 * depth; + bt = dBoxBox (p1,R1,side1,p2,R2,side2,normal2,&depth2,&code,8,contact, + sizeof(dContactGeom)); + + /* + dGeomSetPosition (box2,p2[0],p2[1],p2[2]); + draw_all_objects (space); + */ + + if (bt != 1) { + FAILED(); + dGeomSetPosition (box2,p2[0],p2[1],p2[2]); + draw_all_objects (space); + } + + p2[0] += normal[0] * 0.08 * depth; + p2[1] += normal[1] * 0.08 * depth; + p2[2] += normal[2] * 0.08 * depth; + bt = dBoxBox (p1,R1,side1,p2,R2,side2,normal2,&depth2,&code,8,contact, + sizeof(dContactGeom)); + if (bt != 0) FAILED(); + + // dGeomSetPosition (box2,p2[0],p2[1],p2[2]); + // draw_all_objects (space); + } + + // printf ("code=%2d depth=%.4f ",code,depth); + + PASSED(); +} + +//**************************************************************************** +// graphics + +int space_pressed = 0; + + +// start simulation - set viewpoint + +static void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + static float xyz[3] = {2.4807,-1.8023,2.7600}; + static float hpr[3] = {141.5000,-18.5000,0.0000}; + dsSetViewpoint (xyz,hpr); +} + + +// called when a key pressed + +static void command (int cmd) +{ + if (cmd == ' ') space_pressed = 1; +} + + +// simulation loop + +static void simLoop (int) +{ + do { + draw_all_objects_called = 0; + unsigned long seed = dRandGetSeed(); + testslot[graphical_test].test_fn(); + if (draw_all_objects_called) { + if (space_pressed) space_pressed = 0; else dRandSetSeed (seed); + } + } + while (!draw_all_objects_called); +} + +//**************************************************************************** +// do all the tests + +void do_tests (int argc, char **argv) +{ + int i,j; + + // process command line arguments + if (argc >= 2) { + graphical_test = atoi (argv[1]); + } + + if (graphical_test) { + // do one test gaphically and interactively + + if (graphical_test < 1 || graphical_test >= MAX_TESTS || + !testslot[graphical_test].name) { + dError (0,"invalid test number"); + } + + printf ("performing test: %s\n",testslot[graphical_test].name); + + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + dsSetSphereQuality (3); + dsSetCapsuleQuality (8); + dsSimulationLoop (argc,argv,1280,900,&fn); + } + else { + // do all tests noninteractively + + for (i=0; i<MAX_TESTS; i++) testslot[i].number = i; + + // first put the active tests into a separate array + int n=0; + for (i=0; i<MAX_TESTS; i++) if (testslot[i].name) n++; + TestSlot **ts = (TestSlot**) malloc (n * sizeof(TestSlot*)); + j = 0; + for (i=0; i<MAX_TESTS; i++) if (testslot[i].name) ts[j++] = testslot+i; + if (j != n) dDebug (0,"internal"); + + // do two test batches. the first test batch has far fewer reps and will + // catch problems quickly. if all tests in the first batch passes, the + // second batch is run. + + for (i=0; i<n; i++) ts[i]->failcount = 0; + int total_reps=0; + for (int batch=0; batch<2; batch++) { + int reps = (batch==0) ? TEST_REPS1 : TEST_REPS2; + total_reps += reps; + printf ("testing batch %d (%d reps)...\n",batch+1,reps); + + // run tests + for (j=0; j<reps; j++) { + for (i=0; i<n; i++) { + current_test = ts[i]->number; + if (ts[i]->test_fn() != 1) ts[i]->failcount++; + } + } + + // check for failures + int total_fail_count=0; + for (i=0; i<n; i++) total_fail_count += ts[i]->failcount; + if (total_fail_count) break; + } + + // print results + for (i=0; i<n; i++) { + printf ("%3d: %-30s: ",ts[i]->number,ts[i]->name); + if (ts[i]->failcount) { + printf ("FAILED (%.2f%%) at line %d\n", + double(ts[i]->failcount)/double(total_reps)*100.0, + ts[i]->last_failed_line); + } + else { + printf ("ok\n"); + } + } + } +} + +//**************************************************************************** + +int main (int argc, char **argv) +{ + // setup all tests + + memset (testslot,0,sizeof(testslot)); + dInitODE2(0); + + MAKE_TEST(1,test_sphere_point_depth); + MAKE_TEST(2,test_box_point_depth); + MAKE_TEST(3,test_ccylinder_point_depth); + MAKE_TEST(4,test_plane_point_depth); + + MAKE_TEST(10,test_ray_and_sphere); + MAKE_TEST(11,test_ray_and_box); + MAKE_TEST(12,test_ray_and_ccylinder); + MAKE_TEST(13,test_ray_and_plane); + MAKE_TEST(14,test_ray_and_cylinder); + + MAKE_TEST(100,test_dBoxTouchesBox); + MAKE_TEST(101,test_dBoxBox); + + do_tests (argc,argv); + dCloseODE(); + return 0; +} diff --git a/libs/ode-0.16.1/ode/demo/demo_convex.cpp b/libs/ode-0.16.1/ode/demo/demo_convex.cpp new file mode 100644 index 0000000..eea5c6e --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_convex.cpp @@ -0,0 +1,307 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// Convex demo. +// Serves as a test for the convex geometry. +// By Bram Stolk. + +#include <assert.h> +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#include "halton235_geom.h" + +#ifdef dDOUBLE +# define dsDrawConvex dsDrawConvexD +# define dsDrawLine dsDrawLineD +#endif + + +#ifdef _MSC_VER +# pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + + +// Height at which we drop the composite block. +const dReal H=4.20; + +static dWorldID world; +static dSpaceID space; + +static dBodyID mbody; + +static dBodyID hbody[ halton_numc ]; +static dGeomID hgeom[ halton_numc ]; + +static dJointGroupID contactgroup; + +static bool drawpos=false; +static bool solidkernel=false; + + +// this is called by dSpaceCollide when two objects in space are +// potentially colliding. + +static void nearCallback(void *data, dGeomID o1, dGeomID o2) +{ + assert(o1); + assert(o2); + if (dGeomIsSpace(o1) || dGeomIsSpace(o2)) + { + // colliding a space with something + dSpaceCollide2(o1,o2,data,&nearCallback); + // Note we do not want to test intersections within a space, + // only between spaces. + return; + } + + const int N = 32; + dContact contact[N]; + int n = dCollide (o1,o2,N,&(contact[0].geom),sizeof(dContact)); + if (n > 0) + { + for (int i=0; i<n; i++) + { + contact[i].surface.slip1 = 0.7; + contact[i].surface.slip2 = 0.7; + contact[i].surface.mode = dContactSoftERP | dContactSoftCFM | dContactApprox1 | dContactSlip1 | dContactSlip2; + contact[i].surface.mu = 500.0; // was: dInfinity + contact[i].surface.soft_erp = 0.50; + contact[i].surface.soft_cfm = 0.03; + dJointID c = dJointCreateContact (world,contactgroup,&contact[i]); + dJointAttach + ( + c, + dGeomGetBody(contact[i].geom.g1), + dGeomGetBody(contact[i].geom.g2) + ); + } + } +} + + +// start simulation - set viewpoint + +static void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + static float xyz[3] = {-8,0,5}; + static float hpr[3] = {0.0f,-29.5000f,0.0000f}; + dsSetViewpoint (xyz,hpr); + fprintf(stderr,"Press SPACE to reset the simulation.\n"); +} + + +static void reset() +{ + dQuaternion q; + dQSetIdentity(q); + dBodySetPosition(mbody,0,0,0+H); + dBodySetQuaternion(mbody, q); + dBodySetLinearVel(mbody, 0,0,0); + dBodySetAngularVel(mbody, 0,0,0); + dBodyEnable(mbody); + for ( int i=0; i<halton_numc; ++i ) + { + dBodyID body = hbody[i]; + if ( !body ) continue; + dBodySetPosition(body, halton_pos[i][0], halton_pos[i][1], halton_pos[i][2]+H); + dBodySetQuaternion(body, q); + dBodySetLinearVel(body, 0,0,0); + dBodySetAngularVel(body, 0,0,0); + dBodyEnable(body); + } +} + + +// called when a key pressed + +static void command(int cmd) +{ + switch (cmd) + { + case ' ': + reset(); + break; + default: + break; + } +} + + + +static void simLoop(int pause) +{ + double simstep = 1/240.0; + double dt = dsElapsedTime(); + + int nrofsteps = (int) ceilf(dt/simstep); + nrofsteps = nrofsteps > 8 ? 8 : nrofsteps; + + for (int i=0; i<nrofsteps && !pause; i++) + { + dSpaceCollide (space,0,&nearCallback); + dWorldQuickStep (world, simstep); + dJointGroupEmpty (contactgroup); + } + + dsSetColor (1,1,1); + // Draw the convex objects. + for ( int i=0; i<halton_numc; ++i ) + { + dGeomID geom = hgeom[i]; + dBodyID body = dGeomGetBody(geom); + //const dReal *pos = dBodyGetPosition(body); + //const dReal *rot = dBodyGetRotation(body); + const dReal *pos = dGeomGetPosition(geom); + const dReal *rot = dGeomGetRotation(geom); + dsDrawConvex + ( + pos, rot, + halton_planes[i], + halton_numf[i], + halton_verts[i], + halton_numv[i], + halton_faces[i] + ); + } + + if (drawpos) + { + dsSetColor(1,0,0.2); + dsSetTexture(DS_NONE); + const dReal l = 0.35; + for ( int i=0; i<halton_numc; ++i ) + { + dBodyID body = hbody[i]; + const dReal *pos = dBodyGetPosition(body); + dReal x0[3] = { pos[0]-l, pos[1], pos[2] }; + dReal x1[3] = { pos[0]+l, pos[1], pos[2] }; + dReal y0[3] = { pos[0], pos[1]-l, pos[2] }; + dReal y1[3] = { pos[0], pos[1]+l, pos[2] }; + dReal z0[3] = { pos[0], pos[1], pos[2]-l }; + dReal z1[3] = { pos[0], pos[1], pos[2]+l }; + dsDrawLine(x0,x1); + dsDrawLine(y0,y1); + dsDrawLine(z0,z1); + } + } +} + + +int main (int argc, char **argv) +{ + dMass m; + + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + // create world + dInitODE2(0); + world = dWorldCreate(); + space = dHashSpaceCreate (0); + dHashSpaceSetLevels(space, -3, 5); + dCreatePlane(space,0,0,1,0); // Add a ground plane. + + contactgroup = dJointGroupCreate (0); + dWorldSetGravity(world,0,0,-9.8); + dWorldSetQuickStepNumIterations(world, 32); + dWorldSetContactMaxCorrectingVel(world, 40); + dWorldSetMaxAngularSpeed(world, 62.8); + dWorldSetERP(world, 0.7); + dWorldSetQuickStepW(world, 0.75); // For increased stability. + + dWorldSetAutoDisableFlag( world, true ); + dWorldSetAutoDisableLinearThreshold( world, 0.01 ); + dWorldSetAutoDisableAngularThreshold( world, 0.03 ); + dWorldSetAutoDisableTime( world, 0.15f ); + + const float kernelrad = 0.7; + + mbody = dBodyCreate(world); + dBodySetPosition(mbody, 0,0,0+H); + dMassSetSphere( &m, 5, kernelrad ); + dBodySetMass( mbody, &m ); + + for (int i=0; i<halton_numc; ++i ) + { + dGeomID geom = dCreateConvex + ( + space, + halton_planes[i], + halton_numf[i], + halton_verts[i], + halton_numv[i], + halton_faces[i] + ); + hgeom[i] = geom; + const dReal x = halton_pos[i][0]; + const dReal y = halton_pos[i][1]; + const dReal z = halton_pos[i][2]; + const dReal dsqr = x*x + y*y + z*z; + + if ( dsqr < kernelrad*kernelrad && solidkernel ) + { + dGeomSetBody(geom, mbody); + dGeomSetOffsetPosition(geom, x,y,z); + } + else + { + dBodyID body = dBodyCreate(world); + hbody[i] = body; + dBodySetPosition(body, x,y,z+H); + dReal volu = halton_volu[i]; + dReal rad = pow( volu * 3 / (4*M_PI), (1/3.0) ); + dMassSetSphere( &m,5,rad ); + dBodySetMass( body,&m ); +#if 1 + dBodySetLinearDamping (body, 0.0005); + dBodySetAngularDamping(body, 0.0300); +#endif + dGeomSetBody(geom,body); + } + } + + // run simulation + const int w=1280; + const int h=720; + dsSimulationLoop (argc,argv,w,h,&fn); + + dJointGroupEmpty (contactgroup); + dJointGroupDestroy (contactgroup); + dSpaceDestroy (space); + dWorldDestroy (world); + dCloseODE(); + return 0; +} + + diff --git a/libs/ode-0.16.1/ode/demo/demo_crash.cpp b/libs/ode-0.16.1/ode/demo/demo_crash.cpp new file mode 100644 index 0000000..38ec1ad --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_crash.cpp @@ -0,0 +1,652 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// This is a demo of the QuickStep and StepFast methods, +// originally by David Whittaker. + + +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + +// select correct drawing functions + +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#define dsDrawSphere dsDrawSphereD +#define dsDrawCylinder dsDrawCylinderD +#define dsDrawCapsule dsDrawCapsuleD +#endif + + +// some constants + +#define LENGTH 3.5 // chassis length +#define WIDTH 2.5 // chassis width +#define HEIGHT 1.0 // chassis height +#define RADIUS 0.5 // wheel radius +#define STARTZ 1.0 // starting height of chassis +#define CMASS 1 // chassis mass +#define WMASS 1 // wheel mass +#define COMOFFSET -5 // center of mass offset +#define WALLMASS 1 // wall box mass +#define BALLMASS 1 // ball mass +#define FMAX 25 // car engine fmax +#define ROWS 1 // rows of cars +#define COLS 1 // columns of cars +#define ITERS 20 // number of iterations +#define WBOXSIZE 1.0 // size of wall boxes +#define WALLWIDTH 12 // width of wall +#define WALLHEIGHT 10 // height of wall +#define DISABLE_THRESHOLD 0.008 // maximum velocity (squared) a body can have and be disabled +#define DISABLE_STEPS 10 // number of steps a box has to have been disable-able before it will be disabled +#define CANNON_X -10 // x position of cannon +#define CANNON_Y 5 // y position of cannon +#define CANNON_BALL_MASS 10 // mass of the cannon ball +#define CANNON_BALL_RADIUS 0.5 + +static const dVector3 xunit = { 1, 0, 0 }, yunit = { 0, 1, 0 }, zpunit = { 0, 0, 1 }, zmunit = { 0, 0, -1 }; + +//#define BOX +#define CARS +#define WALL +//#define BALLS +//#define BALLSTACK +//#define ONEBALL +//#define CENTIPEDE +#define CANNON + +// dynamics and collision objects (chassis, 3 wheels, environment) + +static dWorldID world; +static dSpaceID space; +static dThreadingImplementationID threading; +static dThreadingThreadPoolID pool; +static dBodyID body[10000]; +static int bodies; +static dJointID joint[100000]; +static int joints; +static dJointGroupID contactgroup; +static dGeomID ground; +static dGeomID box[10000]; +static int boxes; +static dGeomID sphere[10000]; +static int spheres; +static dGeomID wall_boxes[10000]; +static dBodyID wall_bodies[10000]; +static dGeomID cannon_ball_geom; +static dBodyID cannon_ball_body; +static int wb_stepsdis[10000]; +static int wb; +static bool doFast; +static dBodyID b; +static dMass m; + + +// things that the user controls + +static dReal turn = 0, speed = 0; // user commands +static dReal cannon_angle=0,cannon_elevation=-1.2; + + + +// this is called by dSpaceCollide when two objects in space are +// potentially colliding. + +static void nearCallback (void *, dGeomID o1, dGeomID o2) +{ + int i,n; + + dBodyID b1 = dGeomGetBody(o1); + dBodyID b2 = dGeomGetBody(o2); + if (b1 && b2 && dAreConnected(b1, b2)) + return; + + const int N = 4; + dContact contact[N]; + n = dCollide (o1,o2,N,&contact[0].geom,sizeof(dContact)); + if (n > 0) { + for (i=0; i<n; i++) { + contact[i].surface.mode = dContactSlip1 | dContactSlip2 | dContactSoftERP | dContactSoftCFM | dContactApprox1; + if (dGeomGetClass(o1) == dSphereClass || dGeomGetClass(o2) == dSphereClass) + contact[i].surface.mu = 20; + else + contact[i].surface.mu = 0.5; + contact[i].surface.slip1 = 0.0; + contact[i].surface.slip2 = 0.0; + contact[i].surface.soft_erp = 0.8; + contact[i].surface.soft_cfm = 0.01; + dJointID c = dJointCreateContact (world,contactgroup,contact+i); + dJointAttach (c,dGeomGetBody(o1),dGeomGetBody(o2)); + } + } +} + + +// start simulation - set viewpoint + +static void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + static float xyz[3] = {3.8548f,9.0843f,7.5900f}; + static float hpr[3] = {-145.5f,-22.5f,0.25f}; + dsSetViewpoint (xyz,hpr); + printf ("Press:\t'a' to increase speed.\n" + "\t'z' to decrease speed.\n" + "\t',' to steer left.\n" + "\t'.' to steer right.\n" + "\t' ' to reset speed and steering.\n" + "\t'[' to turn the cannon left.\n" + "\t']' to turn the cannon right.\n" + "\t'1' to raise the cannon.\n" + "\t'2' to lower the cannon.\n" + "\t'x' to shoot from the cannon.\n" + "\t'f' to toggle fast step mode.\n" + "\t'r' to reset simulation.\n"); +} + + +void makeCar(dReal x, dReal y, int &bodyI, int &jointI, int &boxI, int &sphereI) +{ + int i; + dMass m; + + // chassis body + body[bodyI] = dBodyCreate (world); + dBodySetPosition (body[bodyI],x,y,STARTZ); + dMassSetBox (&m,1,LENGTH,WIDTH,HEIGHT); + dMassAdjust (&m,CMASS/2.0); + dBodySetMass (body[bodyI],&m); + box[boxI] = dCreateBox (space,LENGTH,WIDTH,HEIGHT); + dGeomSetBody (box[boxI],body[bodyI]); + + // wheel bodies + for (i=1; i<=4; i++) { + body[bodyI+i] = dBodyCreate (world); + dQuaternion q; + dQFromAxisAndAngle (q,1,0,0,M_PI*0.5); + dBodySetQuaternion (body[bodyI+i],q); + dMassSetSphere (&m,1,RADIUS); + dMassAdjust (&m,WMASS); + dBodySetMass (body[bodyI+i],&m); + sphere[sphereI+i-1] = dCreateSphere (space,RADIUS); + dGeomSetBody (sphere[sphereI+i-1],body[bodyI+i]); + } + dBodySetPosition (body[bodyI+1],x+0.4*LENGTH-0.5*RADIUS,y+WIDTH*0.5,STARTZ-HEIGHT*0.5); + dBodySetPosition (body[bodyI+2],x+0.4*LENGTH-0.5*RADIUS,y-WIDTH*0.5,STARTZ-HEIGHT*0.5); + dBodySetPosition (body[bodyI+3],x-0.4*LENGTH+0.5*RADIUS,y+WIDTH*0.5,STARTZ-HEIGHT*0.5); + dBodySetPosition (body[bodyI+4],x-0.4*LENGTH+0.5*RADIUS,y-WIDTH*0.5,STARTZ-HEIGHT*0.5); + + // front and back wheel hinges + for (i=0; i<4; i++) { + joint[jointI+i] = dJointCreateHinge2 (world,0); + dJointAttach (joint[jointI+i],body[bodyI],body[bodyI+i+1]); + const dReal *a = dBodyGetPosition (body[bodyI+i+1]); + dJointSetHinge2Anchor (joint[jointI+i],a[0],a[1],a[2]); + dJointSetHinge2Axes (joint[jointI+i], (i<2 ? zpunit : zmunit), yunit); + dJointSetHinge2Param (joint[jointI+i],dParamSuspensionERP,0.8); + dJointSetHinge2Param (joint[jointI+i],dParamSuspensionCFM,1e-5); + dJointSetHinge2Param (joint[jointI+i],dParamVel2,0); + dJointSetHinge2Param (joint[jointI+i],dParamFMax2,FMAX); + } + + //center of mass offset body. (hang another copy of the body COMOFFSET units below it by a fixed joint) + dBodyID b = dBodyCreate (world); + dBodySetPosition (b,x,y,STARTZ+COMOFFSET); + dMassSetBox (&m,1,LENGTH,WIDTH,HEIGHT); + dMassAdjust (&m,CMASS/2.0); + dBodySetMass (b,&m); + dJointID j = dJointCreateFixed(world, 0); + dJointAttach(j, body[bodyI], b); + dJointSetFixed(j); + //box[boxI+1] = dCreateBox(space,LENGTH,WIDTH,HEIGHT); + //dGeomSetBody (box[boxI+1],b); + + bodyI += 5; + jointI += 4; + boxI += 1; + sphereI += 4; +} + +static +void shutdownSimulation() +{ + // destroy world if it exists + if (bodies) + { + dThreadingImplementationShutdownProcessing(threading); + dThreadingFreeThreadPool(pool); + dWorldSetStepThreadingImplementation(world, NULL, NULL); + dThreadingFreeImplementation(threading); + + dJointGroupDestroy (contactgroup); + dSpaceDestroy (space); + dWorldDestroy (world); + + bodies = 0; + } +} + +static +void setupSimulation() +{ + int i; + for (i = 0; i < 1000; i++) + wb_stepsdis[i] = 0; + + // recreate world + + world = dWorldCreate(); + +// space = dHashSpaceCreate( 0 ); +// space = dSimpleSpaceCreate( 0 ); + space = dSweepAndPruneSpaceCreate( 0, dSAP_AXES_XYZ ); + + contactgroup = dJointGroupCreate (0); + dWorldSetGravity (world,0,0,-1.5); + dWorldSetCFM (world, 1e-5); + dWorldSetERP (world, 0.8); + dWorldSetQuickStepNumIterations (world,ITERS); + + threading = dThreadingAllocateMultiThreadedImplementation(); + pool = dThreadingAllocateThreadPool(4, 0, dAllocateFlagBasicData, NULL); + dThreadingThreadPoolServeMultiThreadedImplementation(pool, threading); + // dWorldSetStepIslandsProcessingMaxThreadCount(world, 1); + dWorldSetStepThreadingImplementation(world, dThreadingImplementationGetFunctions(threading), threading); + + + ground = dCreatePlane (space,0,0,1,0); + + bodies = 0; + joints = 0; + boxes = 0; + spheres = 0; + wb = 0; + +#ifdef CARS + for (dReal x = 0.0; x < COLS*(LENGTH+RADIUS); x += LENGTH+RADIUS) + for (dReal y = -((ROWS-1)*(WIDTH/2+RADIUS)); y <= ((ROWS-1)*(WIDTH/2+RADIUS)); y += WIDTH+RADIUS*2) + makeCar(x, y, bodies, joints, boxes, spheres); +#endif +#ifdef WALL + bool offset = false; + for (dReal z = WBOXSIZE/2.0; z <= WALLHEIGHT; z+=WBOXSIZE) + { + offset = !offset; + for (dReal y = (-WALLWIDTH+z)/2; y <= (WALLWIDTH-z)/2; y+=WBOXSIZE) + { + wall_bodies[wb] = dBodyCreate (world); + dBodySetPosition (wall_bodies[wb],-20,y,z); + dMassSetBox (&m,1,WBOXSIZE,WBOXSIZE,WBOXSIZE); + dMassAdjust (&m, WALLMASS); + dBodySetMass (wall_bodies[wb],&m); + wall_boxes[wb] = dCreateBox (space,WBOXSIZE,WBOXSIZE,WBOXSIZE); + dGeomSetBody (wall_boxes[wb],wall_bodies[wb]); + //dBodyDisable(wall_bodies[wb++]); + wb++; + } + } + dMessage(0,"wall boxes: %i", wb); +#endif +#ifdef BALLS + for (dReal x = -7; x <= -4; x+=1) + for (dReal y = -1.5; y <= 1.5; y+=1) + for (dReal z = 1; z <= 4; z+=1) + { + b = dBodyCreate (world); + dBodySetPosition (b,x*RADIUS*2,y*RADIUS*2,z*RADIUS*2); + dMassSetSphere (&m,1,RADIUS); + dMassAdjust (&m, BALLMASS); + dBodySetMass (b,&m); + sphere[spheres] = dCreateSphere (space,RADIUS); + dGeomSetBody (sphere[spheres++],b); + } +#endif +#ifdef ONEBALL + b = dBodyCreate (world); + dBodySetPosition (b,0,0,2); + dMassSetSphere (&m,1,RADIUS); + dMassAdjust (&m, 1); + dBodySetMass (b,&m); + sphere[spheres] = dCreateSphere (space,RADIUS); + dGeomSetBody (sphere[spheres++],b); +#endif +#ifdef BALLSTACK + for (dReal z = 1; z <= 6; z+=1) + { + b = dBodyCreate (world); + dBodySetPosition (b,0,0,z*RADIUS*2); + dMassSetSphere (&m,1,RADIUS); + dMassAdjust (&m, 0.1); + dBodySetMass (b,&m); + sphere[spheres] = dCreateSphere (space,RADIUS); + dGeomSetBody (sphere[spheres++],b); + } +#endif +#ifdef CENTIPEDE + dBodyID lastb = 0; + for (dReal y = 0; y < 10*LENGTH; y+=LENGTH+0.1) + { + // chassis body + + b = body[bodies] = dBodyCreate (world); + dBodySetPosition (body[bodies],-15,y,STARTZ); + dMassSetBox (&m,1,WIDTH,LENGTH,HEIGHT); + dMassAdjust (&m,CMASS); + dBodySetMass (body[bodies],&m); + box[boxes] = dCreateBox (space,WIDTH,LENGTH,HEIGHT); + dGeomSetBody (box[boxes++],body[bodies++]); + + for (dReal x = -17; x > -20; x-=RADIUS*2) + { + body[bodies] = dBodyCreate (world); + dBodySetPosition(body[bodies], x, y, STARTZ); + dMassSetSphere(&m, 1, RADIUS); + dMassAdjust(&m, WMASS); + dBodySetMass(body[bodies], &m); + sphere[spheres] = dCreateSphere (space, RADIUS); + dGeomSetBody (sphere[spheres++], body[bodies]); + + joint[joints] = dJointCreateHinge2 (world,0); + if (x == -17) + dJointAttach (joint[joints],b,body[bodies]); + else + dJointAttach (joint[joints],body[bodies-2],body[bodies]); + const dReal *a = dBodyGetPosition (body[bodies++]); + dJointSetHinge2Anchor (joint[joints],a[0],a[1],a[2]); + dJointSetHinge2Axes (joint[joints], zpunit, xunit); + dJointSetHinge2Param (joint[joints],dParamSuspensionERP,1.0); + dJointSetHinge2Param (joint[joints],dParamSuspensionCFM,1e-5); + dJointSetHinge2Param (joint[joints],dParamLoStop,0); + dJointSetHinge2Param (joint[joints],dParamHiStop,0); + dJointSetHinge2Param (joint[joints],dParamVel2,-10.0); + dJointSetHinge2Param (joint[joints++],dParamFMax2,FMAX); + + body[bodies] = dBodyCreate (world); + dBodySetPosition(body[bodies], -30 - x, y, STARTZ); + dMassSetSphere(&m, 1, RADIUS); + dMassAdjust(&m, WMASS); + dBodySetMass(body[bodies], &m); + sphere[spheres] = dCreateSphere (space, RADIUS); + dGeomSetBody (sphere[spheres++], body[bodies]); + + joint[joints] = dJointCreateHinge2 (world,0); + if (x == -17) + dJointAttach (joint[joints],b,body[bodies]); + else + dJointAttach (joint[joints],body[bodies-2],body[bodies]); + const dReal *b = dBodyGetPosition (body[bodies++]); + dJointSetHinge2Anchor (joint[joints],b[0],b[1],b[2]); + dJointSetHinge2Axes (joint[joints], zpunit, xunit); + dJointSetHinge2Param (joint[joints],dParamSuspensionERP,1.0); + dJointSetHinge2Param (joint[joints],dParamSuspensionCFM,1e-5); + dJointSetHinge2Param (joint[joints],dParamLoStop,0); + dJointSetHinge2Param (joint[joints],dParamHiStop,0); + dJointSetHinge2Param (joint[joints],dParamVel2,10.0); + dJointSetHinge2Param (joint[joints++],dParamFMax2,FMAX); + } + if (lastb) + { + dJointID j = dJointCreateFixed(world,0); + dJointAttach (j, b, lastb); + dJointSetFixed(j); + } + lastb = b; + } +#endif +#ifdef BOX + body[bodies] = dBodyCreate (world); + dBodySetPosition (body[bodies],0,0,HEIGHT/2); + dMassSetBox (&m,1,LENGTH,WIDTH,HEIGHT); + dMassAdjust (&m, 1); + dBodySetMass (body[bodies],&m); + box[boxes] = dCreateBox (space,LENGTH,WIDTH,HEIGHT); + dGeomSetBody (box[boxes++],body[bodies++]); +#endif +#ifdef CANNON + cannon_ball_body = dBodyCreate (world); + cannon_ball_geom = dCreateSphere (space,CANNON_BALL_RADIUS); + dMassSetSphereTotal (&m,CANNON_BALL_MASS,CANNON_BALL_RADIUS); + dBodySetMass (cannon_ball_body,&m); + dGeomSetBody (cannon_ball_geom,cannon_ball_body); + dBodySetPosition (cannon_ball_body,CANNON_X,CANNON_Y,CANNON_BALL_RADIUS); +#endif +} + +// called when a key pressed + +static void command (int cmd) +{ + switch (cmd) { + case 'a': case 'A': + speed += 0.3; + break; + case 'z': case 'Z': + speed -= 0.3; + break; + case ',': + turn += 0.1; + if (turn > 0.3) + turn = 0.3; + break; + case '.': + turn -= 0.1; + if (turn < -0.3) + turn = -0.3; + break; + case ' ': + speed = 0; + turn = 0; + break; + case 'f': case 'F': + doFast = !doFast; + break; + case 'r': case 'R': + shutdownSimulation(); + setupSimulation(); + break; + case '[': + cannon_angle += 0.1; + break; + case ']': + cannon_angle -= 0.1; + break; + case '1': + cannon_elevation += 0.1; + break; + case '2': + cannon_elevation -= 0.1; + break; + case 'x': case 'X': { + dMatrix3 R2,R3,R4; + dRFromAxisAndAngle (R2,0,0,1,cannon_angle); + dRFromAxisAndAngle (R3,0,1,0,cannon_elevation); + dMultiply0 (R4,R2,R3,3,3,3); + dReal cpos[3] = {CANNON_X,CANNON_Y,1}; + for (int i=0; i<3; i++) cpos[i] += 3*R4[i*4+2]; + dBodySetPosition (cannon_ball_body,cpos[0],cpos[1],cpos[2]); + dReal force = 10; + dBodySetLinearVel (cannon_ball_body,force*R4[2],force*R4[6],force*R4[10]); + dBodySetAngularVel (cannon_ball_body,0,0,0); + break; + } + } +} + + +// simulation loop + +static void simLoop (int pause) +{ + int i, j; + + dsSetTexture (DS_WOOD); + + if (!pause) { +#ifdef BOX + dBodyAddForce(body[bodies-1],lspeed,0,0); +#endif + for (j = 0; j < joints; j++) + { + dReal curturn = dJointGetHinge2Angle1 (joint[j]); + //dMessage (0,"curturn %e, turn %e, vel %e", curturn, turn, (turn-curturn)*1.0); + dJointSetHinge2Param(joint[j],dParamVel,(turn-curturn)*1.0); + dJointSetHinge2Param(joint[j],dParamFMax,dInfinity); + dJointSetHinge2Param(joint[j],dParamVel2,speed); + dJointSetHinge2Param(joint[j],dParamFMax2,FMAX); + dBodyEnable(dJointGetBody(joint[j],0)); + dBodyEnable(dJointGetBody(joint[j],1)); + } + if (doFast) + { + dSpaceCollide (space,0,&nearCallback); + dWorldQuickStep (world,0.05); + dJointGroupEmpty (contactgroup); + } + else + { + dSpaceCollide (space,0,&nearCallback); + dWorldStep (world,0.05); + dJointGroupEmpty (contactgroup); + } + + for (i = 0; i < wb; i++) + { + b = dGeomGetBody(wall_boxes[i]); + if (dBodyIsEnabled(b)) + { + bool disable = true; + const dReal *lvel = dBodyGetLinearVel(b); + dReal lspeed = lvel[0]*lvel[0]+lvel[1]*lvel[1]+lvel[2]*lvel[2]; + if (lspeed > DISABLE_THRESHOLD) + disable = false; + const dReal *avel = dBodyGetAngularVel(b); + dReal aspeed = avel[0]*avel[0]+avel[1]*avel[1]+avel[2]*avel[2]; + if (aspeed > DISABLE_THRESHOLD) + disable = false; + + if (disable) + wb_stepsdis[i]++; + else + wb_stepsdis[i] = 0; + + if (wb_stepsdis[i] > DISABLE_STEPS) + { + dBodyDisable(b); + dsSetColor(0.5,0.5,1); + } + else + dsSetColor(1,1,1); + + } + else + dsSetColor(0.4,0.4,0.4); + dVector3 ss; + dGeomBoxGetLengths (wall_boxes[i], ss); + dsDrawBox(dGeomGetPosition(wall_boxes[i]), dGeomGetRotation(wall_boxes[i]), ss); + } + } + else + { + for (i = 0; i < wb; i++) + { + b = dGeomGetBody(wall_boxes[i]); + if (dBodyIsEnabled(b)) + dsSetColor(1,1,1); + else + dsSetColor(0.4,0.4,0.4); + dVector3 ss; + dGeomBoxGetLengths (wall_boxes[i], ss); + dsDrawBox(dGeomGetPosition(wall_boxes[i]), dGeomGetRotation(wall_boxes[i]), ss); + } + } + + dsSetColor (0,1,1); + dReal sides[3] = {LENGTH,WIDTH,HEIGHT}; + for (i = 0; i < boxes; i++) + dsDrawBox (dGeomGetPosition(box[i]),dGeomGetRotation(box[i]),sides); + dsSetColor (1,1,1); + for (i=0; i< spheres; i++) dsDrawSphere (dGeomGetPosition(sphere[i]), + dGeomGetRotation(sphere[i]),RADIUS); + + // draw the cannon + dsSetColor (1,1,0); + dMatrix3 R2,R3,R4; + dRFromAxisAndAngle (R2,0,0,1,cannon_angle); + dRFromAxisAndAngle (R3,0,1,0,cannon_elevation); + dMultiply0 (R4,R2,R3,3,3,3); + dReal cpos[3] = {CANNON_X,CANNON_Y,1}; + dReal csides[3] = {2,2,2}; + dsDrawBox (cpos,R2,csides); + for (i=0; i<3; i++) cpos[i] += 1.5*R4[i*4+2]; + dsDrawCylinder (cpos,R4,3,0.5); + + // draw the cannon ball + dsDrawSphere (dBodyGetPosition(cannon_ball_body),dBodyGetRotation(cannon_ball_body), + CANNON_BALL_RADIUS); +} + +int main (int argc, char **argv) +{ + doFast = true; + + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + dInitODE2(0); + + bodies = 0; + joints = 0; + boxes = 0; + spheres = 0; + + setupSimulation(); + + dThreadingImplementationID threading = dThreadingAllocateMultiThreadedImplementation(); + dThreadingThreadPoolID pool = dThreadingAllocateThreadPool(8, 0, dAllocateFlagBasicData, NULL); + dThreadingThreadPoolServeMultiThreadedImplementation(pool, threading); + // dWorldSetStepIslandsProcessingMaxThreadCount(world, 1); + dWorldSetStepThreadingImplementation(world, dThreadingImplementationGetFunctions(threading), threading); + + // run simulation + dsSimulationLoop (argc,argv,352,288,&fn); + + dThreadingImplementationShutdownProcessing(threading); + dThreadingFreeThreadPool(pool); + dWorldSetStepThreadingImplementation(world, NULL, NULL); + dThreadingFreeImplementation(threading); + + shutdownSimulation(); + dCloseODE(); + return 0; +} diff --git a/libs/ode-0.16.1/ode/demo/demo_cyl.cpp b/libs/ode-0.16.1/ode/demo/demo_cyl.cpp new file mode 100644 index 0000000..368a0c1 --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_cyl.cpp @@ -0,0 +1,321 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// Test for non-capped cylinder, by Bram Stolk +#include <ode/odeconfig.h> +#include <assert.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#include "world_geom3.h" // this is our world mesh + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + + +#define BOX +#define CYL + +// some constants + +#define RADIUS 0.22 // wheel radius +#define WMASS 0.2 // wheel mass +#define WHEELW 0.2 // wheel width +#define BOXSZ 0.4 // box size +//#define CYL_GEOM_OFFSET // rotate cylinder using geom offset + +// dynamics and collision objects (chassis, 3 wheels, environment) + +static dWorldID world; +static dSpaceID space; +#ifdef BOX +static dBodyID boxbody; +static dGeomID boxgeom; +#endif +#ifdef CYL +static dBodyID cylbody; +static dGeomID cylgeom; +#endif +static dJointGroupID contactgroup; +static dGeomID world_mesh; + + +// this is called by dSpaceCollide when two objects in space are +// potentially colliding. + +static void nearCallback (void *data, dGeomID o1, dGeomID o2) +{ + assert(o1); + assert(o2); + + if (dGeomIsSpace(o1) || dGeomIsSpace(o2)) + { + fprintf(stderr,"testing space %p %p\n", (void*)o1, (void*)o2); + // colliding a space with something + dSpaceCollide2(o1,o2,data,&nearCallback); + // Note we do not want to test intersections within a space, + // only between spaces. + return; + } + +// fprintf(stderr,"testing geoms %p %p\n", o1, o2); + + const int N = 32; + dContact contact[N]; + int n = dCollide (o1,o2,N,&(contact[0].geom),sizeof(dContact)); + if (n > 0) + { + for (int i=0; i<n; i++) + { + contact[i].surface.slip1 = 0.7; + contact[i].surface.slip2 = 0.7; + contact[i].surface.mode = dContactSoftERP | dContactSoftCFM | dContactApprox1 | dContactSlip1 | dContactSlip2; + contact[i].surface.mu = 50.0; // was: dInfinity + contact[i].surface.soft_erp = 0.96; + contact[i].surface.soft_cfm = 0.04; + dJointID c = dJointCreateContact (world,contactgroup,&contact[i]); + dJointAttach (c, + dGeomGetBody(contact[i].geom.g1), + dGeomGetBody(contact[i].geom.g2)); + } + } +} + + +// start simulation - set viewpoint + +static void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + static float xyz[3] = {-8,-9,3}; + static float hpr[3] = {45.0000f,-27.5000f,0.0000f}; + dsSetViewpoint (xyz,hpr); +} + + + +static void reset_state(void) +{ + float sx=-4, sy=-4, sz=2; + dQuaternion q; + dQFromAxisAndAngle (q,1,0,0,M_PI*0.5); +#ifdef BOX + dBodySetPosition (boxbody, sx, sy+1, sz); + dBodySetLinearVel (boxbody, 0,0,0); + dBodySetAngularVel (boxbody, 0,0,0); + dBodySetQuaternion (boxbody, q); +#endif +#ifdef CYL + dBodySetPosition (cylbody, sx, sy, sz); + dBodySetLinearVel (cylbody, 0,0,0); + dBodySetAngularVel (cylbody, 0,0,0); + dBodySetQuaternion (cylbody, q); +#endif +} + + +// called when a key pressed + +static void command (int cmd) +{ + switch (cmd) + { + case ' ': + reset_state(); + break; + } +} + + + +// simulation loop + +static void simLoop (int pause) +{ + double simstep = 0.005; // 5ms simulation steps + double dt = dsElapsedTime(); + int nrofsteps = (int) ceilf(dt/simstep); + for (int i=0; i<nrofsteps && !pause; i++) + { + dSpaceCollide (space,0,&nearCallback); + dWorldQuickStep (world, simstep); + dJointGroupEmpty (contactgroup); + } + + dsSetColor (1,1,1); +#ifdef BOX + const dReal *BPos = dBodyGetPosition(boxbody); + const dReal *BRot = dBodyGetRotation(boxbody); + float bpos[3] = {BPos[0], BPos[1], BPos[2]}; + float brot[12] = { BRot[0], BRot[1], BRot[2], BRot[3], BRot[4], BRot[5], BRot[6], BRot[7], BRot[8], BRot[9], BRot[10], BRot[11] }; + float sides[3] = {BOXSZ, BOXSZ, BOXSZ}; + dsDrawBox + ( + bpos, + brot, + sides + ); // single precision +#endif +#ifdef CYL + const dReal *CPos = dGeomGetPosition(cylgeom); + const dReal *CRot = dGeomGetRotation(cylgeom); + float cpos[3] = {CPos[0], CPos[1], CPos[2]}; + float crot[12] = { CRot[0], CRot[1], CRot[2], CRot[3], CRot[4], CRot[5], CRot[6], CRot[7], CRot[8], CRot[9], CRot[10], CRot[11] }; + dsDrawCylinder + ( +// dBodyGetPosition(cylbody), +// dBodyGetRotation(cylbody), + cpos, + crot, + WHEELW, + RADIUS + ); // single precision +#endif + + // draw world trimesh + dsSetColor(0.7,0.7,0.4); + dsSetTexture (DS_NONE); + + const dReal* Pos = dGeomGetPosition(world_mesh); + float pos[3] = { Pos[0], Pos[1], Pos[2] }; + + const dReal* Rot = dGeomGetRotation(world_mesh); + float rot[12] = { Rot[0], Rot[1], Rot[2], Rot[3], Rot[4], Rot[5], Rot[6], Rot[7], Rot[8], Rot[9], Rot[10], Rot[11] }; + + int numi = sizeof(world_indices) / sizeof(dTriIndex); + + for (int i=0; i<numi/3; i++) + { + int i0 = world_indices[i*3+0]; + int i1 = world_indices[i*3+1]; + int i2 = world_indices[i*3+2]; + float *v0 = world_vertices+i0*3; + float *v1 = world_vertices+i1*3; + float *v2 = world_vertices+i2*3; + dsDrawTriangle(pos, rot, v0,v1,v2, true); // single precision draw + } +} + + +int main (int argc, char **argv) +{ + dMass m; + dMatrix3 R; + + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + // create world + dInitODE2(0); + world = dWorldCreate(); + space = dHashSpaceCreate (0); + contactgroup = dJointGroupCreate (0); + dWorldSetGravity (world,0,0,-9.8); + dWorldSetQuickStepNumIterations (world, 12); + + + // Create a static world using a triangle mesh that we can collide with. + int numv = sizeof(world_vertices)/(3*sizeof(float)); + int numi = sizeof(world_indices)/ sizeof(dTriIndex); + printf("numv=%d, numi=%d\n", numv, numi); + dTriMeshDataID Data = dGeomTriMeshDataCreate(); + + dGeomTriMeshDataBuildSingle + ( + Data, + world_vertices, + 3 * sizeof(float), + numv, + world_indices, + numi, + 3 * sizeof(dTriIndex) + ); + + world_mesh = dCreateTriMesh(space, Data, 0, 0, 0); + dGeomSetPosition(world_mesh, 0, 0, 0.5); + dRFromAxisAndAngle (R, 0,1,0, 0.0); + dGeomSetRotation (world_mesh, R); + + +#ifdef BOX + boxbody = dBodyCreate (world); + dMassSetBox (&m,1, BOXSZ, BOXSZ, BOXSZ); + dMassAdjust (&m, 1); + dBodySetMass (boxbody,&m); + boxgeom = dCreateBox (0, BOXSZ, BOXSZ, BOXSZ); + dGeomSetBody (boxgeom,boxbody); + dSpaceAdd (space, boxgeom); +#endif +#ifdef CYL + cylbody = dBodyCreate (world); + dMassSetSphere (&m,1,RADIUS); + dMassAdjust (&m,WMASS); + dBodySetMass (cylbody,&m); + cylgeom = dCreateCylinder(0, RADIUS, WHEELW); + dGeomSetBody (cylgeom,cylbody); + + #if defined(CYL_GEOM_OFFSET) + dMatrix3 mat; + dRFromAxisAndAngle(mat,1.0f,0.0f,0.0f,M_PI/2.0); + dGeomSetOffsetRotation(cylgeom,mat); + #endif + + dSpaceAdd (space, cylgeom); +#endif + reset_state(); + + // run simulation + dsSimulationLoop (argc,argv,352,288,&fn); + + dJointGroupEmpty (contactgroup); + dJointGroupDestroy (contactgroup); + + // First destroy geoms, then space, then the world. +#ifdef CYL + dGeomDestroy (cylgeom); +#endif +#ifdef BOX + dGeomDestroy (boxgeom); +#endif + dGeomDestroy (world_mesh); + + dSpaceDestroy (space); + dWorldDestroy (world); + dCloseODE(); + return 0; + (void)world_normals; // get rid of compiler warnings +} + + + diff --git a/libs/ode-0.16.1/ode/demo/demo_cylvssphere.cpp b/libs/ode-0.16.1/ode/demo/demo_cylvssphere.cpp new file mode 100644 index 0000000..a2dc750 --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_cylvssphere.cpp @@ -0,0 +1,240 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// Test for cylinder vs sphere, by Bram Stolk + +#include <ode/odeconfig.h> +#include <assert.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + + +// dynamics and collision objects (chassis, 3 wheels, environment) + +static dWorldID world; +static dSpaceID space; + +static dBodyID cylbody; +static dGeomID cylgeom; + +static dBodyID sphbody; +static dGeomID sphgeom; + +static dJointGroupID contactgroup; + +static bool show_contacts = true; + +#define CYLRADIUS 0.6 +#define CYLLENGTH 2.0 +#define SPHERERADIUS 0.5 + + +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#define dsDrawLine dsDrawLineD +#endif + + + +// this is called by dSpaceCollide when two objects in space are +// potentially colliding. + +static void nearCallback (void *data, dGeomID o1, dGeomID o2) +{ + assert(o1); + assert(o2); + + if (dGeomIsSpace(o1) || dGeomIsSpace(o2)) + { + fprintf(stderr,"testing space %p %p\n", (void*)o1, (void*)o2); + // colliding a space with something + dSpaceCollide2(o1,o2,data,&nearCallback); + // Note we do not want to test intersections within a space, + // only between spaces. + return; + } + + const int N = 32; + dContact contact[N]; + int n = dCollide (o1,o2,N,&(contact[0].geom),sizeof(dContact)); + if (n > 0) + { + for (int i=0; i<n; i++) + { + contact[i].surface.mode = 0; + contact[i].surface.mu = 50.0; // was: dInfinity + dJointID c = dJointCreateContact (world,contactgroup,&contact[i]); + dJointAttach (c, dGeomGetBody(contact[i].geom.g1), dGeomGetBody(contact[i].geom.g2)); + if (show_contacts) + { + dMatrix3 RI; + dRSetIdentity (RI); + const dReal ss[3] = {0.12,0.12,0.12}; + dsSetColorAlpha (0,0,1,0.5); + dsDrawBox (contact[i].geom.pos,RI,ss); + dReal *pos = contact[i].geom.pos; + dReal depth = contact[i].geom.depth; + dReal *norm = contact[i].geom.normal; + dReal endp[3] = {pos[0]+depth*norm[0], pos[1]+depth*norm[1], pos[2]+depth*norm[2]}; + dsSetColorAlpha (1,1,1,1); + dsDrawLine (contact[i].geom.pos, endp); + } + } + } +} + + +// start simulation - set viewpoint + +static void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + static float xyz[3] = {-8,-9,3}; + static float hpr[3] = {45.0000f,-27.5000f,0.0000f}; + dsSetViewpoint (xyz,hpr); +} + + +// called when a key pressed + +static void command (int cmd) +{ + switch (cmd) + { + case ' ': + break; + } +} + + + +// simulation loop + +static void simLoop (int pause) +{ + dSpaceCollide (space,0,&nearCallback); + if (!pause) + { + dWorldQuickStep (world, 0.01); // 100 Hz + } + dJointGroupEmpty (contactgroup); + + dsSetColorAlpha (1,1,0,0.5); + + const dReal *CPos = dBodyGetPosition(cylbody); + const dReal *CRot = dBodyGetRotation(cylbody); + float cpos[3] = {CPos[0], CPos[1], CPos[2]}; + float crot[12] = { CRot[0], CRot[1], CRot[2], CRot[3], CRot[4], CRot[5], CRot[6], CRot[7], CRot[8], CRot[9], CRot[10], CRot[11] }; + dsDrawCylinder + ( + cpos, + crot, + CYLLENGTH, + CYLRADIUS + ); // single precision + + const dReal *SPos = dBodyGetPosition(sphbody); + const dReal *SRot = dBodyGetRotation(sphbody); + float spos[3] = {SPos[0], SPos[1], SPos[2]}; + float srot[12] = { SRot[0], SRot[1], SRot[2], SRot[3], SRot[4], SRot[5], SRot[6], SRot[7], SRot[8], SRot[9], SRot[10], SRot[11] }; + dsDrawSphere + ( + spos, + srot, + SPHERERADIUS + ); // single precision +} + + +int main (int argc, char **argv) +{ + dMass m; + + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + // create world + dInitODE2(0); + world = dWorldCreate(); + space = dHashSpaceCreate (0); + contactgroup = dJointGroupCreate (0); + dWorldSetGravity (world,0,0,-9.8); + dWorldSetQuickStepNumIterations (world, 32); + + dCreatePlane (space,0,0,1, 0.0); + + cylbody = dBodyCreate (world); + dQuaternion q; +#if 0 + dQFromAxisAndAngle (q,1,0,0,M_PI*0.5); +#else +// dQFromAxisAndAngle (q,1,0,0, M_PI * 1.0); + dQFromAxisAndAngle (q,1,0,0, M_PI * -0.77); +#endif + dBodySetQuaternion (cylbody,q); + dMassSetCylinder (&m,1.0,3,CYLRADIUS,CYLLENGTH); + dBodySetMass (cylbody,&m); + cylgeom = dCreateCylinder(0, CYLRADIUS, CYLLENGTH); + dGeomSetBody (cylgeom,cylbody); + dBodySetPosition (cylbody, 0, 0, 3); + dSpaceAdd (space, cylgeom); + + sphbody = dBodyCreate (world); + dMassSetSphere (&m,1,SPHERERADIUS); + dBodySetMass (sphbody,&m); + sphgeom = dCreateSphere(0, SPHERERADIUS); + dGeomSetBody (sphgeom,sphbody); + dBodySetPosition (sphbody, 0, 0, 5.5); + dSpaceAdd (space, sphgeom); + + // run simulation + dsSimulationLoop (argc,argv,352,288,&fn); + + dJointGroupEmpty (contactgroup); + dJointGroupDestroy (contactgroup); + + dGeomDestroy(sphgeom); + dGeomDestroy (cylgeom); + + dSpaceDestroy (space); + dWorldDestroy (world); + dCloseODE(); + return 0; +} + + + diff --git a/libs/ode-0.16.1/ode/demo/demo_dball.cpp b/libs/ode-0.16.1/ode/demo/demo_dball.cpp new file mode 100644 index 0000000..d264cd7 --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_dball.cpp @@ -0,0 +1,194 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#ifdef dDOUBLE +#define dsDrawSphere dsDrawSphereD +#define dsDrawBox dsDrawBoxD +#define dsDrawLine dsDrawLineD +#endif + + +dWorldID world; +dSpaceID space; +dBodyID body1; +dBodyID body2; +dJointID joint1, joint2; + +void start() +{ + world = dWorldCreate(); + dWorldSetGravity (world,0,0,-9.8); + + dWorldSetDamping(world, 1e-4, 1e-5); +// dWorldSetERP(world, 1); + + space = dSimpleSpaceCreate (0); + + body1 = dBodyCreate(world); + body2 = dBodyCreate(world); + + dBodySetPosition(body1, 0, 0, 3); + dBodySetPosition(body2, 0, 0, 1); + + + dGeomID g; + dMass mass; + + g = dCreateBox(space, 0.2, 0.2, 1); + dGeomSetBody(g, body1); + dMassSetBox(&mass, 1, 0.2, 0.2, 1); + dBodySetMass(body1, &mass); + + g = dCreateBox(space, 0.2, 0.2, 1); + dGeomSetBody(g, body2); + dMassSetBox(&mass, 1, 0.2, 0.2, 1); + dBodySetMass(body2, &mass); + + joint1 = dJointCreateDBall(world, 0); + dJointAttach(joint1, body1, 0); + dJointSetDBallAnchor1(joint1, 0, 0, 3.5); + dJointSetDBallAnchor2(joint1, 0, 0, 4.5); + + joint2 = dJointCreateDBall(world, 0); + dJointAttach(joint2, body1, body2); + dJointSetDBallAnchor1(joint2, 0, 0, 2.5); + dJointSetDBallAnchor2(joint2, 0, 0, 1.5); + + + // initial camera position + static float xyz[3] = {3.8966, -2.0614, 4.0300}; + static float hpr[3] = {153.5, -16.5, 0}; + dsSetViewpoint (xyz,hpr); +} + +void stop() +{ + dSpaceDestroy(space); + + dWorldDestroy(world); +} + + +void drawGeom(dGeomID g) +{ + int gclass = dGeomGetClass(g); + const dReal *pos = dGeomGetPosition(g); + const dReal *rot = dGeomGetRotation(g); + + switch (gclass) { + case dSphereClass: + dsSetColorAlpha(0, 0.75, 0.5, 1); + dsSetTexture (DS_CHECKERED); + dsDrawSphere(pos, rot, dGeomSphereGetRadius(g)); + break; + case dBoxClass: + { + dVector3 lengths; + dsSetColorAlpha(1, 1, 0, 1); + dsSetTexture (DS_WOOD); + dGeomBoxGetLengths(g, lengths); + dsDrawBox(pos, rot, lengths); + break; + } + + default: + {} + } +} + +void simLoop(int pause) +{ + if (!pause) { + + static dReal t = 0; + + const dReal step = 0.005; + const unsigned nsteps = 4; + + for (unsigned i=0; i<nsteps; ++i) { + + dReal f = sin(t*1.2)*0.8; + dBodyAddForceAtRelPos(body1, + f, 0, 0, + 0, 0, -0.5); // at the lower end + + dReal g = sin(t*0.7)*0.8; + dBodyAddForceAtRelPos(body2, + 0, g, 0, + 0, 0, -0.5); // at the lower end + t += step; + + dWorldQuickStep(world, step); + } + } + + // now we draw everything + unsigned ngeoms = dSpaceGetNumGeoms(space); + for (unsigned i=0; i<ngeoms; ++i) { + dGeomID g = dSpaceGetGeom(space, i); + + drawGeom(g); + } + + dVector3 a11, a12; + dJointGetDBallAnchor1(joint1, a11); + dJointGetDBallAnchor2(joint1, a12); + dsSetColor(1, 0, 0); + dsDrawLine(a11, a12); + + //printf("Error 1: %f\n", fabs(dJointGetDBallDistance(joint1) - dCalcPointsDistance3(a11, a12))); + + dVector3 a21, a22; + dJointGetDBallAnchor1(joint2, a21); + dJointGetDBallAnchor2(joint2, a22); + dsSetColor(0, 1, 0); + dsDrawLine(a21, a22); + + //printf("Error 2: %f\n", fabs(dJointGetDBallDistance(joint2) - dCalcPointsDistance3(a21, a22))); +} + + + +int main(int argc, char **argv) +{ + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = 0; + fn.stop = stop; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + // create world + dInitODE(); + + // run demo + dsSimulationLoop (argc, argv, 800, 600, &fn); + + dCloseODE(); + return 0; +} diff --git a/libs/ode-0.16.1/ode/demo/demo_dhinge.cpp b/libs/ode-0.16.1/ode/demo/demo_dhinge.cpp new file mode 100644 index 0000000..c27f29e --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_dhinge.cpp @@ -0,0 +1,217 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#ifdef dDOUBLE +#define dsDrawSphere dsDrawSphereD +#define dsDrawBox dsDrawBoxD +#define dsDrawLine dsDrawLineD +#endif + + +dWorldID world; +dSpaceID space; +dBodyID body1; +dBodyID body2; +dJointID joint1, joint2; +bool applyForce = false; + +void start() +{ + world = dWorldCreate(); + dWorldSetGravity (world,0,0,-9.8); + + dWorldSetDamping(world, 1e-4, 1e-5); +// dWorldSetERP(world, 1); + + space = dSimpleSpaceCreate (0); + + body1 = dBodyCreate(world); + body2 = dBodyCreate(world); + + dBodySetPosition(body1, 0, 0, 3); + dBodySetPosition(body2, 0, 0, 1); + + + dGeomID g; + dMass mass; + + g = dCreateBox(space, 0.2, 0.2, 1); + dGeomSetBody(g, body1); + dMassSetBox(&mass, 1, 0.2, 0.2, 1); + dBodySetMass(body1, &mass); + + g = dCreateBox(space, 0.2, 0.2, 1); + dGeomSetBody(g, body2); + dMassSetBox(&mass, 1, 0.2, 0.2, 1); + dBodySetMass(body2, &mass); + +#if 1 + joint1 = dJointCreateDHinge(world, 0); + dJointAttach(joint1, body1, 0); + dJointSetDHingeAxis(joint1, 0, 1, 0); + dJointSetDHingeAnchor1(joint1, 0, 0, 3.5); + dJointSetDHingeAnchor2(joint1, 0, 0, 4.5); +#endif + +#if 1 + joint2 = dJointCreateDHinge(world, 0); + dJointAttach(joint2, body1, body2); + dJointSetDHingeAxis(joint2, 1, 0, 0); + dJointSetDHingeAnchor1(joint2, 0, 0, 2.5); + dJointSetDHingeAnchor2(joint2, 0, 0, 1.5); +#else + joint2 = dJointCreateDBall(world, 0); + dJointAttach(joint2, body1, body2); + dJointSetDBallAnchor1(joint2, 0, 0, 2.5); + dJointSetDBallAnchor2(joint2, 0, 0, 1.5); +#endif + + //dBodyAddForce(body1, 20, 0, 0); + + + // initial camera position + static float xyz[3] = {3.8966, -2.0614, 4.0300}; + static float hpr[3] = {153.5, -16.5, 0}; + dsSetViewpoint (xyz,hpr); +} + +void stop() +{ + dSpaceDestroy(space); + + dWorldDestroy(world); +} + + +void drawGeom(dGeomID g) +{ + int gclass = dGeomGetClass(g); + const dReal *pos = dGeomGetPosition(g); + const dReal *rot = dGeomGetRotation(g); + + switch (gclass) { + case dBoxClass: + { + dVector3 lengths; + if (applyForce) + dsSetColor(1, .5, 0); + else + dsSetColor(1, 1, 0); + dsSetTexture (DS_WOOD); + dGeomBoxGetLengths(g, lengths); + dsDrawBox(pos, rot, lengths); + break; + } + + default: + {} + } +} + + +void simLoop(int pause) +{ + if (!pause) { + + static dReal t = 0; + + const dReal step = 0.005; + const unsigned nsteps = 2; + + for (unsigned i=0; i<nsteps; ++i) { + + applyForce = fmodf(t, 3.) > 2.; + + if (applyForce) { + dReal f = 0.3 * sin(t*1.2); + dBodyAddForceAtRelPos(body1, + f, 0, 0, + 0, 0, -0.5); // at the lower end + + dReal g = 0.3 * sin(t*0.7); + dBodyAddForceAtRelPos(body2, + 0, g, 0, + 0, 0, -0.5); // at the lower end + } + + t += step; + if (t > 20.) + t = 0.; + + dWorldQuickStep(world, step); + } + } + + // now we draw everything + unsigned ngeoms = dSpaceGetNumGeoms(space); + for (unsigned i=0; i<ngeoms; ++i) { + dGeomID g = dSpaceGetGeom(space, i); + + drawGeom(g); + } + +#if 1 + dVector3 a11, a12; + dJointGetDHingeAnchor1(joint1, a11); + dJointGetDHingeAnchor2(joint1, a12); + dsSetColor(1, 0, 0); + dsDrawLine(a11, a12); + //printf("Error 1: %f\n", fabs(dJointGetDHingeDistance(joint1) - dCalcPointsDistance3(a11, a12))); +#endif + +#if 1 + dVector3 a21, a22; + dJointGetDHingeAnchor1(joint2, a21); + dJointGetDHingeAnchor2(joint2, a22); + dsSetColor(0, 1, 0); + dsDrawLine(a21, a22); + + //printf("Error 2: %f\n", fabs(dJointGetDHingeDistance(joint2) - dCalcPointsDistance3(a21, a22))); +#endif +} + + + +int main(int argc, char **argv) +{ + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = 0; + fn.stop = stop; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + // create world + dInitODE(); + + // run demo + dsSimulationLoop (argc, argv, 800, 600, &fn); + + dCloseODE(); + return 0; +} diff --git a/libs/ode-0.16.1/ode/demo/demo_feedback.cpp b/libs/ode-0.16.1/ode/demo/demo_feedback.cpp new file mode 100644 index 0000000..ebcd129 --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_feedback.cpp @@ -0,0 +1,312 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// Test for breaking joints, by Bram Stolk + +#include <ode/odeconfig.h> +#include <assert.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#define dsDrawCylinder dsDrawCylinderD +#endif + + +// dynamics and collision objects (chassis, 3 wheels, environment) + +static dWorldID world; +static dSpaceID space; + +static const int STACKCNT=10; // nr of weights on bridge +static const int SEGMCNT=16; // nr of segments in bridge +static const float SEGMDIM[3] = { 0.9, 4, 0.1 }; + +static dGeomID groundgeom; +static dBodyID segbodies[SEGMCNT]; +static dGeomID seggeoms[SEGMCNT]; +static dBodyID stackbodies[STACKCNT]; +static dGeomID stackgeoms[STACKCNT]; +static dJointID hinges[SEGMCNT-1]; +static dJointID sliders[2]; +static dJointFeedback jfeedbacks[SEGMCNT-1]; +static dReal colours[SEGMCNT]; +static int stress[SEGMCNT-1]; + +static dJointGroupID contactgroup; + + +// this is called by dSpaceCollide when two objects in space are +// potentially colliding. + +static void nearCallback (void *data, dGeomID o1, dGeomID o2) +{ + assert(o1); + assert(o2); + + if (dGeomIsSpace(o1) || dGeomIsSpace(o2)) + { + fprintf(stderr,"testing space %p %p\n", (void*)o1, (void*)o2); + // colliding a space with something + dSpaceCollide2(o1,o2,data,&nearCallback); + // Note we do not want to test intersections within a space, + // only between spaces. + return; + } + + const int N = 32; + dContact contact[N]; + int n = dCollide (o1,o2,N,&(contact[0].geom),sizeof(dContact)); + if (n > 0) + { + for (int i=0; i<n; i++) + { + contact[i].surface.mode = dContactSoftERP | dContactSoftCFM | dContactApprox1; + contact[i].surface.mu = 100.0; + contact[i].surface.soft_erp = 0.96; + contact[i].surface.soft_cfm = 0.02; + dJointID c = dJointCreateContact (world,contactgroup,&contact[i]); + dJointAttach (c, + dGeomGetBody(contact[i].geom.g1), + dGeomGetBody(contact[i].geom.g2)); + } + } +} + + +// start simulation - set viewpoint + +static void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + static float xyz[3] = { -6, 8, 6}; + static float hpr[3] = { -65.0f, -27.0f, 0.0f}; + dsSetViewpoint (xyz,hpr); +} + + +// called when a key pressed + +static void command (int) +{} + + +void drawGeom (dGeomID g) +{ + const dReal *pos = dGeomGetPosition(g); + const dReal *R = dGeomGetRotation(g); + + int type = dGeomGetClass (g); + if (type == dBoxClass) + { + dVector3 sides; + dGeomBoxGetLengths (g, sides); + dsDrawBox (pos,R,sides); + } + if (type == dCylinderClass) + { + dReal r,l; + dGeomCylinderGetParams(g, &r, &l); + dsDrawCylinder (pos, R, l, r); + } +} + + +static void inspectJoints(void) +{ + const dReal forcelimit = 4000.0; + int i; + for (i=0; i<SEGMCNT-1; i++) + { + if (dJointGetBody(hinges[i], 0)) + { + // This joint has not snapped already... inspect it. + dReal l0 = dCalcVectorLength3(jfeedbacks[i].f1); + dReal l1 = dCalcVectorLength3(jfeedbacks[i].f2); + colours[i+0] = 0.95*colours[i+0] + 0.05 * l0/forcelimit; + colours[i+1] = 0.95*colours[i+1] + 0.05 * l1/forcelimit; + if (l0 > forcelimit || l1 > forcelimit) + stress[i]++; + else + stress[i]=0; + if (stress[i]>4) + { + // Low-pass filter the noisy feedback data. + // Only after 4 consecutive timesteps with excessive load, snap. + fprintf(stderr,"SNAP! (that was the sound of joint %d breaking)\n", i); + dJointAttach (hinges[i], 0, 0); + } + } + } +} + + +// simulation loop + +static void simLoop (int pause) +{ + int i; + + double simstep = 0.002; // 2ms simulation steps + double dt = dsElapsedTime(); + int nrofsteps = (int) ceilf(dt/simstep); + for (i=0; i<nrofsteps && !pause; i++) + { + dSpaceCollide (space,0,&nearCallback); + dWorldQuickStep (world, simstep); + dJointGroupEmpty (contactgroup); + inspectJoints(); + } + + for (i=0; i<SEGMCNT; i++) + { + float r=0,g=0,b=0.2; + float v = colours[i]; + if (v>1.0) v=1.0; + if (v<0.5) + { + r=2*v; + g=1.0; + } + else + { + r=1.0; + g=2*(1.0-v); + } + dsSetColor (r,g,b); + drawGeom(seggeoms[i]); + } + dsSetColor (1,1,1); + for (i=0; i<STACKCNT; i++) + drawGeom(stackgeoms[i]); +} + + + +int main (int argc, char **argv) +{ + dMass m; + + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + // create world + dInitODE2(0); + world = dWorldCreate(); + space = dHashSpaceCreate (0); + contactgroup = dJointGroupCreate (0); + dWorldSetGravity (world,0,0,-9.8); + dWorldSetQuickStepNumIterations (world, 20); + + int i; + for (i=0; i<SEGMCNT; i++) + { + segbodies[i] = dBodyCreate (world); + dBodySetPosition(segbodies[i], i - SEGMCNT/2.0, 0, 5); + dMassSetBox (&m, 1, SEGMDIM[0], SEGMDIM[1], SEGMDIM[2]); + dBodySetMass (segbodies[i], &m); + seggeoms[i] = dCreateBox (0, SEGMDIM[0], SEGMDIM[1], SEGMDIM[2]); + dGeomSetBody (seggeoms[i], segbodies[i]); + dSpaceAdd (space, seggeoms[i]); + } + + for (i=0; i<SEGMCNT-1; i++) + { + hinges[i] = dJointCreateHinge (world,0); + dJointAttach (hinges[i], segbodies[i],segbodies[i+1]); + dJointSetHingeAnchor (hinges[i], i + 0.5 - SEGMCNT/2.0, 0, 5); + dJointSetHingeAxis (hinges[i], 0,1,0); + dJointSetHingeParam (hinges[i],dParamFMax, 8000.0); + // NOTE: + // Here we tell ODE where to put the feedback on the forces for this hinge + dJointSetFeedback (hinges[i], jfeedbacks+i); + stress[i]=0; + } + + for (i=0; i<STACKCNT; i++) + { + stackbodies[i] = dBodyCreate(world); + dMassSetBox (&m, 2.0, 2, 2, 0.6); + dBodySetMass(stackbodies[i],&m); + + stackgeoms[i] = dCreateBox(0, 2, 2, 0.6); + dGeomSetBody(stackgeoms[i], stackbodies[i]); + dBodySetPosition(stackbodies[i], 0,0,8+2*i); + dSpaceAdd(space, stackgeoms[i]); + } + + sliders[0] = dJointCreateSlider (world,0); + dJointAttach(sliders[0], segbodies[0], 0); + dJointSetSliderAxis (sliders[0], 1,0,0); + dJointSetSliderParam (sliders[0],dParamFMax, 4000.0); + dJointSetSliderParam (sliders[0],dParamLoStop, 0.0); + dJointSetSliderParam (sliders[0],dParamHiStop, 0.2); + + sliders[1] = dJointCreateSlider (world,0); + dJointAttach(sliders[1], segbodies[SEGMCNT-1], 0); + dJointSetSliderAxis (sliders[1], 1,0,0); + dJointSetSliderParam (sliders[1],dParamFMax, 4000.0); + dJointSetSliderParam (sliders[1],dParamLoStop, 0.0); + dJointSetSliderParam (sliders[1],dParamHiStop, -0.2); + + groundgeom = dCreatePlane(space, 0,0,1,0); + + for (i=0; i<SEGMCNT; i++) + colours[i]=0.0; + + // run simulation + dsSimulationLoop (argc,argv,1280,720,&fn); + + dJointGroupEmpty(contactgroup); + dJointGroupDestroy (contactgroup); + + // First destroy seggeoms, then space, then the world. + for (i=0; i<SEGMCNT; i++) + dGeomDestroy (seggeoms[i]); + for (i=0; i<STACKCNT; i++) + dGeomDestroy (stackgeoms[i]); + + dSpaceDestroy(space); + dWorldDestroy (world); + dCloseODE(); + return 0; +} + + + diff --git a/libs/ode-0.16.1/ode/demo/demo_friction.cpp b/libs/ode-0.16.1/ode/demo/demo_friction.cpp new file mode 100644 index 0000000..f6260bb --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_friction.cpp @@ -0,0 +1,205 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +test the Coulomb friction approximation. + +a 10x10 array of boxes is made, each of which rests on the ground. +a horizantal force is applied to each box to try and get it to slide. +box[i][j] has a mass (i+1)*MASS and a force (j+1)*FORCE. by the Coloumb +friction model, the box should only slide if the force is greater than MU +times the contact normal force, i.e. + + f > MU * body_mass * GRAVITY + (j+1)*FORCE > MU * (i+1)*MASS * GRAVITY + (j+1) > (i+1) * (MU*MASS*GRAVITY/FORCE) + (j+1) > (i+1) * k + +this should be independent of the number of contact points, as N contact +points will each have 1/N'th the normal force but the pushing force will +have to overcome N contacts. the constants are chosen so that k=1. +thus you should see a triangle made of half the bodies in the array start to +slide. + +*/ + + +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + +// select correct drawing functions + +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#define dsDrawSphere dsDrawSphereD +#define dsDrawCylinder dsDrawCylinderD +#define dsDrawCapsule dsDrawCapsuleD +#endif + + +// some constants + +#define LENGTH 0.2 // box length & width +#define HEIGHT 0.05 // box height +#define MASS 0.2 // mass of box[i][j] = (i+1) * MASS +#define FORCE 0.05 // force applied to box[i][j] = (j+1) * FORCE +#define MU 0.5 // the global mu to use +#define GRAVITY 0.5 // the global gravity to use +#define N1 10 // number of different forces to try +#define N2 10 // number of different masses to try + + +// dynamics and collision objects + +static dWorldID world; +static dSpaceID space; +static dBodyID body[N1][N2]; +static dJointGroupID contactgroup; +static dGeomID ground; +static dGeomID box[N1][N2]; + + + +// this is called by dSpaceCollide when two objects in space are +// potentially colliding. + +static void nearCallback (void *, dGeomID o1, dGeomID o2) +{ + int i; + + // only collide things with the ground + int g1 = (o1 == ground); + int g2 = (o2 == ground); + if (!(g1 ^ g2)) return; + + dBodyID b1 = dGeomGetBody(o1); + dBodyID b2 = dGeomGetBody(o2); + + dContact contact[3]; // up to 3 contacts per box + for (i=0; i<3; i++) { + contact[i].surface.mode = dContactSoftCFM | dContactApprox1; + contact[i].surface.mu = MU; + contact[i].surface.soft_cfm = 0.01; + } + if (int numc = dCollide (o1,o2,3,&contact[0].geom,sizeof(dContact))) { + for (i=0; i<numc; i++) { + dJointID c = dJointCreateContact (world,contactgroup,contact+i); + dJointAttach (c,b1,b2); + } + } +} + + +// start simulation - set viewpoint + +static void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + static float xyz[3] = {1.7772,-0.7924,2.7600}; + static float hpr[3] = {90.0000,-54.0000,0.0000}; + dsSetViewpoint (xyz,hpr); +} + + +// simulation loop + +static void simLoop (int pause) +{ + int i; + if (!pause) { + // apply forces to all bodies + for (i=0; i<N1; i++) { + for (int j=0; j<N2; j++) { + dBodyAddForce (body[i][j],FORCE*(i+1),0,0); + } + } + + dSpaceCollide (space,0,&nearCallback); + dWorldStep (world,0.05); + + // remove all contact joints + dJointGroupEmpty (contactgroup); + } + + dsSetColor (1,0,1); + dReal sides[3] = {LENGTH,LENGTH,HEIGHT}; + for (i=0; i<N1; i++) { + for (int j=0; j<N2; j++) { + dsDrawBox (dGeomGetPosition(box[i][j]),dGeomGetRotation(box[i][j]), + sides); + } + } +} + + +int main (int argc, char **argv) +{ + int i,j; + dMass m; + + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = 0; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + // create world + dInitODE2(0); + world = dWorldCreate(); + space = dHashSpaceCreate (0); + contactgroup = dJointGroupCreate (0); + dWorldSetGravity (world,0,0,-GRAVITY); + ground = dCreatePlane (space,0,0,1,0); + + // bodies + for (i=0; i<N1; i++) { + for (j=0; j<N2; j++) { + body[i][j] = dBodyCreate (world); + dMassSetBox (&m,1,LENGTH,LENGTH,HEIGHT); + dMassAdjust (&m,MASS*(j+1)); + dBodySetMass (body[i][j],&m); + dBodySetPosition (body[i][j],i*2*LENGTH,j*2*LENGTH,HEIGHT*0.5); + + box[i][j] = dCreateBox (space,LENGTH,LENGTH,HEIGHT); + dGeomSetBody (box[i][j],body[i][j]); + } + } + + // run simulation + dsSimulationLoop (argc,argv,352,288,&fn); + + dJointGroupDestroy (contactgroup); + dSpaceDestroy (space); + dWorldDestroy (world); + dCloseODE(); + return 0; +} diff --git a/libs/ode-0.16.1/ode/demo/demo_gyro2.cpp b/libs/ode-0.16.1/ode/demo/demo_gyro2.cpp new file mode 100644 index 0000000..454b6b3 --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_gyro2.cpp @@ -0,0 +1,210 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* +Angular friction demo: + +A bunch of ramps of different pitch. +A bunch of spheres with rolling friction. +*/ + + +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + +// select correct drawing functions +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#define dsDrawSphere dsDrawSphereD +#define dsDrawCylinder dsDrawCylinderD +#define dsDrawCapsule dsDrawCapsuleD +#endif + +// dynamics and collision objects +static dWorldID world = 0; + +static const dReal dt = 1/REAL(60.0); // 60 fps +// Water density if units are meters and kg +static const dReal density = 1000; + +// A long skinny thing +static dVector3 sides = {2,.5,.25}; +// Initial angular velocity +static dVector3 omega = {5,1,2}; +static dVector3 torque = {0,10,0}; +static dBodyID noGyroBody; +static dBodyID expGyroBody; +static dBodyID impGyroBody; + +// start simulation - set viewpoint + +static void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + static float xyz[3] = {0,-4.0f,3.0f}; + static float hpr[3] = {90.0000,-15.0000,0.0000}; + dsSetViewpoint (xyz,hpr); + printf ("Press:\n" + "\t'a' to apply a torque\n" + "\t'r' to reset simulation.\n"); +} + +/** + Delete the bodies, etc. +*/ +static void clear() +{ + if (world) dWorldDestroy (world); + world = 0; +} + + + +/** + Cleanup if necessary and rebuild the + world. +*/ +static void reset() +{ + clear(); + + // create world + world = dWorldCreate(); + + // Calculate mass for a box; + dMass boxMass; + dMassSetBox(&boxMass,density,sides[0],sides[1],sides[2]); + + noGyroBody = dBodyCreate(world);// Conservation of ang-velocity + expGyroBody = dBodyCreate(world);// Explicit conservation of ang-momentum + impGyroBody = dBodyCreate(world);// Implicit conservation of ang-momentum + + dBodySetMass( noGyroBody , &boxMass ); + dBodySetMass( expGyroBody, &boxMass ); + dBodySetMass( impGyroBody, &boxMass ); + + // Try to avoid collisions. + dReal sep = dCalcVectorLength3(sides); + dBodySetPosition( noGyroBody , -sep, 0, sep); + dBodySetPosition( expGyroBody, 0, 0, sep); + dBodySetPosition( impGyroBody, sep, 0, sep); + + // Set the initial angular velocity + dBodySetAngularVel( noGyroBody , omega[0], omega[1], omega[2]); + dBodySetAngularVel( expGyroBody, omega[0], omega[1], omega[2]); + dBodySetAngularVel( impGyroBody, omega[0], omega[1], omega[2]); + + dBodySetGyroscopicMode( noGyroBody, 0); + // We compute this ourselves using the math + // that was in the old stepper. + dBodySetGyroscopicMode(expGyroBody, 0); + // Keep things from crashing by limiting + // the angular speed of the explicit body. + // Note that this isn't necessary for + // the other two bodies. + dBodySetMaxAngularSpeed( expGyroBody, 40 ); +} + +static void command (int cmd) +{ + switch (cmd) { + case 'a': case 'A': + dBodyAddTorque( noGyroBody, torque[0], torque[1], torque[2]); + dBodyAddTorque(expGyroBody, torque[0], torque[1], torque[2]); + dBodyAddTorque(impGyroBody, torque[0], torque[1], torque[2]); + break; + case 'r': case 'R': + reset(); + break; + } + +} + +/** + This is the explicit computation of + gyroscopic forces. +*/ +static void expStep(dBodyID body) +{ + // Explicit computation + dMatrix3 I,tmp; + dMass m; + dBodyGetMass(body,&m); + const dReal* R = dBodyGetRotation(body); + // compute inertia tensor in global frame + dMultiply2_333 (tmp,m.I,R); + dMultiply0_333 (I,R,tmp); + // compute explicit rotational force + // we treat 'tmp'like a vector, but that's okay. + const dReal* w = dBodyGetAngularVel(body); + dMultiply0_331 (tmp,I,w); + dVector3 tau; + dCalcVectorCross3(tau,tmp,w); + dBodyAddTorque(body,tau[0],tau[1],tau[2]); +} + + +// simulation loop +static void simLoop (int pause) +{ + if (!pause) { + expStep(expGyroBody); + dWorldStep (world,dt); + } + + dsSetTexture (DS_WOOD); + dsSetColor(1,0,0); + dsDrawBox(dBodyGetPosition(noGyroBody ),dBodyGetRotation(noGyroBody ),sides); + dsSetColor(1,1,0); + dsDrawBox(dBodyGetPosition(expGyroBody),dBodyGetRotation(expGyroBody),sides); + dsSetColor(0,1,0); + dsDrawBox(dBodyGetPosition(impGyroBody),dBodyGetRotation(impGyroBody),sides); +} + + +int main (int argc, char **argv) +{ + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + dInitODE2(0); + reset(); + + // run simulation + dsSimulationLoop (argc,argv,352,288,&fn); + + clear(); + dCloseODE(); + return 0; +} diff --git a/libs/ode-0.16.1/ode/demo/demo_gyroscopic.cpp b/libs/ode-0.16.1/ode/demo/demo_gyroscopic.cpp new file mode 100644 index 0000000..5b6a532 --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_gyroscopic.cpp @@ -0,0 +1,258 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + +// select correct drawing functions + +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#define dsDrawSphere dsDrawSphereD +#define dsDrawCylinder dsDrawCylinderD +#define dsDrawCapsule dsDrawCapsuleD +#define dsDrawConvex dsDrawConvexD +#endif + +bool write_world = false; +bool show_contacts = false; +dWorld * world; +dBody *top1, *top2; +dSpace *space; +dJointGroup contactgroup; + +const dReal pinradius = 0.05f; +const dReal pinlength = 1.5f; +const dReal topradius = 1.0f; +const dReal toplength = 0.25f; +const dReal topmass = 1.0f; + +#define MAX_CONTACTS 4 + +static void nearCallback (void *, dGeomID o1, dGeomID o2) +{ + // for drawing the contact points + dMatrix3 RI; + dRSetIdentity (RI); + const dReal ss[3] = {0.02,0.02,0.02}; + + int i; + dBodyID b1 = dGeomGetBody(o1); + dBodyID b2 = dGeomGetBody(o2); + + dContact contact[MAX_CONTACTS]; + int numc = dCollide (o1,o2,MAX_CONTACTS,&contact[0].geom, + sizeof(dContact)); + + for (i=0; i<numc; i++) { + contact[i].surface.mode = dContactApprox1; + contact[i].surface.mu = 2; + + dJointID c = dJointCreateContact (*world,contactgroup,contact+i); + dJointAttach (c,b1,b2); + if (show_contacts) + dsDrawBox (contact[i].geom.pos, RI, ss); + + } +} + + +// start simulation - set viewpoint + +static void start() +{ + static float xyz[3] = {4.777f, -2.084f, 2.18f}; + static float hpr[3] = {153.0f, -14.5f, 0.0f}; + dsSetViewpoint (xyz,hpr); + printf ("Orange top approximates conservation of angular momentum\n"); + printf ("Green top uses conservation of angular velocity\n"); + printf ("---\n"); + printf ("SPACE to reset\n"); + printf ("A to tilt the tops.\n"); + printf ("T to toggle showing the contact points.\n"); + printf ("1 to save the current state to 'state.dif'.\n"); +} + + +char locase (char c) +{ + if (c >= 'A' && c <= 'Z') return c - ('a'-'A'); + else return c; +} + + +// called when a key pressed +static void reset(); +static void tilt(); + +static void command (int cmd) +{ + cmd = locase (cmd); + if (cmd == ' ') + { + reset(); + } + else if (cmd == 'a') { + tilt(); + } + else if (cmd == 't') { + show_contacts = !show_contacts; + } + else if (cmd == '1') { + write_world = true; + } +} + +// simulation loop + +static void simLoop (int pause) +{ + dsSetColor (0,0,2); + space->collide(0,&nearCallback); + if (!pause) + //world->quickStep(0.02); + world->step(0.02); + + if (write_world) { + FILE *f = fopen ("state.dif","wt"); + if (f) { + dWorldExportDIF (*world,f,"X"); + fclose (f); + } + write_world = false; + } + + // remove all contact joints + dJointGroupEmpty (contactgroup); + + dsSetTexture (DS_WOOD); + + dsSetColor (1,0.5f,0); + dsDrawCylinder(top1->getPosition(), + top1->getRotation(), + toplength, topradius); + dsDrawCapsule(top1->getPosition(), + top1->getRotation(), + pinlength, pinradius); + + dsSetColor (0.5f,1,0); + dsDrawCylinder(top2->getPosition(), + top2->getRotation(), + toplength, topradius); + dsDrawCapsule(top2->getPosition(), + top2->getRotation(), + pinlength, pinradius); + +} + + +static void reset() +{ + dMatrix3 R; + dRSetIdentity(R); + + top1->setRotation(R); + top2->setRotation(R); + + top1->setPosition(0.8f, -2, 2); + top2->setPosition(0.8f, 2, 2); + + top1->setAngularVel(1,0,7); + top2->setAngularVel(1,0,7); + + top1->setLinearVel(0,0.2f,0); + top2->setLinearVel(0,0.2f,0); +} + +static void tilt() +{ + top1->addTorque(0, 10, 0); + top2->addTorque(0, 10, 0); +} + +int main (int argc, char **argv) +{ + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + + // create world + dInitODE(); + world = new dWorld(); + world->setGravity(0,0,-0.5f); + world->setCFM(1e-5f); + world->setLinearDamping(0.00001f); + world->setAngularDamping(0.0001f); + + space = new dSimpleSpace(0); + + dPlane *floor = new dPlane(*space, 0,0,1,0); + + top1 = new dBody(*world); + top2 = new dBody(*world); + + dMass m; + m.setCylinderTotal(1, 3, topradius, toplength); + top1->setMass(m); + top2->setMass(m); + + dGeom *g1, *g2, *pin1, *pin2; + g1 = new dCylinder(*space, topradius, toplength); + g1->setBody(*top1); + g2 = new dCylinder(*space, topradius, toplength); + g2->setBody(*top2); + + pin1 = new dCapsule(*space, pinradius, pinlength); + pin1->setBody(*top1); + pin2 = new dCapsule(*space, pinradius, pinlength); + pin2->setBody(*top2); + + top2->setGyroscopicMode(false); + + reset(); + + // run simulation + dsSimulationLoop (argc,argv,512,384,&fn); + + delete g1; + delete g2; + delete pin1; + delete pin2; + delete floor; + contactgroup.empty(); + delete top1; + delete top2; + delete space; + delete world; + dCloseODE(); +} diff --git a/libs/ode-0.16.1/ode/demo/demo_heightfield.cpp b/libs/ode-0.16.1/ode/demo/demo_heightfield.cpp new file mode 100644 index 0000000..d68cb6a --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_heightfield.cpp @@ -0,0 +1,714 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" +#include "bunny_geom.h" + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + + +#define DEGTORAD 0.01745329251994329577f //!< PI / 180.0, convert degrees to radians + +int g_allow_trimesh; + +// Our heightfield geom +dGeomID gheight; + + + +// Heightfield dimensions + +#define HFIELD_WSTEP 15 // Vertex count along edge >= 2 +#define HFIELD_DSTEP 31 + +#define HFIELD_WIDTH REAL( 4.0 ) +#define HFIELD_DEPTH REAL( 8.0 ) + +#define HFIELD_WSAMP ( HFIELD_WIDTH / ( HFIELD_WSTEP-1 ) ) +#define HFIELD_DSAMP ( HFIELD_DEPTH / ( HFIELD_DSTEP-1 ) ) + + + +//<---- Convex Object +dReal planes[]= // planes for a cube + { + 1.0f ,0.0f ,0.0f ,0.25f, + 0.0f ,1.0f ,0.0f ,0.25f, + 0.0f ,0.0f ,1.0f ,0.25f, + 0.0f ,0.0f ,-1.0f,0.25f, + 0.0f ,-1.0f,0.0f ,0.25f, + -1.0f,0.0f ,0.0f ,0.25f + /* + 1.0f ,0.0f ,0.0f ,2.0f, + 0.0f ,1.0f ,0.0f ,1.0f, + 0.0f ,0.0f ,1.0f ,1.0f, + 0.0f ,0.0f ,-1.0f,1.0f, + 0.0f ,-1.0f,0.0f ,1.0f, + -1.0f,0.0f ,0.0f ,0.0f + */ + }; +const unsigned int planecount=6; + +dReal points[]= // points for a cube + { + 0.25f,0.25f,0.25f, // point 0 + -0.25f,0.25f,0.25f, // point 1 + + 0.25f,-0.25f,0.25f, // point 2 + -0.25f,-0.25f,0.25f,// point 3 + + 0.25f,0.25f,-0.25f, // point 4 + -0.25f,0.25f,-0.25f,// point 5 + + 0.25f,-0.25f,-0.25f,// point 6 + -0.25f,-0.25f,-0.25f,// point 7 + }; +const unsigned int pointcount=8; +unsigned int polygons[] = //Polygons for a cube (6 squares) + { + 4,0,2,6,4, // positive X + 4,1,0,4,5, // positive Y + 4,0,1,3,2, // positive Z + 4,3,1,5,7, // negative X + 4,2,3,7,6, // negative Y + 4,5,4,6,7, // negative Z + }; +//----> Convex Object + +// select correct drawing functions + +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#define dsDrawSphere dsDrawSphereD +#define dsDrawCylinder dsDrawCylinderD +#define dsDrawCapsule dsDrawCapsuleD +#define dsDrawConvex dsDrawConvexD +#define dsDrawTriangle dsDrawTriangleD +#endif + + +// some constants + +#define NUM 100 // max number of objects +#define DENSITY (5.0) // density of all objects +#define GPB 3 // maximum number of geometries per body +#define MAX_CONTACTS 64 // maximum number of contact points per body + + +// dynamics and collision objects + +struct MyObject { + dBodyID body; // the body + dGeomID geom[GPB]; // geometries representing this body + + // Trimesh only - double buffered matrices for 'last transform' setup + dReal matrix_dblbuff[ 16 * 2 ]; + int last_matrix_index; +}; + +static int num=0; // number of objects in simulation +static int nextobj=0; // next object to recycle if num==NUM +static dWorldID world; +static dSpaceID space; +static MyObject obj[NUM]; +static dJointGroupID contactgroup; +static int selected = -1; // selected object +static int show_aabb = 0; // show geom AABBs? +static int show_contacts = 0; // show contact points? +static int random_pos = 1; // drop objects from random position? +static int write_world = 0; + + + + +//============================ + +dGeomID TriMesh1; +dGeomID TriMesh2; +//static dTriMeshDataID TriData1, TriData2; // reusable static trimesh data + +//============================ + + +dReal heightfield_callback( void*, int x, int z ) +{ + dReal fx = ( ((dReal)x) - ( HFIELD_WSTEP-1 )/2 ) / (dReal)( HFIELD_WSTEP-1 ); + dReal fz = ( ((dReal)z) - ( HFIELD_DSTEP-1 )/2 ) / (dReal)( HFIELD_DSTEP-1 ); + + // Create an interesting 'hump' shape + dReal h = REAL( 1.0 ) + ( REAL( -16.0 ) * ( fx*fx*fx + fz*fz*fz ) ); + + return h; +} + + + + +// this is called by dSpaceCollide when two objects in space are +// potentially colliding. + +static void nearCallback (void *, dGeomID o1, dGeomID o2) +{ + int i; + // if (o1->body && o2->body) return; + + // exit without doing anything if the two bodies are connected by a joint + dBodyID b1 = dGeomGetBody(o1); + dBodyID b2 = dGeomGetBody(o2); + if (b1 && b2 && dAreConnectedExcluding(b1,b2,dJointTypeContact)) + return; + + dContact contact[MAX_CONTACTS]; // up to MAX_CONTACTS contacts per box-box + for (i=0; i<MAX_CONTACTS; i++) { + contact[i].surface.mode = dContactBounce | dContactSoftCFM; + contact[i].surface.mu = dInfinity; + contact[i].surface.mu2 = 0; + contact[i].surface.bounce = 0.1; + contact[i].surface.bounce_vel = 0.1; + contact[i].surface.soft_cfm = 0.01; + } + if (int numc = dCollide(o1,o2,MAX_CONTACTS,&contact[0].geom, + sizeof(dContact))) { + dMatrix3 RI; + dRSetIdentity(RI); + const dReal ss[3] = {0.02,0.02,0.02}; + for (i=0; i<numc; i++) { + dJointID c = dJointCreateContact(world,contactgroup,contact+i); + dJointAttach(c,b1,b2); + if (show_contacts) { + dsSetColor(0,0,1); + dsDrawBox(contact[i].geom.pos,RI,ss); + } + } + } +} + + +// start simulation - set viewpoint + +static void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + static float xyz[3] = {2.1640f,-1.3079f,1.7600f}; + static float hpr[3] = {125.5000f,-17.0000f,0.0000f}; + dsSetViewpoint (xyz,hpr); + printf("To drop another object, press:\n"); + printf(" b for box.\n"); + printf(" s for sphere.\n"); + printf(" c for capsule.\n"); + printf(" y for cylinder.\n"); + printf(" v for a convex object.\n"); + printf(" x for a composite object.\n"); + if ( g_allow_trimesh ) + printf(" m for a trimesh.\n"); + printf("To select an object, press space.\n"); + printf("To disable the selected object, press d.\n"); + printf("To enable the selected object, press e.\n"); + printf("To toggle showing the geom AABBs, press a.\n"); + printf("To toggle showing the contact points, press t.\n"); + printf("To toggle dropping from random position/orientation, press r.\n"); + printf("To save the current state to 'state.dif', press 1.\n"); +} + + +char locase(char c) +{ + if (c >= 'A' && c <= 'Z') return c - ('a'-'A'); + else return c; +} + + +// called when a key pressed + +static void command(int cmd) +{ + dsizeint i; + int j,k; + dReal sides[3]; + dMass m; + bool setBody = false; + + cmd = locase (cmd); + + + // + // Geom Creation + // + + if ( cmd == 'b' || cmd == 's' || cmd == 'c' || ( cmd == 'm' && g_allow_trimesh ) || + cmd == 'x' || cmd == 'y' || cmd == 'v' ) { + + if ( num < NUM ) { + i = num; + num++; + } else { + i = nextobj++; + nextobj %= num; + + // destroy the body and geoms for slot i + dBodyDestroy(obj[i].body); + obj[i].body = 0; + + for (k=0; k < GPB; k++) + if (obj[i].geom[k]) { + dGeomDestroy(obj[i].geom[k]); + obj[i].geom[k] = 0; + } + } + + obj[i].body = dBodyCreate(world); + for (k=0; k<3; k++) + sides[k] = dRandReal()*0.5+0.1; + + dMatrix3 R; + if (random_pos) { + dBodySetPosition(obj[i].body, + (dRandReal()-0.5)*HFIELD_WIDTH*0.75, + (dRandReal()-0.5)*HFIELD_DEPTH*0.75, + dRandReal() + 2 ); + dRFromAxisAndAngle(R,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, + dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); + } else { + dReal maxheight = 0; + for (k=0; k<num; k++) { + const dReal *pos = dBodyGetPosition(obj[k].body); + if (pos[2] > maxheight) + maxheight = pos[2]; + } + dBodySetPosition(obj[i].body, 0,maxheight+1,0); + dRFromAxisAndAngle(R,0,0,1,dRandReal()*10.0-5.0); + } + + dBodySetRotation(obj[i].body,R); + + if (cmd == 'b') { + + dMassSetBox(&m,DENSITY,sides[0],sides[1],sides[2]); + obj[i].geom[0] = dCreateBox(space,sides[0],sides[1],sides[2]); + + } else if (cmd == 'c') { + + sides[0] *= 0.5; + dMassSetCapsule(&m,DENSITY,3,sides[0],sides[1]); + obj[i].geom[0] = dCreateCapsule(space,sides[0],sides[1]); + + } else if (cmd == 'v') { + + dMassSetBox (&m,DENSITY,0.25,0.25,0.25); + obj[i].geom[0] = dCreateConvex(space, + planes, + planecount, + points, + pointcount, + polygons); + + } else if (cmd == 'y') { + + dMassSetCylinder(&m,DENSITY,3,sides[0],sides[1]); + obj[i].geom[0] = dCreateCylinder(space,sides[0],sides[1]); + + } else if (cmd == 's') { + + sides[0] *= 0.5; + dMassSetSphere(&m,DENSITY,sides[0]); + obj[i].geom[0] = dCreateSphere(space,sides[0]); + + } else if (cmd == 'm' && g_allow_trimesh) { + + dTriMeshDataID new_tmdata = dGeomTriMeshDataCreate(); + dGeomTriMeshDataBuildSingle(new_tmdata, &Vertices[0], 3 * sizeof(float), VertexCount, + &Indices[0], IndexCount, 3 * sizeof(dTriIndex)); + dGeomTriMeshDataPreprocess2(new_tmdata, (1U << dTRIDATAPREPROCESS_BUILD_FACE_ANGLES), NULL); + + obj[i].geom[0] = dCreateTriMesh(space, new_tmdata, 0, 0, 0); + + dMassSetTrimesh( &m, DENSITY, obj[i].geom[0] ); + printf("mass at %f %f %f\n", m.c[0], m.c[1], m.c[2]); + dGeomSetPosition(obj[i].geom[0], -m.c[0], -m.c[1], -m.c[2]); + dMassTranslate(&m, -m.c[0], -m.c[1], -m.c[2]); + + } else if (cmd == 'x') { + + setBody = 1; + // start accumulating masses for the composite geometries + dMass m2; + dMassSetZero (&m); + + dReal dpos[GPB][3]; // delta-positions for composite geometries + dMatrix3 drot[GPB]; + + // set random delta positions + for (j=0; j<GPB; j++) + for (k=0; k<3; k++) + dpos[j][k] = dRandReal()*0.3-0.15; + + for (k=0; k<GPB; k++) { + if (k==0) { + dReal radius = dRandReal()*0.25+0.05; + obj[i].geom[k] = dCreateSphere (space,radius); + dMassSetSphere (&m2,DENSITY,radius); + } + else if (k==1) { + obj[i].geom[k] = dCreateBox(space,sides[0],sides[1],sides[2]); + dMassSetBox(&m2,DENSITY,sides[0],sides[1],sides[2]); + } else { + dReal radius = dRandReal()*0.1+0.05; + dReal length = dRandReal()*1.0+0.1; + obj[i].geom[k] = dCreateCapsule(space,radius,length); + dMassSetCapsule(&m2,DENSITY,3,radius,length); + } + + dRFromAxisAndAngle(drot[k],dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, + dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); + dMassRotate(&m2,drot[k]); + + dMassTranslate(&m2,dpos[k][0],dpos[k][1],dpos[k][2]); + + // add to the total mass + dMassAdd(&m,&m2); + + } + for (k=0; k<GPB; k++) { + dGeomSetBody(obj[i].geom[k],obj[i].body); + dGeomSetOffsetPosition(obj[i].geom[k], + dpos[k][0]-m.c[0], + dpos[k][1]-m.c[1], + dpos[k][2]-m.c[2]); + dGeomSetOffsetRotation(obj[i].geom[k], drot[k]); + } + dMassTranslate(&m,-m.c[0],-m.c[1],-m.c[2]); + dBodySetMass(obj[i].body,&m); + + } + + if (!setBody) { // avoid calling for composite geometries + for (k=0; k < GPB; k++) + if (obj[i].geom[k]) + dGeomSetBody(obj[i].geom[k],obj[i].body); + + dBodySetMass(obj[i].body,&m); + } + } + + + // + // Control Commands + // + + if (cmd == ' ') { + + selected++; + if (selected >= num) + selected = 0; + if (selected < -1) + selected = 0; + + } else if (cmd == 'd' && selected >= 0 && selected < num) { + + dBodyDisable(obj[selected].body); + + } else if (cmd == 'e' && selected >= 0 && selected < num) { + + dBodyEnable(obj[selected].body); + + } else if (cmd == 'a') { + + show_aabb = !show_aabb; + + } else if (cmd == 't') { + + show_contacts = !show_contacts; + + } else if (cmd == 'r') { + + random_pos = !random_pos; + + } else if (cmd == '1') { + + write_world = 1; + + } +} + + +// draw a geom + +void drawGeom (dGeomID g, const dReal *pos, const dReal *R, int show_aabb) +{ + if (!g) + return; + if (!pos) + pos = dGeomGetPosition(g); + if (!R) + R = dGeomGetRotation(g); + + int type = dGeomGetClass(g); + if (type == dBoxClass) { + + dVector3 sides; + dGeomBoxGetLengths(g,sides); + dsDrawBox(pos,R,sides); + + } else if (type == dSphereClass) { + + dsDrawSphere(pos,R,dGeomSphereGetRadius(g)); + + } else if (type == dCapsuleClass) { + + dReal radius,length; + dGeomCapsuleGetParams(g,&radius,&length); + dsDrawCapsule(pos,R,length,radius); + + } else if (type == dConvexClass) { + + //dVector3 sides={0.50,0.50,0.50}; + dsDrawConvex(pos,R,planes, + planecount, + points, + pointcount, + polygons); + + } else if (type == dCylinderClass) { + + dReal radius,length; + dGeomCylinderGetParams(g,&radius,&length); + dsDrawCylinder(pos,R,length,radius); + + } else if (type == dTriMeshClass) { + + dTriIndex* Indices = (dTriIndex*)::Indices; + + // assume all trimeshes are drawn as bunnies + for (int ii = 0; ii < IndexCount / 3; ii++) { + const dReal v[9] = { // explicit conversion from float to dReal + Vertices[Indices[ii * 3 + 0] * 3 + 0], + Vertices[Indices[ii * 3 + 0] * 3 + 1], + Vertices[Indices[ii * 3 + 0] * 3 + 2], + Vertices[Indices[ii * 3 + 1] * 3 + 0], + Vertices[Indices[ii * 3 + 1] * 3 + 1], + Vertices[Indices[ii * 3 + 1] * 3 + 2], + Vertices[Indices[ii * 3 + 2] * 3 + 0], + Vertices[Indices[ii * 3 + 2] * 3 + 1], + Vertices[Indices[ii * 3 + 2] * 3 + 2] + }; + dsDrawTriangle(pos, R, &v[0], &v[3], &v[6], 1); + } + + } else if (type == dHeightfieldClass) { + + // Set ox and oz to zero for DHEIGHTFIELD_CORNER_ORIGIN mode. + int ox = (int) ( -HFIELD_WIDTH/2 ); + int oz = (int) ( -HFIELD_DEPTH/2 ); + + // for ( int tx = -1; tx < 2; ++tx ) + // for ( int tz = -1; tz < 2; ++tz ) + dsSetColorAlpha (0.5,1,0.5,0.5); + dsSetTexture( DS_WOOD ); + + for ( int i = 0; i < HFIELD_WSTEP - 1; ++i ) + for ( int j = 0; j < HFIELD_DSTEP - 1; ++j ) { + dReal a[3], b[3], c[3], d[3]; + + a[ 0 ] = ox + ( i ) * HFIELD_WSAMP; + a[ 1 ] = heightfield_callback( NULL, i, j ); + a[ 2 ] = oz + ( j ) * HFIELD_DSAMP; + + b[ 0 ] = ox + ( i + 1 ) * HFIELD_WSAMP; + b[ 1 ] = heightfield_callback( NULL, i + 1, j ); + b[ 2 ] = oz + ( j ) * HFIELD_DSAMP; + + c[ 0 ] = ox + ( i ) * HFIELD_WSAMP; + c[ 1 ] = heightfield_callback( NULL, i, j + 1 ); + c[ 2 ] = oz + ( j + 1 ) * HFIELD_DSAMP; + + d[ 0 ] = ox + ( i + 1 ) * HFIELD_WSAMP; + d[ 1 ] = heightfield_callback( NULL, i + 1, j + 1 ); + d[ 2 ] = oz + ( j + 1 ) * HFIELD_DSAMP; + + dsDrawTriangle( pos, R, a, c, b, 1 ); + dsDrawTriangle( pos, R, b, c, d, 1 ); + } + + } + + if (show_aabb) { + // draw the bounding box for this geom + dReal aabb[6]; + dGeomGetAABB(g,aabb); + dVector3 bbpos; + for (int i=0; i<3; i++) + bbpos[i] = 0.5*(aabb[i*2] + aabb[i*2+1]); + dVector3 bbsides; + for (int i=0; i<3; i++) + bbsides[i] = aabb[i*2+1] - aabb[i*2]; + dMatrix3 RI; + dRSetIdentity(RI); + dsSetColorAlpha(1,0,0,0.5); + dsDrawBox(bbpos,RI,bbsides); + } + +} + +// simulation loop + +static void simLoop (int pause) +{ + int i,j; + + dSpaceCollide(space,0,&nearCallback); + + if (!pause) + dWorldQuickStep(world,0.05); + + + if (write_world) { + FILE *f = fopen ("state.dif","wt"); + if (f) { + dWorldExportDIF(world,f,"X"); + fclose (f); + } + write_world = 0; + } + + // remove all contact joints + dJointGroupEmpty(contactgroup); + + + + // + // Draw Heightfield + // + + drawGeom(gheight, 0, 0, 0); + + + + dsSetColor (1,1,0); + dsSetTexture (DS_WOOD); + for (i=0; i<num; i++) { + for (j=0; j < GPB; j++) { + if (i==selected) { + dsSetColor (0,0.7,1); + } else if (! dBodyIsEnabled (obj[i].body)) { + dsSetColor (1,0.8,0); + } else { + dsSetColor (1,1,0); + } + + drawGeom (obj[i].geom[j],0,0,show_aabb); + } + } + +} + + +int main (int argc, char **argv) +{ + printf("ODE configuration: %s\n", dGetConfiguration()); + + // Is trimesh support built into this ODE? + g_allow_trimesh = dCheckConfiguration( "ODE_EXT_trimesh" ); + + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + // create world + dInitODE2(0); + world = dWorldCreate(); + space = dHashSpaceCreate (0); + contactgroup = dJointGroupCreate (0); + dWorldSetGravity(world,0,0,-0.05); + dWorldSetCFM(world,1e-5); + dWorldSetAutoDisableFlag(world,1); + dWorldSetContactMaxCorrectingVel(world,0.1); + dWorldSetContactSurfaceLayer(world,0.001); + memset(obj,0,sizeof(obj)); + + dWorldSetAutoDisableAverageSamplesCount( world, 1 ); + + // base plane to catch overspill + dCreatePlane( space, 0, 0, 1, 0 ); + + + // our heightfield floor + + dHeightfieldDataID heightid = dGeomHeightfieldDataCreate(); + + // Create an finite heightfield. + dGeomHeightfieldDataBuildCallback( heightid, NULL, heightfield_callback, + HFIELD_WIDTH, HFIELD_DEPTH, HFIELD_WSTEP, HFIELD_DSTEP, + REAL( 1.0 ), REAL( 0.0 ), REAL( 0.0 ), 0 ); + + // Give some very bounds which, while conservative, + // makes AABB computation more accurate than +/-INF. + dGeomHeightfieldDataSetBounds( heightid, REAL( -4.0 ), REAL( +6.0 ) ); + + gheight = dCreateHeightfield( space, heightid, 1 ); + + dVector3 pos; + pos[ 0 ] = 0; + pos[ 1 ] = 0; + pos[ 2 ] = 0; + + // Rotate so Z is up, not Y (which is the default orientation) + dMatrix3 R; + dRSetIdentity( R ); + dRFromAxisAndAngle( R, 1, 0, 0, DEGTORAD * 90 ); + + // Place it. + dGeomSetRotation( gheight, R ); + dGeomSetPosition( gheight, pos[0], pos[1], pos[2] ); + + dThreadingImplementationID threading = dThreadingAllocateMultiThreadedImplementation(); + dThreadingThreadPoolID pool = dThreadingAllocateThreadPool(4, 0, dAllocateFlagBasicData, NULL); + dThreadingThreadPoolServeMultiThreadedImplementation(pool, threading); + // dWorldSetStepIslandsProcessingMaxThreadCount(world, 1); + dWorldSetStepThreadingImplementation(world, dThreadingImplementationGetFunctions(threading), threading); + + // run simulation + dsSimulationLoop (argc,argv,352,288,&fn); + + dThreadingImplementationShutdownProcessing(threading); + dThreadingFreeThreadPool(pool); + dWorldSetStepThreadingImplementation(world, NULL, NULL); + dThreadingFreeImplementation(threading); + + dJointGroupDestroy (contactgroup); + dSpaceDestroy (space); + dWorldDestroy (world); + + // destroy heightfield data, because _we_ own it not ODE + dGeomHeightfieldDataDestroy( heightid ); + + dCloseODE(); +} diff --git a/libs/ode-0.16.1/ode/demo/demo_hinge.cpp b/libs/ode-0.16.1/ode/demo/demo_hinge.cpp new file mode 100644 index 0000000..926da21 --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_hinge.cpp @@ -0,0 +1,165 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + +// select correct drawing functions +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#endif + + +// some constants +#define SIDE (0.5f) // side length of a box +#define MASS (1.0) // mass of a box + + +// dynamics and collision objects +static dWorldID world; +static dBodyID body[2]; +static dJointID hinge; + + +// state set by keyboard commands +static int occasional_error = 0; + + +// start simulation - set viewpoint + +static void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + static float xyz[3] = {1.0382f,-1.0811f,1.4700f}; + static float hpr[3] = {135.0000f,-19.5000f,0.0000f}; + dsSetViewpoint (xyz,hpr); + printf ("Press 'e' to start/stop occasional error.\n"); +} + + +// called when a key pressed + +static void command (int cmd) +{ + if (cmd == 'e' || cmd == 'E') { + occasional_error ^= 1; + } +} + + +// simulation loop + +static void simLoop (int pause) +{ + const dReal kd = -0.3; // angular damping constant + if (!pause) { + // add an oscillating torque to body 0, and also damp its rotational motion + static dReal a=0; + const dReal *w = dBodyGetAngularVel (body[0]); + dBodyAddTorque (body[0],kd*w[0],kd*w[1]+0.1*cos(a),kd*w[2]+0.1*sin(a)); + dWorldStep (world,0.05); + a += 0.01; + + // occasionally re-orient one of the bodies to create a deliberate error. + if (occasional_error) { + static int count = 0; + if ((count % 20)==0) { + // randomly adjust orientation of body[0] + const dReal *R1; + dMatrix3 R2,R3; + R1 = dBodyGetRotation (body[0]); + dRFromAxisAndAngle (R2,dRandReal()-0.5,dRandReal()-0.5, + dRandReal()-0.5,dRandReal()-0.5); + dMultiply0 (R3,R1,R2,3,3,3); + dBodySetRotation (body[0],R3); + + // randomly adjust position of body[0] + const dReal *pos = dBodyGetPosition (body[0]); + dBodySetPosition (body[0], + pos[0]+0.2*(dRandReal()-0.5), + pos[1]+0.2*(dRandReal()-0.5), + pos[2]+0.2*(dRandReal()-0.5)); + } + count++; + } + } + + dReal sides1[3] = {SIDE,SIDE,SIDE}; + dReal sides2[3] = {SIDE,SIDE,SIDE*0.8f}; + dsSetTexture (DS_WOOD); + dsSetColor (1,1,0); + dsDrawBox (dBodyGetPosition(body[0]),dBodyGetRotation(body[0]),sides1); + dsSetColor (0,1,1); + dsDrawBox (dBodyGetPosition(body[1]),dBodyGetRotation(body[1]),sides2); +} + + +int main (int argc, char **argv) +{ + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + // create world + dInitODE2(0); + world = dWorldCreate(); + + dMass m; + dMassSetBox (&m,1,SIDE,SIDE,SIDE); + dMassAdjust (&m,MASS); + + dQuaternion q; + dQFromAxisAndAngle (q,1,1,0,0.25*M_PI); + + body[0] = dBodyCreate (world); + dBodySetMass (body[0],&m); + dBodySetPosition (body[0],0.5*SIDE,0.5*SIDE,1); + dBodySetQuaternion (body[0],q); + + body[1] = dBodyCreate (world); + dBodySetMass (body[1],&m); + dBodySetPosition (body[1],-0.5*SIDE,-0.5*SIDE,1); + dBodySetQuaternion (body[1],q); + + hinge = dJointCreateHinge (world,0); + dJointAttach (hinge,body[0],body[1]); + dJointSetHingeAnchor (hinge,0,0,1); + dJointSetHingeAxis (hinge,1,-1,1.41421356); + + // run simulation + dsSimulationLoop (argc,argv,352,288,&fn); + + dWorldDestroy (world); + dCloseODE(); + return 0; +} diff --git a/libs/ode-0.16.1/ode/demo/demo_jointPR.cpp b/libs/ode-0.16.1/ode/demo/demo_jointPR.cpp new file mode 100644 index 0000000..b760af1 --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_jointPR.cpp @@ -0,0 +1,434 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +This file try to demonstrate how the PR joint is working. + +The axisP is draw in red and the axisR is in green + +*/ + + +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include <iostream> +#include <math.h> +#include "texturepath.h" + + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif +// select correct drawing functions +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#endif + + +// physics parameters +#define BOX1_LENGTH 2 // Size along the X axis +#define BOX1_WIDTH 1 // Size along the Y axis +#define BOX1_HEIGHT 0.4 // Size along the Z axis (up) since gravity is (0,0,-10) +#define BOX2_LENGTH 0.2 +#define BOX2_WIDTH 0.1 +#define BOX2_HEIGHT 0.4 +#define Mass1 10 +#define Mass2 0.1 + + +#define PRISMATIC_ONLY 1 +#define ROTOIDE_ONLY 2 +int flag = 0; + + +//camera view +static float xyz[3] = {2.0f,-3.5f,2.0000f}; +static float hpr[3] = {90.000f,-25.5000f,0.0000f}; +//world,space,body & geom +static dWorldID world; +static dSpaceID space; +static dSpaceID box1_space; +static dBodyID box1_body[1]; +static dBodyID box2_body[1]; +static dJointID joint[1]; +static dJointGroupID contactgroup; +static dGeomID ground; +static dGeomID box1[1]; +static dGeomID box2[1]; + + +//collision detection +static void nearCallback (void *, dGeomID o1, dGeomID o2) +{ + int i,n; + + dBodyID b1 = dGeomGetBody(o1); + dBodyID b2 = dGeomGetBody(o2); + if (b1 && b2 && dAreConnectedExcluding (b1,b2,dJointTypeContact)) return; + const int N = 10; + dContact contact[N]; + n = dCollide (o1,o2,N,&contact[0].geom,sizeof(dContact)); + if (n > 0) + { + for (i=0; i<n; i++) + { + contact[i].surface.mode = dContactSlip1 | dContactSlip2 | + dContactSoftERP | dContactSoftCFM | dContactApprox1; + contact[i].surface.mu = 0.1; + contact[i].surface.slip1 = 0.02; + contact[i].surface.slip2 = 0.02; + contact[i].surface.soft_erp = 0.1; + contact[i].surface.soft_cfm = 0.0001; + dJointID c = dJointCreateContact (world,contactgroup,&contact[i]); + dJointAttach (c,dGeomGetBody(contact[i].geom.g1),dGeomGetBody(contact[i].geom.g2)); + } + } +} + + +// start simulation - set viewpoint +static void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + dsSetViewpoint (xyz,hpr); + printf ("Press 'd' to add force along positive x direction.\nPress 'a' to add force along negative x direction.\n"); + printf ("Press 'w' to add force along positive y direction.\nPress 's' to add force along negative y direction.\n"); + printf ("Press 'e' to add torque around positive z direction.\nPress 'q' to add torque around negative z direction.\n"); + printf ("Press 'o' to add force around positive x direction \n"); + + printf("Press 'v' to give a defined velocity and add a FMax to the rotoide axis\n"); + printf("Press 'c' to set the velocity to zero and remove the FMax\n"); + + printf("Press 'l' to add limits (-0.5 to 0.5rad) on the rotoide axis\n"); + printf("Press 'k' to remove the limits on the rotoide axis\n"); + + printf("Press 'i' to get joint info\n"); +} + +// function to update camera position at each step. +void update() +{ +// const dReal *a =(dBodyGetPosition (box1_body[0])); +// float dx=a[0]; +// float dy=a[1]; +// float dz=a[2]; +// xyz[0]=dx; +// xyz[1]=dy-5; +// xyz[2]=dz+2; +// hpr[1]=-22.5000f; +// dsSetViewpoint (xyz,hpr); +} + + +// called when a key pressed +static void command (int cmd) +{ + switch (cmd) + { + case 'w': + case 'W': + dBodyAddForce(box2_body[0],0,500,0); + std::cout<<(dBodyGetPosition(box2_body[0])[1]-dBodyGetPosition(box1_body[0])[1])<<'\n'; + break; + case 's': + case 'S': + dBodyAddForce(box2_body[0],0,-500,0); + std::cout<<(dBodyGetPosition(box2_body[0])[1]-dBodyGetPosition(box1_body[0])[1])<<'\n'; + break; + case 'd': + case 'D': + dBodyAddForce(box2_body[0],500,0,0); + std::cout<<(dBodyGetPosition(box2_body[0])[0]-dBodyGetPosition(box1_body[0])[0])<<'\n'; + break; + case 'a': + case 'A': + dBodyAddForce(box2_body[0],-500,0,0); + std::cout<<(dBodyGetPosition(box2_body[0])[0]-dBodyGetPosition(box1_body[0])[0])<<'\n'; + break; + case 'e': + case 'E': + dBodyAddRelTorque(box2_body[0],0,0,200); + break; + case 'q': + case 'Q': + dBodyAddRelTorque(box2_body[0],0,0,-200); + break; + case 'o': + case 'O': + dBodyAddForce(box1_body[0],10000,0,0); + break; + + case 'v': + case 'V': + dJointSetPRParam(joint[0], dParamVel2, 2); + dJointSetPRParam(joint[0], dParamFMax2, 500); + break; + + case 'c': + case 'C': + dJointSetPRParam(joint[0], dParamVel2, 0); + dJointSetPRParam(joint[0], dParamFMax2, 0); + break; + + case 'l': + case 'L': + dJointSetPRParam(joint[0], dParamLoStop2, -0.5); + dJointSetPRParam(joint[0], dParamHiStop2, 0.5); + break; + + case 'k': + case 'K': + dJointSetPRParam(joint[0], dParamLoStop2, -dInfinity); + dJointSetPRParam(joint[0], dParamHiStop2, dInfinity); + break; + + case 'i': + case 'I': + dVector3 anchor; + dJointGetPRAnchor(joint[0], anchor); + dReal angle = dJointGetPRAngle(joint[0]); + dReal w = dJointGetPRAngleRate(joint[0]); + + dReal l = dJointGetPRPosition(joint[0]); + dReal v = dJointGetPRPositionRate(joint[0]); + + printf("Anchor: [%6.4f, %6.4f, %6.4f]\n", anchor[0], anchor[1], anchor[2]); + printf("Position: %7.4f, Rate: %7.4f\n", l, v); + printf("Angle: %7.4f, Rate: %7.4f\n", angle, w); + break; + } +} + + +// simulation loop +static void simLoop (int pause) +{ + if (!pause) + { + //draw 2 boxes + dVector3 ss; + dsSetTexture (DS_WOOD); + + const dReal *posBox2 = dGeomGetPosition(box2[0]); + const dReal *rotBox2 = dGeomGetRotation(box2[0]); + dsSetColor (1,1,0); + dGeomBoxGetLengths (box2[0],ss); + dsDrawBox (posBox2, rotBox2, ss); + + const dReal *posBox1 = dGeomGetPosition(box1[0]); + const dReal *rotBox1 = dGeomGetRotation(box1[0]); + dsSetColor (1,1,2); + dGeomBoxGetLengths (box1[0], ss); + dsDrawBox (posBox1, rotBox1, ss); + + dVector3 anchorPos; + dJointGetPRAnchor (joint[0], anchorPos); + + // Draw the axisP + if (ROTOIDE_ONLY != flag ) + { + dsSetColor (1,0,0); + dVector3 sizeP = {0, 0.1, 0.1}; + for (int i=0; i<3; ++i) + sizeP[0] += (anchorPos[i] - posBox1[i])*(anchorPos[i] - posBox1[i]); + sizeP[0] = sqrt(sizeP[0]); + dVector3 posAxisP; + for (int i=0; i<3; ++i) + posAxisP[i] = posBox1[i] + (anchorPos[i] - posBox1[i])/2.0; + dsDrawBox (posAxisP, rotBox1, sizeP); + } + + + // Draw the axisR + if (PRISMATIC_ONLY != flag ) + { + dsSetColor (0,1,0); + dVector3 sizeR = {0, 0.1, 0.1}; + for (int i=0; i<3; ++i) + sizeR[0] += (anchorPos[i] - posBox2[i])*(anchorPos[i] - posBox2[i]); + sizeR[0] = sqrt(sizeR[0]); + dVector3 posAxisR; + for (int i=0; i<3; ++i) + posAxisR[i] = posBox2[i] + (anchorPos[i] - posBox2[i])/2.0; + dsDrawBox (posAxisR, rotBox2, sizeR); + } + + dSpaceCollide (space,0,&nearCallback); + dWorldQuickStep (world,0.0001); + update(); + dJointGroupEmpty (contactgroup); + } +} + + +void Help(char **argv) +{ + printf("%s ", argv[0]); + printf(" -h | --help : print this help\n"); + printf(" -b | --both : Display how the complete joint works\n"); + printf(" Default behavior\n"); + printf(" -p | --prismatic-only : Display how the prismatic part works\n"); + printf(" The anchor pts is set at the center of body 2\n"); + printf(" -r | --rotoide-only : Display how the rotoide part works\n"); + printf(" The anchor pts is set at the center of body 1\n"); + printf(" -t | --texture-path path : Path to the texture.\n"); + printf(" Default = %s\n", DRAWSTUFF_TEXTURE_PATH); + printf("--------------------------------------------------\n"); + printf("Hit any key to continue:"); + getchar(); + + exit(0); +} + +int main (int argc, char **argv) +{ + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + if (argc >= 2 ) + { + for (int i=1; i < argc; ++i) + { + if ( 0 == strcmp("-h", argv[i]) || 0 == strcmp("--help", argv[i]) ) + Help(argv); + + if (!flag && (0 == strcmp("-p", argv[i]) ||0 == strcmp("--prismatic-only", argv[i])) ) + flag = PRISMATIC_ONLY; + + if (!flag && (0 == strcmp("-r", argv[i]) || 0 == strcmp("--rotoide-only", argv[i])) ) + flag = ROTOIDE_ONLY; + + if (0 == strcmp("-t", argv[i]) || 0 == strcmp("--texture-path", argv[i])) + { + int j = i+1; + if ( j >= argc || // Check if we have enough arguments + argv[j][0] == '\0' || // We should have a path here + argv[j][0] == '-' ) // We should have a path not a command line + Help(argv); + else + fn.path_to_textures = argv[++i]; // Increase i since we use this argument + } + } + } + + dInitODE2(0); + + // create world + world = dWorldCreate(); + space = dHashSpaceCreate (0); + contactgroup = dJointGroupCreate (0); + dWorldSetGravity (world,0,0,-10); + ground = dCreatePlane (space,0,0,1,0); + + //create two boxes + dMass m; + box1_body[0] = dBodyCreate (world); + dMassSetBox (&m,1,BOX1_LENGTH,BOX1_WIDTH,BOX1_HEIGHT); + dMassAdjust (&m,Mass1); + dBodySetMass (box1_body[0],&m); + box1[0] = dCreateBox (0,BOX1_LENGTH,BOX1_WIDTH,BOX1_HEIGHT); + dGeomSetBody (box1[0],box1_body[0]); + + box2_body[0] = dBodyCreate (world); + dMassSetBox (&m,10,BOX2_LENGTH,BOX2_WIDTH,BOX2_HEIGHT); + dMassAdjust (&m,Mass2); + dBodySetMass (box2_body[0],&m); + box2[0] = dCreateBox (0,BOX2_LENGTH,BOX2_WIDTH,BOX2_HEIGHT); + dGeomSetBody (box2[0],box2_body[0]); + + //set the initial positions of body1 and body2 + dMatrix3 R; + dRSetIdentity(R); + dBodySetPosition (box1_body[0],0,0,BOX1_HEIGHT/2.0); + dBodySetRotation (box1_body[0], R); + + dBodySetPosition (box2_body[0], + 2.1, + 0.0, + BOX2_HEIGHT/2.0); + dBodySetRotation (box2_body[0], R); + + + //set PR joint + joint[0] = dJointCreatePR(world,0); + dJointAttach (joint[0],box1_body[0],box2_body[0]); + switch (flag) + { + case PRISMATIC_ONLY: + dJointSetPRAnchor (joint[0], + 2.1, + 0.0, + BOX2_HEIGHT/2.0); + dJointSetPRParam (joint[0],dParamLoStop, -0.5); + dJointSetPRParam (joint[0],dParamHiStop, 1.5); + break; + + case ROTOIDE_ONLY: + dJointSetPRAnchor (joint[0], + 0.0, + 0.0, + BOX2_HEIGHT/2.0); + dJointSetPRParam (joint[0],dParamLoStop, 0.0); + dJointSetPRParam (joint[0],dParamHiStop, 0.0); + break; + + default: + dJointSetPRAnchor (joint[0], + 1.1, + 0.0, + BOX2_HEIGHT/2.0); + dJointSetPRParam (joint[0],dParamLoStop, -0.5); + dJointSetPRParam (joint[0],dParamHiStop, 1.5); + break; + } + + dJointSetPRAxis1(joint[0],1,0,0); + dJointSetPRAxis2(joint[0],0,0,1); +// We position the 2 body +// The position of the rotoide joint is on the second body so it can rotate on itself +// and move along the X axis. +// With this anchor +// - A force in X will move only the body 2 inside the low and hi limit +// of the prismatic +// - A force in Y will make the 2 bodies to rotate around on the plane + + box1_space = dSimpleSpaceCreate (space); + dSpaceSetCleanup (box1_space,0); + dSpaceAdd(box1_space,box1[0]); + + // run simulation + dsSimulationLoop (argc,argv,400,300,&fn); + dJointGroupDestroy (contactgroup); + dSpaceDestroy (space); + dWorldDestroy (world); + dCloseODE(); + return 0; +} + diff --git a/libs/ode-0.16.1/ode/demo/demo_jointPU.cpp b/libs/ode-0.16.1/ode/demo/demo_jointPU.cpp new file mode 100644 index 0000000..6ec3093 --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_jointPU.cpp @@ -0,0 +1,735 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + This program demonstrates how the PU joint works. + A PU joint is a combination of a Universal joint and a Slider joint. + It is a universal joint with a slider between the anchor point and + body 1. + + + The upper yellow body is fixed to the world + The lower yellow body is attached to the upper body by a PU joint + The green object is one aprt of the slider. + The purple object is the second part of the slider. + The red object represent the axis1 of the universal part. + The blue object represent the axis2 of the universal part. + The gray object represent the anchor2 of the PU joint. +*/ + + +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include <iostream> +#include <math.h> +#include "texturepath.h" + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif +// select correct drawing functions +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#define dsDrawCylinder dsDrawCylinderD +#define dsDrawCapsule dsDrawCapsuleD +#endif + +enum IDX_CYL_DIM +{ + RADIUS, + LENGTH, + NUM_CYL_DIM +}; + + +const dVector3 boxDim = {1,1,1}; +const dVector3 extDim = {0.2,0.2,1.2}; +const dVector3 ancDim = {0.2,0.2,0.5}; +const dReal axDim[NUM_CYL_DIM] = {0.1,1.0}; + + +int type = dJointTypePU; + + +const dReal VEL_INC = 0.01; // Velocity increment + +// physics parameters +const dReal PI = 3.14159265358979323846264338327950288419716939937510; + + +const dReal INT_EXT_RATIO = 0.8; + +#define X 0 +#define Y 1 +#define Z 2 + +enum INDEX +{ + W = 0, + D, + EXT, + INT, + AXIS1, + AXIS2, + ANCHOR, + GROUND, + NUM_PARTS, + ALL = NUM_PARTS, + // INDEX for catBits + JOINT, + LAST_INDEX_CNT +}; + +const int catBits[LAST_INDEX_CNT] = + { + 0x0001, ///< W Cylinder category + 0x0002, ///< D Cylinder category + 0x0004, ///< EXT sliderr category + 0x0008, ///< INT slider category + 0x0010, ///< AXIS1 universal category + 0x0020, ///< AXIS2 universal category + 0x0040, ///< ANCHOR category + 0x0080, ///< Ground category + ~0L, ///< All categories + 0x0004 | 0x0008 | 0x0010 | 0x0020 ///< JOINT category + }; + +#define Mass1 10 +#define Mass2 8 + + +//camera view +static float xyz[3] = {6.0f,0.0f,6.0000f}; +static float hpr[3] = {-180.000f,-25.5000f,0.0000f}; + + +//world,space,body & geom +static dWorldID world; +static dSpaceID space; +static dJointGroupID contactgroup; +static dBodyID body[NUM_PARTS]; +static dGeomID geom[NUM_PARTS]; + +static dJoint *joint; + + + +const dReal BOX_SIDES[3] = {1.0,1.0,1.0}; +const dReal OBS_SIDES[3] = {0.4,0.4,0.4}; +const dReal RECT_SIDES[3] = {0.3, 0.1, 0.2}; + + +//collision detection +static void nearCallback (void *, dGeomID o1, dGeomID o2) +{ + int i,n; + + const int N = 10; + dContact contact[N]; + n = dCollide (o1,o2,N,&contact[0].geom,sizeof (dContact) ); + if (n > 0) { + for (i=0; i<n; i++) { + contact[i].surface.mode = (dContactSlip1 | dContactSlip2 | + dContactSoftERP | dContactSoftCFM | + dContactApprox1); + contact[i].surface.mu = 0.1; + contact[i].surface.slip1 = 0.02; + contact[i].surface.slip2 = 0.02; + contact[i].surface.soft_erp = 0.1; + contact[i].surface.soft_cfm = 0.0001; + dJointID c = dJointCreateContact (world,contactgroup,&contact[i]); + dJointAttach (c,dGeomGetBody (contact[i].geom.g1),dGeomGetBody (contact[i].geom.g2) ); + } + } +} + +static void printKeyBoardShortCut() +{ + printf ("Press 'h' for this help.\n"); + printf ("Press 'q' to add force on BLUE body along positive x direction.\n"); + printf ("Press 'w' to add force on BLUE body along negative x direction.\n"); + + printf ("Press 'a' to add force on BLUE body along positive y direction.\n"); + printf ("Press 's' to add force on BLUE body along negative y direction.\n"); + + printf ("Press 'z' to add force on BLUE body along positive z direction.\n"); + printf ("Press 'x' to add force on BLUE body along negative z direction.\n"); + + printf ("Press 'e' to add torque on BLUE body around positive x direction \n"); + printf ("Press 'r' to add torque on BLUE body around negative x direction \n"); + + printf ("Press 'd' to add torque on BLUE body around positive y direction \n"); + printf ("Press 'f' to add torque on BLUE body around negative y direction \n"); + + printf ("Press 'c' to add torque on BLUE body around positive z direction \n"); + printf ("Press 'v' to add torque on BLUE body around negative z direction \n"); + + printf ("Press '.' to increase joint velocity along the prismatic direction.\n"); + printf ("Press ',' to decrease joint velocity along the prismatic direction.\n"); + + printf ("Press 'l' Toggle ON/OFF the limits on all the axis\n"); + printf ("Press 'g' Toggle ON/OFF the gravity\n"); + + + printf ("Press 'p' to print the position, angle and rates of the joint.\n"); +} + + +// start simulation - set viewpoint +static void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + dsSetViewpoint (xyz,hpr); + printf ("This program demonstrates how the PU joint works.\n"); + printf ("A PU joint is a combination of a Universal joint and a Slider joint.\n"); + printf ("It is a universal joint with a slider between the anchor point and \n"); + printf ("body 1.\n\n"); + printf ("The upper yellow body is fixed to the world\n"); + printf ("The lower yellow body is attached to the upper body by a PU joint\n"); + printf ("The green object is one aprt of the slider.\n"); + printf ("The purple object is the second part of the slider.\n"); + printf ("The red object represent the axis1 of the universal part. \n"); + printf ("The blue object represent the axis2 of the universal part. \n"); + printf ("The gray object represent the anchor2 of the PU joint. \n"); + printKeyBoardShortCut(); +} + +// function to update camera position at each step. +void update() +{ +// static FILE *file = fopen("x:/sim/src/libode/tstsrcSF/export.dat", "w"); + +// static int cnt = 0; +// char str[24]; +// sprintf(str, "%06d",cnt++); + +// dWorldExportDIF(world, file, str); +} + + +// called when a key pressed +static void command (int cmd) +{ + switch (cmd) { +case 'h' : case 'H' : case '?' : + printKeyBoardShortCut(); + break; + + // Force + case 'q' : case 'Q' : + dBodyAddForce(body[D],40,0,0); + break; + case 'w' : case 'W' : + dBodyAddForce(body[D],-40,0,0); + break; + + case 'a' : case 'A' : + dBodyAddForce(body[D],0,40,0); + break; + case 's' : case 'S' : + dBodyAddForce(body[D],0,-40,0); + break; + + case 'z' : case 'Z' : + dBodyAddForce(body[D],0,0,40); + break; + case 'x' : case 'X' : + dBodyAddForce(body[D],0,0,-40); + break; + + // Torque + case 'e': case 'E': + dBodyAddTorque(body[D],0.1,0,0); + break; + case 'r': case 'R': + dBodyAddTorque(body[D],-0.1,0,0); + break; + + case 'd': case 'D': + dBodyAddTorque(body[D],0, 0.1,0); + break; + case 'f': case 'F': + dBodyAddTorque(body[D],0,-0.1,0); + break; + + case 'c': case 'C': + dBodyAddTorque(body[D],0,0,0.1); + break; + case 'v': case 'V': + dBodyAddTorque(body[D],0,0,0.1); + break; + + // Velocity of joint + case ',': case '<' : { + dReal vel = joint->getParam (dParamVel3) - VEL_INC; + joint->setParam (dParamVel3, vel); + joint->setParam (dParamFMax3, 2); + std::cout<<"Velocity = "<<vel<<" FMax = 2"<<'\n'; + } + break; + + case '.': case '>' : { + dReal vel = joint->getParam (dParamVel3) + VEL_INC; + joint->setParam (dParamVel3, vel); + joint->setParam (dParamFMax3, 2); + std::cout<<"Velocity = "<<vel<<" FMax = 2"<<'\n'; + } + break; + + case 'l': case 'L' : { + dReal aLimit, lLimit, fmax; + if ( joint->getParam (dParamFMax) ) { + aLimit = dInfinity; + lLimit = dInfinity; + fmax = 0; + } + else { + aLimit = 0.25*PI; + lLimit = 0.5*axDim[LENGTH]; + fmax = 0.02; + } + + joint->setParam (dParamFMax1, fmax); + joint->setParam (dParamFMax2, fmax); + joint->setParam (dParamFMax3, fmax); + + switch (joint->getType() ) { + case dJointTypePR : { + dPRJoint *pr = reinterpret_cast<dPRJoint *> (joint); + pr->setParam (dParamLoStop, -lLimit); + pr->setParam (dParamHiStop, -lLimit); + pr->setParam (dParamLoStop2, aLimit); + pr->setParam (dParamHiStop2, -aLimit); + } + break; + case dJointTypePU : { + dPUJoint *pu = reinterpret_cast<dPUJoint *> (joint); + pu->setParam (dParamLoStop1, -aLimit); + pu->setParam (dParamHiStop1, aLimit); + pu->setParam (dParamLoStop2, -aLimit); + pu->setParam (dParamHiStop2, aLimit); + pu->setParam (dParamLoStop3, -lLimit); + pu->setParam (dParamHiStop3, lLimit); + } + break; + default: {} // keep the compiler happy + } + } + + break; + + case 'g': case 'G' : { + dVector3 g; + dWorldGetGravity(world, g); + if ( g[2]< -0.1 ) + dWorldSetGravity(world, 0, 0, 0); + else + dWorldSetGravity(world, 0, 0, -0.5); + + } + +case 'p' :case 'P' : { + switch (joint->getType() ) { + case dJointTypeSlider : { + dSliderJoint *sj = reinterpret_cast<dSliderJoint *> (joint); + std::cout<<"Position ="<<sj->getPosition() <<"\n"; + } + break; + case dJointTypePU : { + dPUJoint *pu = reinterpret_cast<dPUJoint *> (joint); + std::cout<<"Position ="<<pu->getPosition() <<"\n"; + std::cout<<"Position Rate="<<pu->getPositionRate() <<"\n"; + std::cout<<"Angle1 ="<<pu->getAngle1() <<"\n"; + std::cout<<"Angle1 Rate="<<pu->getAngle1Rate() <<"\n"; + std::cout<<"Angle2 ="<<pu->getAngle2() <<"\n"; + std::cout<<"Angle2 Rate="<<pu->getAngle2Rate() <<"\n"; + } + break; + default: {} // keep the compiler happy + } + } + break; + } +} + +static void drawBox (dGeomID id, int R, int G, int B) +{ + if (!id) + return; + + const dReal *pos = dGeomGetPosition (id); + const dReal *rot = dGeomGetRotation (id); + dsSetColor (R,G,B); + + dVector3 l; + dGeomBoxGetLengths (id, l); + dsDrawBox (pos, rot, l); +} + + +// simulation loop +static void simLoop (int pause) +{ + static bool todo = false; + if ( todo ) { // DEBUG + static int cnt = 0; + ++cnt; + + if (cnt == 5) + command ( 'q' ); + if (cnt == 10) + dsStop(); + } + + + + + if (!pause) { + double simstep = 0.01; // 10ms simulation steps + double dt = dsElapsedTime(); + + int nrofsteps = (int) ceilf (dt/simstep); + if (!nrofsteps) + nrofsteps = 1; + + for (int i=0; i<nrofsteps && !pause; i++) { + dSpaceCollide (space,0,&nearCallback); + dWorldStep (world, simstep); + + dJointGroupEmpty (contactgroup); + } + + update(); + + + dReal radius, length; + + dsSetTexture (DS_WOOD); + + drawBox (geom[W], 1,1,0); + + + drawBox (geom[EXT], 0,1,0); + + dVector3 anchorPos; + + + + dReal ang1 = 0; + dReal ang2 = 0; + dVector3 axisP, axisR1, axisR2; + + if ( dJointTypePU == type ) { + dPUJoint *pu = dynamic_cast<dPUJoint *> (joint); + ang1 = pu->getAngle1(); + ang2 = pu->getAngle2(); + pu->getAxis1 (axisR1); + pu->getAxis2 (axisR2); + pu->getAxisP (axisP); + + dJointGetPUAnchor (pu->id(), anchorPos); + } + else if ( dJointTypePR == type ) { + dPRJoint *pr = dynamic_cast<dPRJoint *> (joint); + pr->getAxis1 (axisP); + pr->getAxis2 (axisR1); + + dJointGetPRAnchor (pr->id(), anchorPos); + } + + + // Draw the axisR + if ( geom[INT] ) { + dsSetColor (1,0,1); + dVector3 l; + dGeomBoxGetLengths (geom[INT], l); + + const dReal *rotBox = dGeomGetRotation (geom[W]); + + dVector3 pos; + for (int i=0; i<3; ++i) + pos[i] = anchorPos[i] - 0.5*extDim[Z]*axisP[i]; + dsDrawBox (pos, rotBox, l); + } + + dsSetTexture (DS_CHECKERED); + if ( geom[AXIS1] ) { + dQuaternion q, qAng; + dQFromAxisAndAngle (qAng,axisR1[X], axisR1[Y], axisR1[Z], ang1); + dGeomGetQuaternion (geom[AXIS1], q); + + dQuaternion qq; + dQMultiply1 (qq, qAng, q); + dMatrix3 R; + dQtoR (qq,R); + + + dGeomCylinderGetParams (geom[AXIS1], &radius, &length); + dsSetColor (1,0,0); + dsDrawCylinder (anchorPos, R, length, radius); + } + + if ( dJointTypePU == type && geom[AXIS2] ) { + //dPUJoint *pu = dynamic_cast<dPUJoint *> (joint); + + dQuaternion q, qAng, qq, qq1; + dGeomGetQuaternion (geom[AXIS2], q); + + dQFromAxisAndAngle (qAng, 0, 1, 0, ang2); + dQMultiply1 (qq, qAng, q); + + + dQFromAxisAndAngle (qAng,axisR1[X], axisR1[Y], axisR1[Z], ang1); + + dQMultiply1 (qq1, qAng, qq); + + + dMatrix3 R; + dQtoR (qq1,R); + + + dGeomCylinderGetParams (geom[AXIS2], &radius, &length); + dsSetColor (0,0,1); + dsDrawCylinder (anchorPos, R, length, radius); + } + + dsSetTexture (DS_WOOD); + + // Draw the anchor + if ( geom[ANCHOR] ) { + dsSetColor (1,1,1); + dVector3 l; + dGeomBoxGetLengths (geom[ANCHOR], l); + + const dReal *rotBox = dGeomGetRotation (geom[D]); + const dReal *posBox = dGeomGetPosition (geom[D]); + + dVector3 e; + for (int i=0; i<3; ++i) + e[i] = posBox[i] - anchorPos[i]; + dNormalize3 (e); + + dVector3 pos; + for (int i=0; i<3; ++i) + pos[i] = anchorPos[i] + 0.5 * l[Z]*e[i]; + dsDrawBox (pos, rotBox, l); + } + + drawBox (geom[D], 1,1,0); + } +} + + +void Help (char **argv) +{ + printf ("%s ", argv[0]); + printf (" -h | --help : print this help\n"); + printf (" -p | --PRJoint : Use a PR joint instead of PU joint\n"); + printf (" -t | --texture-path path : Path to the texture.\n"); + printf (" Default = %s\n", DRAWSTUFF_TEXTURE_PATH); + printf ("--------------------------------------------------\n"); + printf ("Hit any key to continue:"); + getchar(); + + exit (0); +} + +int main (int argc, char **argv) +{ + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + if (argc >= 2 ) { + for (int i=1; i < argc; ++i) { + if ( 0 == strcmp ("-h", argv[i]) || 0 == strcmp ("--help", argv[i]) ) + Help (argv); + + if ( 0 == strcmp ("-p", argv[i]) || 0 == strcmp ("--PRJoint", argv[i]) ) + type = dJointTypePR; + + if (0 == strcmp ("-t", argv[i]) || 0 == strcmp ("--texture-path", argv[i]) ) { + int j = i+1; + if ( j >= argc || // Check if we have enough arguments + argv[j][0] == '\0' || // We should have a path here + argv[j][0] == '-' ) // We should have a path not a command line + Help (argv); + else + fn.path_to_textures = argv[++i]; // Increase i since we use this argument + } + } + } + + dInitODE2(0); + + world = dWorldCreate(); + dWorldSetERP (world, 0.8); + + space = dSimpleSpaceCreate (0); + contactgroup = dJointGroupCreate (0); + geom[GROUND] = dCreatePlane (space, 0,0,1,0); + dGeomSetCategoryBits (geom[GROUND], catBits[GROUND]); + dGeomSetCollideBits (geom[GROUND], catBits[ALL]); + + dMass m; + + // Create the body attached to the World + body[W] = dBodyCreate (world); + // Main axis of cylinder is along X=1 + m.setBox (1, boxDim[X], boxDim[Y], boxDim[Z]); + m.adjust (Mass1); + geom[W] = dCreateBox (space, boxDim[X], boxDim[Y], boxDim[Z]); + dGeomSetBody (geom[W], body[W]); + dGeomSetCategoryBits (geom[W], catBits[W]); + dGeomSetCollideBits (geom[W], catBits[ALL] & (~catBits[W]) & (~catBits[JOINT]) ); + dBodySetMass (body[W], &m); + + + + + + // Create the dandling body + body[D] = dBodyCreate (world); + // Main axis of capsule is along X=1 + m.setBox (1, boxDim[X], boxDim[Y], boxDim[Z]); + m.adjust (Mass1); + geom[D] = dCreateBox (space, boxDim[X], boxDim[Y], boxDim[Z]); + dGeomSetBody (geom[D], body[D]); + dGeomSetCategoryBits (geom[D], catBits[D]); + dGeomSetCollideBits (geom[D], catBits[ALL] & (~catBits[D]) & (~catBits[JOINT]) ); + dBodySetMass (body[D], &m); + + + // Create the external part of the slider joint + geom[EXT] = dCreateBox (0, extDim[X], extDim[Y], extDim[Z]); + dGeomSetCategoryBits (geom[EXT], catBits[EXT]); + dGeomSetCollideBits (geom[EXT], + catBits[ALL] & (~catBits[JOINT]) & (~catBits[W]) & (~catBits[D]) ); + + // Create the internal part of the slider joint + geom[INT] = dCreateBox (0, INT_EXT_RATIO*extDim[X], + INT_EXT_RATIO*extDim[Y], + INT_EXT_RATIO*extDim[Z]); + dGeomSetCategoryBits (geom[INT], catBits[INT]); + dGeomSetCollideBits (geom[INT], + catBits[ALL] & (~catBits[JOINT]) & (~catBits[W]) & (~catBits[D]) ); + + + dMatrix3 R; + // Create the first axis of the universal joi9nt + //Rotation of 90deg around y + geom[AXIS1] = dCreateCylinder(0, axDim[RADIUS], axDim[LENGTH]); + dRFromAxisAndAngle(R, 0,1,0, 0.5*PI); + dGeomSetRotation(geom[AXIS1], R); + dGeomSetCategoryBits(geom[AXIS1], catBits[AXIS1]); + dGeomSetCollideBits(geom[AXIS1], + catBits[ALL] & ~catBits[JOINT] & ~catBits[W] & ~catBits[D]); + + + // Create the second axis of the universal joint + geom[AXIS2] = dCreateCylinder(0, axDim[RADIUS], axDim[LENGTH]); + //Rotation of 90deg around y + dRFromAxisAndAngle(R, 1,0,0, 0.5*PI); + dGeomSetRotation(geom[AXIS2], R); + dGeomSetCategoryBits(geom[AXIS2], catBits[AXIS2]); + dGeomSetCollideBits(geom[AXIS2], + catBits[ALL] & ~catBits[JOINT] & ~catBits[W] & ~catBits[D]); + + // Create the anchor + geom[ANCHOR] = dCreateBox (0, ancDim[X], ancDim[Y], ancDim[Z]); + dGeomSetCategoryBits(geom[ANCHOR], catBits[ANCHOR]); + dGeomSetCollideBits(geom[ANCHOR], + catBits[ALL] & (~catBits[JOINT]) & (~catBits[W]) & (~catBits[D]) ); + + + + if (body[W]) { + dBodySetPosition(body[W], 0, 0, 5); + } + + + if (geom[EXT]) { + dGeomSetPosition(geom[EXT], 0,0,3.8); + } + if (geom[INT]) { + dGeomSetPosition(geom[INT], 0,0,2.6); + } + if (geom[AXIS1]) { + dGeomSetPosition(geom[AXIS1], 0,0,2.5); + } + if (geom[AXIS2]) { + dGeomSetPosition(geom[AXIS2], 0,0,2.5); + } + + if (geom[ANCHOR]) { + dGeomSetPosition(geom[ANCHOR], 0,0,2.25); + } + + if (body[D]) { + dBodySetPosition(body[D], 0,0,1.5); + } + + + + // Attache the upper box to the world + dJointID fixed = dJointCreateFixed (world,0); + dJointAttach (fixed , NULL, body[W]); + dJointSetFixed (fixed ); + + if (type == dJointTypePR) { + dPRJoint *pr = new dPRJoint (world, 0); + pr->attach (body[W], body[D]); + pr->setAxis1 (0, 0, -1); + pr->setAxis2 (1, 0, 0); + joint = pr; + + dJointSetPRAnchor (pr->id(), 0, 0, 2.5); + } + else { + dPUJoint *pu = new dPUJoint (world, 0); + pu->attach (body[W], body[D]); + pu->setAxis1 (1, 0, 0); + pu->setAxis2 (0, 1, 0); + pu->setAxisP (0, 0, -1); + joint = pu; + + dJointSetPUAnchor (pu->id(), 0, 0, 2.5); + } + + + // run simulation + dsSimulationLoop (argc,argv,400,300,&fn); + + delete joint; + dJointGroupDestroy (contactgroup); + dSpaceDestroy (space); + dWorldDestroy (world); + dCloseODE(); + return 0; +} + diff --git a/libs/ode-0.16.1/ode/demo/demo_joints.cpp b/libs/ode-0.16.1/ode/demo/demo_joints.cpp new file mode 100644 index 0000000..d545369 --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_joints.cpp @@ -0,0 +1,1090 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +perform tests on all the joint types. +this should be done using the double precision version of the library. + +usage: + test_joints [-nXXX] [-g] [-i] [-e] [path_to_textures] + +if a test number is given then that specific test is performed, otherwise +all the tests are performed. the tests are numbered `xxyy', where xx +corresponds to the joint type and yy is the sub-test number. not every +number maps to an actual test. + +flags: + i: the test is interactive. + g: turn off graphical display (can't use this with `i'). + e: turn on occasional error perturbations + n: performe test XXX +some tests compute and display error values. these values are scaled so +<1 is good and >1 is bad. other tests just show graphical results which +you must verify visually. + +*/ + +#include <ctype.h> +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + +// select correct drawing functions +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#endif + + +// some constants +#define NUM_JOINTS 10 // number of joints to test (the `xx' value) +#define SIDE (0.5f) // side length of a box - don't change this +#define MASS (1.0) // mass of a box +#define STEPSIZE 0.05 + +static const dVector3 xunit = { 1, 0, 0 }, zunit = { 0, 0, 1 }; + + +// dynamics objects +static dWorldID world; +static dBodyID body[2]; +static dJointID joint; + + +// data from the command line arguments +static int cmd_test_num = -1; +static int cmd_interactive = 0; +static int cmd_graphics = 1; +static char *cmd_path_to_textures = NULL; +static int cmd_occasional_error = 0; // perturb occasionally + + +// info about the current test +struct TestInfo; +static int test_num = 0; // number of the current test +static int iteration = 0; +static int max_iterations = 0; +static dReal max_error = 0; + +//**************************************************************************** +// utility stuff + +static dReal length (dVector3 a) +{ + return dSqrt (a[0]*a[0] + a[1]*a[1] + a[2]*a[2]); +} + + +// get the max difference between a 3x3 matrix and the identity + +dReal cmpIdentity (const dMatrix3 A) +{ + dMatrix3 I; + dSetZero (I,12); + I[0] = 1; + I[5] = 1; + I[10] = 1; + return dMaxDifference (A,I,3,3); +} + +//**************************************************************************** +// test world construction and utilities + +void constructWorldForTest (dReal gravity, int bodycount, + /* body 1 pos */ dReal pos1x, dReal pos1y, dReal pos1z, + /* body 2 pos */ dReal pos2x, dReal pos2y, dReal pos2z, + /* body 1 rotation axis */ dReal ax1x, dReal ax1y, dReal ax1z, + /* body 1 rotation axis */ dReal ax2x, dReal ax2y, dReal ax2z, + /* rotation angles */ dReal a1, dReal a2) +{ + // create world + world = dWorldCreate(); + dWorldSetERP (world,0.2); + dWorldSetCFM (world,1e-6); + dWorldSetGravity (world,0,0,gravity); + + dMass m; + dMassSetBox (&m,1,SIDE,SIDE,SIDE); + dMassAdjust (&m,MASS); + + body[0] = dBodyCreate (world); + dBodySetMass (body[0],&m); + dBodySetPosition (body[0], pos1x, pos1y, pos1z); + dQuaternion q; + dQFromAxisAndAngle (q,ax1x,ax1y,ax1z,a1); + dBodySetQuaternion (body[0],q); + + if (bodycount==2) { + body[1] = dBodyCreate (world); + dBodySetMass (body[1],&m); + dBodySetPosition (body[1], pos2x, pos2y, pos2z); + dQFromAxisAndAngle (q,ax2x,ax2y,ax2z,a2); + dBodySetQuaternion (body[1],q); + } + else body[1] = 0; +} + + +// add an oscillating torque to body 0 + +void addOscillatingTorque (dReal tscale) +{ + static dReal a=0; + dBodyAddTorque (body[0],tscale*cos(2*a),tscale*cos(2.7183*a), + tscale*cos(1.5708*a)); + a += 0.01; +} + + +void addOscillatingTorqueAbout(dReal tscale, dReal x, dReal y, dReal z) +{ + static dReal a=0; + dBodyAddTorque (body[0], tscale*cos(a) * x, tscale*cos(a) * y, + tscale * cos(a) * z); + a += 0.02; +} + + +// damp the rotational motion of body 0 a bit + +void dampRotationalMotion (dReal kd) +{ + const dReal *w = dBodyGetAngularVel (body[0]); + dBodyAddTorque (body[0],-kd*w[0],-kd*w[1],-kd*w[2]); +} + + +// add a spring force to keep the bodies together, otherwise they may fly +// apart with some joints. + +void addSpringForce (dReal ks) +{ + const dReal *p1 = dBodyGetPosition (body[0]); + const dReal *p2 = dBodyGetPosition (body[1]); + dBodyAddForce (body[0],ks*(p2[0]-p1[0]),ks*(p2[1]-p1[1]),ks*(p2[2]-p1[2])); + dBodyAddForce (body[1],ks*(p1[0]-p2[0]),ks*(p1[1]-p2[1]),ks*(p1[2]-p2[2])); +} + + +// add an oscillating Force to body 0 + +void addOscillatingForce (dReal fscale) +{ + static dReal a=0; + dBodyAddForce (body[0],fscale*cos(2*a),fscale*cos(2.7183*a), + fscale*cos(1.5708*a)); + a += 0.01; +} + +//**************************************************************************** +// stuff specific to the tests +// +// 0xx : fixed +// 1xx : ball and socket +// 2xx : hinge +// 3xx : slider +// 4xx : hinge 2 +// 5xx : contact +// 6xx : amotor +// 7xx : universal joint +// 8xx : PR joint (Prismatic and Rotoide) + +// setup for the given test. return 0 if there is no such test + +int setupTest (int n) +{ + switch (n) { + + // ********** fixed joint + + case 0: { // 2 body + constructWorldForTest (0,2, + 0.5*SIDE,0.5*SIDE,1, -0.5*SIDE,-0.5*SIDE,1, + 1,1,0, 1,1,0, + 0.25*M_PI,0.25*M_PI); + joint = dJointCreateFixed (world,0); + dJointAttach (joint,body[0],body[1]); + dJointSetFixed (joint); + return 1; + } + + case 1: { // 1 body to static env + constructWorldForTest (0,1, + 0.5*SIDE,0.5*SIDE,1, 0,0,0, + 1,0,0, 1,0,0, + 0,0); + joint = dJointCreateFixed (world,0); + dJointAttach (joint,body[0],0); + dJointSetFixed (joint); + return 1; + } + + case 2: { // 2 body with relative rotation + constructWorldForTest (0,2, + 0.5*SIDE,0.5*SIDE,1, -0.5*SIDE,-0.5*SIDE,1, + 1,1,0, 1,1,0, + 0.25*M_PI,-0.25*M_PI); + joint = dJointCreateFixed (world,0); + dJointAttach (joint,body[0],body[1]); + dJointSetFixed (joint); + return 1; + } + + case 3: { // 1 body to static env with relative rotation + constructWorldForTest (0,1, + 0.5*SIDE,0.5*SIDE,1, 0,0,0, + 1,0,0, 1,0,0, + 0.25*M_PI,0); + joint = dJointCreateFixed (world,0); + dJointAttach (joint,body[0],0); + dJointSetFixed (joint); + return 1; + } + + // ********** hinge joint + + case 200: // 2 body + constructWorldForTest (0,2, + 0.5*SIDE,0.5*SIDE,1, -0.5*SIDE,-0.5*SIDE,1, + 1,1,0, 1,1,0, 0.25*M_PI,0.25*M_PI); + joint = dJointCreateHinge (world,0); + dJointAttach (joint,body[0],body[1]); + dJointSetHingeAnchor (joint,0,0,1); + dJointSetHingeAxis (joint,1,-1,1.41421356); + return 1; + + case 220: // hinge angle polarity test + case 221: // hinge angle rate test + constructWorldForTest (0,2, + 0.5*SIDE,0.5*SIDE,1, -0.5*SIDE,-0.5*SIDE,1, + 1,0,0, 1,0,0, 0,0); + joint = dJointCreateHinge (world,0); + dJointAttach (joint,body[0],body[1]); + dJointSetHingeAnchor (joint,0,0,1); + dJointSetHingeAxis (joint,0,0,1); + max_iterations = 50; + return 1; + + case 230: // hinge motor rate (and polarity) test + case 231: // ...with stops + constructWorldForTest (0,2, + 0.5*SIDE,0.5*SIDE,1, -0.5*SIDE,-0.5*SIDE,1, + 1,0,0, 1,0,0, 0,0); + joint = dJointCreateHinge (world,0); + dJointAttach (joint,body[0],body[1]); + dJointSetHingeAnchor (joint,0,0,1); + dJointSetHingeAxis (joint,0,0,1); + dJointSetHingeParam (joint,dParamFMax,1); + if (n==231) { + dJointSetHingeParam (joint,dParamLoStop,-0.5); + dJointSetHingeParam (joint,dParamHiStop,0.5); + } + return 1; + + case 250: // limit bounce test (gravity down) + case 251: { // ...gravity up + constructWorldForTest ((n==251) ? 0.1 : -0.1, 2, + 0.5*SIDE,0,1+0.5*SIDE, -0.5*SIDE,0,1-0.5*SIDE, + 1,0,0, 1,0,0, 0,0); + joint = dJointCreateHinge (world,0); + dJointAttach (joint,body[0],body[1]); + dJointSetHingeAnchor (joint,0,0,1); + dJointSetHingeAxis (joint,0,1,0); + dJointSetHingeParam (joint,dParamLoStop,-0.9); + dJointSetHingeParam (joint,dParamHiStop,0.7854); + dJointSetHingeParam (joint,dParamBounce,0.5); + // anchor 2nd body with a fixed joint + dJointID j = dJointCreateFixed (world,0); + dJointAttach (j,body[1],0); + dJointSetFixed (j); + return 1; + } + + // ********** slider + + case 300: // 2 body + constructWorldForTest (0,2, + 0,0,1, 0.2,0.2,1.2, + 0,0,1, -1,1,0, 0,0.25*M_PI); + joint = dJointCreateSlider (world,0); + dJointAttach (joint,body[0],body[1]); + dJointSetSliderAxis (joint,1,1,1); + return 1; + + case 320: // slider angle polarity test + case 321: // slider angle rate test + constructWorldForTest (0,2, + 0,0,1, 0,0,1.2, + 1,0,0, 1,0,0, 0,0); + joint = dJointCreateSlider (world,0); + dJointAttach (joint,body[0],body[1]); + dJointSetSliderAxis (joint,0,0,1); + max_iterations = 50; + return 1; + + case 330: // slider motor rate (and polarity) test + case 331: // ...with stops + constructWorldForTest (0, 2, + 0,0,1, 0,0,1.2, + 1,0,0, 1,0,0, 0,0); + joint = dJointCreateSlider (world,0); + dJointAttach (joint,body[0],body[1]); + dJointSetSliderAxis (joint,0,0,1); + dJointSetSliderParam (joint,dParamFMax,100); + if (n==331) { + dJointSetSliderParam (joint,dParamLoStop,-0.4); + dJointSetSliderParam (joint,dParamHiStop,0.4); + } + return 1; + + case 350: // limit bounce tests + case 351: { + constructWorldForTest ((n==351) ? 0.1 : -0.1, 2, + 0,0,1, 0,0,1.2, + 1,0,0, 1,0,0, 0,0); + joint = dJointCreateSlider (world,0); + dJointAttach (joint,body[0],body[1]); + dJointSetSliderAxis (joint,0,0,1); + dJointSetSliderParam (joint,dParamLoStop,-0.5); + dJointSetSliderParam (joint,dParamHiStop,0.5); + dJointSetSliderParam (joint,dParamBounce,0.5); + // anchor 2nd body with a fixed joint + dJointID j = dJointCreateFixed (world,0); + dJointAttach (j,body[1],0); + dJointSetFixed (j); + return 1; + } + + // ********** hinge-2 joint + + case 420: // hinge-2 steering angle polarity test + case 421: // hinge-2 steering angle rate test + constructWorldForTest (0,2, + 0.5*SIDE,0,1, -0.5*SIDE,0,1, + 1,0,0, 1,0,0, 0,0); + joint = dJointCreateHinge2 (world,0); + dJointAttach (joint,body[0],body[1]); + dJointSetHinge2Anchor (joint,-0.5*SIDE,0,1); + dJointSetHinge2Axes (joint, zunit, xunit); + max_iterations = 50; + return 1; + + case 430: // hinge 2 steering motor rate (+polarity) test + case 431: // ...with stops + case 432: // hinge 2 wheel motor rate (+polarity) test + constructWorldForTest (0,2, + 0.5*SIDE,0,1, -0.5*SIDE,0,1, + 1,0,0, 1,0,0, 0,0); + joint = dJointCreateHinge2 (world,0); + dJointAttach (joint,body[0],body[1]); + dJointSetHinge2Anchor (joint,-0.5*SIDE,0,1); + dJointSetHinge2Axes (joint, zunit, xunit); + dJointSetHinge2Param (joint,dParamFMax,1); + dJointSetHinge2Param (joint,dParamFMax2,1); + if (n==431) { + dJointSetHinge2Param (joint,dParamLoStop,-0.5); + dJointSetHinge2Param (joint,dParamHiStop,0.5); + } + return 1; + + // ********** angular motor joint + + case 600: // test euler angle calculations + constructWorldForTest (0,2, + -SIDE*0.5,0,1, SIDE*0.5,0,1, + 0,0,1, 0,0,1, 0,0); + joint = dJointCreateAMotor (world,0); + dJointAttach (joint,body[0],body[1]); + + dJointSetAMotorNumAxes (joint,3); + dJointSetAMotorAxis (joint,0,1, 0,0,1); + dJointSetAMotorAxis (joint,2,2, 1,0,0); + dJointSetAMotorMode (joint,dAMotorEuler); + max_iterations = 200; + return 1; + + // ********** universal joint + + case 700: // 2 body + case 701: + case 702: + constructWorldForTest (0,2, + 0.5*SIDE,0.5*SIDE,1, -0.5*SIDE,-0.5*SIDE,1, + 1,1,0, 1,1,0, 0.25*M_PI,0.25*M_PI); + joint = dJointCreateUniversal (world,0); + dJointAttach (joint,body[0],body[1]); + dJointSetUniversalAnchor (joint,0,0,1); + dJointSetUniversalAxis1 (joint, 1, -1, 1.41421356); + dJointSetUniversalAxis2 (joint, 1, -1, -1.41421356); + return 1; + + case 720: // universal transmit torque test + case 721: + case 722: + case 730: // universal torque about axis 1 + case 731: + case 732: + case 740: // universal torque about axis 2 + case 741: + case 742: + constructWorldForTest (0,2, + 0.5*SIDE,0.5*SIDE,1, -0.5*SIDE,-0.5*SIDE,1, + 1,0,0, 1,0,0, 0,0); + joint = dJointCreateUniversal (world,0); + dJointAttach (joint,body[0],body[1]); + dJointSetUniversalAnchor (joint,0,0,1); + dJointSetUniversalAxis1 (joint,0,0,1); + dJointSetUniversalAxis2 (joint, 1, -1,0); + max_iterations = 100; + return 1; + + // Joint PR (Prismatic and Rotoide) + case 800: // 2 body + case 801: // 2 bodies with spring force and prismatic fixed + case 802: // 2 bodies with torque on body1 and prismatic fixed + constructWorldForTest (0, 2, + -1.0, 0.0, 1.0, + 1.0, 0.0, 1.0, + 1,0,0, 1,0,0, + 0, 0); + joint = dJointCreatePR (world, 0); + dJointAttach (joint, body[0], body[1]); + dJointSetPRAnchor (joint,-0.5, 0.0, 1.0); + dJointSetPRAxis1 (joint, 0, 1, 0); + dJointSetPRAxis2 (joint, 1, 0, 0); + dJointSetPRParam (joint,dParamLoStop,-0.5); + dJointSetPRParam (joint,dParamHiStop,0.5); + dJointSetPRParam (joint,dParamLoStop2,0); + dJointSetPRParam (joint,dParamHiStop2,0); + return 1; + case 803: // 2 bodies with spring force and prismatic NOT fixed + case 804: // 2 bodies with torque force and prismatic NOT fixed + case 805: // 2 bodies with force only on first body + constructWorldForTest (0, 2, + -1.0, 0.0, 1.0, + 1.0, 0.0, 1.0, + 1,0,0, 1,0,0, + 0, 0); + joint = dJointCreatePR (world, 0); + dJointAttach (joint, body[0], body[1]); + dJointSetPRAnchor (joint,-0.5, 0.0, 1.0); + dJointSetPRAxis1 (joint, 0, 1, 0); + dJointSetPRAxis2 (joint, 1, 0, 0); + dJointSetPRParam (joint,dParamLoStop,-0.5); + dJointSetPRParam (joint,dParamHiStop,0.5); + dJointSetPRParam (joint,dParamLoStop2,-0.5); + dJointSetPRParam (joint,dParamHiStop2,0.5); + return 1; + } + return 0; +} + + +// do stuff specific to this test each iteration. you can check some +// invariants for the test -- the return value is some scaled error measurement +// that must be less than 1. +// return a dInfinity if error is not measured for this n. + +dReal doStuffAndGetError (int n) +{ + switch (n) { + + // ********** fixed joint + + case 0: { // 2 body + addOscillatingTorque (0.1); + dampRotationalMotion (0.1); + // check the orientations are the same + const dReal *R1 = dBodyGetRotation (body[0]); + const dReal *R2 = dBodyGetRotation (body[1]); + dReal err1 = dMaxDifference (R1,R2,3,3); + // check the body offset is correct + dVector3 p,pp; + const dReal *p1 = dBodyGetPosition (body[0]); + const dReal *p2 = dBodyGetPosition (body[1]); + for (int i=0; i<3; i++) p[i] = p2[i] - p1[i]; + dMultiply1_331 (pp,R1,p); + pp[0] += 0.5; + pp[1] += 0.5; + return (err1 + length (pp)) * 300; + } + + case 1: { // 1 body to static env + addOscillatingTorque (0.1); + + // check the orientation is the identity + dReal err1 = cmpIdentity (dBodyGetRotation (body[0])); + + // check the body offset is correct + dVector3 p; + const dReal *p1 = dBodyGetPosition (body[0]); + for (int i=0; i<3; i++) p[i] = p1[i]; + p[0] -= 0.25; + p[1] -= 0.25; + p[2] -= 1; + return (err1 + length (p)) * 1e6; + } + + case 2: { // 2 body + addOscillatingTorque (0.1); + dampRotationalMotion (0.1); + // check the body offset is correct + // Should really check body rotation too. Oh well. + const dReal *R1 = dBodyGetRotation (body[0]); + dVector3 p,pp; + const dReal *p1 = dBodyGetPosition (body[0]); + const dReal *p2 = dBodyGetPosition (body[1]); + for (int i=0; i<3; i++) p[i] = p2[i] - p1[i]; + dMultiply1_331 (pp,R1,p); + pp[0] += 0.5; + pp[1] += 0.5; + return length(pp) * 300; + } + + case 3: { // 1 body to static env with relative rotation + addOscillatingTorque (0.1); + + // check the body offset is correct + dVector3 p; + const dReal *p1 = dBodyGetPosition (body[0]); + for (int i=0; i<3; i++) p[i] = p1[i]; + p[0] -= 0.25; + p[1] -= 0.25; + p[2] -= 1; + return length (p) * 1e6; + } + + + // ********** hinge joint + + case 200: // 2 body + addOscillatingTorque (0.1); + dampRotationalMotion (0.1); + return dInfinity; + + case 220: // hinge angle polarity test + dBodyAddTorque (body[0],0,0,0.01); + dBodyAddTorque (body[1],0,0,-0.01); + if (iteration == 40) { + dReal a = dJointGetHingeAngle (joint); + if (a > 0.5 && a < 1) return 0; else return 10; + } + return 0; + + case 221: { // hinge angle rate test + static dReal last_angle = 0; + dBodyAddTorque (body[0],0,0,0.01); + dBodyAddTorque (body[1],0,0,-0.01); + dReal a = dJointGetHingeAngle (joint); + dReal r = dJointGetHingeAngleRate (joint); + dReal er = (a-last_angle)/STEPSIZE; // estimated rate + last_angle = a; + return fabs(r-er) * 4e4; + } + + case 230: // hinge motor rate (and polarity) test + case 231: { // ...with stops + static dReal a = 0; + dReal r = dJointGetHingeAngleRate (joint); + dReal err = fabs (cos(a) - r); + if (a==0) err = 0; + a += 0.03; + dJointSetHingeParam (joint,dParamVel,cos(a)); + if (n==231) return dInfinity; + return err * 1e6; + } + + // ********** slider joint + + case 300: // 2 body + addOscillatingTorque (0.05); + dampRotationalMotion (0.1); + addSpringForce (0.5); + return dInfinity; + + case 320: // slider angle polarity test + dBodyAddForce (body[0],0,0,0.1); + dBodyAddForce (body[1],0,0,-0.1); + if (iteration == 40) { + dReal a = dJointGetSliderPosition (joint); + if (a > 0.2 && a < 0.5) + return 0; + else + return 10; // Failed + } + return 0; + + case 321: { // slider angle rate test + static dReal last_pos = 0; + dBodyAddForce (body[0],0,0,0.1); + dBodyAddForce (body[1],0,0,-0.1); + dReal p = dJointGetSliderPosition (joint); + dReal r = dJointGetSliderPositionRate (joint); + dReal er = (p-last_pos)/STEPSIZE; // estimated rate (almost exact) + last_pos = p; + return fabs(r-er) * 1e9; + } + + case 330: // slider motor rate (and polarity) test + case 331: { // ...with stops + static dReal a = 0; + dReal r = dJointGetSliderPositionRate (joint); + dReal err = fabs (0.7*cos(a) - r); + if (a < 0.04) err = 0; + a += 0.03; + dJointSetSliderParam (joint,dParamVel,0.7*cos(a)); + if (n==331) return dInfinity; + return err * 1e6; + } + + // ********** hinge-2 joint + + case 420: // hinge-2 steering angle polarity test + dBodyAddTorque (body[0],0,0,0.01); + dBodyAddTorque (body[1],0,0,-0.01); + if (iteration == 40) { + dReal a = dJointGetHinge2Angle1 (joint); + if (a > 0.5 && a < 0.6) return 0; else return 10; + } + return 0; + + case 421: { // hinge-2 steering angle rate test + static dReal last_angle = 0; + dBodyAddTorque (body[0],0,0,0.01); + dBodyAddTorque (body[1],0,0,-0.01); + dReal a = dJointGetHinge2Angle1 (joint); + dReal r = dJointGetHinge2Angle1Rate (joint); + dReal er = (a-last_angle)/STEPSIZE; // estimated rate + last_angle = a; + return fabs(r-er)*2e4; + } + + case 430: // hinge 2 steering motor rate (+polarity) test + case 431: { // ...with stops + static dReal a = 0; + dReal r = dJointGetHinge2Angle1Rate (joint); + dReal err = fabs (cos(a) - r); + if (a==0) err = 0; + a += 0.03; + dJointSetHinge2Param (joint,dParamVel,cos(a)); + if (n==431) return dInfinity; + return err * 1e6; + } + + case 432: { // hinge 2 wheel motor rate (+polarity) test + static dReal a = 0; + dReal r = dJointGetHinge2Angle2Rate (joint); + dReal err = fabs (cos(a) - r); + if (a==0) err = 0; + a += 0.03; + dJointSetHinge2Param (joint,dParamVel2,cos(a)); + return err * 1e6; + } + + // ********** angular motor joint + + case 600: { // test euler angle calculations + // desired euler angles from last iteration + static dReal a1,a2,a3; + + // find actual euler angles + dReal aa1 = dJointGetAMotorAngle (joint,0); + dReal aa2 = dJointGetAMotorAngle (joint,1); + dReal aa3 = dJointGetAMotorAngle (joint,2); + // printf ("actual = %.4f %.4f %.4f\n\n",aa1,aa2,aa3); + + dReal err = dInfinity; + if (iteration > 0) { + err = dFabs(aa1-a1) + dFabs(aa2-a2) + dFabs(aa3-a3); + err *= 1e10; + } + + // get random base rotation for both bodies + dMatrix3 Rbase; + dRFromAxisAndAngle (Rbase, 3*(dRandReal()-0.5), 3*(dRandReal()-0.5), + 3*(dRandReal()-0.5), 3*(dRandReal()-0.5)); + dBodySetRotation (body[0],Rbase); + + // rotate body 2 by random euler angles w.r.t. body 1 + a1 = 3.14 * 2 * (dRandReal()-0.5); + a2 = 1.57 * 2 * (dRandReal()-0.5); + a3 = 3.14 * 2 * (dRandReal()-0.5); + dMatrix3 R1,R2,R3,Rtmp1,Rtmp2; + dRFromAxisAndAngle (R1,0,0,1,-a1); + dRFromAxisAndAngle (R2,0,1,0,a2); + dRFromAxisAndAngle (R3,1,0,0,-a3); + dMultiply0 (Rtmp1,R2,R3,3,3,3); + dMultiply0 (Rtmp2,R1,Rtmp1,3,3,3); + dMultiply0 (Rtmp1,Rbase,Rtmp2,3,3,3); + dBodySetRotation (body[1],Rtmp1); + // printf ("desired = %.4f %.4f %.4f\n",a1,a2,a3); + + return err; + } + + // ********** universal joint + + case 700: { // 2 body: joint constraint + dVector3 ax1, ax2; + + addOscillatingTorque (0.1); + dampRotationalMotion (0.1); + dJointGetUniversalAxis1(joint, ax1); + dJointGetUniversalAxis2(joint, ax2); + return fabs(10*dCalcVectorDot3(ax1, ax2)); + } + + case 701: { // 2 body: angle 1 rate + static dReal last_angle = 0; + addOscillatingTorque (0.1); + dampRotationalMotion (0.1); + dReal a = dJointGetUniversalAngle1(joint); + dReal r = dJointGetUniversalAngle1Rate(joint); + dReal diff = a - last_angle; + if (diff > M_PI) diff -= 2*M_PI; + if (diff < -M_PI) diff += 2*M_PI; + dReal er = diff / STEPSIZE; // estimated rate + last_angle = a; + // I'm not sure why the error is so large here. + return fabs(r - er) * 1e1; + } + + case 702: { // 2 body: angle 2 rate + static dReal last_angle = 0; + addOscillatingTorque (0.1); + dampRotationalMotion (0.1); + dReal a = dJointGetUniversalAngle2(joint); + dReal r = dJointGetUniversalAngle2Rate(joint); + dReal diff = a - last_angle; + if (diff > M_PI) diff -= 2*M_PI; + if (diff < -M_PI) diff += 2*M_PI; + dReal er = diff / STEPSIZE; // estimated rate + last_angle = a; + // I'm not sure why the error is so large here. + return fabs(r - er) * 1e1; + } + + case 720: { // universal transmit torque test: constraint error + dVector3 ax1, ax2; + addOscillatingTorqueAbout (0.1, 1, 1, 0); + dampRotationalMotion (0.1); + dJointGetUniversalAxis1(joint, ax1); + dJointGetUniversalAxis2(joint, ax2); + return fabs(10*dCalcVectorDot3(ax1, ax2)); + } + + case 721: { // universal transmit torque test: angle1 rate + static dReal last_angle = 0; + addOscillatingTorqueAbout (0.1, 1, 1, 0); + dampRotationalMotion (0.1); + dReal a = dJointGetUniversalAngle1(joint); + dReal r = dJointGetUniversalAngle1Rate(joint); + dReal diff = a - last_angle; + if (diff > M_PI) diff -= 2*M_PI; + if (diff < -M_PI) diff += 2*M_PI; + dReal er = diff / STEPSIZE; // estimated rate + last_angle = a; + return fabs(r - er) * 1e10; + } + + case 722: { // universal transmit torque test: angle2 rate + static dReal last_angle = 0; + addOscillatingTorqueAbout (0.1, 1, 1, 0); + dampRotationalMotion (0.1); + dReal a = dJointGetUniversalAngle2(joint); + dReal r = dJointGetUniversalAngle2Rate(joint); + dReal diff = a - last_angle; + if (diff > M_PI) diff -= 2*M_PI; + if (diff < -M_PI) diff += 2*M_PI; + dReal er = diff / STEPSIZE; // estimated rate + last_angle = a; + return fabs(r - er) * 1e10; + } + + case 730:{ + dVector3 ax1, ax2; + dJointGetUniversalAxis1(joint, ax1); + dJointGetUniversalAxis2(joint, ax2); + addOscillatingTorqueAbout (0.1, ax1[0], ax1[1], ax1[2]); + dampRotationalMotion (0.1); + return fabs(10*dCalcVectorDot3(ax1, ax2)); + } + + case 731:{ + dVector3 ax1; + static dReal last_angle = 0; + dJointGetUniversalAxis1(joint, ax1); + addOscillatingTorqueAbout (0.1, ax1[0], ax1[1], ax1[2]); + dampRotationalMotion (0.1); + dReal a = dJointGetUniversalAngle1(joint); + dReal r = dJointGetUniversalAngle1Rate(joint); + dReal diff = a - last_angle; + if (diff > M_PI) diff -= 2*M_PI; + if (diff < -M_PI) diff += 2*M_PI; + dReal er = diff / STEPSIZE; // estimated rate + last_angle = a; + return fabs(r - er) * 2e3; + } + + case 732:{ + dVector3 ax1; + static dReal last_angle = 0; + dJointGetUniversalAxis1(joint, ax1); + addOscillatingTorqueAbout (0.1, ax1[0], ax1[1], ax1[2]); + dampRotationalMotion (0.1); + dReal a = dJointGetUniversalAngle2(joint); + dReal r = dJointGetUniversalAngle2Rate(joint); + dReal diff = a - last_angle; + if (diff > M_PI) diff -= 2*M_PI; + if (diff < -M_PI) diff += 2*M_PI; + dReal er = diff / STEPSIZE; // estimated rate + last_angle = a; + return fabs(r - er) * 1e10; + } + + case 740:{ + dVector3 ax1, ax2; + dJointGetUniversalAxis1(joint, ax1); + dJointGetUniversalAxis2(joint, ax2); + addOscillatingTorqueAbout (0.1, ax2[0], ax2[1], ax2[2]); + dampRotationalMotion (0.1); + return fabs(10*dCalcVectorDot3(ax1, ax2)); + } + + case 741:{ + dVector3 ax2; + static dReal last_angle = 0; + dJointGetUniversalAxis2(joint, ax2); + addOscillatingTorqueAbout (0.1, ax2[0], ax2[1], ax2[2]); + dampRotationalMotion (0.1); + dReal a = dJointGetUniversalAngle1(joint); + dReal r = dJointGetUniversalAngle1Rate(joint); + dReal diff = a - last_angle; + if (diff > M_PI) diff -= 2*M_PI; + if (diff < -M_PI) diff += 2*M_PI; + dReal er = diff / STEPSIZE; // estimated rate + last_angle = a; + return fabs(r - er) * 1e10; + } + + case 742:{ + dVector3 ax2; + static dReal last_angle = 0; + dJointGetUniversalAxis2(joint, ax2); + addOscillatingTorqueAbout (0.1, ax2[0], ax2[1], ax2[2]); + dampRotationalMotion (0.1); + dReal a = dJointGetUniversalAngle2(joint); + dReal r = dJointGetUniversalAngle2Rate(joint); + dReal diff = a - last_angle; + if (diff > M_PI) diff -= 2*M_PI; + if (diff < -M_PI) diff += 2*M_PI; + dReal er = diff / STEPSIZE; // estimated rate + last_angle = a; + return fabs(r - er) * 1e4; + } + + // ********** slider joint + case 801: + case 803: + addSpringForce (0.25); + return dInfinity; + + case 802: + case 804: { + static dReal a = 0; + dBodyAddTorque (body[0], 0, 0.01*cos(1.5708*a), 0); + a += 0.01; + return dInfinity; + } + + case 805: + addOscillatingForce (0.1); + return dInfinity; + } + + + return dInfinity; +} + +//**************************************************************************** +// simulation stuff common to all the tests + +// start simulation - set viewpoint + +static void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + static float xyz[3] = {1.0382f,-1.0811f,1.4700f}; + static float hpr[3] = {135.0000f,-19.5000f,0.0000f}; + dsSetViewpoint (xyz,hpr); +} + + +// simulation loop + +static void simLoop (int pause) +{ + // stop after a given number of iterations, as long as we are not in + // interactive mode + if (cmd_graphics && !cmd_interactive && + (iteration >= max_iterations)) { + dsStop(); + return; + } + iteration++; + + if (!pause) { + // do stuff for this test and check to see if the joint is behaving well + dReal error = doStuffAndGetError (test_num); + if (error > max_error) max_error = error; + if (cmd_interactive && error < dInfinity) { + printf ("scaled error = %.4e\n",error); + } + + // take a step + dWorldStep (world,STEPSIZE); + + // occasionally re-orient the first body to create a deliberate error. + if (cmd_occasional_error) { + static int count = 0; + if ((count % 20)==0) { + // randomly adjust orientation of body[0] + const dReal *R1; + dMatrix3 R2,R3; + R1 = dBodyGetRotation (body[0]); + dRFromAxisAndAngle (R2,dRandReal()-0.5,dRandReal()-0.5, + dRandReal()-0.5,dRandReal()-0.5); + dMultiply0 (R3,R1,R2,3,3,3); + dBodySetRotation (body[0],R3); + + // randomly adjust position of body[0] + const dReal *pos = dBodyGetPosition (body[0]); + dBodySetPosition (body[0], + pos[0]+0.2*(dRandReal()-0.5), + pos[1]+0.2*(dRandReal()-0.5), + pos[2]+0.2*(dRandReal()-0.5)); + } + count++; + } + } + + if (cmd_graphics) { + dReal sides1[3] = {SIDE,SIDE,SIDE}; + dReal sides2[3] = {SIDE*0.99f,SIDE*0.99f,SIDE*0.99f}; + dsSetTexture (DS_WOOD); + dsSetColor (1,1,0); + dsDrawBox (dBodyGetPosition(body[0]),dBodyGetRotation(body[0]),sides1); + if (body[1]) { + dsSetColor (0,1,1); + dsDrawBox (dBodyGetPosition(body[1]),dBodyGetRotation(body[1]),sides2); + } + } +} + +//**************************************************************************** +// conduct a specific test, and report the results + +void doTest (int argc, char **argv, int n, int fatal_if_bad_n) +{ + test_num = n; + iteration = 0; + max_iterations = 300; + max_error = 0; + + if (! setupTest (n)) { + if (fatal_if_bad_n) dError (0,"bad test number"); + return; + } + + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = 0; + fn.stop = 0; + if (cmd_path_to_textures) + fn.path_to_textures = cmd_path_to_textures; + else + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + // run simulation + if (cmd_graphics) { + dsSimulationLoop (argc,argv,352,288,&fn); + } + else { + for (int i=0; i < max_iterations; i++) simLoop (0); + } + dWorldDestroy (world); + body[0] = 0; + body[1] = 0; + joint = 0; + + // print results + printf ("test %d: ",n); + if (max_error == dInfinity) printf ("error not computed\n"); + else { + printf ("max scaled error = %.4e",max_error); + if (max_error < 1) printf (" - passed\n"); + else printf (" - FAILED\n"); + } +} + +//**************************************************************************** +// main + +int main (int argc, char **argv) +{ + int i; + dInitODE2(0); + + // process the command line args. anything that starts with `-' is assumed + // to be a drawstuff argument. + for (i=1; i<argc; i++) { + if ( argv[i][0]=='-' && argv[i][1]=='i' && argv[i][2]==0) cmd_interactive = 1; + else if ( argv[i][0]=='-' && argv[i][1]=='g' && argv[i][2]==0) cmd_graphics = 0; + else if ( argv[i][0]=='-' && argv[i][1]=='e' && argv[i][2]==0) cmd_graphics = 0; + else if ( argv[i][0]=='-' && argv[i][1]=='n' && isdigit(argv[i][2]) ) { + char *endptr; + long int n = strtol (&(argv[i][2]),&endptr,10); + if (*endptr == 0) cmd_test_num = n; + } + else + cmd_path_to_textures = argv[i]; + } + + // do the tests + if (cmd_test_num == -1) { + for (i=0; i<NUM_JOINTS*100; i++) doTest (argc,argv,i,0); + } + else { + doTest (argc,argv,cmd_test_num,1); + } + + dCloseODE(); + return 0; +} diff --git a/libs/ode-0.16.1/ode/demo/demo_kinematic.cpp b/libs/ode-0.16.1/ode/demo/demo_kinematic.cpp new file mode 100644 index 0000000..5f2c613 --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_kinematic.cpp @@ -0,0 +1,239 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <iostream> +#include <set> +#include <algorithm> +#include <functional> +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#define dsDrawCylinder dsDrawCylinderD +#endif + + +using namespace std; + +dWorld *world; +dSpace *space; +dPlane *ground; +dBody *kbody; +dBox *kbox; +dJointGroup joints; +dCylinder *kpole; +dBody *matraca; +dBox *matraca_geom; +dHingeJoint *hinge; + +struct Box { + dBody body; + dBox geom; + Box() : + body(*world), + geom(*space, 0.2, 0.2, 0.2) + { + dMass mass; + mass.setBox(10, 0.2, 0.2, 0.2); + body.setMass(mass); + geom.setData(this); + geom.setBody(body); + } + void draw() const + { + dVector3 lengths; + geom.getLengths(lengths); + dsSetTexture(DS_WOOD); + dsSetColor(0,1,0); + dsDrawBox(geom.getPosition(), geom.getRotation(), lengths); + } +}; + +set<Box*> boxes; +set<Box*> to_remove; + +void dropBox() +{ + Box *box = new Box(); + + dReal px = (rand() / float(RAND_MAX)) * 2 - 1; + dReal py = (rand() / float(RAND_MAX)) * 2 - 1; + dReal pz = 2.5; + box->body.setPosition(px, py, pz); + + boxes.insert(box); +} + +void queueRemoval(dGeomID g) +{ + Box *b = (Box*)dGeomGetData(g); + to_remove.insert(b); +} + +void removeQueued() +{ + while (!to_remove.empty()) { + Box *b = *to_remove.begin(); + to_remove.erase(b); + boxes.erase(b); + delete b; + } +} + + +void nearCallback(void *, dGeomID g1, dGeomID g2) +{ + if (g1 == ground->id()) { + queueRemoval(g2); + return; + } + if (g2 == ground->id()) { + queueRemoval(g1); + return; + } + + dBodyID b1 = dGeomGetBody(g1); + dBodyID b2 = dGeomGetBody(g2); + + if (b1 && b2 && dAreConnectedExcluding(b1, b2, dJointTypeContact)) + return; + + const int MAX_CONTACTS = 10; + dContact contact[MAX_CONTACTS]; + int n = dCollide(g1, g2, MAX_CONTACTS, &contact[0].geom, sizeof(dContact)); + for (int i=0; i<n; ++i) { + contact[i].surface.mode = 0; + contact[i].surface.mu = 1; + dJointID j = dJointCreateContact (*world, joints.id(), contact+i); + dJointAttach(j, b1, b2); + } +} + + +void +simLoop(int pause) +{ + if (!pause) { + const dReal timestep = 0.04; + + // this does a hard-coded circular motion animation + static float t=0; + t += timestep/4; + if (t > 2*M_PI) + t = 0; + dVector3 next_pos = { dCos(t), dSin(t), REAL(0.5)}; + dVector3 vel; + // vel = (next_pos - cur_pos) / timestep + dSubtractVectors3(vel, next_pos, kbody->getPosition()); + dScaleVector3(vel, 1/timestep); + kbody->setLinearVel(vel); + // end of hard-coded animation + + space->collide(0, nearCallback); + removeQueued(); + + world->quickStep(timestep); + joints.clear(); + } + + dVector3 lengths; + + // the moving platform + kbox->getLengths(lengths); + dsSetTexture(DS_WOOD); + dsSetColor(.3, .3, 1); + dsDrawBox(kbox->getPosition(), kbox->getRotation(), lengths); + dReal length, radius; + kpole->getParams(&radius, &length); + dsSetTexture(DS_CHECKERED); + dsSetColor(1, 1, 0); + dsDrawCylinder(kpole->getPosition(), kpole->getRotation(), length, radius); + + // the matraca + matraca_geom->getLengths(lengths); + dsSetColor(1,0,0); + dsSetTexture(DS_WOOD); + dsDrawBox(matraca_geom->getPosition(), matraca_geom->getRotation(), lengths); + + // and the boxes + for_each(boxes.begin(), boxes.end(), mem_fun(&Box::draw)); +} + +void command(int c) +{ + switch (c) { + case ' ': + dropBox(); + break; + } +} + +int main(int argc, char **argv) +{ + dInitODE(); + + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = 0; + fn.step = &simLoop; + fn.command = &command; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + cout << endl << "*** Press SPACE to drop boxes **" << endl; + + space = new dSimpleSpace(); + ground = new dPlane(*space, 0, 0, 1, 0); + + world = new dWorld; + world->setGravity(0, 0, -.5); + + kbody = new dBody(*world); + kbody->setKinematic(); + const dReal kx = 1, ky = 0, kz = .5; + kbody->setPosition(kx, ky, kz); + kbox = new dBox(*space, 3, 3, .5); + kbox->setBody(*kbody); + kpole = new dCylinder(*space, .125, 1.5); + kpole->setBody(*kbody); + dGeomSetOffsetPosition(kpole->id(), 0, 0, 0.8); + + matraca = new dBody(*world); + matraca->setPosition(kx+0, ky+1, kz+1); + matraca_geom = new dBox(*space, 0.5, 2, 0.75); + matraca_geom->setBody(*matraca); + dMass mass; + mass.setBox(1, 0.5, 2, 0.75); + matraca->setMass(mass); + + hinge = new dHingeJoint(*world); + hinge->attach(*kbody, *matraca); + hinge->setAnchor(kx, ky, kz+1); + hinge->setAxis(0, 0, 1); + + dsSimulationLoop (argc, argv, 640, 480, &fn); + + dCloseODE(); +} diff --git a/libs/ode-0.16.1/ode/demo/demo_motion.cpp b/libs/ode-0.16.1/ode/demo/demo_motion.cpp new file mode 100644 index 0000000..a83887d --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_motion.cpp @@ -0,0 +1,527 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + This demo shows how to use dContactMotionN in a lifting platform. +*/ +//#include <unistd.h> // for usleep() +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + + +// select correct drawing functions + +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#define dsDrawSphere dsDrawSphereD +#define dsDrawCylinder dsDrawCylinderD +#define dsDrawCapsule dsDrawCapsuleD +#define dsDrawConvex dsDrawConvexD +#endif + + +// some constants + +#define NUM 100 // max number of objects +#define DENSITY (5.0) // density of all objects +#define GPB 3 // maximum number of geometries per body +#define MAX_CONTACTS 8 // maximum number of contact points per body +#define USE_GEOM_OFFSET 1 + +// dynamics and collision objects + +struct MyObject { + dBodyID body; // the body + dGeomID geom[GPB]; // geometries representing this body +}; + +static int num=0; // number of objects in simulation +static int nextobj=0; // next object to recycle if num==NUM +static dWorldID world; +static dSpaceID space; +static MyObject obj[NUM]; +static dJointGroupID contactgroup; +static int show_aabb = 0; // show geom AABBs? +static int show_contacts = 0; // show contact points? +static int random_pos = 1; // drop objects from random position? +static int write_world = 0; +static int show_body = 0; + +static dGeomID platform, ground; + +dVector3 platpos = {0, 0, 0}; +int mov_type = 2; +dReal mov_time = 0; + + +const dReal mov1_speed = 0.2; + +dVector3 mov2_vel = { 0.2, 0.1, 0.25}; + + + + +/**************************************************************** + * Movement 1: move platform up, reset every 80 units of time. * + * This is the simplest case * + ****************************************************************/ +static void moveplat_1(dReal stepsize) +{ + mov_time += stepsize; + if (mov_time > 80) + mov_time = 0; + + platpos[0] = platpos[1] = 0; + // the platform moves up (Z) at constant speed: mov1_speed + platpos[2] = mov1_speed * mov_time; +} + +// Generate contact info for movement 1 +static void contactplat_1(dContact &contact) +{ + contact.surface.mode |= dContactMotionN; + contact.surface.motionN = mov1_speed; +} + + + +/**************************************************************** + * Movement 2: move platform along direction mov2_vel, reset * + * every 80 units of time. * + * This is the most general case: the geom moves along * + * an arbitrary direction. * + ****************************************************************/ +static void moveplat_2(dReal stepsize) +{ + mov_time += stepsize; + if (mov_time > 80) + mov_time = 0; + + // the platform moves at constant speed: mov2_speed + platpos[0] = mov2_vel[0] * mov_time; + platpos[1] = mov2_vel[1] * mov_time; + platpos[2] = mov2_vel[2] * mov_time; +} + +// Generate contact info for movement 1 +static void contactplat_2(dContact &contact) +{ + /* + For arbitrary contact directions we need to project the moving + geom's velocity against the contact normal and fdir1, fdir2 + (obtained with dPlaneSpace()). Assuming moving geom=g2 + (so the contact joint is in the moving geom's reference frame): + motion1 = dCalcVectorDot3(fdir1, vel); + motion2 = dCalcVectorDot3(fdir2, vel); + motionN = dCalcVectorDot3(normal, vel); + + For geom=g1 just negate motionN and motion2. fdir1 is an arbitrary + vector, so there's no need to negate motion1. + + */ + contact.surface.mode |= + dContactMotionN | // velocity along normal + dContactMotion1 | dContactMotion2 | // and along the contact plane + dContactFDir1; // don't forget to set the direction 1 + + + // This is a convenience function: given a vector, it finds other 2 perpendicular vectors + dVector3 motiondir1, motiondir2; + dPlaneSpace(contact.geom.normal, motiondir1, motiondir2); + for (int i=0; i<3; ++i) + contact.fdir1[i] = motiondir1[i]; + + + dReal inv = 1; + if (contact.geom.g1 == platform) + inv = -1; + + contact.surface.motion1 = dCalcVectorDot3(mov2_vel, motiondir1); + contact.surface.motion2 = inv * dCalcVectorDot3(mov2_vel, motiondir2); + contact.surface.motionN = inv * dCalcVectorDot3(mov2_vel, contact.geom.normal); + +} + + + + + +static void nearCallback (void *, dGeomID o1, dGeomID o2) +{ + dMatrix3 RI; + static const dReal ss[3] = {0.02,0.02,0.02}; + + dContact contact[MAX_CONTACTS]; + int numc = dCollide (o1, o2, MAX_CONTACTS, + &contact[0].geom, sizeof(dContact)); + + if (numc) + dRSetIdentity(RI); + + bool isplatform = (o1 == platform) || (o2 == platform); + + for (int i=0; i< numc; i++) { + contact[i].surface.mode = dContactBounce; + contact[i].surface.mu = 1; + contact[i].surface.bounce = 0.25; + contact[i].surface.bounce_vel = 0.01; + + if (isplatform) { + switch (mov_type) { + case 1: + contactplat_1(contact[i]); + break; + case 2: + contactplat_2(contact[i]); + break; + } + } + + dJointID c = dJointCreateContact (world,contactgroup,contact+i); + dJointAttach (c, dGeomGetBody(o1), dGeomGetBody(o2)); + if (show_contacts) + dsDrawBox (contact[i].geom.pos, RI, ss); + } +} + + +// start simulation - set viewpoint + +static float xyz[3] = {2.1106f,-1.3007,2.f}; +static float hpr[3] = {150.f,-13.5000f,0.0000f}; + +static void start() +{ + //dAllocateODEDataForThread(dAllocateMaskAll); + dsSetViewpoint (xyz,hpr); + printf ("To drop another object, press:\n"); + printf (" b for box.\n"); + printf (" s for sphere.\n"); + printf (" c for capsule.\n"); + printf (" y for cylinder.\n"); + printf ("Press m to change the movement type\n"); + printf ("Press space to reset the platform\n"); + printf ("To toggle showing the geom AABBs, press a.\n"); + printf ("To toggle showing the contact points, press t.\n"); + printf ("To toggle dropping from random position/orientation, press r.\n"); + printf ("To save the current state to 'state.dif', press 1.\n"); +} + + +char locase (char c) +{ + if (c >= 'A' && c <= 'Z') return c - ('a'-'A'); + else return c; +} + + +// called when a key pressed + +static void command (int cmd) +{ + dsizeint i; + int k; + dReal sides[3]; + dMass m; + int setBody; + + cmd = locase (cmd); + if (cmd == 'b' || cmd == 's' || cmd == 'c' || cmd == 'y') + { + setBody = 0; + if (num < NUM) { + i = num; + num++; + } + else { + i = nextobj; + nextobj++; + if (nextobj >= num) nextobj = 0; + + // destroy the body and geoms for slot i + if (obj[i].body) { + dBodyDestroy (obj[i].body); + } + for (k=0; k < GPB; k++) { + if (obj[i].geom[k]) { + dGeomDestroy (obj[i].geom[k]); + } + } + memset (&obj[i],0,sizeof(obj[i])); + } + + obj[i].body = dBodyCreate (world); + for (k=0; k<3; k++) sides[k] = dRandReal()*0.5+0.1; + + dMatrix3 R; + if (random_pos) + { + dBodySetPosition (obj[i].body, + dRandReal()*2-1 + platpos[0], + dRandReal()*2-1 + platpos[1], + dRandReal()+2 + platpos[2]); + dRFromAxisAndAngle (R,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, + dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); + } + else + { + dBodySetPosition (obj[i].body, + platpos[0], + platpos[1], + platpos[2]+2); + dRSetIdentity (R); + } + dBodySetRotation (obj[i].body,R); + dBodySetData (obj[i].body,(void*) i); + + if (cmd == 'b') { + dMassSetBox (&m,DENSITY,sides[0],sides[1],sides[2]); + obj[i].geom[0] = dCreateBox (space,sides[0],sides[1],sides[2]); + } + else if (cmd == 'c') { + sides[0] *= 0.5; + dMassSetCapsule (&m,DENSITY,3,sides[0],sides[1]); + obj[i].geom[0] = dCreateCapsule (space,sides[0],sides[1]); + } + else if (cmd == 'y') { + dMassSetCylinder (&m,DENSITY,3,sides[0],sides[1]); + obj[i].geom[0] = dCreateCylinder (space,sides[0],sides[1]); + } + else if (cmd == 's') { + sides[0] *= 0.5; + dMassSetSphere (&m,DENSITY,sides[0]); + obj[i].geom[0] = dCreateSphere (space,sides[0]); + } + + if (!setBody) + for (k=0; k < GPB; k++) { + if (obj[i].geom[k]) { + dGeomSetBody (obj[i].geom[k],obj[i].body); + } + } + + dBodySetMass (obj[i].body,&m); + } + else if (cmd == 'a') { + show_aabb ^= 1; + } + else if (cmd == 't') { + show_contacts ^= 1; + } + else if (cmd == 'r') { + random_pos ^= 1; + } + else if (cmd == '1') { + write_world = 1; + } + else if (cmd == ' ') { + mov_time = 0; + } + else if (cmd == 'm') { + mov_type = mov_type==1 ? 2 : 1; + mov_time = 0; + } +} + + +// draw a geom + +void drawGeom (dGeomID g, const dReal *pos, const dReal *R, int show_aabb) +{ + int i; + + if (!g) return; + if (!pos) pos = dGeomGetPosition (g); + if (!R) R = dGeomGetRotation (g); + + int type = dGeomGetClass (g); + if (type == dBoxClass) { + dVector3 sides; + dGeomBoxGetLengths (g,sides); + dsDrawBox (pos,R,sides); + } + else if (type == dSphereClass) { + dsDrawSphere (pos,R,dGeomSphereGetRadius (g)); + } + else if (type == dCapsuleClass) { + dReal radius,length; + dGeomCapsuleGetParams (g,&radius,&length); + dsDrawCapsule (pos,R,length,radius); + } + else if (type == dCylinderClass) { + dReal radius,length; + dGeomCylinderGetParams (g,&radius,&length); + dsDrawCylinder (pos,R,length,radius); + } + + if (show_body) { + dBodyID body = dGeomGetBody(g); + if (body) { + const dReal *bodypos = dBodyGetPosition (body); + const dReal *bodyr = dBodyGetRotation (body); + dReal bodySides[3] = { 0.1, 0.1, 0.1 }; + dsSetColorAlpha(0,1,0,1); + dsDrawBox(bodypos,bodyr,bodySides); + } + } + if (show_aabb) { + // draw the bounding box for this geom + dReal aabb[6]; + dGeomGetAABB (g,aabb); + dVector3 bbpos; + for (i=0; i<3; i++) bbpos[i] = 0.5*(aabb[i*2] + aabb[i*2+1]); + dVector3 bbsides; + for (i=0; i<3; i++) bbsides[i] = aabb[i*2+1] - aabb[i*2]; + dMatrix3 RI; + dRSetIdentity (RI); + dsSetColorAlpha (1,0,0,0.5); + dsDrawBox (bbpos,RI,bbsides); + } +} + + +// simulation loop + +static void updatecam() +{ + xyz[0] = platpos[0] + 3.3; + xyz[1] = platpos[1] - 1.8; + xyz[2] = platpos[2] + 2; + dsSetViewpoint (xyz, hpr); +} + +static void simLoop (int pause) +{ + const dReal stepsize = 0.02; + + dsSetColor (0,0,2); + dSpaceCollide (space,0,&nearCallback); + if (!pause) { + + if (mov_type == 1) + moveplat_1(stepsize); + else + moveplat_2(stepsize); + + dGeomSetPosition(platform, platpos[0], platpos[1], platpos[2]); + updatecam(); + dWorldQuickStep (world,stepsize); + //dWorldStep (world,stepsize); + } + + if (write_world) { + FILE *f = fopen ("state.dif","wt"); + if (f) { + dWorldExportDIF (world,f,"X"); + fclose (f); + } + write_world = 0; + } + + // remove all contact joints + dJointGroupEmpty (contactgroup); + + dsSetColor (1,1,0); + dsSetTexture (DS_WOOD); + for (int i=0; i<num; i++) { + for (int j=0; j < GPB; j++) { + if (! dBodyIsEnabled (obj[i].body)) { + dsSetColor (1,0.8,0); + } + else { + dsSetColor (1,1,0); + } + drawGeom (obj[i].geom[j],0,0,show_aabb); + } + } + dsSetColor (1,0,0); + drawGeom (platform,0,0,show_aabb); + //usleep(5000); +} + + +int main (int argc, char **argv) +{ + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + // create world + dInitODE(); + world = dWorldCreate(); + +#if 1 + space = dHashSpaceCreate (0); +#elif 0 + dVector3 center = {0,0,0}, extents = { 100, 100, 100}; + space = dQuadTreeSpaceCreate(0, center, extents, 5); +#elif 0 + space = dSweepAndPruneSpaceCreate (0, dSAP_AXES_XYZ); +#else + space = dSimpleSpaceCreate(0); +#endif + + contactgroup = dJointGroupCreate (0); + dWorldSetGravity (world,0,0,-0.5); + dWorldSetCFM (world,1e-5); + + dWorldSetLinearDamping(world, 0.00001); + dWorldSetAngularDamping(world, 0.005); + dWorldSetMaxAngularSpeed(world, 200); + + dWorldSetContactSurfaceLayer (world,0.001); + ground = dCreatePlane (space,0,0,1,0); + + memset (obj,0,sizeof(obj)); + + // create lift platform + platform = dCreateBox(space, 4, 4, 1); + + dGeomSetCategoryBits(ground, 1ul); + dGeomSetCategoryBits(platform, 2ul); + dGeomSetCollideBits(ground, ~2ul); + dGeomSetCollideBits(platform, ~1ul); + + // run simulation + dsSimulationLoop (argc,argv,352,288,&fn); + + dJointGroupDestroy (contactgroup); + dSpaceDestroy (space); + dWorldDestroy (world); + dCloseODE(); + return 0; +} + + +// Local Variables: +// c-basic-offset:4 +// End: diff --git a/libs/ode-0.16.1/ode/demo/demo_motor.cpp b/libs/ode-0.16.1/ode/demo/demo_motor.cpp new file mode 100644 index 0000000..9e0dede --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_motor.cpp @@ -0,0 +1,209 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + +// select correct drawing functions +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#endif + + +// some constants +#define SIDE (0.5f) // side length of a box +#define MASS (1.0) // mass of a box + + +// dynamics and collision objects +static dWorldID world; +static dBodyID body[2]; +static dGeomID geom[2]; +static dJointID lmotor[2]; +static dJointID amotor[2]; +static dSpaceID space; +static dJointGroupID contactgroup; + + +// start simulation - set viewpoint + +static void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + static float xyz[3] = {1.0382f,-1.0811f,1.4700f}; + static float hpr[3] = {135.0000f,-19.5000f,0.0000f}; + dsSetViewpoint (xyz,hpr); + printf ("Press 'q,a,z' to control one axis of lmotor connectiong two bodies. (q is +,a is 0, z is -)\n"); + printf ("Press 'w,e,r' to control one axis of lmotor connectiong first body with world. (w is +,e is 0, r is -)\n"); +} + + +// called when a key pressed + +static void command (int cmd) +{ + if (cmd == 'q' || cmd == 'Q') { + dJointSetLMotorParam(lmotor[0],dParamVel,0); + dJointSetLMotorParam(lmotor[0],dParamVel2,0); + dJointSetLMotorParam(lmotor[0],dParamVel3,0.1); + } else if (cmd == 'a' || cmd == 'A') { + dJointSetLMotorParam(lmotor[0],dParamVel,0); + dJointSetLMotorParam(lmotor[0],dParamVel2,0); + dJointSetLMotorParam(lmotor[0],dParamVel3,0); + } else if (cmd == 'z' || cmd == 'Z') { + dJointSetLMotorParam(lmotor[0],dParamVel,0); + dJointSetLMotorParam(lmotor[0],dParamVel2,0); + dJointSetLMotorParam(lmotor[0],dParamVel3,-0.1); + } else if (cmd == 'w' || cmd == 'W') { + dJointSetLMotorParam(lmotor[1],dParamVel,0.1); + dJointSetLMotorParam(lmotor[1],dParamVel2,0); + dJointSetLMotorParam(lmotor[1],dParamVel3,0); + } else if (cmd == 'e' || cmd == 'E') { + dJointSetLMotorParam(lmotor[1],dParamVel,0); + dJointSetLMotorParam(lmotor[1],dParamVel2,0); + dJointSetLMotorParam(lmotor[1],dParamVel3,0); + } else if (cmd == 'r' || cmd == 'R') { + dJointSetLMotorParam(lmotor[1],dParamVel,-0.1); + dJointSetLMotorParam(lmotor[1],dParamVel2,0); + dJointSetLMotorParam(lmotor[1],dParamVel3,0); + } + +} + + + +static void nearCallback (void *, dGeomID o1, dGeomID o2) +{ + // exit without doing anything if the two bodies are connected by a joint + dBodyID b1 = dGeomGetBody(o1); + dBodyID b2 = dGeomGetBody(o2); + + dContact contact; + contact.surface.mode = 0; + contact.surface.mu = dInfinity; + if (dCollide (o1,o2,1,&contact.geom,sizeof(dContactGeom))) { + dJointID c = dJointCreateContact (world,contactgroup,&contact); + dJointAttach (c,b1,b2); + } +} + +// simulation loop + +static void simLoop (int pause) +{ + if (!pause) { + dSpaceCollide(space,0,&nearCallback); + dWorldQuickStep (world,0.05); + dJointGroupEmpty(contactgroup); + } + + dReal sides1[3]; + dGeomBoxGetLengths(geom[0], sides1); + dReal sides2[3]; + dGeomBoxGetLengths(geom[1], sides2); + dsSetTexture (DS_WOOD); + dsSetColor (1,1,0); + dsDrawBox (dBodyGetPosition(body[0]),dBodyGetRotation(body[0]),sides1); + dsSetColor (0,1,1); + dsDrawBox (dBodyGetPosition(body[1]),dBodyGetRotation(body[1]),sides2); +} + + +int main (int argc, char **argv) +{ + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + // create world + dInitODE2(0); + contactgroup = dJointGroupCreate(0); + world = dWorldCreate(); + space = dSimpleSpaceCreate(0); + dMass m; + dMassSetBox (&m,1,SIDE,SIDE,SIDE); + dMassAdjust (&m,MASS); + + body[0] = dBodyCreate (world); + dBodySetMass (body[0],&m); + dBodySetPosition (body[0],0,0,1); + geom[0] = dCreateBox(space,SIDE,SIDE,SIDE); + body[1] = dBodyCreate (world); + dBodySetMass (body[1],&m); + dBodySetPosition (body[1],0,0,2); + geom[1] = dCreateBox(space,SIDE,SIDE,SIDE); + + dGeomSetBody(geom[0],body[0]); + dGeomSetBody(geom[1],body[1]); + + lmotor[0] = dJointCreateLMotor (world,0); + dJointAttach (lmotor[0],body[0],body[1]); + lmotor[1] = dJointCreateLMotor (world,0); + dJointAttach (lmotor[1],body[0],0); + amotor[0] = dJointCreateAMotor(world,0); + dJointAttach(amotor[0], body[0],body[1]); + amotor[1] = dJointCreateAMotor(world,0); + dJointAttach(amotor[1], body[0], 0); + + for (int i=0; i<2; i++) { + dJointSetAMotorNumAxes(amotor[i], 3); + dJointSetAMotorAxis(amotor[i],0,1,1,0,0); + dJointSetAMotorAxis(amotor[i],1,1,0,1,0); + dJointSetAMotorAxis(amotor[i],2,1,0,0,1); + dJointSetAMotorParam(amotor[i],dParamFMax,0.00001); + dJointSetAMotorParam(amotor[i],dParamFMax2,0.00001); + dJointSetAMotorParam(amotor[i],dParamFMax3,0.00001); + + dJointSetAMotorParam(amotor[i],dParamVel,0); + dJointSetAMotorParam(amotor[i],dParamVel2,0); + dJointSetAMotorParam(amotor[i],dParamVel3,0); + + dJointSetLMotorNumAxes(lmotor[i],3); + dJointSetLMotorAxis(lmotor[i],0,1,1,0,0); + dJointSetLMotorAxis(lmotor[i],1,1,0,1,0); + dJointSetLMotorAxis(lmotor[i],2,1,0,0,1); + + dJointSetLMotorParam(lmotor[i],dParamFMax,0.0001); + dJointSetLMotorParam(lmotor[i],dParamFMax2,0.0001); + dJointSetLMotorParam(lmotor[i],dParamFMax3,0.0001); + } + + // run simulation + dsSimulationLoop (argc,argv,352,288,&fn); + + dJointGroupDestroy(contactgroup); + dSpaceDestroy (space); + dWorldDestroy (world); + dCloseODE(); + return 0; +} diff --git a/libs/ode-0.16.1/ode/demo/demo_moving_convex.cpp b/libs/ode-0.16.1/ode/demo/demo_moving_convex.cpp new file mode 100644 index 0000000..2f03900 --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_moving_convex.cpp @@ -0,0 +1,415 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" +#include "bunny_geom.h" +#include "convex_bunny_geom.h" + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + +// select correct drawing functions + +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#define dsDrawSphere dsDrawSphereD +#define dsDrawCylinder dsDrawCylinderD +#define dsDrawCapsule dsDrawCapsuleD +#define dsDrawLine dsDrawLineD +#define dsDrawTriangle dsDrawTriangleD +#define dsDrawConvex dsDrawConvexD +#endif + + +// some constants + +#define NUM 200 // max number of objects +#define DENSITY (5.0) // density of all objects +#define GPB 3 // maximum number of geometries per body +#define MAX_CONTACTS 64 // maximum number of contact points per body + + +// dynamics and collision objects + +struct MyObject +{ + dBodyID body; // the body + dGeomID geom[GPB]; // geometries representing this body +}; + +static int num=0; // number of objects in simulation +static int nextobj=0; // next object to recycle if num==NUM +static dWorldID world; +static dSpaceID space; +static MyObject obj[NUM]; +static dJointGroupID contactgroup; +static int selected = -1; // selected object +static int show_aabb = 0; // show geom AABBs? +static int show_contacts = 0; // show contact points? +static int random_pos = 1; // drop objects from random position? + +typedef dReal dVector3R[3]; + +// this is called by dSpaceCollide when two objects in space are +// potentially colliding. + +static void nearCallback( void *, dGeomID o1, dGeomID o2 ) +{ + int i; + // if (o1->body && o2->body) return; + + // exit without doing anything if the two bodies are connected by a joint + dBodyID b1 = dGeomGetBody( o1 ); + dBodyID b2 = dGeomGetBody( o2 ); + if ( b1 && b2 && dAreConnectedExcluding( b1,b2,dJointTypeContact ) ) return; + + dContact contact[MAX_CONTACTS]; // up to MAX_CONTACTS contacts per box-box + for ( i=0; i<MAX_CONTACTS; i++ ) + { + contact[i].surface.mode = dContactBounce | dContactSoftCFM; + contact[i].surface.mu = dInfinity; + contact[i].surface.mu2 = 0; + contact[i].surface.bounce = 0.1; + contact[i].surface.bounce_vel = 0.1; + contact[i].surface.soft_cfm = 0.01; + } + if ( int numc = dCollide( o1,o2,MAX_CONTACTS,&contact[0].geom, + sizeof( dContact ) ) ) + { + dMatrix3 RI; + dRSetIdentity( RI ); + const dReal ss[3] = {0.02,0.02,0.02}; + for ( i=0; i<numc; i++ ) + { + dJointID c = dJointCreateContact( world,contactgroup,contact+i ); + dJointAttach( c,b1,b2 ); + if ( show_contacts ) dsDrawBox( contact[i].geom.pos,RI,ss ); + } + } +} + + +// start simulation - set viewpoint + +static void start() +{ + dAllocateODEDataForThread( dAllocateMaskAll ); + + static float xyz[3] = {2.1640f,-1.3079f,1.7600f}; + static float hpr[3] = {125.5000f,-17.0000f,0.0000f}; + dsSetViewpoint( xyz,hpr ); + printf( "To drop another object, press:\n" ); + printf( " b for box.\n" ); + printf( " s for sphere.\n" ); + printf( " c for capsule.\n" ); + printf( " v for a convex.\n" ); + printf( "To select an object, press space.\n" ); + printf( "To disable the selected object, press d.\n" ); + printf( "To enable the selected object, press e.\n" ); + printf( "To toggle showing the geom AABBs, press a.\n" ); + printf( "To toggle showing the contact points, press t.\n" ); + printf( "To toggle dropping from random position/orientation, press r.\n" ); +} + + +char locase( char c ) +{ + if ( c >= 'A' && c <= 'Z' ) return c - ( 'a'-'A' ); + else return c; +} + + +// called when a key pressed +static void command( int cmd ) +{ + int i,k; + dReal sides[3]; + dMass m; + + cmd = locase( cmd ); + if ( cmd == 'v' || cmd == 'b' || cmd == 'c' || cmd == 's' || cmd == 'y') + { + if ( num < NUM ) + { + i = num; + num++; + } + else + { + i = nextobj; + nextobj++; + if ( nextobj >= num ) nextobj = 0; + + // destroy the body and geoms for slot i + dBodyDestroy( obj[i].body ); + for ( k=0; k < GPB; k++ ) + { + if ( obj[i].geom[k] ) dGeomDestroy( obj[i].geom[k] ); + } + memset( &obj[i],0,sizeof( obj[i] ) ); + } + + obj[i].body = dBodyCreate( world ); + for ( k=0; k<3; k++ ) sides[k] = dRandReal()*0.5+0.1; + + dMatrix3 R; + if ( random_pos ) + { + dBodySetPosition( obj[i].body, + dRandReal()*2-1,dRandReal()*2-1,dRandReal()+3 ); + dRFromAxisAndAngle( R,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, + dRandReal()*2.0-1.0,dRandReal()*10.0-5.0 ); + } + else + { + dReal maxheight = 0; + for ( k=0; k<num; k++ ) + { + const dReal *pos = dBodyGetPosition( obj[k].body ); + if ( pos[2] > maxheight ) maxheight = pos[2]; + } + dBodySetPosition( obj[i].body, 0,0,maxheight+1 ); + dRFromAxisAndAngle( R,0,0,1,dRandReal()*10.0-5.0 ); + } + dBodySetRotation( obj[i].body,R ); + dBodySetData( obj[i].body,( void* )( dsizeint )i ); + + if ( cmd == 'b' ) + { + dMassSetBox( &m,DENSITY,sides[0],sides[1],sides[2] ); + obj[i].geom[0] = dCreateBox( space,sides[0],sides[1],sides[2] ); + } + else if ( cmd == 'c' ) + { + sides[0] *= 0.5; + dMassSetCapsule( &m,DENSITY,3,sides[0],sides[1] ); + obj[i].geom[0] = dCreateCapsule( space,sides[0],sides[1] ); + } + else if (cmd == 'y') { + dMassSetCylinder (&m,DENSITY,3,sides[0],sides[1]); + obj[i].geom[0] = dCreateCylinder (space,sides[0],sides[1]); + } + else if ( cmd == 's' ) + { + sides[0] *= 0.5; + dMassSetSphere( &m,DENSITY,sides[0] ); + obj[i].geom[0] = dCreateSphere( space,sides[0] ); + } + else if ( cmd == 'v' ) + { + obj[i].geom[0] = dCreateConvex( space, + convexBunnyPlanes, + convexBunnyPlaneCount, + convexBunnyPoints, + convexBunnyPointCount, + convexBunnyPolygons ); + + /// Use equivalent TriMesh to set mass + dTriMeshDataID new_tmdata = dGeomTriMeshDataCreate(); + dGeomTriMeshDataBuildSingle( new_tmdata, &Vertices[0], 3 * sizeof( float ), VertexCount, + ( dTriIndex* )&Indices[0], IndexCount, 3 * sizeof( dTriIndex ) ); + dGeomTriMeshDataPreprocess2( new_tmdata, (1U << dTRIDATAPREPROCESS_BUILD_FACE_ANGLES), NULL ); + + dGeomID triMesh = dCreateTriMesh( 0, new_tmdata, 0, 0, 0 ); + + dMassSetTrimesh( &m, DENSITY, triMesh ); + + dGeomDestroy( triMesh ); + dGeomTriMeshDataDestroy( new_tmdata ); + + printf( "mass at %f %f %f\n", m.c[0], m.c[1], m.c[2] ); + dGeomSetPosition( obj[i].geom[0], -m.c[0], -m.c[1], -m.c[2] ); + dMassTranslate( &m, -m.c[0], -m.c[1], -m.c[2] ); + } + + for ( k=0; k < GPB; k++ ) + { + if ( obj[i].geom[k] ) dGeomSetBody( obj[i].geom[k],obj[i].body ); + } + + dBodySetMass( obj[i].body,&m ); + } + + if ( cmd == ' ' ) + { + selected++; + if ( selected >= num ) selected = 0; + if ( selected < 0 ) selected = 0; + } + else if ( cmd == 'd' && selected >= 0 && selected < num ) + { + dBodyDisable( obj[selected].body ); + } + else if ( cmd == 'e' && selected >= 0 && selected < num ) + { + dBodyEnable( obj[selected].body ); + } + else if ( cmd == 'a' ) + { + show_aabb ^= 1; + } + else if ( cmd == 't' ) + { + show_contacts ^= 1; + } + else if ( cmd == 'r' ) + { + random_pos ^= 1; + } +} + +// draw a geom +void drawGeom( dGeomID g, const dReal *pos, const dReal *R, int show_aabb ) +{ + if ( !g ) return; + if ( !pos ) pos = dGeomGetPosition( g ); + if ( !R ) R = dGeomGetRotation( g ); + + int type = dGeomGetClass( g ); + if ( type == dBoxClass ) + { + dVector3 sides; + dGeomBoxGetLengths( g,sides ); + dsDrawBox( pos,R,sides ); + } + else if ( type == dSphereClass ) + { + dsDrawSphere( pos,R,dGeomSphereGetRadius( g ) ); + } + else if (type == dCylinderClass) { + dReal radius,length; + dGeomCylinderGetParams (g,&radius,&length); + dsDrawCylinder (pos,R,length,radius); + } + else if ( type == dCapsuleClass ) + { + dReal radius,length; + dGeomCapsuleGetParams( g,&radius,&length ); + dsDrawCapsule( pos,R,length,radius ); + } + else if ( type == dConvexClass ) + { + dsDrawConvex( pos,R, + convexBunnyPlanes, + convexBunnyPlaneCount, + convexBunnyPoints, + convexBunnyPointCount, + convexBunnyPolygons ); + } + + if ( show_aabb ) + { + // draw the bounding box for this geom + dReal aabb[6]; + dGeomGetAABB( g,aabb ); + dVector3 bbpos; + for ( int i=0; i<3; i++ ) bbpos[i] = 0.5*( aabb[i*2] + aabb[i*2+1] ); + dVector3 bbsides; + for ( int j=0; j<3; j++ ) bbsides[j] = aabb[j*2+1] - aabb[j*2]; + dMatrix3 RI; + dRSetIdentity( RI ); + dsSetColorAlpha( 1,0,0,0.5 ); + dsDrawBox( bbpos,RI,bbsides ); + } +} + +// simulation loop + +static void simLoop( int pause ) +{ + dsSetColor( 0,0,2 ); + dSpaceCollide( space,0,&nearCallback ); + + if ( !pause ) dWorldQuickStep( world,0.05 ); + + for ( int j = 0; j < dSpaceGetNumGeoms( space ); j++ ) + { + dSpaceGetGeom( space, j ); + } + + // remove all contact joints + dJointGroupEmpty( contactgroup ); + + dsSetColor( 1,1,0 ); + dsSetTexture( DS_WOOD ); + for ( int i=0; i<num; i++ ) + { + for ( int j=0; j < GPB; j++ ) + { + if ( obj[i].geom[j] ) + { + if ( i==selected ) + { + dsSetColor( 0,0.7,1 ); + } + else if ( ! dBodyIsEnabled( obj[i].body ) ) + { + dsSetColor( 1,0,0 ); + } + else + { + dsSetColor( 1,1,0 ); + } + + drawGeom( obj[i].geom[j],0,0,show_aabb ); + } + } + } +} + + +int main( int argc, char **argv ) +{ + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + // create world + dInitODE2( 0 ); + world = dWorldCreate(); + + space = dSimpleSpaceCreate( 0 ); + contactgroup = dJointGroupCreate( 0 ); + dWorldSetGravity( world,0,0,-0.5 ); + dWorldSetCFM( world,1e-5 ); + dCreatePlane( space,0,0,1,0 ); + memset( obj,0,sizeof( obj ) ); + + // run simulation + dsSimulationLoop( argc,argv,352,288,&fn ); + + dJointGroupDestroy( contactgroup ); + dSpaceDestroy( space ); + dWorldDestroy( world ); + dCloseODE(); + return 0; +} + + diff --git a/libs/ode-0.16.1/ode/demo/demo_moving_trimesh.cpp b/libs/ode-0.16.1/ode/demo/demo_moving_trimesh.cpp new file mode 100644 index 0000000..26034ae --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_moving_trimesh.cpp @@ -0,0 +1,677 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" +#include "bunny_geom.h" + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + +//<---- Convex Object +static const dReal planes[] = // planes for a cube +{ + 1.0f ,0.0f ,0.0f ,0.25f, + 0.0f ,1.0f ,0.0f ,0.25f, + 0.0f ,0.0f ,1.0f ,0.25f, + 0.0f ,0.0f ,-1.0f,0.25f, + 0.0f ,-1.0f,0.0f ,0.25f, + -1.0f,0.0f ,0.0f ,0.25f + /* + 1.0f ,0.0f ,0.0f ,2.0f, + 0.0f ,1.0f ,0.0f ,1.0f, + 0.0f ,0.0f ,1.0f ,1.0f, + 0.0f ,0.0f ,-1.0f,1.0f, + 0.0f ,-1.0f,0.0f ,1.0f, + -1.0f,0.0f ,0.0f ,0.0f + */ +}; +static const unsigned int planecount=6; + +static const dReal points[] = // points for a cube +{ + 0.25f,0.25f,0.25f, + -0.25f,0.25f,0.25f, + + 0.25f,-0.25f,0.25f, + -0.25f,-0.25f,0.25f, + + 0.25f,0.25f,-0.25f, + -0.25f,0.25f,-0.25f, + + 0.25f,-0.25f,-0.25f, + -0.25f,-0.25f,-0.25f, +}; +static const unsigned int pointcount=8; + +static const unsigned int polygons[] = //Polygons for a cube (6 squares) + { + 4,0,2,6,4, // positive X + 4,1,0,4,5, // positive Y + 4,0,1,3,2, // positive Z + 4,3,1,5,7, // negative X + 4,2,3,7,6, // negative Y + 4,5,4,6,7, // negative Z + }; +//----> Convex Object + +int tmTriangles[] = +{ + 0,2,6, + 0,6,4, + 1,0,4, + 1,4,5, + 0,1,3, + 0,3,2, + 3,1,5, + 3,5,7, + 2,3,7, + 2,7,6, + 5,4,6, + 5,6,7 +}; + +float tmVertices[] = +{ + 0.25f,0.25f,0.25f, // point 0 + -0.25f,0.25f,0.25f, // point 1 + + 0.25f,-0.25f,0.25f, // point 2 + -0.25f,-0.25f,0.25f,// point 3 + + 0.25f,0.25f,-0.25f, // point 4 + -0.25f,0.25f,-0.25f,// point 5 + + 0.25f,-0.25f,-0.25f,// point 6 + -0.25f,-0.25f,-0.25f,// point 7 +}; + +// select correct drawing functions + +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#define dsDrawSphere dsDrawSphereD +#define dsDrawCylinder dsDrawCylinderD +#define dsDrawCapsule dsDrawCapsuleD +#define dsDrawLine dsDrawLineD +#define dsDrawTriangle dsDrawTriangleD +#define dsDrawConvex dsDrawConvexD +#endif + + +// some constants + +#define NUM 200 // max number of objects +#define DENSITY (5.0) // density of all objects +#define GPB 3 // maximum number of geometries per body +#define MAX_CONTACTS 64 // maximum number of contact points per body + + +// dynamics and collision objects + +struct MyObject { + dBodyID body; // the body + dGeomID geom[GPB]; // geometries representing this body + + // Trimesh only - double buffered matrices for 'last transform' setup + dReal matrix_dblbuff[ 16 * 2 ]; + int last_matrix_index; +}; + +static int num=0; // number of objects in simulation +static int nextobj=0; // next object to recycle if num==NUM +static dWorldID world; +static dSpaceID space; +static MyObject obj[NUM]; +static dJointGroupID contactgroup; +static int selected = -1; // selected object +static int show_aabb = 0; // show geom AABBs? +static int show_contacts = 0; // show contact points? +static int random_pos = 1; // drop objects from random position? + +typedef dReal dVector3R[3]; + +dGeomID TriMesh1; +dGeomID TriMesh2; +static dTriMeshDataID TriData1, TriData2; // reusable static trimesh data + +// this is called by dSpaceCollide when two objects in space are +// potentially colliding. + +static void nearCallback (void *, dGeomID o1, dGeomID o2) +{ + int i; + // if (o1->body && o2->body) return; + + // exit without doing anything if the two bodies are connected by a joint + dBodyID b1 = dGeomGetBody(o1); + dBodyID b2 = dGeomGetBody(o2); + if (b1 && b2 && dAreConnectedExcluding (b1,b2,dJointTypeContact)) return; + + dContact contact[MAX_CONTACTS]; // up to MAX_CONTACTS contacts per box-box + for (i=0; i<MAX_CONTACTS; i++) { + contact[i].surface.mode = dContactBounce | dContactSoftCFM; + contact[i].surface.mu = dInfinity; + contact[i].surface.mu2 = 0; + contact[i].surface.bounce = 0.1; + contact[i].surface.bounce_vel = 0.1; + contact[i].surface.soft_cfm = 0.01; + } + if (int numc = dCollide (o1,o2,MAX_CONTACTS,&contact[0].geom, + sizeof(dContact))) { + dMatrix3 RI; + dRSetIdentity (RI); + const dReal ss[3] = {0.02,0.02,0.02}; + for (i=0; i<numc; i++) { + dJointID c = dJointCreateContact (world,contactgroup,contact+i); + dJointAttach (c,b1,b2); + if (show_contacts) dsDrawBox (contact[i].geom.pos,RI,ss); + } + } +} + + +// start simulation - set viewpoint + +static void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + static float xyz[3] = {2.1640f,-1.3079f,1.7600f}; + static float hpr[3] = {125.5000f,-17.0000f,0.0000f}; + dsSetViewpoint (xyz,hpr); + printf ("To drop another object, press:\n"); + printf (" b for box.\n"); + printf (" s for sphere.\n"); + printf (" y for cylinder.\n"); + printf (" c for capsule.\n"); + printf (" x for a composite object.\n"); + printf (" v for a convex object.\n"); + printf (" m for a trimesh.\n"); + printf ("To select an object, press space.\n"); + printf ("To disable the selected object, press d.\n"); + printf ("To enable the selected object, press e.\n"); + printf ("To toggle showing the geom AABBs, press a.\n"); + printf ("To toggle showing the contact points, press t.\n"); + printf ("To toggle dropping from random position/orientation, press r.\n"); +} + + +char locase (char c) +{ + if (c >= 'A' && c <= 'Z') return c - ('a'-'A'); + else return c; +} + + +// called when a key pressed + +static void command (int cmd) +{ + int i,j,k; + dReal sides[3]; + dMass m; + bool setBody = false; + + cmd = locase (cmd); + if (cmd == 'b' || cmd == 's' || cmd == 'c' || cmd == 'x' || cmd == 'm' || cmd == 'y' || cmd == 'v') { + if (num < NUM) { + i = num; + num++; + } + else { + i = nextobj; + nextobj++; + if (nextobj >= num) nextobj = 0; + + // destroy the body and geoms for slot i + dBodyDestroy (obj[i].body); + for (k=0; k < GPB; k++) { + if (obj[i].geom[k]) dGeomDestroy (obj[i].geom[k]); + } + memset (&obj[i],0,sizeof(obj[i])); + } + + obj[i].body = dBodyCreate (world); + for (k=0; k<3; k++) sides[k] = dRandReal()*0.5+0.1; + + dMatrix3 R; + if (random_pos) { + dBodySetPosition (obj[i].body, + dRandReal()*2-1,dRandReal()*2-1,dRandReal()+3); + dRFromAxisAndAngle (R,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, + dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); + } + else { + dReal maxheight = 0; + for (k=0; k<num; k++) { + const dReal *pos = dBodyGetPosition (obj[k].body); + if (pos[2] > maxheight) maxheight = pos[2]; + } + dBodySetPosition (obj[i].body, 0,0,maxheight+1); + dRFromAxisAndAngle (R,0,0,1,dRandReal()*10.0-5.0); + } + dBodySetRotation (obj[i].body,R); + dBodySetData (obj[i].body,(void*)(dsizeint)i); + + if (cmd == 'b') { + dMassSetBox (&m,DENSITY,sides[0],sides[1],sides[2]); + obj[i].geom[0] = dCreateBox (space,sides[0],sides[1],sides[2]); + } + else if (cmd == 'c') { + sides[0] *= 0.5; + dMassSetCapsule (&m,DENSITY,3,sides[0],sides[1]); + obj[i].geom[0] = dCreateCapsule (space,sides[0],sides[1]); + } else if (cmd == 'v') { + + dMassSetBox (&m,DENSITY,0.25,0.25,0.25); + obj[i].geom[0] = dCreateConvex(space, + planes, + planecount, + points, + pointcount, + polygons); + } + else if (cmd == 'y') { + sides[1] *= 0.5; + dMassSetCylinder (&m,DENSITY,3,sides[0],sides[1]); + obj[i].geom[0] = dCreateCylinder (space,sides[0],sides[1]); + } + else if (cmd == 's') { + sides[0] *= 0.5; + dMassSetSphere (&m,DENSITY,sides[0]); + obj[i].geom[0] = dCreateSphere (space,sides[0]); + } + else if (cmd == 'm') { + dTriMeshDataID new_tmdata = dGeomTriMeshDataCreate(); + dGeomTriMeshDataBuildSingle(new_tmdata, &Vertices[0], 3 * sizeof(float), VertexCount, + (dTriIndex*)&Indices[0], IndexCount, 3 * sizeof(dTriIndex)); + dGeomTriMeshDataPreprocess2(new_tmdata, (1U << dTRIDATAPREPROCESS_BUILD_FACE_ANGLES), NULL); + + + obj[i].geom[0] = dCreateTriMesh(space, new_tmdata, 0, 0, 0); + + // remember the mesh's dTriMeshDataID on its userdata for convenience. + dGeomSetData(obj[i].geom[0], new_tmdata); + + dMassSetTrimesh( &m, DENSITY, obj[i].geom[0] ); + printf("mass at %f %f %f\n", m.c[0], m.c[1], m.c[2]); + dGeomSetPosition(obj[i].geom[0], -m.c[0], -m.c[1], -m.c[2]); + dMassTranslate(&m, -m.c[0], -m.c[1], -m.c[2]); + } + else if (cmd == 'x') { + + setBody = true; + // start accumulating masses for the composite geometries + dMass m2; + dMassSetZero (&m); + + dReal dpos[GPB][3]; // delta-positions for composite geometries + dMatrix3 drot[GPB]; + + // set random delta positions + for (j=0; j<GPB; j++) + for (k=0; k<3; k++) + dpos[j][k] = dRandReal()*0.3-0.15; + + for (k=0; k<GPB; k++) { + if (k==0) { + dReal radius = dRandReal()*0.25+0.05; + obj[i].geom[k] = dCreateSphere (space,radius); + dMassSetSphere (&m2,DENSITY,radius); + } else if (k==1) { + obj[i].geom[k] = dCreateBox(space,sides[0],sides[1],sides[2]); + dMassSetBox(&m2,DENSITY,sides[0],sides[1],sides[2]); + } else { + dReal radius = dRandReal()*0.1+0.05; + dReal length = dRandReal()*1.0+0.1; + obj[i].geom[k] = dCreateCapsule(space,radius,length); + dMassSetCapsule(&m2,DENSITY,3,radius,length); + } + + dRFromAxisAndAngle(drot[k],dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, + dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); + dMassRotate(&m2,drot[k]); + + dMassTranslate(&m2,dpos[k][0],dpos[k][1],dpos[k][2]); + + // add to the total mass + dMassAdd(&m,&m2); + + } + for (k=0; k<GPB; k++) { + dGeomSetBody(obj[i].geom[k],obj[i].body); + dGeomSetOffsetPosition(obj[i].geom[k], + dpos[k][0]-m.c[0], + dpos[k][1]-m.c[1], + dpos[k][2]-m.c[2]); + dGeomSetOffsetRotation(obj[i].geom[k], drot[k]); + } + dMassTranslate(&m,-m.c[0],-m.c[1],-m.c[2]); + dBodySetMass(obj[i].body,&m); + + } + + if (!setBody) { // avoid calling for composite geometries + for (k=0; k < GPB; k++) + if (obj[i].geom[k]) + dGeomSetBody(obj[i].geom[k],obj[i].body); + + dBodySetMass(obj[i].body,&m); + } + } + + if (cmd == ' ') { + selected++; + if (selected >= num) selected = 0; + if (selected < 0) selected = 0; + } + else if (cmd == 'd' && selected >= 0 && selected < num) { + dBodyDisable (obj[selected].body); + } + else if (cmd == 'e' && selected >= 0 && selected < num) { + dBodyEnable (obj[selected].body); + } + else if (cmd == 'a') { + show_aabb ^= 1; + } + else if (cmd == 't') { + show_contacts ^= 1; + } + else if (cmd == 'r') { + random_pos ^= 1; + } +} + + +// draw a geom + +void drawGeom (dGeomID g, const dReal *pos, const dReal *R, int show_aabb) +{ + if (!g) return; + if (!pos) pos = dGeomGetPosition (g); + if (!R) R = dGeomGetRotation (g); + + int type = dGeomGetClass (g); + if (type == dBoxClass) { + dVector3 sides; + dGeomBoxGetLengths (g,sides); + dsDrawBox (pos,R,sides); + } + else if (type == dSphereClass) { + dsDrawSphere (pos,R,dGeomSphereGetRadius (g)); + } + else if (type == dCapsuleClass) { + dReal radius,length; + dGeomCapsuleGetParams (g,&radius,&length); + dsDrawCapsule (pos,R,length,radius); + } + else if (type == dCylinderClass) { + dReal radius,length; + dGeomCylinderGetParams (g,&radius,&length); + dsDrawCylinder (pos,R,length,radius); + } else if (type == dConvexClass) { + //dVector3 sides={0.50,0.50,0.50}; + dsDrawConvex(pos,R,planes, + planecount, + points, + pointcount, + polygons); + } + + if (show_aabb) { + // draw the bounding box for this geom + dReal aabb[6]; + dGeomGetAABB (g,aabb); + dVector3 bbpos; + for (int i=0; i<3; i++) bbpos[i] = 0.5*(aabb[i*2] + aabb[i*2+1]); + dVector3 bbsides; + for (int j=0; j<3; j++) bbsides[j] = aabb[j*2+1] - aabb[j*2]; + dMatrix3 RI; + dRSetIdentity (RI); + dsSetColorAlpha (1,0,0,0.5); + dsDrawBox (bbpos,RI,bbsides); + } +} + + +// set previous transformation matrix for trimesh +void setCurrentTransform(dGeomID geom) +{ + const dReal* Pos = dGeomGetPosition(geom); + const dReal* Rot = dGeomGetRotation(geom); + + const dReal Transform[16] = + { + Rot[0], Rot[4], Rot[8], 0, + Rot[1], Rot[5], Rot[9], 0, + Rot[2], Rot[6], Rot[10], 0, + Pos[0], Pos[1], Pos[2], 1 + }; + + dGeomTriMeshSetLastTransform( geom, *(dMatrix4*)(&Transform) ); + +} + + +// simulation loop + +static void simLoop (int pause) +{ + dsSetColor (0,0,2); + dSpaceCollide (space,0,&nearCallback); + + +#if 1 + // What is this for??? - Bram + if (!pause) + { + for (int i=0; i<num; i++) + for (int j=0; j < GPB; j++) + if (obj[i].geom[j]) + if (dGeomGetClass(obj[i].geom[j]) == dTriMeshClass) + setCurrentTransform(obj[i].geom[j]); + + setCurrentTransform(TriMesh1); + setCurrentTransform(TriMesh2); + } +#endif + + //if (!pause) dWorldStep (world,0.05); + if (!pause) dWorldQuickStep (world,0.05); + + for (int j = 0; j < dSpaceGetNumGeoms(space); j++){ + dSpaceGetGeom(space, j); + } + + // remove all contact joints + dJointGroupEmpty (contactgroup); + + dsSetColor (1,1,0); + dsSetTexture (DS_WOOD); + for (int i=0; i<num; i++) { + for (int j=0; j < GPB; j++) { + if (obj[i].geom[j]) { + if (i==selected) { + dsSetColor (0,0.7,1); + } + else if (! dBodyIsEnabled (obj[i].body)) { + dsSetColor (1,0,0); + } + else { + dsSetColor (1,1,0); + } + + if (dGeomGetClass(obj[i].geom[j]) == dTriMeshClass) { + dTriIndex* Indices = (dTriIndex*)::Indices; + + // assume all trimeshes are drawn as bunnies + const dReal* Pos = dGeomGetPosition(obj[i].geom[j]); + const dReal* Rot = dGeomGetRotation(obj[i].geom[j]); + + for (int ii = 0; ii < IndexCount / 3; ii++) { + const dReal v[9] = { // explicit conversion from float to dReal + Vertices[Indices[ii * 3 + 0] * 3 + 0], + Vertices[Indices[ii * 3 + 0] * 3 + 1], + Vertices[Indices[ii * 3 + 0] * 3 + 2], + Vertices[Indices[ii * 3 + 1] * 3 + 0], + Vertices[Indices[ii * 3 + 1] * 3 + 1], + Vertices[Indices[ii * 3 + 1] * 3 + 2], + Vertices[Indices[ii * 3 + 2] * 3 + 0], + Vertices[Indices[ii * 3 + 2] * 3 + 1], + Vertices[Indices[ii * 3 + 2] * 3 + 2] + }; + dsDrawTriangle(Pos, Rot, &v[0], &v[3], &v[6], 1); + } + + // tell the tri-tri collider the current transform of the trimesh -- + // this is fairly important for good results. + + // Fill in the (4x4) matrix. + dReal* p_matrix = obj[i].matrix_dblbuff + ( obj[i].last_matrix_index * 16 ); + + p_matrix[ 0 ] = Rot[ 0 ]; p_matrix[ 1 ] = Rot[ 1 ]; p_matrix[ 2 ] = Rot[ 2 ]; p_matrix[ 3 ] = 0; + p_matrix[ 4 ] = Rot[ 4 ]; p_matrix[ 5 ] = Rot[ 5 ]; p_matrix[ 6 ] = Rot[ 6 ]; p_matrix[ 7 ] = 0; + p_matrix[ 8 ] = Rot[ 8 ]; p_matrix[ 9 ] = Rot[ 9 ]; p_matrix[10 ] = Rot[10 ]; p_matrix[11 ] = 0; + p_matrix[12 ] = Pos[ 0 ]; p_matrix[13 ] = Pos[ 1 ]; p_matrix[14 ] = Pos[ 2 ]; p_matrix[15 ] = 1; + + // Flip to other matrix. + obj[i].last_matrix_index = !obj[i].last_matrix_index; + + dGeomTriMeshSetLastTransform( obj[i].geom[j], + *(dMatrix4*)( obj[i].matrix_dblbuff + obj[i].last_matrix_index * 16 ) ); + + } else { + drawGeom (obj[i].geom[j],0,0,show_aabb); + } + } + } + } + + dTriIndex* Indices = (dTriIndex*)::Indices; + + {const dReal* Pos = dGeomGetPosition(TriMesh1); + const dReal* Rot = dGeomGetRotation(TriMesh1); + + {for (int i = 0; i < IndexCount / 3; i++){ + const dReal v[9] = { // explicit conversion from float to dReal + Vertices[Indices[i * 3 + 0] * 3 + 0], + Vertices[Indices[i * 3 + 0] * 3 + 1], + Vertices[Indices[i * 3 + 0] * 3 + 2], + Vertices[Indices[i * 3 + 1] * 3 + 0], + Vertices[Indices[i * 3 + 1] * 3 + 1], + Vertices[Indices[i * 3 + 1] * 3 + 2], + Vertices[Indices[i * 3 + 2] * 3 + 0], + Vertices[Indices[i * 3 + 2] * 3 + 1], + Vertices[Indices[i * 3 + 2] * 3 + 2] + }; + dsDrawTriangle(Pos, Rot, &v[0], &v[3], &v[6], 0); + }}} + + {const dReal* Pos = dGeomGetPosition(TriMesh2); + const dReal* Rot = dGeomGetRotation(TriMesh2); + + {for (int i = 0; i < IndexCount / 3; i++){ + const dReal v[9] = { // explicit conversion from float to dReal + Vertices[Indices[i * 3 + 0] * 3 + 0], + Vertices[Indices[i * 3 + 0] * 3 + 1], + Vertices[Indices[i * 3 + 0] * 3 + 2], + Vertices[Indices[i * 3 + 1] * 3 + 0], + Vertices[Indices[i * 3 + 1] * 3 + 1], + Vertices[Indices[i * 3 + 1] * 3 + 2], + Vertices[Indices[i * 3 + 2] * 3 + 0], + Vertices[Indices[i * 3 + 2] * 3 + 1], + Vertices[Indices[i * 3 + 2] * 3 + 2] + }; + dsDrawTriangle(Pos, Rot, &v[0], &v[3], &v[6], 1); + }}} +} + + +int main (int argc, char **argv) +{ + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + // create world + dInitODE2(0); + world = dWorldCreate(); + + space = dSimpleSpaceCreate(0); + contactgroup = dJointGroupCreate (0); + dWorldSetGravity (world,0,0,-0.5); + dWorldSetCFM (world,1e-5); + dCreatePlane (space,0,0,1,0); + memset (obj,0,sizeof(obj)); + + // note: can't share tridata if intending to trimesh-trimesh collide + const unsigned preprocessFlags = (1U << dTRIDATAPREPROCESS_BUILD_CONCAVE_EDGES) | (1U << dTRIDATAPREPROCESS_BUILD_FACE_ANGLES); + TriData1 = dGeomTriMeshDataCreate(); + dGeomTriMeshDataBuildSingle(TriData1, &Vertices[0], 3 * sizeof(float), VertexCount, (dTriIndex*)&Indices[0], IndexCount, 3 * sizeof(dTriIndex)); + dGeomTriMeshDataPreprocess2(TriData1, preprocessFlags, NULL); + TriData2 = dGeomTriMeshDataCreate(); + dGeomTriMeshDataBuildSingle(TriData2, &Vertices[0], 3 * sizeof(float), VertexCount, (dTriIndex*)&Indices[0], IndexCount, 3 * sizeof(dTriIndex)); + dGeomTriMeshDataPreprocess2(TriData2, preprocessFlags, NULL); + + TriMesh1 = dCreateTriMesh(space, TriData1, 0, 0, 0); + TriMesh2 = dCreateTriMesh(space, TriData2, 0, 0, 0); + dGeomSetData(TriMesh1, TriData1); + dGeomSetData(TriMesh2, TriData2); + + {dGeomSetPosition(TriMesh1, 0, 0, 0.9); + dMatrix3 Rotation; + dRFromAxisAndAngle(Rotation, 1, 0, 0, M_PI / 2); + dGeomSetRotation(TriMesh1, Rotation);} + + {dGeomSetPosition(TriMesh2, 1, 0, 0.9); + dMatrix3 Rotation; + dRFromAxisAndAngle(Rotation, 1, 0, 0, M_PI / 2); + dGeomSetRotation(TriMesh2, Rotation);} + + dThreadingImplementationID threading = dThreadingAllocateMultiThreadedImplementation(); + dThreadingThreadPoolID pool = dThreadingAllocateThreadPool(4, 0, dAllocateFlagBasicData, NULL); + dThreadingThreadPoolServeMultiThreadedImplementation(pool, threading); + // dWorldSetStepIslandsProcessingMaxThreadCount(world, 1); + dWorldSetStepThreadingImplementation(world, dThreadingImplementationGetFunctions(threading), threading); + + // run simulation + dsSimulationLoop (argc,argv,352,288,&fn); + + dThreadingImplementationShutdownProcessing(threading); + dThreadingFreeThreadPool(pool); + dWorldSetStepThreadingImplementation(world, NULL, NULL); + dThreadingFreeImplementation(threading); + + dJointGroupDestroy (contactgroup); + dSpaceDestroy (space); + dWorldDestroy (world); + dCloseODE(); + return 0; +} diff --git a/libs/ode-0.16.1/ode/demo/demo_ode.cpp b/libs/ode-0.16.1/ode/demo/demo_ode.cpp new file mode 100644 index 0000000..ead9338 --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_ode.cpp @@ -0,0 +1,1380 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <setjmp.h> +#include <ode/ode.h> + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + +//**************************************************************************** +// matrix sizes + +#define dALIGN_SIZE(buf_size, alignment) (((buf_size) + (alignment - 1)) & (int)(~(alignment - 1))) // Casting the mask to int ensures sign-extension to larger integer sizes +#define dALIGN_PTR(buf_ptr, alignment) ((void *)(((duintptr)(buf_ptr) + ((alignment) - 1)) & (int)(~(alignment - 1)))) // Casting the mask to int ensures sign-extension to larger integer sizes + +#define MSIZE 21 +#define MSIZE4 dALIGN_SIZE(MSIZE, 4) // MSIZE rounded up to 4 + + + +//**************************************************************************** +// matrix accessors + +#define _A(i,j) A[(i)*4+(j)] +#define _I(i,j) I[(i)*4+(j)] +#define _R(i,j) R[(i)*4+(j)] + +//**************************************************************************** +// tolerances + +#ifdef dDOUBLE +const double tol = 1e-10; +#endif + +#ifdef dSINGLE +const double tol = 1e-5; +#endif + +//**************************************************************************** +// misc messages and error handling + +#ifdef __GNUC__ +#define HEADER printf ("%s()\n", __FUNCTION__); +#else +#define HEADER printf ("%s:%d\n",__FILE__,__LINE__); +#endif + +static jmp_buf jump_buffer; + + +void myMessageFunction (int num, const char *msg, va_list ap) +{ + printf ("(Message %d: ",num); + vprintf (msg,ap); + printf (")"); + dSetMessageHandler (0); + longjmp (jump_buffer,1); +} + + +#define TRAP_MESSAGE(do,ifnomsg,ifmsg) \ + dSetMessageHandler (&myMessageFunction); \ + if (setjmp (jump_buffer)) { \ + dSetMessageHandler (0); \ + ifmsg ; \ + } \ + else { \ + dSetMessageHandler (&myMessageFunction); \ + do ; \ + ifnomsg ; \ + } \ + dSetMessageHandler (0); + +//**************************************************************************** +// utility stuff + +// compare two numbers, within a threshhold, return 1 if approx equal + +int cmp (dReal a, dReal b) +{ + return (fabs(a-b) < tol); +} + +//**************************************************************************** +// matrix utility stuff + +// compare a 3x3 matrix with the identity + +int cmpIdentityMat3 (dMatrix3 A) +{ + return + (cmp(_A(0,0),1.0) && cmp(_A(0,1),0.0) && cmp(_A(0,2),0.0) && + cmp(_A(1,0),0.0) && cmp(_A(1,1),1.0) && cmp(_A(1,2),0.0) && + cmp(_A(2,0),0.0) && cmp(_A(2,1),0.0) && cmp(_A(2,2),1.0)); +} + + +// transpose a 3x3 matrix in-line + +void transpose3x3 (dMatrix3 A) +{ + dReal tmp; + tmp=A[4]; A[4]=A[1]; A[1]=tmp; + tmp=A[8]; A[8]=A[2]; A[2]=tmp; + tmp=A[9]; A[9]=A[6]; A[6]=tmp; +} + +//**************************************************************************** +// test miscellaneous math functions + +void testRandomNumberGenerator() +{ + HEADER; + if (dTestRand()) printf ("\tpassed\n"); + else printf ("\tFAILED\n"); +} + + +void testInfinity() +{ + HEADER; + if (1e10 < dInfinity && -1e10 > -dInfinity && -dInfinity < dInfinity) + printf ("\tpassed\n"); + else printf ("\tFAILED\n"); +} + + +void testPad() +{ + HEADER; + char s[100]; + s[0]=0; + for (int i=0; i<=16; i++) sprintf (s+strlen(s),"%d ",dPAD(i)); + printf ("\t%s\n", strcmp(s,"0 1 4 4 4 8 8 8 8 12 12 12 12 16 16 16 16 ") ? + "FAILED" : "passed"); +} + + +void testCrossProduct() +{ + HEADER; + + dVector3 a1,a2,b,c; + dMatrix3 B; + dMakeRandomVector (b,3,1.0); + dMakeRandomVector (c,3,1.0); + + dCalcVectorCross3(a1,b,c); + + dSetZero (B,12); + dSetCrossMatrixPlus(B,b,4); + dMultiply0 (a2,B,c,3,3,1); + + dReal diff = dMaxDifference(a1,a2,3,1); + printf ("\t%s\n", diff > tol ? "FAILED" : "passed"); +} + + +void testSetZero() +{ + HEADER; + dReal a[100]; + dMakeRandomVector (a,100,1.0); + dSetZero (a,100); + for (int i=0; i<100; i++) if (a[i] != 0.0) { + printf ("\tFAILED\n"); + return; + } + printf ("\tpassed\n"); +} + + +void testNormalize3() +{ + HEADER; + int i,j,bad=0; + dVector3 n1,n2; + for (i=0; i<1000; i++) { + dMakeRandomVector (n1,3,1.0); + for (j=0; j<3; j++) n2[j]=n1[j]; + dNormalize3 (n2); + if (dFabs(dCalcVectorDot3(n2,n2) - 1.0) > tol) bad |= 1; + if (dFabs(n2[0]/n1[0] - n2[1]/n1[1]) > tol) bad |= 2; + if (dFabs(n2[0]/n1[0] - n2[2]/n1[2]) > tol) bad |= 4; + if (dFabs(n2[1]/n1[1] - n2[2]/n1[2]) > tol) bad |= 8; + if (dFabs(dCalcVectorDot3(n2,n1) - dSqrt(dCalcVectorDot3(n1,n1))) > tol) bad |= 16; + if (bad) { + printf ("\tFAILED (code=%x)\n",bad); + return; + } + } + printf ("\tpassed\n"); +} + + +/* +void testReorthonormalize() +{ +HEADER; +dMatrix3 R,I; +dMakeRandomMatrix (R,3,3,1.0); +for (int i=0; i<30; i++) dReorthonormalize (R); +dMultiply2 (I,R,R,3,3,3); +printf ("\t%s\n",cmpIdentityMat3 (I) ? "passed" : "FAILED"); +} +*/ + + +void testPlaneSpace() +{ + HEADER; + dVector3 n,p,q; + int bad = 0; + for (int i=0; i<1000; i++) { + dMakeRandomVector (n,3,1.0); + dNormalize3 (n); + dPlaneSpace (n,p,q); + if (fabs(dCalcVectorDot3(n,p)) > tol) bad = 1; + if (fabs(dCalcVectorDot3(n,q)) > tol) bad = 1; + if (fabs(dCalcVectorDot3(p,q)) > tol) bad = 1; + if (fabs(dCalcVectorDot3(p,p)-1) > tol) bad = 1; + if (fabs(dCalcVectorDot3(q,q)-1) > tol) bad = 1; + } + printf ("\t%s\n", bad ? "FAILED" : "passed"); +} + +//**************************************************************************** +// test matrix functions + +void testMatrixMultiply() +{ + // A is 2x3, B is 3x4, B2 is B except stored columnwise, C is 2x4 + dReal A[8],B[12],A2[12],B2[16],C[8]; + int i; + + HEADER; + dSetZero (A,8); + for (i=0; i<3; i++) A[i] = i+2; + for (i=0; i<3; i++) A[i+4] = i+3+2; + for (i=0; i<12; i++) B[i] = i+8; + dSetZero (A2,12); + for (i=0; i<6; i++) A2[i+2*(i/2)] = A[i+i/3]; + dSetZero (B2,16); + for (i=0; i<12; i++) B2[i+i/3] = B[i]; + + dMultiply0 (C,A,B,2,3,4); + if (C[0] != 116 || C[1] != 125 || C[2] != 134 || C[3] != 143 || + C[4] != 224 || C[5] != 242 || C[6] != 260 || C[7] != 278) + printf ("\tFAILED (1)\n"); else printf ("\tpassed (1)\n"); + + dMultiply1 (C,A2,B,2,3,4); + if (C[0] != 160 || C[1] != 172 || C[2] != 184 || C[3] != 196 || + C[4] != 196 || C[5] != 211 || C[6] != 226 || C[7] != 241) + printf ("\tFAILED (2)\n"); else printf ("\tpassed (2)\n"); + + dMultiply2 (C,A,B2,2,3,4); + if (C[0] != 83 || C[1] != 110 || C[2] != 137 || C[3] != 164 || + C[4] != 164 || C[5] != 218 || C[6] != 272 || C[7] != 326) + printf ("\tFAILED (3)\n"); else printf ("\tpassed (3)\n"); +} + + +void testSmallMatrixMultiply() +{ + dMatrix3 A,B,C,A2; + dVector3 a,a2,x; + + HEADER; + dMakeRandomMatrix (A,3,3,1.0); + dMakeRandomMatrix (B,3,3,1.0); + dMakeRandomMatrix (C,3,3,1.0); + dMakeRandomMatrix (x,3,1,1.0); + + // dMultiply0_331() + dMultiply0_331 (a,B,x); + dMultiply0 (a2,B,x,3,3,1); + printf ("\t%s (1)\n",(dMaxDifference (a,a2,3,1) > tol) ? "FAILED" : + "passed"); + + // dMultiply1_331() + dMultiply1_331 (a,B,x); + dMultiply1 (a2,B,x,3,3,1); + printf ("\t%s (2)\n",(dMaxDifference (a,a2,3,1) > tol) ? "FAILED" : + "passed"); + + // dMultiply0_133 + dMultiply0_133 (a,x,B); + dMultiply0 (a2,x,B,1,3,3); + printf ("\t%s (3)\n",(dMaxDifference (a,a2,1,3) > tol) ? "FAILED" : + "passed"); + + // dMultiply0_333() + dMultiply0_333 (A,B,C); + dMultiply0 (A2,B,C,3,3,3); + printf ("\t%s (4)\n",(dMaxDifference (A,A2,3,3) > tol) ? "FAILED" : + "passed"); + + // dMultiply1_333() + dMultiply1_333 (A,B,C); + dMultiply1 (A2,B,C,3,3,3); + printf ("\t%s (5)\n",(dMaxDifference (A,A2,3,3) > tol) ? "FAILED" : + "passed"); + + // dMultiply2_333() + dMultiply2_333 (A,B,C); + dMultiply2 (A2,B,C,3,3,3); + printf ("\t%s (6)\n",(dMaxDifference (A,A2,3,3) > tol) ? "FAILED" : + "passed"); +} + + +void testCholeskyFactorization() +{ + dsizeint matrixSize = sizeof(dReal) * MSIZE4 * MSIZE; + dReal *A = (dReal *)dAlloc(matrixSize), *B = (dReal *)dAlloc(matrixSize), *C = (dReal *)dAlloc(matrixSize), diff; + + HEADER; + dMakeRandomMatrix (A,MSIZE,MSIZE,1.0); + dMultiply2 (B,A,A,MSIZE,MSIZE,MSIZE); + memcpy (A,B,MSIZE4*MSIZE*sizeof(dReal)); + if (dFactorCholesky (B,MSIZE)) printf ("\tpassed (1)\n"); + else printf ("\tFAILED (1)\n"); + dClearUpperTriangle (B,MSIZE); + dMultiply2 (C,B,B,MSIZE,MSIZE,MSIZE); + diff = dMaxDifference(A,C,MSIZE,MSIZE); + printf ("\tmaximum difference = %.6e - %s (2)\n",diff, + diff > tol ? "FAILED" : "passed"); + + dFree(C, matrixSize); + dFree(B, matrixSize); + dFree(A, matrixSize); +} + + +void testCholeskySolve() +{ + dsizeint matrixSize = sizeof(dReal) * MSIZE4 * MSIZE, vectorSize = sizeof(dReal) * MSIZE; + dReal *A = (dReal *)dAlloc(matrixSize), *L = (dReal *)dAlloc(matrixSize); + dReal *b = (dReal *)dAlloc(vectorSize), *x = (dReal *)dAlloc(vectorSize), *btest = (dReal *)dAlloc(vectorSize), diff; + + HEADER; + + // get A,L = PD matrix + dMakeRandomMatrix (A,MSIZE,MSIZE,1.0); + dMultiply2 (L,A,A,MSIZE,MSIZE,MSIZE); + memcpy (A,L,MSIZE4*MSIZE*sizeof(dReal)); + + // get b,x = right hand side + dMakeRandomMatrix (b,MSIZE,1,1.0); + memcpy (x,b,MSIZE*sizeof(dReal)); + + // factor L + if (dFactorCholesky (L,MSIZE)) printf ("\tpassed (1)\n"); + else printf ("\tFAILED (1)\n"); + dClearUpperTriangle (L,MSIZE); + + // solve A*x = b + dSolveCholesky (L,x,MSIZE); + + // compute A*x and compare it with b + dMultiply2 (btest,A,x,MSIZE,MSIZE,1); + diff = dMaxDifference(b,btest,MSIZE,1); + printf ("\tmaximum difference = %.6e - %s (2)\n",diff, + diff > tol ? "FAILED" : "passed"); + + dFree(btest, vectorSize); + dFree(x, vectorSize); + dFree(b, vectorSize); + dFree(L, matrixSize); + dFree(A, matrixSize); +} + + +void testInvertPDMatrix() +{ + int i,j,ok; + dsizeint matrixSize = sizeof(dReal) * MSIZE4 * MSIZE; + dReal *A = (dReal *)dAlloc(matrixSize), *Ainv = (dReal *)dAlloc(matrixSize), *I = (dReal *)dAlloc(matrixSize); + + HEADER; + + dMakeRandomMatrix (A,MSIZE,MSIZE,1.0); + dMultiply2 (Ainv,A,A,MSIZE,MSIZE,MSIZE); + memcpy (A,Ainv,MSIZE4*MSIZE*sizeof(dReal)); + dSetZero (Ainv,MSIZE4*MSIZE); + + if (dInvertPDMatrix (A,Ainv,MSIZE)) + printf ("\tpassed (1)\n"); else printf ("\tFAILED (1)\n"); + dMultiply0 (I,A,Ainv,MSIZE,MSIZE,MSIZE); + + // compare with identity + ok = 1; + for (i=0; i<MSIZE; i++) { + for (j=0; j<MSIZE; j++) { + if (i != j) if (cmp (I[i*MSIZE4+j],0.0)==0) ok = 0; + } + } + for (i=0; i<MSIZE; i++) { + if (cmp (I[i*MSIZE4+i],1.0)==0) ok = 0; + } + if (ok) printf ("\tpassed (2)\n"); else printf ("\tFAILED (2)\n"); + + dFree(I, matrixSize); + dFree(Ainv, matrixSize); + dFree(A, matrixSize); +} + + +void testIsPositiveDefinite() +{ + dsizeint matrixSize = sizeof(dReal) * MSIZE4 * MSIZE; + dReal *A = (dReal *)dAlloc(matrixSize), *B = (dReal *)dAlloc(matrixSize); + + HEADER; + + dMakeRandomMatrix (A,MSIZE,MSIZE,1.0); + dMultiply2 (B,A,A,MSIZE,MSIZE,MSIZE); + printf ("\t%s\n",dIsPositiveDefinite(A,MSIZE) ? "FAILED (1)":"passed (1)"); + printf ("\t%s\n",dIsPositiveDefinite(B,MSIZE) ? "passed (2)":"FAILED (2)"); + + dFree(B, matrixSize); + dFree(A, matrixSize); +} + + +void testFastLDLTFactorization() +{ + int i,j; + dsizeint matrixSize = sizeof(dReal) * MSIZE4 * MSIZE, vectorSize = sizeof(dReal) * MSIZE; + dReal *A = (dReal *)dAlloc(matrixSize), *L = (dReal *)dAlloc(matrixSize), *DL = (dReal *)dAlloc(matrixSize), + *ATEST = (dReal *)dAlloc(matrixSize), *d = (dReal *)dAlloc(vectorSize), diff; + + HEADER; + + dMakeRandomMatrix (A,MSIZE,MSIZE,1.0); + dMultiply2 (L,A,A,MSIZE,MSIZE,MSIZE); + memcpy (A,L,MSIZE4*MSIZE*sizeof(dReal)); + + dFactorLDLT (L,d,MSIZE,MSIZE4); + + dClearUpperTriangle (L,MSIZE); + for (i=0; i<MSIZE; i++) L[i*MSIZE4+i] = 1.0; + + dSetZero (DL,MSIZE4*MSIZE); + for (i=0; i<MSIZE; i++) { + for (j=0; j<MSIZE; j++) DL[i*MSIZE4+j] = L[i*MSIZE4+j] / d[j]; + } + + dMultiply2 (ATEST,L,DL,MSIZE,MSIZE,MSIZE); + diff = dMaxDifference(A,ATEST,MSIZE,MSIZE); + printf ("\tmaximum difference = %.6e - %s\n",diff, + diff > tol ? "FAILED" : "passed"); + + dFree(d, vectorSize); + dFree(ATEST, matrixSize); + dFree(DL, matrixSize); + dFree(L, matrixSize); + dFree(A, matrixSize); +} + + +void testCoopLDLTFactorization() +{ + int i,j; + + const dsizeint COOP_MSIZE = MSIZE * 51, COOP_MSIZE4 = dALIGN_SIZE(COOP_MSIZE, 4); + + dsizeint matrixSize = sizeof(dReal) * COOP_MSIZE4 * COOP_MSIZE, vectorSize = sizeof(dReal) * COOP_MSIZE; + dReal *A = (dReal *)dAlloc(matrixSize), *L = (dReal *)dAlloc(matrixSize), *DL = (dReal *)dAlloc(matrixSize), + *ATEST = (dReal *)dAlloc(matrixSize), *d = (dReal *)dAlloc(vectorSize), diff; + + const unsigned threadCountMaximum = 8; + dThreadingImplementationID threading = dThreadingAllocateMultiThreadedImplementation(); + dCooperativeID cooperative = dCooperativeCreate(dThreadingImplementationGetFunctions(threading), threading); + dThreadingThreadPoolID pool = dThreadingAllocateThreadPool(threadCountMaximum, 0, dAllocateFlagBasicData, NULL); + dThreadingThreadPoolServeMultiThreadedImplementation(pool, threading); + + dResourceRequirementsID requirements = dResourceRequirementsCreate(cooperative); + dEstimateCooperativelyFactorLDLTResourceRequirements(requirements, threadCountMaximum, COOP_MSIZE); + dResourceContainerID resources = dResourceContainerAcquire(requirements); + + HEADER; + + for (int pass = 0; pass != 4; ++pass) + { + dTimerStart ("Factoring LDLT"); + + const unsigned allowedThreads = 4; + const unsigned PASS_MSIZE = COOP_MSIZE - pass, PASS_MSIZE4 = dALIGN_SIZE(PASS_MSIZE, 4); + + dTimerNow ("Preparing data"); + dMakeRandomMatrix (L, PASS_MSIZE, PASS_MSIZE, 1.0); + dMultiply2 (A, L, L, PASS_MSIZE, PASS_MSIZE, PASS_MSIZE); + memcpy (L, A, sizeof(dReal) * PASS_MSIZE4 * PASS_MSIZE); + + dTimerNow ("Factoring multi threaded"); + dCooperativelyFactorLDLT (resources, allowedThreads, L, d, PASS_MSIZE, PASS_MSIZE4); + + dTimerNow ("Verifying"); + dClearUpperTriangle (L, PASS_MSIZE); + for (i = 0; i < PASS_MSIZE; i++) L[i * PASS_MSIZE4 + i] = 1.0; + + dSetZero (DL, PASS_MSIZE4 * PASS_MSIZE); + for (i = 0; i < PASS_MSIZE; i++) { + for (j = 0; j < PASS_MSIZE; j++) DL[i * PASS_MSIZE4 + j] = L[i * PASS_MSIZE4 + j] / d[j]; + } + + dMultiply2 (ATEST, L, DL, PASS_MSIZE, PASS_MSIZE, PASS_MSIZE); + diff = dMaxDifference(A, ATEST, PASS_MSIZE, PASS_MSIZE); + printf ("\tN=%u: maximum difference = %.6e - %s\n", PASS_MSIZE, diff, diff > 1e2 * tol ? "FAILED" : "passed"); + + dTimerEnd(); + dTimerReport(stdout, 0); + } + + dResourceContainerDestroy(resources); + dResourceRequirementsDestroy(requirements); + + dThreadingImplementationShutdownProcessing(threading); + dThreadingFreeThreadPool(pool); + dCooperativeDestroy(cooperative); + dThreadingFreeImplementation(threading); + + dFree(d, vectorSize); + dFree(ATEST, matrixSize); + dFree(DL, matrixSize); + dFree(L, matrixSize); + dFree(A, matrixSize); +} + + +void testSolveLDLT() +{ + dsizeint matrixSize = sizeof(dReal) * MSIZE4 * MSIZE, vectorSize = sizeof(dReal) * MSIZE; + dReal *A = (dReal *)dAlloc(matrixSize), *L = (dReal *)dAlloc(matrixSize), + *d = (dReal *)dAlloc(vectorSize), *x = (dReal *)dAlloc(vectorSize), + *b = (dReal *)dAlloc(vectorSize), *btest = (dReal *)dAlloc(vectorSize), diff; + + HEADER; + + dMakeRandomMatrix (A,MSIZE,MSIZE,1.0); + dMultiply2 (L,A,A,MSIZE,MSIZE,MSIZE); + memcpy (A,L,MSIZE4*MSIZE*sizeof(dReal)); + + dMakeRandomMatrix (b,MSIZE,1,1.0); + memcpy (x,b,MSIZE*sizeof(dReal)); + + dFactorLDLT (L,d,MSIZE,MSIZE4); + dSolveLDLT (L,d,x,MSIZE,MSIZE4); + + dMultiply2 (btest,A,x,MSIZE,MSIZE,1); + diff = dMaxDifference(b,btest,MSIZE,1); + printf ("\tmaximum difference = %.6e - %s\n",diff, + diff > tol ? "FAILED" : "passed"); + + dFree(btest, vectorSize); + dFree(b, vectorSize); + dFree(x, vectorSize); + dFree(d, vectorSize); + dFree(L, matrixSize); + dFree(A, matrixSize); +} + +void testCoopSolveLDLT() +{ + const dsizeint COOP_MSIZE = MSIZE * 51, COOP_MSIZE4 = dALIGN_SIZE(COOP_MSIZE, 4); + + dsizeint matrixSize = sizeof(dReal) * COOP_MSIZE4 * COOP_MSIZE, vectorSize = sizeof(dReal) * COOP_MSIZE; + dReal *A = (dReal *)dAlloc(matrixSize), *L = (dReal *)dAlloc(matrixSize), + *d = (dReal *)dAlloc(vectorSize), *x = (dReal *)dAlloc(vectorSize), + *b = (dReal *)dAlloc(vectorSize), *btest = (dReal *)dAlloc(vectorSize), diff; + + const unsigned threadCountMaximum = 8; + dThreadingImplementationID threading = dThreadingAllocateMultiThreadedImplementation(); + dCooperativeID cooperative = dCooperativeCreate(dThreadingImplementationGetFunctions(threading), threading); + dThreadingThreadPoolID pool = dThreadingAllocateThreadPool(threadCountMaximum, 0, dAllocateFlagBasicData, NULL); + dThreadingThreadPoolServeMultiThreadedImplementation(pool, threading); + + dResourceRequirementsID requirements = dResourceRequirementsCreate(cooperative); + dEstimateCooperativelySolveLDLTResourceRequirements(requirements, threadCountMaximum, COOP_MSIZE); + dResourceContainerID resources = dResourceContainerAcquire(requirements); + + HEADER; + + for (int pass = 0; pass != 4; ++pass) + { + dTimerStart ("Solving LDLT"); + + const unsigned allowedThreads = 4; + const unsigned PASS_MSIZE = COOP_MSIZE - pass, PASS_MSIZE4 = dALIGN_SIZE(PASS_MSIZE, 4); + + dTimerNow ("Preparing data"); + dMakeRandomMatrix (b, PASS_MSIZE, 1, 1.0); + + dMakeRandomMatrix (L, PASS_MSIZE, PASS_MSIZE, 1.0); + dMultiply2 (A, L, L, PASS_MSIZE, PASS_MSIZE, PASS_MSIZE); + + memcpy (x, b, PASS_MSIZE * sizeof(dReal)); + memcpy (L, A, sizeof(dReal) * PASS_MSIZE4 * PASS_MSIZE); + + dTimerNow ("Factoring"); + dFactorLDLT (L, d, PASS_MSIZE, PASS_MSIZE4); + + dTimerNow ("Solving multi-threaded"); + dCooperativelySolveLDLT(resources, allowedThreads, L, d, x, PASS_MSIZE, PASS_MSIZE4); + + dTimerNow ("Verifying solution"); + dMultiply2 (btest, A, x, PASS_MSIZE, PASS_MSIZE, 1); + diff = dMaxDifference(b, btest, PASS_MSIZE, 1); + printf ("\tN=%u: maximum difference = %.6e - %s\n", PASS_MSIZE, diff, diff > 1e2 * tol ? "FAILED" : "passed"); + + dTimerEnd(); + dTimerReport(stdout, 0); + } + + dResourceContainerDestroy(resources); + dResourceRequirementsDestroy(requirements); + + dThreadingImplementationShutdownProcessing(threading); + dThreadingFreeThreadPool(pool); + dCooperativeDestroy(cooperative); + dThreadingFreeImplementation(threading); + + dFree(btest, vectorSize); + dFree(b, vectorSize); + dFree(x, vectorSize); + dFree(d, vectorSize); + dFree(L, matrixSize); + dFree(A, matrixSize); +} + + +void testLDLTAddTL() +{ + int i,j; + dsizeint matrixSize = sizeof(dReal) * MSIZE4 * MSIZE, vectorSize = sizeof(dReal) * MSIZE; + dReal *A = (dReal *)dAlloc(matrixSize), *L = (dReal *)dAlloc(matrixSize), + *DL = (dReal *)dAlloc(matrixSize), *ATEST = (dReal *)dAlloc(matrixSize), + *d = (dReal *)dAlloc(vectorSize), *a = (dReal *)dAlloc(vectorSize), diff; + + HEADER; + + dMakeRandomMatrix (A,MSIZE,MSIZE,1.0); + dMultiply2 (L,A,A,MSIZE,MSIZE,MSIZE); + memcpy (A,L,MSIZE4*MSIZE*sizeof(dReal)); + dFactorLDLT (L,d,MSIZE,MSIZE4); + + // delete first row and column of factorization + for (i=0; i<MSIZE; i++) a[i] = -A[i*MSIZE4]; + a[0] += 1; + dLDLTAddTL (L,d,a,MSIZE,MSIZE4); + for (i=1; i<MSIZE; i++) L[i*MSIZE4] = 0; + d[0] = 1; + + // get modified L*D*L' + dClearUpperTriangle (L,MSIZE); + for (i=0; i<MSIZE; i++) L[i*MSIZE4+i] = 1.0; + dSetZero (DL,MSIZE4*MSIZE); + for (i=0; i<MSIZE; i++) { + for (j=0; j<MSIZE; j++) DL[i*MSIZE4+j] = L[i*MSIZE4+j] / d[j]; + } + dMultiply2 (ATEST,L,DL,MSIZE,MSIZE,MSIZE); + + // compare it to A with its first row/column removed + for (i=1; i<MSIZE; i++) A[i*MSIZE4] = A[i] = 0; + A[0] = 1; + diff = dMaxDifference(A,ATEST,MSIZE,MSIZE); + printf ("\tmaximum difference = %.6e - %s\n",diff, + diff > tol ? "FAILED" : "passed"); + + dFree(a, vectorSize); + dFree(d, vectorSize); + dFree(ATEST, matrixSize); + dFree(DL, matrixSize); + dFree(L, matrixSize); + dFree(A, matrixSize); +} + + +void testLDLTRemove() +{ + int i,j,r; + dsizeint intVectorSize = sizeof(int) * MSIZE, matrixSize = sizeof(dReal) * MSIZE4 * MSIZE, vectorSize = sizeof(dReal) * MSIZE; + int *p = (int *)dAlloc(intVectorSize); + dReal *A = (dReal *)dAlloc(matrixSize), *L = (dReal *)dAlloc(matrixSize), + *L2 = (dReal *)dAlloc(matrixSize), *DL2 = (dReal *)dAlloc(matrixSize), + *Atest1 = (dReal *)dAlloc(matrixSize), *Atest2 = (dReal *)dAlloc(matrixSize), + *d = (dReal *)dAlloc(vectorSize), *d2 = (dReal *)dAlloc(vectorSize), diff, maxdiff; + + HEADER; + + // make array of A row pointers + dReal *Arows[MSIZE]; + for (i=0; i<MSIZE; i++) Arows[i] = A+i*MSIZE4; + + // fill permutation vector + for (i=0; i<MSIZE; i++) p[i]=i; + + dMakeRandomMatrix (A,MSIZE,MSIZE,1.0); + dMultiply2 (L,A,A,MSIZE,MSIZE,MSIZE); + memcpy (A,L,MSIZE4*MSIZE*sizeof(dReal)); + dFactorLDLT (L,d,MSIZE,MSIZE4); + + maxdiff = 1e10; + for (r=0; r<MSIZE; r++) { + // get Atest1 = A with row/column r removed + memcpy (Atest1,A,MSIZE4*MSIZE*sizeof(dReal)); + dRemoveRowCol (Atest1,MSIZE,MSIZE4,r); + + // test that the row/column removal worked + int bad = 0; + for (i=0; i<MSIZE; i++) { + for (j=0; j<MSIZE; j++) { + if (i != r && j != r) { + int ii = i; + int jj = j; + if (ii >= r) ii--; + if (jj >= r) jj--; + if (A[i*MSIZE4+j] != Atest1[ii*MSIZE4+jj]) bad = 1; + } + } + } + if (bad) printf ("\trow/col removal FAILED for row %d\n",r); + + // zero out last row/column of Atest1 + for (i=0; i<MSIZE; i++) { + Atest1[(MSIZE-1)*MSIZE4+i] = 0; + Atest1[i*MSIZE4+MSIZE-1] = 0; + } + + // get L2*D2*L2' = adjusted factorization to remove that row + memcpy (L2,L,MSIZE4*MSIZE*sizeof(dReal)); + memcpy (d2,d,MSIZE*sizeof(dReal)); + dLDLTRemove (/*A*/ Arows,p,L2,d2,MSIZE,MSIZE,r,MSIZE4); + + // get Atest2 = L2*D2*L2' + dClearUpperTriangle (L2,MSIZE); + for (i=0; i<(MSIZE-1); i++) L2[i*MSIZE4+i] = 1.0; + for (i=0; i<MSIZE; i++) L2[(MSIZE-1)*MSIZE4+i] = 0; + d2[MSIZE-1] = 1; + dSetZero (DL2,MSIZE4*MSIZE); + for (i=0; i<(MSIZE-1); i++) { + for (j=0; j<MSIZE-1; j++) DL2[i*MSIZE4+j] = L2[i*MSIZE4+j] / d2[j]; + } + + dMultiply2 (Atest2,L2,DL2,MSIZE,MSIZE,MSIZE); + + diff = dMaxDifference(Atest1,Atest2,MSIZE,MSIZE); + if (diff < maxdiff) maxdiff = diff; + + /* + dPrintMatrix (Atest1,MSIZE,MSIZE); + printf ("\n"); + dPrintMatrix (Atest2,MSIZE,MSIZE); + printf ("\n"); + */ + } + printf ("\tmaximum difference = %.6e - %s\n",maxdiff, + maxdiff > tol ? "FAILED" : "passed"); + + dFree(d2, vectorSize); + dFree(d, vectorSize); + dFree(Atest2, matrixSize); + dFree(Atest1, matrixSize); + dFree(DL2, matrixSize); + dFree(L2, matrixSize); + dFree(L, matrixSize); + dFree(A, matrixSize); +} + +//**************************************************************************** +// test mass stuff + +#define NUMP 10 // number of particles + + +void printMassParams (dMass *m) +{ + printf ("mass = %.4f\n",m->mass); + printf ("com = (%.4f,%.4f,%.4f)\n",m->c[0],m->c[1],m->c[2]); + printf ("I = [ %10.4f %10.4f %10.4f ]\n" + " [ %10.4f %10.4f %10.4f ]\n" + " [ %10.4f %10.4f %10.4f ]\n", + m->_I(0,0),m->_I(0,1),m->_I(0,2), + m->_I(1,0),m->_I(1,1),m->_I(1,2), + m->_I(2,0),m->_I(2,1),m->_I(2,2)); +} + + +void compareMassParams (dMass *m1, dMass *m2, const char *msg) +{ + int i,j,ok = 1; + if (!(cmp(m1->mass,m2->mass) && cmp(m1->c[0],m2->c[0]) && + cmp(m1->c[1],m2->c[1]) && cmp(m1->c[2],m2->c[2]))) + ok = 0; + for (i=0; i<3; i++) for (j=0; j<3; j++) + if (cmp (m1->_I(i,j),m2->_I(i,j))==0) ok = 0; + if (ok) printf ("\tpassed (%s)\n",msg); else printf ("\tFAILED (%s)\n",msg); +} + + +// compute the mass parameters of a particle set + +void computeMassParams (dMass *m, dReal q[NUMP][3], dReal pm[NUMP]) +{ + int i,j; + dMassSetZero (m); + for (i=0; i<NUMP; i++) { + m->mass += pm[i]; + for (j=0; j<3; j++) m->c[j] += pm[i]*q[i][j]; + m->_I(0,0) += pm[i]*(q[i][1]*q[i][1] + q[i][2]*q[i][2]); + m->_I(1,1) += pm[i]*(q[i][0]*q[i][0] + q[i][2]*q[i][2]); + m->_I(2,2) += pm[i]*(q[i][0]*q[i][0] + q[i][1]*q[i][1]); + m->_I(0,1) -= pm[i]*(q[i][0]*q[i][1]); + m->_I(0,2) -= pm[i]*(q[i][0]*q[i][2]); + m->_I(1,2) -= pm[i]*(q[i][1]*q[i][2]); + } + for (j=0; j<3; j++) m->c[j] /= m->mass; + m->_I(1,0) = m->_I(0,1); + m->_I(2,0) = m->_I(0,2); + m->_I(2,1) = m->_I(1,2); +} + + +void testMassFunctions() +{ + dMass m; + int i,j; + dReal q[NUMP][3]; // particle positions + dReal pm[NUMP]; // particle masses + dMass m1,m2; + dMatrix3 R; + + HEADER; + + printf ("\t"); + dMassSetZero (&m); + TRAP_MESSAGE (dMassSetParameters (&m,10, 0,0,0, 1,2,3, 4,5,6), + printf (" FAILED (1)\n"), printf (" passed (1)\n")); + + printf ("\t"); + dMassSetZero (&m); + TRAP_MESSAGE (dMassSetParameters (&m,10, 0.1,0.2,0.15, 3,5,14, 3.1,3.2,4), + printf ("passed (2)\n") , printf (" FAILED (2)\n")); + if (m.mass==10 && m.c[0]==REAL(0.1) && m.c[1]==REAL(0.2) && + m.c[2]==REAL(0.15) && m._I(0,0)==3 && m._I(1,1)==5 && m._I(2,2)==14 && + m._I(0,1)==REAL(3.1) && m._I(0,2)==REAL(3.2) && m._I(1,2)==4 && + m._I(1,0)==REAL(3.1) && m._I(2,0)==REAL(3.2) && m._I(2,1)==4) + printf ("\tpassed (3)\n"); else printf ("\tFAILED (3)\n"); + + dMassSetZero (&m); + dMassSetSphere (&m,1.4, 0.86); + if (cmp(m.mass,3.73002719949386) && m.c[0]==0 && m.c[1]==0 && m.c[2]==0 && + cmp(m._I(0,0),1.10349124669826) && + cmp(m._I(1,1),1.10349124669826) && + cmp(m._I(2,2),1.10349124669826) && + m._I(0,1)==0 && m._I(0,2)==0 && m._I(1,2)==0 && + m._I(1,0)==0 && m._I(2,0)==0 && m._I(2,1)==0) + printf ("\tpassed (4)\n"); else printf ("\tFAILED (4)\n"); + + dMassSetZero (&m); + dMassSetCapsule (&m,1.3,1,0.76,1.53); + if (cmp(m.mass,5.99961928996029) && m.c[0]==0 && m.c[1]==0 && m.c[2]==0 && + cmp(m._I(0,0),1.59461986077384) && + cmp(m._I(1,1),4.21878433864904) && + cmp(m._I(2,2),4.21878433864904) && + m._I(0,1)==0 && m._I(0,2)==0 && m._I(1,2)==0 && + m._I(1,0)==0 && m._I(2,0)==0 && m._I(2,1)==0) + printf ("\tpassed (5)\n"); else printf ("\tFAILED (5)\n"); + + dMassSetZero (&m); + dMassSetBox (&m,0.27,3,4,5); + if (cmp(m.mass,16.2) && m.c[0]==0 && m.c[1]==0 && m.c[2]==0 && + cmp(m._I(0,0),55.35) && cmp(m._I(1,1),45.9) && cmp(m._I(2,2),33.75) && + m._I(0,1)==0 && m._I(0,2)==0 && m._I(1,2)==0 && + m._I(1,0)==0 && m._I(2,0)==0 && m._I(2,1)==0) + printf ("\tpassed (6)\n"); else printf ("\tFAILED (6)\n"); + + // test dMassAdjust? + + // make random particles and compute the mass, COM and inertia, then + // translate and repeat. + for (i=0; i<NUMP; i++) { + pm[i] = dRandReal()+0.5; + for (j=0; j<3; j++) { + q[i][j] = 2.0*(dRandReal()-0.5); + } + } + computeMassParams (&m1,q,pm); + memcpy (&m2,&m1,sizeof(dMass)); + dMassTranslate (&m2,1,2,-3); + for (i=0; i<NUMP; i++) { + q[i][0] += 1; + q[i][1] += 2; + q[i][2] -= 3; + } + computeMassParams (&m1,q,pm); + compareMassParams (&m1,&m2,"7"); + + // rotate the masses + _R(0,0) = -0.87919618797635; + _R(0,1) = 0.15278881840384; + _R(0,2) = -0.45129772879842; + _R(1,0) = -0.47307856232664; + _R(1,1) = -0.39258064912909; + _R(1,2) = 0.78871864932708; + _R(2,0) = -0.05666336483842; + _R(2,1) = 0.90693771059546; + _R(2,2) = 0.41743652473765; + dMassRotate (&m2,R); + for (i=0; i<NUMP; i++) { + dReal a[3]; + dMultiply0 (a,&_R(0,0),&q[i][0],3,3,1); + q[i][0] = a[0]; + q[i][1] = a[1]; + q[i][2] = a[2]; + } + computeMassParams (&m1,q,pm); + compareMassParams (&m1,&m2,"8"); +} + +//**************************************************************************** +// test rotation stuff + +void makeRandomRotation (dMatrix3 R) +{ + dReal *u1 = R, *u2=R+4, *u3=R+8; + dMakeRandomVector (u1,3,1.0); + dNormalize3 (u1); + dMakeRandomVector (u2,3,1.0); + dReal d = dCalcVectorDot3(u1,u2); + u2[0] -= d*u1[0]; + u2[1] -= d*u1[1]; + u2[2] -= d*u1[2]; + dNormalize3(u2); + dCalcVectorCross3(u3,u1,u2); +} + + +void testRtoQandQtoR() +{ + HEADER; + dMatrix3 R,I,R2; + dQuaternion q; + int i; + + // test makeRandomRotation() + makeRandomRotation (R); + dMultiply2 (I,R,R,3,3,3); + printf ("\tmakeRandomRotation() - %s (1)\n", + cmpIdentityMat3(I) ? "passed" : "FAILED"); + + // test QtoR() on random normalized quaternions + int ok = 1; + for (i=0; i<100; i++) { + dMakeRandomVector (q,4,1.0); + dNormalize4 (q); + dQtoR (q,R); + dMultiply2 (I,R,R,3,3,3); + if (cmpIdentityMat3(I)==0) ok = 0; + } + printf ("\tQtoR() orthonormality %s (2)\n", ok ? "passed" : "FAILED"); + + // test R -> Q -> R works + dReal maxdiff=0; + for (i=0; i<100; i++) { + makeRandomRotation (R); + dRtoQ (R,q); + dQtoR (q,R2); + dReal diff = dMaxDifference (R,R2,3,3); + if (diff > maxdiff) maxdiff = diff; + } + printf ("\tmaximum difference = %e - %s (3)\n",maxdiff, + (maxdiff > tol) ? "FAILED" : "passed"); +} + + +void testQuaternionMultiply() +{ + HEADER; + dMatrix3 RA,RB,RC,Rtest; + dQuaternion qa,qb,qc; + dReal diff,maxdiff=0; + + for (int i=0; i<100; i++) { + makeRandomRotation (RB); + makeRandomRotation (RC); + dRtoQ (RB,qb); + dRtoQ (RC,qc); + + dMultiply0 (RA,RB,RC,3,3,3); + dQMultiply0 (qa,qb,qc); + dQtoR (qa,Rtest); + diff = dMaxDifference (Rtest,RA,3,3); + if (diff > maxdiff) maxdiff = diff; + + dMultiply1 (RA,RB,RC,3,3,3); + dQMultiply1 (qa,qb,qc); + dQtoR (qa,Rtest); + diff = dMaxDifference (Rtest,RA,3,3); + if (diff > maxdiff) maxdiff = diff; + + dMultiply2 (RA,RB,RC,3,3,3); + dQMultiply2 (qa,qb,qc); + dQtoR (qa,Rtest); + diff = dMaxDifference (Rtest,RA,3,3); + if (diff > maxdiff) maxdiff = diff; + + dMultiply0 (RA,RC,RB,3,3,3); + transpose3x3 (RA); + dQMultiply3 (qa,qb,qc); + dQtoR (qa,Rtest); + diff = dMaxDifference (Rtest,RA,3,3); + if (diff > maxdiff) maxdiff = diff; + } + printf ("\tmaximum difference = %e - %s\n",maxdiff, + (maxdiff > tol) ? "FAILED" : "passed"); +} + + +void testRotationFunctions() +{ + dMatrix3 R1; + HEADER; + + printf ("\tdRSetIdentity - "); + dMakeRandomMatrix (R1,3,3,1.0); + dRSetIdentity (R1); + if (cmpIdentityMat3(R1)) printf ("passed\n"); else printf ("FAILED\n"); + + printf ("\tdRFromAxisAndAngle - "); + + printf ("\n"); + printf ("\tdRFromEulerAngles - "); + + printf ("\n"); + printf ("\tdRFrom2Axes - "); + + printf ("\n"); +} + +//**************************************************************************** + +#include <assert.h> + +template<class T> +class simplevector +{ +private: + int n; + int max; + T* data; + +public: + simplevector() { initialize(); } + ~simplevector() { finalize(); } + T& operator[](int i) { assert(i>=0 && i<n); return data[i]; } + const T& operator[](int i) const { assert(i>=0 && i<n); return data[i]; } + void push_back(const T& elem) + { + if (n == max) + { + max *= 2; + T* newdata = new T[max]; + memcpy(newdata, data, sizeof(T)*n); + delete[] data; + data = newdata; + } + data[n++] = elem; + } + int size() const { return n; } + void clear() { finalize(); initialize(); } + +private: + void finalize() { delete[] data; } + void initialize() { data = new T[32]; max = 32; n = 0; } +}; + +// matrix header on the stack + +class dMatrixComparison { + struct dMatInfo; + simplevector<dMatInfo*> mat; + int afterfirst,index; + +public: + dMatrixComparison(); + ~dMatrixComparison(); + + dReal nextMatrix (dReal *A, int n, int m, int lower_tri, const char *name, ...); + // add a new n*m matrix A to the sequence. the name of the matrix is given + // by the printf-style arguments (name,...). if this is the first sequence + // then this object will simply record the matrices and return 0. + // if this the second or subsequent sequence then this object will compare + // the matrices with the first sequence, and report any differences. + // the matrix error will be returned. if `lower_tri' is 1 then only the + // lower triangle of the matrix (including the diagonal) will be compared + // (the matrix must be square). + + void end(); + // end a sequence. + + void reset(); + // restarts the object, so the next sequence will be the first sequence. + + void dump(); + // print out info about all the matrices in the sequence +}; + +struct dMatrixComparison::dMatInfo { + int n,m; // size of matrix + char name[128]; // name of the matrix + dReal *data; // matrix data + int size; // size of `data' +}; + + + +dMatrixComparison::dMatrixComparison() +{ + afterfirst = 0; + index = 0; +} + + +dMatrixComparison::~dMatrixComparison() +{ + reset(); +} + + +dReal dMatrixComparison::nextMatrix (dReal *A, int n, int m, int lower_tri, + const char *name, ...) +{ + if (A==0 || n < 1 || m < 1 || name==0) dDebug (0,"bad args to nextMatrix"); + int num = n*dPAD(m); + + if (afterfirst==0) { + dMatInfo *mi = (dMatInfo*) dAlloc (sizeof(dMatInfo)); + mi->n = n; + mi->m = m; + mi->size = num * sizeof(dReal); + mi->data = (dReal*) dAlloc (mi->size); + memcpy (mi->data,A,mi->size); + + va_list ap; + va_start (ap,name); + vsprintf (mi->name,name,ap); + va_end (ap); + if (strlen(mi->name) >= sizeof (mi->name)) dDebug (0,"name too long"); + + mat.push_back(mi); + return 0; + } + else { + if (lower_tri && n != m) + dDebug (0,"dMatrixComparison, lower triangular matrix must be square"); + if (index >= mat.size()) dDebug (0,"dMatrixComparison, too many matrices"); + dMatInfo *mp = mat[index]; + index++; + + dMatInfo mi; + va_list ap; + va_start (ap,name); + vsprintf (mi.name,name,ap); + va_end (ap); + if (strlen(mi.name) >= sizeof (mi.name)) dDebug (0,"name too long"); + + if (strcmp(mp->name,mi.name) != 0) + dDebug (0,"dMatrixComparison, name mismatch (\"%s\" and \"%s\")", + mp->name,mi.name); + if (mp->n != n || mp->m != m) + dDebug (0,"dMatrixComparison, size mismatch (%dx%d and %dx%d)", + mp->n,mp->m,n,m); + + dReal maxdiff; + if (lower_tri) { + maxdiff = dMaxDifferenceLowerTriangle (A,mp->data,n); + } + else { + maxdiff = dMaxDifference (A,mp->data,n,m); + } + if (maxdiff > tol) + dDebug (0,"dMatrixComparison, matrix error (size=%dx%d, name=\"%s\", " + "error=%.4e)",n,m,mi.name,maxdiff); + return maxdiff; + } +} + + +void dMatrixComparison::end() +{ + if (mat.size() <= 0) dDebug (0,"no matrices in sequence"); + afterfirst = 1; + index = 0; +} + + +void dMatrixComparison::reset() +{ + for (int i=0; i<mat.size(); i++) { + dFree (mat[i]->data,mat[i]->size); + dFree (mat[i],sizeof(dMatInfo)); + } + mat.clear(); + afterfirst = 0; + index = 0; +} + + +void dMatrixComparison::dump() +{ + for (int i=0; i<mat.size(); i++) + printf ("%d: %s (%dx%d)\n",i,mat[i]->name,mat[i]->n,mat[i]->m); +} + +//**************************************************************************** +// unit test + +#include <setjmp.h> + +// static jmp_buf jump_buffer; + +static void myDebug (int /*num*/, const char* /*msg*/, va_list /*ap*/) +{ + // printf ("(Error %d: ",num); + // vprintf (msg,ap); + // printf (")\n"); + longjmp (jump_buffer,1); +} + + +extern "C" void dTestMatrixComparison() +{ + volatile int i; + printf ("dTestMatrixComparison()\n"); + dMessageFunction *orig_debug = dGetDebugHandler(); + + dMatrixComparison mc; + dReal A[50*50]; + + // make first sequence + unsigned long seed = dRandGetSeed(); + for (i=1; i<49; i++) { + dMakeRandomMatrix (A,i,i+1,1.0); + mc.nextMatrix (A,i,i+1,0,"A%d",i); + } + mc.end(); + + //mc.dump(); + + // test identical sequence + dSetDebugHandler (&myDebug); + dRandSetSeed (seed); + if (setjmp (jump_buffer)) { + printf ("\tFAILED (1)\n"); + } + else { + for (i=1; i<49; i++) { + dMakeRandomMatrix (A,i,i+1,1.0); + mc.nextMatrix (A,i,i+1,0,"A%d",i); + } + mc.end(); + printf ("\tpassed (1)\n"); + } + dSetDebugHandler (orig_debug); + + // test broken sequences (with matrix error) + dRandSetSeed (seed); + volatile int passcount = 0; + for (i=1; i<49; i++) { + if (setjmp (jump_buffer)) { + passcount++; + } + else { + dSetDebugHandler (&myDebug); + dMakeRandomMatrix (A,i,i+1,1.0); + A[(i-1)*dPAD(i+1)+i] += REAL(0.01); + mc.nextMatrix (A,i,i+1,0,"A%d",i); + dSetDebugHandler (orig_debug); + } + } + mc.end(); + printf ("\t%s (2)\n",(passcount == 48) ? "passed" : "FAILED"); + + // test broken sequences (with name error) + dRandSetSeed (seed); + passcount = 0; + for (i=1; i<49; i++) { + if (setjmp (jump_buffer)) { + passcount++; + } + else { + dSetDebugHandler (&myDebug); + dMakeRandomMatrix (A,i,i+1,1.0); + mc.nextMatrix (A,i,i+1,0,"B%d",i); + dSetDebugHandler (orig_debug); + } + } + mc.end(); + printf ("\t%s (3)\n",(passcount == 48) ? "passed" : "FAILED"); + + // test identical sequence again + dSetDebugHandler (&myDebug); + dRandSetSeed (seed); + if (setjmp (jump_buffer)) { + printf ("\tFAILED (4)\n"); + } + else { + for (i=1; i<49; i++) { + dMakeRandomMatrix (A,i,i+1,1.0); + mc.nextMatrix (A,i,i+1,0,"A%d",i); + } + mc.end(); + printf ("\tpassed (4)\n"); + } + dSetDebugHandler (orig_debug); +} + +//**************************************************************************** + +// internal unit tests +extern "C" void dTestDataStructures(); +extern "C" void dTestMatrixComparison(); +extern "C" int dTestSolveLCP(); + + +int main() +{ + dInitODE(); + testRandomNumberGenerator(); + testInfinity(); + testPad(); + testCrossProduct(); + testSetZero(); + testNormalize3(); + //testReorthonormalize(); ... not any more + testPlaneSpace(); + testMatrixMultiply(); + testSmallMatrixMultiply(); + testCholeskyFactorization(); + testCholeskySolve(); + testInvertPDMatrix(); + testIsPositiveDefinite(); + testFastLDLTFactorization(); + testCoopLDLTFactorization(); + testSolveLDLT(); + testCoopSolveLDLT(); + testLDLTAddTL(); + testLDLTRemove(); + testMassFunctions(); + testRtoQandQtoR(); + testQuaternionMultiply(); + testRotationFunctions(); + dTestMatrixComparison(); + dTestSolveLCP(); + // dTestDataStructures(); + dCloseODE(); + return 0; +} diff --git a/libs/ode-0.16.1/ode/demo/demo_piston.cpp b/libs/ode-0.16.1/ode/demo/demo_piston.cpp new file mode 100644 index 0000000..8a0453a --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_piston.cpp @@ -0,0 +1,813 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + * Created by: Remi Ricard * + * (remi.ricard@simlog.com or papaDoc@videotron.ca) * + * Creation date: 2007/05/04 * + *************************************************************************/ + +/* + This program demonstrates how the Piston joint works. + + A Piston joint enables the sliding of a body with respect to another body + and the 2 bodies are free to rotate about the sliding axis. + + - The yellow body is fixed to the world. + - The yellow body and the blue body are attached by a Piston joint with + the axis along the x direction. + - The purple object is a geometry obstacle. + - The red line is the representation of the prismatic axis + - The orange line is the representation of the rotoide axis + - The light blue ball is the anchor position + + N.B. Many command options are available type -h to print them. +*/ + +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include <iostream> +#include <math.h> +#include "texturepath.h" + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif +// select correct drawing functions +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#define dsDrawCylinder dsDrawCylinderD +#define dsDrawCapsule dsDrawCapsuleD +#define dsDrawSphere dsDrawSphereD +#endif + + +const dReal VEL_INC = 0.01; // Velocity increment + +// physics parameters +const dReal PI = 3.14159265358979323846264338327950288419716939937510; +const dReal BODY1_LENGTH = 1.5; // Size along the X axis + +const dReal RADIUS = 0.2; +const dReal AXIS_RADIUS = 0.01; + + +#define X 0 +#define Y 1 +#define Z 2 + +enum INDEX +{ + BODY1 = 0, + BODY2, + RECT, + BOX, + OBS, + GROUND, + NUM_PARTS, + ALL = NUM_PARTS +}; + +const int catBits[NUM_PARTS+1] = +{ + 0x0001, ///< Ext Cylinder category + 0x0002, ///< Int Cylinder category + 0x0004, ///< Int_Rect Cylinder category + 0x0008, ///< Box category + 0x0010, ///< Obstacle category + 0x0020, ///< Ground category + ~0L ///< All categories +}; + +#define Mass1 10 +#define Mass2 8 + + +//camera view +static float xyz[3] = {2.0f,-3.5f,2.0000f}; +static float hpr[3] = {90.000f,-25.5000f,0.0000f}; + + +//world,space,body & geom +static dWorldID world; +static dSpaceID space; +static dJointGroupID contactgroup; +static dBodyID body[NUM_PARTS]; +static dGeomID geom[NUM_PARTS]; + +// Default Positions and anchor of the 2 bodies +dVector3 pos1; +dVector3 pos2; +dVector3 anchor; + +static dJoint *joint; + + +const dReal BODY2_SIDES[3] = {0.4, 0.4, 0.4}; +const dReal OBS_SIDES[3] = {1,1,1}; +const dReal RECT_SIDES[3] = {0.3, 0.1, 0.2}; + + +int type = dJointTypePiston; + +//#pragma message("tc to be changed to 0") + +int tc = 0; // The test case choice; + + +//collision detection +static void nearCallback (void *, dGeomID o1, dGeomID o2) +{ + int i,n; + + dBodyID b1 = dGeomGetBody (o1); + dBodyID b2 = dGeomGetBody (o2); + if (b1 && b2 && dAreConnectedExcluding (b1,b2,dJointTypeContact) ) return; + const int N = 10; + dContact contact[N]; + n = dCollide (o1,o2,N,&contact[0].geom,sizeof (dContact) ); + if (n > 0) + { + for (i=0; i<n; i++) + { + contact[i].surface.mode = (dContactSlip1 | dContactSlip2 | + dContactSoftERP | dContactSoftCFM | + dContactApprox1); + contact[i].surface.mu = 0.1; + contact[i].surface.slip1 = 0.02; + contact[i].surface.slip2 = 0.02; + contact[i].surface.soft_erp = 0.1; + contact[i].surface.soft_cfm = 0.0001; + dJointID c = dJointCreateContact (world,contactgroup,&contact[i]); + dJointAttach (c,dGeomGetBody (contact[i].geom.g1),dGeomGetBody (contact[i].geom.g2) ); + } + } +} + +static void printKeyBoardShortCut() +{ + printf ("Press 'h' for this help.\n"); + printf ("Press 'q' to add force on BLUE body along positive x direction.\n"); + printf ("Press 'w' to add force on BLUE body along negative x direction.\n"); + + printf ("Press 'a' to add force on BLUE body along positive y direction.\n"); + printf ("Press 's' to add force on BLUE body along negative y direction.\n"); + + printf ("Press 'z' to add force on BLUE body along positive z direction.\n"); + printf ("Press 'x' to add force on BLUE body along negative z direction.\n"); + + printf ("Press 'e' to add torque on BLUE body around positive x direction \n"); + printf ("Press 'r' to add torque on BLUE body around negative x direction \n"); + + printf ("Press 'd' to add torque on BLUE body around positive y direction \n"); + printf ("Press 'f' to add torque on BLUE body around negative y direction \n"); + + printf ("Press 'c' to add torque on BLUE body around positive z direction \n"); + printf ("Press 'v' to add torque on BLUE body around negative z direction \n"); + + printf ("Press 't' to add force on prismatic joint in the positive axis direction\n"); + printf ("Press 'y' to add force on prismatic joint in the negative axis direction\n"); + + printf ("Press 'i' to add limits on the prismatic joint (0 to 0) \n"); + printf ("Press 'o' to add limits on the rotoide joint (0 to 0)\n"); + printf ("Press 'k' to add limits on the rotoide joint (-45 to 45deg) \n"); + printf ("Press 'l' to remove limits on the rotoide joint \n"); + + + printf ("Press '.' to increase joint velocity along the prismatic direction.\n"); + printf ("Press ',' to decrease joint velocity along the prismatic direction.\n"); + + printf ("Press 'p' to print the Position of the joint.\n"); + + printf ("Press '+' Go to the next test case.\n"); + printf ("Press '-' Go to the previous test case.\n"); + + printf ("Press '8' To remove one of the body. The blue body and the world will be\n"); + printf (" attached to the joint (blue body at position 1)\n"); + printf ("Press '9' To remove one of the body. The blue body and the world will be\n"); + printf (" attached to the joint (body body at position 2)\n"); + + +} + + +// start simulation - set viewpoint +static void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + dsSetViewpoint (xyz,hpr); + printf ("This program demonstrates how the Piston joint works.\n"); + printf ("A Piston joint enables the sliding of a body with respect to another body\n"); + printf ("and the 2 bodies are free to rotate about the sliding axis.\n\n"); + printf ("The yellow body is fixed to the world\n"); + printf ("The yellow body and the blue body are attached by a Piston joint with\n"); + printf ("the axis along the x direction.\n"); + printf ("The purple object is a geometry obstacle.\n"); + + printKeyBoardShortCut(); +} + + +void setPositionBodies (int val) +{ + const dVector3 POS1 = {0,0,1.5,0}; + const dVector3 POS2 = {0,0,1.5,0}; + const dVector3 ANCHOR = {0,0,1.5,0}; + + for (int i=0; i<3; ++i) + { + pos1[i] = POS1[i]; + pos2[i] = POS2[i]; + anchor[i] = ANCHOR[i]; + } + + if (body[BODY1]) + { + dBodySetLinearVel (body[BODY1], 0,0,0); + dBodySetAngularVel (body[BODY1], 0,0,0); + } + + if (body[BODY2]) + { + dBodySetLinearVel (body[BODY2], 0,0,0); + dBodySetAngularVel (body[BODY2], 0,0,0); + } + + switch (val) + { + case 3: + pos1[Z] += -0.5; + anchor[Z] -= 0.25; + break; + case 2: + pos1[Z] -= 0.5; + anchor[Z] -= 0.5; + break; + case 1: + pos1[Z] += -0.5; + break; + default: // This is also case 0 + // Nothing to be done + break; + } + + const dMatrix3 R = + { + 1,0,0,0, + 0,1,0,0, + 0,0,1,0 + }; + + if (body[BODY1]) + { + dBodySetPosition (body[BODY1], pos1[X], pos1[Y], pos1[Z]); + dBodySetRotation (body[BODY1], R); + } + + if (body[BODY2]) + { + dBodySetPosition (body[BODY2], pos2[X], pos2[Y], pos2[Z]); + dBodySetRotation (body[BODY2], R); + } + + + + if (joint) + { + joint->attach (body[BODY1], body[BODY2]); + if (joint->getType() == dJointTypePiston) + dJointSetPistonAnchor(joint->id(), anchor[X], anchor[Y], anchor[Z]); + } + +} + + +// function to update camera position at each step. +void update() +{ +// static FILE *file = fopen("x:/sim/src/libode/tstsrcSF/export.dat", "w"); + +// static int cnt = 0; +// char str[24]; +// sprintf(str, "%06d",cnt++); + +// dWorldExportDIF(world, file, str); +} + + +// called when a key pressed +static void command (int cmd) +{ + switch (cmd) + { + case 'h' : + case 'H' : + case '?' : + printKeyBoardShortCut(); + break; + + // Force + case 'q' : + case 'Q' : + dBodyAddForce (body[BODY1],4,0,0); + break; + case 'w' : + case 'W' : + dBodyAddForce (body[BODY1],-4,0,0); + break; + + case 'a' : + case 'A' : + dBodyAddForce (body[BODY1],0,40,0); + break; + case 's' : + case 'S' : + dBodyAddForce (body[BODY1],0,-40,0); + break; + + case 'z' : + case 'Z' : + dBodyAddForce (body[BODY1],0,0,4); + break; + case 'x' : + case 'X' : + dBodyAddForce (body[BODY1],0,0,-4); + break; + + // Torque + case 'e': + case 'E': + dBodyAddTorque (body[BODY1],0.1,0,0); + break; + case 'r': + case 'R': + dBodyAddTorque (body[BODY1],-0.1,0,0); + break; + + case 'd': + case 'D': + dBodyAddTorque (body[BODY1],0, 0.1,0); + break; + case 'f': + case 'F': + dBodyAddTorque (body[BODY1],0,-0.1,0); + break; + + case 'c': + case 'C': + dBodyAddTorque (body[BODY1],0.1,0,0); + break; + case 'v': + case 'V': + dBodyAddTorque (body[BODY1],-0.1,0,0); + break; + + case 't': + case 'T': + if (joint->getType() == dJointTypePiston) + dJointAddPistonForce (joint->id(),1); + else + dJointAddSliderForce (joint->id(),1); + break; + case 'y': + case 'Y': + if (joint->getType() == dJointTypePiston) + dJointAddPistonForce (joint->id(),-1); + else + dJointAddSliderForce (joint->id(),-1); + break; + + + case '8' : + dJointAttach(joint->id(), body[0], 0); + break; + case '9' : + dJointAttach(joint->id(), 0, body[0]); + break; + + case 'i': + case 'I' : + joint->setParam (dParamLoStop, 0); + joint->setParam (dParamHiStop, 0); + break; + + case 'o': + case 'O' : + joint->setParam (dParamLoStop2, 0); + joint->setParam (dParamHiStop2, 0); + break; + + case 'k': + case 'K': + joint->setParam (dParamLoStop2, -45.0*3.14159267/180.0); + joint->setParam (dParamHiStop2, 45.0*3.14159267/180.0); + break; + case 'l': + case 'L': + joint->setParam (dParamLoStop2, -dInfinity); + joint->setParam (dParamHiStop2, dInfinity); + break; + + // Velocity of joint + case ',': + case '<' : + { + dReal vel = joint->getParam (dParamVel) - VEL_INC; + joint->setParam (dParamVel, vel); + std::cout<<"Velocity = "<<vel<<" FMax = 2"<<'\n'; + } + break; + + case '.': + case '>' : + { + dReal vel = joint->getParam (dParamVel) + VEL_INC; + joint->setParam (dParamVel, vel); + std::cout<<"Velocity = "<<vel<<" FMax = 2"<<'\n'; + } + break; + + case 'p' : + case 'P' : + { + switch (joint->getType() ) + { + case dJointTypeSlider : + { + dSliderJoint *sj = reinterpret_cast<dSliderJoint *> (joint); + std::cout<<"Position ="<<sj->getPosition() <<"\n"; + } + break; + case dJointTypePiston : + { + dPistonJoint *rj = reinterpret_cast<dPistonJoint *> (joint); + std::cout<<"Position ="<<rj->getPosition() <<"\n"; + } + break; + default: + {} // keep the compiler happy + } + } + break; + + case '+' : + (++tc) %= 4; + setPositionBodies (tc); + break; + case '-' : + (--tc) %= 4; + setPositionBodies (tc); + break; + + + } +} + +static void drawBox (dGeomID id, int R, int G, int B) +{ + if (!id) + return; + + const dReal *pos = dGeomGetPosition (id); + const dReal *rot = dGeomGetRotation (id); + dsSetColor (R,G,B); + + dVector3 l; + dGeomBoxGetLengths (id, l); + dsDrawBox (pos, rot, l); +} + + +// simulation loop +static void simLoop (int pause) +{ + const dReal *rot; + dVector3 ax; + dReal l=0; + + switch (joint->getType() ) + { + case dJointTypeSlider : + ( (dSliderJoint *) joint)->getAxis (ax); + l = ( (dSliderJoint *) joint)->getPosition(); + break; + case dJointTypePiston : + ( (dPistonJoint *) joint)->getAxis (ax); + l = ( (dPistonJoint *) joint)->getPosition(); + break; + default: + {} // keep the compiler happy + } + + + if (!pause) + { + double simstep = 0.01; // 1ms simulation steps + double dt = dsElapsedTime(); + + int nrofsteps = (int) ceilf (dt/simstep); + if (!nrofsteps) + nrofsteps = 1; + + for (int i=0; i<nrofsteps && !pause; i++) + { + dSpaceCollide (space,0,&nearCallback); + dWorldStep (world, simstep); + + dJointGroupEmpty (contactgroup); + } + + update(); + + + dReal radius, length; + + dsSetTexture (DS_WOOD); + + drawBox (geom[BODY2], 1,1,0); + + drawBox (geom[RECT], 0,0,1); + + if ( geom[BODY1] ) + { + const dReal *pos = dGeomGetPosition (geom[BODY1]); + rot = dGeomGetRotation (geom[BODY1]); + dsSetColor (0,0,1); + + dGeomCapsuleGetParams (geom[BODY1], &radius, &length); + dsDrawCapsule (pos, rot, length, radius); + } + + + drawBox (geom[OBS], 1,0,1); + + + // Draw the prismatic axis + if ( geom[BODY1] ) + { + const dReal *pos = dGeomGetPosition (geom[BODY1]); + rot = dGeomGetRotation (geom[BODY2]); + dVector3 p; + p[X] = pos[X] - l*ax[X]; + p[Y] = pos[Y] - l*ax[Y]; + p[Z] = pos[Z] - l*ax[Z]; + dsSetColor (1,0,0); + dsDrawCylinder (p, rot, 3.75, 1.05*AXIS_RADIUS); + } + + + if (joint->getType() == dJointTypePiston ) + { + dVector3 anchor; + dJointGetPistonAnchor(joint->id(), anchor); + + // Draw the rotoide axis + rot = dGeomGetRotation (geom[BODY2]); + dsSetColor (1,0.5,0); + dsDrawCylinder (anchor, rot, 4, AXIS_RADIUS); + + + dsSetColor (0,1,1); + rot = dGeomGetRotation (geom[BODY1]); + dsDrawSphere (anchor, rot, 1.5*RADIUS); + } + + } +} + + +void Help (char **argv) +{ + printf ("%s ", argv[0]); + printf (" -h | --help : print this help\n"); + printf (" -s | --slider : Set the joint as a slider\n"); + printf (" -p | --piston : Set the joint as a Piston. (Default joint)\n"); + printf (" -1 | --offset1 : Create an offset between the 2 bodies\n"); + printf (" Offset one of the body by z=-0.5 and keep the anchor\n"); + printf (" point in the middle of the fixed body\n"); + printf (" -2 | --offset2 : Create an offset between the 2 bodies\n"); + printf (" Offset one of the body by z=-0.5 and set the anchor\n"); + printf (" point in the middle of the movable body\n"); + printf (" -3 | --offset3 : Create an offset between the 2 bodies\n"); + printf (" Offset one of the body by z=-0.5 and set the anchor\n"); + printf (" point in the middle of the 2 bodies\n"); + printf (" -t | --texture-path path : Path to the texture.\n"); + printf (" Default = %s\n", DRAWSTUFF_TEXTURE_PATH); + printf (" -n | --notFixed : In free space with no gravity mode"); + printf ("-notex : Don't use texture\n"); + printf ("-noshadow : No shadow\n"); + printf ("-noshadows : No shadows\n"); + printf ("-pause : Initial pause\n"); + printf ("--------------------------------------------------\n"); + printf ("Hit any key to continue:"); + getchar(); + + exit (0); +} + +int main (int argc, char **argv) +{ + dInitODE2(0); + bool fixed = true; + + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + dVector3 offset; + dSetZero (offset, 4); + + // Default test case + + if (argc >= 2 ) + { + for (int i=1; i < argc; ++i) + { + //static int tata = 0; + + if (1) + { + if ( 0 == strcmp ("-h", argv[i]) || 0 == strcmp ("--help", argv[i]) ) + Help (argv); + + if ( 0 == strcmp ("-s", argv[i]) || 0 == strcmp ("--slider", argv[i]) ) + type = dJointTypeSlider; + + if ( 0 == strcmp ("-t", argv[i]) || 0 == strcmp ("--texture-path", argv[i]) ) + { + int j = i+1; + if ( j >= argc || // Check if we have enough arguments + argv[j][0] == '\0' || // We should have a path here + argv[j][0] == '-' ) // We should have a path not a command line + Help (argv); + else + fn.path_to_textures = argv[++i]; // Increase i since we use this argument + } + } + + + if ( 0 == strcmp ("-1", argv[i]) || 0 == strcmp ("--offset1", argv[i]) ) + tc = 1; + + if ( 0 == strcmp ("-2", argv[i]) || 0 == strcmp ("--offset2", argv[i]) ) + tc = 2; + + if ( 0 == strcmp ("-3", argv[i]) || 0 == strcmp ("--offset3", argv[i]) ) + tc = 3; + + if (0 == strcmp ("-n", argv[i]) || 0 == strcmp ("--notFixed", argv[i]) ) + fixed = false; + } + } + + world = dWorldCreate(); + dWorldSetERP (world, 0.8); + + space = dSimpleSpaceCreate (0); + contactgroup = dJointGroupCreate (0); + geom[GROUND] = dCreatePlane (space, 0,0,1,0); + dGeomSetCategoryBits (geom[GROUND], catBits[GROUND]); + dGeomSetCollideBits (geom[GROUND], catBits[ALL]); + + dMass m; + dMatrix3 R; + + + // Create the Obstacle + geom[OBS] = dCreateBox (space, OBS_SIDES[0], OBS_SIDES[1], OBS_SIDES[2]); + dGeomSetCategoryBits (geom[OBS], catBits[OBS]); + dGeomSetCollideBits (geom[OBS], catBits[ALL]); + //Rotation of 45deg around y + dRFromAxisAndAngle (R, 1,1,0, -0.25*PI); + dGeomSetRotation (geom[OBS], R); + dGeomSetPosition (geom[OBS], 1.95, -0.2, 0.5); + + + //Rotation of 90deg around y + // Will orient the Z axis along X + dRFromAxisAndAngle (R, 0,1,0, -0.5*PI); + + + // Create Body2 (Wiil be attached to the world) + body[BODY2] = dBodyCreate (world); + // Main axis of cylinder is along X=1 + dMassSetBox (&m, 1, BODY2_SIDES[0], BODY2_SIDES[1], BODY2_SIDES[2]); + dMassAdjust (&m, Mass1); + geom[BODY2] = dCreateBox (space, BODY2_SIDES[0], BODY2_SIDES[1], BODY2_SIDES[2]); + dGeomSetBody (geom[BODY2], body[BODY2]); + dGeomSetOffsetRotation (geom[BODY2], R); + dGeomSetCategoryBits (geom[BODY2], catBits[BODY2]); + dGeomSetCollideBits (geom[BODY2], catBits[ALL] & (~catBits[BODY1]) ); + dBodySetMass (body[BODY2], &m); + + + // Create Body 1 (Slider on the prismatic axis) + body[BODY1] = dBodyCreate (world); + // Main axis of capsule is along X=1 + dMassSetCapsule (&m, 1, 1, RADIUS, BODY1_LENGTH); + dMassAdjust (&m, Mass1); + geom[BODY1] = dCreateCapsule (space, RADIUS, BODY1_LENGTH); + dGeomSetBody (geom[BODY1], body[BODY1]); + dGeomSetOffsetRotation (geom[BODY1], R); + dGeomSetCategoryBits (geom[BODY1], catBits[BODY1]); + dGeomSetCollideBits (geom[BODY1], catBits[ALL] & ~catBits[BODY2] & ~catBits[RECT]); + + dMass mRect; + dMassSetBox (&mRect, 1, RECT_SIDES[0], RECT_SIDES[1], RECT_SIDES[2]); + dMassAdd (&m, &mRect); + // TODO: translate m? + geom[RECT] = dCreateBox (space, RECT_SIDES[0], RECT_SIDES[1], RECT_SIDES[2]); + dGeomSetBody (geom[RECT], body[BODY1]); + dGeomSetOffsetPosition (geom[RECT], + (BODY1_LENGTH-RECT_SIDES[0]) /2.0, + 0.0, + -RADIUS -RECT_SIDES[2]/2.0); + dGeomSetCategoryBits (geom[RECT], catBits[RECT]); + dGeomSetCollideBits (geom[RECT], catBits[ALL] & (~catBits[BODY1]) ); + + dBodySetMass (body[BODY1], &m); + + + + setPositionBodies (tc); + + + if ( fixed ) + { + // Attache external cylinder to the world + dJointID fixed = dJointCreateFixed (world,0); + dJointAttach (fixed , NULL, body[BODY2]); + dJointSetFixed (fixed ); + dWorldSetGravity (world,0,0,-0.8); + } + else + { + dWorldSetGravity (world,0,0,0); + } + + + + + // The static is here only to help debugging + switch (type) + { + case dJointTypeSlider : + { + dSliderJoint *sj = new dSliderJoint (world, 0); + sj->attach (body[BODY1], body[BODY2]); + sj->setAxis (1, 0, 0); + joint = sj; + } + break; + + case dJointTypePiston : // fall through default + default: + { + dPistonJoint *pj = new dPistonJoint (world, 0); + pj->attach (body[BODY1], body[BODY2]); + pj->setAxis (1, 0, 0); + + dJointSetPistonAnchor(pj->id(), anchor[X], anchor[Y], anchor[Z]); + + joint = pj; + } + break; + }; + + + // run simulation + dsSimulationLoop (argc,argv,400,300,&fn); + + delete joint; + dJointGroupDestroy (contactgroup); + dSpaceDestroy (space); + dWorldDestroy (world); + dCloseODE(); + return 0; +} + + + + diff --git a/libs/ode-0.16.1/ode/demo/demo_plane2d.cpp b/libs/ode-0.16.1/ode/demo/demo_plane2d.cpp new file mode 100644 index 0000000..559f9ae --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_plane2d.cpp @@ -0,0 +1,304 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// Test my Plane2D constraint. +// Uses ode-0.35 collision API. + +# include <stdio.h> +# include <stdlib.h> +# include <math.h> +# include <ode/ode.h> +# include <drawstuff/drawstuff.h> +#include "texturepath.h" + + +# define drand48() ((double) (((double) rand()) / ((double) RAND_MAX))) + +# define N_BODIES 40 +# define STAGE_SIZE 8.0 // in m + +# define TIME_STEP 0.01 +# define K_SPRING 10.0 +# define K_DAMP 10.0 + +//using namespace ode; + +struct GlobalVars +{ + dWorld dyn_world; + dBody dyn_bodies[N_BODIES]; + dReal bodies_sides[N_BODIES][3]; + + dSpaceID coll_space_id; + dJointID plane2d_joint_ids[N_BODIES]; + dJointGroup coll_contacts; +}; + +static GlobalVars *g_globals_ptr = NULL; + + + +static void cb_start () +/*************************/ +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + static float xyz[3] = { 0.5f*STAGE_SIZE, 0.5f*STAGE_SIZE, 0.65f*STAGE_SIZE}; + static float hpr[3] = { 90.0f, -90.0f, 0 }; + + dsSetViewpoint (xyz, hpr); +} + + + +static void cb_near_collision (void *, dGeomID o1, dGeomID o2) +/********************************************************************/ +{ + dBodyID b1 = dGeomGetBody (o1); + dBodyID b2 = dGeomGetBody (o2); + dContact contact; + + + // exit without doing anything if the two bodies are static + if (b1 == 0 && b2 == 0) + return; + + // exit without doing anything if the two bodies are connected by a joint + if (b1 && b2 && dAreConnected (b1, b2)) + { + /* MTRAP; */ + return; + } + + contact.surface.mode = 0; + contact.surface.mu = 0; // frictionless + + if (dCollide (o1, o2, 1, &contact.geom, sizeof (dContactGeom))) + { + dJointID c = dJointCreateContact (g_globals_ptr->dyn_world.id(), + g_globals_ptr->coll_contacts.id (), &contact); + dJointAttach (c, b1, b2); + } +} + + +static void track_to_pos (dBody &body, dJointID joint_id, + dReal target_x, dReal target_y) +/************************************************************************/ +{ + dReal curr_x = body.getPosition()[0]; + dReal curr_y = body.getPosition()[1]; + + dJointSetPlane2DXParam (joint_id, dParamVel, 1 * (target_x - curr_x)); + dJointSetPlane2DYParam (joint_id, dParamVel, 1 * (target_y - curr_y)); +} + + + +static void cb_sim_step (int pause) +/*************************************/ +{ + if (! pause) + { + static dReal angle = 0; + + angle += REAL( 0.01 ); + + track_to_pos (g_globals_ptr->dyn_bodies[0], g_globals_ptr->plane2d_joint_ids[0], + dReal( STAGE_SIZE/2 + STAGE_SIZE/2.0 * cos (angle) ), + dReal( STAGE_SIZE/2 + STAGE_SIZE/2.0 * sin (angle) )); + + /* double f0 = 0.001; */ + /* for (int b = 0; b < N_BODIES; b ++) */ + /* { */ + /* double p = 1 + b / (double) N_BODIES; */ + /* double q = 2 - b / (double) N_BODIES; */ + /* g_globals_ptr->dyn_bodies[b].addForce (f0 * cos (p*angle), f0 * sin (q*angle), 0); */ + /* } */ + /* g_globals_ptr->dyn_bodies[0].addTorque (0, 0, 0.1); */ + + const int n = 10; + for (int i = 0; i < n; i ++) + { + dSpaceCollide (g_globals_ptr->coll_space_id, 0, &cb_near_collision); + g_globals_ptr->dyn_world.step (dReal(TIME_STEP/n)); + g_globals_ptr->coll_contacts.empty (); + } + } + +# if 1 /* [ */ + { + // @@@ hack Plane2D constraint error reduction here: + for (int b = 0; b < N_BODIES; b ++) + { + const dReal *rot = dBodyGetAngularVel (g_globals_ptr->dyn_bodies[b].id()); + const dReal *quat_ptr; + dReal quat[4], + quat_len; + + + quat_ptr = dBodyGetQuaternion (g_globals_ptr->dyn_bodies[b].id()); + quat[0] = quat_ptr[0]; + quat[1] = 0; + quat[2] = 0; + quat[3] = quat_ptr[3]; + quat_len = sqrt (quat[0] * quat[0] + quat[3] * quat[3]); + quat[0] /= quat_len; + quat[3] /= quat_len; + dBodySetQuaternion (g_globals_ptr->dyn_bodies[b].id(), quat); + dBodySetAngularVel (g_globals_ptr->dyn_bodies[b].id(), 0, 0, rot[2]); + } + } +# endif /* ] */ + + +# if 0 /* [ */ + { + // @@@ friction + for (int b = 0; b < N_BODIES; b ++) + { + const dReal *vel = dBodyGetLinearVel (g_globals_ptr->dyn_bodies[b].id()), + *rot = dBodyGetAngularVel (g_globals_ptr->dyn_bodies[b].id()); + dReal s = 1.00; + dReal t = 0.99; + + dBodySetLinearVel (g_globals_ptr->dyn_bodies[b].id(), s*vel[0],s*vel[1],s*vel[2]); + dBodySetAngularVel (g_globals_ptr->dyn_bodies[b].id(),t*rot[0],t*rot[1],t*rot[2]); + } + } +# endif /* ] */ + + + { + // ode drawstuff + + dsSetTexture (DS_WOOD); + for (int b = 0; b < N_BODIES; b ++) + { + if (b == 0) + dsSetColor (1.0, 0.5, 1.0); + else + dsSetColor (0, 0.5, 1.0); +#ifdef dDOUBLE + dsDrawBoxD (g_globals_ptr->dyn_bodies[b].getPosition(), g_globals_ptr->dyn_bodies[b].getRotation(), g_globals_ptr->bodies_sides[b]); +#else + dsDrawBox (g_globals_ptr->dyn_bodies[b].getPosition(), g_globals_ptr->dyn_bodies[b].getRotation(), g_globals_ptr->bodies_sides[b]); +#endif + } + } +} + + + +extern int main +/******************/ +( + int argc, + char **argv +) +{ + int b; + dsFunctions drawstuff_functions; + + + dInitODE2(0); + + g_globals_ptr = new GlobalVars(); + + // dynamic world + + dReal cf_mixing;// = 1 / TIME_STEP * K_SPRING + K_DAMP; + dReal err_reduct;// = TIME_STEP * K_SPRING * cf_mixing; + err_reduct = REAL( 0.5 ); + cf_mixing = REAL( 0.001 ); + dWorldSetERP (g_globals_ptr->dyn_world.id (), err_reduct); + dWorldSetCFM (g_globals_ptr->dyn_world.id (), cf_mixing); + g_globals_ptr->dyn_world.setGravity (0, 0.0, -1.0); + + g_globals_ptr->coll_space_id = dSimpleSpaceCreate (0); + + // dynamic bodies + for (b = 0; b < N_BODIES; b ++) + { + int l = (int) (1 + sqrt ((double) N_BODIES)); + dReal x = dReal( (0.5 + (b / l)) / l * STAGE_SIZE ); + dReal y = dReal( (0.5 + (b % l)) / l * STAGE_SIZE ); + dReal z = REAL( 1.0 ) + REAL( 0.1 ) * (dReal)drand48(); + + g_globals_ptr->bodies_sides[b][0] = dReal( 5 * (0.2 + 0.7*drand48()) / sqrt((double)N_BODIES) ); + g_globals_ptr->bodies_sides[b][1] = dReal( 5 * (0.2 + 0.7*drand48()) / sqrt((double)N_BODIES) ); + g_globals_ptr->bodies_sides[b][2] = z; + + g_globals_ptr->dyn_bodies[b].create (g_globals_ptr->dyn_world); + g_globals_ptr->dyn_bodies[b].setPosition (x, y, z/2); + g_globals_ptr->dyn_bodies[b].setData ((void*) (dsizeint)b); + dBodySetLinearVel (g_globals_ptr->dyn_bodies[b].id (), + dReal( 3 * (drand48 () - 0.5) ), + dReal( 3 * (drand48 () - 0.5) ), 0); + + dMass m; + m.setBox (1, g_globals_ptr->bodies_sides[b][0],g_globals_ptr->bodies_sides[b][1],g_globals_ptr->bodies_sides[b][2]); + m.adjust (REAL(0.1) * g_globals_ptr->bodies_sides[b][0] * g_globals_ptr->bodies_sides[b][1]); + g_globals_ptr->dyn_bodies[b].setMass (&m); + + g_globals_ptr->plane2d_joint_ids[b] = dJointCreatePlane2D (g_globals_ptr->dyn_world.id (), 0); + dJointAttach (g_globals_ptr->plane2d_joint_ids[b], g_globals_ptr->dyn_bodies[b].id (), 0); + } + + dJointSetPlane2DXParam (g_globals_ptr->plane2d_joint_ids[0], dParamFMax, 10); + dJointSetPlane2DYParam (g_globals_ptr->plane2d_joint_ids[0], dParamFMax, 10); + + + // collision geoms and joints + dCreatePlane (g_globals_ptr->coll_space_id, 1, 0, 0, 0); + dCreatePlane (g_globals_ptr->coll_space_id, -1, 0, 0, -STAGE_SIZE); + dCreatePlane (g_globals_ptr->coll_space_id, 0, 1, 0, 0); + dCreatePlane (g_globals_ptr->coll_space_id, 0, -1, 0, -STAGE_SIZE); + + for (b = 0; b < N_BODIES; b ++) + { + dGeomID coll_box_id; + coll_box_id = dCreateBox (g_globals_ptr->coll_space_id, + g_globals_ptr->bodies_sides[b][0], g_globals_ptr->bodies_sides[b][1], g_globals_ptr->bodies_sides[b][2]); + dGeomSetBody (coll_box_id, g_globals_ptr->dyn_bodies[b].id ()); + } + + g_globals_ptr->coll_contacts.create (); + + { + // simulation loop (by drawstuff lib) + drawstuff_functions.version = DS_VERSION; + drawstuff_functions.start = &cb_start; + drawstuff_functions.step = &cb_sim_step; + drawstuff_functions.command = 0; + drawstuff_functions.stop = 0; + drawstuff_functions.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + dsSimulationLoop (argc, argv, 352,288,&drawstuff_functions); + } + + delete g_globals_ptr; + g_globals_ptr = NULL; + + dCloseODE(); + return 0; +} diff --git a/libs/ode-0.16.1/ode/demo/demo_rfriction.cpp b/libs/ode-0.16.1/ode/demo/demo_rfriction.cpp new file mode 100644 index 0000000..61d1115 --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_rfriction.cpp @@ -0,0 +1,258 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* +Angular friction demo: + +A bunch of ramps of different pitch. +A bunch of spheres with rolling friction. +*/ + + +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + +// select correct drawing functions +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#define dsDrawSphere dsDrawSphereD +#define dsDrawCylinder dsDrawCylinderD +#define dsDrawCapsule dsDrawCapsuleD +#endif + + +// some constants +#define GRAVITY 10 // the global gravity to use +#define RAMP_COUNT 8 + +static const dReal rampX = 6.0f; +static const dReal rampY = 0.5f; +static const dReal rampZ = 0.25f; +static const dReal sphereRadius = 0.25f; +static const dReal maxRamp = M_PI/4.0f; // Needs to be less than pi/2 +static const dReal rampInc = maxRamp/RAMP_COUNT; + +// dynamics and collision objects +static dWorldID world = 0; +static dSpaceID space = 0; +static dJointGroupID contactgroup = 0; +static dGeomID ground; + +static dReal mu = REAL(0.37); // the global mu to use +static dReal rho = REAL(0.1); // the global rho to use +static dReal omega = REAL(25.0); + +static dGeomID rampGeom[RAMP_COUNT]; +static dBodyID sphereBody[RAMP_COUNT]; +static dGeomID sphereGeom[RAMP_COUNT]; + + +// this is called by dSpaceCollide when two objects in space are +// potentially colliding. + +static void nearCallback (void *, dGeomID o1, dGeomID o2) +{ + int i; + + dBodyID b1 = dGeomGetBody(o1); + dBodyID b2 = dGeomGetBody(o2); + + if (b1==0 && b2==0) return; + + dContact contact[3]; + for (int ii=0; ii<3; ii++) { + contact[ii].surface.mode = dContactApprox1 | dContactRolling; + contact[ii].surface.mu = mu; + contact[ii].surface.rho = rho; + } + if (int numc = dCollide (o1,o2,3,&contact[0].geom,sizeof(dContact))) { + for (i=0; i<numc; i++) { + dJointID c = dJointCreateContact (world,contactgroup,contact+i); + dJointAttach (c,b1,b2); + } + } +} + + +// start simulation - set viewpoint + +static void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + static float xyz[3] = {0,-3.0f,3.0f}; + static float hpr[3] = {90.0000,-15.0000,0.0000}; + dsSetViewpoint (xyz,hpr); + printf ("Press:\n" + "\t'[' or ']' to change initial angular velocity\n" + "\t'm' to increase sliding friction\n" + "\t'n' to decrease sliding friction\n" + "\t'j' to increase rolling friction\n" + "\t'h' to decrease rolling friction\n" + "\t'r' to reset simulation.\n"); +} + +/** + Delete the bodies, etc. +*/ +static void clear() +{ + if (contactgroup) dJointGroupDestroy (contactgroup); + if (space) dSpaceDestroy (space); + if (world) dWorldDestroy (world); +} + + + +/** + Cleanup if necessary and rebuild the + world. +*/ +static void reset() +{ + clear(); + + // create world + world = dWorldCreate(); + space = dHashSpaceCreate (0); + contactgroup = dJointGroupCreate (0); + dWorldSetGravity (world,0,0,-GRAVITY); + ground = dCreatePlane (space,0,0,1,0); + + // Calculate mass for sphere a capsule with water density. + dMass sphereMass; + dMassSetSphere(&sphereMass,1000,sphereRadius); + + for (int ii=0;ii<RAMP_COUNT;++ii) { + dQuaternion q; + + dReal angle = (ii+1)*rampInc; + dReal cosA = dCos(angle); + dReal sinA = dSin(angle); + dReal rampW = rampX/cosA; // Box width that preserves ground distance + dReal zPos = REAL(0.5)*(sinA*rampW-cosA*rampZ); // Position that makes end meet ground + dReal yPos = ii*1.25*rampY; + dReal xPos = 0; + + + // Create the ramp + rampGeom[ii] = dCreateBox(space,rampW,rampY,rampZ); + dQFromAxisAndAngle(q,0,1,0,angle); + dGeomSetQuaternion(rampGeom[ii],q); + dGeomSetPosition(rampGeom[ii],xPos,yPos,zPos); + + // Create the spheres + xPos = -REAL(0.5)*rampX + sphereRadius; + zPos = sinA*rampW + sphereRadius; + sphereBody[ii] = dBodyCreate(world); + dBodySetMass(sphereBody[ii],&sphereMass); + sphereGeom[ii] = dCreateSphere(space,sphereRadius); + dGeomSetBody(sphereGeom[ii],sphereBody[ii]); + dBodySetPosition(sphereBody[ii],xPos,yPos,zPos); + dBodySetAngularVel(sphereBody[ii],0,omega,0); + } +} + + +static void command (int cmd) +{ + switch (cmd) { + case 'h': case 'H': + rho-=0.02; + if (rho<0) rho=0; + break; + case 'j': case 'J': + rho+=0.02; + if (rho>1) rho=1; + break; + case 'n': case 'N': + mu-=0.02; + if (mu<0) mu=0; + break; + case 'm': case 'M': + mu+=0.02; + if (mu>1) mu=1; + break; + case 'r': case 'R': + reset(); + break; + case ']': + omega+=1; + break; + case '[': + omega-=1; + break; + } +} + +// simulation loop + +static void simLoop (int pause) +{ + if (!pause) { + dSpaceCollide (space,0,&nearCallback); + dWorldStep (world,0.017); // 60 fps + // remove all contact joints + dJointGroupEmpty (contactgroup); + } + + // Render ramps and spheres + dsSetTexture (DS_WOOD); + for (int ii=0;ii<RAMP_COUNT;++ii) { + dVector3 sides; + + dsSetColor (1,0.5,0); + dGeomBoxGetLengths(rampGeom[ii],sides); + dsDrawBox (dGeomGetPosition(rampGeom[ii]),dGeomGetRotation(rampGeom[ii]),sides); + + dsSetColor(0,0,1); + dsDrawSphere (dGeomGetPosition(sphereGeom[ii]),dGeomGetRotation(sphereGeom[ii]), sphereRadius); + } +} + + +int main (int argc, char **argv) +{ + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + dInitODE2(0); + reset(); + + // run simulation + dsSimulationLoop (argc,argv,352,288,&fn); + + clear(); + dCloseODE(); + return 0; +} diff --git a/libs/ode-0.16.1/ode/demo/demo_slider.cpp b/libs/ode-0.16.1/ode/demo/demo_slider.cpp new file mode 100644 index 0000000..33be9ed --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_slider.cpp @@ -0,0 +1,171 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + +// select correct drawing functions +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#endif + + +// some constants +#define SIDE (0.5f) // side length of a box +#define MASS (1.0) // mass of a box + + +// dynamics and collision objects +static dWorldID world; +static dBodyID body[2]; +static dJointID slider; + + +// state set by keyboard commands +static int occasional_error = 0; + + +// start simulation - set viewpoint + +static void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + static float xyz[3] = {1.0382f,-1.0811f,1.4700f}; + static float hpr[3] = {135.0000f,-19.5000f,0.0000f}; + dsSetViewpoint (xyz,hpr); + printf ("Press 'e' to start/stop occasional error.\n"); +} + + +// called when a key pressed + +static void command (int cmd) +{ + if (cmd == 'e' || cmd == 'E') { + occasional_error ^= 1; + } +} + + +// simulation loop + +static void simLoop (int pause) +{ + const dReal kd = -0.3; // angular damping constant + const dReal ks = 0.5; // spring constant + if (!pause) { + // add an oscillating torque to body 0, and also damp its rotational motion + static dReal a=0; + const dReal *w = dBodyGetAngularVel (body[0]); + dBodyAddTorque (body[0],kd*w[0],kd*w[1]+0.1*cos(a),kd*w[2]+0.1*sin(a)); + a += 0.01; + + // add a spring force to keep the bodies together, otherwise they will + // fly apart along the slider axis. + const dReal *p1 = dBodyGetPosition (body[0]); + const dReal *p2 = dBodyGetPosition (body[1]); + dBodyAddForce (body[0],ks*(p2[0]-p1[0]),ks*(p2[1]-p1[1]), + ks*(p2[2]-p1[2])); + dBodyAddForce (body[1],ks*(p1[0]-p2[0]),ks*(p1[1]-p2[1]), + ks*(p1[2]-p2[2])); + + // occasionally re-orient one of the bodies to create a deliberate error. + if (occasional_error) { + static int count = 0; + if ((count % 20)==0) { + // randomly adjust orientation of body[0] + const dReal *R1; + dMatrix3 R2,R3; + R1 = dBodyGetRotation (body[0]); + dRFromAxisAndAngle (R2,dRandReal()-0.5,dRandReal()-0.5, + dRandReal()-0.5,dRandReal()-0.5); + dMultiply0 (R3,R1,R2,3,3,3); + dBodySetRotation (body[0],R3); + + // randomly adjust position of body[0] + const dReal *pos = dBodyGetPosition (body[0]); + dBodySetPosition (body[0], + pos[0]+0.2*(dRandReal()-0.5), + pos[1]+0.2*(dRandReal()-0.5), + pos[2]+0.2*(dRandReal()-0.5)); + } + count++; + } + + dWorldStep (world,0.05); + } + + dReal sides1[3] = {SIDE,SIDE,SIDE}; + dReal sides2[3] = {SIDE*0.8f,SIDE*0.8f,SIDE*2.0f}; + dsSetTexture (DS_WOOD); + dsSetColor (1,1,0); + dsDrawBox (dBodyGetPosition(body[0]),dBodyGetRotation(body[0]),sides1); + dsSetColor (0,1,1); + dsDrawBox (dBodyGetPosition(body[1]),dBodyGetRotation(body[1]),sides2); +} + + +int main (int argc, char **argv) +{ + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + // create world + dInitODE2(0); + world = dWorldCreate(); + dMass m; + dMassSetBox (&m,1,SIDE,SIDE,SIDE); + dMassAdjust (&m,MASS); + + body[0] = dBodyCreate (world); + dBodySetMass (body[0],&m); + dBodySetPosition (body[0],0,0,1); + body[1] = dBodyCreate (world); + dBodySetMass (body[1],&m); + dQuaternion q; + dQFromAxisAndAngle (q,-1,1,0,0.25*M_PI); + dBodySetPosition (body[1],0.2,0.2,1.2); + dBodySetQuaternion (body[1],q); + + slider = dJointCreateSlider (world,0); + dJointAttach (slider,body[0],body[1]); + dJointSetSliderAxis (slider,1,1,1); + + // run simulation + dsSimulationLoop (argc,argv,352,288,&fn); + + dWorldDestroy (world); + dCloseODE(); + return 0; +} diff --git a/libs/ode-0.16.1/ode/demo/demo_space.cpp b/libs/ode-0.16.1/ode/demo/demo_space.cpp new file mode 100644 index 0000000..6f871f6 --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_space.cpp @@ -0,0 +1,232 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +testing procedure: + * create a bunch of random boxes + * test for intersections directly, put results in n^2 array + * get space to report collisions: + - all correct collisions reported + - no pair reported more than once + - no incorrect collisions reported + +*/ + + +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + +// select correct drawing functions + +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#define dsDrawSphere dsDrawSphereD +#define dsDrawCylinder dsDrawCylinderD +#define dsDrawCapsule dsDrawCapsuleD +#endif + + +// some constants + +#define NUM 20 // number of boxes to test + + +// collision objects and globals + +static dSpaceID space; +static dGeomID geom[NUM]; +static dReal bounds[NUM][6]; +static dsizeint good_matrix[NUM][NUM]; // correct collision matrix +static dsizeint test_matrix[NUM][NUM]; // testing collision matrix +static dsizeint hits[NUM]; // number of collisions a box has +static unsigned long seed=37; + + +static void init_test() +{ + int i,j; + const dReal scale = 0.5; + + // set random boxes + dRandSetSeed (seed); + for (i=0; i < NUM; i++) { + bounds[i][0] = dRandReal()*2-1; + bounds[i][1] = bounds[i][0] + dRandReal()*scale; + bounds[i][2] = dRandReal()*2-1; + bounds[i][3] = bounds[i][2] + dRandReal()*scale; + bounds[i][4] = dRandReal()*2; + bounds[i][5] = bounds[i][4] + dRandReal()*scale; + + if (geom[i]) dGeomDestroy (geom[i]); + geom[i] = dCreateBox (space, + bounds[i][1] - bounds[i][0], + bounds[i][3] - bounds[i][2], + bounds[i][5] - bounds[i][4]); + dGeomSetPosition (geom[i], + (bounds[i][0] + bounds[i][1])*0.5, + (bounds[i][2] + bounds[i][3])*0.5, + (bounds[i][4] + bounds[i][5])*0.5); + dGeomSetData (geom[i],(void*)(dsizeint)(i)); + } + + // compute all intersections and put the results in "good_matrix" + for (i=0; i < NUM; i++) { + for (j=0; j < NUM; j++) good_matrix[i][j] = 0; + } + for (i=0; i < NUM; i++) hits[i] = 0; + + for (i=0; i < NUM; i++) { + for (j=i+1; j < NUM; j++) { + dReal *bounds1 = &bounds[i][0]; + dReal *bounds2 = &bounds[j][0]; + if (bounds1[0] > bounds2[1] || + bounds1[1] < bounds2[0] || + bounds1[2] > bounds2[3] || + bounds1[3] < bounds2[2] || + bounds1[4] > bounds2[5] || + bounds1[5] < bounds2[4]) continue; + good_matrix[i][j] = 1; + good_matrix[j][i] = 1; + hits[i]++; + hits[j]++; + } + } +} + + +// this is called by dSpaceCollide when two objects in space are +// potentially colliding. + +static void nearCallback (void *, dGeomID o1, dGeomID o2) +{ + dsizeint i,j; + i = (dsizeint) dGeomGetData (o1); + j = (dsizeint) dGeomGetData (o2); + if (i==j) + printf ("collision (%d,%d) is between the same object\n",(int)i,(int)j); + if (!good_matrix[i][j] || !good_matrix[j][i]) + printf ("collision (%d,%d) is incorrect\n",(int)i,(int)j); + if (test_matrix[i][j] || test_matrix[j][i]) + printf ("collision (%d,%d) reported more than once\n",(int)i,(int)j); + test_matrix[i][j] = 1; + test_matrix[j][i] = 1; +} + + +// start simulation - set viewpoint + +static void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + static float xyz[3] = {2.1640f,-1.3079f,1.7600f}; + static float hpr[3] = {125.5000f,-17.0000f,0.0000f}; + dsSetViewpoint (xyz,hpr); +} + + +static void command (int cmd) +{ + if (cmd == ' ') { + seed++; + init_test(); + } +} + + +// simulation loop + +static void simLoop (int) +{ + int i,j; + + for (i=0; i < NUM; i++) { + for (j=0; j < NUM; j++) test_matrix[i][j] = 0; + } + dSpaceCollide (space,0,&nearCallback); + for (i=0; i < NUM; i++) { + for (j=i+1; j < NUM; j++) { + if (good_matrix[i][j] && !test_matrix[i][j]) { + printf ("failed to report collision (%d,%d) (seed=%ld)\n",i,j,seed); + } + } + } + + seed++; + init_test(); + + for (i=0; i<NUM; i++) { + dVector3 pos,side; + dMatrix3 R; + dRSetIdentity (R); + for (j=0; j<3; j++) pos[j] = (bounds[i][j*2+1] + bounds[i][j*2]) * 0.5; + for (j=0; j<3; j++) side[j] = bounds[i][j*2+1] - bounds[i][j*2]; + if (hits[i] > 0) dsSetColor (1,0,0); + else dsSetColor (1,1,0); + dsDrawBox (pos,R,side); + } +} + + +int main (int argc, char **argv) +{ + int i; + + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + dInitODE2(0); + + // test the simple space: + // space = dSimpleSpaceCreate(); + + // test the hash space: + // space = dHashSpaceCreate (0); + // dHashSpaceSetLevels (space,-10,10); + + // test the quadtree space + dVector3 Center = {0, 0, 0, 0}; + dVector3 Extents = {10, 0, 10, 0}; + space = dQuadTreeSpaceCreate(0, Center, Extents, 7); + + for (i=0; i < NUM; i++) geom[i] = 0; + init_test(); + + // run simulation + dsSimulationLoop (argc,argv,352,288,&fn); + + dSpaceDestroy (space); + dCloseODE(); + return 0; +} diff --git a/libs/ode-0.16.1/ode/demo/demo_space_stress.cpp b/libs/ode-0.16.1/ode/demo/demo_space_stress.cpp new file mode 100644 index 0000000..dcbd9d7 --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_space_stress.cpp @@ -0,0 +1,449 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <string> + +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + +// select correct drawing functions + +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#define dsDrawSphere dsDrawSphereD +#define dsDrawCylinder dsDrawCylinderD +#define dsDrawCapsule dsDrawCapsuleD +#endif + + +// some constants + +#define NUM 10000 // max number of objects +#define DENSITY (5.0) // density of all objects +#define GPB 3 // maximum number of geometries per body +#define MAX_CONTACTS 4 // maximum number of contact points per body +#define WORLD_SIZE 20 +#define WORLD_HEIGHT 20 + + +// dynamics and collision objects + +struct MyObject { + dBodyID body; // the body + dGeomID geom[GPB]; // geometries representing this body +}; + +static int num=0; // number of objects in simulation +static int nextobj=0; // next object to recycle if num==NUM +static dWorldID world; +static dSpaceID space = NULL; +static MyObject obj[NUM]; +static dJointGroupID contactgroup; +static int selected = -1; // selected object +static int show_aabb = 0; // show geom AABBs? +static int show_contacts = 0; // show contact points? +static int random_pos = 1; // drop objects from random position? +static int draw_geom = 1; + + +// this is called by dSpaceCollide when two objects in space are +// potentially colliding. + +static void nearCallback (void *, dGeomID o1, dGeomID o2) +{ + int i; + // if (o1->body && o2->body) return; + + // exit without doing anything if the two bodies are connected by a joint + dBodyID b1 = dGeomGetBody(o1); + dBodyID b2 = dGeomGetBody(o2); + if (b1 && b2 && dAreConnectedExcluding (b1,b2,dJointTypeContact)) return; + + dContact contact[MAX_CONTACTS]; // up to MAX_CONTACTS contacts per box-box + for (i=0; i<MAX_CONTACTS; i++) { + contact[i].surface.mode = dContactBounce | dContactSoftCFM; + contact[i].surface.mu = dInfinity; + contact[i].surface.mu2 = 0; + contact[i].surface.bounce = 0.1; + contact[i].surface.bounce_vel = 0.1; + contact[i].surface.soft_cfm = 0.01; + } + if (int numc = dCollide (o1,o2,MAX_CONTACTS,&contact[0].geom, + sizeof(dContact))) { + dMatrix3 RI; + dRSetIdentity (RI); + const dReal ss[3] = {0.02,0.02,0.02}; + for (i=0; i<numc; i++) { + dJointID c = dJointCreateContact (world,contactgroup,contact+i); + dJointAttach (c,b1,b2); + if (show_contacts) dsDrawBox (contact[i].geom.pos,RI,ss); + } + } +} + + +// start simulation - set viewpoint + +static void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + static float xyz[3] = {2.1640f,-1.3079f,3.7600f}; + static float hpr[3] = {125.5000f,-17.0000f,0.0000f}; + dsSetViewpoint (xyz,hpr); + printf ("To drop another object, press:\n"); + printf (" o to disable rendering.\n"); + printf (" b for box.\n"); + printf (" s for sphere.\n"); + printf (" c for cylinder.\n"); + printf (" x for a composite object.\n"); + printf (" y for cylinder.\n"); + printf ("To select an object, press space.\n"); + printf ("To disable the selected object, press d.\n"); + printf ("To enable the selected object, press e.\n"); + printf ("To toggle showing the geom AABBs, press a.\n"); + printf ("To toggle showing the contact points, press t.\n"); + printf ("To toggle dropping from random position/orientation, press r.\n"); +} + + +char locase(char c) +{ + if (c >= 'A' && c <= 'Z') return c - ('a'-'A'); + else return c; +} + + +// called when a key pressed + +static void command (int cmd) +{ + int i,j,k; + dReal sides[3]; + dMass m; + bool setBody = false; + + cmd = locase(cmd); + if (cmd == 'b' || cmd == 's' || cmd == 'c' || cmd == 'x' || cmd == 'y') { + if (num < NUM) { + // new object to be created + i = num; + num++; + } else { + // recycle existing object + i = nextobj++; + nextobj %= num; // wrap-around if needed + + // destroy the body and geoms for slot i + dBodyDestroy (obj[i].body); + obj[i].body = 0; + + for (k=0; k < GPB; k++) + if (obj[i].geom[k]) { + dGeomDestroy(obj[i].geom[k]); + obj[i].geom[k] = 0; + } + } + + obj[i].body = dBodyCreate(world); + + for (k=0; k<3; k++) + sides[k] = dRandReal()*0.5+0.1; + + dMatrix3 R; + if (random_pos) { + dBodySetPosition(obj[i].body, + dRandReal()*2-1,dRandReal()*2-1,dRandReal()+2); + dRFromAxisAndAngle(R,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, + dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); + } else { + // higher than highest body position + dReal maxheight = 0; + for (k=0; k<num; k++) { + const dReal *pos = dBodyGetPosition(obj[k].body); + if (pos[2] > maxheight) + maxheight = pos[2]; + } + dBodySetPosition(obj[i].body, 0,0,maxheight+1); + dRSetIdentity(R); + //dRFromAxisAndAngle (R,0,0,1,/*dRandReal()*10.0-5.0*/0); + } + + dBodySetRotation(obj[i].body,R); + + if (cmd == 'b') { + + dMassSetBox(&m,DENSITY,sides[0],sides[1],sides[2]); + obj[i].geom[0] = dCreateBox(space,sides[0],sides[1],sides[2]); + + } else if (cmd == 'c') { + + sides[0] *= 0.5; + dMassSetCapsule(&m,DENSITY,3,sides[0],sides[1]); + obj[i].geom[0] = dCreateCapsule (space,sides[0],sides[1]); + + } else if (cmd == 'y') { + + dMassSetCylinder(&m,DENSITY,3,sides[0],sides[1]); + obj[i].geom[0] = dCreateCylinder(space,sides[0],sides[1]); + + } else if (cmd == 's') { + + sides[0] *= 0.5; + dMassSetSphere (&m,DENSITY,sides[0]); + obj[i].geom[0] = dCreateSphere (space,sides[0]); + + } else if (cmd == 'x') { + + setBody = true; + // start accumulating masses for the composite geometries + dMass m2; + dMassSetZero (&m); + + dReal dpos[GPB][3]; // delta-positions for composite geometries + dMatrix3 drot[GPB]; + + // set random delta positions + for (j=0; j<GPB; j++) + for (k=0; k<3; k++) + dpos[j][k] = dRandReal()*0.3-0.15; + + for (k=0; k<GPB; k++) { + if (k==0) { + dReal radius = dRandReal()*0.25+0.05; + obj[i].geom[k] = dCreateSphere (space,radius); + dMassSetSphere (&m2,DENSITY,radius); + } else if (k==1) { + obj[i].geom[k] = dCreateBox(space,sides[0],sides[1],sides[2]); + dMassSetBox(&m2,DENSITY,sides[0],sides[1],sides[2]); + } else { + dReal radius = dRandReal()*0.1+0.05; + dReal length = dRandReal()*1.0+0.1; + obj[i].geom[k] = dCreateCapsule(space,radius,length); + dMassSetCapsule(&m2,DENSITY,3,radius,length); + } + + dRFromAxisAndAngle(drot[k],dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, + dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); + dMassRotate(&m2,drot[k]); + + dMassTranslate(&m2,dpos[k][0],dpos[k][1],dpos[k][2]); + + // add to the total mass + dMassAdd(&m,&m2); + + } + for (k=0; k<GPB; k++) { + dGeomSetBody(obj[i].geom[k],obj[i].body); + dGeomSetOffsetPosition(obj[i].geom[k], + dpos[k][0]-m.c[0], + dpos[k][1]-m.c[1], + dpos[k][2]-m.c[2]); + dGeomSetOffsetRotation(obj[i].geom[k], drot[k]); + } + dMassTranslate(&m,-m.c[0],-m.c[1],-m.c[2]); + dBodySetMass(obj[i].body,&m); + + } + + if (!setBody) { // avoid calling for composite geometries + for (k=0; k < GPB; k++) + if (obj[i].geom[k]) + dGeomSetBody(obj[i].geom[k],obj[i].body); + + dBodySetMass(obj[i].body,&m); + } + } + + + if (cmd == ' ') { + selected++; + if (selected >= num) selected = 0; + if (selected < 0) selected = 0; + } + else if (cmd == 'd' && selected >= 0 && selected < num) { + dBodyDisable (obj[selected].body); + } + else if (cmd == 'e' && selected >= 0 && selected < num) { + dBodyEnable (obj[selected].body); + } + else if (cmd == 'a') { + show_aabb ^= 1; + } + else if (cmd == 't') { + show_contacts ^= 1; + } + else if (cmd == 'r') { + random_pos ^= 1; + } + else if (cmd == 'o') { + draw_geom ^= 1; + } +} + + +// draw a geom + +void drawGeom (dGeomID g, const dReal *pos, const dReal *R, int show_aabb) +{ + if (!draw_geom){ + return; + } + + if (!g) return; + if (!pos) pos = dGeomGetPosition(g); + if (!R) R = dGeomGetRotation(g); + + int type = dGeomGetClass (g); + if (type == dBoxClass) { + dVector3 sides; + dGeomBoxGetLengths(g,sides); + dsDrawBox(pos,R,sides); + } + else if (type == dSphereClass) { + dsDrawSphere(pos,R,dGeomSphereGetRadius (g)); + } + else if (type == dCapsuleClass) { + dReal radius,length; + dGeomCapsuleGetParams(g,&radius,&length); + dsDrawCapsule (pos,R,length,radius); + } else if (type == dCylinderClass) { + dReal radius,length; + dGeomCylinderGetParams(g,&radius,&length); + dsDrawCylinder(pos,R,length,radius); + } + + if (show_aabb) { + // draw the bounding box for this geom + dReal aabb[6]; + dGeomGetAABB(g,aabb); + dVector3 bbpos; + for (int i=0; i<3; i++) + bbpos[i] = 0.5*(aabb[i*2] + aabb[i*2+1]); + dVector3 bbsides; + for (int j=0; j<3; j++) + bbsides[j] = aabb[j*2+1] - aabb[j*2]; + dMatrix3 RI; + dRSetIdentity(RI); + dsSetColorAlpha(1,0,0,0.5); + dsDrawBox(bbpos,RI,bbsides); + } +} + + +// simulation loop + +static void simLoop (int pause) +{ + dsSetColor (0,0,2); + dSpaceCollide (space,0,&nearCallback); + //if (!pause) dWorldStep (world,0.05); + if (!pause) dWorldQuickStep (world,0.05); + //if (!pause) dWorldStepFast (world,0.05, 1); + + // remove all contact joints + dJointGroupEmpty (contactgroup); + + dsSetColor (1,1,0); + dsSetTexture (DS_WOOD); + for (int i=0; i<num; i++) { + for (int j=0; j < GPB; j++) { + if (i==selected) { + dsSetColor (0,0.7,1); + } + else if (! dBodyIsEnabled (obj[i].body)) { + dsSetColor (1,0,0); + } + else { + dsSetColor (1,1,0); + } + drawGeom (obj[i].geom[j],0,0,show_aabb); + } + } +} + + +int main (int argc, char **argv) +{ + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + dsSetSphereQuality(0); + + // create world + dInitODE2(0); + world = dWorldCreate(); + + for (int i=1; i<argc; ++i) { + if (argv[i] == std::string("quad")) { + dVector3 Center = {0, 0, 0, 0}; + dVector3 Extents = {WORLD_SIZE * 0.55, WORLD_SIZE * 0.55, WORLD_SIZE * 0.55, 0}; + puts(":::: Using dQuadTreeSpace"); + space = dQuadTreeSpaceCreate (0, Center, Extents, 6); + } else if (argv[i] == std::string("hash")) { + puts(":::: Using dHashSpace"); + space = dHashSpaceCreate (0); + } else if (argv[i] == std::string("sap")) { + puts(":::: Using dSweepAndPruneSpace"); + space = dSweepAndPruneSpaceCreate (0, dSAP_AXES_XYZ); + } else if (argv[i] == std::string("simple")) { + puts(":::: Using dSimpleSpace"); + space = dSimpleSpaceCreate(0); + } + } + if (!space) { + puts(":::: You can specify 'quad', 'hash', 'sap' or 'simple' in the"); + puts(":::: command line to specify the type of space."); + puts(":::: Using SAP space by default."); + space = dSweepAndPruneSpaceCreate (0, dSAP_AXES_XYZ); + } + + contactgroup = dJointGroupCreate (0); + dWorldSetGravity (world,0,0,-0.5); + dWorldSetCFM (world,1e-5); + dCreatePlane (space,0,0,1,0); + memset (obj,0,sizeof(obj)); + + for (int i = 0; i < NUM; i++){ + command('s'); + } + + // run simulation + dsSimulationLoop (argc,argv,352,288,&fn); + + dJointGroupDestroy (contactgroup); + dSpaceDestroy (space); + dWorldDestroy (world); + dCloseODE(); + return 0; +} diff --git a/libs/ode-0.16.1/ode/demo/demo_step.cpp b/libs/ode-0.16.1/ode/demo/demo_step.cpp new file mode 100644 index 0000000..f19a99c --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_step.cpp @@ -0,0 +1,192 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// test the step function by comparing the output of the fast and the slow +// version, for various systems. currently you have to define COMPARE_METHODS +// in step.cpp for this to work properly. +// +// @@@ report MAX error + +#include <time.h> +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + +// select correct drawing functions + +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#define dsDrawSphere dsDrawSphereD +#define dsDrawCylinder dsDrawCylinderD +#define dsDrawCapsule dsDrawCapsuleD +#endif + + +// some constants + +#define NUM 10 // number of bodies +#define NUMJ 9 // number of joints +#define SIDE (0.2) // side length of a box +#define MASS (1.0) // mass of a box +#define RADIUS (0.1732f) // sphere radius + + + +// dynamics and collision objects + +static dWorldID world=0; +static dBodyID body[NUM]; +static dJointID joint[NUMJ]; + + +// create the test system + +void createTest() +{ + int i,j; + if (world) dWorldDestroy (world); + + world = dWorldCreate(); + + // create random bodies + for (i=0; i<NUM; i++) { + // create bodies at random position and orientation + body[i] = dBodyCreate (world); + dBodySetPosition (body[i],dRandReal()*2-1,dRandReal()*2-1, + dRandReal()*2+RADIUS); + dReal q[4]; + for (j=0; j<4; j++) q[j] = dRandReal()*2-1; + dBodySetQuaternion (body[i],q); + + // set random velocity + dBodySetLinearVel (body[i], dRandReal()*2-1,dRandReal()*2-1, + dRandReal()*2-1); + dBodySetAngularVel (body[i], dRandReal()*2-1,dRandReal()*2-1, + dRandReal()*2-1); + + // set random mass (random diagonal mass rotated by a random amount) + dMass m; + dMatrix3 R; + dMassSetBox (&m,1,dRandReal()+0.1,dRandReal()+0.1,dRandReal()+0.1); + dMassAdjust (&m,dRandReal()+1); + for (j=0; j<4; j++) q[j] = dRandReal()*2-1; + dQtoR (q,R); + dMassRotate (&m,R); + dBodySetMass (body[i],&m); + } + + // create ball-n-socket joints at random positions, linking random bodies + // (but make sure not to link the same pair of bodies twice) + char linked[NUM*NUM]; + for (i=0; i<NUM*NUM; i++) linked[i] = 0; + for (i=0; i<NUMJ; i++) { + int b1,b2; + do { + b1 = dRandInt (NUM); + b2 = dRandInt (NUM); + } while (linked[b1*NUM + b2] || b1==b2); + linked[b1*NUM + b2] = 1; + linked[b2*NUM + b1] = 1; + joint[i] = dJointCreateBall (world,0); + dJointAttach (joint[i],body[b1],body[b2]); + dJointSetBallAnchor (joint[i],dRandReal()*2-1, + dRandReal()*2-1,dRandReal()*2+RADIUS); + } + + for (i=0; i<NUM; i++) { + // move bodies a bit to get some joint error + const dReal *pos = dBodyGetPosition (body[i]); + dBodySetPosition (body[i],pos[0]+dRandReal()*0.2-0.1, + pos[1]+dRandReal()*0.2-0.1,pos[2]+dRandReal()*0.2-0.1); + } +} + + +// start simulation - set viewpoint + +static void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + static float xyz[3] = {2.6117f,-1.4433f,2.3700f}; + static float hpr[3] = {151.5000f,-30.5000f,0.0000f}; + dsSetViewpoint (xyz,hpr); +} + + +// simulation loop + +static void simLoop (int pause) +{ + if (!pause) { + // add random forces and torques to all bodies + int i; + const dReal scale1 = 5; + const dReal scale2 = 5; + for (i=0; i<NUM; i++) { + dBodyAddForce (body[i], + scale1*(dRandReal()*2-1), + scale1*(dRandReal()*2-1), + scale1*(dRandReal()*2-1)); + dBodyAddTorque (body[i], + scale2*(dRandReal()*2-1), + scale2*(dRandReal()*2-1), + scale2*(dRandReal()*2-1)); + } + + dWorldStep (world,0.05); + createTest(); + } + + // float sides[3] = {SIDE,SIDE,SIDE}; + dsSetColor (1,1,0); + for (int i=0; i<NUM; i++) + dsDrawSphere (dBodyGetPosition(body[i]), dBodyGetRotation(body[i]),RADIUS); +} + + +int main (int argc, char **argv) +{ + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = 0; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + dInitODE2(0); + dRandSetSeed (time(0)); + createTest(); + + // run simulation + dsSimulationLoop (argc,argv,352,288,&fn); + + dWorldDestroy (world); + dCloseODE(); + return 0; +} diff --git a/libs/ode-0.16.1/ode/demo/demo_tracks.cpp b/libs/ode-0.16.1/ode/demo/demo_tracks.cpp new file mode 100644 index 0000000..9b4f5dd --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_tracks.cpp @@ -0,0 +1,498 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +//#include <iostream> +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#ifdef dDOUBLE +#define dsDrawSphere dsDrawSphereD +#define dsDrawBox dsDrawBoxD +#define dsDrawTriangle dsDrawTriangleD +#define dsDrawLine dsDrawLineD +#endif + + + +const dReal ball_radius = 0.4; +const dReal balls_sep = 2; // separation between the balls + +/* Choose one test case + */ +#define TEST_CASE 0 + +#if TEST_CASE == 0 +const dReal track_len = 10; +const dReal track_height = 1; +const dReal track_width = 0.1; +const dReal track_gauge = 1; +const dReal track_elevation = 2; +const dReal track_angle = 80 * M_PI/180.; +const dReal track_incl = 10 * M_PI/180.; +#elif TEST_CASE == 1 +const dReal track_len = 10; +const dReal track_height = 1; +const dReal track_width = 0.1; +const dReal track_gauge = 1.9*ball_radius; +const dReal track_elevation = 2; +const dReal track_angle = 0 * M_PI/180.; +const dReal track_incl = 10 * M_PI/180.; +#elif TEST_CASE == 2 +const dReal track_len = 10; +const dReal track_height = 1; +const dReal track_width = 0.1; +const dReal track_gauge = 1.9*ball_radius; +const dReal track_elevation = 2; +const dReal track_angle = 15 * M_PI/180.; +const dReal track_incl = 10 * M_PI/180.; +#elif TEST_CASE == 3 +const dReal track_len = 10; +const dReal track_height = .7; +const dReal track_width = 0.1; +const dReal track_gauge = track_height*1.1; +const dReal track_elevation = 2; +const dReal track_angle = 90 * M_PI/180.; +const dReal track_incl = 10 * M_PI/180.; +#else +#error "TEST_CAST to a valid value!" +#endif + + + +dWorldID world; +dSpaceID space; +dJointGroupID contact_group; +dGeomID ground; +dGeomID ball1_geom, ball2_geom; +dTriMeshDataID mesh_data; +dGeomID mesh_geom; + +dBodyID ball1_body, ball2_body; + +const unsigned n_box_verts = 8; +dVector3 box_verts[n_box_verts] = { + {-track_len/2, -track_width/2, track_height/2}, // 0 + { track_len/2, -track_width/2, track_height/2}, // 1 + { track_len/2, track_width/2, track_height/2}, // 2 + {-track_len/2, track_width/2, track_height/2}, // 3 + { track_len/2, -track_width/2, -track_height/2}, // 4 + {-track_len/2, -track_width/2, -track_height/2}, // 5 + {-track_len/2, track_width/2, -track_height/2}, // 6 + { track_len/2, track_width/2, -track_height/2} // 7 +}; + +const unsigned n_box_faces = 12; +dTriIndex box_faces[n_box_faces * 3] = { + 0, 1, 2, + 0, 2, 3, + 1, 4, 7, + 1, 7, 2, + 4, 5, 6, + 4, 6, 7, + 5, 0, 3, + 5, 3, 6, + 3, 2, 7, + 3, 7, 6, + 0, 5, 4, + 0, 4, 1 +}; + + +const unsigned n_track_verts = n_box_verts * 2; +const unsigned n_track_faces = n_box_faces * 2; + +dVector3 track_verts[n_track_verts]; +dTriIndex track_faces[n_track_faces * 3]; + + + +void resetBall(dBodyID b, unsigned idx) +{ + dBodySetPosition(b, + 0.5*track_len*cos(track_incl) // Z + - 0.5*track_height*sin(track_incl) + - ball_radius, // X + balls_sep*idx, // Y + track_elevation + ball_radius// Z + + 0.5*track_len*sin(track_incl) + + 0.5*track_height*cos(track_incl)); + dMatrix3 r = {1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0}; + dBodySetRotation(b, r); + dBodySetLinearVel(b, 0, 0, 0); + dBodySetAngularVel(b, 0, 0, 0); + +} + + +void resetSim() +{ + resetBall(ball1_body, 0); + resetBall(ball2_body, 1); +} + + +void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + world = dWorldCreate(); + dWorldSetGravity (world,0,0,-9.8); + + contact_group = dJointGroupCreate(0); + + space = dSimpleSpaceCreate (0); + + + // first, the ground plane + // it has to coincide with the plane we have in drawstuff + ground = dCreatePlane(space, 0, 0, 1, 0); + + + // now a ball + dMass m; + dMassSetSphere(&m, 0.1, ball_radius); + + ball1_geom = dCreateSphere(space, ball_radius); + ball1_body = dBodyCreate(world); + dGeomSetBody(ball1_geom, ball1_body); + dBodySetMass(ball1_body, &m); + + ball2_geom = dCreateSphere(space, ball_radius); + ball2_body = dBodyCreate(world); + dGeomSetBody(ball2_geom, ball2_body); + dBodySetMass(ball2_body, &m); + + + + + // tracks made out of boxes + dGeomID trk; + dMatrix3 r1, r2, r3; + dVector3 ro = {0, -(0.5*track_gauge + 0.5*track_width), track_elevation}; + dMatrix3 s1, s2, s3; + dVector3 so = {0, 0.5*track_gauge + 0.5*track_width, track_elevation}; + + dRFromAxisAndAngle(r1, 1, 0, 0, track_angle); + dRFromAxisAndAngle(r2, 0, 1, 0, -track_incl); + dMultiply0_333(r3, r2, r1); + + dRFromAxisAndAngle(s1, 1, 0, 0, -track_angle); + dRFromAxisAndAngle(s2, 0, 1, 0, -track_incl); + dMultiply0_333(s3, s2, s1); + + trk = dCreateBox(space, track_len, track_width, track_height); + dGeomSetPosition(trk, ro[0], ro[1] + balls_sep, ro[2]); + dGeomSetRotation(trk, r3); + + trk = dCreateBox(space, track_len, track_width, track_height); + dGeomSetPosition(trk, so[0], so[1] + balls_sep, so[2]); + dGeomSetRotation(trk, s3); + + + + + + // tracks made out of trimesh + for (unsigned i=0; i<n_box_verts; ++i) { + dVector3 p; + dMultiply0_331(p, s3, box_verts[i]); + dAddVectors3(p, p, so); + dCopyVector3(track_verts[i], p); + } + // trimesh tracks 2, transform all vertices by s3 + for (unsigned i=0; i<n_box_verts; ++i) { + dVector3 p; + dMultiply0_331(p, r3, box_verts[i]); + dAddVectors3(p, p, ro); + dCopyVector3(track_verts[n_box_verts + i], p); + } + + // copy face indices + for (unsigned i=0; i<n_box_faces; ++i) + for (unsigned j=0; j<3; ++j) // each face index + track_faces[3*i+j] = box_faces[3*i+j]; + for (unsigned i=0; i<n_box_faces; ++i) + for (unsigned j=0; j<3; ++j) // each face index + track_faces[3*(i + n_box_faces)+j] = box_faces[3*i+j] + n_box_verts; + + mesh_data = dGeomTriMeshDataCreate(); + dGeomTriMeshDataBuildSimple(mesh_data, + track_verts[0], n_track_verts, + track_faces, 3*n_track_faces); + mesh_geom = dCreateTriMesh(space, mesh_data, 0, 0, 0); + + + + + + resetSim(); + + + // initial camera position + static float xyz[3] = {-5.9414,-0.4804,2.9800}; + static float hpr[3] = {32.5000,-10.0000,0.0000}; + dsSetViewpoint (xyz,hpr); + + dsSetSphereQuality(3); +} + + +void nearCallback(void *, dGeomID a, dGeomID b) +{ + const unsigned max_contacts = 8; + dContact contacts[max_contacts]; + + if (!dGeomGetBody(a) && !dGeomGetBody(b)) + return; // don't handle static geom collisions + + int n = dCollide(a, b, max_contacts, &contacts[0].geom, sizeof(dContact)); + //clog << "got " << n << " contacts" << endl; + + /* Simple contact merging: + * If we have contacts that are too close with the same normal, keep only + * the one with maximum depth. + * The epsilon that defines what "too close" means can be a heuristic. + */ + int new_n = 0; + dReal epsilon = 1e-1; // default + /* If we know one of the geoms is a sphere, we can base the epsilon on the + * sphere's radius. + */ + dGeomID s = 0; + if ((dGeomGetClass(a) == dSphereClass && (s = a)) || + (dGeomGetClass(b) == dSphereClass && (s = b))) { + epsilon = dGeomSphereGetRadius(s) * 0.3; + } + + + for (int i=0; i<n; ++i) { + + // this block draws the contact points before merging, in red + dMatrix3 r; + dRSetIdentity(r); + dsSetColor(1, 0, 0); + dsSetTexture(DS_NONE); + dsDrawSphere(contacts[i].geom.pos, r, 0.008); + + // let's offset the line a bit to avoid drawing overlap issues + float xyzf[3], hprf[3]; + dsGetViewpoint(xyzf, hprf); + dVector3 xyz = {dReal(xyzf[0]), dReal(xyzf[1]), dReal(xyzf[2])}; + dVector3 v; + dSubtractVectors3(v, contacts[i].geom.pos, xyz); + dVector3 c; + dCalcVectorCross3(c, v, contacts[i].geom.pos); + dNormalize3(c); + dVector3 pos1; + dAddScaledVectors3(pos1, contacts[i].geom.pos, c, 1, 0.005); + dVector3 pos2; + dAddScaledVectors3(pos2, pos1, contacts[i].geom.normal, 1, 0.05); + dsDrawLine(pos1, pos2); + // end of contacts drawing code + + + + int closest_point = i; + for (int j=0; j<new_n; ++j) { + dReal alignment = dCalcVectorDot3(contacts[i].geom.normal, contacts[j].geom.normal); + if (alignment > 0.99 // about 8 degrees of difference + && + dCalcPointsDistance3(contacts[i].geom.pos, contacts[j].geom.pos) < epsilon) { + // they are too close + closest_point = j; + //clog << "found close points: " << j << " and " << i << endl; + break; + } + } + + if (closest_point != i) { + // we discard one of the points + if (contacts[i].geom.depth > contacts[closest_point].geom.depth) + // the new point is deeper, copy it over closest_point + contacts[closest_point] = contacts[i]; + } else + contacts[new_n++] = contacts[i]; // the point is preserved + } + //clog << "reduced from " << n << " to " << new_n << endl; + n = new_n; + + for (int i=0; i<n; ++i) { + contacts[i].surface.mode = dContactBounce | dContactApprox1 | dContactSoftERP; + contacts[i].surface.mu = 10; + contacts[i].surface.bounce = 0.2; + contacts[i].surface.bounce_vel = 0; + contacts[i].surface.soft_erp = 1e-3; + //clog << "depth: " << contacts[i].geom.depth << endl; + + + dJointID contact = dJointCreateContact(world, contact_group, &contacts[i]); + dJointAttach(contact, dGeomGetBody(a), dGeomGetBody(b)); + + dMatrix3 r; + dRSetIdentity(r); + dsSetColor(0, 0, 1); + dsSetTexture(DS_NONE); + dsDrawSphere(contacts[i].geom.pos, r, 0.01); + dsSetColor(0, 1, 0); + dVector3 pos2; + dAddScaledVectors3(pos2, contacts[i].geom.pos, contacts[i].geom.normal, 1, 0.1); + dsDrawLine(contacts[i].geom.pos, pos2); + } + //clog << "----" << endl; +} + + + + +void stop() +{ + dGeomDestroy(mesh_geom); + dGeomTriMeshDataDestroy(mesh_data); + + dBodyDestroy(ball1_body); + dBodyDestroy(ball2_body); + + dGeomDestroy(ground); + + dJointGroupDestroy(contact_group); + + dSpaceDestroy(space); // will destroy all geoms + + dWorldDestroy(world); +} + + +static void command (int cmd) +{ + switch (cmd) { + case ' ': + resetSim(); + break; + } +} + + +void drawGeom(dGeomID g) +{ + int gclass = dGeomGetClass(g); + const dReal *pos = dGeomGetPosition(g); + const dReal *rot = dGeomGetRotation(g); + + switch (gclass) { + case dSphereClass: + dsSetColorAlpha(0, 0.75, 0.5, 0.5); + dsSetTexture (DS_CHECKERED); + dsDrawSphere(pos, rot, dGeomSphereGetRadius(g)); + break; + case dBoxClass: + { + dVector3 lengths; + dsSetColorAlpha(1, 1, 0, 0.5); + dsSetTexture (DS_WOOD); + dGeomBoxGetLengths(g, lengths); + dsDrawBox(pos, rot, lengths); + break; + } + case dTriMeshClass: + { + int numi = dGeomTriMeshGetTriangleCount(g); + + for (int i=0; i<numi; ++i) { + dVector3 v0, v1, v2; + dGeomTriMeshGetTriangle(g, i, &v0, &v1, &v2); + + dsSetTexture (DS_WOOD); + + dsSetDrawMode(DS_WIREFRAME); + dsSetColorAlpha(0, 0, 0, 1.0); + dsDrawTriangle(pos, rot, v0, v1, v2, true); + + dsSetDrawMode(DS_POLYFILL); + dsSetColorAlpha(1, 1, 0, 0.5); + dsDrawTriangle(pos, rot, v0, v1, v2, true); + } + break; + } + + default: + {} + } +} + + + +void simLoop (int pause) +{ + if (!pause) { + + const dReal step = 0.02; + const unsigned nsteps = 1; + + for (unsigned i=0; i<nsteps; ++i) { + dSpaceCollide(space, 0, nearCallback); + dWorldQuickStep(world, step); + dJointGroupEmpty(contact_group); + } + } else { + dSpaceCollide(space, 0, nearCallback); + dJointGroupEmpty(contact_group); + } + + // now we draw everything + unsigned ngeoms = dSpaceGetNumGeoms(space); + for (unsigned i=0; i<ngeoms; ++i) { + dGeomID g = dSpaceGetGeom(space, i); + + if (g == ground) + continue; // drawstuff is already drawing it for us + + drawGeom(g); + } + + if (dBodyGetPosition(ball1_body)[0] < -track_len) + resetSim(); +} + + +int main (int argc, char **argv) +{ + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = stop; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + // create world + dInitODE(); + + // run demo + dsSimulationLoop (argc, argv, 800, 600, &fn); + + dCloseODE(); + return 0; +} diff --git a/libs/ode-0.16.1/ode/demo/demo_transmission.cpp b/libs/ode-0.16.1/ode/demo/demo_transmission.cpp new file mode 100644 index 0000000..50cb820 --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_transmission.cpp @@ -0,0 +1,414 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#ifdef dDOUBLE +#define dsDrawCylinder dsDrawCylinderD +#define dsDrawLine dsDrawLineD +#define dsDrawSphere dsDrawSphereD +#endif + +dReal theta = M_PI / 4; +dReal ratio = 1, speed = 5, rho_1 = 1, rho_2 = 1, backlash = 0.1; +int mode = 0; + +dWorldID world; +dSpaceID space; +dBodyID body1, body2; +dGeomID geom1, geom2; +dJointID hinge1, hinge2, transmission; +dJointFeedback feedback; + +void setup() { + dMatrix3 R; + + switch (mode) { + case 0: + // Parallel axes. + + dBodySetPosition(body1, 1, 0, 1); + dBodySetPosition(body2, -1, 0, 1); + + dRSetIdentity (R); + dBodySetRotation (body1, R); + dBodySetRotation (body2, R); + + dJointSetHingeAnchor(hinge2, -1, 0, 1); + dJointSetHingeAxis(hinge2, 0, 0, 1); + + dJointSetHingeAnchor(hinge1, 1, 0, 1); + dJointSetHingeAxis(hinge1, 0, 0, 1); + + dJointSetTransmissionMode(transmission, dTransmissionParallelAxes); + dJointSetTransmissionRatio(transmission, ratio); + dJointSetTransmissionAnchor1(transmission, 1, 0, 1); + dJointSetTransmissionAnchor2(transmission, -1, 0, 1); + dJointSetTransmissionAxis(transmission, 0, 0, 1); + + break; + case 1: + // Intersecting axes. + + dBodySetPosition(body1, 1, 0, 1); + dBodySetPosition(body2, -1, 0, 2); + + dRSetIdentity (R); + dBodySetRotation (body1, R); + + dRFromZAxis (R, cos(theta), 0, sin(theta)); + dBodySetRotation (body2, R); + + dJointSetHingeAnchor(hinge2, -1, 0, 2); + dJointSetHingeAxis(hinge2, cos(theta), 0, sin(theta)); + + dJointSetHingeAnchor(hinge1, 1, 0, 1); + dJointSetHingeAxis(hinge1, 0, 0, 1); + + dJointSetTransmissionMode(transmission, dTransmissionIntersectingAxes); + dJointSetTransmissionAnchor1(transmission, 1, 0, 1); + dJointSetTransmissionAnchor2(transmission, -1, 0, 2); + dJointSetTransmissionAxis1(transmission, 0, 0, -1); + dJointSetTransmissionAxis2(transmission, cos(theta), 0, sin(theta)); + + break; + case 2: + // Chain. + + dBodySetPosition(body1, 2, 0, 1); + dBodySetPosition(body2, -2, 0, 1); + + dRSetIdentity (R); + dBodySetRotation (body1, R); + dBodySetRotation (body2, R); + + dJointSetHingeAnchor(hinge2, -2, 0, 1); + dJointSetHingeAxis(hinge2, 0, 0, 1); + + dJointSetHingeAnchor(hinge1, 2, 0, 1); + dJointSetHingeAxis(hinge1, 0, 0, 1); + + dJointSetTransmissionMode(transmission, dTransmissionChainDrive); + dJointSetTransmissionAnchor1(transmission, 2, 0, 1); + dJointSetTransmissionAnchor2(transmission, -2, 0, 1); + dJointSetTransmissionRadius1(transmission, rho_1); + dJointSetTransmissionRadius2(transmission, rho_2); + dJointSetTransmissionAxis(transmission, 0, 0, 1); + + break; + } + + dJointSetTransmissionBacklash(transmission, backlash); + + dJointSetHingeParam(hinge2, dParamVel, speed); + dJointSetHingeParam(hinge2, dParamFMax, 50); + + dJointSetHingeParam(hinge1, dParamVel, 0); + dJointSetHingeParam(hinge1, dParamFMax, 2); + + dBodySetLinearVel(body1, 0, 0, 0); + dBodySetLinearVel(body2, 0, 0, 0); + dBodySetAngularVel(body1, 0, 0, 0); + dBodySetAngularVel(body2, 0, 0, 0); +} + +void start() +{ + dMass mass; + + world = dWorldCreate(); + dWorldSetGravity (world,0,0,-9.8); + + dWorldSetERP(world, 0.2); + + space = dSimpleSpaceCreate (0); + + body1 = dBodyCreate(world); + body2 = dBodyCreate(world); + + dBodySetFiniteRotationMode(body1, 1); + dBodySetFiniteRotationMode(body2, 1); + + geom1 = dCreateCylinder(space, 0.2, 0.5); + dGeomSetBody(geom1, body1); + dMassSetCylinder(&mass, 100, 3, 0.2, 0.5); + dBodySetMass(body1, &mass); + + geom2 = dCreateCylinder(space, 0.2, 0.5); + dGeomSetBody(geom2, body2); + dMassSetCylinder(&mass, 100, 3, 0.2, 0.5); + dBodySetMass(body2, &mass); + + hinge1 = dJointCreateHinge(world, 0); + dJointAttach(hinge1, body1, 0); + + hinge2 = dJointCreateHinge(world, 0); + dJointAttach(hinge2, body2, 0); + + transmission = dJointCreateTransmission(world, 0); + dJointAttach(transmission, body1, body2); + dJointSetFeedback(transmission, &feedback); + + setup(); + + // initial camera position + static float xyz[3] = {1.15,-2.78,4.1}; + static float hpr[3] = {105,-45.5,0}; + dsSetViewpoint (xyz,hpr); + + fprintf (stderr, + "The green wheel is driving the red one. To control it use the following:\n" + " '[' : decrease wheel ratio\n" + " ']' : increase wheel ratio\n" + " ',' : decrease driving wheel speed\n" + " '.' : increase driving wheel speed\n" + " '-' : decrease backlash\n" + " '=' : increase backlash\n" + " '1' : switch to parallel axes gears mode\n" + " '2' : switch to intersecting axes gears mode\n" + " '3' : switch to chain (or belt) mode\n" +); +} + +void stop() +{ + dSpaceDestroy(space); + + dWorldDestroy(world); +} + +void drawGeom(dGeomID g) +{ + int gclass = dGeomGetClass(g); + const dReal *pos = dGeomGetPosition(g); + const dReal *rot = dGeomGetRotation(g); + + switch (gclass) { + case dCylinderClass: + { + dReal length, radius; + + if (g == geom1) { + dsSetColorAlpha(1, 0, 0, 1); + } else { + dsSetColorAlpha(0, 1, 0, 1); + } + + dsSetTexture (DS_WOOD); + dGeomCylinderGetParams(g, &radius, &length); + dsDrawCylinder(pos, rot, length, radius); + break; + } + + default: + { + abort(); + } + } +} + +void simLoop(int pause) +{ + if (!pause) { + + const dReal step = 0.003; + const unsigned nsteps = 4; + + for (unsigned i=0; i<nsteps; ++i) { + dWorldQuickStep(world, step); + } + } + +#if 0 + { + const dReal *omega_1, *omega_2; + + omega_1 = dBodyGetAngularVel(body1); + omega_2 = dBodyGetAngularVel(body2); + + printf ("T1: %f, %f, %f\n", + feedback.t1[0], feedback.t1[1], feedback.t1[2]); + + printf ("T2: %f, %f, %f\n", + feedback.t2[0], feedback.t2[1], feedback.t2[2]); + + printf ("F1: %f, %f, %f\n", + feedback.f1[0], feedback.f1[1], feedback.f1[2]); + + printf ("F2: %f, %f, %f\n", + feedback.f2[0], feedback.f2[1], feedback.f2[2]); + } +#endif + + // now we draw everything + unsigned ngeoms = dSpaceGetNumGeoms(space); + for (unsigned i=0; i<ngeoms; ++i) { + dGeomID g = dSpaceGetGeom(space, i); + + drawGeom(g); + } + + const dReal *R_1 = dGeomGetRotation(geom1); + const dReal *R_2 = dGeomGetRotation(geom2); + dVector3 c_1, c_2, a_1, a_2; + + dJointGetTransmissionContactPoint1(transmission, c_1); + dJointGetTransmissionContactPoint2(transmission, c_2); + dJointGetTransmissionAnchor1(transmission, a_1); + dJointGetTransmissionAnchor2(transmission, a_2); + + dsSetColorAlpha(1, 0, 0, 0.5); + dsDrawCylinder(a_1, R_1, 0.05, dCalcPointsDistance3(c_1, a_1)); + dsSetColorAlpha(0, 1, 0, 0.5); + dsDrawCylinder(a_2, R_2, 0.05, dCalcPointsDistance3(c_2, a_2)); + + dsSetColorAlpha(1, 0, 0, 0.5); + dsDrawSphere (c_1, R_1, 0.05); + dsDrawSphere (c_2, R_1, 0.05); + + dsSetColorAlpha(1, 1, 0, 0.5); + if (mode == dTransmissionChainDrive) { + dsDrawLine(c_1, c_2); + } +} + +static void command (int cmd) +{ + if (cmd == '[') { + switch(mode) { + case dTransmissionParallelAxes: + if (ratio > 0.125) { + ratio *= 0.5; + + fprintf (stderr, "Gear ratio set to %.3f.\n", ratio); + } + break; + case dTransmissionIntersectingAxes: + if (theta > 0.1) { + theta -= 0.1; + + fprintf (stderr, "Gear angle set to %.3f deg.\n", + theta / M_PI * 180); + } + break; + case dTransmissionChainDrive: + if (rho_2 > 0.125) { + rho_2 /= 2; + + fprintf (stderr, "Sprocket ratio set to %.3f.\n", rho_2 / rho_1); + } + break; + } + + setup(); + } else if (cmd == ']') { + switch(mode) { + case dTransmissionParallelAxes: + if (ratio < 8) { + ratio *= 2; + + fprintf (stderr, "Gear ratio set to %.3f.\n", ratio); + } + break; + case dTransmissionIntersectingAxes: + if (theta < 0.9) { + theta += 0.1; + + fprintf (stderr, "Gear angle set to %.3f deg.\n", + theta / M_PI * 180); + } + break; + case dTransmissionChainDrive: + if (rho_2 < 2) { + rho_2 *= 2; + + fprintf (stderr, "Sprocket ratio set to %.3f.\n", rho_2 / rho_1); + } + break; + } + + setup(); + } else if (cmd == '.') { + speed += 5; + + fprintf (stderr, "Driving wheel speed set to %g rad/s.\n", speed); + + dJointSetHingeParam(hinge2, dParamVel, speed); + } else if (cmd == ',') { + speed -= 5; + + fprintf (stderr, "Driving wheel speed set to %g rad/s.\n", speed); + + dJointSetHingeParam(hinge2, dParamVel, speed); + } else if (cmd == '/') { + if (dJointGetHingeParam(hinge2, dParamFMax) > 0) { + dJointSetHingeParam(hinge2, dParamFMax, 0); + } else { + dJointSetHingeParam(hinge2, dParamFMax, 50); + } + + } else if (cmd == '-') { + backlash -= 0.1; + + fprintf (stderr, "Backlash set to %g m.\n", backlash); + + dJointSetTransmissionBacklash(transmission, backlash); + } else if (cmd == '=') { + backlash += 0.1; + + fprintf (stderr, "Backlash set to %g m.\n", backlash); + + dJointSetTransmissionBacklash(transmission, backlash); + } else if (cmd == '1') { + mode = dTransmissionParallelAxes; + setup(); + } else if (cmd == '2') { + mode = dTransmissionIntersectingAxes; + setup(); + } else if (cmd == '3') { + mode = dTransmissionChainDrive; + setup(); + } +} + +int main(int argc, char **argv) +{ + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = stop; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + // create world + dInitODE(); + + // run demo + dsSimulationLoop (argc, argv, 800, 600, &fn); + + dCloseODE(); + return 0; +} diff --git a/libs/ode-0.16.1/ode/demo/demo_trimesh.cpp b/libs/ode-0.16.1/ode/demo/demo_trimesh.cpp new file mode 100644 index 0000000..1c53334 --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/demo_trimesh.cpp @@ -0,0 +1,605 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// TriMesh test by Erwin de Vries + +#include <ode/ode.h> +#include <drawstuff/drawstuff.h> +#include "texturepath.h" + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + +//<---- Convex Object +static const dReal planes[] = // planes for a cube +{ + 1.0f ,0.0f ,0.0f ,0.25f, + 0.0f ,1.0f ,0.0f ,0.25f, + 0.0f ,0.0f ,1.0f ,0.25f, + 0.0f ,0.0f ,-1.0f,0.25f, + 0.0f ,-1.0f,0.0f ,0.25f, + -1.0f,0.0f ,0.0f ,0.25f + /* + 1.0f ,0.0f ,0.0f ,2.0f, + 0.0f ,1.0f ,0.0f ,1.0f, + 0.0f ,0.0f ,1.0f ,1.0f, + 0.0f ,0.0f ,-1.0f,1.0f, + 0.0f ,-1.0f,0.0f ,1.0f, + -1.0f,0.0f ,0.0f ,0.0f + */ +}; +static const unsigned int planecount=6; + +static const dReal points[] = // points for a cube +{ + 0.25f,0.25f,0.25f, + -0.25f,0.25f,0.25f, + + 0.25f,-0.25f,0.25f, + -0.25f,-0.25f,0.25f, + + 0.25f,0.25f,-0.25f, + -0.25f,0.25f,-0.25f, + + 0.25f,-0.25f,-0.25f, + -0.25f,-0.25f,-0.25f, +}; +static const unsigned int pointcount=8; + +static const unsigned int polygons[] = //Polygons for a cube (6 squares) + { + 4,0,2,6,4, // positive X + 4,1,0,4,5, // positive Y + 4,0,1,3,2, // positive Z + 4,3,1,5,7, // negative X + 4,2,3,7,6, // negative Y + 4,5,4,6,7, // negative Z + }; +//----> Convex Object + +// select correct drawing functions + +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#define dsDrawSphere dsDrawSphereD +#define dsDrawCylinder dsDrawCylinderD +#define dsDrawCapsule dsDrawCapsuleD +#define dsDrawLine dsDrawLineD +#define dsDrawTriangle dsDrawTriangleD +#define dsDrawConvex dsDrawConvexD +#endif + + +// some constants + +#define NUM 200 // max number of objects +#define DENSITY (5.0) // density of all objects +#define GPB 3 // maximum number of geometries per body +#define MAX_CONTACTS 40 // maximum number of contact points per body + + +// dynamics and collision objects + +struct MyObject { + dBodyID body; // the body + dGeomID geom[GPB]; // geometries representing this body +}; + +static int num=0; // number of objects in simulation +static int nextobj=0; // next object to recycle if num==NUM +static dWorldID world; +static dSpaceID space; +static MyObject obj[NUM]; +static dJointGroupID contactgroup; +static int selected = -1; // selected object +static int show_aabb = 0; // show geom AABBs? +static int show_contacts = 0; // show contact points? +static int random_pos = 1; // drop objects from random position? + +#define VertexCount 5 +#define IndexCount 12 + +static dVector3 Size; +static float Vertices[VertexCount][3]; +static dTriIndex Indices[IndexCount]; + +static dGeomID TriMesh; +static dGeomID Ray; + + +// this is called by dSpaceCollide when two objects in space are +// potentially colliding. + +static void nearCallback (void *, dGeomID o1, dGeomID o2) +{ + int i; + // if (o1->body && o2->body) return; + + // exit without doing anything if the two bodies are connected by a joint + dBodyID b1 = dGeomGetBody(o1); + dBodyID b2 = dGeomGetBody(o2); + if (b1 && b2 && dAreConnectedExcluding (b1,b2,dJointTypeContact)) return; + + dContact contact[MAX_CONTACTS]; // up to MAX_CONTACTS contacts per box-box + for (i=0; i<MAX_CONTACTS; i++) { + contact[i].surface.mode = dContactBounce | dContactSoftCFM; + contact[i].surface.mu = dInfinity; + contact[i].surface.mu2 = 0; + contact[i].surface.bounce = 0.1; + contact[i].surface.bounce_vel = 0.1; + contact[i].surface.soft_cfm = 0.01; + } + if (int numc = dCollide (o1,o2,MAX_CONTACTS,&contact[0].geom, + sizeof(dContact))) { + dMatrix3 RI; + dRSetIdentity (RI); + const dReal ss[3] = {0.02,0.02,0.02}; + for (i=0; i<numc; i++) { + if (dGeomGetClass(o1) == dRayClass || dGeomGetClass(o2) == dRayClass){ + dMatrix3 Rotation; + dRSetIdentity(Rotation); + dsDrawSphere(contact[i].geom.pos, Rotation, REAL(0.01)); + + dVector3 End; + End[0] = contact[i].geom.pos[0] + (contact[i].geom.normal[0] * contact[i].geom.depth); + End[1] = contact[i].geom.pos[1] + (contact[i].geom.normal[1] * contact[i].geom.depth); + End[2] = contact[i].geom.pos[2] + (contact[i].geom.normal[2] * contact[i].geom.depth); + End[3] = contact[i].geom.pos[3] + (contact[i].geom.normal[3] * contact[i].geom.depth); + + dsDrawLine(contact[i].geom.pos, End); + continue; + } + + dJointID c = dJointCreateContact (world,contactgroup,contact+i); + dJointAttach (c,b1,b2); + if (show_contacts) dsDrawBox (contact[i].geom.pos,RI,ss); + } + } +} + + +// start simulation - set viewpoint + +static void start() +{ + dAllocateODEDataForThread(dAllocateMaskAll); + + static float xyz[3] = {2.1640f,-1.3079f,1.7600f}; + static float hpr[3] = {125.5000f,-17.0000f,0.0000f}; + dsSetViewpoint (xyz,hpr); + printf ("To drop another object, press:\n"); + printf (" b for box.\n"); + printf (" s for sphere.\n"); + printf (" c for cylinder.\n"); + printf( " v for a convex.\n" ); + printf (" x for a composite object.\n"); + printf ("To select an object, press space.\n"); + printf ("To disable the selected object, press d.\n"); + printf ("To enable the selected object, press e.\n"); + printf ("To toggle showing the geom AABBs, press a.\n"); + printf ("To toggle showing the contact points, press t.\n"); + printf ("To toggle dropping from random position/orientation, press r.\n"); +} + + +char locase (char c) +{ + if (c >= 'A' && c <= 'Z') return c - ('a'-'A'); + else return c; +} + + +// called when a key pressed + +static void command (int cmd) +{ + int i,j,k; + dReal sides[3]; + dMass m; + bool setBody = false; + + cmd = locase (cmd); + if (cmd == 'b' || cmd == 's' || cmd == 'c' || cmd == 'x' || cmd == 'v' + /* || cmd == 'l' */) { + if (num < NUM) { + i = num; + num++; + } + else { + i = nextobj; + nextobj++; + if (nextobj >= num) nextobj = 0; + + // destroy the body and geoms for slot i + dBodyDestroy (obj[i].body); + for (k=0; k < GPB; k++) { + if (obj[i].geom[k]) dGeomDestroy (obj[i].geom[k]); + } + memset (&obj[i],0,sizeof(obj[i])); + } + + obj[i].body = dBodyCreate (world); + for (k=0; k<3; k++) sides[k] = dRandReal()*0.5+0.1; + + dMatrix3 R; + if (random_pos) { + dBodySetPosition (obj[i].body, + dRandReal()*2-1,dRandReal()*2-1,dRandReal()+1); + dRFromAxisAndAngle (R,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, + dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); + } + else { + dReal maxheight = 0; + for (k=0; k<num; k++) { + const dReal *pos = dBodyGetPosition (obj[k].body); + if (pos[2] > maxheight) maxheight = pos[2]; + } + dBodySetPosition (obj[i].body, 0,0,maxheight+1); + dRFromAxisAndAngle (R,0,0,1,dRandReal()*10.0-5.0); + } + dBodySetRotation (obj[i].body,R); + dBodySetData (obj[i].body,(void*)(dsizeint)i); + + if (cmd == 'b') { + dMassSetBox (&m,DENSITY,sides[0],sides[1],sides[2]); + obj[i].geom[0] = dCreateBox (space,sides[0],sides[1],sides[2]); + } + else if (cmd == 'c') { + sides[0] *= 0.5; + dMassSetCapsule (&m,DENSITY,3,sides[0],sides[1]); + obj[i].geom[0] = dCreateCapsule (space,sides[0],sides[1]); + } +/* + // cylinder option not yet implemented + else if (cmd == 'l') { + sides[1] *= 0.5; + dMassSetCapsule (&m,DENSITY,3,sides[0],sides[1]); + obj[i].geom[0] = dCreateCylinder (space,sides[0],sides[1]); + } +*/ + else if (cmd == 's') { + sides[0] *= 0.5; + dMassSetSphere (&m,DENSITY,sides[0]); + obj[i].geom[0] = dCreateSphere (space,sides[0]); + } + else if (cmd == 'x') { + + setBody = true; + // start accumulating masses for the composite geometries + dMass m2; + dMassSetZero (&m); + + dReal dpos[GPB][3]; // delta-positions for composite geometries + dMatrix3 drot[GPB]; + + // set random delta positions + for (j=0; j<GPB; j++) + for (k=0; k<3; k++) + dpos[j][k] = dRandReal()*0.3-0.15; + + for (k=0; k<GPB; k++) { + if (k==0) { + dReal radius = dRandReal()*0.25+0.05; + obj[i].geom[k] = dCreateSphere (space,radius); + dMassSetSphere (&m2,DENSITY,radius); + } else if (k==1) { + obj[i].geom[k] = dCreateBox(space,sides[0],sides[1],sides[2]); + dMassSetBox(&m2,DENSITY,sides[0],sides[1],sides[2]); + } else { + dReal radius = dRandReal()*0.1+0.05; + dReal length = dRandReal()*1.0+0.1; + obj[i].geom[k] = dCreateCapsule(space,radius,length); + dMassSetCapsule(&m2,DENSITY,3,radius,length); + } + + dRFromAxisAndAngle(drot[k],dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, + dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); + dMassRotate(&m2,drot[k]); + + dMassTranslate(&m2,dpos[k][0],dpos[k][1],dpos[k][2]); + + // add to the total mass + dMassAdd(&m,&m2); + + } + for (k=0; k<GPB; k++) { + dGeomSetBody(obj[i].geom[k],obj[i].body); + dGeomSetOffsetPosition(obj[i].geom[k], + dpos[k][0]-m.c[0], + dpos[k][1]-m.c[1], + dpos[k][2]-m.c[2]); + dGeomSetOffsetRotation(obj[i].geom[k], drot[k]); + } + dMassTranslate(&m,-m.c[0],-m.c[1],-m.c[2]); + dBodySetMass(obj[i].body,&m); + + } else if (cmd == 'v') { + + dMassSetBox (&m,DENSITY,0.25,0.25,0.25); + + obj[i].geom[0] = dCreateConvex(space, + planes, + planecount, + points, + pointcount, + polygons); + } + + if (!setBody) { // avoid calling for composite geometries + for (k=0; k < GPB; k++) + if (obj[i].geom[k]) + dGeomSetBody(obj[i].geom[k],obj[i].body); + + dBodySetMass(obj[i].body,&m); + } + } + + if (cmd == ' ') { + selected++; + if (selected >= num) selected = 0; + if (selected < 0) selected = 0; + } + else if (cmd == 'd' && selected >= 0 && selected < num) { + dBodyDisable (obj[selected].body); + } + else if (cmd == 'e' && selected >= 0 && selected < num) { + dBodyEnable (obj[selected].body); + } + else if (cmd == 'a') { + show_aabb ^= 1; + } + else if (cmd == 't') { + show_contacts ^= 1; + } + else if (cmd == 'r') { + random_pos ^= 1; + } +} + + +// draw a geom + +void drawGeom (dGeomID g, const dReal *pos, const dReal *R, int show_aabb) +{ + if (!g) return; + if (!pos) pos = dGeomGetPosition (g); + if (!R) R = dGeomGetRotation (g); + + int type = dGeomGetClass (g); + if (type == dBoxClass) { + dVector3 sides; + dGeomBoxGetLengths (g,sides); + dsDrawBox (pos,R,sides); + } + else if (type == dSphereClass) { + dsDrawSphere (pos,R,dGeomSphereGetRadius (g)); + } + else if (type == dCapsuleClass) { + dReal radius,length; + dGeomCapsuleGetParams (g,&radius,&length); + dsDrawCapsule (pos,R,length,radius); + } else if (type == dConvexClass) { + //dVector3 sides={0.50,0.50,0.50}; + dsDrawConvex(pos,R,planes, + planecount, + points, + pointcount, + polygons); + } +/* + // cylinder option not yet implemented + else if (type == dCylinderClass) { + dReal radius,length; + dGeomCylinderGetParams (g,&radius,&length); + dsDrawCylinder (pos,R,length,radius); + } +*/ + + if (show_aabb) { + // draw the bounding box for this geom + dReal aabb[6]; + dGeomGetAABB (g,aabb); + dVector3 bbpos; + for (int i=0; i<3; i++) bbpos[i] = 0.5*(aabb[i*2] + aabb[i*2+1]); + dVector3 bbsides; + for (int j=0; j<3; j++) bbsides[j] = aabb[j*2+1] - aabb[j*2]; + dMatrix3 RI; + dRSetIdentity (RI); + dsSetColorAlpha (1,0,0,0.5); + dsDrawBox (bbpos,RI,bbsides); + } +} + + +// simulation loop + +static void simLoop (int pause) +{ + dsSetColor (0,0,2); + dSpaceCollide (space,0,&nearCallback); + if (!pause) dWorldStep (world,0.05); + //if (!pause) dWorldStepFast (world,0.05, 1); + + // remove all contact joints + dJointGroupEmpty (contactgroup); + + dsSetColor (1,1,0); + dsSetTexture (DS_WOOD); + for (int i=0; i<num; i++) { + for (int j=0; j < GPB; j++) { + if (i==selected) { + dsSetColor (0,0.7,1); + } + else if (! dBodyIsEnabled (obj[i].body)) { + dsSetColor (1,0,0); + } + else { + dsSetColor (1,1,0); + } + drawGeom (obj[i].geom[j],0,0,show_aabb); + } + } + + /*{ + for (int i = 1; i < IndexCount; i++) { + dsDrawLine(Vertices[Indices[i - 1]], Vertices[Indices[i]]); + } + }*/ + + {const dReal* Pos = dGeomGetPosition(TriMesh); + const dReal* Rot = dGeomGetRotation(TriMesh); + + {for (int i = 0; i < IndexCount / 3; i++){ + const float *p = Vertices[Indices[i * 3 + 0]]; + const dVector3 v0 = { p[0], p[1], p[2] }; + p = Vertices[Indices[i * 3 + 1]]; + const dVector3 v1 = { p[0], p[1], p[2] }; + p = Vertices[Indices[i * 3 + 2]]; + const dVector3 v2 = { p[0], p[1], p[2] }; + dsDrawTriangle(Pos, Rot, v0, v1, v2, 0); + }}} + + if (Ray){ + dVector3 Origin, Direction; + dGeomRayGet(Ray, Origin, Direction); + + dReal Length = dGeomRayGetLength(Ray); + + dVector3 End; + End[0] = Origin[0] + (Direction[0] * Length); + End[1] = Origin[1] + (Direction[1] * Length); + End[2] = Origin[2] + (Direction[2] * Length); + End[3] = Origin[3] + (Direction[3] * Length); + + dsDrawLine(Origin, End); + } +} + + +int main (int argc, char **argv) +{ + // setup pointers to drawstuff callback functions + dsFunctions fn; + fn.version = DS_VERSION; + fn.start = &start; + fn.step = &simLoop; + fn.command = &command; + fn.stop = 0; + fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; + + // create world + dInitODE2(0); + world = dWorldCreate(); + + space = dSimpleSpaceCreate(0); + contactgroup = dJointGroupCreate (0); + dWorldSetGravity (world,0,0,-0.5); + dWorldSetCFM (world,1e-5); + //dCreatePlane (space,0,0,1,0); + memset (obj,0,sizeof(obj)); + + Size[0] = 5.0f; + Size[1] = 5.0f; + Size[2] = 2.5f; + + Vertices[0][0] = -Size[0]; + Vertices[0][1] = -Size[1]; + Vertices[0][2] = Size[2]; + + Vertices[1][0] = Size[0]; + Vertices[1][1] = -Size[1]; + Vertices[1][2] = Size[2]; + + Vertices[2][0] = Size[0]; + Vertices[2][1] = Size[1]; + Vertices[2][2] = Size[2]; + + Vertices[3][0] = -Size[0]; + Vertices[3][1] = Size[1]; + Vertices[3][2] = Size[2]; + + Vertices[4][0] = 0; + Vertices[4][1] = 0; + Vertices[4][2] = 0; + + Indices[0] = 0; + Indices[1] = 1; + Indices[2] = 4; + + Indices[3] = 1; + Indices[4] = 2; + Indices[5] = 4; + + Indices[6] = 2; + Indices[7] = 3; + Indices[8] = 4; + + Indices[9] = 3; + Indices[10] = 0; + Indices[11] = 4; + + dTriMeshDataID Data = dGeomTriMeshDataCreate(); + + //dGeomTriMeshDataBuildSimple(Data, (dReal*)Vertices, VertexCount, Indices, IndexCount); + dGeomTriMeshDataBuildSingle(Data, Vertices[0], 3 * sizeof(float), VertexCount, &Indices[0], IndexCount, 3 * sizeof(dTriIndex)); + dGeomTriMeshDataPreprocess2(Data, (1U << dTRIDATAPREPROCESS_BUILD_FACE_ANGLES), NULL); + + TriMesh = dCreateTriMesh(space, Data, 0, 0, 0); + + //dGeomSetPosition(TriMesh, 0, 0, 1.0); + + Ray = dCreateRay(space, 0.9); + dVector3 Origin, Direction; + Origin[0] = 0.0; + Origin[1] = 0; + Origin[2] = 0.5; + Origin[3] = 0; + + Direction[0] = 0; + Direction[1] = 1.1f; + Direction[2] = -1; + Direction[3] = 0; + dNormalize3(Direction); + + dGeomRaySet(Ray, Origin[0], Origin[1], Origin[2], Direction[0], Direction[1], Direction[2]); + + dThreadingImplementationID threading = dThreadingAllocateMultiThreadedImplementation(); + dThreadingThreadPoolID pool = dThreadingAllocateThreadPool(4, 0, dAllocateFlagBasicData, NULL); + dThreadingThreadPoolServeMultiThreadedImplementation(pool, threading); + // dWorldSetStepIslandsProcessingMaxThreadCount(world, 1); + dWorldSetStepThreadingImplementation(world, dThreadingImplementationGetFunctions(threading), threading); + + // run simulation + dsSimulationLoop (argc,argv,352,288,&fn); + + dThreadingImplementationShutdownProcessing(threading); + dThreadingFreeThreadPool(pool); + dWorldSetStepThreadingImplementation(world, NULL, NULL); + dThreadingFreeImplementation(threading); + + dJointGroupDestroy (contactgroup); + dSpaceDestroy (space); + dWorldDestroy (world); + dCloseODE(); + return 0; +} diff --git a/libs/ode-0.16.1/ode/demo/halton235_geom.h b/libs/ode-0.16.1/ode/demo/halton235_geom.h new file mode 100644 index 0000000..c571d4f --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/halton235_geom.h @@ -0,0 +1,2271 @@ +// Generated by ./Tools/mksrc.py + +// h00 +const int h00_numv = 14; +const int h00_numf = 9; +const dReal h00_volu = 0.105869; +const dReal h00_pos[3] = { -0.801161,-0.825905,-0.503586 }; +const dReal h00_verts[ h00_numv * 3 ] = { + -0.198839,-0.174095,-0.496414, -0.198839,-0.073069,-0.496414, 0.355754,-0.174095,0.317906, 0.266263,0.078525,-0.113353, -0.198839,0.418138,0.148658, -0.198839,0.151957,0.285583, -0.004749,-0.165186,-0.496414, -0.198839,0.342511,-0.068863, -0.198839,-0.174095,0.341490, 0.030157,-0.174095,0.397398, -0.005096,-0.174095,-0.496414, 0.428901,-0.174095,0.139324, -0.198839,0.419530,0.145078, -0.111897,0.386202,0.018538, +}; +const unsigned int h00_faces[] = { + 5, 7,13,3,6,1, + 4, 6,10,0,1, + 7, 0,8,5,4,12,7,1, + 6, 11,3,13,12,4,2, + 4, 4,5,9,2, + 6, 9,8,0,10,11,2, + 4, 11,10,6,3, + 3, 8,9,5, + 3, 12,13,7, +}; +const dReal h00_planes[ h00_numf * 4 ] = { + 0.322183,0.678839,-0.659831,0.213885,0,0,-1,0.496414,-1,3.46515e-16,1.34725e-16,0.198839,0.66261,0.69806,0.271405,0.200478,0.212159,0.447018,0.869002,0.273913,-0,-1,0,0.174095,0.825473,-0.0322069,-0.563523,0.281141,-0.233951,0.164312,0.958263,0.34515,-0.131169,0.932758,-0.335793,0.368685 +}; +// h01 +const int h01_numv = 16; +const int h01_numf = 10; +const dReal h01_volu = 0.123003; +const dReal h01_pos[3] = { -0.669502,-0.555335,-0.800913 }; +const dReal h01_verts[ h01_numv * 3 ] = { + 0.137874,0.266251,0.316069, -0.136407,-0.435756,-0.199087, -0.330498,0.127352,-0.199087, 0.378917,-0.091301,0.019367, 0.437409,0.033623,-0.016334, 0.038469,0.311615,0.180723, -0.330498,-0.343638,-0.199087, 0.193689,-0.157234,0.188948, 0.276656,-0.200503,-0.199087, 0.399981,0.033623,-0.199087, -0.039317,0.311615,-0.199087, -0.330498,0.071941,0.228464, 0.134604,-0.192045,0.183974, -0.243556,0.115632,0.315865, 0.128360,0.261346,0.324519, -0.053858,0.233367,0.333678, +}; +const unsigned int h01_faces[] = { + 5, 8,3,7,12,1, + 5, 12,13,11,6,1, + 6, 6,2,10,9,8,1, + 6, 11,13,15,5,10,2, + 3, 6,11,2, + 4, 8,9,4,3, + 5, 4,0,14,7,3, + 5, 9,10,5,0,4, + 4, 15,14,0,5, + 5, 14,15,13,12,7, +}; +const dReal h01_planes[ h01_numf * 4 ] = { + 0.485031,-0.851631,0.198669,0.265389,-0.322183,-0.678839,0.659831,0.208392,0,0,-1,0.199087,-0.53156,0.839996,0.108863,0.260981,-1,0,-0,0.330498,0.870584,-0.458578,-0.178296,0.368295,0.693474,-0.121763,0.710118,0.287639,0.531559,0.839996,-0.108863,0.26253,-0.120149,0.911352,0.393704,0.35052,0.0929092,-0.293639,0.951391,0.243929 +}; +// h02 +const int h02_numv = 22; +const int h02_numf = 13; +const dReal h02_volu = 0.069699; +const dReal h02_pos[3] = { -0.226726,-0.554920,-0.490680 }; +const dReal h02_verts[ h02_numv * 3 ] = { + 0.092179,-0.226103,0.260087, -0.296734,0.272195,0.041665, -0.063859,-0.091716,-0.290866, 0.291800,-0.116083,-0.104671, -0.005367,0.033207,-0.326567, 0.057499,0.071569,-0.315604, -0.314416,0.260931,0.014286, 0.001987,-0.310858,0.106391, 0.200664,0.041526,0.249449, -0.249087,-0.157649,-0.121285, 0.164143,-0.213455,-0.116915, 0.086533,-0.112211,0.311781, 0.301609,-0.100599,-0.031006, -0.013037,0.041374,0.269240, 0.214238,-0.145305,0.159971, -0.177599,0.337949,0.022880, -0.304902,0.265836,0.005836, 0.151444,0.029502,0.298046, 0.226514,0.065723,0.196331, -0.078156,0.329100,-0.024159, 0.053890,0.084483,0.272741, -0.198047,0.327898,0.050872, +}; +const unsigned int h02_faces[] = { + 4, 13,20,21,1, + 5, 21,15,16,6,1, + 7, 6,9,7,0,11,13,1, + 5, 9,6,16,4,2, + 5, 4,5,3,10,2, + 4, 10,7,9,2, + 5, 5,19,18,12,3, + 6, 12,14,0,7,10,3, + 5, 16,15,19,5,4, + 7, 18,19,15,21,20,17,8, + 5, 17,11,0,14,8, + 4, 14,12,18,8, + 4, 17,20,13,11, +}; +const dReal h02_planes[ h02_numf * 4 ] = { + -0.322885,0.43293,0.841615,0.248718,-0.488006,0.871758,-0.0434537,0.380285,-0.73548,-0.309929,0.602505,0.158984,-0.693474,0.121763,-0.710118,0.239666,0.398278,-0.419584,-0.815674,0.250302,-0.11362,-0.877785,-0.465387,0.223128,0.726907,0.646142,-0.23261,0.161453,0.598819,-0.796079,0.0875987,0.257978,-0.27553,0.653111,-0.705358,0.253514,0.315015,0.796483,0.516121,0.225033,0.709719,-0.26169,0.654077,0.294707,0.913105,-0.120244,0.389591,0.275417,-0.158394,0.166869,0.973173,0.270985 +}; +// h03 +const int h03_numv = 18; +const int h03_numf = 11; +const dReal h03_volu = 0.069585; +const dReal h03_pos[3] = { -0.013871,-0.718833,-0.869565 }; +const dReal h03_verts[ h03_numv * 3 ] = { + -0.207492,-0.281167,-0.130435, 0.113468,0.049972,0.264160, -0.007999,0.353837,-0.130435, 0.078945,0.047830,0.274214, -0.003048,-0.281167,0.119131, -0.048711,-0.049541,0.261970, -0.155356,0.235482,0.063281, 0.163083,-0.281167,0.065052, -0.378975,-0.037005,-0.130435, -0.276714,0.072197,0.088019, 0.263172,-0.281167,-0.130435, 0.247851,0.256254,-0.130435, 0.308871,0.008019,-0.130435, 0.268707,0.210552,0.010520, 0.116203,0.335344,-0.130435, 0.263499,0.226082,-0.009852, -0.255650,0.197121,-0.130435, -0.218222,0.197121,0.052318, +}; +const unsigned int h03_faces[] = { + 7, 13,15,14,2,6,3,1, + 5, 3,5,4,7,1, + 5, 7,10,12,13,1, + 4, 16,17,6,2, + 8, 14,11,12,10,0,8,16,2, + 5, 6,17,9,5,3, + 5, 5,9,8,0,4, + 4, 0,10,7,4, + 4, 9,17,16,8, + 3, 14,15,11, + 4, 15,13,12,11, +}; +const dReal h03_planes[ h03_numf * 4 ] = { + 0.119725,0.804079,0.582343,0.207598,0.274018,-0.465094,0.841785,0.230216,0.881437,-0.139289,0.451296,0.212269,-0.53156,0.839996,0.108863,0.287274,0,-0,-1,0.130435,-0.398278,0.419584,0.815674,0.212296,-0.679728,-0.477395,0.556833,0.202635,-0,-1,-0,0.281167,-0.870584,0.458578,0.178296,0.289704,0.509459,0.848006,0.146072,0.324522,0.968964,0.238186,-0.066148,0.309823 +}; +// h04 +const int h04_numv = 18; +const int h04_numf = 11; +const dReal h04_volu = 0.049776; +const dReal h04_pos[3] = { 0.037853,-0.892026,-0.431971 }; +const dReal h04_verts[ h04_numv * 3 ] = { + -0.100436,0.123651,-0.175624, 0.353999,-0.060233,0.083056, 0.061744,0.223165,-0.173434, -0.054772,-0.107974,-0.318463, 0.079577,0.232813,-0.134685, 0.365414,-0.107974,0.061633, 0.111359,-0.107974,-0.372542, -0.262592,0.026248,0.047682, -0.327682,-0.107974,0.107959, -0.050341,0.191801,0.101262, -0.248632,-0.107974,0.379486, -0.172400,0.111003,0.201378, 0.324182,-0.074827,0.146980, 0.312271,-0.107974,0.174077, -0.248842,-0.086035,0.364515, -0.264984,-0.107974,0.352871, 0.027221,0.221023,-0.163380, 0.037030,0.236507,-0.089715, +}; +const unsigned int h04_faces[] = { + 4, 12,13,5,1, + 5, 5,6,2,4,1, + 5, 4,17,9,12,1, + 4, 16,17,4,2, + 5, 6,3,0,16,2, + 4, 8,7,0,3, + 7, 6,5,13,10,15,8,3, + 5, 8,15,14,11,7, + 6, 11,9,17,16,0,7, + 6, 11,14,10,13,12,9, + 3, 14,15,10, +}; +const dReal h04_planes[ h04_numf * 4 ] = { + 0.903842,0.0244154,0.42717,0.353968,0.79204,0.397342,-0.463457,0.217956,0.496382,0.766976,0.406636,0.163295,-0.11569,0.975032,-0.189546,0.243324,-0.274018,0.465094,-0.841785,0.232868,-0.83085,0.164121,-0.531744,0.197127,0,-1,0,0.107974,-0.837582,0.502473,0.214421,0.243355,-0.598819,0.796079,-0.0875987,0.173963,0.289106,0.541464,0.789452,0.169241,-0.80443,0.32957,0.494242,0.35198 +}; +// h05 +const int h05_numv = 12; +const int h05_numf = 8; +const dReal h05_volu = 0.060052; +const dReal h05_pos[3] = { -0.361440,-0.882680,-0.728709 }; +const dReal h05_verts[ h05_numv * 3 ] = { + -0.444817,-0.117320,-0.271291, 0.140076,-0.117320,-0.271291, 0.136701,0.016901,0.344420, -0.031407,0.126842,-0.271291, 0.070855,0.236044,-0.052837, -0.114373,0.170111,0.116744, 0.344521,-0.117320,-0.021725, 0.298857,0.114305,0.121114, -0.444469,-0.108411,-0.271291, 0.071611,-0.117320,0.404697, -0.173458,0.135300,0.111770, -0.010820,-0.117320,0.364447, +}; +const unsigned int h05_faces[] = { + 5, 3,4,7,6,1, + 5, 6,9,11,0,1, + 4, 0,8,3,1, + 5, 5,10,11,9,2, + 4, 9,6,7,2, + 4, 7,4,5,2, + 5, 8,10,5,4,3, + 4, 0,11,10,8, +}; +const dReal h05_planes[ h05_numf * 4 ] = { + 0.679728,0.477395,-0.556833,0.190269,0,-1,0,0.11732,0,0,-1,0.271291,-0.373525,0.524676,0.76498,0.221281,0.83085,-0.164121,0.531744,0.293948,0.11362,0.877785,0.465387,0.190656,-0.485031,0.851631,-0.198669,0.177153,-0.825473,0.0322069,0.563523,0.210527 +}; +// h06 +const int h06_numv = 16; +const int h06_numf = 10; +const dReal h06_volu = 0.067458; +const dReal h06_pos[3] = { 0.885250,-0.616510,-0.689541 }; +const dReal h06_verts[ h06_numv * 3 ] = { + -0.230633,-0.043361,0.025874, -0.001305,-0.383490,-0.079103, 0.114750,-0.383490,0.055891, 0.114750,0.141993,-0.310459, 0.042572,0.157183,0.322917, 0.114750,0.349093,0.009138, 0.114750,-0.209139,-0.310459, 0.114750,-0.383490,-0.220772, 0.114750,0.143660,0.326163, -0.023969,0.120047,-0.310459, -0.230634,0.218132,-0.108639, -0.072958,0.349093,0.054965, -0.138827,-0.119612,0.199579, 0.020027,-0.383490,0.025057, -0.041036,-0.038390,0.301047, 0.114750,-0.091790,0.305977, +}; +const unsigned int h06_faces[] = { + 6, 0,10,9,6,7,1, + 4, 7,2,13,1, + 4, 13,12,0,1, + 5, 15,14,12,13,2, + 7, 7,6,3,5,8,15,2, + 5, 9,10,11,5,3, + 3, 6,9,3, + 4, 14,15,8,4, + 4, 8,5,11,4, + 6, 11,10,0,12,14,4, +}; +const dReal h06_planes[ h06_numf * 4 ] = { + -0.735479,-0.309932,-0.602505,0.167476,0,-1,0,0.38349,-0.794108,-0.585614,0.162633,0.212748,-0.239912,-0.631869,0.73701,0.255977,1,-0,0,0.11475,-0.131611,0.831909,-0.539079,0.270385,0,0,-1,0.310459,-0.0606999,-0.0852635,0.994508,0.305158,0.131611,0.831909,0.539078,0.310442,-0.793214,0.278548,0.541501,0.184874 +}; +// h07 +const int h07_numv = 18; +const int h07_numf = 11; +const dReal h07_volu = 0.100040; +const dReal h07_pos[3] = { 0.439796,-0.816642,-0.690430 }; +const dReal h07_verts[ h07_numv * 3 ] = { + -0.290584,-0.183358,-0.114083, 0.444149,-0.183358,-0.078214, -0.340199,0.147781,0.085025, -0.036530,-0.183358,0.320092, -0.047944,-0.135617,0.341515, 0.306627,0.080520,0.200468, -0.322367,0.157429,0.123774, 0.465481,-0.183358,0.025945, 0.214820,0.156771,0.026763, -0.144796,0.105827,-0.309570, 0.159858,-0.183358,-0.309570, -0.190496,-0.183358,-0.309570, -0.155412,0.298926,0.091748, -0.184960,0.308361,-0.168615, -0.134267,0.332806,-0.106403, 0.196572,0.110989,0.274357, -0.157992,0.325768,-0.131745, -0.142419,0.333870,-0.095406, +}; +const unsigned int h07_faces[] = { + 7, 10,9,13,16,14,8,1, + 4, 8,5,7,1, + 6, 7,3,0,11,10,1, + 6, 6,12,17,16,13,2, + 5, 13,9,11,0,2, + 5, 0,3,4,6,2, + 5, 7,5,15,4,3, + 4, 15,12,6,4, + 6, 8,14,17,12,15,5, + 3, 10,11,9, + 3, 16,17,14, +}; +const dReal h07_planes[ h07_numf * 4 ] = { + 0.525603,0.55372,-0.645861,0.182432,0.794108,0.585614,-0.162633,0.258045,0,-1,0,0.183358,-0.632147,0.768422,0.0995875,0.337082,-0.881437,0.139289,-0.451296,0.282078,-0.79204,-0.397342,0.463457,0.250137,0.488522,-0.25733,0.833743,0.296212,-0.212159,0.447016,0.869003,0.246326,0.381225,0.903643,0.195187,0.228784,-1.58443e-16,2.50379e-17,-1,0.30957,-0.105626,0.979232,-0.173057,0.35849 +}; +// h08 +const int h08_numv = 22; +const int h08_numf = 13; +const dReal h08_volu = 0.095115; +const dReal h08_pos[3] = { 0.582909,-0.382310,-0.514785 }; +const dReal h08_verts[ h08_numv * 3 ] = { + 0.039696,0.333763,-0.114253, -0.040720,0.073975,-0.343437, -0.281418,0.194479,0.107755, 0.071707,-0.016068,-0.283395, 0.071707,-0.277561,-0.148882, 0.163514,-0.353812,0.024824, 0.072380,0.310495,-0.182078, 0.344912,-0.077018,0.148161, 0.229382,0.114893,-0.119790, 0.056106,0.251986,0.176207, 0.261304,-0.272590,0.126291, 0.053460,-0.323343,0.098712, -0.280479,0.198156,0.096008, -0.285532,-0.100462,-0.271051, 0.094134,-0.250952,0.200497, -0.277380,-0.101526,-0.282048, -0.010614,0.002589,0.315575, -0.026292,0.211375,0.249710, 0.146296,0.123570,0.286302, 0.056041,0.119791,0.321947, -0.290185,0.102104,0.127875, -0.298525,-0.135406,-0.083897, +}; +const unsigned int h08_faces[] = { + 6, 15,13,12,0,6,1, + 4, 6,8,3,1, + 4, 3,4,15,1, + 5, 20,16,19,17,2, + 5, 17,9,0,12,2, + 5, 12,13,21,20,2, + 6, 8,7,10,5,4,3, + 6, 5,11,21,13,15,4, + 4, 10,14,11,5, + 6, 0,9,18,7,8,6, + 6, 18,19,16,14,10,7, + 4, 17,19,18,9, + 5, 14,16,20,21,11, +}; +const dReal h08_planes[ h08_numf * 4 ] = { + -0.595386,0.627237,-0.502085,0.243079,0.598205,0.236327,-0.765702,0.256094,0.107916,-0.45476,-0.884052,0.265581,-0.484779,0.229821,0.843903,0.272055,-0.215549,0.936705,0.275902,0.272559,-0.995125,0.0827659,-0.053632,0.290362,0.793214,-0.278548,-0.541501,0.214813,-0.381225,-0.903643,-0.195187,0.252539,0.131611,-0.83191,0.539077,0.329242,0.750032,0.646492,0.139642,0.229594,0.364346,-0.255892,0.895417,0.278042,0.228161,0.721101,0.654183,0.30978,-0.595564,-0.522855,0.609857,0.197424 +}; +// h09 +const int h09_numv = 16; +const int h09_numf = 10; +const dReal h09_volu = 0.059582; +const dReal h09_pos[3] = { 0.627742,-0.657906,-0.898694 }; +const dReal h09_verts[ h09_numv * 3 ] = { + -0.028087,-0.342094,-0.101306, 0.372258,-0.342094,-0.101306, 0.233539,0.161443,-0.101306, 0.372258,-0.167743,-0.101306, 0.256203,-0.342094,0.130050, 0.372258,-0.342094,-0.011619, -0.322212,0.174071,0.101861, 0.026875,-0.001965,0.235027, -0.098160,0.388838,-0.101306, 0.026875,0.259528,0.100514, -0.332742,-0.052909,-0.101306, -0.085552,0.349571,0.040471, -0.393762,0.195327,-0.101306, -0.372906,0.149626,0.039648, -0.378114,0.165155,0.019276, -0.345937,0.167033,0.076519, +}; +const unsigned int h09_faces[] = { + 7, 0,10,12,8,2,3,1, + 3, 3,5,1, + 4, 5,4,0,1, + 4, 8,11,9,2, + 6, 9,7,4,5,3,2, + 7, 7,6,15,13,10,0,4, + 6, 11,8,12,14,15,6, + 4, 7,9,11,6, + 4, 13,14,12,10, + 3, 15,14,13, +}; +const dReal h09_planes[ h09_numf * 4 ] = { + 0,0,-1,0.101306,1,0,0,0.372258,0,-1,0,0.342094,0.55667,0.812007,0.175394,0.243329,0.735479,0.309932,0.602505,0.160762,-0.525603,-0.55372,0.645861,0.138757,-0.527367,0.805591,0.270012,0.337657,-0.107916,0.45476,0.884052,0.203982,-0.968964,-0.238186,0.066148,0.328316,-0.830322,0.320028,0.456232,0.375605 +}; +// h10 +const int h10_numv = 18; +const int h10_numf = 11; +const dReal h10_volu = 0.082139; +const dReal h10_pos[3] = { -0.348593,-0.203405,-0.827574 }; +const dReal h10_verts[ h10_numv * 3 ] = { + 0.351136,-0.038001,-0.172426, 0.318157,0.110282,-0.172426, -0.183035,-0.085679,0.342730, -0.360226,-0.040315,-0.172426, 0.190400,0.248876,-0.172426, 0.296736,0.161596,-0.025823, 0.116500,-0.318307,0.010327, -0.282440,-0.040315,0.207384, -0.155944,0.334915,-0.140051, -0.055732,-0.013566,0.359774, 0.296359,0.169251,-0.045236, -0.155944,0.347503,-0.172426, 0.079072,-0.318307,-0.172426, 0.043711,-0.022416,0.312735, 0.326723,-0.161591,-0.172426, 0.179366,-0.279946,0.021290, 0.100706,0.105108,0.263039, 0.042697,0.111008,0.290353, +}; +const unsigned int h10_faces[] = { + 4, 10,5,0,1, + 7, 0,14,12,3,11,4,1, + 3, 4,10,1, + 5, 6,15,13,9,2, + 5, 9,17,8,7,2, + 5, 7,3,12,6,2, + 4, 7,8,11,3, + 7, 11,8,17,16,5,10,4, + 6, 16,13,15,14,0,5, + 4, 12,14,15,6, + 4, 13,16,17,9, +}; +const dReal h10_planes[ h10_numf * 4 ] = { + 0.973989,0.216619,0.066491,0.322306,-0,0,-1,0.172426,0.722579,0.66608,-0.18498,0.335245,0.27553,-0.653111,0.705358,0.247274,-0.46199,0.681388,0.567693,0.220745,-0.531559,-0.839996,0.108863,0.206575,-0.870584,0.458578,0.178296,0.264376,0.256529,0.900843,0.350248,0.212649,0.830851,-0.164118,0.531744,0.206291,0.53156,-0.839996,-0.108863,0.328179,0.433652,0.152283,0.888119,0.293288 +}; +// h11 +const int h11_numv = 18; +const int h11_numf = 11; +const dReal h11_volu = 0.058443; +const dReal h11_pos[3] = { -0.902277,0.042835,-0.283464 }; +const dReal h11_verts[ h11_numv * 3 ] = { + 0.065494,-0.341848,-0.057123, 0.194525,0.153131,-0.091230, -0.097723,-0.350111,0.163707, 0.194525,-0.144351,0.061796, 0.065493,0.122511,-0.295991, -0.097723,-0.183345,0.306682, -0.097723,0.152153,0.335446, -0.097723,-0.428001,-0.052654, 0.107269,-0.156775,0.196004, -0.097723,0.199975,-0.375687, 0.037223,0.358435,0.033582, -0.097723,0.406471,-0.057020, -0.067761,-0.416891,-0.051054, -0.040073,-0.340339,0.134552, 0.056142,-0.350169,-0.055126, 0.004412,-0.376327,-0.008857, 0.025793,-0.108438,0.290488, -0.096343,0.152412,0.335215, +}; +const unsigned int h11_faces[] = { + 5, 4,9,11,10,1, + 6, 10,17,16,8,3,1, + 4, 3,0,4,1, + 5, 7,12,15,13,2, + 5, 13,8,16,5,2, + 6, 5,6,11,9,7,2, + 6, 8,13,15,14,0,3, + 6, 0,14,12,7,9,4, + 4, 16,17,6,5, + 4, 17,10,11,6, + 3, 14,15,12, +}; +const dReal h11_planes[ h11_numf * 4 ] = { + 0.553062,0.69918,-0.453068,0.255983,0.793213,0.278551,0.5415,0.147553,0.835369,-0.251444,-0.48881,0.168589,0.314046,-0.893286,0.321583,0.334705,0.443092,-0.583496,0.68059,0.272405,-1,0,0,0.0977235,0.66062,-0.653782,0.368986,0.245683,0.212159,-0.447018,-0.869002,0.216347,0.179474,-0.0840327,0.980167,0.298468,-0.066237,0.837367,0.542613,0.315898,0.474713,-0.879502,0.0335246,0.332778 +}; +// h12 +const int h12_numv = 22; +const int h12_numf = 13; +const dReal h12_volu = 0.106128; +const dReal h12_pos[3] = { -0.838340,-0.076123,-0.758521 }; +const dReal h12_verts[ h12_numv * 3 ] = { + 0.207307,-0.167597,0.138331, 0.129521,-0.167597,-0.241479, -0.161660,0.318933,0.099371, 0.312802,0.272050,-0.241479, -0.161660,-0.330252,0.400013, -0.074718,-0.363580,0.273473, 0.001556,0.241469,0.179066, -0.161660,-0.309043,0.422403, -0.161660,-0.407271,0.186072, -0.161660,-0.351860,-0.241479, -0.007794,-0.231211,0.419931, 0.001557,-0.222890,0.417934, 0.309084,0.269226,-0.210613, -0.161660,0.422173,-0.241479, 0.072963,0.309250,0.057032, -0.161660,0.392766,-0.014569, -0.131698,-0.297933,0.424004, -0.161660,-0.327468,0.404309, 0.114980,-0.245845,0.291286, 0.009169,-0.227496,0.411012, 0.333803,0.207633,-0.209104, 0.333803,0.220221,-0.241479, +}; +const unsigned int h12_faces[] = { + 6, 0,18,5,8,9,1, + 5, 9,13,3,21,1, + 4, 21,20,0,1, + 4, 6,14,15,2, + 8, 15,13,9,8,4,17,7,2, + 6, 7,16,10,11,6,2, + 4, 12,20,21,3, + 5, 13,15,14,12,3, + 7, 5,18,19,10,16,17,4, + 3, 8,5,4, + 8, 11,19,18,0,20,12,14,6, + 3, 17,16,7, + 3, 19,11,10, +}; +const dReal h12_planes[ h12_numf * 4 ] = { + 0.53156,-0.839996,-0.108863,0.235917,0,0,-1,0.241479,0.870584,-0.458578,-0.178296,0.23267,0.131611,0.83191,0.539077,0.297616,-1,0,0,0.16166,-0.212159,0.447018,0.869002,0.263219,0.917084,0.371595,0.144476,0.353071,0.299389,0.946218,0.12263,0.321456,0.425203,-0.759567,0.4922,0.378997,0.131169,-0.932758,0.335793,0.421162,0.735479,0.309932,0.602505,0.183872,0.216442,-0.684063,0.696571,0.470649,0.494656,-0.366713,0.787932,0.411811 +}; +// h13 +const int h13_numv = 22; +const int h13_numf = 13; +const dReal h13_volu = 0.080573; +const dReal h13_pos[3] = { -0.579196,0.019592,-0.524795 }; +const dReal h13_verts[ h13_numv * 3 ] = { + -0.186181,0.213535,-0.176694, 0.154423,-0.034973,0.266436, 0.105286,0.335497,0.021835, 0.055737,-0.302317,0.075780, -0.128556,-0.121108,0.303127, 0.252786,0.058395,0.170378, -0.257588,0.145754,-0.054660, 0.097995,0.334920,0.024505, 0.093556,-0.038093,0.287537, 0.074659,0.111918,-0.442830, -0.051837,-0.263312,-0.095394, -0.257587,-0.318605,0.184208, 0.273300,-0.111989,-0.012426, 0.049940,0.173511,-0.444339, -0.026589,0.239892,0.129875, -0.128556,0.176374,0.150102, 0.038054,-0.313581,0.048402, 0.047568,-0.308676,0.039952, -0.249976,-0.323211,0.177286, -0.144164,-0.341560,0.057561, 0.174871,-0.236563,0.056995, 0.154423,-0.246614,0.084987, +}; +const unsigned int h13_faces[] = { + 5, 21,20,12,5,1, + 6, 5,2,7,14,8,1, + 7, 8,4,11,18,3,21,1, + 5, 5,12,9,13,2, + 4, 13,0,7,2, + 5, 16,17,20,21,3, + 4, 18,19,16,3, + 4, 8,14,15,4, + 4, 15,6,11,4, + 5, 15,14,7,0,6, + 8, 0,13,9,10,19,18,11,6, + 5, 12,20,17,10,9, + 4, 17,16,19,10, +}; +const dReal h13_planes[ h13_numf * 4 ] = { + 0.805487,-0.385719,0.449901,0.257745,0.24653,0.556538,0.793403,0.229997,0.284317,-0.624016,0.727852,0.259655,0.904761,0.357436,-0.231619,0.21012,-0.184883,0.934913,-0.302912,0.287581,0.488006,-0.871758,0.0434537,0.29404,0.159459,-0.944944,0.285751,0.316215,-0.107916,0.45476,0.884052,0.226779,-0.835369,0.251444,0.48881,0.225111,-0.493234,0.850287,0.183662,0.240945,-0.735479,-0.309932,-0.602505,0.17721,0.46199,-0.681388,-0.567693,0.209624,0.120149,-0.911352,-0.393704,0.271298 +}; +// h14 +const int h14_numv = 24; +const int h14_numf = 14; +const dReal h14_volu = 0.092625; +const dReal h14_pos[3] = { 0.037294,-0.326434,-0.629340 }; +const dReal h14_verts[ h14_numv * 3 ] = { + 0.244511,-0.164440,-0.192835, -0.034752,0.085028,-0.370660, -0.037506,-0.162763,0.334991, -0.206521,-0.156917,-0.176944, 0.151340,0.267484,0.166363, 0.265137,0.142280,0.210563, 0.260084,-0.156338,-0.156496, -0.285181,0.228137,0.064806, 0.037588,-0.329085,0.107655, -0.342176,0.100614,0.114501, 0.027780,-0.344569,0.033990, -0.089151,0.284625,-0.224057, -0.059164,-0.038562,-0.370660, 0.065038,-0.057055,-0.370660, 0.036995,0.362842,0.085406, 0.062303,-0.342427,0.023935, 0.217542,-0.181847,-0.229705, 0.212334,-0.166317,-0.250077, 0.224212,0.171137,0.236256, 0.080136,-0.332779,0.062684, 0.146779,-0.002116,0.303773, 0.264198,0.138603,0.222310, 0.247091,-0.191282,0.030659, 0.255431,0.046228,0.242430, +}; +const unsigned int h14_faces[] = { + 6, 12,3,9,7,11,1, + 9, 11,14,4,5,6,0,17,13,1, + 3, 13,12,1, + 6, 8,19,22,23,20,2, + 7, 20,18,4,14,7,9,2, + 5, 9,3,10,8,2, + 7, 12,13,17,16,15,10,3, + 4, 18,21,5,4, + 5, 21,23,22,6,5, + 6, 22,19,15,16,0,6, + 3, 14,11,7, + 4, 10,15,19,8, + 3, 17,0,16, + 4, 20,23,21,18, +}; +const dReal h14_planes[ h14_numf * 4 ] = { + -0.830851,0.164118,-0.531744,0.239924,0.738081,0.518376,-0.431883,0.178509,0,0,-1,0.37066,0.582463,-0.552262,0.596442,0.267845,-0.240814,0.443968,0.863077,0.225893,-0.726907,-0.646142,0.23261,0.210353,-0.119725,-0.804079,-0.582343,0.253941,0.662611,0.698059,0.271405,0.33215,0.995125,-0.0827659,0.053632,0.263362,0.632147,-0.768422,-0.0995875,0.300129,-0.380333,0.921564,-0.0778922,0.313659,0.11569,-0.975032,0.189546,0.345622,0.830322,-0.320028,-0.456232,0.343625,0.433652,0.152283,0.888119,0.333115 +}; +// h15 +const int h15_numv = 16; +const int h15_numf = 10; +const dReal h15_volu = 0.047330; +const dReal h15_pos[3] = { 0.221274,0.213040,-0.893886 }; +const dReal h15_verts[ h15_numv * 3 ] = { + -0.273508,-0.247194,0.021075, -0.214206,0.249387,-0.106114, -0.394680,0.092354,-0.106114, 0.468273,-0.026582,-0.106114, -0.379467,-0.167569,-0.106114, -0.251710,-0.306163,-0.106114, -0.130453,-0.090301,0.212222, 0.215618,0.100683,0.162583, 0.108399,0.111587,0.216806, 0.543500,0.089559,-0.106114, 0.556660,0.080198,-0.106114, 0.496376,0.018888,-0.040935, 0.000444,-0.021162,0.246756, 0.322381,0.024676,0.097420, 0.541635,0.087788,-0.096097, 0.556215,0.081512,-0.106114, +}; +const unsigned int h15_faces[] = { + 5, 2,6,12,8,1, + 5, 8,7,14,9,1, + 8, 9,15,10,3,5,4,2,1, + 4, 4,0,6,2, + 3, 10,11,3, + 7, 11,13,12,6,0,5,3, + 3, 5,0,4, + 6, 13,11,10,15,14,7, + 4, 8,12,13,7, + 3, 14,15,9, +}; +const dReal h15_planes[ h15_numf * 4 ] = { + -0.469359,0.539421,0.69909,0.160881,0.201934,0.957321,0.206781,0.173545,0,0,-1,0.106114,-0.781405,-0.0457332,0.622346,0.238142,0.765488,-0.633631,0.11198,0.363418,0.324513,-0.835692,0.443069,0.127159,-0.722579,-0.66608,0.18498,0.366181,0.613049,0.207593,0.762283,0.27702,0.433652,-0.152283,0.888119,0.222564,0.518906,0.82,0.241527,0.329834 +}; +// h16 +const int h16_numv = 24; +const int h16_numf = 14; +const dReal h16_volu = 0.105221; +const dReal h16_pos[3] = { -0.230932,0.200668,-0.677519 }; +const dReal h16_verts[ h16_numv * 3 ] = { + 0.072738,-0.155197,-0.322481, 0.178698,-0.234822,-0.195293, -0.074965,-0.293065,0.140297, -0.273605,-0.069158,-0.290106, -0.242978,0.154421,0.174559, 0.321753,-0.077929,-0.004145, 0.331656,-0.130769,0.158361, -0.234281,0.105965,-0.322481, 0.057526,0.104725,-0.322481, -0.070916,0.357222,-0.022485, 0.179075,-0.242477,-0.175878, 0.305221,-0.164260,0.133584, 0.289986,0.017556,0.326217, -0.205442,0.224195,0.181431, -0.273605,-0.056571,-0.322481, -0.016955,-0.298965,0.112984, -0.012263,0.183238,-0.322481, -0.122870,0.351842,-0.002882, -0.294606,-0.004741,-0.322481, -0.298324,-0.007565,-0.291615, 0.354068,-0.072999,0.110530, 0.306083,0.044665,0.287425, 0.072223,0.006072,0.394149, -0.095479,-0.122681,0.323101, +}; +const unsigned int h16_faces[] = { + 7, 10,15,2,3,14,0,1, + 4, 0,8,5,1, + 6, 5,20,6,11,10,1, + 7, 15,11,6,12,22,23,2, + 5, 23,4,19,3,2, + 4, 19,18,14,3, + 4, 23,22,13,4, + 6, 13,17,7,18,19,4, + 6, 8,16,9,21,20,5, + 4, 20,21,12,6, + 4, 17,9,16,7, + 6, 16,8,0,14,18,7, + 6, 17,13,22,12,21,9, + 3, 11,15,10, +}; +const dReal h16_planes[ h16_numf * 4 ] = { + -0.256529,-0.900843,-0.350248,0.234098,0.781405,0.0457332,-0.622346,0.250435,0.837582,-0.502473,-0.214421,0.309541,0.247318,-0.694798,0.675344,0.27983,-0.904761,-0.357436,0.231619,0.205073,-0.917084,-0.371595,-0.144476,0.318531,-0.501077,0.186311,0.84511,0.298042,-0.876412,0.477567,-0.0618929,0.275891,0.726908,0.64614,-0.232611,0.184496,0.941719,-0.0992098,0.32144,0.376203,-0.28037,0.805551,-0.521997,0.31938,0,0,-1,0.322481,0.148211,0.780702,0.607074,0.254723,0.380333,-0.921564,0.0778922,0.277867 +}; +// h17 +const int h17_numv = 26; +const int h17_numf = 15; +const dReal h17_volu = 0.108916; +const dReal h17_pos[3] = { 0.335926,-0.094685,-0.795267 }; +const dReal h17_verts[ h17_numv * 3 ] = { + 0.319363,0.022871,0.098404, -0.388160,0.060531,-0.077543, 0.353621,0.281144,-0.204733, 0.207729,0.332401,-0.001198, 0.193656,-0.174383,-0.204733, -0.101947,-0.367894,-0.204733, -0.366362,0.001562,-0.204733, -0.261637,0.131093,0.251333, 0.356211,0.239639,0.008049, -0.212790,0.222354,0.228279, -0.038549,-0.388087,0.009431, -0.033495,-0.089469,0.376490, -0.054122,-0.396189,-0.026907, 0.286680,0.046139,0.166229, 0.206263,-0.213650,-0.062955, -0.030396,-0.389151,-0.001566, -0.086298,-0.398066,-0.084150, -0.233594,-0.288804,-0.204733, -0.114208,0.286563,0.148137, -0.245105,0.217424,0.113603, 0.376946,0.258587,-0.036908, 0.381724,0.326613,-0.139554, -0.147292,0.035735,0.332290, -0.235202,0.164584,0.276109, -0.333383,-0.146721,-0.204733, -0.387783,0.052876,-0.058130, +}; +const unsigned int h17_faces[] = { + 4, 6,24,25,1, + 6, 25,7,23,9,19,1, + 7, 19,18,3,21,2,6,1, + 6, 21,20,0,14,4,2, + 6, 4,5,17,24,6,2, + 4, 8,20,21,3, + 8, 18,9,23,22,11,13,8,3, + 6, 14,15,12,16,5,4, + 3, 16,17,5, + 3, 22,23,7, + 9, 25,24,17,16,12,10,11,22,7, + 4, 13,0,20,8, + 3, 18,19,9, + 6, 15,14,0,13,11,10, + 3, 12,15,10, +}; +const dReal h17_planes[ h17_numf * 4 ] = { + -0.973989,-0.216619,-0.066491,0.370108,-0.837582,0.502473,0.214421,0.338905,-0.324513,0.835692,-0.443069,0.210905,0.929286,-0.326334,-0.173016,0.27229,-4.07036e-16,-9.05266e-17,-1,0.204733,0.43192,0.742413,0.512121,0.335888,0.289106,0.541464,0.789452,0.239093,0.527367,-0.805591,-0.270012,0.297889,-0.509459,-0.848006,-0.146072,0.39382,-0.621965,-0.0849382,0.778424,0.347238,-0.738081,-0.518376,0.431883,0.2337,0.903842,0.0244154,0.42717,0.331247,-0.485104,0.868795,0.0993492,0.319085,0.595386,-0.627237,0.502085,0.225206,0.105626,-0.979232,0.173057,0.377587 +}; +// h18 +const int h18_numv = 18; +const int h18_numf = 11; +const dReal h18_volu = 0.081077; +const dReal h18_pos[3] = { 0.870716,-0.039183,-0.528244 }; +const dReal h18_verts[ h18_numv * 3 ] = { + -0.102809,0.184137,0.110997, 0.129284,0.393063,-0.471756, 0.129284,0.325763,0.151471, 0.124364,0.395398,-0.471756, -0.058424,-0.228234,-0.106332, 0.057106,-0.420144,0.161620, -0.248110,-0.009363,-0.100794, -0.231701,-0.091141,0.189666, 0.129284,-0.228234,-0.152159, 0.129284,-0.433667,0.164866, 0.129284,-0.166980,0.404939, -0.141510,-0.219557,0.299761, 0.129284,0.397646,-0.471756, -0.215427,-0.032631,-0.168619, 0.102902,0.388713,-0.463077, 0.129284,0.404181,-0.453605, -0.178579,0.184137,-0.258974, -0.157844,0.203085,-0.303931, +}; +const unsigned int h18_faces[] = { + 7, 8,4,13,17,14,3,1, + 3, 3,12,1, + 7, 12,15,2,10,9,8,1, + 6, 15,14,17,16,0,2, + 5, 0,7,11,10,2, + 4, 14,15,12,3, + 6, 5,11,7,6,13,4, + 4, 8,9,5,4, + 4, 9,10,11,5, + 4, 16,17,13,6, + 4, 7,0,16,6, +}; +const dReal h18_planes[ h18_numf * 4 ] = { + -0.212159,-0.447018,-0.869002,0.206822,0,-0,-1,0.471756,1,0,-0,0.129284,-0.53156,0.839996,0.108863,0.221407,-0.398278,0.419585,0.815673,0.208745,-0.395039,0.86436,-0.311169,0.439434,-0.750032,-0.646492,-0.139642,0.206219,-0.131611,-0.831909,-0.539078,0.25488,-0.156805,-0.660773,0.734024,0.387299,-0.903842,-0.0244154,-0.42717,0.267537,-0.870583,0.45858,0.178295,0.193736 +}; +// h19 +const int h19_numv = 16; +const int h19_numf = 10; +const dReal h19_volu = 0.057269; +const dReal h19_pos[3] = { 0.808301,-0.134672,-0.879100 }; +const dReal h19_verts[ h19_numv * 3 ] = { + 0.052980,-0.361791,-0.120900, 0.191699,-0.339845,-0.120900, -0.030366,0.427910,-0.120900, 0.191699,0.488552,-0.120900, -0.118754,0.321131,-0.120900, 0.191699,-0.132745,0.198697, 0.186779,0.490887,-0.120900, 0.003992,-0.132745,0.244524, -0.153012,0.062857,0.182237, -0.153685,-0.263706,0.080920, -0.278719,-0.134396,-0.120900, -0.266112,-0.173663,0.020877, -0.090651,0.366600,-0.055721, -0.095429,0.298574,0.046924, -0.012422,0.433588,-0.120900, 0.165316,0.484202,-0.112221, +}; +const unsigned int h19_faces[] = { + 5, 5,7,9,0,1, + 8, 0,10,4,2,14,6,3,1, + 3, 3,5,1, + 5, 12,13,15,14,2, + 3, 4,12,2, + 7, 6,15,13,8,7,5,3, + 6, 10,11,8,13,12,4, + 3, 14,15,6, + 4, 8,11,9,7, + 4, 11,10,0,9, +}; +const dReal h19_planes[ h19_numf * 4 ] = { + 0.131611,-0.831909,0.539079,0.242775,-4.33777e-17,-9.13967e-17,-1,0.1209,1,0,0,0.191699,-0.256638,0.811103,0.525594,0.291328,-0.765488,0.633631,-0.11198,0.307921,0.212159,0.447018,0.869002,0.153999,-0.929286,0.326334,0.173016,0.194234,-0.275992,0.959497,0.0565231,0.412621,-0.598205,-0.236327,0.765702,0.216216,-0.55667,-0.812007,-0.175394,0.28549 +}; +// h20 +const int h20_numv = 30; +const int h20_numf = 17; +const dReal h20_volu = 0.107509; +const dReal h20_pos[3] = { 0.402458,0.140897,-0.404353 }; +const dReal h20_verts[ h20_numv * 3 ] = { + -0.100408,0.282050,-0.142576, 0.065914,0.236686,0.319509, -0.125820,0.203801,0.337118, 0.365449,0.004057,-0.012894, 0.056400,0.231781,0.327959, 0.034434,0.172826,-0.326950, -0.072786,0.183730,-0.272727, -0.247229,0.030507,0.295489, 0.136546,-0.281738,0.161639, 0.289679,0.004057,-0.382865, 0.141197,0.096819,-0.392113, -0.100966,-0.328728,-0.002677, -0.140953,-0.296194,0.011269, -0.180740,0.050981,-0.242777, -0.253566,0.024492,0.286206, -0.033492,0.282050,0.184162, 0.236557,-0.271221,0.065774, 0.154159,-0.311832,0.139278, -0.301735,-0.070997,-0.114805, -0.213824,-0.199847,-0.058625, -0.310451,0.100424,0.233258, -0.241567,0.131963,0.326249, -0.062874,0.247232,-0.227963, -0.327109,0.098788,0.164544, -0.279322,-0.013228,-0.162635, -0.343405,0.077327,0.053051, -0.313038,0.127071,0.015013, -0.327307,0.104436,0.014259, -0.100027,-0.325051,-0.014425, 0.220147,-0.189444,-0.224685, +}; +const unsigned int h20_faces[] = { + 8, 3,9,10,5,22,0,15,1, + 4, 15,2,4,1, + 6, 4,8,17,16,3,1, + 7, 15,0,26,23,20,21,2, + 5, 21,7,8,4,2, + 4, 16,29,9,3, + 3, 6,22,5, + 4, 10,13,6,5, + 7, 13,24,27,26,0,22,6, + 6, 14,12,11,17,8,7, + 4, 21,20,14,7, + 8, 29,28,19,18,24,13,10,9, + 5, 28,29,16,17,11, + 4, 12,19,28,11, + 7, 14,20,23,25,18,19,12, + 4, 25,27,24,18, + 4, 26,27,25,23, +}; +const dReal h20_planes[ h20_numf * 4 ] = { + 0.531561,0.839995,-0.108864,0.199069,-0.120149,0.911351,0.393704,0.333576,0.693474,-0.121763,0.710118,0.243778,-0.53156,0.839996,0.108863,0.274773,0.0929092,-0.293639,0.951391,0.249197,0.870583,-0.45858,-0.178295,0.318592,-0.320422,0.578682,-0.749971,0.334181,-0.433652,0.152283,-0.888119,0.301757,-0.720506,0.471135,-0.508826,0.277775,-0.322183,-0.678839,0.659831,0.253916,-0.770892,-0.145024,0.620237,0.369436,-0.289106,-0.541464,-0.789452,0.21631,0.215549,-0.936705,-0.275902,0.286897,-0.662611,-0.698059,-0.271405,0.297099,-0.847832,-0.483811,0.217045,0.265252,-0.941719,0.0992098,-0.32144,0.314009,-0.846082,0.532633,0.0211314,0.332856 +}; +// h21 +const int h21_numv = 20; +const int h21_numf = 12; +const dReal h21_volu = 0.107886; +const dReal h21_pos[3] = { -0.701261,0.516623,-0.734170 }; +const dReal h21_verts[ h21_numv * 3 ] = { + 0.220060,-0.162111,0.233880, -0.071194,0.139979,-0.265830, 0.326350,0.086982,0.076961, 0.175723,-0.320696,-0.265830, -0.194481,0.286846,0.262411, 0.236048,-0.209990,-0.265830, -0.298739,0.200252,0.166960, 0.264887,-0.091760,0.238083, 0.347459,0.035887,0.053770, -0.298739,0.031984,-0.265830, -0.298739,-0.199980,-0.038920, -0.298739,-0.170573,-0.265830, -0.064116,-0.283496,0.032682, 0.172005,-0.323520,-0.234964, 0.067327,0.317485,0.021628, 0.227351,-0.161534,0.231210, 0.015724,0.286846,0.365050, -0.065674,0.367082,0.311546, 0.153155,0.171345,0.362933, 0.139764,0.180879,0.371107, +}; +const unsigned int h21_faces[] = { + 6, 9,6,4,17,14,1, + 5, 14,2,8,5,1, + 5, 5,3,11,9,1, + 4, 18,7,8,2, + 6, 14,17,16,19,18,2, + 6, 5,8,7,15,13,3, + 5, 13,12,10,11,3, + 3, 16,17,4, + 7, 6,10,12,0,19,16,4, + 4, 9,11,10,6, + 5, 18,19,0,15,7, + 4, 13,15,0,12, +}; +const dReal h21_planes[ h21_numf * 4 ] = { + -0.404539,0.852363,-0.331398,0.236209,0.595564,0.522855,-0.609857,0.192906,-1.16998e-16,-0,-1,0.26583,0.864691,0.138024,0.482969,0.331367,0.636259,0.754085,0.162882,0.285771,0.876412,-0.477567,0.0618929,0.290707,-0.299389,-0.946218,-0.12263,0.283437,-0.433652,0.152285,0.888119,0.361071,-0.398278,-0.419584,0.815674,0.171144,-1,0,0,0.298739,0.349687,-0.276295,0.895198,0.331112,0.184883,-0.934913,0.302912,0.26309 +}; +// h22 +const int h22_numv = 14; +const int h22_numf = 9; +const dReal h22_volu = 0.065276; +const dReal h22_pos[3] = { -0.383570,0.726249,-0.891974 }; +const dReal h22_verts[ h22_numv * 3 ] = { + 0.403835,0.273751,-0.108026, -0.250365,0.107859,0.179431, -0.224444,0.273751,-0.108026, 0.311631,-0.076337,-0.108026, -0.388885,-0.069647,-0.108026, 0.349740,0.107545,0.033083, 0.400677,0.273751,-0.064850, -0.189576,0.273751,0.079255, 0.008658,-0.122644,0.234765, -0.081643,-0.419616,-0.108026, 0.029768,-0.173739,0.211573, 0.125191,-0.098941,0.194122, 0.140375,-0.342343,-0.108026, 0.081722,-0.168359,0.191970, +}; +const unsigned int h22_faces[] = { + 6, 8,11,5,6,7,1, + 4, 7,2,4,1, + 5, 4,9,10,8,1, + 4, 7,6,0,2, + 6, 0,3,12,9,4,2, + 5, 5,11,13,12,3, + 4, 0,6,5,3, + 4, 10,13,11,8, + 4, 12,13,10,9, +}; +const dReal h22_planes[ h22_numf * 4 ] = { + 0.212159,0.447018,0.869002,0.151024,-0.889469,0.425934,0.165603,0.298347,-0.595564,-0.522855,0.609857,0.202141,0,1,0,0.273751,0,0,-1,0.108026,0.758508,-0.488331,0.431507,0.227038,0.964613,-0.254054,0.0705546,0.312375,0.364346,-0.255892,0.895417,0.244751,0.28037,-0.805551,0.521997,0.258742 +}; +// h23 +const int h23_numv = 16; +const int h23_numf = 10; +const dReal h23_volu = 0.051599; +const dReal h23_pos[3] = { -0.800668,0.450995,-0.472891 }; +const dReal h23_verts[ h23_numv * 3 ] = { + 0.035291,-0.217869,-0.228598, -0.199332,-0.134353,-0.300199, -0.199332,0.265879,-0.094319, -0.095074,0.352473,0.001132, -0.199332,-0.001690,0.132407, -0.199332,-0.208186,-0.186260, 0.189555,0.299490,0.167366, -0.199332,0.309177,-0.027504, -0.064385,-0.049725,0.223009, -0.036116,-0.285650,-0.106564, 0.116475,0.143410,0.211970, 0.319467,-0.096483,-0.027399, 0.092916,-0.255030,0.098198, 0.194883,-0.191512,0.077971, 0.239171,0.246507,0.109828, 0.115131,0.352473,0.103771, +}; +const unsigned int h23_faces[] = { + 4, 0,9,5,1, + 5, 5,4,7,2,1, + 7, 2,3,15,14,11,0,1, + 3, 7,3,2, + 7, 7,4,8,10,6,15,3, + 5, 5,9,12,8,4, + 3, 14,15,6, + 5, 10,13,11,14,6, + 4, 12,13,10,8, + 5, 0,11,13,12,9, +}; +const dReal h23_planes[ h23_numf * 4 ] = { + -0.131611,-0.83191,-0.539077,0.299835,-1,6.69634e-17,-4.33923e-17,0.199332,0.398278,0.419584,-0.815674,0.109103,-0.195313,0.823048,-0.533334,0.308068,-0.398278,0.419585,0.815673,0.186681,-0.553062,-0.69918,0.453068,0.171414,0.647541,0.750402,-0.132616,0.325287,0.693474,-0.121763,0.710118,0.213834,0.349687,-0.276295,0.895198,0.190861,0.493234,-0.850287,-0.183662,0.244643 +}; +// h24 +const int h24_numv = 12; +const int h24_numf = 8; +const dReal h24_volu = 0.050770; +const dReal h24_pos[3] = { -0.845297,0.862613,-0.757515 }; +const dReal h24_verts[ h24_numv * 3 ] = { + 0.078361,0.021092,0.334891, -0.154703,-0.145738,0.190305, -0.154703,0.137387,-0.242485, -0.154703,-0.314006,-0.242485, 0.072842,-0.206011,-0.242485, 0.237283,0.137387,-0.242485, -0.154703,-0.102441,0.257120, -0.050445,-0.059144,0.285756, 0.211362,-0.028505,0.044972, -0.154703,0.137387,0.380489, 0.272151,0.137387,-0.055204, 0.060041,0.137387,0.393596, +}; +const unsigned int h24_faces[] = { + 3, 7,6,1, + 5, 6,9,2,3,1, + 6, 3,4,8,0,7,1, + 4, 5,4,3,2, + 5, 9,11,10,5,2, + 4, 5,10,8,4, + 5, 7,0,11,9,6, + 4, 10,11,0,8, +}; +const dReal h24_planes[ h24_numf * 4 ] = { + 0.195313,-0.823048,0.533334,0.19123,-1,0,0,0.154703,0.404539,-0.852363,0.331398,0.124705,0,0,-1,0.242485,0,1,-0,0.137387,0.889469,-0.425934,-0.165603,0.192694,-0.0541955,-0.456759,0.887938,0.283483,0.901694,-0.0730722,0.426155,0.211832 +}; +// h25 +const int h25_numv = 16; +const int h25_numf = 10; +const dReal h25_volu = 0.064196; +const dReal h25_pos[3] = { 0.265380,0.609017,-0.859766 }; +const dReal h25_verts[ h25_numv * 3 ] = { + 0.171512,-0.295294,0.128463, -0.112864,0.390983,-0.140234, -0.179972,0.258217,0.163631, -0.171482,0.390983,0.031499, -0.146465,0.312621,0.159756, 0.063572,-0.117444,0.267684, -0.245115,0.390983,-0.140234, -0.337319,0.040895,-0.140234, 0.499394,-0.306418,-0.140234, 0.112578,-0.021086,0.259138, 0.074204,-0.220888,0.227450, 0.064293,-0.284390,0.182686, -0.258312,-0.146590,-0.140234, 0.497529,-0.308188,-0.130217, -0.299210,0.224777,0.000875, -0.248273,0.390983,-0.097058, +}; +const unsigned int h25_faces[] = { + 6, 3,4,9,13,8,1, + 5, 8,12,7,6,1, + 4, 6,15,3,1, + 7, 14,7,12,11,10,5,2, + 4, 5,9,4,2, + 5, 4,3,15,14,2, + 5, 10,0,13,9,5, + 4, 7,14,15,6, + 5, 13,0,11,12,8, + 3, 11,0,10, +}; +const dReal h25_planes[ h25_numf * 4 ] = { + 0.727925,0.639055,0.248465,0.13286,0,-0,-1,0.140234,0,1,0,0.390983,-0.735479,-0.309932,0.602505,0.150925,-0.158394,0.166867,0.973173,0.230836,-0.747363,0.49209,0.446425,0.33462,0.598205,-0.236329,0.765702,0.270751,-0.964613,0.254054,-0.0705546,0.345666,-0.201934,-0.957321,-0.206781,0.221494,0.320422,-0.578682,0.749971,0.322182 +}; +// h26 +const int h26_numv = 24; +const int h26_numf = 14; +const dReal h26_volu = 0.101687; +const dReal h26_pos[3] = { -0.341007,0.877992,-0.537072 }; +const dReal h26_verts[ h26_numv * 3 ] = { + 0.358114,0.122008,-0.419752, -0.168425,-0.052359,0.397165, -0.220490,-0.180490,0.174009, 0.459922,0.043646,-0.162938, 0.324251,-0.109249,-0.070985, -0.202046,0.011183,0.424477, 0.252084,0.007514,0.202105, -0.286958,0.122008,0.388199, 0.307177,-0.044198,-0.321819, 0.426415,-0.010758,-0.159063, 0.082627,-0.250684,-0.160780, -0.033904,-0.274387,-0.120138, -0.232139,0.122008,-0.275647, -0.292928,-0.043884,-0.175471, -0.344531,-0.074523,0.167952, -0.207099,-0.190024,0.165835, -0.444249,0.122008,0.173153, -0.425929,0.005713,0.114448, 0.327136,0.122008,0.185091, -0.202046,0.122008,0.443480, 0.434905,0.122008,-0.291195, 0.483509,0.122008,-0.120325, -0.187210,-0.038985,0.408631, -0.270106,-0.127507,0.231547, +}; +const unsigned int h26_faces[] = { + 5, 22,23,2,15,1, + 6, 15,11,10,4,6,1, + 6, 6,18,19,5,22,1, + 3, 23,14,2, + 6, 14,17,13,11,15,2, + 3, 20,21,3, + 6, 21,18,6,4,9,3, + 5, 9,8,0,20,3, + 4, 10,8,9,4, + 3, 19,7,5, + 7, 7,16,17,14,23,22,5, + 8, 19,18,21,20,0,12,16,7, + 6, 10,11,13,12,0,8, + 4, 13,17,16,12, +}; +const dReal h26_planes[ h26_numf * 4 ] = { + -0.256638,-0.811103,0.525594,0.29444,0.324513,-0.835692,0.443069,0.165071,0.433652,-0.152285,0.888119,0.287665,-0.647541,-0.750402,0.132616,0.301294,-0.636259,-0.754085,-0.162882,0.248051,0.95246,-0.139363,-0.270922,0.476118,0.791095,-0.458379,0.40504,0.277839,0.747363,-0.49209,-0.446425,0.39499,0.555832,-0.7947,-0.243931,0.284365,-0.540055,-0.142236,0.829524,0.459639,-0.742791,-0.391264,0.543299,0.37632,0,1,0,0.122008,-0.212159,-0.447018,-0.869002,0.234249,-0.901694,0.0730722,-0.426155,0.335702 +}; +// h27 +const int h27_numv = 24; +const int h27_numf = 14; +const dReal h27_volu = 0.100588; +const dReal h27_pos[3] = { 0.167088,0.649940,-0.364014 }; +const dReal h27_verts[ h27_numv * 3 ] = { + -0.183844,0.118803,-0.244043, -0.044353,-0.266136,0.405236, -0.256011,0.235567,0.029047, 0.161864,-0.158366,-0.228068, 0.300539,0.065664,-0.127155, -0.024586,0.350060,-0.293383, -0.048173,0.271698,-0.335996, -0.180959,0.350060,0.012033, -0.081680,0.217294,-0.332121, -0.044357,0.350060,0.088262, -0.006196,-0.377080,0.285910, 0.201878,-0.226993,0.143823, -0.003872,-0.277036,0.420726, 0.210870,-0.062009,-0.236614, -0.003871,0.350060,0.098146, 0.183618,0.350060,-0.130723, -0.165155,-0.254165,0.331667, -0.075081,-0.408619,0.192919, -0.091738,-0.410255,0.124205, 0.005721,-0.287236,0.414262, -0.077668,-0.381972,-0.025325, -0.102748,-0.401170,0.182332, 0.134962,-0.226993,-0.182915, 0.109551,-0.305242,0.296779, +}; +const unsigned int h27_faces[] = { + 7, 16,21,17,10,19,12,1, + 4, 12,14,9,1, + 5, 9,7,2,16,1, + 6, 7,5,6,8,0,2, + 6, 0,20,18,21,16,2, + 5, 13,4,11,22,3, + 5, 22,20,0,8,3, + 4, 8,6,13,3, + 5, 13,6,5,15,4, + 7, 15,14,12,19,23,11,4, + 5, 7,9,14,15,5, + 7, 17,18,20,22,11,23,10, + 3, 23,19,10, + 3, 21,18,17, +}; +const dReal h27_planes[ h27_numf * 4 ] = { + -0.40667,-0.730271,0.54893,0.434835,-0.212159,0.447018,0.869002,0.242593,-0.444511,0.409753,0.796563,0.233461,-0.791095,0.458379,-0.40504,0.298742,-0.954535,-0.263372,-0.139635,0.178273,0.870583,-0.45858,-0.178295,0.254203,-0.309646,-0.434949,-0.84554,0.211601,0.158394,-0.166867,-0.973173,0.274014,0.598205,0.236328,-0.765702,0.292665,0.73548,0.309929,0.602505,0.16478,1.09327e-15,1,1.13815e-15,0.35006,0.53156,-0.839996,-0.108863,0.282326,0.425203,-0.759567,0.4922,0.424508,-0.292039,-0.95183,0.0934524,0.428891 +}; +// h28 +const int h28_numv = 18; +const int h28_numf = 11; +const dReal h28_volu = 0.075441; +const dReal h28_pos[3] = { 0.013616,0.472900,-0.719797 }; +const dReal h28_verts[ h28_numv * 3 ] = { + -0.187022,-0.167506,-0.280203, 0.109520,-0.345231,0.152809, -0.085555,0.177012,-0.280203, -0.271995,0.154408,0.021945, -0.030372,0.295843,0.111740, 0.061535,-0.227567,0.329703, 0.075804,-0.204932,0.330457, 0.071792,0.394334,0.023662, 0.208102,-0.281022,0.072668, -0.047446,0.360894,-0.139094, 0.077205,-0.350161,0.038133, -0.006548,-0.010473,-0.280203, 0.288434,-0.049953,0.172868, 0.315336,0.018674,0.127715, 0.316057,-0.148273,0.042717, 0.325968,-0.084770,0.087482, -0.256811,-0.088994,-0.280203, -0.315464,0.084990,0.019794, +}; +const unsigned int h28_faces[] = { + 7, 8,14,15,12,6,5,1, + 6, 5,17,16,0,10,1, + 3, 10,8,1, + 5, 16,17,3,9,2, + 7, 9,7,13,15,14,11,2, + 4, 11,0,16,2, + 5, 17,5,6,4,3, + 4, 4,7,9,3, + 5, 6,12,13,7,4, + 5, 10,0,11,14,8, + 3, 15,13,12, +}; +const dReal h28_planes[ h28_numf * 4 ] = { + 0.720506,-0.471135,0.508826,0.319313,-0.726908,-0.64614,0.232611,0.179002,0.485104,-0.868795,-0.0993492,0.337882,-0.758508,0.488331,-0.431507,0.272244,0.735479,0.309932,-0.602505,0.160762,0,0,-1,0.280203,-0.469484,0.267909,0.841315,0.187527,-0.555832,0.7947,0.243931,0.279245,0.309646,0.434949,0.84554,0.213753,0.469359,-0.539421,-0.69909,0.198463,0.901694,-0.0730722,0.426155,0.337399 +}; +// h29 +const int h29_numv = 20; +const int h29_numf = 12; +const dReal h29_volu = 0.090754; +const dReal h29_pos[3] = { -0.195482,0.549508,-0.348926 }; +const dReal h29_verts[ h29_numv * 3 ] = { + -0.062897,0.077801,-0.348926, 0.254536,-0.331284,-0.002375, -0.179429,0.054098,-0.308283, 0.178726,0.219235,-0.259131, -0.352624,0.138460,-0.022310, 0.259822,-0.300738,0.167244, 0.197415,-0.153733,0.316579, 0.065987,-0.327570,0.133724, 0.114982,-0.134660,0.333685, 0.270633,-0.304175,-0.041168, -0.106366,0.008382,-0.351078, 0.106560,0.335999,0.013959, -0.240892,-0.124645,-0.147161, -0.313950,0.276125,0.209019, -0.158320,0.003002,-0.331475, 0.036774,-0.342768,0.065557, 0.284902,-0.281540,-0.040413, 0.270832,-0.309823,0.109117, 0.013405,-0.084041,0.336165, 0.046528,-0.137097,0.329090, +}; +const unsigned int h29_faces[] = { + 4, 9,16,17,1, + 5, 17,5,7,15,1, + 6, 15,12,14,10,9,1, + 4, 0,10,14,2, + 4, 14,12,4,2, + 6, 4,13,11,3,0,2, + 5, 16,9,10,0,3, + 6, 11,6,5,17,16,3, + 7, 12,15,7,19,18,13,4, + 5, 6,8,19,7,5, + 5, 11,13,18,8,6, + 3, 18,19,8, +}; +const dReal h29_planes[ h29_numf * 4 ] = { + 0.846082,-0.532633,-0.0211314,0.391862,0.105626,-0.979232,0.173057,0.350878,-0.148211,-0.780702,-0.607074,0.22235,-0.364346,0.255892,-0.895417,0.355259,-0.864691,-0.138024,-0.482969,0.296575,-0.324513,0.835692,-0.443069,0.240027,0.469484,-0.267909,-0.841315,0.243184,0.954535,0.263372,0.139635,0.192157,-0.73808,-0.518378,0.431882,0.178854,-0.0212658,-0.716912,0.696839,0.326619,0.289106,0.541462,0.789453,0.223758,-0.0600487,-0.168696,0.983837,0.344105 +}; +// h30 +const int h30_numv = 26; +const int h30_numf = 15; +const dReal h30_volu = 0.141813; +const dReal h30_pos[3] = { 0.709749,0.432546,-0.520590 }; +const dReal h30_verts[ h30_numv * 3 ] = { + 0.086130,-0.133630,-0.479410, 0.290251,-0.067548,-0.461259, 0.290251,0.254276,-0.130163, -0.166094,-0.194830,-0.275875, -0.114073,0.017151,0.452790, 0.263868,-0.083016,-0.470730, -0.015645,0.141724,0.383369, -0.170984,0.316821,0.046789, -0.242122,0.283058,0.029421, 0.290251,0.110614,0.239339, -0.340783,-0.009598,0.300399, 0.290251,-0.018830,0.261535, 0.067740,-0.137994,-0.479410, -0.241377,-0.054963,0.435747, 0.058158,-0.287592,0.103343, 0.290251,-0.145966,0.143817, 0.068185,-0.139308,-0.479410, -0.017612,-0.287592,-0.266628, 0.053160,-0.131717,-0.469392, -0.272857,-0.118823,-0.210712, 0.007901,-0.200618,-0.414231, 0.003123,-0.268644,-0.311584, -0.331791,0.155385,-0.080037, -0.407699,-0.009598,-0.026339, -0.380797,0.059028,-0.071491, -0.370165,-0.044416,-0.111725, +}; +const unsigned int h30_faces[] = { + 6, 15,14,17,21,5,1, + 9, 5,0,12,18,22,8,7,2,1, + 5, 2,9,11,15,1, + 4, 7,6,9,2, + 4, 20,21,17,3, + 8, 17,14,13,10,23,25,19,3, + 6, 19,18,12,16,20,3, + 5, 13,14,15,11,4, + 4, 11,9,6,4, + 6, 6,7,8,10,13,4, + 5, 21,20,16,0,5, + 5, 22,24,23,10,8, + 3, 0,16,12, + 5, 19,25,24,22,18, + 3, 24,25,23, +}; +const dReal h30_planes[ h30_numf * 4 ] = { + 0.53156,-0.839996,-0.108863,0.26124,-0.167754,0.706913,-0.687119,0.220498,1,-0,0,0.290251,0.256529,0.900844,0.350247,0.257932,-0.43192,-0.742413,-0.512121,0.357665,-0.531561,-0.839995,0.108864,0.221912,-0.613049,-0.207593,-0.762283,0.352564,0.275531,-0.653109,0.705359,0.276747,0.433652,0.152285,0.888119,0.355275,-0.46199,0.681388,0.567693,0.321433,0.256638,-0.811103,-0.525594,0.382466,-0.870583,0.45858,0.178295,0.345838,-0,0,-1,0.479409,-0.598205,0.236329,-0.765702,0.296486,-0.901694,0.0730722,-0.426155,0.378142 +}; +// h31 +const int h31_numv = 20; +const int h31_numf = 12; +const dReal h31_volu = 0.145607; +const dReal h31_pos[3] = { 0.628702,0.773411,-0.793457 }; +const dReal h31_verts[ h31_numv * 3 ] = { + -0.189575,0.226589,0.317223, 0.371298,-0.414948,-0.206543, -0.476185,0.226589,-0.206543, 0.371298,0.226589,-0.206543, -0.250744,-0.185480,0.192828, 0.148787,-0.478859,-0.206543, -0.509787,0.148227,0.093447, -0.534804,0.226589,-0.034811, -0.277996,0.226589,0.298719, -0.486200,0.226589,0.136059, 0.371298,-0.408413,-0.188392, 0.167177,-0.474495,-0.206543, 0.366378,-0.417196,-0.206543, 0.344915,-0.423881,-0.197864, 0.371298,-0.086589,0.142703, 0.371298,0.226589,0.089002, -0.161075,-0.057807,0.302287, -0.089936,-0.024044,0.319655, 0.134207,-0.472582,-0.196526, 0.136072,-0.470812,-0.206543, +}; +const unsigned int h31_faces[] = { + 4, 10,13,12,1, + 7, 12,11,5,19,2,3,1, + 5, 3,15,14,10,1, + 6, 19,18,4,6,7,2, + 7, 7,9,8,0,15,3,2, + 5, 16,8,9,6,4, + 9, 18,5,11,13,10,14,17,16,4, + 3, 18,19,5, + 3, 9,7,6, + 4, 16,17,0,8, + 3, 12,13,11, + 4, 15,0,17,14, +}; +const dReal h31_planes[ h31_numf * 4 ] = { + 0.395039,-0.86436,0.311169,0.441071,-0,-0,-1,0.206543,1,-0,0,0.371298,-0.727925,-0.639055,-0.248465,0.253143,4.94863e-17,1,-0,0.226589,-0.598205,-0.236328,0.765702,0.341479,0.167754,-0.706913,0.687119,0.221551,-0.518906,-0.82,-0.241527,0.365343,-0.95246,0.139363,0.270922,0.531526,-0.204299,-0.0717432,0.976276,0.332171,0.275992,-0.959497,-0.0565231,0.51309,0.372229,0.156858,0.91479,0.255169 +}; +// h32 +const int h32_numv = 22; +const int h32_numf = 13; +const dReal h32_volu = 0.092552; +const dReal h32_pos[3] = { -0.648077,-0.694629,-0.055690 }; +const dReal h32_verts[ h32_numv * 3 ] = { + -0.351923,0.020682,-0.162313, -0.351923,0.291038,-0.298522, 0.116588,0.074450,0.304425, 0.180292,0.145010,-0.063690, -0.351923,0.286862,-0.299238, 0.082653,-0.305371,0.200452, 0.444715,-0.214767,0.086986, 0.440565,-0.305371,0.060643, 0.437298,-0.305371,0.003205, 0.441236,-0.180086,0.007980, 0.202670,-0.305371,-0.129990, -0.122926,-0.305371,-0.050498, -0.351923,0.343433,0.003710, 0.034975,0.067995,0.334312, -0.249787,0.361137,-0.236631, 0.059834,0.222599,0.089656, 0.420946,-0.305371,-0.023410, 0.437088,-0.283432,-0.011766, -0.351923,0.387353,-0.064067, -0.294272,0.397125,-0.093222, -0.351923,0.309463,-0.280428, -0.321961,0.320573,-0.278827, +}; +const unsigned int h32_faces[] = { + 3, 20,21,1, + 9, 21,14,3,9,17,16,10,4,1, + 6, 4,0,12,18,20,1, + 5, 13,5,7,6,2, + 5, 6,9,3,15,2, + 6, 15,19,18,12,13,2, + 4, 14,19,15,3, + 4, 10,11,0,4, + 5, 13,12,0,11,5, + 6, 11,10,16,8,7,5, + 5, 7,8,17,9,6, + 3, 16,17,8, + 5, 21,20,18,19,14, +}; +const dReal h32_planes[ h32_numf * 4 ] = { + -0.216442,0.684063,-0.696571,0.483201,0.433652,0.152285,-0.888119,0.156831,-1,0,0,0.351923,0.349687,-0.276295,0.895198,0.29272,0.727924,0.639056,0.248465,0.208084,0.131611,0.83191,0.539077,0.241389,0.471464,0.878752,-0.0742736,0.21716,-0.212159,-0.447018,-0.869002,0.206469,-0.73548,-0.309929,0.602505,0.154628,-3.74119e-15,-1,2.12832e-16,0.305371,0.99796,-0.0292037,-0.0567728,0.445142,0.80443,-0.32957,-0.494242,0.450833,-0.314046,0.893286,-0.321583,0.47714 +}; +// h33 +const int h33_numv = 18; +const int h33_numf = 11; +const dReal h33_volu = 0.056945; +const dReal h33_pos[3] = { -0.288352,-0.547292,0.050646 }; +const dReal h33_verts[ h33_numv * 3 ] = { + 0.084990,-0.362104,-0.019350, -0.079434,0.021164,0.334816, 0.019488,-0.072734,0.262363, 0.115516,0.076855,-0.268585, 0.213070,0.021874,-0.243280, 0.274323,0.089944,-0.132397, 0.019789,0.332949,0.053313, 0.257211,0.025988,-0.078610, 0.131191,0.288888,-0.060012, 0.118204,-0.320377,0.031687, 0.081511,-0.327423,-0.098356, -0.243137,-0.072887,0.198089, -0.179433,-0.002327,-0.170026, -0.299891,0.075262,-0.016680, -0.055817,0.322184,0.088384, -0.038680,0.277450,0.153234, 0.148159,-0.119839,-0.229545, 0.048588,0.033746,-0.272086, +}; +const unsigned int h33_faces[] = { + 5, 11,0,9,2,1, + 7, 2,7,5,8,6,15,1, + 5, 15,14,13,11,1, + 3, 9,7,2, + 4, 4,16,17,3, + 7, 17,12,13,14,6,8,3, + 4, 8,5,4,3, + 7, 5,7,9,0,10,16,4, + 3, 14,15,6, + 5, 0,11,13,12,10, + 4, 12,17,16,10, +}; +const dReal h33_planes[ h33_numf * 4 ] = { + -0.167754,-0.706913,0.687119,0.228423,0.73548,0.309929,0.602505,0.149866,-0.708232,0.479648,0.518021,0.239851,0.830851,-0.164118,0.531744,0.167639,0.158394,-0.166869,-0.973173,0.266852,-0.391463,0.659847,-0.641373,0.177755,0.49733,0.589428,-0.636583,0.273727,0.877503,-0.423705,-0.224641,0.232352,0.131611,0.83191,0.539077,0.308327,-0.727924,-0.639056,-0.248465,0.174346,-0.309646,-0.434949,-0.84554,0.200337 +}; +// h34 +const int h34_numv = 24; +const int h34_numf = 14; +const dReal h34_volu = 0.086482; +const dReal h34_pos[3] = { -0.499709,-0.643458,-0.327986 }; +const dReal h34_verts[ h34_numv * 3 ] = { + -0.500291,0.235691,-0.026942, -0.413349,0.203755,-0.157062, -0.223651,0.321490,-0.139249, 0.209880,-0.356542,0.003973, 0.365162,-0.137565,0.097393, 0.292868,-0.231257,0.280276, 0.359516,-0.023673,0.149087, -0.329463,0.339839,-0.019523, -0.041433,0.349469,-0.148408, 0.054302,-0.356542,0.142306, 0.272578,-0.356542,0.248886, 0.288720,-0.334603,0.260530, 0.023896,-0.069111,-0.283979, 0.274970,-0.222320,-0.056303, 0.127449,-0.356542,-0.036276, -0.035189,-0.103922,-0.288953, -0.023751,0.360733,-0.121029, -0.500291,0.237083,-0.030523, -0.346425,0.336124,-0.010604, 0.259945,0.129913,0.106546, -0.500291,0.239867,-0.026226, -0.470329,0.269402,-0.006532, -0.398155,0.309966,0.035665, 0.031924,0.093839,0.208606, +}; +const unsigned int h34_faces[] = { + 7, 17,20,21,18,7,2,1, + 5, 2,8,12,15,1, + 6, 15,14,9,0,17,1, + 4, 7,16,8,2, + 5, 14,15,12,13,3, + 5, 13,4,11,10,3, + 4, 10,9,14,3, + 7, 13,12,8,16,19,6,4, + 4, 6,5,11,4, + 4, 6,19,23,5, + 9, 23,22,21,20,0,9,10,11,5, + 6, 18,22,23,19,16,7, + 3, 0,20,17, + 3, 21,22,18, +}; +const dReal h34_planes[ h34_numf * 4 ] = { + -0.425203,0.759567,-0.4922,0.407829,-0.0929092,0.293639,-0.951391,0.247662,-0.66261,-0.69806,-0.271405,0.174284,-0.159459,0.944944,-0.285751,0.379244,0.373525,-0.524676,-0.76498,0.262425,0.837582,-0.502473,-0.214421,0.354093,0,-1,0,0.356542,0.73548,0.309929,-0.602505,0.167254,0.941719,-0.0992098,0.32144,0.388833,0.309646,0.434949,0.84554,0.227085,-0.433652,-0.152285,0.888119,0.157132,0.148211,0.780702,0.607074,0.204631,-1,0,-0,0.500291,-0.474713,0.879502,-0.0335246,0.460429 +}; +// h35 +const int h35_numv = 12; +const int h35_numf = 8; +const dReal h35_volu = 0.072358; +const dReal h35_pos[3] = { -0.852811,-0.781078,0.150064 }; +const dReal h35_verts[ h35_numv * 3 ] = { + -0.147189,-0.218922,0.332047, 0.103613,-0.074924,0.288589, -0.147189,0.429882,-0.202044, -0.147189,-0.218922,-0.312160, 0.239709,0.154443,0.128558, 0.287386,-0.218922,-0.005301, -0.043492,-0.218922,0.344705, 0.074717,-0.218922,0.306226, -0.147189,0.402063,0.012610, 0.208223,0.167113,0.176854, -0.147189,0.107130,-0.368067, 0.081807,-0.218922,-0.256252, +}; +const unsigned int h35_faces[] = { + 3, 6,7,1, + 5, 7,5,4,9,1, + 5, 9,8,0,6,1, + 4, 8,9,4,2, + 5, 4,5,11,10,2, + 5, 10,3,0,8,2, + 3, 10,11,3, + 6, 11,5,7,6,0,3, +}; +const dReal h35_planes[ h35_numf * 4 ] = { + 0.309078,0.0542691,0.949487,0.301971,0.822068,-0.096228,0.561199,0.254343,-0.107916,0.45476,0.884052,0.209874,0.512085,0.851811,0.110395,0.2685,0.73548,0.309929,-0.602505,0.146711,-1,-0,-0,0.147189,0.233951,-0.164312,-0.958263,0.300667,0,-1,0,0.218922 +}; +// h36 +const int h36_numv = 18; +const int h36_numf = 11; +const dReal h36_volu = 0.076715; +const dReal h36_pos[3] = { 0.330903,-0.599381,-0.308448 }; +const dReal h36_verts[ h36_numv * 3 ] = { + 0.235744,-0.093981,0.208985, 0.157036,0.091360,0.296934, -0.213473,-0.059832,-0.258208, 0.131366,0.084254,0.304768, 0.060949,-0.352878,-0.040467, 0.031132,-0.367472,0.023458, -0.038178,0.319175,-0.078462, 0.346140,-0.033881,-0.005840, 0.305466,-0.106272,-0.107625, -0.256020,-0.056138,-0.213238, -0.331115,0.110184,0.014099, -0.356965,0.085987,0.067218, 0.185622,-0.147504,0.212044, 0.241393,0.219660,0.109239, -0.343391,-0.100844,-0.022261, -0.046519,0.081665,-0.290234, -0.272849,0.156195,0.144404, -0.146830,0.270831,-0.017119, +}; +const unsigned int h36_faces[] = { + 6, 13,6,17,16,3,1, + 4, 3,12,0,1, + 4, 0,7,13,1, + 6, 9,10,17,6,15,2, + 4, 15,8,4,2, + 5, 4,5,14,9,2, + 6, 16,11,14,5,12,3, + 6, 8,7,0,12,5,4, + 5, 13,7,8,15,6, + 4, 14,11,10,9, + 4, 11,16,17,10, +}; +const dReal h36_planes[ h36_numf * 4 ] = { + -0.066237,0.837367,0.542613,0.227221,0.349687,-0.276295,0.895198,0.295486,0.864691,0.138024,0.482969,0.291807,-0.582463,0.552262,-0.596442,0.245303,0.212159,-0.447016,-0.869003,0.205839,-0.496382,-0.766976,-0.406636,0.25685,-0.398278,-0.419584,0.815674,0.16092,0.722578,-0.66608,0.18498,0.2716,0.595564,0.522855,-0.609857,0.191995,-0.913105,0.120244,-0.389591,0.310099,-0.654405,0.755705,0.0257735,0.300313 +}; +// h37 +const int h37_numv = 18; +const int h37_numf = 11; +const dReal h37_volu = 0.098217; +const dReal h37_pos[3] = { 0.055330,-0.588368,0.333127 }; +const dReal h37_verts[ h37_numv * 3 ] = { + -0.107417,0.016721,0.347927, 0.283844,-0.036335,0.197820, 0.129290,0.324988,-0.064466, -0.012100,0.128834,-0.356552, 0.344968,0.171444,-0.038138, -0.270436,0.127441,0.395275, -0.130084,-0.375511,-0.154724, 0.001812,-0.380727,-0.087638, -0.247911,0.142505,0.383526, 0.360906,0.133475,0.137346, 0.062042,-0.352141,-0.072933, 0.261216,0.073240,-0.194499, 0.127844,0.325300,-0.059106, 0.361773,0.137946,0.130076, -0.225478,-0.279302,-0.250794, -0.324194,-0.031659,-0.020118, -0.297963,0.086614,0.328910, -0.086471,0.067064,-0.361091, +}; +const unsigned int h37_faces[] = { + 6, 10,11,4,13,9,1, + 5, 9,8,5,0,1, + 4, 0,7,10,1, + 4, 12,13,4,2, + 4, 4,11,3,2, + 8, 3,17,15,16,5,8,12,2, + 7, 11,10,7,6,14,17,3, + 5, 16,6,7,0,5, + 4, 16,15,14,6, + 4, 9,13,12,8, + 3, 15,17,14, +}; +const dReal h37_planes[ h37_numf * 4 ] = { + 0.870583,-0.45858,-0.178295,0.228502,0.372229,0.156856,0.91479,0.280919,0.167754,-0.706913,0.687119,0.209227,0.568104,0.816131,0.105771,0.331865,0.49733,0.589428,-0.636583,0.296895,-0.616962,0.758294,-0.21059,0.180245,0.398278,-0.419585,-0.815673,0.231954,-0.32928,-0.737152,0.590069,0.228345,-0.799798,-0.547681,0.245698,0.271686,0.226312,0.817437,0.529699,0.263537,-0.830851,0.164118,-0.531744,0.274859 +}; +// h38 +const int h38_numv = 28; +const int h38_numf = 16; +const dReal h38_volu = 0.093559; +const dReal h38_pos[3] = { 0.133166,-0.773583,-0.050905 }; +const dReal h38_verts[ h38_numv * 3 ] = { + -0.076024,-0.195512,0.296394, 0.264846,-0.226417,0.026836, 0.183380,0.258456,0.189533, -0.015793,-0.166926,0.311098, -0.267713,-0.007440,-0.179688, -0.159228,0.260189,-0.190326, -0.343945,-0.226417,-0.001580, -0.273359,0.106452,-0.127994, 0.216958,-0.226417,-0.206989, 0.383359,0.026697,-0.045499, 0.329103,0.258456,0.047225, -0.089936,0.314049,0.027481, -0.145654,0.073358,-0.279804, 0.228869,-0.193270,-0.234086, -0.131382,0.326289,-0.026485, -0.075112,0.330397,-0.113139, -0.208448,0.248166,-0.141729, -0.011151,-0.226417,0.296364, -0.211663,-0.226417,0.216210, -0.072038,-0.226417,0.288931, -0.336528,-0.135813,0.082201, -0.147195,0.316236,-0.030846, -0.340678,-0.226417,0.055858, -0.164307,0.252279,0.022941, -0.344155,-0.204478,-0.016551, -0.340007,-0.101132,0.003195, -0.207920,-0.190296,0.229308, -0.303314,-0.094086,0.133238, +}; +const unsigned int h38_faces[] = { + 4, 8,13,9,1, + 6, 9,10,2,3,17,1, + 7, 17,19,18,22,6,8,1, + 5, 10,15,14,11,2, + 7, 11,23,27,26,0,3,2, + 4, 0,19,17,3, + 4, 24,25,7,4, + 5, 7,16,5,12,4, + 6, 12,13,8,6,24,4, + 5, 16,21,14,15,5, + 6, 15,10,9,13,12,5, + 5, 22,20,25,24,6, + 7, 25,20,27,23,21,16,7, + 4, 14,21,23,11, + 5, 26,27,20,22,18, + 4, 19,0,26,18, +}; +const dReal h38_planes[ h38_numf * 4 ] = { + 0.870583,-0.45858,-0.178295,0.329616,0.693474,-0.121763,0.710118,0.23029,0,-1,0,0.226417,0.124536,0.983986,0.127525,0.301324,-0.398278,0.419585,0.815673,0.190005,-0.117405,-0.247372,0.961781,0.342356,-0.941719,0.0992098,-0.32144,0.309131,-0.709719,0.26169,-0.654077,0.305583,-0.289106,-0.541464,-0.789452,0.223281,-0.465257,0.845503,-0.262033,0.343944,0.398278,0.419584,-0.815674,0.200998,-0.99796,0.0292037,0.0567728,0.336541,-0.877503,0.423705,0.224641,0.256225,-0.548603,0.619234,0.561769,0.259246,-0.770892,-0.145024,0.620237,0.330106,-0.445543,-0.264025,0.855443,0.33904 +}; +// h39 +const int h39_numv = 32; +const int h39_numf = 18; +const dReal h39_volu = 0.060173; +const dReal h39_pos[3] = { -0.130993,-0.349156,0.297470 }; +const dReal h39_verts[ h39_numv * 3 ] = { + 0.132777,-0.098138,-0.374861, 0.174223,-0.110378,-0.320895, -0.236793,-0.176972,0.087992, 0.120090,0.163784,-0.274197, -0.036262,0.126682,-0.293283, -0.239846,-0.040235,0.342234, -0.196039,0.079314,-0.093590, -0.026168,0.090752,-0.306837, -0.084113,-0.111771,0.430932, -0.132771,0.138527,-0.197817, -0.061588,-0.096707,0.419183, -0.167047,-0.030107,0.457226, 0.314167,0.086089,-0.023449, 0.140527,0.255266,-0.004320, -0.137571,0.134813,-0.193511, 0.315613,0.085777,-0.028809, 0.116964,-0.108191,-0.379221, 0.099852,-0.172148,-0.325434, -0.176687,-0.026318,0.447418, -0.168971,-0.023213,0.453768, -0.137871,-0.270870,0.015539, -0.111640,-0.152598,0.364567, -0.122362,-0.092357,0.456223, -0.127730,-0.079472,0.460978, -0.243030,-0.080780,0.324741, -0.136583,-0.114124,0.420896, -0.241856,-0.054541,0.348612, -0.178625,-0.028253,0.445248, -0.171209,-0.024409,0.453290, -0.169333,-0.024798,0.455225, 0.224076,0.244621,-0.088171, 0.213513,0.251212,-0.061379, +}; +const unsigned int h39_faces[] = { + 5, 0,3,30,15,1, + 8, 15,12,10,8,21,20,17,1, + 4, 17,16,0,1, + 5, 20,21,25,24,2, + 5, 24,26,5,6,2, + 7, 6,14,7,16,17,20,2, + 5, 0,16,7,4,3, + 6, 4,9,13,31,30,3, + 4, 7,14,9,4, + 4, 26,27,18,5, + 8, 18,28,19,13,9,14,6,5, + 4, 10,23,22,8, + 4, 22,25,21,8, + 8, 12,31,13,19,29,11,23,10, + 7, 27,26,24,25,22,23,11, + 5, 29,28,18,27,11, + 4, 15,30,31,12, + 3, 28,29,19, +}; +const dReal h39_planes[ h39_numf * 4 ] = { + 0.794364,0.251059,-0.553132,0.288182,0.616962,-0.758294,0.21059,0.12361,0.548603,-0.619234,-0.561769,0.344197,-0.526505,-0.792388,0.308081,0.292012,-0.991673,0.108076,-0.0700326,0.209533,-0.73548,-0.309929,-0.602505,0.17599,0.0284606,0.359798,-0.932596,0.318062,-0.184883,0.934913,-0.302912,0.213979,-0.696788,0.0734069,-0.713511,0.243827,-0.830322,0.320028,0.456232,0.342411,-0.493232,0.850288,0.183662,0.146944,0.512456,-0.101226,0.852726,0.335677,-0.0662371,-0.837367,0.542614,0.332994,0.553104,0.49165,0.672575,0.200322,-0.664689,-0.486283,0.567201,0.385014,-0.721996,-0.0507074,0.690036,0.437637,0.818514,0.542417,0.189261,0.299408,-0.474458,0.651966,0.591464,0.333423 +}; +// h40 +const int h40_numv = 24; +const int h40_numf = 14; +const dReal h40_volu = 0.115424; +const dReal h40_pos[3] = { 0.492476,-0.748212,0.263785 }; +const dReal h40_verts[ h40_numv * 3 ] = { + -0.375103,-0.192297,-0.003592, 0.259307,0.208511,0.137583, 0.097667,-0.251788,0.295436, 0.264741,-0.251788,-0.112461, -0.092178,0.331289,0.031204, 0.024049,0.001327,-0.360189, 0.074171,0.054850,-0.363248, 0.312772,-0.115013,-0.159366, -0.175930,0.233085,-0.125157, -0.094464,-0.251788,-0.287854, -0.004537,0.240191,-0.275299, -0.030207,0.233085,-0.267465, -0.370461,-0.251788,-0.018326, 0.056736,-0.251788,0.315422, -0.153302,0.123509,0.267162, -0.068302,0.078845,0.319783, 0.171724,0.348803,0.156293, 0.053571,0.367605,-0.023060, -0.075373,0.297791,0.199418, 0.109457,0.331072,0.189737, -0.005042,0.303901,0.226077, 0.014996,0.282164,0.244247, -0.076239,0.293319,0.206688, -0.068649,0.297216,0.207331, +}; +const unsigned int h40_faces[] = { + 4, 2,3,7,1, + 6, 7,6,10,17,16,1, + 7, 16,19,21,15,13,2,1, + 5, 13,12,9,3,2, + 5, 9,5,6,7,3, + 5, 17,10,11,8,4, + 6, 8,0,14,22,18,4, + 7, 18,23,20,19,16,17,4, + 6, 9,12,0,8,11,5, + 4, 11,10,6,5, + 5, 13,15,14,0,12, + 6, 15,21,20,23,22,14, + 3, 22,23,18, + 3, 20,21,19, +}; +const dReal h40_planes[ h40_numf * 4 ] = { + 0.908278,-0.191373,0.372031,0.246805,0.73808,0.518378,-0.431882,0.240058,0.433652,0.152285,0.888119,0.266393,5.15129e-17,-1,5.27492e-17,0.251788,0.398278,-0.419585,-0.815673,0.302818,-0.348894,0.86639,-0.357268,0.308038,-0.870583,0.45858,0.178295,0.237735,-0.162747,0.964426,0.208316,0.341006,-0.693474,0.121763,-0.710118,0.23926,-0.349687,0.276295,-0.895198,0.314397,-0.598205,-0.236328,0.765702,0.267084,-0.296224,0.4369,0.849335,0.326283,-0.440632,0.78713,0.431589,0.353679,0.071473,0.677671,0.731884,0.371046 +}; +// h41 +const int h41_numv = 18; +const int h41_numf = 11; +const dReal h41_volu = 0.076473; +const dReal h41_pos[3] = { 0.741085,-0.876917,-0.246261 }; +const dReal h41_verts[ h41_numv * 3 ] = { + 0.005338,0.140795,-0.243701, -0.174437,0.183555,0.146798, 0.258916,-0.123083,-0.387389, 0.103129,0.222017,-0.142233, 0.164192,-0.123083,-0.418224, 0.016133,-0.123083,0.397585, 0.258916,0.168617,-0.137303, 0.258916,-0.123083,0.279039, -0.343073,-0.123083,0.222192, -0.064041,0.243655,-0.068027, -0.104715,0.171264,-0.169812, -0.390960,-0.123083,-0.011633, -0.224559,0.130032,0.149857, -0.379049,-0.089936,-0.038730, -0.349233,-0.075342,-0.102654, -0.337817,-0.123083,-0.124077, 0.258916,-0.009416,0.259549, 0.064164,0.013692,0.350680, +}; +const unsigned int h41_faces[] = { + 6, 9,10,14,13,12,1, + 5, 12,8,5,17,1, + 6, 17,16,6,3,9,1, + 5, 4,0,3,6,2, + 4, 6,16,7,2, + 7, 7,5,8,11,15,4,2, + 4, 0,10,9,3, + 5, 15,14,10,0,4, + 4, 7,16,17,5, + 4, 12,13,11,8, + 4, 13,14,15,11, +}; +const dReal h41_planes[ h41_numf * 4 ] = { + -0.722578,0.66608,-0.18498,0.221152,-0.398278,0.419585,0.815673,0.266231,0.287163,0.873965,0.392074,0.167884,0.239912,0.631869,-0.73701,0.269854,1,0,0,0.258915,0,-1,0,0.123083,-0.131611,0.83191,-0.539077,0.2478,-0.488522,0.25733,-0.833743,0.236806,0.433652,0.152285,0.888119,0.341356,-0.870583,0.45858,0.178295,0.281846,-0.903842,-0.0244154,-0.42717,0.361341 +}; +// h42 +const int h42_numv = 26; +const int h42_numf = 15; +const dReal h42_volu = 0.137951; +const dReal h42_pos[3] = { 0.814994,-0.482932,0.027418 }; +const dReal h42_verts[ h42_numv * 3 ] = { + -0.063211,-0.056769,0.373950, 0.185005,0.097851,0.415613, -0.248347,-0.210430,-0.126881, 0.112828,0.023604,-0.394042, -0.108847,0.115253,0.400661, -0.327055,-0.025089,-0.038931, -0.085789,0.224192,-0.255901, 0.185005,-0.403401,-0.014130, 0.185005,-0.225368,-0.410982, -0.009747,-0.380293,0.077002, -0.175394,0.222730,-0.208732, 0.002670,0.221670,0.389944, -0.150794,0.083523,0.392660, 0.160182,0.229752,0.436714, 0.133897,0.345057,0.231744, -0.006362,0.255606,0.329122, 0.185005,0.234054,0.438967, 0.185005,0.352490,0.238788, 0.029219,-0.171968,-0.415912, -0.137952,-0.150330,-0.341706, 0.185005,0.276769,-0.150723, 0.185005,0.010082,-0.390796, -0.176045,0.220413,-0.220256, -0.242698,0.103211,-0.226628, -0.268948,0.102325,0.213307, -0.248100,0.136462,0.190657, +}; +const unsigned int h42_faces[] = { + 4, 0,9,7,1, + 7, 7,8,21,20,17,16,1, + 6, 16,13,4,12,0,1, + 4, 5,23,19,2, + 6, 19,18,8,7,9,2, + 6, 9,0,12,24,5,2, + 4, 6,20,21,3, + 4, 21,8,18,3, + 6, 18,19,23,22,6,3, + 3, 13,11,4, + 6, 11,15,25,24,12,4, + 6, 24,25,10,22,23,5, + 6, 22,10,14,17,20,6, + 4, 25,15,14,10, + 6, 13,16,17,14,15,11, +}; +const dReal h42_planes[ h42_numf * 4 ] = { + 0.267862,-0.627092,0.731441,0.29219,1,2.67045e-16,1.9344e-17,0.185006,-0.0600487,-0.168696,0.983837,0.381279,-0.864691,-0.138024,-0.482969,0.305068,-0.287163,-0.873965,-0.392074,0.304972,-0.73808,-0.518378,0.431882,0.237585,0.156805,0.660773,-0.734024,0.322525,0.0606999,0.0852635,-0.994508,0.400738,-0.364346,0.255892,-0.895417,0.317763,-0.280943,0.383024,0.879979,0.427298,-0.590109,0.664552,0.458413,0.324491,-0.86695,0.495807,-0.0507289,0.273077,-0.11569,0.975032,-0.189546,0.277024,-0.485104,0.868795,0.0993492,0.257853,-0.191731,0.844679,0.499756,0.381605 +}; +// h43 +const int h43_numv = 26; +const int h43_numf = 15; +const dReal h43_volu = 0.091347; +const dReal h43_pos[3] = { -0.439313,0.395062,-0.161996 }; +const dReal h43_verts[ h43_numv * 3 ] = { + -0.171800,0.355423,-0.143529, -0.041887,-0.040549,-0.338294, -0.088904,0.443945,0.033555, -0.050746,0.256028,0.267789, -0.120718,0.085236,0.331241, 0.112903,-0.317075,-0.192421, -0.024680,-0.380539,0.081401, 0.014540,-0.410443,-0.096363, -0.166472,-0.135578,-0.232924, -0.179653,0.199344,0.219565, 0.056744,-0.387608,-0.004660, -0.088904,0.425462,0.081094, -0.046327,-0.413563,-0.075262, -0.024725,0.299814,0.247575, -0.150602,0.151087,0.286944, -0.050613,-0.134365,0.334664, -0.244880,0.199344,-0.098926, -0.122184,0.302440,-0.201067, -0.108793,0.292906,-0.209241, -0.034597,-0.039973,-0.340964, 0.309817,-0.173124,-0.053206, -0.070119,0.430571,0.022089, 0.002939,0.029802,-0.334091, 0.280604,-0.188322,-0.121373, 0.290359,0.017349,0.142160, 0.257236,0.070405,0.149235, +}; +const unsigned int h43_faces[] = { + 5, 8,16,0,17,1, + 5, 17,18,22,19,1, + 6, 19,5,7,12,8,1, + 5, 21,18,17,0,2, + 5, 0,16,9,11,2, + 5, 11,13,25,21,2, + 6, 4,15,24,25,13,3, + 5, 13,11,9,14,3, + 3, 14,4,3, + 8, 14,9,16,8,12,6,15,4, + 4, 19,22,23,5, + 5, 23,20,10,7,5, + 5, 10,20,24,15,6, + 4, 12,7,10,6, + 7, 21,25,24,20,23,22,18, +}; +const dReal h43_planes[ h43_numf * 4 ] = { + -0.693474,0.121763,-0.710118,0.264339,-0.349687,0.276295,-0.895198,0.306284,-0.24653,-0.556538,-0.793403,0.301297,0.256638,0.811103,-0.525594,0.319633,-0.870583,0.45858,0.178295,0.286965,0.662611,0.698059,0.271405,0.260098,0.433652,0.152285,0.888119,0.254811,-0.49733,0.589429,0.636582,0.346617,-0.296224,0.4369,0.849335,0.354333,-0.935836,-0.295766,0.191659,0.151248,0.501077,-0.186311,-0.84511,0.278264,0.632147,-0.768422,-0.0995875,0.334181,0.582464,-0.552261,0.596443,0.244332,0.11569,-0.975032,0.189546,0.383611,0.73808,0.518378,-0.431882,0.161906 +}; +// h44 +const int h44_numv = 26; +const int h44_numf = 15; +const dReal h44_volu = 0.104111; +const dReal h44_pos[3] = { -0.656166,-0.300748,0.215302 }; +const dReal h44_verts[ h44_numv * 3 ] = { + -0.220317,0.235145,-0.208278, 0.078796,0.351295,-0.102059, 0.283317,-0.102949,0.430780, 0.285327,-0.088643,0.424402, 0.201177,0.226255,-0.138992, 0.124677,-0.319431,0.033433, 0.117727,0.304230,-0.184196, 0.043064,-0.325887,0.063320, -0.138842,0.186808,-0.302762, 0.311997,0.075640,-0.076273, 0.067923,-0.171282,-0.181336, -0.343834,-0.050448,-0.267282, -0.343834,-0.078267,-0.052628, -0.343834,0.035932,0.053112, 0.088073,0.239020,0.159535, 0.282143,-0.129188,0.406909, -0.286183,0.003244,-0.364214, -0.343834,0.054532,0.043544, 0.011578,-0.313217,0.111616, 0.329134,0.030906,-0.011422, 0.089881,-0.140507,0.355648, 0.092412,-0.225203,0.279944, 0.288380,-0.225380,0.170160, 0.101854,0.336248,-0.130909, -0.343834,-0.006528,-0.335059, -0.343834,0.160238,-0.192084, +}; +const unsigned int h44_faces[] = { + 7, 14,3,19,9,4,23,1, + 5, 23,6,8,0,1, + 5, 0,25,17,14,1, + 5, 15,22,19,3,2, + 6, 3,14,17,13,20,2, + 4, 20,21,15,2, + 6, 9,10,16,8,6,4, + 3, 6,23,4, + 6, 22,15,21,18,7,5, + 6, 7,11,24,16,10,5, + 5, 10,9,19,22,5, + 4, 18,12,11,7, + 5, 16,24,25,0,8, + 6, 12,13,17,25,24,11, + 5, 18,21,20,13,12, +}; +const dReal h44_planes[ h44_numf * 4 ] = { + 0.727924,0.639056,0.248465,0.256497,-0.131611,0.83191,-0.539077,0.336893,-0.446963,0.816184,0.366152,0.214133,0.991673,-0.108076,0.0700326,0.322253,-0.398278,0.419585,0.815673,0.19534,-0.156805,-0.660773,0.734024,0.339803,0.438192,-0.051293,-0.897417,0.201283,0.722578,0.66608,-0.18498,0.321781,0.20808,-0.904248,0.372879,0.327254,-0.131611,-0.83191,-0.539077,0.231306,0.708232,-0.479648,-0.518021,0.224196,-0.512085,-0.851811,-0.110395,0.248551,-0.443092,0.583496,-0.68059,0.376579,-1,6.26681e-16,4.55506e-17,0.343834,-0.619037,-0.533581,0.576268,0.22428 +}; +// h45 +const int h45_numv = 22; +const int h45_numf = 13; +const dReal h45_volu = 0.073607; +const dReal h45_pos[3] = { -0.692003,0.228592,-0.074767 }; +const dReal h45_verts[ h45_numv * 3 ] = { + 0.206363,-0.247093,-0.162491, 0.114633,-0.178045,0.188010, 0.007810,0.365814,-0.186155, -0.306616,-0.033345,0.126518, -0.055718,0.198405,0.254002, 0.153565,-0.225110,0.105873, -0.184480,-0.294195,0.081791, 0.073037,0.365814,0.132336, 0.155930,-0.080562,0.225951, -0.173050,0.172678,-0.175116, -0.103005,-0.342532,-0.012694, -0.015749,-0.330108,-0.146901, 0.086218,0.030892,-0.320153, -0.015750,-0.032626,-0.299926, 0.228010,-0.214069,-0.005829, 0.104078,0.176805,0.286842, 0.137691,-0.193092,0.159160, 0.102087,0.317557,0.199715, -0.062260,0.197254,0.252076, 0.131971,0.251706,0.244012, 0.186972,0.021095,0.262581, 0.202077,0.032105,0.247435, +}; +const unsigned int h45_faces[] = { + 8, 8,20,15,4,18,3,6,1, + 5, 6,10,5,16,1, + 3, 16,8,1, + 4, 12,13,9,2, + 5, 9,3,18,7,2, + 8, 7,17,19,21,14,0,12,2, + 6, 9,13,11,10,6,3, + 4, 15,19,17,4, + 4, 17,7,18,4, + 6, 14,21,20,8,16,5, + 5, 10,11,0,14,5, + 4, 13,12,0,11, + 4, 20,21,19,15, +}; +const dReal h45_planes[ h45_numf * 4 ] = { + -0.228531,-0.267508,0.936063,0.19742,0.131611,-0.83191,0.539077,0.264556,0.535431,-0.493566,0.685351,0.278107,-0.349687,0.276295,-0.895198,0.264987,-0.717787,0.680568,0.147003,0.21599,0.935836,0.295766,-0.191659,0.151183,-0.793213,-0.278551,-0.5415,0.183991,-0.103318,0.522457,0.846383,0.324397,-0.311731,0.703731,0.638425,0.319154,0.777333,-0.40946,0.477593,0.262108,0.35532,-0.923345,0.145539,0.277827,0.107916,-0.45476,-0.884052,0.278288,0.613049,0.207593,0.762283,0.319163 +}; +// h46 +const int h46_numv = 24; +const int h46_numf = 14; +const dReal h46_volu = 0.077166; +const dReal h46_pos[3] = { -0.506861,-0.263372,-0.148064 }; +const dReal h46_verts[ h46_numv * 3 ] = { + -0.435488,-0.034132,-0.000849, 0.039076,-0.286247,0.028683, -0.031577,0.266854,0.179170, 0.042868,0.277895,0.067468, 0.334025,-0.207064,-0.069876, -0.200891,0.161856,-0.073604, -0.329922,-0.035641,-0.192524, -0.391003,-0.070120,-0.144257, 0.124292,0.270826,-0.018593, -0.288147,0.149432,0.060603, 0.051872,0.188879,0.224374, -0.081382,-0.208658,0.182030, 0.243097,0.052743,0.247717, 0.267097,-0.250173,-0.073376, 0.162691,0.038264,0.287094, 0.339607,0.040898,0.152251, 0.238297,0.049029,0.252023, 0.349700,0.004968,0.138697, 0.021220,0.244871,-0.089194, -0.322311,-0.040247,-0.199445, -0.016599,-0.019353,-0.300951, 0.082088,0.247991,-0.110295, -0.339273,-0.043963,-0.190526, 0.082087,0.036350,-0.291745, +}; +const unsigned int h46_faces[] = { + 6, 7,22,19,20,13,1, + 7, 13,4,17,16,14,11,1, + 4, 11,0,7,1, + 6, 10,12,15,8,3,2, + 5, 3,18,5,9,2, + 6, 9,0,11,14,10,2, + 4, 8,21,18,3, + 4, 13,20,23,4, + 6, 23,21,8,15,17,4, + 7, 18,21,23,20,19,6,5, + 6, 6,22,7,0,9,5, + 3, 19,22,6, + 4, 14,16,12,10, + 4, 16,17,15,12, +}; +const dReal h46_planes[ h46_numf * 4 ] = { + -0.148211,-0.780702,-0.607074,0.200269,0.391463,-0.659847,0.641373,0.222573,-0.471464,-0.878752,0.0742736,0.235248,0.496382,0.766976,0.406636,0.261853,-0.35532,0.923345,-0.145539,0.231542,-0.438192,0.051293,0.897417,0.188315,-0.11569,0.975032,-0.189546,0.253209,0.322885,-0.43293,-0.841615,0.256305,0.792041,0.39734,-0.463457,0.214671,-0.284317,0.624016,-0.727852,0.21169,-0.66062,0.653782,-0.368986,0.26569,-0.494656,0.366713,-0.787932,0.301823,0.289106,0.541464,0.789452,0.2944,0.696788,-0.0734069,0.713511,0.342264 +}; +// h47 +const int h47_numv = 36; +const int h47_numf = 20; +const dReal h47_volu = 0.096745; +const dReal h47_pos[3] = { -0.132135,0.108975,0.072319 }; +const dReal h47_verts[ h47_numv * 3 ] = { + 0.298509,0.263511,-0.009995, -0.406303,-0.105494,-0.041213, 0.295351,0.263929,-0.015607, -0.362255,0.123840,0.142831, -0.016819,0.303436,-0.092155, 0.214655,-0.206919,0.163772, 0.119596,0.038081,0.333996, -0.357791,0.151721,0.100349, 0.141669,-0.202865,0.220831, -0.322854,-0.183468,0.003991, -0.422177,-0.073475,0.012073, 0.248529,0.277838,-0.020262, -0.331858,-0.094452,-0.152914, -0.250434,-0.101521,-0.238975, -0.131628,-0.319604,0.027334, 0.281027,0.056414,-0.190466, 0.134068,0.286800,-0.104666, 0.293847,0.266235,0.003176, -0.403938,0.039055,0.078865, -0.372896,0.140712,0.115495, -0.035119,-0.331449,-0.068132, 0.121232,-0.294347,-0.049046, 0.051634,0.305873,-0.087560, 0.254870,0.274829,-0.031097, 0.196475,0.139795,-0.254001, 0.002640,0.112963,-0.287521, 0.198447,0.073853,0.288417, 0.224142,0.132346,-0.243414, 0.225218,-0.213510,0.136980, 0.298178,-0.027388,0.023425, 0.292448,0.199019,0.106734, 0.304944,0.253729,-0.022071, 0.308556,0.186869,0.065231, 0.305066,0.254217,-0.020526, 0.293027,0.163885,-0.150423, 0.287364,0.062429,-0.181183, +}; +const unsigned int h47_faces[] = { + 6, 12,13,20,14,9,1, + 3, 9,10,1, + 6, 10,18,19,7,12,1, + 4, 0,33,31,2, + 7, 31,34,27,24,16,23,2, + 5, 23,11,17,0,2, + 10, 6,26,30,17,11,22,4,7,19,3, + 3, 19,18,3, + 7, 18,10,9,14,8,6,3, + 5, 22,16,24,25,4, + 5, 25,13,12,7,4, + 6, 28,29,32,30,26,5, + 4, 26,6,8,5, + 6, 8,14,20,21,28,5, + 4, 23,16,22,11, + 7, 25,24,27,15,21,20,13, + 4, 27,34,35,15, + 5, 35,29,28,21,15, + 5, 30,32,33,0,17, + 6, 35,34,31,33,32,29, +}; +const dReal h47_planes[ h47_numf * 4 ] = { + -0.496382,-0.766976,-0.406636,0.299351,-0.722578,-0.66608,0.18498,0.35623,-0.777333,0.40946,-0.477593,0.292321,0.60243,0.746152,-0.283435,0.379283,0.40667,0.730271,-0.54893,0.321417,0.292039,0.95183,-0.0934524,0.338928,-0.066237,0.837367,0.542613,0.205196,-0.897445,0.121213,0.424146,0.400696,-0.398278,-0.419584,0.815674,0.208821,0.0212658,0.716912,-0.696839,0.281397,-0.582464,0.552261,-0.596443,0.232337,0.913105,-0.120244,0.389591,0.284687,0.576312,-0.303571,0.758755,0.310786,0.184883,-0.934913,0.302912,0.282746,0.191593,0.968844,-0.156953,0.319978,0.212159,-0.447018,-0.869002,0.19992,0.770892,0.145024,-0.620237,0.342957,0.836212,-0.484521,-0.256884,0.256592,0.900933,0.358346,0.24476,0.360918,0.997066,-0.0350131,-0.0680664,0.296668 +}; +// h48 +const int h48_numv = 24; +const int h48_numf = 14; +const dReal h48_volu = 0.097516; +const dReal h48_pos[3] = { 0.292729,-0.243911,-0.041409 }; +const dReal h48_verts[ h48_numv * 3 ] = { + -0.303632,0.058539,0.064682, -0.108656,-0.084639,-0.284158, 0.263889,0.072976,-0.223666, 0.274166,-0.102559,0.259484, 0.253318,-0.136696,0.282134, 0.346872,-0.016291,-0.139905, -0.290945,-0.203383,-0.035982, 0.008763,0.056080,-0.365621, 0.246275,0.103070,-0.201305, 0.107569,-0.173012,0.336398, -0.249499,-0.215623,0.017984, -0.234675,-0.199275,-0.122635, 0.023817,-0.271216,0.180037, 0.169540,-0.271216,0.037729, -0.126686,0.325499,0.137154, 0.195210,-0.264110,0.029895, 0.346221,-0.018608,-0.151429, 0.279567,-0.135810,-0.157801, -0.143837,0.409300,-0.076739, -0.137500,0.415315,-0.067456, -0.031223,0.088614,-0.351675, -0.000004,-0.036295,-0.345501, -0.199646,0.139376,0.250708, -0.108109,-0.019468,0.310070, +}; +const unsigned int h48_faces[] = { + 4, 20,7,21,1, + 6, 21,17,15,13,11,1, + 6, 11,6,0,18,20,1, + 5, 16,17,21,7,2, + 6, 7,20,18,19,8,2, + 4, 8,5,16,2, + 6, 14,22,23,9,4,3, + 6, 4,15,17,16,5,3, + 5, 5,8,19,14,3, + 5, 9,12,13,15,4, + 5, 10,23,22,0,6, + 5, 11,13,12,10,6, + 4, 23,10,12,9, + 5, 19,18,0,22,14, +}; +const dReal h48_planes[ h48_numf * 4 ] = { + -0.433652,-0.152283,-0.888119,0.312375,0.066237,-0.837367,-0.542613,0.217865,-0.830851,0.164118,-0.531744,0.227486,0.484779,-0.229821,-0.843903,0.299909,0.322183,0.678839,-0.659831,0.282141,0.794108,0.585614,-0.162633,0.288667,0.212159,0.447018,0.869002,0.237812,0.86695,-0.495807,0.0507289,0.301701,0.66261,0.69806,0.271405,0.180498,0.348894,-0.86639,0.357268,0.30761,-0.794364,-0.251059,0.553132,0.262275,-0.124536,-0.983986,-0.127525,0.240948,-0.49733,-0.589428,0.636583,0.262626,-0.836212,0.484521,0.256884,0.29888 +}; +// h49 +const int h49_numv = 30; +const int h49_numf = 17; +const dReal h49_volu = 0.103417; +const dReal h49_pos[3] = { -0.082648,-0.117151,-0.277803 }; +const dReal h49_verts[ h49_numv * 3 ] = { + 0.344154,-0.038146,-0.115281, -0.165239,0.018854,-0.286732, -0.342125,0.101770,0.019444, -0.222234,-0.108669,-0.237036, -0.321677,-0.099820,-0.189997, 0.084432,-0.330143,0.200412, -0.076061,0.323891,-0.005566, -0.299921,0.124605,0.111147, -0.223248,0.024754,-0.259418, 0.141702,0.335375,-0.073499, 0.231540,0.282540,0.159656, 0.156937,0.153559,-0.266131, -0.243762,0.195138,-0.076614, -0.084607,-0.105324,0.281990, 0.266721,-0.211399,-0.047765, 0.071745,-0.068221,0.301076, -0.090188,-0.353285,0.059864, -0.342125,-0.109871,-0.162005, -0.074513,-0.141253,0.268436, 0.140702,-0.326035,0.113759, 0.082436,-0.372046,-0.016546, 0.056586,-0.396243,0.036572, 0.007365,-0.408266,0.085169, 0.068619,-0.340196,0.196052, 0.183372,0.187050,-0.241355, 0.271282,0.058201,-0.185174, 0.174655,0.358472,0.106708, -0.046848,0.339089,0.062601, 0.146988,0.365921,0.096121, 0.157998,0.356836,0.037994, +}; +const unsigned int h49_faces[] = { + 4, 3,4,8,1, + 7, 8,12,6,9,24,11,1, + 7, 11,25,0,14,20,3,1, + 6, 17,16,18,13,7,2, + 5, 7,27,6,12,2, + 5, 12,8,4,17,2, + 7, 20,21,22,16,17,4,3, + 5, 15,13,18,23,5, + 5, 23,22,21,19,5, + 6, 19,14,0,10,15,5, + 5, 27,28,29,9,6, + 7, 13,15,10,26,28,27,7, + 7, 29,26,10,0,25,24,9, + 3, 24,25,11, + 4, 19,21,20,14, + 4, 22,23,18,16, + 3, 29,28,26, +}; +const dReal h49_planes[ h49_numf * 4 ] = { + -0.433652,-0.152283,-0.888119,0.323437,-0.247318,0.694798,-0.675344,0.247609,0.240814,-0.443968,-0.863077,0.199309,-0.792041,-0.39734,0.463457,0.239551,-0.632147,0.768422,0.0995875,0.296413,-0.805487,0.385719,-0.449901,0.306085,-0.315015,-0.796483,-0.516121,0.2789,-0.0284606,-0.359798,0.932596,0.303286,0.465257,-0.845503,0.262033,0.370934,0.830851,-0.164118,0.531744,0.230901,-0.105626,0.979232,-0.173057,0.326162,-0.212159,0.447018,0.869002,0.215918,0.847832,0.483811,-0.217045,0.29835,0.621965,0.0849382,-0.778424,0.317815,0.654405,-0.755705,-0.0257735,0.33553,-0.49733,-0.589428,0.636583,0.291198,0.292039,0.95183,-0.0934524,0.382238 +}; +// h50 +const int h50_numv = 20; +const int h50_numf = 12; +const dReal h50_volu = 0.069183; +const dReal h50_pos[3] = { -0.304007,-0.060848,0.383791 }; +const dReal h50_verts[ h50_numv * 3 ] = { + 0.035443,-0.153495,-0.279832, 0.291468,0.207904,0.022524, -0.264086,-0.000880,-0.008953, -0.190383,0.293663,-0.168640, 0.004043,-0.311521,0.367447, -0.001962,-0.311376,0.364440, -0.150982,-0.013645,-0.307481, -0.250305,0.096348,-0.299398, 0.040243,-0.149781,-0.284138, -0.040162,-0.164260,-0.244761, -0.228192,0.064423,0.060664, 0.001805,-0.312717,0.366969, -0.232066,0.208878,-0.232607, -0.273363,0.111395,-0.270548, 0.313541,-0.033043,-0.090641, -0.003673,-0.314626,0.361097, -0.023025,-0.208994,-0.179911, -0.066832,-0.328543,0.255913, -0.170020,0.271491,-0.017447, 0.190786,0.198102,0.196479, +}; +const unsigned int h50_faces[] = { + 4, 3,18,19,1, + 4, 19,4,14,1, + 7, 14,8,6,7,12,3,1, + 6, 10,18,3,12,13,2, + 7, 13,7,6,9,16,17,2, + 5, 17,15,5,10,2, + 8, 11,15,17,16,0,8,14,4, + 6, 19,18,10,5,11,4, + 3, 15,11,5, + 4, 8,0,9,6, + 3, 13,12,7, + 3, 0,16,9, +}; +const dReal h50_planes[ h50_numf * 4 ] = { + 0.124536,0.983986,0.127525,0.243745,0.859244,-0.150868,0.488814,0.230086,0.398278,0.419584,-0.815674,0.184946,-0.929286,0.326334,0.173016,0.243575,-0.727924,-0.639056,-0.248465,0.195021,-0.848621,-0.0894025,0.521393,0.219519,0.493232,-0.850288,-0.183662,0.199392,-0.398278,0.419584,0.815674,0.167397,-0.604872,-0.393584,0.692258,0.376026,-0.289106,-0.541464,-0.789452,0.293779,-0.535431,0.493566,-0.685351,0.386768,-0.131611,-0.83191,-0.539077,0.273881 +}; +// h51 +const int h51_numv = 20; +const int h51_numf = 12; +const dReal h51_volu = 0.097496; +const dReal h51_pos[3] = { 0.796238,0.092236,-0.101631 }; +const dReal h51_verts[ h51_numv * 3 ] = { + -0.221011,0.347408,0.061823, -0.319697,0.291705,0.052616, 0.203762,-0.222678,0.367837, -0.200562,0.357460,0.033830, 0.203762,0.194344,-0.275142, -0.239620,-0.263171,-0.163444, 0.152653,-0.230111,0.360793, 0.203762,0.321480,-0.157424, -0.337380,0.280442,0.025237, -0.327866,0.285347,0.016786, -0.028332,0.052718,-0.315616, 0.203762,-0.298399,-0.021674, -0.257234,-0.233077,-0.141083, -0.157288,-0.354755,-0.091207, 0.203762,0.006585,0.328526, -0.156637,-0.352438,-0.079683, 0.030926,0.103995,0.283692, -0.036002,0.060886,0.280191, -0.157223,-0.222560,-0.236947, -0.067033,-0.350976,-0.126852, +}; +const unsigned int h51_faces[] = { + 4, 17,16,0,1, + 5, 0,3,9,8,1, + 6, 8,12,15,6,17,1, + 5, 14,16,17,6,2, + 6, 6,15,13,19,11,2, + 5, 11,4,7,14,2, + 5, 7,4,10,9,3, + 5, 0,16,14,7,3, + 5, 11,19,18,10,4, + 4, 18,19,13,5, + 4, 13,15,12,5, + 6, 12,8,9,10,18,5, +}; +const dReal h51_planes[ h51_numf * 4 ] = { + -0.322885,0.43293,0.841615,0.273796,-0.488006,0.871758,-0.0434538,0.408025,-0.73548,-0.309929,0.602505,0.176424,-0.158394,0.166869,0.973173,0.288536,0.11569,-0.975032,0.189546,0.310413,1,0,0,0.203762,-0.275531,0.653109,-0.705359,0.26486,0.315015,0.796483,0.516121,0.238991,0.398278,-0.419585,-0.815673,0.224036,-0.228161,-0.721101,-0.654183,0.351367,-0.794108,-0.585614,0.162633,0.31782,-0.693474,0.121763,-0.710118,0.250191 +}; +// h52 +const int h52_numv = 16; +const int h52_numf = 10; +const dReal h52_volu = 0.084293; +const dReal h52_pos[3] = { 0.513157,0.018456,0.067444 }; +const dReal h52_verts[ h52_numv * 3 ] = { + -0.347114,0.063132,0.028301, -0.352265,0.254404,-0.145548, 0.247079,0.134666,0.111116, -0.336736,0.277388,0.070106, 0.126444,-0.278658,-0.248758, -0.340226,0.344736,-0.015651, 0.295476,-0.245782,0.289096, -0.054299,0.354222,-0.143838, 0.053738,-0.364926,0.150631, -0.036616,0.365485,-0.116459, 0.025847,-0.159297,-0.310158, -0.357928,0.152948,-0.176308, 0.019058,0.098592,0.213176, 0.435734,-0.156331,0.191718, -0.340348,0.344248,-0.017196, -0.236518,0.326242,-0.134679, +}; +const unsigned int h52_faces[] = { + 3, 14,15,1, + 5, 15,7,10,11,1, + 6, 11,0,3,5,14,1, + 4, 12,6,13,2, + 6, 13,4,10,7,9,2, + 5, 9,5,3,12,2, + 5, 0,8,6,12,3, + 4, 13,6,8,4, + 5, 8,0,11,10,4, + 5, 9,7,15,14,5, +}; +const dReal h52_planes[ h52_numf * 4 ] = { + -0.425203,0.759567,-0.4922,0.41466,-0.0929092,0.293639,-0.951391,0.245904,-0.997066,0.0350131,0.0680664,0.350232,0.309646,0.434949,0.84554,0.229033,0.73548,0.309929,-0.602505,0.156511,0.148211,0.780702,0.607074,0.209209,-0.433652,-0.152285,0.888119,0.166047,0.485104,-0.868795,-0.0993492,0.328149,-0.66261,-0.69806,-0.271405,0.17825,-0.159459,0.944944,-0.285751,0.38448 +}; +// h53 +const int h53_numv = 16; +const int h53_numf = 10; +const dReal h53_volu = 0.086476; +const dReal h53_pos[3] = { -0.781555,0.807509,0.197497 }; +const dReal h53_verts[ h53_numv * 3 ] = { + 0.291496,-0.156419,-0.091704, -0.218445,0.192491,0.461269, -0.218445,0.192491,-0.255541, -0.218445,-0.397567,0.047987, 0.027292,-0.381663,-0.020188, -0.218445,-0.373860,0.169935, 0.033835,-0.380512,-0.018262, 0.352556,0.192491,0.043056, 0.162589,-0.213103,-0.139928, 0.191640,-0.261360,-0.072549, 0.238502,0.192491,-0.291089, 0.253338,0.013015,-0.278399, 0.326334,-0.087525,-0.081781, 0.317517,-0.112633,-0.111918, 0.238502,0.081667,-0.310092, 0.153590,0.192491,-0.346370, +}; +const unsigned int h53_faces[] = { + 7, 5,6,9,0,12,7,1, + 5, 7,10,15,2,1, + 4, 2,3,5,1, + 7, 15,14,11,8,4,3,2, + 4, 4,6,5,3, + 4, 8,9,6,4, + 6, 12,13,11,14,10,7, + 5, 11,13,0,9,8, + 3, 14,15,10, + 3, 0,13,12, +}; +const dReal h53_planes[ h53_numf * 4 ] = { + 0.545755,-0.383303,0.745138,0.150709,-0,1,0,0.192491,-1,0,-0,0.218445,-0.212159,-0.447018,-0.869002,0.182363,0.11569,-0.975032,0.189546,0.371464,0.311731,-0.703731,-0.638425,0.289984,0.944939,0.0553043,-0.322539,0.329903,0.49733,-0.589429,-0.636582,0.295545,0.540055,0.142236,-0.829524,0.397648,0.877441,-0.462191,0.128357,0.316295 +}; +// h54 +const int h54_numv = 20; +const int h54_numf = 12; +const dReal h54_volu = 0.089003; +const dReal h54_pos[3] = { -0.845912,0.679404,-0.140778 }; +const dReal h54_verts[ h54_numv * 3 ] = { + 0.317695,0.141120,0.059877, 0.091649,-0.253558,0.318087, -0.154088,0.080768,-0.359617, -0.152707,-0.484157,0.192529, -0.154088,0.320596,0.082735, 0.078976,0.204301,-0.281846, -0.154088,-0.269462,0.386262, -0.154088,0.320596,-0.236248, -0.154088,-0.484416,0.192760, 0.226946,-0.084997,0.198347, 0.060656,0.320596,-0.223141, 0.161719,-0.084997,-0.120143, 0.217947,0.320596,-0.008094, -0.049829,0.124065,-0.330981, -0.154088,-0.230098,-0.199706, -0.019141,-0.278134,-0.109104, 0.160374,0.124065,-0.228342, 0.234799,0.071081,-0.164747, 0.302859,0.209772,0.028184, 0.317695,0.159603,0.012337, +}; +const unsigned int h54_faces[] = { + 4, 6,8,3,1, + 5, 3,15,11,9,1, + 7, 9,0,18,12,4,6,1, + 5, 7,10,5,13,2, + 7, 13,16,17,11,15,14,2, + 6, 14,8,6,4,7,2, + 4, 8,14,15,3, + 4, 12,10,7,4, + 7, 10,12,18,19,17,16,5, + 3, 16,13,5, + 5, 11,17,19,0,9, + 3, 0,19,18, +}; +const dReal h54_planes[ h54_numf * 4 ] = { + 0.242073,-0.64915,0.721114,0.41616,0.717787,-0.680568,-0.147003,0.191588,0.212159,0.447018,0.869002,0.182518,0.0541955,0.456759,-0.887938,0.347858,0.398278,-0.419585,-0.815673,0.19807,-1,0,0,0.154088,0.066237,-0.837367,-0.542613,0.290833,0,1,0,0.320596,0.742791,0.391264,-0.543299,0.291725,0.433652,-0.152285,-0.888119,0.253448,0.870583,-0.45858,-0.178295,0.201189,0.962317,0.253449,0.0985412,0.34739 +}; +// h55 +const int h55_numv = 16; +const int h55_numf = 10; +const dReal h55_volu = 0.055290; +const dReal h55_pos[3] = { 0.087136,0.788999,0.139771 }; +const dReal h55_verts[ h55_numv * 3 ] = { + 0.076080,-0.416095,-0.083059, -0.323951,0.211001,0.286715, 0.205112,0.211001,-0.185127, 0.076081,0.211001,-0.405639, -0.148237,0.211001,0.332473, 0.101171,-0.226374,0.192117, -0.006832,-0.085411,0.277812, 0.205111,-0.223849,0.038561, -0.274823,0.078877,0.258729, 0.035595,0.211001,-0.415523, 0.074576,-0.413789,-0.064275, 0.079238,-0.416513,-0.077447, 0.107256,-0.249478,0.168347, 0.117855,-0.236273,0.172768, 0.029258,-0.402186,-0.087713, 0.035598,-0.405195,-0.098549, +}; +const unsigned int h55_faces[] = { + 4, 8,6,4,1, + 5, 4,2,3,9,1, + 5, 9,15,14,8,1, + 5, 7,11,0,3,2, + 6, 4,6,5,13,7,2, + 4, 0,15,9,3, + 3, 12,13,5, + 6, 6,8,14,10,12,5, + 5, 13,12,10,11,7, + 5, 14,15,0,11,10, +}; +const dReal h55_planes[ h55_numf * 4 ] = { + -0.241471,-0.286187,0.927248,0.283694,0,1,0,0.211001,-0.866617,-0.228251,-0.443708,0.105363,0.835368,-0.251447,-0.48881,0.20878,0.793214,0.278548,0.541501,0.121225,0.212159,-0.447018,-0.869002,0.274321,0.443092,-0.583496,0.68059,0.307669,-0.463507,-0.691764,0.553737,0.216086,0.66062,-0.653782,0.368986,0.296077,-0.292039,-0.95183,0.0934524,0.366071 +}; +// h56 +const int h56_numv = 20; +const int h56_numf = 12; +const dReal h56_volu = 0.096963; +const dReal h56_pos[3] = { -0.186579,0.800379,0.005269 }; +const dReal h56_verts[ h56_numv * 3 ] = { + 0.004502,-0.334912,-0.018030, 0.302973,-0.413566,0.046788, 0.309310,0.199621,-0.281021, -0.242420,0.199621,0.235284, -0.121421,0.199621,0.412527, 0.172708,0.199621,-0.357250, -0.050236,0.199621,0.421217, -0.341638,0.020145,-0.086171, -0.356474,0.199621,-0.098861, 0.097656,0.085128,-0.340236, -0.001108,0.067497,0.393231, -0.356474,0.088797,-0.117864, -0.277459,-0.105503,0.080310, 0.309314,-0.416575,0.035953, 0.106078,-0.385531,-0.020510, 0.188512,-0.404604,-0.037617, -0.268642,-0.080395,0.110447, -0.118494,0.123210,0.393231, -0.341638,0.038628,-0.133710, -0.322853,0.025254,-0.145176, +}; +const unsigned int h56_faces[] = { + 4, 14,15,13,1, + 5, 13,2,6,10,1, + 7, 10,17,16,12,0,14,1, + 5, 13,15,9,5,2, + 6, 5,8,3,4,6,2, + 4, 16,17,4,3, + 6, 8,11,7,12,16,3, + 4, 17,10,6,4, + 6, 9,19,18,11,8,5, + 5, 18,19,0,12,7, + 3, 11,18,7, + 5, 15,14,0,19,9, +}; +const dReal h56_planes[ h56_numf * 4 ] = { + -0.191593,-0.968844,0.156953,0.349977,0.866617,0.228251,0.443708,0.188925,-0.322183,-0.678838,0.659831,0.214003,0.444511,-0.409753,-0.796563,0.279548,4.04497e-16,1,-1.19541e-16,0.199621,-0.813673,-0.17144,0.555468,0.293719,-0.944939,-0.0553043,0.322539,0.29392,-0.117405,-0.247371,0.961782,0.361636,-0.433652,0.152285,-0.888119,0.272785,-0.662611,-0.698059,-0.271405,0.235698,-0.962317,-0.253449,-0.0985412,0.33215,-0.289106,-0.541462,-0.789453,0.194274 +}; +// h57 +const int h57_numv = 16; +const int h57_numf = 10; +const dReal h57_volu = 0.081294; +const dReal h57_pos[3] = { 0.851151,0.533342,0.098902 }; +const dReal h57_verts[ h57_numv * 3 ] = { + -0.184097,0.265595,0.004922, 0.148849,0.009818,-0.380153, 0.148849,-0.049459,0.325702, -0.275924,-0.093697,-0.138710, 0.148849,-0.119626,-0.357957, -0.275924,0.137573,0.059567, -0.112901,0.343928,0.059438, -0.249462,0.157589,0.121951, 0.148849,-0.434521,0.127992, 0.148849,0.447452,0.070089, 0.148849,-0.343521,0.212252, -0.023987,-0.337111,0.083159, -0.018406,-0.089149,0.305285, -0.008312,-0.125079,0.291731, -0.255475,-0.083645,-0.166703, -0.157047,0.040928,-0.236124, +}; +const unsigned int h57_faces[] = { + 4, 4,14,15,1, + 5, 15,0,6,9,1, + 6, 9,2,10,8,4,1, + 4, 12,13,10,2, + 5, 9,6,7,12,2, + 5, 14,4,8,11,3, + 6, 11,13,12,7,5,3, + 5, 5,0,15,14,3, + 4, 7,6,0,5, + 4, 10,13,11,8, +}; +const dReal h57_planes[ h57_numf * 4 ] = { + -0.433652,-0.152285,-0.888119,0.271577,-0.247318,0.694798,-0.675344,0.226742,1,0,-0,0.148849,-0.0284606,-0.359798,0.932596,0.317307,-0.212159,0.447018,0.869002,0.229347,-0.315015,-0.796483,-0.516121,0.233139,-0.792041,-0.39734,0.463457,0.191487,-0.805488,0.385717,-0.449902,0.248519,-0.777693,0.614473,0.132726,0.307026,-0.49733,-0.589428,0.636583,0.26357 +}; +// h58 +const int h58_numv = 20; +const int h58_numf = 12; +const dReal h58_volu = 0.077812; +const dReal h58_pos[3] = { 0.374418,0.849026,0.291935 }; +const dReal h58_verts[ h58_numv * 3 ] = { + -0.082171,-0.283876,-0.113603, 0.200809,-0.178111,-0.133466, -0.082170,0.150974,-0.337291, 0.089508,-0.034332,0.259248, 0.146093,0.150974,0.326019, 0.410849,0.150974,-0.104898, -0.435519,0.150974,0.180309, -0.294114,-0.145438,0.125648, 0.292636,-0.050089,-0.188111, 0.183309,0.150974,-0.304884, 0.227271,-0.158095,-0.071082, 0.363832,0.028244,-0.133595, -0.169427,-0.296300,0.020604, 0.087144,-0.178878,0.139171, 0.071270,-0.146859,0.192458, -0.429747,0.150974,0.185433, -0.186111,-0.286401,0.039952, 0.048213,-0.131812,0.221308, -0.268420,-0.171352,0.132706, -0.212551,-0.233071,0.128708, +}; +const unsigned int h58_faces[] = { + 5, 10,13,12,0,1, + 5, 0,2,9,8,1, + 4, 8,11,10,1, + 6, 0,12,16,7,6,2, + 6, 6,15,4,5,9,2, + 6, 4,15,18,19,17,3, + 3, 17,14,3, + 7, 14,13,10,11,5,4,3, + 4, 11,8,9,5, + 4, 7,18,15,6, + 4, 16,19,18,7, + 6, 13,14,17,19,16,12, +}; +const dReal h58_planes[ h58_numf * 4 ] = { + 0.35532,-0.923345,0.145539,0.216384,0.107916,-0.45476,-0.884052,0.220658,0.777693,-0.614473,-0.132726,0.283326,-0.793214,-0.278548,-0.541501,0.205768,0,1,-0,0.150974,-0.228531,-0.267508,0.936063,0.231401,0.535431,-0.493566,0.685351,0.242546,0.777334,-0.409459,0.477594,0.20745,0.658203,-0.077045,-0.748888,0.337347,-0.604377,-0.413861,0.68077,0.323484,-0.722579,-0.66608,0.18498,0.332636,0.131611,-0.83191,0.539078,0.235303 +}; +// h59 +const int h59_numv = 12; +const int h59_numf = 8; +const dReal h59_volu = 0.098632; +const dReal h59_pos[3] = { 0.795288,0.838821,-0.270144 }; +const dReal h59_verts[ h59_numv * 3 ] = { + -0.010021,0.161179,0.457181, -0.356162,0.161179,-0.206090, 0.204712,-0.152000,-0.380610, 0.204712,0.161179,-0.434310, -0.057037,0.038449,0.428484, -0.237561,0.161179,0.257195, -0.256523,-0.089455,-0.203657, -0.128234,-0.039885,0.373968, 0.204712,-0.295661,-0.011106, -0.101183,-0.264551,0.132922, 0.204712,0.141973,0.439135, 0.204712,0.161179,0.444075, +}; +const unsigned int h59_faces[] = { + 4, 3,2,6,1, + 5, 6,9,7,5,1, + 5, 5,0,11,3,1, + 5, 3,11,10,8,2, + 4, 8,9,6,2, + 4, 10,11,0,4, + 4, 0,5,7,4, + 5, 7,9,8,10,4, +}; +const dReal h59_planes[ h59_numf * 4 ] = { + -0.372229,-0.156858,-0.91479,0.29582,-0.90476,-0.357438,0.231619,0.216895,0,1,0,0.161178,1,1.92688e-15,-1.87292e-15,0.204712,-0.256529,-0.900844,-0.350247,0.217721,0.0590083,-0.248661,0.966792,0.401329,-0.658203,0.077045,0.748888,0.361391,0.247318,-0.694798,0.675344,0.248554 +}; +// h60 +const int h60_numv = 22; +const int h60_numf = 13; +const dReal h60_volu = 0.091310; +const dReal h60_pos[3] = { 0.415485,0.715407,-0.130668 }; +const dReal h60_verts[ h60_numv * 3 ] = { + -0.064779,0.284593,-0.364069, 0.142242,0.284593,0.117719, -0.242554,-0.352215,0.182461, 0.061056,-0.331466,0.081653, 0.180191,-0.265711,0.062868, 0.251569,0.083531,0.234492, -0.123237,0.284593,0.085312, -0.123238,-0.150257,0.309000, 0.159742,-0.044491,0.289138, 0.278619,-0.141137,-0.006553, -0.252268,0.284593,-0.135200, 0.123280,0.033960,-0.343133, 0.052142,0.000197,-0.360501, 0.023641,0.284593,-0.345566, 0.159742,-0.275763,0.090860, -0.138846,-0.370709,0.063434, -0.249111,-0.342921,0.192992, -0.046519,-0.292460,-0.089523, -0.252269,-0.342503,0.187380, -0.242676,-0.352703,0.180916, 0.052887,-0.337824,0.045824, 0.043373,-0.342729,0.054274, +}; +const unsigned int h60_faces[] = { + 5, 5,9,11,13,1, + 5, 13,0,10,6,1, + 5, 6,7,8,5,1, + 4, 16,18,19,2, + 5, 19,15,21,3,2, + 6, 3,14,8,7,16,2, + 5, 21,20,4,14,3, + 6, 20,17,12,11,9,4, + 5, 9,5,8,14,4, + 5, 10,18,16,7,6, + 7, 0,12,17,15,19,18,10, + 4, 12,0,13,11, + 4, 17,20,21,15, +}; +const dReal h60_planes[ h60_numf * 4 ] = { + 0.90476,0.357438,-0.231619,0.203154,8.63556e-17,1,-5.05304e-17,0.284593,-0.107916,0.45476,0.884052,0.218141,-0.60243,-0.746152,0.283435,0.460644,0.159459,-0.944944,0.285751,0.346285,0.284317,-0.624015,0.727852,0.28363,0.488006,-0.871758,0.0434538,0.322301,0.46199,-0.681388,-0.567693,0.228609,0.805488,-0.385717,0.449902,0.275915,-0.835368,0.251447,0.48881,0.21621,-0.73548,-0.309929,-0.602505,0.178793,0.204299,0.0717432,-0.976276,0.362615,0.120149,-0.911351,-0.393704,0.29619 +}; +// h61 +const int h61_numv = 24; +const int h61_numf = 14; +const dReal h61_volu = 0.075853; +const dReal h61_pos[3] = { 0.499694,0.403970,0.252554 }; +const dReal h61_verts[ h61_numv * 3 ] = { + 0.101994,0.286961,-0.031701, -0.294704,0.148756,0.059985, -0.023153,-0.020028,-0.301569, 0.156136,0.037589,0.286475, -0.323273,-0.108125,-0.115004, 0.032521,-0.286922,0.028066, -0.038132,0.266178,0.178552, 0.260541,-0.250848,-0.073994, 0.327470,-0.207739,-0.070493, 0.075532,0.266945,-0.094084, 0.075532,0.035675,-0.292362, 0.343145,0.004293,0.138079, 0.231743,0.048354,0.251404, 0.045317,0.188205,0.223756, -0.087937,-0.209333,0.181412, -0.330859,-0.089605,0.055955, 0.333052,0.040223,0.151633, 0.236542,0.052068,0.247099, -0.339382,-0.095975,-0.073501, -0.326763,-0.040778,-0.200761, -0.207448,0.161180,-0.074222, -0.333320,-0.031483,-0.190230, -0.305302,0.135551,0.055565, -0.337982,-0.028760,-0.177059, +}; +const unsigned int h61_faces[] = { + 5, 20,21,23,22,1, + 7, 22,15,14,3,13,6,1, + 5, 6,0,9,20,1, + 5, 7,5,4,19,2, + 6, 19,21,20,9,10,2, + 4, 10,8,7,2, + 7, 14,5,7,8,11,12,3, + 4, 12,17,13,3, + 5, 18,23,21,19,4, + 5, 5,14,15,18,4, + 5, 13,17,16,0,6, + 6, 10,9,0,16,11,8, + 4, 16,17,12,11, + 4, 22,23,18,15, +}; +const dReal h61_planes[ h61_numf * 4 ] = { + -0.66062,0.653782,-0.368986,0.269808,-0.438192,0.051293,0.897417,0.190598,-0.35532,0.923345,-0.145539,0.233338,-0.148211,-0.780702,-0.607074,0.202142,-0.284317,0.624015,-0.727852,0.213583,0.322885,-0.43293,-0.841615,0.255,0.391463,-0.659847,0.641373,0.220056,0.289106,0.541462,0.789453,0.291652,-0.900933,-0.358346,-0.24476,0.358143,-0.471464,-0.878752,0.0742736,0.238885,0.496382,0.766976,0.406636,0.25783,0.792041,0.39734,-0.463457,0.209497,0.696788,-0.0734069,0.713511,0.337305,-0.991833,0.112685,0.0597434,0.321404 +}; +// h62 +const int h62_numv = 18; +const int h62_numf = 11; +const dReal h62_volu = 0.089635; +const dReal h62_pos[3] = { -0.412607,-0.798932,0.393221 }; +const dReal h62_verts[ h62_numv * 3 ] = { + 0.143743,0.178906,-0.080212, -0.336591,-0.057070,0.045432, -0.365487,-0.201068,0.063069, -0.043446,-0.201068,0.325146, -0.118881,0.178753,-0.144486, -0.152818,-0.201068,-0.248459, 0.205095,-0.201068,-0.388268, 0.337853,-0.164947,-0.214818, 0.038585,0.368996,0.228990, 0.242459,-0.068737,-0.310888, -0.200495,0.172297,-0.114599, -0.231981,0.184967,-0.066303, 0.334110,-0.201068,-0.227916, 0.209245,-0.110463,-0.361925, 0.145031,0.335652,0.325145, 0.169974,0.297178,0.268816, -0.151147,0.272981,0.102025, 0.044821,0.272804,-0.007759, +}; +const unsigned int h62_faces[] = { + 5, 11,10,5,2,1, + 6, 2,3,14,8,16,1, + 3, 16,11,1, + 5, 5,6,12,3,2, + 5, 12,7,15,14,3, + 6, 10,11,16,8,17,4, + 5, 17,0,9,13,4, + 5, 13,6,5,10,4, + 5, 13,9,7,12,6, + 4, 9,0,15,7, + 5, 14,15,0,17,8, +}; +const dReal h62_planes[ h62_numf * 4 ] = { + -0.822068,0.096228,-0.561199,0.245712,-0.616244,0.216405,0.75724,0.229475,-0.870583,0.45858,0.178295,0.27496,4.16641e-16,-1,1.84056e-16,0.201068,0.793214,-0.278548,0.541501,0.197612,-0.20808,0.904248,-0.372879,0.24025,0.167754,0.706913,-0.687119,0.205699,-0.349687,0.276295,-0.895198,0.220304,0.770892,0.145024,-0.620237,0.369765,0.799798,0.547681,-0.245698,0.232657,0.526505,0.792388,-0.308081,0.242156 +}; +// h63 +const int h63_numv = 20; +const int h63_numf = 12; +const dReal h63_volu = 0.065070; +const dReal h63_pos[3] = { -0.683722,-0.408459,0.881106 }; +const dReal h63_verts[ h63_numv * 3 ] = { + 0.408763,0.050375,-0.050997, 0.001643,0.372246,0.104787, -0.316278,-0.373443,0.118894, -0.000569,0.379463,0.118894, -0.316278,-0.303582,-0.012874, 0.413107,-0.090210,0.118894, 0.072977,-0.026465,-0.250457, -0.316278,0.104758,0.118894, -0.133134,0.036421,-0.232486, -0.316278,-0.061367,-0.137470, 0.406500,0.014459,-0.083368, 0.416439,0.055265,0.118894, 0.411396,0.069115,-0.001513, 0.370009,0.144956,0.118894, 0.377753,0.036235,-0.132875, 0.381520,0.034894,-0.130346, 0.374104,0.031050,-0.138388, 0.376042,0.032985,-0.136218, 0.383396,0.034505,-0.128411, 0.385682,0.029196,-0.126410, +}; +const unsigned int h63_faces[] = { + 5, 8,9,7,3,1, + 8, 3,13,12,0,18,15,14,1, + 6, 14,17,16,6,8,1, + 7, 4,6,16,19,10,5,2, + 6, 5,11,13,3,7,2, + 4, 7,9,4,2, + 4, 9,8,6,4, + 5, 10,0,12,11,5, + 4, 19,18,0,10, + 3, 12,13,11, + 3, 15,17,14, + 5, 18,19,16,17,15, +}; +const dReal h63_planes[ h63_numf * 4 ] = { + -0.589724,0.677749,-0.439183,0.2053,0.50496,0.797961,-0.32905,0.263387,0.141863,0.672536,-0.72634,0.174471,0.324513,-0.835692,-0.443069,0.156769,2.1681e-17,-2.49173e-17,1,0.118894,-1,0,0,0.316278,-0.212159,-0.447018,-0.869002,0.213995,0.998749,-0.0228741,-0.044466,0.409367,0.901569,0.256913,-0.348094,0.399222,0.887955,0.459664,0.015677,0.397046,0.604872,0.393584,-0.692258,0.334738,0.721996,0.0507074,-0.690036,0.367169 +}; +// h64 +const int h64_numv = 14; +const int h64_numf = 9; +const dReal h64_volu = 0.063334; +const dReal h64_pos[3] = { -0.862240,-0.589074,0.504780 }; +const dReal h64_verts[ h64_numv * 3 ] = { + -0.034062,-0.410926,-0.010011, 0.045384,0.217035,0.143840, 0.295955,0.147819,0.066170, 0.251495,0.154150,0.125869, -0.137760,-0.410926,0.116573, -0.137760,0.324258,-0.236366, -0.137760,0.210059,-0.342106, -0.137760,-0.122967,0.363452, -0.137760,-0.410926,-0.022669, 0.298486,0.063123,-0.009534, -0.137760,0.298525,-0.037806, 0.113042,-0.266928,-0.066127, -0.137760,0.119248,0.238856, 0.217652,-0.024891,-0.177862, +}; +const unsigned int h64_faces[] = { + 3, 10,12,1, + 4, 12,7,3,1, + 5, 3,2,5,10,1, + 5, 9,13,6,5,2, + 7, 3,7,4,0,11,9,2, + 7, 7,12,10,5,6,8,4, + 3, 8,0,4, + 5, 13,11,0,8,6, + 3, 11,13,9, +}; +const dReal h64_planes[ h64_numf * 4 ] = { + -0.163718,0.827886,0.536471,0.249417,0.212159,0.447018,0.869002,0.231645,0.299389,0.946218,0.12263,0.23659,0.619037,0.533581,-0.576268,0.223949,0.679728,-0.477395,0.556833,0.167446,-1,0,0,0.13776,-0,-1,0,0.410926,0.107916,-0.45476,-0.884052,0.192047,0.870583,-0.45858,-0.178295,0.23261 +}; +// h65 +const int h65_numv = 22; +const int h65_numf = 13; +const dReal h65_volu = 0.115639; +const dReal h65_pos[3] = { -0.632833,-0.759826,0.781144 }; +const dReal h65_verts[ h65_numv * 3 ] = { + -0.367167,-0.022076,0.218856, 0.176779,-0.240174,-0.062777, -0.145261,-0.240174,-0.324854, -0.367167,-0.240174,-0.159791, -0.367167,-0.240174,0.218856, 0.229214,-0.240174,0.218856, -0.367167,0.047785,0.087088, 0.379478,0.318313,-0.027451, 0.258810,0.329890,-0.158933, 0.022088,0.324902,-0.150495, -0.263470,-0.240174,-0.286375, -0.116365,-0.096176,-0.342491, 0.384007,0.200623,0.218856, 0.365257,0.296546,-0.062778, 0.323215,0.382417,-0.038426, 0.362218,0.261157,0.218856, 0.374110,0.331198,-0.022696, 0.069079,0.233875,-0.285898, 0.066548,0.318571,-0.210194, 0.259984,0.356129,-0.135062, 0.334793,0.380563,-0.026448, 0.355611,0.365826,0.016594, +}; +const unsigned int h65_faces[] = { + 5, 13,7,12,5,1, + 6, 5,4,3,10,2,1, + 6, 2,11,17,8,13,1, + 3, 10,11,2, + 7, 6,9,18,17,11,10,3, + 4, 4,0,6,3, + 5, 5,12,15,0,4, + 7, 0,15,21,20,14,9,6, + 7, 13,8,19,14,20,16,7, + 5, 16,21,15,12,7, + 4, 17,18,19,8, + 4, 14,19,18,9, + 3, 20,21,16, +}; +const dReal h65_planes[ h65_numf * 4 ] = { + 0.929286,-0.326334,-0.173016,0.253517,5.14845e-16,-1,8.60294e-16,0.240174,0.616244,-0.216405,-0.75724,0.208451,-0.309078,-0.0542691,-0.949487,0.366376,-0.679728,0.477395,-0.556833,0.223893,-1,0,0,0.367167,-0,0,1,0.218856,-0.324513,0.835692,0.443069,0.19767,0.664689,0.486283,-0.567201,0.422595,0.931229,0.335191,0.143037,0.45615,0.156805,0.660773,-0.734024,0.375226,-0.11569,0.975032,-0.189546,0.34276,0.777249,0.606249,-0.168364,0.495386 +}; +// h66 +const int h66_numv = 12; +const int h66_numf = 8; +const dReal h66_volu = 0.090843; +const dReal h66_pos[3] = { 0.194452,-0.846656,0.702344 }; +const dReal h66_verts[ h66_numv * 3 ] = { + 0.144722,0.221953,-0.171396, 0.354760,-0.153344,-0.123136, 0.229722,0.177289,-0.118776, -0.077080,-0.093853,-0.442151, -0.263367,-0.153344,0.297656, 0.293204,-0.153344,0.297656, -0.291202,0.163722,0.297656, 0.229722,0.015381,0.297656, -0.072437,-0.153344,-0.456885, -0.246539,0.275009,-0.021290, -0.133324,-0.153344,-0.464317, -0.137311,-0.122439,-0.456854, +}; +const unsigned int h66_faces[] = { + 5, 8,3,0,2,1, + 4, 2,7,5,1, + 5, 5,4,10,8,1, + 5, 0,9,6,7,2, + 4, 8,10,11,3, + 4, 11,9,0,3, + 5, 6,9,11,10,4, + 4, 5,7,6,4, +}; +const dReal h66_planes[ h66_numf * 4 ] = { + 0.598205,0.236328,-0.765702,0.270266,0.927293,0.348894,0.13565,0.258762,2.17789e-18,-1,-1.78413e-17,0.153344,0.256529,0.900843,0.350248,0.17704,0.117405,0.247372,-0.961781,0.392986,-0.167754,0.706913,-0.687119,0.250394,-0.982077,-0.0862167,-0.167608,0.221978,0,0,1,0.297657 +}; +// h67 +const int h67_numv = 14; +const int h67_numf = 9; +const dReal h67_volu = 0.073139; +const dReal h67_pos[3] = { -0.182450,-0.819619,0.699488 }; +const dReal h67_verts[ h67_numv * 3 ] = { + 0.085699,0.136685,0.300512, -0.221169,-0.180381,0.300512, -0.273604,-0.180381,0.018878, 0.130363,0.247972,-0.018435, -0.085126,0.356339,0.018877, 0.113535,-0.180381,0.300512, -0.066376,0.260416,0.300512, -0.060183,0.317865,-0.037452, 0.103953,-0.180381,-0.534183, 0.107696,-0.144260,-0.521085, 0.239592,-0.149476,-0.453999, 0.243578,-0.180381,-0.461462, -0.070905,0.378106,0.054205, -0.032656,0.358692,0.028913, +}; +const unsigned int h67_faces[] = { + 5, 6,12,4,2,1, + 5, 2,8,11,5,1, + 4, 5,0,6,1, + 5, 4,7,9,8,2, + 5, 10,9,7,13,3, + 5, 13,12,6,0,3, + 5, 0,5,11,10,3, + 4, 12,13,7,4, + 4, 9,10,11,8, +}; +const dReal h67_planes[ h67_numf * 4 ] = { + -0.929286,0.326334,0.173016,0.198658,4.99955e-17,-1,-5.73911e-19,0.180381,0,0,1,0.300512,-0.793214,0.278548,-0.541501,0.156559,0.32928,0.737152,-0.590069,0.236597,0.59399,0.730061,0.337914,0.25224,0.982077,0.0862167,0.167608,0.146316,0.0662371,0.837367,-0.542614,0.282505,0.445543,0.264025,-0.855443,0.455654 +}; +// h68 +const int h68_numv = 24; +const int h68_numf = 14; +const dReal h68_volu = 0.110178; +const dReal h68_pos[3] = { 0.194790,-0.476753,0.823942 }; +const dReal h68_verts[ h68_numv * 3 ] = { + -0.387371,0.030890,-0.107289, 0.221446,0.021860,-0.353469, -0.465405,-0.021917,0.176058, -0.291540,-0.206181,0.176058, 0.076464,0.334736,-0.007133, 0.229384,-0.354523,0.176058, 0.292644,0.032441,-0.334080, -0.452945,0.146290,0.025179, 0.246219,0.093034,-0.297244, 0.229037,0.025757,-0.352826, 0.107091,0.321655,0.176058, 0.390186,-0.018723,0.176058, 0.312682,0.010704,-0.315910, 0.229384,-0.192615,-0.240374, 0.144384,-0.147950,-0.292995, -0.246877,-0.094895,-0.142888, -0.409896,0.015825,-0.095540, -0.443616,-0.082450,0.176058, -0.462073,0.123559,0.176058, -0.472012,0.082753,-0.026204, -0.453513,0.048124,-0.065494, -0.448145,0.035240,-0.070249, -0.469749,0.118668,0.006167, -0.467116,0.137408,0.055651, +}; +const unsigned int h68_faces[] = { + 5, 14,15,16,0,1, + 9, 0,20,19,22,7,4,8,9,1, + 6, 9,6,12,13,14,1, + 5, 19,20,21,17,2, + 7, 17,3,5,11,10,18,2, + 5, 18,23,22,19,2, + 5, 17,21,16,15,3, + 5, 15,14,13,5,3, + 6, 10,11,12,6,8,4, + 5, 7,23,18,10,4, + 4, 13,12,11,5, + 3, 9,8,6, + 3, 22,23,7, + 4, 21,20,0,16, +}; +const dReal h68_planes[ h68_numf * 4 ] = { + -0.372229,-0.156856,-0.91479,0.237492,-0.27553,0.653111,-0.705358,0.202583,0.296224,-0.4369,-0.849335,0.35626,-0.931229,-0.335191,-0.143037,0.415561,-0,0,1,0.176058,-0.998749,0.0228741,0.044466,0.472149,-0.59399,-0.730061,-0.337914,0.264205,-0.256529,-0.900843,-0.350248,0.198862,0.766208,0.637263,-0.0825892,0.272492,-0.326272,0.937436,0.121492,0.287979,0.88947,-0.425933,-0.165603,0.325878,0.16676,0.602337,-0.780629,0.329134,-0.777217,0.601031,-0.186267,0.435271,-0.512456,0.101226,-0.852726,0.293125 +}; +// h69 +const int h69_numv = 18; +const int h69_numf = 11; +const dReal h69_volu = 0.150904; +const dReal h69_pos[3] = { 0.751581,-0.668854,0.749549 }; +const dReal h69_verts[ h69_numv * 3 ] = { + 0.248419,0.357221,0.250451, -0.263925,-0.331146,0.250451, 0.248419,0.283773,-0.306518, 0.248419,-0.331146,0.009798, 0.000203,0.129153,-0.348181, 0.248419,-0.331146,0.250451, -0.202369,-0.331146,-0.170342, -0.161439,-0.331146,-0.190328, 0.248419,0.424683,-0.270088, -0.087381,0.269445,-0.329471, -0.149648,0.251714,-0.296027, -0.327407,-0.162422,0.250451, -0.166605,0.173379,0.250451, -0.045433,0.301175,-0.321470, -0.327407,-0.000512,-0.165981, -0.244109,0.202806,-0.241517, 0.223596,0.415674,-0.285417, 0.248419,0.419976,-0.283164, +}; +const unsigned int h69_faces[] = { + 4, 11,14,6,1, + 5, 6,7,3,5,1, + 5, 5,0,12,11,1, + 6, 4,9,13,16,17,2, + 6, 17,8,0,5,3,2, + 4, 3,7,4,2, + 7, 7,6,14,15,10,9,4, + 3, 17,16,8, + 7, 16,13,10,15,12,0,8, + 3, 10,13,9, + 4, 12,15,14,11, +}; +const dReal h69_planes[ h69_numf * 4 ] = { + -0.927293,-0.348894,-0.13565,0.326296,0,-1,-0,0.331146,8.48822e-17,-4.06468e-17,1,0.250451,0.0600487,0.168696,-0.983837,0.364353,1,-0,0,0.248419,0.398278,-0.419585,-0.815673,0.229892,-0.433652,-0.152285,-0.888119,0.28947,-0.131169,0.932758,-0.335793,0.454236,-0.402198,0.907959,0.117672,0.2539,-0.469026,0.741177,-0.480283,0.39893,-0.88947,0.425933,0.165603,0.263513 +}; +// h70 +const int h70_numv = 8; +const int h70_numf = 6; +const dReal h70_volu = 0.052841; +const dReal h70_pos[3] = { 0.870032,-0.820199,0.384721 }; +const dReal h70_verts[ h70_numv * 3 ] = { + 0.129968,-0.179801,0.374626, 0.129968,-0.179801,-0.351943, -0.279890,-0.179801,0.174500, 0.129968,0.435118,0.058310, -0.112815,-0.179801,-0.233397, -0.118249,0.280498,0.016648, 0.129968,-0.066134,-0.371433, -0.064784,-0.043027,-0.280302, +}; +const unsigned int h70_faces[] = { + 4, 4,7,6,1, + 4, 6,3,0,1, + 4, 0,2,4,1, + 4, 5,7,4,2, + 4, 0,3,5,2, + 4, 6,7,5,3, +}; +const dReal h70_planes[ h70_numf * 4 ] = { + -0.433652,-0.152285,-0.888119,0.283587,1,0,0,0.129968,0,-1,0,0.179801,-0.908278,0.191373,-0.372031,0.154889,-0.398278,0.419585,0.815673,0.178367,-0.267862,0.627092,-0.731441,0.195395 +}; +// h71 +const int h71_numv = 16; +const int h71_numf = 10; +const dReal h71_volu = 0.078575; +const dReal h71_pos[3] = { -0.715618,-0.146967,0.614144 }; +const dReal h71_verts[ h71_numv * 3 ] = { + -0.284382,-0.099249,-0.355298, 0.407938,-0.228507,0.130744, -0.284382,-0.117849,-0.345730, 0.406000,-0.230442,0.128574, 0.033539,0.110754,0.371749, 0.104873,-0.287957,0.016505, -0.197952,0.422046,0.249299, -0.284382,0.237452,0.048837, -0.101238,-0.225072,0.034476, -0.284382,-0.143582,-0.147170, 0.149333,-0.294288,-0.043194, 0.409649,-0.225257,0.134087, 0.147525,0.085239,-0.239307, 0.183419,0.150542,-0.169689, 0.342769,-0.256730,0.031938, 0.344779,-0.242424,0.025560, +}; +const unsigned int h71_faces[] = { + 4, 3,14,15,1, + 5, 15,12,13,11,1, + 6, 11,4,8,5,3,1, + 6, 0,12,15,14,10,2, + 5, 10,5,8,9,2, + 4, 9,7,0,2, + 4, 5,10,14,3, + 4, 11,13,6,4, + 5, 6,7,9,8,4, + 5, 13,12,0,7,6, +}; +const dReal h71_planes[ h71_numf * 4 ] = { + 0.830322,-0.320028,-0.456232,0.352199,0.848621,0.0894025,-0.521393,0.257586,-0.141863,-0.672536,0.72634,0.190772,0.398278,-0.419585,-0.815673,0.218187,-0.299389,-0.946218,-0.12263,0.239048,-1,-0,0,0.284382,0.11569,-0.975032,0.189546,0.296029,0.727925,0.639055,0.248465,0.187558,-0.735479,-0.309932,0.602505,0.164988,-0.1544,0.759081,-0.632422,0.193269 +}; +// h72 +const int h72_numv = 24; +const int h72_numf = 14; +const dReal h72_volu = 0.135103; +const dReal h72_pos[3] = { -0.469590,0.119774,0.755853 }; +const dReal h72_verts[ h72_numv * 3 ] = { + -0.212489,-0.155987,0.230040, -0.214701,-0.148769,0.244147, -0.443980,0.155306,0.107590, 0.375305,0.040715,-0.139275, -0.004437,0.090870,-0.389509, 0.311360,0.156806,0.046426, -0.480672,0.247962,0.244147, -0.005314,0.363706,-0.137567, 0.163621,-0.491997,-0.007622, 0.213688,0.055724,0.244147, -0.495580,0.247143,0.161130, -0.499540,0.269230,0.219387, 0.144703,0.290282,-0.088352, 0.355676,0.140088,-0.062598, -0.062609,-0.116199,-0.311398, -0.088334,0.254773,-0.303291, 0.356369,0.017480,-0.175583, 0.155877,-0.383277,0.244147, 0.169264,-0.493727,-0.003158, 0.197264,-0.459118,0.123740, 0.194631,-0.477857,0.074256, 0.211435,-0.450236,0.093267, 0.167388,-0.493339,-0.005093, 0.169626,-0.492143,-0.004615, +}; +const unsigned int h72_faces[] = { + 8, 0,8,22,18,20,19,17,1, + 4, 17,9,6,1, + 6, 6,11,10,2,0,1, + 5, 10,15,4,14,2, + 4, 14,8,0,2, + 7, 16,4,15,7,12,13,3, + 7, 13,5,9,17,19,21,3, + 6, 21,20,18,23,16,3, + 6, 16,23,22,8,14,4, + 3, 13,12,5, + 6, 12,7,11,6,9,5, + 4, 15,10,11,7, + 3, 22,23,18, + 3, 20,21,19, +}; +const dReal h72_planes[ h72_numf * 4 ] = { + -0.50496,-0.797961,0.32905,0.307465,0,0,1,0.244147,-0.820856,-0.550308,0.152828,0.29542,-0.751031,-0.0376746,-0.659191,0.256669,-0.727925,-0.639055,-0.248465,0.197203,0.49733,0.589429,-0.636582,0.299309,0.913105,-0.120244,0.389591,0.283536,0.892822,-0.397939,-0.210981,0.348263,0.398278,-0.419584,-0.815674,0.277818,0.568103,0.816132,0.105771,0.30977,0.226312,0.817437,0.529699,0.223235,-0.411928,0.842404,-0.347377,0.356365,0.474458,-0.651966,-0.591464,0.404071,0.777217,-0.601031,0.186267,0.452309 +}; +// h73 +const int h73_numv = 16; +const int h73_numf = 10; +const dReal h73_volu = 0.036032; +const dReal h73_pos[3] = { -0.912743,-0.085439,0.831075 }; +const dReal h73_verts[ h73_numv * 3 ] = { + 0.095887,-0.286600,-0.182455, -0.087257,0.175924,-0.168094, -0.087257,-0.205110,-0.364101, 0.230664,0.049226,0.154818, -0.037519,0.453174,0.168925, 0.228452,0.056443,0.168925, -0.087257,0.484247,0.168925, -0.000826,0.360518,0.032367, -0.087257,-0.218262,0.168925, -0.087257,-0.384387,-0.087440, -0.087257,0.485343,0.150329, -0.064760,0.476158,0.168925, -0.052427,0.452355,0.085908, -0.087257,0.457669,0.073457, -0.056387,0.474442,0.144165, -0.056885,0.474757,0.144652, +}; +const unsigned int h73_faces[] = { + 4, 13,12,7,1, + 5, 7,3,0,2,1, + 7, 2,9,8,6,10,13,1, + 3, 0,9,2, + 5, 5,8,9,0,3, + 6, 7,12,14,4,5,3, + 4, 14,15,11,4, + 5, 11,6,8,5,4, + 4, 11,15,10,6, + 5, 15,14,12,13,10, +}; +const dReal h73_planes[ h73_numf * 4 ] = { + 0.347582,0.610296,-0.711847,0.196695,0.735479,0.309932,-0.602505,0.091627,-1,0,0,0.0872566,0.163718,-0.827886,-0.536471,0.350852,0.589724,-0.677749,0.439183,0.170659,0.820856,0.550308,-0.152828,0.192771,0.636259,0.754085,0.162882,0.345375,3.43778e-17,-3.95092e-17,1,0.168925,0.337828,0.939579,0.0553497,0.434861,0.255819,0.909579,-0.327448,0.369911 +}; +// h74 +const int h74_numv = 22; +const int h74_numf = 13; +const dReal h74_volu = 0.115647; +const dReal h74_pos[3] = { -0.806688,0.162223,0.365754 }; +const dReal h74_verts[ h74_numv * 3 ] = { + -0.106882,0.112856,0.497689, -0.158482,0.204693,0.551229, 0.218764,0.243174,-0.153679, 0.270615,-0.014193,-0.214570, -0.193312,-0.071737,0.297227, 0.312298,0.070592,-0.150604, -0.069795,-0.227826,-0.358730, 0.248765,0.212323,0.086808, -0.193312,-0.408439,-0.106908, -0.193312,0.210007,0.538778, 0.301657,0.087464,-0.177940, -0.191931,0.033024,-0.314003, -0.193312,0.271426,0.001678, 0.058968,0.264774,-0.186519, -0.193312,0.247719,-0.120270, 0.052425,0.263623,-0.188445, 0.332661,0.048420,0.000590, 0.274489,-0.158648,0.078702, 0.238595,-0.223951,0.009084, 0.229318,-0.111676,-0.252511, -0.193312,-0.302733,-0.342536, -0.193312,0.032765,-0.313772, +}; +const unsigned int h74_faces[] = { + 6, 7,2,13,12,9,1, + 4, 9,4,0,1, + 5, 0,17,16,7,1, + 5, 7,16,5,10,2, + 8, 10,3,19,6,11,15,13,2, + 6, 5,16,17,18,19,3, + 3, 10,5,3, + 7, 9,12,14,21,20,8,4, + 5, 8,18,17,0,4, + 4, 20,21,11,6, + 5, 19,18,8,20,6, + 4, 21,14,15,11, + 4, 13,15,14,12, +}; +const dReal h74_planes[ h74_numf * 4 ] = { + 0.110273,0.987466,0.11292,0.246896,-0.347582,-0.610296,0.711847,0.322553,0.751031,0.0376746,0.659191,0.252053,0.878502,0.475257,-0.0486263,0.315228,0.228531,0.267508,-0.936063,0.258898,0.929286,-0.326334,-0.173016,0.293234,0.897445,-0.121213,-0.424146,0.335592,-1,0,0,0.193312,0.1544,-0.759081,0.632422,0.21258,-0.179474,0.0840327,-0.980167,0.344997,0.446963,-0.816184,-0.366152,0.286102,-0.242073,0.64915,-0.721114,0.29433,-0.11569,0.975032,-0.189546,0.286695 +}; +// h75 +const int h75_numv = 18; +const int h75_numf = 11; +const dReal h75_volu = 0.089620; +const dReal h75_pos[3] = { 0.052817,0.072055,0.868740 }; +const dReal h75_verts[ h75_numv * 3 ] = { + 0.433734,0.123433,0.131260, 0.005775,0.176863,-0.278988, 0.218437,-0.214071,-0.051932, -0.366530,-0.335558,0.131260, -0.308719,0.103443,0.131260, -0.147102,0.088434,-0.252162, -0.310972,-0.402518,-0.019619, -0.003079,0.231496,-0.237914, 0.112171,0.347564,-0.006639, 0.302595,-0.019353,-0.141822, 0.235603,0.353295,0.131260, 0.077918,0.377107,0.131260, 0.249063,-0.227153,0.131260, -0.166731,0.187806,-0.175486, -0.093909,0.310921,0.131260, -0.211047,0.204525,-0.066461, -0.325143,-0.411399,0.010853, -0.320100,-0.425249,0.131260, +}; +const unsigned int h75_faces[] = { + 6, 7,8,10,0,9,1, + 5, 9,2,6,5,1, + 4, 5,13,7,1, + 5, 12,17,16,6,2, + 4, 9,0,12,2, + 3, 16,17,3, + 8, 17,12,0,10,11,14,4,3, + 7, 4,15,13,5,6,16,3, + 3, 14,15,4, + 6, 13,15,14,11,8,7, + 3, 11,10,8, +}; +const dReal h75_planes[ h75_numf * 4 ] = { + 0.619037,0.533582,-0.576267,0.258718,0.107917,-0.454758,-0.884053,0.166834,-0.421977,0.500122,-0.756183,0.296982,0.326272,-0.937436,-0.121492,0.278257,0.870584,-0.458578,-0.178296,0.297595,-0.887955,-0.459664,-0.015677,0.477648,0,0,1,0.13126,-0.913105,0.120244,-0.389591,0.243193,-0.694517,0.719058,0.0245236,0.292011,-0.345296,0.896431,-0.277815,0.27468,0.14709,0.974029,-0.172138,0.356179 +}; +// h76 +const int h76_numv = 24; +const int h76_numf = 14; +const dReal h76_volu = 0.095138; +const dReal h76_pos[3] = { 0.088788,-0.142804,0.576459 }; +const dReal h76_verts[ h76_numv * 3 ] = { + 0.352221,-0.240915,-0.049761, -0.386828,-0.236459,0.178237, 0.182466,0.000788,0.240349, -0.006268,0.044860,-0.340368, 0.298110,0.182836,0.102163, -0.389114,-0.231150,0.176236, -0.030195,0.391722,0.013292, -0.363747,-0.215280,0.253650, -0.388752,-0.229565,0.174779, -0.101327,0.289860,-0.170144, 0.328315,-0.307617,-0.113256, -0.079254,0.048914,-0.283309, 0.094387,-0.120263,-0.302438, -0.281369,-0.303059,0.140194, 0.335039,-0.308192,-0.105343, 0.327448,-0.312089,-0.105986, 0.022142,0.379302,-0.133650, -0.346943,-0.187659,0.272661, -0.202009,0.280058,0.003811, -0.183073,0.303293,0.040119, 0.266624,0.195506,0.150459, -0.022476,0.325632,-0.215723, -0.347511,-0.285824,0.181989, -0.366010,-0.251196,0.221279, +}; +const unsigned int h76_faces[] = { + 3, 22,23,1, + 4, 23,7,5,1, + 8, 5,8,11,3,12,13,22,1, + 9, 17,7,23,22,13,15,14,0,2, + 4, 0,4,20,2, + 5, 20,6,19,17,2, + 4, 11,9,21,3, + 8, 21,16,4,0,14,10,12,3, + 4, 16,6,20,4, + 6, 7,17,19,18,8,5, + 6, 16,21,9,18,19,6, + 4, 18,9,11,8, + 3, 14,15,10, + 4, 15,13,12,10, +}; +const dReal h76_planes[ h76_numf * 4 ] = { + -0.777249,-0.606249,0.168364,0.474024,-0.901569,-0.256913,0.348094,0.471545,-0.553104,-0.49165,-0.672575,0.210334,0.27553,-0.653111,0.705358,0.219292,0.822068,-0.096228,0.561199,0.284807,-0.107917,0.454758,0.884053,0.193148,-0.576312,0.303571,-0.758755,0.275486,0.73548,0.309929,-0.602505,0.214367,0.512085,0.851811,0.110395,0.319678,-0.892822,0.397939,0.210981,0.292608,-0.517294,0.817451,-0.253339,0.332466,-0.859244,0.150868,-0.488814,0.213964,0.440632,-0.78713,-0.431589,0.435681,-0.226312,-0.817437,-0.529699,0.237148 +}; +// h77 +const int h77_numv = 26; +const int h77_numf = 15; +const dReal h77_volu = 0.087804; +const dReal h77_pos[3] = { 0.390778,-0.073451,0.362494 }; +const dReal h77_verts[ h77_numv * 3 ] = { + -0.003880,0.113483,0.316128, 0.315369,-0.294228,0.065585, -0.206158,-0.189928,-0.093832, 0.020979,0.268088,0.071472, -0.324466,0.256279,-0.001758, -0.230465,0.381445,-0.183441, 0.426887,-0.187811,0.054869, 0.211155,-0.343689,0.091028, -0.224735,0.155039,-0.266749, 0.077733,0.119939,0.286241, 0.026325,-0.376970,0.100709, -0.297695,-0.031084,-0.153195, 0.009520,-0.343472,-0.067504, 0.155269,-0.307156,-0.121769, -0.207604,-0.189616,-0.088472, -0.308258,-0.024493,-0.126403, 0.050231,-0.310268,0.164204, 0.176117,-0.273019,-0.144419, 0.417855,-0.153875,-0.005953, 0.273422,-0.325958,0.057585, 0.096656,-0.370860,0.127368, 0.033049,-0.377545,0.108622, -0.214357,0.369295,-0.224944, 0.141437,0.190499,-0.081874, -0.279848,0.309949,0.080316, -0.221943,0.387815,-0.053985, +}; +const unsigned int h77_faces[] = { + 6, 19,13,17,18,6,1, + 7, 6,9,0,16,20,7,1, + 3, 7,19,1, + 4, 14,15,11,2, + 6, 11,8,17,13,12,2, + 4, 12,10,14,2, + 5, 25,24,0,9,3, + 5, 9,6,18,23,3, + 5, 23,22,5,25,3, + 4, 24,25,5,4, + 6, 5,22,8,11,15,4, + 8, 15,14,10,21,16,0,24,4, + 7, 20,21,10,12,13,19,7, + 5, 22,23,18,17,8, + 3, 21,20,16, +}; +const dReal h77_planes[ h77_numf * 4 ] = { + 0.590109,-0.664552,-0.458413,0.351567,0.349687,-0.276295,0.895198,0.250286,0.469026,-0.741177,0.480283,0.397491,-0.818514,-0.542417,-0.189261,0.289522,-0.212159,-0.447018,-0.869002,0.21018,-0.568104,-0.816131,-0.105771,0.28205,0.131611,0.83191,0.539077,0.264315,0.727924,0.639056,0.248465,0.204352,0.471464,0.878752,-0.0742736,0.240165,-0.784459,0.61982,0.0211391,0.41334,-0.913105,0.120244,-0.389591,0.327772,-0.73548,-0.309929,0.602505,0.158151,0.162747,-0.964426,-0.208316,0.346865,0.433652,0.152285,-0.888119,0.163058,-0.16676,-0.602337,0.780629,0.306692 +}; +// h78 +const int h78_numv = 20; +const int h78_numf = 12; +const dReal h78_volu = 0.126407; +const dReal h78_pos[3] = { 0.652845,-0.171711,0.785711 }; +const dReal h78_verts[ h78_numv * 3 ] = { + -0.350965,0.016612,0.214289, 0.347155,-0.072460,-0.306250, -0.381591,0.029695,0.031097, 0.347155,-0.139922,0.214289, 0.322332,-0.081469,-0.321579, -0.265947,0.211743,-0.107089, -0.020631,0.312250,-0.000249, 0.347155,0.151286,0.214289, 0.347155,-0.036860,-0.269624, -0.184333,0.218199,-0.136976, -0.297433,0.224413,-0.058793, -0.211836,-0.212008,-0.259013, -0.050911,-0.245429,-0.332189, -0.067869,-0.323764,0.214289, -0.166294,0.367199,0.214289, -0.026282,0.399418,0.214289, -0.145373,-0.294337,-0.277679, -0.165410,-0.272600,-0.295849, 0.053302,-0.195968,-0.357632, 0.164820,-0.089551,-0.368349, +}; +const unsigned int h78_faces[] = { + 7, 3,13,16,12,18,4,1, + 6, 4,19,9,6,8,1, + 4, 8,7,3,1, + 6, 11,17,16,13,0,2, + 4, 0,14,10,2, + 4, 10,5,11,2, + 6, 7,15,14,0,13,3, + 3, 18,19,4, + 6, 10,14,15,6,9,5, + 7, 9,19,18,12,17,11,5, + 4, 15,7,8,6, + 3, 16,17,12, +}; +const dReal h78_planes[ h78_numf * 4 ] = { + 0.402198,-0.907959,-0.117672,0.241453,0.167754,0.706913,-0.687119,0.217444,1,-0,0,0.347155,-0.766208,-0.637263,0.0825892,0.276023,-0.870584,0.458578,0.178296,0.351369,-0.822068,0.096228,-0.561199,0.2991,0,-0,1,0.214289,0.280943,-0.383024,-0.879979,0.404745,-0.20808,0.904248,-0.372879,0.286737,-0.349687,0.276295,-0.895198,0.247367,0.526505,0.792388,-0.308081,0.236638,-0.071473,-0.677671,-0.731884,0.413083 +}; +// h79 +const int h79_numv = 20; +const int h79_numf = 12; +const dReal h79_volu = 0.069132; +const dReal h79_pos[3] = { 0.747670,0.086302,0.441993 }; +const dReal h79_verts[ h79_numv * 3 ] = { + 0.252330,0.012519,-0.215098, 0.012566,0.066820,-0.263433, 0.201221,-0.224177,-0.182831, 0.095169,0.321961,-0.051360, -0.091840,0.355257,0.097036, -0.215455,0.030746,-0.161373, -0.279159,-0.039814,0.206742, 0.060963,-0.313628,-0.085453, -0.115456,0.054238,0.343469, 0.252330,-0.294873,0.074094, -0.016233,0.366022,0.061965, -0.074702,0.310522,0.161887, 0.252330,0.103519,-0.130839, 0.252330,-0.216744,-0.175787, -0.335913,0.108335,-0.008027, 0.079494,0.109929,-0.259932, 0.069995,-0.347564,-0.024631, 0.252330,-0.330473,0.037468, 0.252330,-0.335180,0.024392, 0.227507,-0.339482,0.022139, +}; +const unsigned int h79_faces[] = { + 7, 5,14,4,10,3,15,1, + 5, 15,0,13,2,1, + 4, 2,7,5,1, + 6, 13,18,19,16,7,2, + 6, 10,11,8,9,12,3, + 4, 12,0,15,3, + 5, 14,6,8,11,4, + 3, 11,10,4, + 5, 7,16,6,14,5, + 6, 16,19,17,9,8,6, + 6, 17,18,13,0,12,9, + 3, 19,18,17, +}; +const dReal h79_planes[ h79_numf * 4 ] = { + -0.391463,0.659847,-0.641373,0.208131,0.158394,-0.166869,-0.973173,0.247207,-0.309646,-0.434949,-0.84554,0.189789,0.191731,-0.844679,-0.499756,0.319309,0.73548,0.309929,0.602505,0.138836,0.49733,0.589428,-0.636583,0.269798,-0.708232,0.479648,0.518021,0.285709,0.131611,0.831909,0.539078,0.335765,-0.727924,-0.639056,-0.248465,0.177281,-0.167754,-0.706913,0.687119,0.217031,1,0,0,0.25233,0.131169,-0.932758,0.335793,0.35393 +}; +// h80 +const int h80_numv = 14; +const int h80_numf = 9; +const dReal h80_volu = 0.076324; +const dReal h80_pos[3] = { 0.872729,0.237609,0.718600 }; +const dReal h80_verts[ h80_numv * 3 ] = { + 0.127271,0.331095,-0.032200, 0.127271,-0.258034,0.281400, 0.127271,-0.446180,-0.202512, -0.199761,0.159215,-0.114719, -0.141292,0.214715,-0.214641, -0.136492,0.218429,-0.218946, -0.240515,-0.097070,0.066863, -0.246166,-0.009903,0.281400, -0.239577,0.050556,0.281400, 0.127271,0.263358,0.281400, 0.127271,0.246274,-0.293996, 0.127271,-0.047788,-0.407445, -0.039983,0.206584,-0.314412, -0.029889,0.170654,-0.327966, +}; +const unsigned int h80_faces[] = { + 4, 7,6,2,1, + 6, 2,11,10,0,9,1, + 4, 9,8,7,1, + 6, 6,3,4,13,11,2, + 6, 8,9,0,5,4,3, + 4, 6,7,8,3, + 4, 5,12,13,4, + 4, 0,10,12,5, + 4, 11,13,12,10, +}; +const dReal h80_planes[ h80_numf * 4 ] = { + -0.526505,-0.792388,0.308081,0.224148,1,0,0,0.127271,0,0,1,0.281401,-0.73548,-0.309929,-0.602505,0.166694,-0.493234,0.850287,0.183662,0.212838,-0.991673,0.108076,-0.0700326,0.223339,-0.696788,0.0734069,-0.713511,0.267361,-0.184883,0.934913,-0.302912,0.295769,0.0284606,0.359798,-0.932596,0.36641 +}; +// h81 +const int h81_numv = 10; +const int h81_numf = 7; +const dReal h81_volu = 0.092471; +const dReal h81_pos[3] = { -0.647649,0.823554,0.820209 }; +const dReal h81_verts[ h81_numv * 3 ] = { + 0.457657,0.176446,0.179791, -0.352351,-0.423650,0.161195, -0.352351,0.176446,-0.147497, -0.352351,-0.424746,0.179791, -0.352351,0.176446,0.179791, 0.395926,0.059255,0.179791, 0.203225,-0.169390,-0.173056, 0.338792,0.176446,-0.400601, -0.321979,-0.434236,0.155518, -0.329854,-0.432835,0.179791, +}; +const unsigned int h81_faces[] = { + 4, 8,9,3,1, + 4, 3,4,2,1, + 5, 2,7,6,8,1, + 4, 4,0,7,2, + 5, 9,5,0,4,3, + 4, 6,7,0,5, + 4, 9,8,6,5, +}; +const dReal h81_planes[ h81_numf * 4 ] = { + -0.337828,-0.939579,-0.0553497,0.508165,-1,-9.23352e-17,0,0.352351,-0.309646,-0.434949,-0.84554,0.157073,0,1,-0,0.176446,-0,0,1,0.179791,0.870584,-0.458578,-0.178296,0.285458,0.546922,-0.806654,0.224019,0.209019 +}; +// h82 +const int h82_numv = 22; +const int h82_numf = 13; +const dReal h82_volu = 0.133984; +const dReal h82_pos[3] = { -0.704013,0.655334,0.510913 }; +const dReal h82_verts[ h82_numv * 3 ] = { + -0.295987,0.344666,0.147853, 0.143982,-0.175036,-0.341668, -0.295987,-0.255430,0.470491, 0.398940,0.268255,-0.112413, -0.265615,-0.266016,0.464814, -0.043708,-0.228337,-0.331678, 0.395156,0.344666,-0.091306, 0.146090,-0.280788,-0.058352, 0.259589,-0.001170,0.136240, -0.295987,0.344666,0.161799, 0.268488,-0.087750,0.102566, -0.295987,-0.221685,-0.143481, -0.265117,-0.266331,0.464327, 0.229109,-0.171854,0.107373, -0.295987,-0.283104,0.393619, -0.261157,-0.288418,0.406070, 0.116089,-0.249937,-0.298838, 0.396013,0.344666,-0.093117, 0.248792,0.064649,-0.395197, 0.275014,0.344666,-0.270360, 0.114098,-0.109185,-0.385965, 0.213954,-0.004245,-0.405120, +}; +const unsigned int h82_faces[] = { + 4, 16,5,20,1, + 3, 20,21,1, + 8, 21,18,3,10,13,7,16,1, + 5, 14,15,12,4,2, + 5, 4,8,6,9,2, + 5, 9,0,11,14,2, + 4, 18,19,17,3, + 5, 17,6,8,10,3, + 5, 12,13,10,8,4, + 6, 16,7,15,14,11,5, + 7, 11,0,19,18,21,20,5, + 5, 17,19,0,9,6, + 4, 13,12,15,7, +}; +const dReal h82_planes[ h82_numf * 4 ] = { + 0.103318,-0.522457,-0.846383,0.395508,0.296224,-0.4369,-0.849335,0.409315,0.88947,-0.425933,-0.165603,0.259202,-0.255819,-0.909579,0.327448,0.462115,0.309646,0.434949,0.84554,0.195068,-1,0,0,0.295987,0.813673,0.17144,-0.555468,0.433038,0.901694,-0.0730707,0.426155,0.292215,0.598205,-0.236328,0.765702,0.259883,-0.110273,-0.987466,-0.11292,0.267748,-0.545755,0.383303,-0.745138,0.183477,-9.72172e-17,1,0,0.344666,0.411928,-0.842404,0.347377,0.276446 +}; +// h83 +const int h83_numv = 12; +const int h83_numf = 8; +const dReal h83_volu = 0.056796; +const dReal h83_pos[3] = { -0.429347,0.488254,0.882979 }; +const dReal h83_verts[ h83_numv * 3 ] = { + -0.006178,0.079330,-0.269501, -0.548156,-0.097535,0.117020, -0.015077,0.165910,-0.235826, -0.540281,-0.098936,0.092747, 0.104460,-0.078198,-0.215479, 0.388255,-0.105278,0.117020, 0.173445,-0.312756,0.117020, 0.177624,0.394555,0.117020, -0.045557,-0.004774,-0.264694, 0.271117,-0.211674,-0.080700, -0.539783,-0.099251,0.092261, -0.520915,-0.120519,0.117020, +}; +const unsigned int h83_faces[] = { + 4, 3,10,11,1, + 5, 11,6,5,7,1, + 4, 7,2,3,1, + 6, 7,5,9,4,0,2, + 5, 0,8,10,3,2, + 6, 9,6,11,10,8,4, + 3, 8,0,4, + 3, 6,9,5, +}; +const dReal h83_planes[ h83_numf * 4 ] = { + -0.636259,-0.754085,-0.162882,0.403258,0,0,1,0.117021,-0.546922,0.806654,-0.224019,0.194907,0.735479,0.309932,-0.602505,0.182419,-0.598205,0.236328,-0.765702,0.228801,-0.226312,-0.817437,-0.529699,0.15442,0.233951,-0.164311,-0.958264,0.243773,0.694517,-0.719058,-0.0245236,0.342481 +}; +// h84 +const int h84_numv = 22; +const int h84_numf = 13; +const dReal h84_volu = 0.109330; +const dReal h84_pos[3] = { -0.121674,0.670783,0.713170 }; +const dReal h84_verts[ h84_numv * 3 ] = { + -0.313851,-0.103198,-0.099691, -0.010109,0.329217,0.286830, 0.252410,-0.221620,0.286830, -0.068318,0.329217,0.286830, 0.080582,-0.287807,0.286830, 0.201978,0.032805,-0.295587, -0.187183,0.329217,-0.293562, 0.227672,0.006891,-0.288529, -0.130049,0.212026,0.286830, -0.322750,-0.016619,-0.066017, -0.036556,-0.394202,0.089109, 0.171412,-0.367231,-0.082344, -0.203213,-0.260726,-0.045669, 0.007760,-0.410921,-0.019916, 0.265234,-0.083360,-0.251274, 0.286662,-0.251163,0.148930, -0.115141,0.329217,-0.286684, -0.066013,0.197094,-0.314670, -0.183399,0.252807,-0.314670, -0.186326,0.329217,-0.295374, 0.060573,0.329217,-0.240926, 0.066345,0.329217,-0.235802, +}; +const unsigned int h84_faces[] = { + 6, 2,15,14,7,21,1, + 7, 21,20,16,19,6,3,1, + 5, 3,8,4,2,1, + 6, 4,10,13,11,15,2, + 4, 6,9,8,3, + 6, 8,9,0,12,10,4, + 4, 20,21,7,5, + 9, 7,14,11,13,12,0,18,17,5, + 4, 17,16,20,5, + 5, 19,18,0,9,6, + 3, 12,13,10, + 3, 14,15,11, + 4, 17,18,19,16, +}; +const dReal h84_planes[ h84_numf * 4 ] = { + 0.894954,0.426518,0.130919,0.168922,0,1,0,0.329217,0,0,1,0.28683,0.345296,-0.896431,0.277815,0.365509,-0.870584,0.458578,0.178296,0.261589,-0.735479,-0.309932,0.602505,0.202751,0.604377,0.413861,-0.68077,0.336874,-0.212159,-0.447018,-0.869002,0.19935,0.241471,0.286187,-0.927248,0.332242,-0.901694,0.0730707,-0.426155,0.317941,-0.568103,-0.816132,-0.105771,0.333064,0.877503,-0.423705,-0.224641,0.32451,0.117405,0.247371,-0.961782,0.343649 +}; +// h85 +const int h85_numv = 36; +const int h85_numf = 20; +const dReal h85_volu = 0.148789; +const dReal h85_pos[3] = { -0.198763,0.456116,0.345386 }; +const dReal h85_verts[ h85_numv * 3 ] = { + 0.248501,-0.152565,0.285440, 0.011075,0.411760,0.053114, 0.304761,0.221558,0.079254, 0.360475,-0.080906,-0.269891, -0.389161,-0.050719,-0.133311, 0.279067,0.247472,0.072197, 0.342323,0.131307,0.116509, -0.236762,0.111468,0.268093, 0.084849,-0.196255,0.347868, 0.186224,-0.309060,0.060929, -0.295627,-0.223301,-0.130236, 0.016686,0.009351,-0.358147, 0.315157,-0.069303,-0.293328, -0.106311,0.467473,0.053114, 0.257356,-0.207198,0.244366, 0.367598,-0.141752,-0.036878, 0.104478,-0.295627,0.271192, -0.126124,-0.046060,0.322115, -0.256458,0.263868,-0.229670, 0.085542,-0.318862,0.234884, -0.291296,0.194974,-0.239593, -0.265275,0.238760,-0.259807, -0.361268,0.024182,-0.176141, -0.291163,-0.195420,-0.172718, -0.276141,0.027364,0.272900, -0.306268,-0.206429,-0.157572, -0.275264,-0.245473,0.020958, -0.359160,-0.081570,0.107176, 0.360630,0.159839,0.075257, 0.387070,0.106509,-0.013499, 0.393155,0.083405,-0.037268, 0.359076,-0.148122,-0.166333, 0.309693,-0.219618,0.097423, 0.265075,-0.273288,0.015350, 0.118262,-0.041268,-0.360627, 0.049809,-0.043705,-0.365222, +}; +const unsigned int h85_faces[] = { + 7, 12,34,11,21,18,13,1, + 9, 13,7,17,8,0,6,2,5,1, + 6, 5,29,30,3,12,1, + 4, 28,29,5,2, + 3, 6,28,2, + 4, 30,15,31,3, + 10, 31,33,9,10,25,23,35,34,12,3, + 5, 25,10,26,27,4, + 8, 27,24,7,13,18,20,22,4, + 4, 22,23,25,4, + 8, 0,14,32,15,30,29,28,6, + 3, 24,17,7, + 7, 17,24,27,26,19,16,8, + 4, 16,14,0,8, + 4, 19,26,10,9, + 6, 33,32,14,16,19,9, + 3, 34,35,11, + 6, 35,23,22,20,21,11, + 4, 32,33,31,15, + 3, 21,20,18, +}; +const dReal h85_planes[ h85_numf * 4 ] = { + 0.322183,0.678838,-0.659831,0.24804,0.212159,0.447018,0.869002,0.23257,0.463507,0.691764,-0.553737,0.260563,0.722579,0.66608,-0.18498,0.353129,0.602768,0.50566,0.617235,0.344652,0.991833,-0.112685,-0.0597434,0.382771,0.066237,-0.837367,-0.542613,0.238071,-0.878502,-0.475257,0.0486263,0.359502,-0.88947,0.425933,0.165603,0.302468,-0.613049,-0.207593,-0.762283,0.350725,0.933932,-0.105417,0.341552,0.345658,-0.233951,0.164311,0.958264,0.33061,-0.49733,-0.589429,0.636582,0.294927,0.421977,-0.500122,0.756183,0.397007,-0.124536,-0.983986,-0.127525,0.273149,0.517294,-0.817451,0.253339,0.364409,0.0600487,0.168696,-0.983837,0.354938,-0.433652,-0.152285,-0.888119,0.309417,0.784459,-0.61982,-0.0211391,0.377005,-0.877441,0.462191,-0.128357,0.376465 +}; +// h86 +const int h86_numv = 14; +const int h86_numf = 9; +const dReal h86_volu = 0.108919; +const dReal h86_pos[3] = { 0.238541,0.789776,0.775739 }; +const dReal h86_verts[ h86_numv * 3 ] = { + -0.094981,-0.202353,-0.313843, -0.370325,0.210224,0.224261, -0.076674,-0.173821,-0.355096, 0.281969,0.210224,-0.157785, 0.225385,0.024918,-0.224556, 0.374020,0.210224,0.224261, 0.316487,0.210224,-0.084750, -0.107806,-0.340614,0.224261, 0.201351,-0.281476,0.224261, 0.184090,-0.072562,-0.262496, -0.073553,-0.370157,0.086361, 0.049879,-0.364426,0.224261, -0.132543,-0.112102,-0.351098, -0.293871,0.210224,-0.298371, +}; +const unsigned int h86_faces[] = { + 6, 13,12,0,10,7,1, + 5, 7,11,8,5,1, + 5, 5,6,3,13,1, + 6, 12,13,3,4,9,2, + 6, 9,8,11,10,0,2, + 3, 0,12,2, + 3, 6,4,3, + 5, 6,5,8,9,4, + 3, 10,11,7, +}; +const dReal h86_planes[ h86_numf * 4 ] = { + -0.894954,-0.426518,-0.130919,0.212399,0,0,1,0.224261,0,1,0,0.210224,0.228531,0.267508,-0.936063,0.268372,0.446964,-0.816183,-0.366153,0.237618,-0.602768,-0.50566,-0.617235,0.353289,0.897445,-0.121212,-0.424146,0.294495,0.929286,-0.326334,-0.173016,0.240167,-0.14709,-0.974029,0.172138,0.386228 +}; +// h87 +const int h87_numv = 16; +const int h87_numf = 10; +const dReal h87_volu = 0.089360; +const dReal h87_pos[3] = { 0.798384,0.791714,0.481127 }; +const dReal h87_verts[ h87_numv * 3 ] = { + -0.277873,0.208286,0.136827, -0.253373,-0.199539,-0.004817, 0.201616,0.208286,-0.307196, 0.201616,0.189080,-0.312136, 0.201616,-0.223010,0.205272, 0.201616,0.208286,0.427133, 0.201616,-0.307831,-0.056523, -0.352696,-0.089547,0.003266, -0.060134,0.085556,-0.322787, -0.013117,0.208286,-0.294090, -0.336822,-0.121565,-0.050021, -0.196695,-0.100782,-0.260274, -0.062147,-0.335676,0.018525, 0.034362,-0.347521,-0.076940, -0.334458,0.022980,0.070056, -0.243356,0.208286,0.209862, +}; +const unsigned int h87_faces[] = { + 5, 10,11,13,12,1, + 7, 12,4,5,15,14,7,1, + 3, 7,10,1, + 4, 3,8,9,2, + 5, 9,0,15,5,2, + 5, 5,4,6,3,2, + 5, 6,13,11,8,3, + 4, 12,13,6,4, + 7, 14,0,9,8,11,10,7, + 3, 15,0,14, +}; +const dReal h87_planes[ h87_numf * 4 ] = { + -0.496382,-0.766976,-0.406636,0.28077,-0.398278,-0.419587,0.815673,0.180707,-0.722578,-0.66608,0.18498,0.3151,-0.0590083,0.248661,-0.966792,0.336891,0,1,0,0.208286,1,1.89246e-16,1.50725e-16,0.201616,0.212159,-0.447018,-0.869002,0.229499,0.184883,-0.934913,0.302912,0.307949,-0.777334,0.409459,-0.477594,0.235937,-0.897445,0.121212,0.424146,0.332657 +}; +// h88 +const int h88_numv = 26; +const int h88_numf = 15; +const dReal h88_volu = 0.102785; +const dReal h88_pos[3] = { 0.372790,0.365732,0.656967 }; +const dReal h88_verts[ h88_numv * 3 ] = { + -0.084370,0.059618,0.343033, 0.095722,-0.319244,-0.008232, 0.172221,0.226443,-0.180656, 0.300178,0.031092,-0.053086, 0.259424,-0.225193,0.128495, 0.253773,-0.138025,0.343033, -0.207802,0.053887,0.205134, 0.072899,0.336435,-0.172573, -0.203955,-0.051368,-0.348458, 0.260362,-0.077566,0.343033, 0.038967,-0.171095,-0.223000, 0.088772,0.304416,-0.225861, 0.113761,-0.170244,0.343033, 0.067103,0.142568,0.343033, -0.229230,0.221691,-0.195070, -0.323052,-0.062181,-0.026140, 0.014109,-0.325700,0.021656, -0.261860,-0.129234,-0.214158, -0.017378,-0.313030,0.069951, -0.314197,-0.116814,-0.067215, 0.049841,0.351482,-0.143724, -0.178398,0.173789,-0.348849, -0.210923,0.250223,-0.236324, 0.283040,0.075827,-0.117937, -0.184483,0.196893,-0.325078, -0.167799,0.186994,-0.344427, +}; +const unsigned int h88_faces[] = { + 5, 10,23,3,4,1, + 6, 4,5,12,18,16,1, + 5, 16,17,8,10,1, + 7, 23,10,8,21,25,11,2, + 3, 11,7,2, + 7, 7,20,13,9,3,23,2, + 4, 9,5,4,3, + 5, 9,13,0,12,5, + 6, 15,19,18,12,0,6, + 6, 0,13,20,22,14,6, + 3, 14,15,6, + 6, 11,25,24,22,20,7, + 8, 17,19,15,14,22,24,21,8, + 4, 18,19,17,16, + 3, 24,25,21, +}; +const dReal h88_planes[ h88_numf * 4 ] = { + 0.708232,-0.479648,-0.518021,0.225182,0.20808,-0.904248,0.372879,0.305524,-0.131611,-0.83191,-0.539077,0.257422,0.438192,-0.051293,-0.897417,0.225975,0.722578,0.66608,-0.18498,0.30869,0.727925,0.639055,0.248465,0.225187,0.991673,-0.108076,0.0700326,0.2906,0,-0,1,0.343033,-0.619037,-0.533582,0.576267,0.218095,-0.446964,0.816183,0.366153,0.211972,-0.877503,0.423705,0.224641,0.25126,-0.131611,0.83191,-0.539078,0.36332,-0.933932,0.105417,-0.341552,0.304082,-0.512085,-0.851811,-0.110395,0.267819,-0.443092,0.583496,-0.68059,0.417874 +}; +// h89 +const int h89_numv = 16; +const int h89_numf = 10; +const dReal h89_volu = 0.098811; +const dReal h89_pos[3] = { 0.713605,0.673779,0.814484 }; +const dReal h89_verts[ h89_numv * 3 ] = { + -0.273713,-0.165479,0.185516, -0.080453,-0.385613,0.185516, 0.286395,-0.172812,0.185516, 0.286395,0.326221,0.093776, -0.101044,0.326221,0.185516, 0.286395,0.326221,0.185516, 0.017832,-0.221455,-0.310526, 0.286395,-0.105074,-0.128085, -0.040637,-0.276955,-0.210604, -0.057774,-0.232220,-0.275455, -0.158577,0.326221,-0.123495, -0.267917,0.028388,-0.330091, -0.290974,0.043435,-0.301241, -0.249679,0.140915,-0.263301, -0.168594,-0.081604,-0.338174, 0.022632,-0.217741,-0.314831, +}; +const unsigned int h89_faces[] = { + 6, 8,6,15,7,2,1, + 5, 2,5,4,0,1, + 7, 0,12,11,14,9,8,1, + 4, 7,3,5,2, + 7, 7,15,14,11,13,10,3, + 4, 10,4,5,3, + 5, 10,13,12,0,4, + 4, 9,14,15,6, + 3, 8,9,6, + 3, 12,13,11, +}; +const dReal h89_planes[ h89_numf * 4 ] = { + 0.493234,-0.850287,-0.183662,0.254128,-0,1.12896e-16,1,0.185516,-0.727925,-0.639055,-0.248465,0.258897,1,0,0,0.286395,0.398278,0.419587,-0.815673,0.174452,0,1,0,0.326221,-0.929286,0.326334,0.173016,0.232453,-0.289106,-0.541462,-0.789453,0.3599,-0.131611,-0.831909,-0.539078,0.349281,-0.535431,0.493566,-0.685351,0.38369 +}; + +//Aggregate of all cells. +const int halton_numc = 90; +const int halton_numv[ halton_numc ] = { + h00_numv,h01_numv,h02_numv,h03_numv,h04_numv,h05_numv,h06_numv,h07_numv,h08_numv,h09_numv,h10_numv,h11_numv,h12_numv,h13_numv,h14_numv,h15_numv,h16_numv,h17_numv,h18_numv,h19_numv,h20_numv,h21_numv,h22_numv,h23_numv,h24_numv,h25_numv,h26_numv,h27_numv,h28_numv,h29_numv,h30_numv,h31_numv,h32_numv,h33_numv,h34_numv,h35_numv,h36_numv,h37_numv,h38_numv,h39_numv,h40_numv,h41_numv,h42_numv,h43_numv,h44_numv,h45_numv,h46_numv,h47_numv,h48_numv,h49_numv,h50_numv,h51_numv,h52_numv,h53_numv,h54_numv,h55_numv,h56_numv,h57_numv,h58_numv,h59_numv,h60_numv,h61_numv,h62_numv,h63_numv,h64_numv,h65_numv,h66_numv,h67_numv,h68_numv,h69_numv,h70_numv,h71_numv,h72_numv,h73_numv,h74_numv,h75_numv,h76_numv,h77_numv,h78_numv,h79_numv,h80_numv,h81_numv,h82_numv,h83_numv,h84_numv,h85_numv,h86_numv,h87_numv,h88_numv,h89_numv, +}; +const int halton_numf[ halton_numc ] = { + h00_numf,h01_numf,h02_numf,h03_numf,h04_numf,h05_numf,h06_numf,h07_numf,h08_numf,h09_numf,h10_numf,h11_numf,h12_numf,h13_numf,h14_numf,h15_numf,h16_numf,h17_numf,h18_numf,h19_numf,h20_numf,h21_numf,h22_numf,h23_numf,h24_numf,h25_numf,h26_numf,h27_numf,h28_numf,h29_numf,h30_numf,h31_numf,h32_numf,h33_numf,h34_numf,h35_numf,h36_numf,h37_numf,h38_numf,h39_numf,h40_numf,h41_numf,h42_numf,h43_numf,h44_numf,h45_numf,h46_numf,h47_numf,h48_numf,h49_numf,h50_numf,h51_numf,h52_numf,h53_numf,h54_numf,h55_numf,h56_numf,h57_numf,h58_numf,h59_numf,h60_numf,h61_numf,h62_numf,h63_numf,h64_numf,h65_numf,h66_numf,h67_numf,h68_numf,h69_numf,h70_numf,h71_numf,h72_numf,h73_numf,h74_numf,h75_numf,h76_numf,h77_numf,h78_numf,h79_numf,h80_numf,h81_numf,h82_numf,h83_numf,h84_numf,h85_numf,h86_numf,h87_numf,h88_numf,h89_numf, +}; +const dReal halton_volu[ halton_numc ] = { + h00_volu,h01_volu,h02_volu,h03_volu,h04_volu,h05_volu,h06_volu,h07_volu,h08_volu,h09_volu,h10_volu,h11_volu,h12_volu,h13_volu,h14_volu,h15_volu,h16_volu,h17_volu,h18_volu,h19_volu,h20_volu,h21_volu,h22_volu,h23_volu,h24_volu,h25_volu,h26_volu,h27_volu,h28_volu,h29_volu,h30_volu,h31_volu,h32_volu,h33_volu,h34_volu,h35_volu,h36_volu,h37_volu,h38_volu,h39_volu,h40_volu,h41_volu,h42_volu,h43_volu,h44_volu,h45_volu,h46_volu,h47_volu,h48_volu,h49_volu,h50_volu,h51_volu,h52_volu,h53_volu,h54_volu,h55_volu,h56_volu,h57_volu,h58_volu,h59_volu,h60_volu,h61_volu,h62_volu,h63_volu,h64_volu,h65_volu,h66_volu,h67_volu,h68_volu,h69_volu,h70_volu,h71_volu,h72_volu,h73_volu,h74_volu,h75_volu,h76_volu,h77_volu,h78_volu,h79_volu,h80_volu,h81_volu,h82_volu,h83_volu,h84_volu,h85_volu,h86_volu,h87_volu,h88_volu,h89_volu, +}; +const dReal* halton_pos[ halton_numc ] = { + h00_pos,h01_pos,h02_pos,h03_pos,h04_pos,h05_pos,h06_pos,h07_pos,h08_pos,h09_pos,h10_pos,h11_pos,h12_pos,h13_pos,h14_pos,h15_pos,h16_pos,h17_pos,h18_pos,h19_pos,h20_pos,h21_pos,h22_pos,h23_pos,h24_pos,h25_pos,h26_pos,h27_pos,h28_pos,h29_pos,h30_pos,h31_pos,h32_pos,h33_pos,h34_pos,h35_pos,h36_pos,h37_pos,h38_pos,h39_pos,h40_pos,h41_pos,h42_pos,h43_pos,h44_pos,h45_pos,h46_pos,h47_pos,h48_pos,h49_pos,h50_pos,h51_pos,h52_pos,h53_pos,h54_pos,h55_pos,h56_pos,h57_pos,h58_pos,h59_pos,h60_pos,h61_pos,h62_pos,h63_pos,h64_pos,h65_pos,h66_pos,h67_pos,h68_pos,h69_pos,h70_pos,h71_pos,h72_pos,h73_pos,h74_pos,h75_pos,h76_pos,h77_pos,h78_pos,h79_pos,h80_pos,h81_pos,h82_pos,h83_pos,h84_pos,h85_pos,h86_pos,h87_pos,h88_pos,h89_pos, +}; +const dReal* halton_verts[ halton_numc ] = { + h00_verts,h01_verts,h02_verts,h03_verts,h04_verts,h05_verts,h06_verts,h07_verts,h08_verts,h09_verts,h10_verts,h11_verts,h12_verts,h13_verts,h14_verts,h15_verts,h16_verts,h17_verts,h18_verts,h19_verts,h20_verts,h21_verts,h22_verts,h23_verts,h24_verts,h25_verts,h26_verts,h27_verts,h28_verts,h29_verts,h30_verts,h31_verts,h32_verts,h33_verts,h34_verts,h35_verts,h36_verts,h37_verts,h38_verts,h39_verts,h40_verts,h41_verts,h42_verts,h43_verts,h44_verts,h45_verts,h46_verts,h47_verts,h48_verts,h49_verts,h50_verts,h51_verts,h52_verts,h53_verts,h54_verts,h55_verts,h56_verts,h57_verts,h58_verts,h59_verts,h60_verts,h61_verts,h62_verts,h63_verts,h64_verts,h65_verts,h66_verts,h67_verts,h68_verts,h69_verts,h70_verts,h71_verts,h72_verts,h73_verts,h74_verts,h75_verts,h76_verts,h77_verts,h78_verts,h79_verts,h80_verts,h81_verts,h82_verts,h83_verts,h84_verts,h85_verts,h86_verts,h87_verts,h88_verts,h89_verts, +}; +const unsigned int* halton_faces[ halton_numc ] = { + h00_faces,h01_faces,h02_faces,h03_faces,h04_faces,h05_faces,h06_faces,h07_faces,h08_faces,h09_faces,h10_faces,h11_faces,h12_faces,h13_faces,h14_faces,h15_faces,h16_faces,h17_faces,h18_faces,h19_faces,h20_faces,h21_faces,h22_faces,h23_faces,h24_faces,h25_faces,h26_faces,h27_faces,h28_faces,h29_faces,h30_faces,h31_faces,h32_faces,h33_faces,h34_faces,h35_faces,h36_faces,h37_faces,h38_faces,h39_faces,h40_faces,h41_faces,h42_faces,h43_faces,h44_faces,h45_faces,h46_faces,h47_faces,h48_faces,h49_faces,h50_faces,h51_faces,h52_faces,h53_faces,h54_faces,h55_faces,h56_faces,h57_faces,h58_faces,h59_faces,h60_faces,h61_faces,h62_faces,h63_faces,h64_faces,h65_faces,h66_faces,h67_faces,h68_faces,h69_faces,h70_faces,h71_faces,h72_faces,h73_faces,h74_faces,h75_faces,h76_faces,h77_faces,h78_faces,h79_faces,h80_faces,h81_faces,h82_faces,h83_faces,h84_faces,h85_faces,h86_faces,h87_faces,h88_faces,h89_faces, +}; +const dReal* halton_planes[ halton_numc ] = { + h00_planes,h01_planes,h02_planes,h03_planes,h04_planes,h05_planes,h06_planes,h07_planes,h08_planes,h09_planes,h10_planes,h11_planes,h12_planes,h13_planes,h14_planes,h15_planes,h16_planes,h17_planes,h18_planes,h19_planes,h20_planes,h21_planes,h22_planes,h23_planes,h24_planes,h25_planes,h26_planes,h27_planes,h28_planes,h29_planes,h30_planes,h31_planes,h32_planes,h33_planes,h34_planes,h35_planes,h36_planes,h37_planes,h38_planes,h39_planes,h40_planes,h41_planes,h42_planes,h43_planes,h44_planes,h45_planes,h46_planes,h47_planes,h48_planes,h49_planes,h50_planes,h51_planes,h52_planes,h53_planes,h54_planes,h55_planes,h56_planes,h57_planes,h58_planes,h59_planes,h60_planes,h61_planes,h62_planes,h63_planes,h64_planes,h65_planes,h66_planes,h67_planes,h68_planes,h69_planes,h70_planes,h71_planes,h72_planes,h73_planes,h74_planes,h75_planes,h76_planes,h77_planes,h78_planes,h79_planes,h80_planes,h81_planes,h82_planes,h83_planes,h84_planes,h85_planes,h86_planes,h87_planes,h88_planes,h89_planes, +}; diff --git a/libs/ode-0.16.1/ode/demo/icosahedron_geom.h b/libs/ode-0.16.1/ode/demo/icosahedron_geom.h new file mode 100644 index 0000000..eb0a0ea --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/icosahedron_geom.h @@ -0,0 +1,216 @@ +//<---- Icosahedron ----> +/* + This is a description of a convex icosahedron, to test + the convex collision detection. +*/ +unsigned int Sphere_pointcount = 42; +unsigned int Sphere_planecount = 80; +dReal Sphere_points[126]={ +0.000000,0.000000,-0.300000, +0.217080,-0.157716,-0.134164, +-0.082915,-0.255192,-0.134164, +-0.268327,0.000000,-0.134164, +-0.082915,0.255192,-0.134164, +0.217080,0.157716,-0.134164, +0.082915,-0.255192,0.134164, +-0.217080,-0.157716,0.134164, +-0.217080,0.157716,0.134164, +0.082915,0.255192,0.134164, +0.268327,0.000000,0.134164, +0.000000,0.000000,0.300000, +0.127597,-0.092703,-0.255196, +-0.048737,-0.149999,-0.255196, +0.078861,-0.242703,-0.157721, +0.127597,0.092703,-0.255196, +0.255194,0.000000,-0.157721, +-0.157719,0.000000,-0.255195, +-0.206457,-0.149999,-0.157721, +-0.048737,0.149999,-0.255196, +-0.206457,0.149999,-0.157721, +0.078861,0.242703,-0.157721, +0.285317,0.092704,0.000000, +0.285317,-0.092704,0.000000, +0.176336,-0.242705,0.000000, +0.000000,-0.300000,0.000000, +-0.176336,-0.242705,0.000000, +-0.285317,-0.092704,0.000000, +-0.285317,0.092704,0.000000, +-0.176336,0.242705,0.000000, +0.000000,0.300000,0.000000, +0.176336,0.242705,0.000000, +0.206457,-0.149999,0.157721, +-0.078861,-0.242703,0.157721, +-0.255194,0.000000,0.157721, +-0.078861,0.242703,0.157721, +0.206457,0.149999,0.157721, +0.157719,0.000000,0.255195, +0.048737,-0.149999,0.255196, +-0.127597,-0.092703,0.255196, +-0.127597,0.092703,0.255196, +0.048737,0.149999,0.255196 +}; +unsigned int Sphere_polygons[]={ +3,14,12,1, +3,12,14,13, +3,2,13,14, +3,13,0,12, +3,16,1,12, +3,12,15,16, +3,5,16,15, +3,12,0,15, +3,18,13,2, +3,13,18,17, +3,3,17,18, +3,17,0,13, +3,20,17,3, +3,17,20,19, +3,4,19,20, +3,19,0,17, +3,21,19,4, +3,19,21,15, +3,5,15,21, +3,15,0,19, +3,23,1,16, +3,16,22,23, +3,10,23,22, +3,22,16,5, +3,25,2,14, +3,14,24,25, +3,6,25,24, +3,24,14,1, +3,27,3,18, +3,18,26,27, +3,7,27,26, +3,26,18,2, +3,29,4,20, +3,20,28,29, +3,8,29,28, +3,28,20,3, +3,31,5,21, +3,21,30,31, +3,9,31,30, +3,30,21,4, +3,32,23,10, +3,23,32,24, +3,6,24,32, +3,24,1,23, +3,33,25,6, +3,25,33,26, +3,7,26,33, +3,26,2,25, +3,34,27,7, +3,27,34,28, +3,8,28,34, +3,28,3,27, +3,35,29,8, +3,29,35,30, +3,9,30,35, +3,30,4,29, +3,36,31,9, +3,31,36,22, +3,10,22,36, +3,22,5,31, +3,38,6,32, +3,32,37,38, +3,11,38,37, +3,37,32,10, +3,39,7,33, +3,33,38,39, +3,11,39,38, +3,38,33,6, +3,40,8,34, +3,34,39,40, +3,11,40,39, +3,39,34,7, +3,41,9,35, +3,35,40,41, +3,11,41,40, +3,40,35,8, +3,37,10,36, +3,36,41,37, +3,11,37,41, +3,41,36,9, +}; +dReal Sphere_planes[]={ +0.471317,-0.583121,-0.661687,0.283056, +0.187594,-0.577345,-0.794658,0.280252, +-0.038547,-0.748789,-0.661687,0.283056, +0.102381,-0.315090,-0.943523,0.283057, +0.700228,-0.268049,-0.661688,0.283056, +0.607060,0.000000,-0.794656,0.280252, +0.700228,0.268049,-0.661688,0.283056, +0.331305,0.000000,-0.943524,0.283057, +-0.408939,-0.628443,-0.661686,0.283056, +-0.491119,-0.356821,-0.794657,0.280252, +-0.724044,-0.194735,-0.661694,0.283057, +-0.268034,-0.194737,-0.943523,0.283057, +-0.724044,0.194735,-0.661694,0.283057, +-0.491119,0.356821,-0.794657,0.280252, +-0.408939,0.628443,-0.661686,0.283056, +-0.268034,0.194737,-0.943523,0.283057, +-0.038547,0.748789,-0.661687,0.283056, +0.187594,0.577345,-0.794658,0.280252, +0.471317,0.583121,-0.661687,0.283056, +0.102381,0.315090,-0.943523,0.283057, +0.904981,-0.268049,-0.330393,0.283056, +0.982246,0.000000,-0.187599,0.280252, +0.992077,0.000000,0.125631,0.283057, +0.904981,0.268049,-0.330393,0.283056, +0.024726,-0.943519,-0.330396,0.283056, +0.303531,-0.934171,-0.187598,0.280251, +0.306568,-0.943519,0.125651,0.283056, +0.534590,-0.777851,-0.330395,0.283056, +-0.889698,-0.315092,-0.330386,0.283056, +-0.794656,-0.577348,-0.187595,0.280251, +-0.802607,-0.583125,0.125648,0.283055, +-0.574584,-0.748793,-0.330397,0.283055, +-0.574584,0.748793,-0.330397,0.283055, +-0.794656,0.577348,-0.187595,0.280251, +-0.802607,0.583125,0.125648,0.283055, +-0.889698,0.315092,-0.330386,0.283056, +0.534590,0.777851,-0.330395,0.283056, +0.303531,0.934171,-0.187598,0.280251, +0.306568,0.943519,0.125651,0.283056, +0.024726,0.943519,-0.330396,0.283056, +0.889698,-0.315092,0.330386,0.283056, +0.794656,-0.577348,0.187595,0.280251, +0.574584,-0.748793,0.330397,0.283055, +0.802607,-0.583125,-0.125648,0.283055, +-0.024726,-0.943519,0.330396,0.283055, +-0.303531,-0.934171,0.187598,0.280251, +-0.534590,-0.777851,0.330395,0.283056, +-0.306568,-0.943519,-0.125651,0.283056, +-0.904981,-0.268049,0.330393,0.283056, +-0.982246,0.000000,0.187599,0.280252, +-0.904981,0.268049,0.330393,0.283056, +-0.992077,0.000000,-0.125631,0.283057, +-0.534590,0.777851,0.330395,0.283056, +-0.303531,0.934171,0.187598,0.280251, +-0.024726,0.943519,0.330396,0.283055, +-0.306568,0.943519,-0.125651,0.283056, +0.574584,0.748793,0.330397,0.283055, +0.794656,0.577348,0.187595,0.280251, +0.889698,0.315092,0.330386,0.283056, +0.802607,0.583125,-0.125648,0.283055, +0.408939,-0.628443,0.661686,0.283056, +0.491119,-0.356821,0.794657,0.280252, +0.268034,-0.194737,0.943523,0.283057, +0.724044,-0.194735,0.661694,0.283057, +-0.471317,-0.583121,0.661687,0.283056, +-0.187594,-0.577345,0.794658,0.280252, +-0.102381,-0.315090,0.943523,0.283057, +0.038547,-0.748789,0.661687,0.283056, +-0.700228,0.268049,0.661688,0.283056, +-0.607060,0.000000,0.794656,0.280252, +-0.331305,0.000000,0.943524,0.283057, +-0.700228,-0.268049,0.661688,0.283056, +0.038547,0.748789,0.661687,0.283056, +-0.187594,0.577345,0.794658,0.280252, +-0.102381,0.315090,0.943523,0.283057, +-0.471317,0.583121,0.661687,0.283056, +0.724044,0.194735,0.661694,0.283057, +0.491119,0.356821,0.794657,0.280252, +0.268034,0.194737,0.943523,0.283057, +0.408939,0.628443,0.661686,0.283056, +}; + diff --git a/libs/ode-0.16.1/ode/demo/texturepath.h b/libs/ode-0.16.1/ode/demo/texturepath.h new file mode 100644 index 0000000..5815138 --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/texturepath.h @@ -0,0 +1,26 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef DRAWSTUFF_TEXTURE_PATH +#define DRAWSTUFF_TEXTURE_PATH "../../drawstuff/textures" +#endif + diff --git a/libs/ode-0.16.1/ode/demo/world_geom3.h b/libs/ode-0.16.1/ode/demo/world_geom3.h new file mode 100644 index 0000000..27cd69e --- /dev/null +++ b/libs/ode-0.16.1/ode/demo/world_geom3.h @@ -0,0 +1,9 @@ +// mesh for a world model, to be used with test_cyl.cpp + +static float world_vertices[] = {10.000000f,-10.000000f,1.000000f,-10.000000f,-10.000000f,1.000000f,-10.000000f,-10.000000f,-1.000000f,-10.000000f,-10.000000f,-1.000000f,10.000000f,-10.000000f,-1.000000f,10.000000f,-10.000000f,1.000000f,10.000000f,10.000000f,1.000000f,10.000000f,-10.000000f,1.000000f,10.000000f,-10.000000f,-1.000000f,10.000000f,-10.000000f,-1.000000f,10.000000f,10.000000f,-1.000000f,10.000000f,10.000000f,1.000000f,10.000000f,10.000000f,-1.000000f,10.000000f,-10.000000f,-1.000000f,-10.000000f,-10.000000f,-1.000000f,-10.000000f,-10.000000f,-1.000000f,-10.000000f,10.000000f,-1.000000f,10.000000f,10.000000f,-1.000000f,0.000000f,9.000000f,-0.000000f,0.000000f,-9.000000f,0.000000f,9.000000f,-9.000000f,0.000000f,0.000000f,9.000000f,-0.000000f,9.000000f,-9.000000f,0.000000f,9.000000f,9.000000f,-0.000000f,10.000000f,10.000000f,-1.000000f,-10.000000f,10.000000f,-1.000000f,-10.000000f,10.000000f,1.000000f,10.000000f,10.000000f,-1.000000f,-10.000000f,10.000000f,1.000000f,10.000000f,10.000000f,1.000000f,-10.000000f,-10.000000f,-1.000000f,-10.000000f,-10.000000f,1.000000f,-10.000000f,10.000000f,1.000000f,-10.000000f,10.000000f,1.000000f,-10.000000f,10.000000f,-1.000000f,-10.000000f,-10.000000f,-1.000000f,9.000000f,-9.000000f,1.000000f,-9.000000f,-9.000000f,1.000000f,10.000000f,-10.000000f,1.000000f,-9.000000f,-9.000000f,1.000000f,-10.000000f,-10.000000f,1.000000f,10.000000f,-10.000000f,1.000000f,9.000000f,9.000000f,1.000000f,9.000000f,-9.000000f,1.000000f,10.000000f,-10.000000f,1.000000f,10.000000f,-10.000000f,1.000000f,10.000000f,10.000000f,1.000000f,9.000000f,9.000000f,1.000000f,-9.000000f,9.000000f,1.000000f,9.000000f,9.000000f,1.000000f,10.000000f,10.000000f,1.000000f,10.000000f,10.000000f,1.000000f,-10.000000f,10.000000f,1.000000f,-9.000000f,9.000000f,1.000000f,-9.000000f,9.000000f,1.000000f,-10.000000f,10.000000f,1.000000f,-9.000000f,-9.000000f,1.000000f,-10.000000f,10.000000f,1.000000f,-10.000000f,-10.000000f,1.000000f,-9.000000f,-9.000000f,1.000000f,0.000000f,-9.000000f,0.000000f,-9.000000f,-9.000000f,0.000000f,-9.000000f,-9.000000f,1.000000f,0.000000f,-9.000000f,0.000000f,-9.000000f,-9.000000f,1.000000f,9.000000f,-9.000000f,1.000000f,0.000000f,-9.000000f,0.000000f,9.000000f,-9.000000f,1.000000f,9.000000f,-9.000000f,0.000000f,9.000000f,-9.000000f,0.000000f,9.000000f,-9.000000f,1.000000f,9.000000f,9.000000f,1.000000f,9.000000f,9.000000f,1.000000f,9.000000f,9.000000f,-0.000000f,9.000000f,-9.000000f,0.000000f,0.000000f,9.000000f,-0.000000f,9.000000f,9.000000f,-0.000000f,9.000000f,9.000000f,1.000000f,0.000000f,9.000000f,-0.000000f,9.000000f,9.000000f,1.000000f,-9.000000f,9.000000f,1.000000f,0.000000f,9.000000f,-0.000000f,-9.000000f,9.000000f,1.000000f,-9.000000f,9.000000f,-0.000000f,-9.000000f,9.000000f,1.000000f,-9.000000f,-9.000000f,1.000000f,-9.000000f,-9.000000f,0.000000f,-9.000000f,-9.000000f,0.000000f,-9.000000f,9.000000f,-0.000000f,-9.000000f,9.000000f,1.000000f,-2.997000f,-1.748874f,0.000000f,-2.997000f,-2.001000f,0.000000f,0.000000f,-9.000000f,0.000000f,-2.997000f,-1.748874f,0.000000f,0.000000f,-9.000000f,0.000000f,-2.997000f,1.748874f,-0.000000f,-2.997000f,-2.001000f,0.000000f,-2.997000f,-6.003000f,0.002697f,0.000000f,-9.000000f,0.000000f,0.000000f,9.000000f,-0.000000f,-2.997000f,2.001000f,-0.000000f,-2.997000f,1.748874f,-0.000000f,0.000000f,9.000000f,-0.000000f,-2.997000f,1.748874f,-0.000000f,0.000000f,-9.000000f,0.000000f,-2.997000f,2.001000f,-0.000000f,0.000000f,9.000000f,-0.000000f,-2.997000f,6.003000f,0.002697f,-6.003000f,6.003000f,0.002697f,-2.997000f,6.003000f,0.002697f,0.000000f,9.000000f,-0.000000f,0.000000f,9.000000f,-0.000000f,-9.000000f,9.000000f,-0.000000f,-6.003000f,6.003000f,0.002697f,-6.003000f,1.748874f,-0.000000f,-9.000000f,-9.000000f,0.000000f,-6.003000f,-1.748874f,0.000000f,-6.003000f,2.001000f,-0.000000f,-6.003000f,6.003000f,0.002697f,-9.000000f,9.000000f,-0.000000f,-9.000000f,9.000000f,-0.000000f,-6.003000f,1.748874f,-0.000000f,-6.003000f,2.001000f,-0.000000f,-9.000000f,9.000000f,-0.000000f,-9.000000f,-9.000000f,0.000000f,-6.003000f,1.748874f,-0.000000f,-9.000000f,-9.000000f,0.000000f,-6.003000f,-6.003000f,0.002697f,-6.003000f,-2.001000f,0.000000f,-9.000000f,-9.000000f,0.000000f,-6.003000f,-2.001000f,0.000000f,-6.003000f,-1.748874f,0.000000f,-6.003000f,-6.003000f,0.002697f,-9.000000f,-9.000000f,0.000000f,0.000000f,-9.000000f,0.000000f,-6.003000f,-6.003000f,0.002697f,0.000000f,-9.000000f,0.000000f,-2.997000f,-6.003000f,0.002697f,-2.997000f,1.748874f,1.237951f,-2.997000f,1.748874f,-0.000000f,-2.997000f,2.001000f,-0.000000f,-2.997000f,1.748874f,1.237951f,-2.997000f,2.001000f,-0.000000f,-2.997000f,2.001000f,1.515748f,-6.003000f,-2.001000f,1.515748f,-6.003000f,-6.003000f,0.002697f,-2.997000f,-6.003000f,0.002697f,-6.003000f,-2.001000f,1.515748f,-2.997000f,-6.003000f,0.002697f,-2.997000f,-2.001000f,1.515748f,-2.997000f,2.001000f,1.515748f,-2.997000f,6.003000f,0.002697f,-6.003000f,6.003000f,0.002697f,-6.003000f,6.003000f,0.002697f,-6.003000f,2.001000f,1.515748f,-2.997000f,2.001000f,1.515748f,-6.003000f,-2.001000f,0.000000f,-6.003000f,-6.003000f,0.002697f,-6.003000f,-2.001000f,1.515748f,-6.003000f,2.001000f,1.515748f,-6.003000f,6.003000f,0.002697f,-6.003000f,2.001000f,-0.000000f,-2.997000f,-2.001000f,1.515748f,-2.997000f,-6.003000f,0.002697f,-2.997000f,-2.001000f,0.000000f,-2.997000f,2.001000f,-0.000000f,-2.997000f,6.003000f,0.002697f,-2.997000f,2.001000f,1.515748f,-2.997000f,-2.001000f,1.515748f,-2.997000f,2.001000f,1.515748f,-6.003000f,2.001000f,1.515748f,-6.003000f,2.001000f,1.515748f,-6.003000f,-2.001000f,1.515748f,-2.997000f,-2.001000f,1.515748f,-2.997000f,-1.748874f,1.237951f,-2.997000f,1.748874f,1.237951f,-2.997000f,2.001000f,1.515748f,-2.997000f,-1.748874f,1.237951f,-2.997000f,2.001000f,1.515748f,-2.997000f,-2.001000f,1.515748f,-6.003000f,-1.748874f,1.237951f,-6.003000f,-1.748874f,0.000000f,-6.003000f,-2.001000f,0.000000f,-6.003000f,-1.748874f,1.237951f,-6.003000f,-2.001000f,0.000000f,-6.003000f,-2.001000f,1.515748f,-2.997000f,-2.001000f,1.515748f,-2.997000f,-2.001000f,0.000000f,-2.997000f,-1.748874f,1.237951f,-2.997000f,-2.001000f,0.000000f,-2.997000f,-1.748874f,0.000000f,-2.997000f,-1.748874f,1.237951f,-6.003000f,1.748874f,1.237951f,-6.003000f,2.001000f,1.515748f,-6.003000f,2.001000f,-0.000000f,-6.003000f,1.748874f,1.237951f,-6.003000f,2.001000f,-0.000000f,-6.003000f,1.748874f,-0.000000f,-6.003000f,1.748874f,1.237951f,-6.003000f,-1.748874f,1.237951f,-6.003000f,-2.001000f,1.515748f,-6.003000f,1.748874f,1.237951f,-6.003000f,-2.001000f,1.515748f,-6.003000f,2.001000f,1.515748f,-6.003000f,1.748874f,1.237951f,-6.003000f,1.748874f,-0.000000f,-2.997000f,1.748874f,1.237951f,-6.003000f,1.748874f,-0.000000f,-2.997000f,1.748874f,-0.000000f,-2.997000f,1.748874f,1.237951f,-6.003000f,1.748874f,-0.000000f,-6.003000f,-1.748874f,0.000000f,-2.997000f,-1.748874f,0.000000f,-6.003000f,1.748874f,-0.000000f,-2.997000f,-1.748874f,0.000000f,-2.997000f,1.748874f,-0.000000f,-6.003000f,-1.748874f,0.000000f,-6.003000f,-1.748874f,1.237951f,-2.997000f,-1.748874f,1.237951f,-2.997000f,-1.748874f,1.237951f,-2.997000f,-1.748874f,0.000000f,-6.003000f,-1.748874f,0.000000f,-6.003000f,-1.748874f,1.237951f,-6.003000f,1.748874f,1.237951f,-2.997000f,-1.748874f,1.237951f,-6.003000f,1.748874f,1.237951f,-2.997000f,1.748874f,1.237951f,-2.997000f,-1.748874f,1.237951f}; + +static float world_normals[] = {0.000000f,-1.000000f,0.000000f,-0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,-0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000225f,0.000161f,1.000000f,0.000225f,-0.000161f,1.000000f,0.000000f,0.000000f,1.000000f,0.000225f,0.000161f,1.000000f,0.000000f,0.000000f,1.000000f,-0.000000f,0.000000f,1.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,-0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,-0.000000f,-1.000000f,0.000000f,0.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,-0.000000f,-1.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,-0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,-0.000000f,0.000000f,1.000000f,0.000787f,0.000337f,1.000000f,0.000225f,-0.000161f,1.000000f,-0.000000f,0.000000f,1.000000f,0.000225f,-0.000161f,1.000000f,0.000000f,0.000000f,1.000000f,0.000787f,0.000337f,1.000000f,0.000400f,-0.179805f,0.983702f,0.000225f,-0.000161f,1.000000f,0.000225f,0.000161f,1.000000f,0.000787f,-0.000337f,1.000000f,0.000000f,0.000000f,1.000000f,0.000225f,0.000161f,1.000000f,0.000000f,0.000000f,1.000000f,0.000225f,-0.000161f,1.000000f,0.000787f,-0.000337f,1.000000f,0.000225f,0.000161f,1.000000f,0.000532f,0.119686f,0.992812f,-0.000320f,0.143927f,0.989588f,0.000532f,0.119686f,0.992812f,0.000225f,0.000161f,1.000000f,0.000225f,0.000161f,1.000000f,-0.000393f,0.000056f,1.000000f,-0.000320f,0.143927f,0.989588f,-0.000000f,0.000000f,1.000000f,-0.000315f,-0.000045f,1.000000f,0.000000f,0.000000f,1.000000f,-0.000787f,-0.000337f,1.000000f,-0.000320f,0.143927f,0.989588f,-0.000393f,0.000056f,1.000000f,-0.000393f,0.000056f,1.000000f,-0.000000f,0.000000f,1.000000f,-0.000787f,-0.000337f,1.000000f,-0.000393f,0.000056f,1.000000f,-0.000315f,-0.000045f,1.000000f,-0.000000f,0.000000f,1.000000f,-0.000315f,-0.000045f,1.000000f,-0.000398f,-0.089784f,0.995961f,-0.000787f,0.000337f,1.000000f,-0.000315f,-0.000045f,1.000000f,-0.000787f,0.000337f,1.000000f,0.000000f,0.000000f,1.000000f,-0.000398f,-0.089784f,0.995961f,-0.000315f,-0.000045f,1.000000f,0.000225f,-0.000161f,1.000000f,-0.000398f,-0.089784f,0.995961f,0.000225f,-0.000161f,1.000000f,0.000400f,-0.179805f,0.983702f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,0.000000f,-0.239222f,0.970965f,-0.000398f,-0.089784f,0.995961f,0.000400f,-0.179805f,0.983702f,0.000000f,-0.239222f,0.970965f,0.000400f,-0.179805f,0.983702f,0.000000f,-0.119611f,0.992821f,0.000000f,0.239222f,0.970965f,0.000532f,0.119686f,0.992812f,-0.000320f,0.143927f,0.989588f,-0.000320f,0.143927f,0.989588f,0.000000f,0.119611f,0.992821f,0.000000f,0.239222f,0.970965f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,0.000000f,-0.119611f,0.992821f,0.000000f,0.239222f,0.970965f,0.000000f,0.119611f,0.992821f,0.000000f,0.119611f,0.992821f,0.000000f,-0.239222f,0.970965f,0.000000f,-0.119611f,0.992821f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,-0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,-0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,-0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,-0.000000f,0.000000f,1.000000f,-0.000000f,0.000000f,1.000000f,-0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,1.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f}; + + +static dTriIndex world_indices[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227}; + diff --git a/libs/ode-0.16.1/ode/doc/Doxyfile.in b/libs/ode-0.16.1/ode/doc/Doxyfile.in new file mode 100644 index 0000000..bfb9412 --- /dev/null +++ b/libs/ode-0.16.1/ode/doc/Doxyfile.in @@ -0,0 +1,2331 @@ +# Doxyfile 1.8.5 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all text +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv +# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv +# for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = ODE + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = @ODE_VERSION@ + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify an logo or icon that is included in +# the documentation. The maximum height of the logo should not exceed 55 pixels +# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo +# to the output directory. + +PROJECT_LOGO = @top_srcdir@/web/ODElogo.png + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese- +# Traditional, Croatian, Czech, Danish, Dutch, English, Esperanto, Farsi, +# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en, +# Korean, Korean-en, Latvian, Norwegian, Macedonian, Persian, Polish, +# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, +# Turkish, Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a +# new page for each member. If set to NO, the documentation of a member will be +# part of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. +# +# Note For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by by putting a % sign in front of the word +# or globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO these classes will be included in the various overviews. This option has +# no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO these declarations will be +# included in the documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO the members will appear in declaration order. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the +# todo list. This list is created by putting \todo commands in the +# documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the +# test list. This list is created by putting \test commands in the +# documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if <section_label> ... \endif and \cond <section_label> +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES the list +# will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. Do not use file names with spaces, bibtex cannot handle them. See +# also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO doxygen will only warn about wrong or incomplete parameter +# documentation, but not about the absence of documentation. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. +# Note: If this tag is empty the current directory is searched. + +INPUT = @top_srcdir@/include/ode @top_builddir@/include/ode + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: http://www.gnu.org/software/libiconv) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank the +# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, +# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, +# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, +# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, +# *.qsf, *.as and *.js. + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.idl \ + *.ddl \ + *.odl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.cs \ + *.d \ + *.php \ + *.php4 \ + *.php5 \ + *.phtml \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.py \ + *.f90 \ + *.f \ + *.for \ + *.tcl \ + *.vhd \ + *.vhdl \ + *.ucf \ + *.qsf \ + *.as \ + *.js + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = ODE_API + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# <filter> <input-file> +# +# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER ) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# function all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES, then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see http://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = d + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user- +# defined cascading style sheet that is included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefor more robust against future updates. +# Doxygen will copy the style sheet file to the output directory. For an example +# see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the stylesheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# http://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 243 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 187 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 92 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to NO can help when comparing the output of multiple runs. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: http://developer.apple.com/tools/xcode/), introduced with +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler ( hhc.exe). If non-empty +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated ( +# YES) or that it should be included in the master .chm file ( NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated ( +# YES) or a normal table of contents ( NO) in the .chm file. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- +# folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = YES + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# http://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using prerendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = YES + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = NativeMML + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from http://www.mathjax.org before deployment. +# The default value is: http://cdn.mathjax.org/mathjax/latest. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use <access key> + S +# (what the <access key> is depends on the OS and browser, but it is typically +# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down +# key> to jump into the search results window, the results can be navigated +# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel +# the search. The filter options can be selected when the cursor is inside the +# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys> +# to select a filter and <Enter> or <escape> to activate or cancel the filter +# option. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a web server instead of a web client using Javascript. There +# are two flavours of web server based searching depending on the +# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for +# searching and an index file used by the script. When EXTERNAL_SEARCH is +# enabled the indexing and searching needs to be provided by external tools. See +# the section "External Indexing and Searching" for details. +# The default value is: NO. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SERVER_BASED_SEARCH = NO + +# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP +# script for searching. Instead the search results are written to an XML file +# which needs to be processed by an external indexer. Doxygen will invoke an +# external search engine pointed to by the SEARCHENGINE_URL option to obtain the +# search results. +# +# Doxygen ships with an example indexer ( doxyindexer) and search engine +# (doxysearch.cgi) which are based on the open source search engine library +# Xapian (see: http://xapian.org/). +# +# See the section "External Indexing and Searching" for details. +# The default value is: NO. +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTERNAL_SEARCH = NO + +# The SEARCHENGINE_URL should point to a search engine hosted by a web server +# which will return the search results when EXTERNAL_SEARCH is enabled. +# +# Doxygen ships with an example indexer ( doxyindexer) and search engine +# (doxysearch.cgi) which are based on the open source search engine library +# Xapian (see: http://xapian.org/). See the section "External Indexing and +# Searching" for details. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SEARCHENGINE_URL = + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed +# search data is written to a file for indexing by an external tool. With the +# SEARCHDATA_FILE tag the name of this file can be specified. +# The default file is: searchdata.xml. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SEARCHDATA_FILE = searchdata.xml + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the +# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is +# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple +# projects and redirect the results back to the right project. +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTERNAL_SEARCH_ID = + +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen +# projects other than the one defined by this configuration file, but that are +# all added to the same external search index. Each project needs to have a +# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of +# to a relative location where the documentation can be found. The format is: +# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTRA_SEARCH_MAPPINGS = + +#--------------------------------------------------------------------------- +# Configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output. +# The default value is: YES. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: latex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. +# +# Note that when enabling USE_PDFLATEX this option is only used for generating +# bitmaps for formulas in the HTML output, but not in the Makefile that is +# written to the output directory. +# The default file is: latex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate +# index for LaTeX. +# The default file is: makeindex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX +# documents. This may be useful for small projects and may help to save some +# trees in general. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used by the +# printer. +# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x +# 14 inches) and executive (7.25 x 10.5 inches). +# The default value is: a4. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names +# that should be included in the LaTeX output. To get the times font for +# instance you can specify +# EXTRA_PACKAGES=times +# If left blank no extra packages will be included. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the +# generated LaTeX document. The header should contain everything until the first +# chapter. If it is left blank doxygen will generate a standard header. See +# section "Doxygen usage" for information on how to let doxygen write the +# default header to a separate file. +# +# Note: Only use a user-defined header if you know what you are doing! The +# following commands have a special meaning inside the header: $title, +# $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will +# replace them by respectively the title of the page, the current date and time, +# only the current date, the version number of doxygen, the project name (see +# PROJECT_NAME), or the project number (see PROJECT_NUMBER). +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the +# generated LaTeX document. The footer should contain everything after the last +# chapter. If it is left blank doxygen will generate a standard footer. +# +# Note: Only use a user-defined footer if you know what you are doing! +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_FOOTER = + +# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the LATEX_OUTPUT output +# directory. Note that the files will be copied as-is; there are no commands or +# markers available. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EXTRA_FILES = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is +# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will +# contain links (just like the HTML output) instead of page references. This +# makes the output suitable for online browsing using a PDF viewer. +# The default value is: YES. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +PDF_HYPERLINKS = YES + +# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate +# the PDF file directly from the LaTeX files. Set this option to YES to get a +# higher quality PDF documentation. +# The default value is: YES. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode +# command to the generated LaTeX files. This will instruct LaTeX to keep running +# if errors occur, instead of asking the user for help. This option is also used +# when generating formulas in HTML. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_BATCHMODE = NO + +# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the +# index chapters (such as File Index, Compound Index, etc.) in the output. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_HIDE_INDICES = NO + +# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source +# code with syntax highlighting in the LaTeX output. +# +# Note that which sources are shown also depends on other settings such as +# SOURCE_BROWSER. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. See +# http://en.wikipedia.org/wiki/BibTeX and \cite for more info. +# The default value is: plain. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# Configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The +# RTF output is optimized for Word 97 and may not look too pretty with other RTF +# readers/editors. +# The default value is: NO. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: rtf. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF +# documents. This may be useful for small projects and may help to save some +# trees in general. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will +# contain hyperlink fields. The RTF file will contain links (just like the HTML +# output) instead of page references. This makes the output suitable for online +# browsing using Word or some other Word compatible readers that support those +# fields. +# +# Note: WordPad (write) and others do not support links. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's config +# file, i.e. a series of assignments. You only have to provide replacements, +# missing definitions are set to their default value. +# +# See also section "Doxygen usage" for information on how to generate the +# default style sheet that doxygen normally uses. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an RTF document. Syntax is +# similar to doxygen's config file. A template extensions file can be generated +# using doxygen -e rtf extensionFile. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for +# classes and files. +# The default value is: NO. + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. A directory man3 will be created inside the directory specified by +# MAN_OUTPUT. +# The default directory is: man. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to the generated +# man pages. In case the manual section does not start with a number, the number +# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is +# optional. +# The default value is: .3. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it +# will generate one additional man file for each entity documented in the real +# man page(s). These additional files only source the real man page, but without +# them the man command would be unable to find the correct page. +# The default value is: NO. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that +# captures the structure of the code including all documentation. +# The default value is: NO. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: xml. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a +# validating XML parser to check the syntax of the XML files. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify a XML DTD, which can be used by a +# validating XML parser to check the syntax of the XML files. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program +# listings (including syntax highlighting and cross-referencing information) to +# the XML output. Note that enabling this will significantly increase the size +# of the XML output. +# The default value is: YES. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- + +# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files +# that can be used to generate PDF. +# The default value is: NO. + +GENERATE_DOCBOOK = NO + +# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in +# front of it. +# The default directory is: docbook. +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. + +DOCBOOK_OUTPUT = docbook + +#--------------------------------------------------------------------------- +# Configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen +# Definitions (see http://autogen.sf.net) file that captures the structure of +# the code including all documentation. Note that this feature is still +# experimental and incomplete at the moment. +# The default value is: NO. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module +# file that captures the structure of the code including all documentation. +# +# Note that this feature is still experimental and incomplete at the moment. +# The default value is: NO. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary +# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI +# output from the Perl module output. +# The default value is: NO. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely +# formatted so it can be parsed by a human reader. This is useful if you want to +# understand what is going on. On the other hand, if this tag is set to NO the +# size of the Perl module output will be much smaller and Perl will parse it +# just the same. +# The default value is: YES. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file are +# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful +# so different doxyrules.make files included by the same Makefile don't +# overwrite each other's variables. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all +# C-preprocessor directives found in the sources and include files. +# The default value is: YES. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names +# in the source code. If set to NO only conditional compilation will be +# performed. Macro expansion can be done in a controlled way by setting +# EXPAND_ONLY_PREDEF to YES. +# The default value is: NO. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then +# the macro expansion is limited to the macros specified with the PREDEFINED and +# EXPAND_AS_DEFINED tags. +# The default value is: NO. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +EXPAND_ONLY_PREDEF = YES + +# If the SEARCH_INCLUDES tag is set to YES the includes files in the +# INCLUDE_PATH will be searched if a #include is found. +# The default value is: YES. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by the +# preprocessor. +# This tag requires that the tag SEARCH_INCLUDES is set to YES. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will be +# used. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that are +# defined before the preprocessor is started (similar to the -D option of e.g. +# gcc). The argument of the tag is a list of macros of the form: name or +# name=definition (no spaces). If the definition and the "=" are omitted, "=1" +# is assumed. To prevent a macro definition from being undefined via #undef or +# recursively expanded use the := operator instead of the = operator. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +PREDEFINED = ODE_API= + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this +# tag can be used to specify a list of macro names that should be expanded. The +# macro definition that is found in the sources will be used. Use the PREDEFINED +# tag if you want to use a different macro definition that overrules the +# definition found in the source code. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will +# remove all refrences to function-like macros that are alone on a line, have an +# all uppercase name, and do not end with a semicolon. Such function macros are +# typically used for boiler-plate code, and will confuse the parser if not +# removed. +# The default value is: YES. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES tag can be used to specify one or more tag files. For each tag +# file the location of the external documentation should be added. The format of +# a tag file without this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where loc1 and loc2 can be relative or absolute paths or URLs. See the +# section "Linking to external documentation" for more information about the use +# of tag files. +# Note: Each tag file must have an unique name (where the name does NOT include +# the path). If a tag file is not located in the directory in which doxygen is +# run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create a +# tag file that is based on the input files it reads. See section "Linking to +# external documentation" for more information about the usage of tag files. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external class will be listed in the +# class index. If set to NO only the inherited external classes will be listed. +# The default value is: NO. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in +# the modules index. If set to NO, only the current project's groups will be +# listed. +# The default value is: YES. + +EXTERNAL_GROUPS = YES + +# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in +# the related pages index. If set to NO, only the current project's pages will +# be listed. +# The default value is: YES. + +EXTERNAL_PAGES = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of 'which perl'). +# The default file (with absolute path) is: /usr/bin/perl. + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram +# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to +# NO turns the diagrams off. Note that this option also works with HAVE_DOT +# disabled, but it is recommended to install and use dot, since it yields more +# powerful graphs. +# The default value is: YES. + +CLASS_DIAGRAMS = NO + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see: +# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide inheritance +# and usage relations if the target is undocumented or is not a class. +# The default value is: YES. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz (see: +# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent +# Bell Labs. The other options in this section have no effect if this option is +# set to NO +# The default value is: NO. + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed +# to run in parallel. When set to 0 doxygen will base this on the number of +# processors available in the system. You can set it explicitly to a value +# larger than 0 to get control over the balance between CPU load and processing +# speed. +# Minimum value: 0, maximum value: 32, default value: 0. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_NUM_THREADS = 0 + +# When you want a differently looking font n the dot files that doxygen +# generates you can specify the font name using DOT_FONTNAME. You need to make +# sure dot is able to find the font, which can be done by putting it in a +# standard location or by setting the DOTFONTPATH environment variable or by +# setting DOT_FONTPATH to the directory containing the font. +# The default value is: Helvetica. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of +# dot graphs. +# Minimum value: 4, maximum value: 24, default value: 10. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the default font as specified with +# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set +# the path where dot can find it using this tag. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTPATH = + +# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for +# each documented class showing the direct and indirect inheritance relations. +# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a +# graph for each documented class showing the direct and indirect implementation +# dependencies (inheritance, containment, and class references variables) of the +# class with other documented classes. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +COLLABORATION_GRAPH = NO + +# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for +# groups, showing the direct groups dependencies. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +UML_LOOK = NO + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside the +# class node. If there are many fields or methods and many nodes the graph may +# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the +# number of items for each type to make the size more manageable. Set this to 0 +# for no limit. Note that the threshold may be exceeded by 50% before the limit +# is enforced. So when you set the threshold to 10, up to 15 fields may appear, +# but if the number exceeds 15, the total amount of fields shown is limited to +# 10. +# Minimum value: 0, maximum value: 100, default value: 10. +# This tag requires that the tag HAVE_DOT is set to YES. + +UML_LIMIT_NUM_FIELDS = 10 + +# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and +# collaboration graphs will show the relations between templates and their +# instances. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +TEMPLATE_RELATIONS = NO + +# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to +# YES then doxygen will generate a graph for each documented file showing the +# direct and indirect include dependencies of the file with other documented +# files. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +INCLUDE_GRAPH = NO + +# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are +# set to YES then doxygen will generate a graph for each documented file showing +# the direct and indirect include dependencies of the file with other documented +# files. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +INCLUDED_BY_GRAPH = NO + +# If the CALL_GRAPH tag is set to YES then doxygen will generate a call +# dependency graph for every global function or class method. +# +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller +# dependency graph for every global function or class method. +# +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical +# hierarchy of all classes instead of a textual one. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GRAPHICAL_HIERARCHY = NO + +# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the +# dependencies a directory has on other directories in a graphical way. The +# dependency relations are determined by the #include relations between the +# files in the directories. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. +# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order +# to make the SVG files visible in IE 9+ (other browsers do not have this +# requirement). +# Possible values are: png, jpg, gif and svg. +# The default value is: png. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# +# Note that this requires a modern browser other than Internet Explorer. Tested +# and working are Firefox, Chrome, Safari, and Opera. +# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make +# the SVG files visible. Older versions of IE do not have SVG support. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +INTERACTIVE_SVG = NO + +# The DOT_PATH tag can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the \dotfile +# command). +# This tag requires that the tag HAVE_DOT is set to YES. + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the \mscfile +# command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes +# that will be shown in the graph. If the number of nodes in a graph becomes +# larger than this value, doxygen will truncate the graph, which is visualized +# by representing a node as a red box. Note that doxygen if the number of direct +# children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that +# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. +# Minimum value: 0, maximum value: 10000, default value: 50. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs +# generated by dot. A depth value of 3 means that only nodes reachable from the +# root by following a path via at most 3 edges will be shown. Nodes that lay +# further from the root node will be omitted. Note that setting this option to 1 +# or 2 may greatly reduce the computation time needed for large code bases. Also +# note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. +# Minimum value: 0, maximum value: 1000, default value: 0. +# This tag requires that the tag HAVE_DOT is set to YES. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not seem +# to support this out of the box. +# +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) support +# this, this feature is disabled by default. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page +# explaining the meaning of the various boxes and arrows in the dot generated +# graphs. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot +# files that are used to generate the various graphs. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_CLEANUP = YES diff --git a/libs/ode-0.16.1/ode/doc/Makefile.am b/libs/ode-0.16.1/ode/doc/Makefile.am new file mode 100644 index 0000000..a7a006e --- /dev/null +++ b/libs/ode-0.16.1/ode/doc/Makefile.am @@ -0,0 +1,11 @@ +EXTRA_DIST = Doxyfile.in main.dox pix + +if HAVE_DOXYGEN + +mostlyclean-local: + rm -rf html + +html-local: Doxyfile + $(DOXYGEN) Doxyfile + +endif diff --git a/libs/ode-0.16.1/ode/doc/Makefile.in b/libs/ode-0.16.1/ode/doc/Makefile.in new file mode 100644 index 0000000..f031226 --- /dev/null +++ b/libs/ode-0.16.1/ode/doc/Makefile.in @@ -0,0 +1,472 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = ode/doc +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ode/src/config.h +CONFIG_CLEAN_FILES = Doxyfile +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Doxyfile.in $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_CFLAGS = @CCD_CFLAGS@ +CCD_LIBS = @CCD_LIBS@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSTDCXX = @LIBSTDCXX@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ODE_PRECISION = @ODE_PRECISION@ +ODE_VERSION = @ODE_VERSION@ +ODE_VERSION_INFO = @ODE_VERSION_INFO@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = Doxyfile.in main.dox pix +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign ode/doc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign ode/doc/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +Doxyfile: $(top_builddir)/config.status $(srcdir)/Doxyfile.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +@HAVE_DOXYGEN_FALSE@html-local: +@HAVE_DOXYGEN_FALSE@mostlyclean-local: +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: html-local + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool \ + mostlyclean-local + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am html-local \ + info info-am install install-am install-data install-data-am \ + install-dvi install-dvi-am install-exec install-exec-am \ + install-html install-html-am install-info install-info-am \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool \ + mostlyclean-local pdf pdf-am ps ps-am tags-am uninstall \ + uninstall-am + +.PRECIOUS: Makefile + + +@HAVE_DOXYGEN_TRUE@mostlyclean-local: +@HAVE_DOXYGEN_TRUE@ rm -rf html + +@HAVE_DOXYGEN_TRUE@html-local: Doxyfile +@HAVE_DOXYGEN_TRUE@ $(DOXYGEN) Doxyfile + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/ode/doc/main.dox b/libs/ode-0.16.1/ode/doc/main.dox new file mode 100644 index 0000000..5136c33 --- /dev/null +++ b/libs/ode-0.16.1/ode/doc/main.dox @@ -0,0 +1,22 @@ +/**
+@mainpage Open Dynamics Engine API Reference
+
+<center><em>This document is © Russell Smith and the ODE Project</em></center>
+
+The Open Dynamics Engine (ODE) is a free, industrial quality library for
+simulating articulated rigid body dynamics. ODE is being developed by
+<a href="http://www.q12.org/">Russell Smith</a> with help from several
+<a href="http://ode.org/community.html">contributors</a>.
+
+This document describes the library API. For a more general introduction
+to ODE, please see the <a href="http://opende.sourceforge.net/wiki/index.php/Manual">
+Online Handbook</a>.
+
+<h2>Important: this document is not yet complete!</h2>
+
+We are still working on getting the full API documentated. In the meantime,
+please refer to the <a href="http://opende.sourceforge.net/wiki/index.php/Manual">
+Online Handbook</a>
+
+*/
+
diff --git a/libs/ode-0.16.1/ode/doc/pix/amotor.jpg b/libs/ode-0.16.1/ode/doc/pix/amotor.jpg Binary files differnew file mode 100644 index 0000000..bb80810 --- /dev/null +++ b/libs/ode-0.16.1/ode/doc/pix/amotor.jpg diff --git a/libs/ode-0.16.1/ode/doc/pix/ball-and-socket-bad.jpg b/libs/ode-0.16.1/ode/doc/pix/ball-and-socket-bad.jpg Binary files differnew file mode 100644 index 0000000..90abaf3 --- /dev/null +++ b/libs/ode-0.16.1/ode/doc/pix/ball-and-socket-bad.jpg diff --git a/libs/ode-0.16.1/ode/doc/pix/ball-and-socket.jpg b/libs/ode-0.16.1/ode/doc/pix/ball-and-socket.jpg Binary files differnew file mode 100644 index 0000000..050e136 --- /dev/null +++ b/libs/ode-0.16.1/ode/doc/pix/ball-and-socket.jpg diff --git a/libs/ode-0.16.1/ode/doc/pix/body.jpg b/libs/ode-0.16.1/ode/doc/pix/body.jpg Binary files differnew file mode 100644 index 0000000..e026b93 --- /dev/null +++ b/libs/ode-0.16.1/ode/doc/pix/body.jpg diff --git a/libs/ode-0.16.1/ode/doc/pix/contact.jpg b/libs/ode-0.16.1/ode/doc/pix/contact.jpg Binary files differnew file mode 100644 index 0000000..5d96809 --- /dev/null +++ b/libs/ode-0.16.1/ode/doc/pix/contact.jpg diff --git a/libs/ode-0.16.1/ode/doc/pix/hinge.jpg b/libs/ode-0.16.1/ode/doc/pix/hinge.jpg Binary files differnew file mode 100644 index 0000000..ffd634e --- /dev/null +++ b/libs/ode-0.16.1/ode/doc/pix/hinge.jpg diff --git a/libs/ode-0.16.1/ode/doc/pix/hinge2.jpg b/libs/ode-0.16.1/ode/doc/pix/hinge2.jpg Binary files differnew file mode 100644 index 0000000..fda5e94 --- /dev/null +++ b/libs/ode-0.16.1/ode/doc/pix/hinge2.jpg diff --git a/libs/ode-0.16.1/ode/doc/pix/joints.jpg b/libs/ode-0.16.1/ode/doc/pix/joints.jpg Binary files differnew file mode 100644 index 0000000..188ed01 --- /dev/null +++ b/libs/ode-0.16.1/ode/doc/pix/joints.jpg diff --git a/libs/ode-0.16.1/ode/doc/pix/rollingcontact.jpg b/libs/ode-0.16.1/ode/doc/pix/rollingcontact.jpg Binary files differnew file mode 100644 index 0000000..b20bd1b --- /dev/null +++ b/libs/ode-0.16.1/ode/doc/pix/rollingcontact.jpg diff --git a/libs/ode-0.16.1/ode/doc/pix/sf-graph1.jpg b/libs/ode-0.16.1/ode/doc/pix/sf-graph1.jpg Binary files differnew file mode 100644 index 0000000..aee4ca7 --- /dev/null +++ b/libs/ode-0.16.1/ode/doc/pix/sf-graph1.jpg diff --git a/libs/ode-0.16.1/ode/doc/pix/sf-graph2.jpg b/libs/ode-0.16.1/ode/doc/pix/sf-graph2.jpg Binary files differnew file mode 100644 index 0000000..67d08bc --- /dev/null +++ b/libs/ode-0.16.1/ode/doc/pix/sf-graph2.jpg diff --git a/libs/ode-0.16.1/ode/doc/pix/slider.jpg b/libs/ode-0.16.1/ode/doc/pix/slider.jpg Binary files differnew file mode 100644 index 0000000..040f76f --- /dev/null +++ b/libs/ode-0.16.1/ode/doc/pix/slider.jpg diff --git a/libs/ode-0.16.1/ode/doc/pix/universal.jpg b/libs/ode-0.16.1/ode/doc/pix/universal.jpg Binary files differnew file mode 100644 index 0000000..bc63523 --- /dev/null +++ b/libs/ode-0.16.1/ode/doc/pix/universal.jpg diff --git a/libs/ode-0.16.1/ode/src/Makefile.am b/libs/ode-0.16.1/ode/src/Makefile.am new file mode 100644 index 0000000..609044b --- /dev/null +++ b/libs/ode-0.16.1/ode/src/Makefile.am @@ -0,0 +1,201 @@ +SUBDIRS = joints + +AM_CPPFLAGS = -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ + -D__ODE__ + + + +lib_LTLIBRARIES = libode.la + +libode_la_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ @ODE_VERSION_INFO@ +libode_la_LIBADD = joints/libjoints.la + + +# please, let's keep the filenames sorted +libode_la_SOURCES = nextafterf.c \ + array.cpp array.h \ + box.cpp \ + capsule.cpp \ + collision_cylinder_box.cpp \ + collision_cylinder_plane.cpp \ + collision_cylinder_sphere.cpp \ + collision_kernel.cpp collision_kernel.h \ + collision_quadtreespace.cpp \ + collision_sapspace.cpp \ + collision_space.cpp \ + collision_space_internal.h \ + collision_std.h \ + collision_transform.cpp collision_transform.h \ + collision_trimesh_colliders.h \ + collision_trimesh_disabled.cpp \ + collision_trimesh_internal.h \ + collision_trimesh_opcode.h \ + collision_trimesh_gimpact.h \ + collision_util.cpp collision_util.h \ + common.h \ + convex.cpp \ + coop_matrix_types.h \ + cylinder.cpp \ + default_threading.cpp default_threading.h \ + error.cpp error.h \ + export-dif.cpp \ + fastdot.cpp fastdot_impl.h \ + fastldltfactor.cpp fastldltfactor_impl.h \ + fastldltsolve.cpp fastldltsolve_impl.h \ + fastlsolve.cpp fastlsolve_impl.h \ + fastltsolve.cpp fastltsolve_impl.h \ + fastvecscale.cpp fastvecscale_impl.h \ + heightfield.cpp heightfield.h \ + lcp.cpp lcp.h \ + mass.cpp \ + mat.cpp mat.h \ + matrix.cpp matrix.h \ + memory.cpp \ + misc.cpp \ + objects.cpp objects.h \ + obstack.cpp obstack.h \ + ode.cpp \ + odeinit.cpp \ + odemath.cpp odemath.h \ + odeou.h \ + odetls.h \ + plane.cpp \ + quickstep.cpp quickstep.h \ + ray.cpp \ + resource_control.cpp resource_control.h \ + rotation.cpp \ + simple_cooperative.cpp simple_cooperative.h \ + sphere.cpp \ + step.cpp step.h \ + timer.cpp \ + threaded_solver_ldlt.h \ + threading_atomics_provs.h \ + threading_base.cpp threading_base.h \ + threading_fake_sync.h \ + threading_impl.cpp threading_impl.h \ + threading_impl_posix.h \ + threading_impl_templates.h \ + threading_impl_win.h \ + threading_pool_posix.cpp \ + threading_pool_win.cpp \ + threadingutils.h \ + typedefs.h \ + util.cpp util.h + + +################################### +# O U S T U F F +################################### + + +if ENABLE_OU + +AM_CPPFLAGS += -I$(top_srcdir)/ou/include +libode_la_LIBADD += $(top_builddir)/ou/src/ou/libou.la +libode_la_SOURCES += odetls.cpp odetls.h \ + odeou.cpp odeou.h + +endif + + +################################### +# G I M P A C T S T U F F +################################### + + +if GIMPACT +AM_CPPFLAGS += -DdTRIMESH_ENABLED -DdTRIMESH_GIMPACT -I$(top_srcdir)/GIMPACT/include + +libode_la_LIBADD += $(top_builddir)/GIMPACT/src/libGIMPACT.la +libode_la_SOURCES += collision_trimesh_gimpact.cpp \ + collision_trimesh_internal.cpp collision_trimesh_internal_impl.h \ + gimpact_contact_export_helper.cpp gimpact_contact_export_helper.h \ + gimpact_gim_contact_accessor.h \ + gimpact_plane_contact_accessor.h \ + collision_trimesh_trimesh.cpp \ + collision_trimesh_sphere.cpp \ + collision_trimesh_ray.cpp \ + collision_trimesh_box.cpp \ + collision_trimesh_ccylinder.cpp \ + collision_trimesh_internal.h \ + collision_cylinder_trimesh.cpp \ + collision_trimesh_plane.cpp \ + collision_convex_trimesh.cpp +endif + + + +################################# +# O P C O D E S T U F F +################################# + + +if OPCODE +AM_CPPFLAGS += -I$(top_srcdir)/OPCODE -I$(top_srcdir)/OPCODE/Ice -DdTRIMESH_ENABLED -DdTRIMESH_OPCODE +libode_la_LIBADD += $(top_builddir)/OPCODE/libOPCODE.la \ + $(top_builddir)/OPCODE/Ice/libIce.la + +libode_la_SOURCES+= collision_trimesh_opcode.cpp \ + collision_trimesh_internal.cpp collision_trimesh_internal_impl.h \ + collision_trimesh_trimesh.cpp \ + collision_trimesh_trimesh_old.cpp \ + collision_trimesh_sphere.cpp \ + collision_trimesh_ray.cpp \ + collision_trimesh_box.cpp \ + collision_trimesh_ccylinder.cpp \ + collision_trimesh_internal.h \ + collision_cylinder_trimesh.cpp \ + collision_trimesh_plane.cpp \ + collision_convex_trimesh.cpp +endif + + +if LIBCCD + +AM_CPPFLAGS += -DdLIBCCD_ENABLED +AM_CPPFLAGS += -I$(top_srcdir)/libccd/src/custom + +if LIBCCD_INTERNAL +AM_CPPFLAGS += -I$(top_srcdir)/libccd/src -I$(top_builddir)/libccd/src +libode_la_LIBADD += $(top_builddir)/libccd/src/libccd.la +AM_CPPFLAGS += -DdLIBCCD_INTERNAL +else +AM_CPPFLAGS += $(CCD_CFLAGS) +libode_la_LIBADD += $(CCD_LIBS) +AM_CPPFLAGS += -DdLIBCCD_SYSTEM +endif + + +libode_la_SOURCES += collision_libccd.cpp collision_libccd.h + +if LIBCCD_BOX_CYL +AM_CPPFLAGS += -DdLIBCCD_BOX_CYL +endif + +if LIBCCD_CYL_CYL +AM_CPPFLAGS += -DdLIBCCD_CYL_CYL +endif + +if LIBCCD_CAP_CYL +AM_CPPFLAGS += -DdLIBCCD_CAP_CYL +endif + +if LIBCCD_CONVEX_BOX +AM_CPPFLAGS += -DdLIBCCD_CONVEX_BOX +endif +if LIBCCD_CONVEX_CAP +AM_CPPFLAGS += -DdLIBCCD_CONVEX_CAP +endif +if LIBCCD_CONVEX_CYL +AM_CPPFLAGS += -DdLIBCCD_CONVEX_CYL +endif +if LIBCCD_CONVEX_SPHERE +AM_CPPFLAGS += -DdLIBCCD_CONVEX_SPHERE +endif +if LIBCCD_CONVEX_CONVEX +AM_CPPFLAGS += -DdLIBCCD_CONVEX_CONVEX +endif + + +endif diff --git a/libs/ode-0.16.1/ode/src/Makefile.in b/libs/ode-0.16.1/ode/src/Makefile.in new file mode 100644 index 0000000..330d599 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/Makefile.in @@ -0,0 +1,1100 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ + +################################### +# O U S T U F F +################################### +@ENABLE_OU_TRUE@am__append_1 = -I$(top_srcdir)/ou/include +@ENABLE_OU_TRUE@am__append_2 = $(top_builddir)/ou/src/ou/libou.la +@ENABLE_OU_TRUE@am__append_3 = odetls.cpp odetls.h \ +@ENABLE_OU_TRUE@ odeou.cpp odeou.h + + +################################### +# G I M P A C T S T U F F +################################### +@GIMPACT_TRUE@am__append_4 = -DdTRIMESH_ENABLED -DdTRIMESH_GIMPACT -I$(top_srcdir)/GIMPACT/include +@GIMPACT_TRUE@am__append_5 = $(top_builddir)/GIMPACT/src/libGIMPACT.la +@GIMPACT_TRUE@am__append_6 = collision_trimesh_gimpact.cpp \ +@GIMPACT_TRUE@ collision_trimesh_internal.cpp collision_trimesh_internal_impl.h \ +@GIMPACT_TRUE@ gimpact_contact_export_helper.cpp gimpact_contact_export_helper.h \ +@GIMPACT_TRUE@ gimpact_gim_contact_accessor.h \ +@GIMPACT_TRUE@ gimpact_plane_contact_accessor.h \ +@GIMPACT_TRUE@ collision_trimesh_trimesh.cpp \ +@GIMPACT_TRUE@ collision_trimesh_sphere.cpp \ +@GIMPACT_TRUE@ collision_trimesh_ray.cpp \ +@GIMPACT_TRUE@ collision_trimesh_box.cpp \ +@GIMPACT_TRUE@ collision_trimesh_ccylinder.cpp \ +@GIMPACT_TRUE@ collision_trimesh_internal.h \ +@GIMPACT_TRUE@ collision_cylinder_trimesh.cpp \ +@GIMPACT_TRUE@ collision_trimesh_plane.cpp \ +@GIMPACT_TRUE@ collision_convex_trimesh.cpp + + +################################# +# O P C O D E S T U F F +################################# +@OPCODE_TRUE@am__append_7 = -I$(top_srcdir)/OPCODE -I$(top_srcdir)/OPCODE/Ice -DdTRIMESH_ENABLED -DdTRIMESH_OPCODE +@OPCODE_TRUE@am__append_8 = $(top_builddir)/OPCODE/libOPCODE.la \ +@OPCODE_TRUE@ $(top_builddir)/OPCODE/Ice/libIce.la + +@OPCODE_TRUE@am__append_9 = collision_trimesh_opcode.cpp \ +@OPCODE_TRUE@ collision_trimesh_internal.cpp collision_trimesh_internal_impl.h \ +@OPCODE_TRUE@ collision_trimesh_trimesh.cpp \ +@OPCODE_TRUE@ collision_trimesh_trimesh_old.cpp \ +@OPCODE_TRUE@ collision_trimesh_sphere.cpp \ +@OPCODE_TRUE@ collision_trimesh_ray.cpp \ +@OPCODE_TRUE@ collision_trimesh_box.cpp \ +@OPCODE_TRUE@ collision_trimesh_ccylinder.cpp \ +@OPCODE_TRUE@ collision_trimesh_internal.h \ +@OPCODE_TRUE@ collision_cylinder_trimesh.cpp \ +@OPCODE_TRUE@ collision_trimesh_plane.cpp \ +@OPCODE_TRUE@ collision_convex_trimesh.cpp + +@LIBCCD_TRUE@am__append_10 = -DdLIBCCD_ENABLED \ +@LIBCCD_TRUE@ -I$(top_srcdir)/libccd/src/custom +@LIBCCD_INTERNAL_TRUE@@LIBCCD_TRUE@am__append_11 = \ +@LIBCCD_INTERNAL_TRUE@@LIBCCD_TRUE@ -I$(top_srcdir)/libccd/src \ +@LIBCCD_INTERNAL_TRUE@@LIBCCD_TRUE@ -I$(top_builddir)/libccd/src \ +@LIBCCD_INTERNAL_TRUE@@LIBCCD_TRUE@ -DdLIBCCD_INTERNAL +@LIBCCD_INTERNAL_TRUE@@LIBCCD_TRUE@am__append_12 = $(top_builddir)/libccd/src/libccd.la +@LIBCCD_INTERNAL_FALSE@@LIBCCD_TRUE@am__append_13 = $(CCD_CFLAGS) \ +@LIBCCD_INTERNAL_FALSE@@LIBCCD_TRUE@ -DdLIBCCD_SYSTEM +@LIBCCD_INTERNAL_FALSE@@LIBCCD_TRUE@am__append_14 = $(CCD_LIBS) +@LIBCCD_TRUE@am__append_15 = collision_libccd.cpp collision_libccd.h +@LIBCCD_BOX_CYL_TRUE@@LIBCCD_TRUE@am__append_16 = -DdLIBCCD_BOX_CYL +@LIBCCD_CYL_CYL_TRUE@@LIBCCD_TRUE@am__append_17 = -DdLIBCCD_CYL_CYL +@LIBCCD_CAP_CYL_TRUE@@LIBCCD_TRUE@am__append_18 = -DdLIBCCD_CAP_CYL +@LIBCCD_CONVEX_BOX_TRUE@@LIBCCD_TRUE@am__append_19 = -DdLIBCCD_CONVEX_BOX +@LIBCCD_CONVEX_CAP_TRUE@@LIBCCD_TRUE@am__append_20 = -DdLIBCCD_CONVEX_CAP +@LIBCCD_CONVEX_CYL_TRUE@@LIBCCD_TRUE@am__append_21 = -DdLIBCCD_CONVEX_CYL +@LIBCCD_CONVEX_SPHERE_TRUE@@LIBCCD_TRUE@am__append_22 = -DdLIBCCD_CONVEX_SPHERE +@LIBCCD_CONVEX_CONVEX_TRUE@@LIBCCD_TRUE@am__append_23 = -DdLIBCCD_CONVEX_CONVEX +subdir = ode/src +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +am__DEPENDENCIES_1 = +@LIBCCD_INTERNAL_FALSE@@LIBCCD_TRUE@am__DEPENDENCIES_2 = \ +@LIBCCD_INTERNAL_FALSE@@LIBCCD_TRUE@ $(am__DEPENDENCIES_1) +libode_la_DEPENDENCIES = joints/libjoints.la $(am__append_2) \ + $(am__append_5) $(am__append_8) $(am__append_12) \ + $(am__DEPENDENCIES_2) +am__libode_la_SOURCES_DIST = nextafterf.c array.cpp array.h box.cpp \ + capsule.cpp collision_cylinder_box.cpp \ + collision_cylinder_plane.cpp collision_cylinder_sphere.cpp \ + collision_kernel.cpp collision_kernel.h \ + collision_quadtreespace.cpp collision_sapspace.cpp \ + collision_space.cpp collision_space_internal.h collision_std.h \ + collision_transform.cpp collision_transform.h \ + collision_trimesh_colliders.h collision_trimesh_disabled.cpp \ + collision_trimesh_internal.h collision_trimesh_opcode.h \ + collision_trimesh_gimpact.h collision_util.cpp \ + collision_util.h common.h convex.cpp coop_matrix_types.h \ + cylinder.cpp default_threading.cpp default_threading.h \ + error.cpp error.h export-dif.cpp fastdot.cpp fastdot_impl.h \ + fastldltfactor.cpp fastldltfactor_impl.h fastldltsolve.cpp \ + fastldltsolve_impl.h fastlsolve.cpp fastlsolve_impl.h \ + fastltsolve.cpp fastltsolve_impl.h fastvecscale.cpp \ + fastvecscale_impl.h heightfield.cpp heightfield.h lcp.cpp \ + lcp.h mass.cpp mat.cpp mat.h matrix.cpp matrix.h memory.cpp \ + misc.cpp objects.cpp objects.h obstack.cpp obstack.h ode.cpp \ + odeinit.cpp odemath.cpp odemath.h odeou.h odetls.h plane.cpp \ + quickstep.cpp quickstep.h ray.cpp resource_control.cpp \ + resource_control.h rotation.cpp simple_cooperative.cpp \ + simple_cooperative.h sphere.cpp step.cpp step.h timer.cpp \ + threaded_solver_ldlt.h threading_atomics_provs.h \ + threading_base.cpp threading_base.h threading_fake_sync.h \ + threading_impl.cpp threading_impl.h threading_impl_posix.h \ + threading_impl_templates.h threading_impl_win.h \ + threading_pool_posix.cpp threading_pool_win.cpp \ + threadingutils.h typedefs.h util.cpp util.h odetls.cpp \ + odeou.cpp collision_trimesh_gimpact.cpp \ + collision_trimesh_internal.cpp \ + collision_trimesh_internal_impl.h \ + gimpact_contact_export_helper.cpp \ + gimpact_contact_export_helper.h gimpact_gim_contact_accessor.h \ + gimpact_plane_contact_accessor.h collision_trimesh_trimesh.cpp \ + collision_trimesh_sphere.cpp collision_trimesh_ray.cpp \ + collision_trimesh_box.cpp collision_trimesh_ccylinder.cpp \ + collision_cylinder_trimesh.cpp collision_trimesh_plane.cpp \ + collision_convex_trimesh.cpp collision_trimesh_opcode.cpp \ + collision_trimesh_trimesh_old.cpp collision_libccd.cpp \ + collision_libccd.h +@ENABLE_OU_TRUE@am__objects_1 = odetls.lo odeou.lo +@GIMPACT_TRUE@am__objects_2 = collision_trimesh_gimpact.lo \ +@GIMPACT_TRUE@ collision_trimesh_internal.lo \ +@GIMPACT_TRUE@ gimpact_contact_export_helper.lo \ +@GIMPACT_TRUE@ collision_trimesh_trimesh.lo \ +@GIMPACT_TRUE@ collision_trimesh_sphere.lo \ +@GIMPACT_TRUE@ collision_trimesh_ray.lo \ +@GIMPACT_TRUE@ collision_trimesh_box.lo \ +@GIMPACT_TRUE@ collision_trimesh_ccylinder.lo \ +@GIMPACT_TRUE@ collision_cylinder_trimesh.lo \ +@GIMPACT_TRUE@ collision_trimesh_plane.lo \ +@GIMPACT_TRUE@ collision_convex_trimesh.lo +@OPCODE_TRUE@am__objects_3 = collision_trimesh_opcode.lo \ +@OPCODE_TRUE@ collision_trimesh_internal.lo \ +@OPCODE_TRUE@ collision_trimesh_trimesh.lo \ +@OPCODE_TRUE@ collision_trimesh_trimesh_old.lo \ +@OPCODE_TRUE@ collision_trimesh_sphere.lo \ +@OPCODE_TRUE@ collision_trimesh_ray.lo collision_trimesh_box.lo \ +@OPCODE_TRUE@ collision_trimesh_ccylinder.lo \ +@OPCODE_TRUE@ collision_cylinder_trimesh.lo \ +@OPCODE_TRUE@ collision_trimesh_plane.lo \ +@OPCODE_TRUE@ collision_convex_trimesh.lo +@LIBCCD_TRUE@am__objects_4 = collision_libccd.lo +am_libode_la_OBJECTS = nextafterf.lo array.lo box.lo capsule.lo \ + collision_cylinder_box.lo collision_cylinder_plane.lo \ + collision_cylinder_sphere.lo collision_kernel.lo \ + collision_quadtreespace.lo collision_sapspace.lo \ + collision_space.lo collision_transform.lo \ + collision_trimesh_disabled.lo collision_util.lo convex.lo \ + cylinder.lo default_threading.lo error.lo export-dif.lo \ + fastdot.lo fastldltfactor.lo fastldltsolve.lo fastlsolve.lo \ + fastltsolve.lo fastvecscale.lo heightfield.lo lcp.lo mass.lo \ + mat.lo matrix.lo memory.lo misc.lo objects.lo obstack.lo \ + ode.lo odeinit.lo odemath.lo plane.lo quickstep.lo ray.lo \ + resource_control.lo rotation.lo simple_cooperative.lo \ + sphere.lo step.lo timer.lo threading_base.lo threading_impl.lo \ + threading_pool_posix.lo threading_pool_win.lo util.lo \ + $(am__objects_1) $(am__objects_2) $(am__objects_3) \ + $(am__objects_4) +libode_la_OBJECTS = $(am_libode_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libode_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(libode_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +SOURCES = $(libode_la_SOURCES) +DIST_SOURCES = $(am__libode_la_SOURCES_DIST) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ + $(LISP)config.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_CFLAGS = @CCD_CFLAGS@ +CCD_LIBS = @CCD_LIBS@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSTDCXX = @LIBSTDCXX@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ODE_PRECISION = @ODE_PRECISION@ +ODE_VERSION = @ODE_VERSION@ +ODE_VERSION_INFO = @ODE_VERSION_INFO@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = joints +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include \ + -D__ODE__ $(am__append_1) $(am__append_4) $(am__append_7) \ + $(am__append_10) $(am__append_11) $(am__append_13) \ + $(am__append_16) $(am__append_17) $(am__append_18) \ + $(am__append_19) $(am__append_20) $(am__append_21) \ + $(am__append_22) $(am__append_23) +lib_LTLIBRARIES = libode.la +libode_la_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ @ODE_VERSION_INFO@ +libode_la_LIBADD = joints/libjoints.la $(am__append_2) $(am__append_5) \ + $(am__append_8) $(am__append_12) $(am__append_14) + +# please, let's keep the filenames sorted +libode_la_SOURCES = nextafterf.c array.cpp array.h box.cpp capsule.cpp \ + collision_cylinder_box.cpp collision_cylinder_plane.cpp \ + collision_cylinder_sphere.cpp collision_kernel.cpp \ + collision_kernel.h collision_quadtreespace.cpp \ + collision_sapspace.cpp collision_space.cpp \ + collision_space_internal.h collision_std.h \ + collision_transform.cpp collision_transform.h \ + collision_trimesh_colliders.h collision_trimesh_disabled.cpp \ + collision_trimesh_internal.h collision_trimesh_opcode.h \ + collision_trimesh_gimpact.h collision_util.cpp \ + collision_util.h common.h convex.cpp coop_matrix_types.h \ + cylinder.cpp default_threading.cpp default_threading.h \ + error.cpp error.h export-dif.cpp fastdot.cpp fastdot_impl.h \ + fastldltfactor.cpp fastldltfactor_impl.h fastldltsolve.cpp \ + fastldltsolve_impl.h fastlsolve.cpp fastlsolve_impl.h \ + fastltsolve.cpp fastltsolve_impl.h fastvecscale.cpp \ + fastvecscale_impl.h heightfield.cpp heightfield.h lcp.cpp \ + lcp.h mass.cpp mat.cpp mat.h matrix.cpp matrix.h memory.cpp \ + misc.cpp objects.cpp objects.h obstack.cpp obstack.h ode.cpp \ + odeinit.cpp odemath.cpp odemath.h odeou.h odetls.h plane.cpp \ + quickstep.cpp quickstep.h ray.cpp resource_control.cpp \ + resource_control.h rotation.cpp simple_cooperative.cpp \ + simple_cooperative.h sphere.cpp step.cpp step.h timer.cpp \ + threaded_solver_ldlt.h threading_atomics_provs.h \ + threading_base.cpp threading_base.h threading_fake_sync.h \ + threading_impl.cpp threading_impl.h threading_impl_posix.h \ + threading_impl_templates.h threading_impl_win.h \ + threading_pool_posix.cpp threading_pool_win.cpp \ + threadingutils.h typedefs.h util.cpp util.h $(am__append_3) \ + $(am__append_6) $(am__append_9) $(am__append_15) +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +.SUFFIXES: .c .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign ode/src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign ode/src/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status ode/src/config.h +$(srcdir)/config.h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libode.la: $(libode_la_OBJECTS) $(libode_la_DEPENDENCIES) $(EXTRA_libode_la_DEPENDENCIES) + $(AM_V_CXXLD)$(libode_la_LINK) -rpath $(libdir) $(libode_la_OBJECTS) $(libode_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/array.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/box.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/capsule.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision_convex_trimesh.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision_cylinder_box.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision_cylinder_plane.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision_cylinder_sphere.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision_cylinder_trimesh.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision_kernel.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision_libccd.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision_quadtreespace.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision_sapspace.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision_space.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision_transform.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision_trimesh_box.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision_trimesh_ccylinder.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision_trimesh_disabled.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision_trimesh_gimpact.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision_trimesh_internal.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision_trimesh_opcode.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision_trimesh_plane.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision_trimesh_ray.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision_trimesh_sphere.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision_trimesh_trimesh.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision_trimesh_trimesh_old.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision_util.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/convex.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cylinder.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/default_threading.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/error.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/export-dif.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fastdot.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fastldltfactor.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fastldltsolve.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fastlsolve.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fastltsolve.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fastvecscale.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpact_contact_export_helper.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/heightfield.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lcp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mass.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mat.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/matrix.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memory.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nextafterf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/objects.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/obstack.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ode.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odeinit.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odemath.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odeou.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odetls.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plane.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quickstep.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ray.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/resource_control.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rotation.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simple_cooperative.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sphere.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/step.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/threading_base.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/threading_impl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/threading_pool_posix.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/threading_pool_win.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +.cpp.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(LTLIBRARIES) config.h +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES + +.MAKE: $(am__recursive_targets) all install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libLTLIBRARIES \ + clean-libtool cscopelist-am ctags ctags-am distclean \ + distclean-compile distclean-generic distclean-hdr \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-libLTLIBRARIES install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs installdirs-am \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-libLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/ode/src/array.cpp b/libs/ode-0.16.1/ode/src/array.cpp new file mode 100644 index 0000000..4d63925 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/array.cpp @@ -0,0 +1,81 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <ode/odeconfig.h> +#include <ode/memory.h> +#include <ode/error.h> +#include "config.h" +#include "array.h" + + +static inline int roundUpToPowerOfTwo (int x) +{ + int i = 1; + while (i < x) i <<= 1; + return i; +} + + +void dArrayBase::_freeAll (int sizeofT) +{ + if (_data) { + if (_data == this+1) return; // if constructLocalArray() was called + dFree (_data,_anum * sizeofT); + } +} + + +void dArrayBase::_setSize (int newsize, int sizeofT) +{ + if (newsize < 0) return; + if (newsize > _anum) { + if (_data == this+1) { + // this is a no-no, because constructLocalArray() was called + dDebug (0,"setSize() out of space in LOCAL array"); + } + int newanum = roundUpToPowerOfTwo (newsize); + if (_data) _data = dRealloc (_data, _anum*sizeofT, newanum*sizeofT); + else _data = dAlloc (newanum*sizeofT); + _anum = newanum; + } + _size = newsize; +} + + +void * dArrayBase::operator new (size_t size) +{ + return dAlloc (size); +} + + +void dArrayBase::operator delete (void *ptr, size_t size) +{ + dFree (ptr,size); +} + + +void dArrayBase::constructLocalArray (int __anum) +{ + _size = 0; + _anum = __anum; + _data = this+1; +} diff --git a/libs/ode-0.16.1/ode/src/array.h b/libs/ode-0.16.1/ode/src/array.h new file mode 100644 index 0000000..7ce9e48 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/array.h @@ -0,0 +1,135 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* this comes from the `reuse' library. copy any changes back to the source. + * + * Variable sized array template. The array is always stored in a contiguous + * chunk. The array can be resized. A size increase will cause more memory + * to be allocated, and may result in relocation of the array memory. + * A size decrease has no effect on the memory allocation. + * + * Array elements with constructors or destructors are not supported! + * But if you must have such elements, here's what to know/do: + * - Bitwise copy is used when copying whole arrays. + * - When copying individual items (via push(), insert() etc) the `=' + * (equals) operator is used. Thus you should define this operator to do + * a bitwise copy. You should probably also define the copy constructor. + */ + + +#ifndef _ODE_ARRAY_H_ +#define _ODE_ARRAY_H_ + +#include <ode/odeconfig.h> + + +// this base class has no constructors or destructor, for your convenience. + +class dArrayBase { +protected: + int _size; // number of elements in `data' + int _anum; // allocated number of elements in `data' + void *_data; // array data + + void _freeAll (int sizeofT); + void _setSize (int newsize, int sizeofT); + // set the array size to `newsize', allocating more memory if necessary. + // if newsize>_anum and is a power of two then this is guaranteed to + // set _size and _anum to newsize. + +public: + // not: dArrayBase () { _size=0; _anum=0; _data=0; } + + int size() const { return _size; } + int allocatedSize() const { return _anum; } + void * operator new (size_t size); + void operator delete (void *ptr, size_t size); + + void constructor() { _size=0; _anum=0; _data=0; } + // if this structure is allocated with malloc() instead of new, you can + // call this to set it up. + + void constructLocalArray (int __anum); + // this helper function allows non-reallocating arrays to be constructed + // on the stack (or in the heap if necessary). this is something of a + // kludge and should be used with extreme care. this function acts like + // a constructor - it is called on uninitialized memory that will hold the + // Array structure and the data. __anum is the number of elements that + // are allocated. the memory MUST be allocated with size: + // sizeof(ArrayBase) + __anum*sizeof(T) + // arrays allocated this way will never try to reallocate or free the + // memory - that's your job. +}; + + +template <class T> class dArray : public dArrayBase { +public: + void equals (const dArray<T> &x) { + setSize (x.size()); + memcpy (_data,x._data,x._size * sizeof(T)); + } + + dArray () { constructor(); } + dArray (const dArray<T> &x) { constructor(); equals (x); } + ~dArray () { _freeAll(sizeof(T)); } + void setSize (int newsize) { _setSize (newsize,sizeof(T)); } + T *data() const { return (T*) _data; } + T & operator[] (int i) const { return ((T*)_data)[i]; } + void operator = (const dArray<T> &x) { equals (x); } + + void push (const T item) { + if (_size < _anum) _size++; else _setSize (_size+1,sizeof(T)); + memcpy (&(((T*)_data)[_size-1]), &item, sizeof(T)); + } + + void swap (dArray<T> &x) { + int tmp1; + void *tmp2; + tmp1=_size; _size=x._size; x._size=tmp1; + tmp1=_anum; _anum=x._anum; x._anum=tmp1; + tmp2=_data; _data=x._data; x._data=tmp2; + } + + // insert the item at the position `i'. if i<0 then add the item to the + // start, if i >= size then add the item to the end of the array. + void insert (int i, const T item) { + if (_size < _anum) _size++; else _setSize (_size+1,sizeof(T)); + if (i >= (_size-1)) i = _size-1; // add to end + else { + if (i < 0) i=0; // add to start + int n = _size-1-i; + if (n>0) memmove (((T*)_data) + i+1, ((T*)_data) + i, n*sizeof(T)); + } + ((T*)_data)[i] = item; + } + + void remove (int i) { + if (i >= 0 && i < _size) { // passing this test guarantees size>0 + int n = _size-1-i; + if (n>0) memmove (((T*)_data) + i, ((T*)_data) + i+1, n*sizeof(T)); + _size--; + } + } +}; + + +#endif diff --git a/libs/ode-0.16.1/ode/src/box.cpp b/libs/ode-0.16.1/ode/src/box.cpp new file mode 100644 index 0000000..cfedb01 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/box.cpp @@ -0,0 +1,878 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + + standard ODE geometry primitives: public API and pairwise collision functions. + + the rule is that only the low level primitive collision functions should set + dContactGeom::g1 and dContactGeom::g2. + +*/ + +#include <ode/common.h> +#include <ode/collision.h> +#include <ode/rotation.h> +#include "config.h" +#include "matrix.h" +#include "odemath.h" +#include "collision_kernel.h" +#include "collision_std.h" +#include "collision_util.h" + +#ifdef _MSC_VER +#pragma warning(disable:4291) // for VC++, no complaints about "no matching operator delete found" +#endif + +//**************************************************************************** +// box public API + +dxBox::dxBox (dSpaceID space, dReal lx, dReal ly, dReal lz) : dxGeom (space,1) +{ + dAASSERT (lx >= 0 && ly >= 0 && lz >= 0); + type = dBoxClass; + side[0] = lx; + side[1] = ly; + side[2] = lz; + updateZeroSizedFlag(!lx || !ly || !lz); +} + + +void dxBox::computeAABB() +{ + const dMatrix3& R = final_posr->R; + const dVector3& pos = final_posr->pos; + + dReal xrange = REAL(0.5) * (dFabs (R[0] * side[0]) + + dFabs (R[1] * side[1]) + dFabs (R[2] * side[2])); + dReal yrange = REAL(0.5) * (dFabs (R[4] * side[0]) + + dFabs (R[5] * side[1]) + dFabs (R[6] * side[2])); + dReal zrange = REAL(0.5) * (dFabs (R[8] * side[0]) + + dFabs (R[9] * side[1]) + dFabs (R[10] * side[2])); + aabb[0] = pos[0] - xrange; + aabb[1] = pos[0] + xrange; + aabb[2] = pos[1] - yrange; + aabb[3] = pos[1] + yrange; + aabb[4] = pos[2] - zrange; + aabb[5] = pos[2] + zrange; +} + + +dGeomID dCreateBox (dSpaceID space, dReal lx, dReal ly, dReal lz) +{ + return new dxBox (space,lx,ly,lz); +} + + +void dGeomBoxSetLengths (dGeomID g, dReal lx, dReal ly, dReal lz) +{ + dUASSERT (g && g->type == dBoxClass,"argument not a box"); + dAASSERT (lx >= 0 && ly >= 0 && lz >= 0); + dxBox *b = (dxBox*) g; + b->side[0] = lx; + b->side[1] = ly; + b->side[2] = lz; + b->updateZeroSizedFlag(!lx || !ly || !lz); + dGeomMoved (g); +} + + +void dGeomBoxGetLengths (dGeomID g, dVector3 result) +{ + dUASSERT (g && g->type == dBoxClass,"argument not a box"); + dxBox *b = (dxBox*) g; + result[0] = b->side[0]; + result[1] = b->side[1]; + result[2] = b->side[2]; +} + + +dReal dGeomBoxPointDepth (dGeomID g, dReal x, dReal y, dReal z) +{ + dUASSERT (g && g->type == dBoxClass,"argument not a box"); + g->recomputePosr(); + dxBox *b = (dxBox*) g; + + // Set p = (x,y,z) relative to box center + // + // This will be (0,0,0) if the point is at (side[0]/2,side[1]/2,side[2]/2) + + dVector3 p,q; + + p[0] = x - b->final_posr->pos[0]; + p[1] = y - b->final_posr->pos[1]; + p[2] = z - b->final_posr->pos[2]; + + // Rotate p into box's coordinate frame, so we can + // treat the OBB as an AABB + + dMultiply1_331 (q,b->final_posr->R,p); + + // Record distance from point to each successive box side, and see + // if the point is inside all six sides + + dReal dist[6]; + int i; + + bool inside = true; + + for (i=0; i < 3; i++) { + dReal side = b->side[i] * REAL(0.5); + + dist[i ] = side - q[i]; + dist[i+3] = side + q[i]; + + if ((dist[i] < 0) || (dist[i+3] < 0)) { + inside = false; + } + } + + // If point is inside the box, the depth is the smallest positive distance + // to any side + + if (inside) { + dReal smallest_dist = (dReal) (unsigned) -1; + + for (i=0; i < 6; i++) { + if (dist[i] < smallest_dist) smallest_dist = dist[i]; + } + + return smallest_dist; + } + + // Otherwise, if point is outside the box, the depth is the largest + // distance to any side. This is an approximation to the 'proper' + // solution (the proper solution may be larger in some cases). + + dReal largest_dist = 0; + + for (i=0; i < 6; i++) { + if (dist[i] > largest_dist) largest_dist = dist[i]; + } + + return -largest_dist; +} + +//**************************************************************************** +// box-box collision utility + + +// 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]). +// +// the intersection points are returned as x,y pairs in the 'ret' array. +// the number of intersection points is returned by the function (this will +// be in the range 0 to 8). + +static int intersectRectQuad (dReal h[2], dReal p[8], dReal ret[16]) +{ + // q (and r) contain nq (and nr) coordinate points for the current (and + // chopped) polygons + int nq=4,nr; + dReal buffer[16]; + dReal *q = p; + dReal *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] + dReal *pq = q; + dReal *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; + } + } + dReal *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(dReal)); + return nr; +} + + +// given n points in the plane (array p, of size 2*n), generate m points that +// best represent the whole set. the definition of 'best' here is not +// predetermined - the idea is to select points that give good box-box +// collision detection behavior. the chosen point indexes are returned in the +// array iret (of size m). 'i0' is always the first entry in the array. +// 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 cullPoints (int n, dReal p[], int m, int i0, int iret[]) +{ + // compute the centroid of the polygon in cx,cy + int i,j; + dReal a,cx,cy,q; + if (n==1) { + cx = p[0]; + cy = p[1]; + } + else if (n==2) { + cx = REAL(0.5)*(p[0] + p[2]); + cy = REAL(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]; + a = dRecip(REAL(3.0)*(a+q)); + 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 + dReal A[8]; + for (i=0; i<n; i++) A[i] = dAtan2(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 = (dReal)(dReal(j)*(2*M_PI/m) + A[i0]); + if (a > M_PI) a -= (dReal)(2*M_PI); + dReal maxdiff=1e9,diff; +#ifndef dNODEBUG + *iret = i0; // iret is not allowed to keep this value +#endif + for (i=0; i<n; i++) { + if (avail[i]) { + diff = dFabs (A[i]-a); + if (diff > M_PI) diff = (dReal) (2*M_PI - diff); + if (diff < maxdiff) { + maxdiff = diff; + *iret = i; + } + } + } +#ifndef dNODEBUG + dIASSERT (*iret != i0); // ensure iret got set +#endif + avail[*iret] = 0; + iret++; + } +} + + +// 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. +// `normal' returns the contact normal. +// `depth' returns the maximum penetration depth along that normal. +// `return_code' returns a number indicating the type of contact that was +// detected: +// 1,2,3 = box 2 intersects with a face of box 1 +// 4,5,6 = box 1 intersects with a face of box 2 +// 7..15 = edge-edge contact +// `maxc' is the maximum number of contacts allowed to be generated, i.e. +// the size of the `contact' array. +// `contact' and `skip' are the contact array information provided to the +// collision functions. this function only fills in the position and depth +// fields. + + +int dBoxBox (const dVector3 p1, const dMatrix3 R1, + const dVector3 side1, const dVector3 p2, + const dMatrix3 R2, const dVector3 side2, + dVector3 normal, dReal *depth, int *return_code, + int flags, dContactGeom *contact, int skip) +{ + const dReal fudge_factor = REAL(1.05); + dVector3 p,pp,normalC={0,0,0}; + const dReal *normalR = 0; + dReal 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,expr1_val; + int i,j,invert_normal,code; + + // get vector from centers of box 1 to box 2, relative to box 1 + p[0] = p2[0] - p1[0]; + p[1] = p2[1] - p1[1]; + p[2] = p2[2] - p1[2]; + dMultiply1_331 (pp,R1,p); // get pp = p relative to body 1 + + // get side lengths / 2 + A[0] = side1[0]*REAL(0.5); + A[1] = side1[1]*REAL(0.5); + A[2] = side1[2]*REAL(0.5); + B[0] = side2[0]*REAL(0.5); + B[1] = side2[1]*REAL(0.5); + B[2] = side2[2]*REAL(0.5); + + // Rij is R1'*R2, i.e. the relative rotation between R1 and R2 + R11 = dCalcVectorDot3_44(R1+0,R2+0); R12 = dCalcVectorDot3_44(R1+0,R2+1); R13 = dCalcVectorDot3_44(R1+0,R2+2); + R21 = dCalcVectorDot3_44(R1+1,R2+0); R22 = dCalcVectorDot3_44(R1+1,R2+1); R23 = dCalcVectorDot3_44(R1+1,R2+2); + R31 = dCalcVectorDot3_44(R1+2,R2+0); R32 = dCalcVectorDot3_44(R1+2,R2+1); R33 = dCalcVectorDot3_44(R1+2,R2+2); + + Q11 = dFabs(R11); Q12 = dFabs(R12); Q13 = dFabs(R13); + Q21 = dFabs(R21); Q22 = dFabs(R22); Q23 = dFabs(R23); + Q31 = dFabs(R31); Q32 = dFabs(R32); Q33 = dFabs(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. + + do { +#define TST(expr1,expr2,norm,cc) \ + expr1_val = (expr1); /* Avoid duplicate evaluation of expr1 */ \ + s2 = dFabs(expr1_val) - (expr2); \ + if (s2 > 0) return 0; \ + if (s2 > s) { \ + s = s2; \ + normalR = norm; \ + invert_normal = ((expr1_val) < 0); \ + code = (cc); \ + if (flags & CONTACTS_UNIMPORTANT) break; \ + } + + 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 = v1,v2,v3 + TST (dCalcVectorDot3_41(R2+0,p),(A[0]*Q11 + A[1]*Q21 + A[2]*Q31 + B[0]),R2+0,4); + TST (dCalcVectorDot3_41(R2+1,p),(A[0]*Q12 + A[1]*Q22 + A[2]*Q32 + B[1]),R2+1,5); + TST (dCalcVectorDot3_41(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. +#undef TST +#define TST(expr1,expr2,n1,n2,n3,cc) \ + expr1_val = (expr1); /* Avoid duplicate evaluation of expr1 */ \ + s2 = dFabs(expr1_val) - (expr2); \ + if (s2 > 0) return 0; \ + l = dSqrt ((n1)*(n1) + (n2)*(n2) + (n3)*(n3)); \ + if (l > 0) { \ + 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_val) < 0); \ + code = (cc); \ + if (flags & CONTACTS_UNIMPORTANT) break; \ + } \ + } + + // We only need to check 3 edges per box + // since parallel edges are equivalent. + + // 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 = 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 + } while (0); + + 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 + dVector3 pa; + dReal sign; + // Copy p1 into pa + for (i=0; i<3; i++) pa[i] = p1[i]; // why no memcpy? + // Get world position of p2 into pa + for (j=0; j<3; j++) { + sign = (dCalcVectorDot3_14(normal,R1+j) > 0) ? REAL(1.0) : REAL(-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 + dVector3 pb; + // Copy p2 into pb + for (i=0; i<3; i++) pb[i] = p2[i]; // why no memcpy? + // Get world position of p2 into pb + for (j=0; j<3; j++) { + sign = (dCalcVectorDot3_14(normal,R2+j) > 0) ? REAL(-1.0) : REAL(1.0); + for (i=0; i<3; i++) pb[i] += sign * B[j] * R2[i*4+j]; + } + + dReal alpha,beta; + dVector3 ua,ub; + // Get direction of first edge + for (i=0; i<3; i++) ua[i] = R1[((code)-7)/3 + i*4]; + // Get direction of second edge + for (i=0; i<3; i++) ub[i] = R2[((code)-7)%3 + i*4]; + // Get closest points between edges (one at each) + 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; + // Set the contact point as halfway between the 2 closest points + for (i=0; i<3; i++) contact[0].pos[i] = REAL(0.5)*(pa[i]+pb[i]); + contact[0].depth = *depth; + *return_code = code; + 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). + // Note: Unmodified parameter values are being used here + const dReal *Ra,*Rb,*pa,*pb,*Sa,*Sb; + if (code <= 3) { // One of the faces of box 1 is the reference face + Ra = R1; // Rotation of 'a' + Rb = R2; // Rotation of 'b' + pa = p1; // Center (location) of 'a' + pb = p2; // Center (location) of 'b' + Sa = A; // Side Lenght of 'a' + Sb = B; // Side Lenght of 'b' + } + else { // One of the faces of box 2 is the reference face + Ra = R2; // Rotation of 'a' + Rb = R1; // Rotation of 'b' + pa = p2; // Center (location) of 'a' + pb = p1; // Center (location) of 'b' + Sa = B; // Side Lenght of 'a' + Sb = A; // Side Lenght of 'b' + } + + // nr = normal vector of reference face dotted with axes of incident box. + // anr = absolute values of nr. + /* + The normal is flipped if necessary so it always points outward from box 'a', + box 'b' is thus always the incident box + */ + dVector3 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]; + } + // Rotate normal2 in incident box opposite direction + dMultiply1_331 (nr,Rb,normal2); + anr[0] = dFabs (nr[0]); + anr[1] = dFabs (nr[1]); + anr[2] = dFabs (nr[2]); + + // find the largest compontent of anr: this corresponds to the normal + // for the incident face. the other axis numbers of the incident 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 + dVector3 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 + dReal quad[8]; // 2D coordinate of incident face (x,y pairs) + dReal c1,c2,m11,m12,m21,m22; + c1 = dCalcVectorDot3_14 (center,Ra+code1); + c2 = dCalcVectorDot3_14 (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 = dCalcVectorDot3_44 (Ra+code1,Rb+a1); + m12 = dCalcVectorDot3_44 (Ra+code1,Rb+a2); + m21 = dCalcVectorDot3_44 (Ra+code2,Rb+a1); + m22 = dCalcVectorDot3_44 (Ra+code2,Rb+a2); + { + dReal k1 = m11*Sb[a1]; + dReal k2 = m21*Sb[a1]; + dReal k3 = m12*Sb[a2]; + dReal 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 + dReal rect[2]; + rect[0] = Sa[code1]; + rect[1] = Sa[code2]; + + // intersect the incident and reference faces + dReal ret[16]; + int n = intersectRectQuad (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. + dReal point[3*8]; // penetrating contact points + dReal dep[8]; // depths for those points + dReal det1 = dRecip(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++) { + dReal k1 = m22*(ret[j*2]-c1) - m12*(ret[j*2+1]-c2); + dReal 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] - dCalcVectorDot3(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 | CONTACTS_UNIMPORTANT) == (flags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) { + break; + } + } + } + if (cnum < 1) { + return 0; // this should not happen, yet does at times (demo_plane2d single precision). + } + + // we can't generate more contacts than we actually have + int maxc = flags & NUMC_MASK; + if (maxc > cnum) maxc = cnum; + if (maxc < 1) maxc = 1; // Even though max count must not be zero this check is kept for backward compatibility as this is a public function + + if (cnum <= maxc) { + // we have less contacts than we need, so we use them all + for (j=0; j < cnum; j++) { + dContactGeom *con = CONTACT(contact,skip*j); + for (i=0; i<3; i++) con->pos[i] = point[j*3+i] + pa[i]; + con->depth = dep[j]; + } + } + else { + dIASSERT(!(flags & CONTACTS_UNIMPORTANT)); // cnum should be generated not greater than maxc so that "then" clause is executed + // 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; + dReal maxdepth = dep[0]; + for (i=1; i<cnum; i++) { + if (dep[i] > maxdepth) { + maxdepth = dep[i]; + i1 = i; + } + } + + int iret[8]; + cullPoints (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]]; + } + cnum = maxc; + } + + *return_code = code; + return cnum; +} + + + +int dCollideBoxBox (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dBoxClass); + dIASSERT (o2->type == dBoxClass); + dIASSERT ((flags & NUMC_MASK) >= 1); + + dVector3 normal; + dReal depth; + int code; + dxBox *b1 = (dxBox*) o1; + dxBox *b2 = (dxBox*) o2; + int num = dBoxBox (o1->final_posr->pos,o1->final_posr->R,b1->side, o2->final_posr->pos,o2->final_posr->R,b2->side, + normal,&depth,&code,flags,contact,skip); + for (int i=0; i<num; i++) { + dContactGeom *currContact = CONTACT(contact,i*skip); + currContact->normal[0] = -normal[0]; + currContact->normal[1] = -normal[1]; + currContact->normal[2] = -normal[2]; + currContact->g1 = o1; + currContact->g2 = o2; + currContact->side1 = -1; + currContact->side2 = -1; + } + return num; +} + + +int dCollideBoxPlane (dxGeom *o1, dxGeom *o2, + int flags, dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dBoxClass); + dIASSERT (o2->type == dPlaneClass); + dIASSERT ((flags & NUMC_MASK) >= 1); + + dxBox *box = (dxBox*) o1; + dxPlane *plane = (dxPlane*) o2; + + contact->g1 = o1; + contact->g2 = o2; + contact->side1 = -1; + contact->side2 = -1; + + int ret = 0; + + //@@@ problem: using 4-vector (plane->p) as 3-vector (normal). + const dReal *R = o1->final_posr->R; // rotation of box + const dReal *n = plane->p; // normal vector + + // project sides lengths along normal vector, get absolute values + dReal Q1 = dCalcVectorDot3_14(n,R+0); + dReal Q2 = dCalcVectorDot3_14(n,R+1); + dReal Q3 = dCalcVectorDot3_14(n,R+2); + dReal A1 = box->side[0] * Q1; + dReal A2 = box->side[1] * Q2; + dReal A3 = box->side[2] * Q3; + dReal B1 = dFabs(A1); + dReal B2 = dFabs(A2); + dReal B3 = dFabs(A3); + + // early exit test + dReal depth = plane->p[3] + REAL(0.5)*(B1+B2+B3) - dCalcVectorDot3(n,o1->final_posr->pos); + if (depth < 0) return 0; + + // find number of contacts requested + int maxc = flags & NUMC_MASK; + // if (maxc < 1) maxc = 1; // an assertion is made on entry + if (maxc > 4) maxc = 4; // not more than 4 contacts per box allowed + + // find deepest point + dVector3 p; + p[0] = o1->final_posr->pos[0]; + p[1] = o1->final_posr->pos[1]; + p[2] = o1->final_posr->pos[2]; +#define FOO(i,op) \ + p[0] op REAL(0.5)*box->side[i] * R[0+i]; \ + p[1] op REAL(0.5)*box->side[i] * R[4+i]; \ + p[2] op REAL(0.5)*box->side[i] * R[8+i]; +#define BAR(i,iinc) if (A ## iinc > 0) { FOO(i,-=) } else { FOO(i,+=) } + BAR(0,1); + BAR(1,2); + BAR(2,3); +#undef FOO +#undef BAR + + // the deepest point is the first contact point + contact->pos[0] = p[0]; + contact->pos[1] = p[1]; + contact->pos[2] = p[2]; + contact->depth = depth; + ret = 1; // ret is number of contact points found so far + if (maxc == 1) goto done; + + // get the second and third contact points by starting from `p' and going + // along the two sides with the smallest projected length. + +#define FOO(i,j,op) \ + CONTACT(contact,i*skip)->pos[0] = p[0] op box->side[j] * R[0+j]; \ + CONTACT(contact,i*skip)->pos[1] = p[1] op box->side[j] * R[4+j]; \ + CONTACT(contact,i*skip)->pos[2] = p[2] op box->side[j] * R[8+j]; +#define BAR(ctact,side,sideinc) \ + if (depth - B ## sideinc < 0) goto done; \ + if (A ## sideinc > 0) { FOO(ctact,side,+); } else { FOO(ctact,side,-); } \ + CONTACT(contact,ctact*skip)->depth = depth - B ## sideinc; \ + ret++; + + if (B1 < B2) { + if (B3 < B1) goto use_side_3; else { + BAR(1,0,1); // use side 1 + if (maxc == 2) goto done; + if (B2 < B3) goto contact2_2; else goto contact2_3; + } + } + else { + if (B3 < B2) { +use_side_3: // use side 3 + BAR(1,2,3); + if (maxc == 2) goto done; + if (B1 < B2) goto contact2_1; else goto contact2_2; + } + else { + BAR(1,1,2); // use side 2 + if (maxc == 2) goto done; + if (B1 < B3) goto contact2_1; else goto contact2_3; + } + } + +contact2_1: BAR(2,0,1); goto done; +contact2_2: BAR(2,1,2); goto done; +contact2_3: BAR(2,2,3); goto done; +#undef FOO +#undef BAR + +done: + + if (maxc == 4 && ret == 3) { // If user requested 4 contacts, and the first 3 were created... + // Combine contacts 2 and 3 (vectorial sum) and get the fourth one + // Result: if a box face is completely inside a plane, contacts are created for all the 4 vertices + dReal d4 = CONTACT(contact,1*skip)->depth + CONTACT(contact,2*skip)->depth - depth; // depth is the depth for first contact + if (d4 > 0) { + CONTACT(contact,3*skip)->pos[0] = CONTACT(contact,1*skip)->pos[0] + CONTACT(contact,2*skip)->pos[0] - p[0]; // p is the position of first contact + CONTACT(contact,3*skip)->pos[1] = CONTACT(contact,1*skip)->pos[1] + CONTACT(contact,2*skip)->pos[1] - p[1]; + CONTACT(contact,3*skip)->pos[2] = CONTACT(contact,1*skip)->pos[2] + CONTACT(contact,2*skip)->pos[2] - p[2]; + CONTACT(contact,3*skip)->depth = d4; + ret++; + } + } + + for (int i=0; i<ret; i++) { + dContactGeom *currContact = CONTACT(contact,i*skip); + currContact->g1 = o1; + currContact->g2 = o2; + currContact->side1 = -1; + currContact->side2 = -1; + + currContact->normal[0] = n[0]; + currContact->normal[1] = n[1]; + currContact->normal[2] = n[2]; + } + return ret; +} diff --git a/libs/ode-0.16.1/ode/src/capsule.cpp b/libs/ode-0.16.1/ode/src/capsule.cpp new file mode 100644 index 0000000..80e24ac --- /dev/null +++ b/libs/ode-0.16.1/ode/src/capsule.cpp @@ -0,0 +1,416 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +standard ODE geometry primitives: public API and pairwise collision functions. + +the rule is that only the low level primitive collision functions should set +dContactGeom::g1 and dContactGeom::g2. + +*/ + +#include <ode/common.h> +#include <ode/collision.h> +#include <ode/rotation.h> +#include "config.h" +#include "matrix.h" +#include "odemath.h" +#include "collision_kernel.h" +#include "collision_std.h" +#include "collision_util.h" + +#ifdef _MSC_VER +#pragma warning(disable:4291) // for VC++, no complaints about "no matching operator delete found" +#endif + +//**************************************************************************** +// capped cylinder public API + +dxCapsule::dxCapsule (dSpaceID space, dReal _radius, dReal _length) : +dxGeom (space,1) +{ + dAASSERT (_radius >= 0 && _length >= 0); + type = dCapsuleClass; + radius = _radius; + lz = _length; + updateZeroSizedFlag(!_radius/* || !_length -- zero length capsule is not a zero sized capsule*/); +} + + +void dxCapsule::computeAABB() +{ + const dMatrix3& R = final_posr->R; + const dVector3& pos = final_posr->pos; + + dReal xrange = dFabs(R[2] * lz) * REAL(0.5) + radius; + dReal yrange = dFabs(R[6] * lz) * REAL(0.5) + radius; + dReal zrange = dFabs(R[10] * lz) * REAL(0.5) + radius; + aabb[0] = pos[0] - xrange; + aabb[1] = pos[0] + xrange; + aabb[2] = pos[1] - yrange; + aabb[3] = pos[1] + yrange; + aabb[4] = pos[2] - zrange; + aabb[5] = pos[2] + zrange; +} + + +dGeomID dCreateCapsule (dSpaceID space, dReal radius, dReal length) +{ + return new dxCapsule (space,radius,length); +} + + +void dGeomCapsuleSetParams (dGeomID g, dReal radius, dReal length) +{ + dUASSERT (g && g->type == dCapsuleClass,"argument not a ccylinder"); + dAASSERT (radius >= 0 && length >= 0); + dxCapsule *c = (dxCapsule*) g; + c->radius = radius; + c->lz = length; + c->updateZeroSizedFlag(!radius/* || !length -- zero length capsule is not a zero sized capsule*/); + dGeomMoved (g); +} + + +void dGeomCapsuleGetParams (dGeomID g, dReal *radius, dReal *length) +{ + dUASSERT (g && g->type == dCapsuleClass,"argument not a ccylinder"); + dxCapsule *c = (dxCapsule*) g; + *radius = c->radius; + *length = c->lz; +} + + +dReal dGeomCapsulePointDepth (dGeomID g, dReal x, dReal y, dReal z) +{ + dUASSERT (g && g->type == dCapsuleClass,"argument not a ccylinder"); + g->recomputePosr(); + dxCapsule *c = (dxCapsule*) g; + + const dReal* R = g->final_posr->R; + const dReal* pos = g->final_posr->pos; + + dVector3 a; + a[0] = x - pos[0]; + a[1] = y - pos[1]; + a[2] = z - pos[2]; + dReal beta = dCalcVectorDot3_14(a,R+2); + dReal lz2 = c->lz*REAL(0.5); + if (beta < -lz2) beta = -lz2; + else if (beta > lz2) beta = lz2; + a[0] = c->final_posr->pos[0] + beta*R[0*4+2]; + a[1] = c->final_posr->pos[1] + beta*R[1*4+2]; + a[2] = c->final_posr->pos[2] + beta*R[2*4+2]; + return c->radius - + dSqrt ((x-a[0])*(x-a[0]) + (y-a[1])*(y-a[1]) + (z-a[2])*(z-a[2])); +} + + + +int dCollideCapsuleSphere (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dCapsuleClass); + dIASSERT (o2->type == dSphereClass); + dIASSERT ((flags & NUMC_MASK) >= 1); + + dxCapsule *ccyl = (dxCapsule*) o1; + dxSphere *sphere = (dxSphere*) o2; + + contact->g1 = o1; + contact->g2 = o2; + contact->side1 = -1; + contact->side2 = -1; + + // find the point on the cylinder axis that is closest to the sphere + dReal alpha = + o1->final_posr->R[2] * (o2->final_posr->pos[0] - o1->final_posr->pos[0]) + + o1->final_posr->R[6] * (o2->final_posr->pos[1] - o1->final_posr->pos[1]) + + o1->final_posr->R[10] * (o2->final_posr->pos[2] - o1->final_posr->pos[2]); + dReal lz2 = ccyl->lz * REAL(0.5); + if (alpha > lz2) alpha = lz2; + if (alpha < -lz2) alpha = -lz2; + + // collide the spheres + dVector3 p; + p[0] = o1->final_posr->pos[0] + alpha * o1->final_posr->R[2]; + p[1] = o1->final_posr->pos[1] + alpha * o1->final_posr->R[6]; + p[2] = o1->final_posr->pos[2] + alpha * o1->final_posr->R[10]; + return dCollideSpheres (p,ccyl->radius,o2->final_posr->pos,sphere->radius,contact); +} + + +int dCollideCapsuleBox (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dCapsuleClass); + dIASSERT (o2->type == dBoxClass); + dIASSERT ((flags & NUMC_MASK) >= 1); + + dxCapsule *cyl = (dxCapsule*) o1; + dxBox *box = (dxBox*) o2; + + contact->g1 = o1; + contact->g2 = o2; + contact->side1 = -1; + contact->side2 = -1; + + // get p1,p2 = cylinder axis endpoints, get radius + dVector3 p1,p2; + dReal clen = cyl->lz * REAL(0.5); + p1[0] = o1->final_posr->pos[0] + clen * o1->final_posr->R[2]; + p1[1] = o1->final_posr->pos[1] + clen * o1->final_posr->R[6]; + p1[2] = o1->final_posr->pos[2] + clen * o1->final_posr->R[10]; + p2[0] = o1->final_posr->pos[0] - clen * o1->final_posr->R[2]; + p2[1] = o1->final_posr->pos[1] - clen * o1->final_posr->R[6]; + p2[2] = o1->final_posr->pos[2] - clen * o1->final_posr->R[10]; + dReal radius = cyl->radius; + + // copy out box center, rotation matrix, and side array + dReal *c = o2->final_posr->pos; + dReal *R = o2->final_posr->R; + const dReal *side = box->side; + + // get the closest point between the cylinder axis and the box + dVector3 pl,pb; + dClosestLineBoxPoints (p1,p2,c,R,side,pl,pb); + + // if the capsule is penetrated further than radius + // then pl and pb are equal (up to mindist) -> unknown normal + // use normal vector of closest box surface +#ifdef dSINGLE + dReal mindist = REAL(1e-6); +#else + dReal mindist = REAL(1e-15); +#endif + if (dCalcPointsDistance3(pl, pb)<mindist) { + // consider capsule as box + dVector3 normal; + dReal depth; + int code; + // WARNING! rad2 is declared as #define in Microsoft headers (as well as psh2, chx2, grp2, frm2, rct2, ico2, stc2, lst2, cmb2, edt2, scr2). Avoid abbreviations! + /* dReal rad2 = radius*REAL(2.0); */ dReal radiusMul2 = radius * REAL(2.0); + const dVector3 capboxside = {radiusMul2, radiusMul2, cyl->lz + radiusMul2}; + int num = dBoxBox (c, R, side, + o1->final_posr->pos, o1->final_posr->R, capboxside, + normal, &depth, &code, flags, contact, skip); + + for (int i=0; i<num; i++) { + dContactGeom *currContact = CONTACT(contact,i*skip); + currContact->normal[0] = normal[0]; + currContact->normal[1] = normal[1]; + currContact->normal[2] = normal[2]; + currContact->g1 = o1; + currContact->g2 = o2; + currContact->side1 = -1; + currContact->side2 = -1; + } + return num; + } else { + // generate contact point + return dCollideSpheres (pl,radius,pb,0,contact); + } +} + + +int dCollideCapsuleCapsule (dxGeom *o1, dxGeom *o2, + int flags, dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dCapsuleClass); + dIASSERT (o2->type == dCapsuleClass); + dIASSERT ((flags & NUMC_MASK) >= 1); + + int i; + const dReal tolerance = REAL(1e-5); + + dxCapsule *cyl1 = (dxCapsule*) o1; + dxCapsule *cyl2 = (dxCapsule*) o2; + + contact->g1 = o1; + contact->g2 = o2; + contact->side1 = -1; + contact->side2 = -1; + + // copy out some variables, for convenience + dReal lz1 = cyl1->lz * REAL(0.5); + dReal lz2 = cyl2->lz * REAL(0.5); + dReal *pos1 = o1->final_posr->pos; + dReal *pos2 = o2->final_posr->pos; + dReal axis1[3],axis2[3]; + axis1[0] = o1->final_posr->R[2]; + axis1[1] = o1->final_posr->R[6]; + axis1[2] = o1->final_posr->R[10]; + axis2[0] = o2->final_posr->R[2]; + axis2[1] = o2->final_posr->R[6]; + axis2[2] = o2->final_posr->R[10]; + + // if the cylinder axes are close to parallel, we'll try to detect up to + // two contact points along the body of the cylinder. if we can't find any + // points then we'll fall back to the closest-points algorithm. note that + // we are not treating this special case for reasons of degeneracy, but + // because we want two contact points in some situations. the closet-points + // algorithm is robust in all casts, but it can return only one contact. + + dVector3 sphere1,sphere2; + dReal a1a2 = dCalcVectorDot3 (axis1,axis2); + dReal det = REAL(1.0)-a1a2*a1a2; + if (det < tolerance) { + // the cylinder axes (almost) parallel, so we will generate up to two + // contacts. alpha1 and alpha2 (line position parameters) are related by: + // alpha2 = alpha1 + (pos1-pos2)'*axis1 (if axis1==axis2) + // or alpha2 = -(alpha1 + (pos1-pos2)'*axis1) (if axis1==-axis2) + // first compute where the two cylinders overlap in alpha1 space: + if (a1a2 < 0) { + axis2[0] = -axis2[0]; + axis2[1] = -axis2[1]; + axis2[2] = -axis2[2]; + } + dReal q[3]; + for (i=0; i<3; i++) q[i] = pos1[i]-pos2[i]; + dReal k = dCalcVectorDot3 (axis1,q); + dReal a1lo = -lz1; + dReal a1hi = lz1; + dReal a2lo = -lz2 - k; + dReal a2hi = lz2 - k; + dReal lo = (a1lo > a2lo) ? a1lo : a2lo; + dReal hi = (a1hi < a2hi) ? a1hi : a2hi; + if (lo <= hi) { + int num_contacts = flags & NUMC_MASK; + if (num_contacts >= 2 && lo < hi) { + // generate up to two contacts. if one of those contacts is + // not made, fall back on the one-contact strategy. + for (i=0; i<3; i++) sphere1[i] = pos1[i] + lo*axis1[i]; + for (i=0; i<3; i++) sphere2[i] = pos2[i] + (lo+k)*axis2[i]; + int n1 = dCollideSpheres (sphere1,cyl1->radius, + sphere2,cyl2->radius,contact); + if (n1) { + for (i=0; i<3; i++) sphere1[i] = pos1[i] + hi*axis1[i]; + for (i=0; i<3; i++) sphere2[i] = pos2[i] + (hi+k)*axis2[i]; + dContactGeom *c2 = CONTACT(contact,skip); + int n2 = dCollideSpheres (sphere1,cyl1->radius, + sphere2,cyl2->radius, c2); + if (n2) { + c2->g1 = o1; + c2->g2 = o2; + c2->side1 = -1; + c2->side2 = -1; + return 2; + } + } + } + + // just one contact to generate, so put it in the middle of + // the range + dReal alpha1 = (lo + hi) * REAL(0.5); + dReal alpha2 = alpha1 + k; + for (i=0; i<3; i++) sphere1[i] = pos1[i] + alpha1*axis1[i]; + for (i=0; i<3; i++) sphere2[i] = pos2[i] + alpha2*axis2[i]; + return dCollideSpheres (sphere1,cyl1->radius, + sphere2,cyl2->radius,contact); + } + } + + // use the closest point algorithm + dVector3 a1,a2,b1,b2; + a1[0] = o1->final_posr->pos[0] + axis1[0]*lz1; + a1[1] = o1->final_posr->pos[1] + axis1[1]*lz1; + a1[2] = o1->final_posr->pos[2] + axis1[2]*lz1; + a2[0] = o1->final_posr->pos[0] - axis1[0]*lz1; + a2[1] = o1->final_posr->pos[1] - axis1[1]*lz1; + a2[2] = o1->final_posr->pos[2] - axis1[2]*lz1; + b1[0] = o2->final_posr->pos[0] + axis2[0]*lz2; + b1[1] = o2->final_posr->pos[1] + axis2[1]*lz2; + b1[2] = o2->final_posr->pos[2] + axis2[2]*lz2; + b2[0] = o2->final_posr->pos[0] - axis2[0]*lz2; + b2[1] = o2->final_posr->pos[1] - axis2[1]*lz2; + b2[2] = o2->final_posr->pos[2] - axis2[2]*lz2; + + dClosestLineSegmentPoints (a1,a2,b1,b2,sphere1,sphere2); + return dCollideSpheres (sphere1,cyl1->radius,sphere2,cyl2->radius,contact); +} + + +int dCollideCapsulePlane (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dCapsuleClass); + dIASSERT (o2->type == dPlaneClass); + dIASSERT ((flags & NUMC_MASK) >= 1); + + dxCapsule *ccyl = (dxCapsule*) o1; + dxPlane *plane = (dxPlane*) o2; + + // collide the deepest capping sphere with the plane + dReal sign = (dCalcVectorDot3_14 (plane->p,o1->final_posr->R+2) > 0) ? REAL(-1.0) : REAL(1.0); + dVector3 p; + p[0] = o1->final_posr->pos[0] + o1->final_posr->R[2] * ccyl->lz * REAL(0.5) * sign; + p[1] = o1->final_posr->pos[1] + o1->final_posr->R[6] * ccyl->lz * REAL(0.5) * sign; + p[2] = o1->final_posr->pos[2] + o1->final_posr->R[10] * ccyl->lz * REAL(0.5) * sign; + + dReal k = dCalcVectorDot3 (p,plane->p); + dReal depth = plane->p[3] - k + ccyl->radius; + if (depth < 0) return 0; + contact->normal[0] = plane->p[0]; + contact->normal[1] = plane->p[1]; + contact->normal[2] = plane->p[2]; + contact->pos[0] = p[0] - plane->p[0] * ccyl->radius; + contact->pos[1] = p[1] - plane->p[1] * ccyl->radius; + contact->pos[2] = p[2] - plane->p[2] * ccyl->radius; + contact->depth = depth; + + int ncontacts = 1; + if ((flags & NUMC_MASK) >= 2) { + // collide the other capping sphere with the plane + p[0] = o1->final_posr->pos[0] - o1->final_posr->R[2] * ccyl->lz * REAL(0.5) * sign; + p[1] = o1->final_posr->pos[1] - o1->final_posr->R[6] * ccyl->lz * REAL(0.5) * sign; + p[2] = o1->final_posr->pos[2] - o1->final_posr->R[10] * ccyl->lz * REAL(0.5) * sign; + + k = dCalcVectorDot3 (p,plane->p); + depth = plane->p[3] - k + ccyl->radius; + if (depth >= 0) { + dContactGeom *c2 = CONTACT(contact,skip); + c2->normal[0] = plane->p[0]; + c2->normal[1] = plane->p[1]; + c2->normal[2] = plane->p[2]; + c2->pos[0] = p[0] - plane->p[0] * ccyl->radius; + c2->pos[1] = p[1] - plane->p[1] * ccyl->radius; + c2->pos[2] = p[2] - plane->p[2] * ccyl->radius; + c2->depth = depth; + ncontacts = 2; + } + } + + for (int i=0; i < ncontacts; i++) { + dContactGeom *currContact = CONTACT(contact,i*skip); + currContact->g1 = o1; + currContact->g2 = o2; + currContact->side1 = -1; + currContact->side2 = -1; + } + return ncontacts; +} + diff --git a/libs/ode-0.16.1/ode/src/collision_convex_trimesh.cpp b/libs/ode-0.16.1/ode/src/collision_convex_trimesh.cpp new file mode 100644 index 0000000..651f236 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_convex_trimesh.cpp @@ -0,0 +1,120 @@ +/*************************************************************************
+ * *
+ * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. *
+ * All rights reserved. Email: russ@q12.org Web: www.q12.org *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of EITHER: *
+ * (1) The GNU Lesser General Public License as published by the Free *
+ * Software Foundation; either version 2.1 of the License, or (at *
+ * your option) any later version. The text of the GNU Lesser *
+ * General Public License is included with this library in the *
+ * file LICENSE.TXT. *
+ * (2) The BSD-style license that is included with this library in *
+ * the file LICENSE-BSD.TXT. *
+ * *
+ * This library 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 files *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
+ * *
+ *************************************************************************/
+
+#include <ode/collision.h>
+#include <ode/rotation.h>
+#include "config.h"
+#include "matrix.h"
+#include "odemath.h"
+
+
+typedef struct _sLocalContactData
+{
+ dVector3 vPos;
+ dVector3 vNormal;
+ dReal fDepth;
+ int triIndex;
+ int nFlags; // 0 = filtered out, 1 = OK
+}sLocalContactData;
+
+
+#if dTRIMESH_ENABLED
+
+#include "collision_util.h"
+#include "collision_std.h"
+#include "collision_trimesh_internal.h"
+#if dLIBCCD_ENABLED
+#include "collision_libccd.h"
+#endif
+
+int dCollideConvexTrimesh( dxGeom *o1, dxGeom *o2, int flags, dContactGeom* contacts, int skip )
+{
+ int contactcount = 0;
+ dIASSERT( skip >= (int)sizeof( dContactGeom ) );
+ dIASSERT( o1->type == dConvexClass );
+ dIASSERT( o2->type == dTriMeshClass );
+ dIASSERT ((flags & NUMC_MASK) >= 1);
+
+#if dLIBCCD_ENABLED
+
+#if dTRIMESH_OPCODE
+ const dVector3 &meshPosition = *(const dVector3 *)dGeomGetPosition(o2);
+ // Find convex OBB in trimesh coordinates
+ Point convexAABBMin(o1->aabb[0] - meshPosition[0], o1->aabb[2] - meshPosition[1], o1->aabb[4] - meshPosition[2]);
+ Point convexAABBMax(o1->aabb[1] - meshPosition[0], o1->aabb[3] - meshPosition[1], o1->aabb[5] - meshPosition[2]);
+
+ const Point convexCenter = 0.5f * (convexAABBMax + convexAABBMin);
+ const Point convexExtents = 0.5f * (convexAABBMax - convexAABBMin);
+ const Matrix3x3 convexRotation(1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f);
+ OBB convexOOB(convexCenter, convexExtents, convexRotation);
+
+ Matrix4x4 meshTransformation;
+ const dMatrix3 &meshRotation = *(const dMatrix3 *)dGeomGetRotation(o2);
+ const dVector3 zeroVector = { REAL(0.0), };
+ MakeMatrix(zeroVector, meshRotation, meshTransformation);
+
+ OBBCollider collider;
+ collider.SetFirstContact(false);
+ collider.SetTemporalCoherence(false);
+ collider.SetPrimitiveTests(false);
+
+ OBBCache cache;
+ dxTriMesh *trimesh = (dxTriMesh *)o2;
+ if (collider.Collide(cache, convexOOB, trimesh->retrieveMeshBVTreeRef(), null, &meshTransformation)) {
+ int triCount = collider.GetNbTouchedPrimitives();
+ if (triCount > 0) {
+ int* triangles = (int*)collider.GetTouchedPrimitives();
+ contactcount = dCollideConvexTrimeshTrianglesCCD(o1, o2, triangles, triCount, flags, contacts, skip);
+ }
+ }
+
+#elif dTRIMESH_GIMPACT
+ dxTriMesh *trimesh = (dxTriMesh *)o2;
+
+ aabb3f test_aabb(o1->aabb[0], o1->aabb[1], o1->aabb[2], o1->aabb[3], o1->aabb[4], o1->aabb[5]);
+
+ GDYNAMIC_ARRAY collision_result;
+ GIM_CREATE_BOXQUERY_LIST(collision_result);
+
+ gim_aabbset_box_collision(&test_aabb, &trimesh->m_collision_trimesh.m_aabbset, &collision_result);
+
+ if (collision_result.m_size != 0)
+ {
+ GUINT32 * boxesresult = GIM_DYNARRAY_POINTER(GUINT32,collision_result);
+ GIM_TRIMESH * ptrimesh = &trimesh->m_collision_trimesh;
+ gim_trimesh_locks_work_data(ptrimesh);
+
+ contactcount = dCollideConvexTrimeshTrianglesCCD(o1, o2, (int *)boxesresult, collision_result.m_size, flags, contacts, skip);
+
+ gim_trimesh_unlocks_work_data(ptrimesh);
+ }
+
+ GIM_DYNARRAY_DESTROY(collision_result);
+#endif // dTRIMESH_GIMPACT
+
+#endif // dLIBCCD_ENABLED
+
+ return contactcount;
+}
+
+#endif // dTRIMESH_ENABLED
+
diff --git a/libs/ode-0.16.1/ode/src/collision_cylinder_box.cpp b/libs/ode-0.16.1/ode/src/collision_cylinder_box.cpp new file mode 100644 index 0000000..4eaf92d --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_cylinder_box.cpp @@ -0,0 +1,1038 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * Cylinder-box collider by Alen Ladavac + * Ported to ODE by Nguyen Binh + */ + +#include <ode/collision.h> +#include <ode/rotation.h> +#include "config.h" +#include "matrix.h" +#include "odemath.h" +#include "collision_util.h" + +static const int MAX_CYLBOX_CLIP_POINTS = 16; +static const int nCYLINDER_AXIS = 2; +// Number of segment of cylinder base circle. +// Must be divisible by 4. +static const int nCYLINDER_SEGMENT = 8; + +#define MAX_FLOAT dInfinity + +// Data that passed through the collider's functions +struct sCylinderBoxData +{ + sCylinderBoxData(dxGeom *Cylinder, dxGeom *Box, int flags, dContactGeom *contact, int skip): + m_gBox(Box), m_gCylinder(Cylinder), m_gContact(contact), m_iFlags(flags), m_iSkip(skip), m_nContacts(0) + { + } + + void _cldInitCylinderBox(); + int _cldTestAxis( dVector3& vInputNormal, int iAxis ); + int _cldTestEdgeCircleAxis( const dVector3 &vCenterPoint, + const dVector3 &vVx0, const dVector3 &vVx1, int iAxis ); + int _cldTestSeparatingAxes(); + int _cldClipCylinderToBox(); + void _cldClipBoxToCylinder(); + int PerformCollisionChecking(); + + // cylinder parameters + dMatrix3 m_mCylinderRot; + dVector3 m_vCylinderPos; + dVector3 m_vCylinderAxis; + dReal m_fCylinderRadius; + dReal m_fCylinderSize; + dVector3 m_avCylinderNormals[nCYLINDER_SEGMENT]; + + // box parameters + + dMatrix3 m_mBoxRot; + dVector3 m_vBoxPos; + dVector3 m_vBoxHalfSize; + // box vertices array : 8 vertices + dVector3 m_avBoxVertices[8]; + + // global collider data + dVector3 m_vDiff; + dVector3 m_vNormal; + dReal m_fBestDepth; + dReal m_fBestrb; + dReal m_fBestrc; + int m_iBestAxis; + + // contact data + dVector3 m_vEp0, m_vEp1; + dReal m_fDepth0, m_fDepth1; + + // ODE stuff + dGeomID m_gBox; + dGeomID m_gCylinder; + dContactGeom* m_gContact; + int m_iFlags; + int m_iSkip; + int m_nContacts; + +}; + + +// initialize collision data +void sCylinderBoxData::_cldInitCylinderBox() +{ + // get cylinder position, orientation + const dReal* pRotCyc = dGeomGetRotation(m_gCylinder); + dMatrix3Copy(pRotCyc,m_mCylinderRot); + + const dVector3* pPosCyc = (const dVector3*)dGeomGetPosition(m_gCylinder); + dVector3Copy(*pPosCyc,m_vCylinderPos); + + dMat3GetCol(m_mCylinderRot,nCYLINDER_AXIS,m_vCylinderAxis); + + // get cylinder radius and size + dGeomCylinderGetParams(m_gCylinder,&m_fCylinderRadius,&m_fCylinderSize); + + // get box position, orientation, size + const dReal* pRotBox = dGeomGetRotation(m_gBox); + dMatrix3Copy(pRotBox,m_mBoxRot); + const dVector3* pPosBox = (const dVector3*)dGeomGetPosition(m_gBox); + dVector3Copy(*pPosBox,m_vBoxPos); + + dGeomBoxGetLengths(m_gBox, m_vBoxHalfSize); + m_vBoxHalfSize[0] *= REAL(0.5); + m_vBoxHalfSize[1] *= REAL(0.5); + m_vBoxHalfSize[2] *= REAL(0.5); + + // vertex 0 + m_avBoxVertices[0][0] = -m_vBoxHalfSize[0]; + m_avBoxVertices[0][1] = m_vBoxHalfSize[1]; + m_avBoxVertices[0][2] = -m_vBoxHalfSize[2]; + + // vertex 1 + m_avBoxVertices[1][0] = m_vBoxHalfSize[0]; + m_avBoxVertices[1][1] = m_vBoxHalfSize[1]; + m_avBoxVertices[1][2] = -m_vBoxHalfSize[2]; + + // vertex 2 + m_avBoxVertices[2][0] = -m_vBoxHalfSize[0]; + m_avBoxVertices[2][1] = -m_vBoxHalfSize[1]; + m_avBoxVertices[2][2] = -m_vBoxHalfSize[2]; + + // vertex 3 + m_avBoxVertices[3][0] = m_vBoxHalfSize[0]; + m_avBoxVertices[3][1] = -m_vBoxHalfSize[1]; + m_avBoxVertices[3][2] = -m_vBoxHalfSize[2]; + + // vertex 4 + m_avBoxVertices[4][0] = m_vBoxHalfSize[0]; + m_avBoxVertices[4][1] = m_vBoxHalfSize[1]; + m_avBoxVertices[4][2] = m_vBoxHalfSize[2]; + + // vertex 5 + m_avBoxVertices[5][0] = m_vBoxHalfSize[0]; + m_avBoxVertices[5][1] = -m_vBoxHalfSize[1]; + m_avBoxVertices[5][2] = m_vBoxHalfSize[2]; + + // vertex 6 + m_avBoxVertices[6][0] = -m_vBoxHalfSize[0]; + m_avBoxVertices[6][1] = -m_vBoxHalfSize[1]; + m_avBoxVertices[6][2] = m_vBoxHalfSize[2]; + + // vertex 7 + m_avBoxVertices[7][0] = -m_vBoxHalfSize[0]; + m_avBoxVertices[7][1] = m_vBoxHalfSize[1]; + m_avBoxVertices[7][2] = m_vBoxHalfSize[2]; + + // temp index + int i = 0; + dVector3 vTempBoxVertices[8]; + // transform vertices in absolute space + for(i=0; i < 8; i++) + { + dMultiplyMat3Vec3(m_mBoxRot,m_avBoxVertices[i], vTempBoxVertices[i]); + dVector3Add(vTempBoxVertices[i], m_vBoxPos, m_avBoxVertices[i]); + } + + // find relative position + dVector3Subtract(m_vCylinderPos,m_vBoxPos,m_vDiff); + m_fBestDepth = MAX_FLOAT; + m_vNormal[0] = REAL(0.0); + m_vNormal[1] = REAL(0.0); + m_vNormal[2] = REAL(0.0); + + // calculate basic angle for nCYLINDER_SEGMENT-gon + dReal fAngle = (dReal) (M_PI/nCYLINDER_SEGMENT); + + // calculate angle increment + dReal fAngleIncrement = fAngle * REAL(2.0); + + // calculate nCYLINDER_SEGMENT-gon points + for(i = 0; i < nCYLINDER_SEGMENT; i++) + { + m_avCylinderNormals[i][0] = -dCos(fAngle); + m_avCylinderNormals[i][1] = -dSin(fAngle); + m_avCylinderNormals[i][2] = 0; + + fAngle += fAngleIncrement; + } + + m_fBestrb = 0; + m_fBestrc = 0; + m_iBestAxis = 0; + m_nContacts = 0; + +} + +// test for given separating axis +int sCylinderBoxData::_cldTestAxis( dVector3& vInputNormal, int iAxis ) +{ + // check length of input normal + dReal fL = dVector3Length(vInputNormal); + // if not long enough + if ( fL < REAL(1e-5) ) + { + // do nothing + return 1; + } + + // otherwise make it unit for sure + dNormalize3(vInputNormal); + + // project box and Cylinder on mAxis + dReal fdot1 = dVector3Dot(m_vCylinderAxis, vInputNormal); + + dReal frc; + + if (fdot1 > REAL(1.0)) + { + // assume fdot1 = 1 + frc = m_fCylinderSize*REAL(0.5); + } + else if (fdot1 < REAL(-1.0)) + { + // assume fdot1 = -1 + frc = m_fCylinderSize*REAL(0.5); + } + else + { + // project box and capsule on iAxis + frc = dFabs( fdot1 * (m_fCylinderSize*REAL(0.5))) + m_fCylinderRadius * dSqrt(REAL(1.0)-(fdot1*fdot1)); + } + + dVector3 vTemp1; + + dMat3GetCol(m_mBoxRot,0,vTemp1); + dReal frb = dFabs(dVector3Dot(vTemp1,vInputNormal))*m_vBoxHalfSize[0]; + + dMat3GetCol(m_mBoxRot,1,vTemp1); + frb += dFabs(dVector3Dot(vTemp1,vInputNormal))*m_vBoxHalfSize[1]; + + dMat3GetCol(m_mBoxRot,2,vTemp1); + frb += dFabs(dVector3Dot(vTemp1,vInputNormal))*m_vBoxHalfSize[2]; + + // project their distance on separating axis + dReal fd = dVector3Dot(m_vDiff,vInputNormal); + + // get depth + + dReal fDepth = frc + frb; // Calculate partial depth + + // if they do not overlap exit, we have no intersection + if ( dFabs(fd) > fDepth ) + { + return 0; + } + + // Finalyze the depth calculation + fDepth -= dFabs(fd); + + // get maximum depth + if ( fDepth < m_fBestDepth ) + { + m_fBestDepth = fDepth; + dVector3Copy(vInputNormal,m_vNormal); + m_iBestAxis = iAxis; + m_fBestrb = frb; + m_fBestrc = frc; + + // flip normal if interval is wrong faced + if (fd > 0) + { + dVector3Inv(m_vNormal); + } + } + + return 1; +} + + +// check for separation between box edge and cylinder circle edge +int sCylinderBoxData::_cldTestEdgeCircleAxis( + const dVector3 &vCenterPoint, + const dVector3 &vVx0, const dVector3 &vVx1, + int iAxis ) +{ + // calculate direction of edge + dVector3 vDirEdge; + dVector3Subtract(vVx1,vVx0,vDirEdge); + dNormalize3(vDirEdge); + // starting point of edge + dVector3 vEStart; + dVector3Copy(vVx0,vEStart);; + + // calculate angle cosine between cylinder axis and edge + dReal fdot2 = dVector3Dot (vDirEdge,m_vCylinderAxis); + + // if edge is perpendicular to cylinder axis + if(dFabs(fdot2) < REAL(1e-5)) + { + // this can't be separating axis, because edge is parallel to circle plane + return 1; + } + + // find point of intersection between edge line and circle plane + dVector3 vTemp1; + dVector3Subtract(vCenterPoint,vEStart,vTemp1); + dReal fdot1 = dVector3Dot(vTemp1,m_vCylinderAxis); + dVector3 vpnt; + vpnt[0]= vEStart[0] + vDirEdge[0] * (fdot1/fdot2); + vpnt[1]= vEStart[1] + vDirEdge[1] * (fdot1/fdot2); + vpnt[2]= vEStart[2] + vDirEdge[2] * (fdot1/fdot2); + + // find tangent vector on circle with same center (vCenterPoint) that + // touches point of intersection (vpnt) + dVector3 vTangent; + dVector3Subtract(vCenterPoint,vpnt,vTemp1); + dVector3Cross(vTemp1,m_vCylinderAxis,vTangent); + + // find vector orthogonal both to tangent and edge direction + dVector3 vAxis; + dVector3Cross(vTangent,vDirEdge,vAxis); + + // use that vector as separating axis + return _cldTestAxis( vAxis, iAxis ); +} + +// Test separating axis for collision +int sCylinderBoxData::_cldTestSeparatingAxes() +{ + // reset best axis + m_fBestDepth = MAX_FLOAT; + m_iBestAxis = 0; + m_fBestrb = 0; + m_fBestrc = 0; + m_nContacts = 0; + + dVector3 vAxis = {REAL(0.0),REAL(0.0),REAL(0.0),REAL(0.0)}; + + // Epsilon value for checking axis vector length + const dReal fEpsilon = REAL(1e-6); + + // axis A0 + dMat3GetCol(m_mBoxRot, 0 , vAxis); + if (!_cldTestAxis( vAxis, 1 )) + { + return 0; + } + + // axis A1 + dMat3GetCol(m_mBoxRot, 1 , vAxis); + if (!_cldTestAxis( vAxis, 2 )) + { + return 0; + } + + // axis A2 + dMat3GetCol(m_mBoxRot, 2 , vAxis); + if (!_cldTestAxis( vAxis, 3 )) + { + return 0; + } + + // axis C - Cylinder Axis + //vAxis = vCylinderAxis; + dVector3Copy(m_vCylinderAxis , vAxis); + if (!_cldTestAxis( vAxis, 4 )) + { + return 0; + } + + // axis CxA0 + //vAxis = ( vCylinderAxis cross mthGetColM33f( mBoxRot, 0 )); + dVector3CrossMat3Col(m_mBoxRot, 0 ,m_vCylinderAxis, vAxis); + if(dVector3LengthSquare( vAxis ) > fEpsilon ) + { + if (!_cldTestAxis( vAxis, 5 )) + { + return 0; + } + } + + // axis CxA1 + //vAxis = ( vCylinderAxis cross mthGetColM33f( mBoxRot, 1 )); + dVector3CrossMat3Col(m_mBoxRot, 1 ,m_vCylinderAxis, vAxis); + if(dVector3LengthSquare( vAxis ) > fEpsilon ) + { + if (!_cldTestAxis( vAxis, 6 )) + { + return 0; + } + } + + // axis CxA2 + //vAxis = ( vCylinderAxis cross mthGetColM33f( mBoxRot, 2 )); + dVector3CrossMat3Col(m_mBoxRot, 2 ,m_vCylinderAxis, vAxis); + if(dVector3LengthSquare( vAxis ) > fEpsilon ) + { + if (!_cldTestAxis( vAxis, 7 )) + { + return 0; + } + } + + int i = 0; + dVector3 vTemp1; + dVector3 vTemp2; + // here we check box's vertices axis + for(i=0; i< 8; i++) + { + //vAxis = ( vCylinderAxis cross (m_avBoxVertices[i] - vCylinderPos)); + dVector3Subtract(m_avBoxVertices[i],m_vCylinderPos,vTemp1); + dVector3Cross(m_vCylinderAxis,vTemp1,vTemp2); + //vAxis = ( vCylinderAxis cross vAxis ); + dVector3Cross(m_vCylinderAxis,vTemp2,vAxis); + if(dVector3LengthSquare( vAxis ) > fEpsilon ) + { + if (!_cldTestAxis( vAxis, 8 + i )) + { + return 0; + } + } + } + + // ************************************ + // this is defined for first 12 axes + // normal of plane that contains top circle of cylinder + // center of top circle of cylinder + dVector3 vcc; + vcc[0] = (m_vCylinderPos)[0] + m_vCylinderAxis[0]*(m_fCylinderSize*REAL(0.5)); + vcc[1] = (m_vCylinderPos)[1] + m_vCylinderAxis[1]*(m_fCylinderSize*REAL(0.5)); + vcc[2] = (m_vCylinderPos)[2] + m_vCylinderAxis[2]*(m_fCylinderSize*REAL(0.5)); + // ************************************ + + if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[1], m_avBoxVertices[0], 16)) + { + return 0; + } + + if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[1], m_avBoxVertices[3], 17)) + { + return 0; + } + + if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[2], m_avBoxVertices[3], 18)) + { + return 0; + } + + if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[2], m_avBoxVertices[0], 19)) + { + return 0; + } + + + if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[4], m_avBoxVertices[1], 20)) + { + return 0; + } + + if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[4], m_avBoxVertices[7], 21)) + { + return 0; + } + + if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[0], m_avBoxVertices[7], 22)) + { + return 0; + } + + if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[5], m_avBoxVertices[3], 23)) + { + return 0; + } + + if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[5], m_avBoxVertices[6], 24)) + { + return 0; + } + + if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[2], m_avBoxVertices[6], 25)) + { + return 0; + } + + if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[4], m_avBoxVertices[5], 26)) + { + return 0; + } + + if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[6], m_avBoxVertices[7], 27)) + { + return 0; + } + + // ************************************ + // this is defined for second 12 axes + // normal of plane that contains bottom circle of cylinder + // center of bottom circle of cylinder + // vcc = vCylinderPos - vCylinderAxis*(fCylinderSize*REAL(0.5)); + vcc[0] = (m_vCylinderPos)[0] - m_vCylinderAxis[0]*(m_fCylinderSize*REAL(0.5)); + vcc[1] = (m_vCylinderPos)[1] - m_vCylinderAxis[1]*(m_fCylinderSize*REAL(0.5)); + vcc[2] = (m_vCylinderPos)[2] - m_vCylinderAxis[2]*(m_fCylinderSize*REAL(0.5)); + // ************************************ + + if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[1], m_avBoxVertices[0], 28)) + { + return 0; + } + + if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[1], m_avBoxVertices[3], 29)) + { + return 0; + } + + if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[2], m_avBoxVertices[3], 30)) + { + return 0; + } + + if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[2], m_avBoxVertices[0], 31)) + { + return 0; + } + + if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[4], m_avBoxVertices[1], 32)) + { + return 0; + } + + if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[4], m_avBoxVertices[7], 33)) + { + return 0; + } + + if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[0], m_avBoxVertices[7], 34)) + { + return 0; + } + + if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[5], m_avBoxVertices[3], 35)) + { + return 0; + } + + if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[5], m_avBoxVertices[6], 36)) + { + return 0; + } + + if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[2], m_avBoxVertices[6], 37)) + { + return 0; + } + + if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[4], m_avBoxVertices[5], 38)) + { + return 0; + } + + if (!_cldTestEdgeCircleAxis( vcc, m_avBoxVertices[6], m_avBoxVertices[7], 39)) + { + return 0; + } + + return 1; +} + +int sCylinderBoxData::_cldClipCylinderToBox() +{ + dIASSERT(m_nContacts != (m_iFlags & NUMC_MASK)); + + // calculate that vector perpendicular to cylinder axis which closes lowest angle with collision normal + dVector3 vN; + dReal fTemp1 = dVector3Dot(m_vCylinderAxis,m_vNormal); + vN[0] = m_vNormal[0] - m_vCylinderAxis[0]*fTemp1; + vN[1] = m_vNormal[1] - m_vCylinderAxis[1]*fTemp1; + vN[2] = m_vNormal[2] - m_vCylinderAxis[2]*fTemp1; + + // normalize that vector + dNormalize3(vN); + + // translate cylinder end points by the vector + dVector3 vCposTrans; + vCposTrans[0] = m_vCylinderPos[0] + vN[0] * m_fCylinderRadius; + vCposTrans[1] = m_vCylinderPos[1] + vN[1] * m_fCylinderRadius; + vCposTrans[2] = m_vCylinderPos[2] + vN[2] * m_fCylinderRadius; + + m_vEp0[0] = vCposTrans[0] + m_vCylinderAxis[0]*(m_fCylinderSize*REAL(0.5)); + m_vEp0[1] = vCposTrans[1] + m_vCylinderAxis[1]*(m_fCylinderSize*REAL(0.5)); + m_vEp0[2] = vCposTrans[2] + m_vCylinderAxis[2]*(m_fCylinderSize*REAL(0.5)); + + m_vEp1[0] = vCposTrans[0] - m_vCylinderAxis[0]*(m_fCylinderSize*REAL(0.5)); + m_vEp1[1] = vCposTrans[1] - m_vCylinderAxis[1]*(m_fCylinderSize*REAL(0.5)); + m_vEp1[2] = vCposTrans[2] - m_vCylinderAxis[2]*(m_fCylinderSize*REAL(0.5)); + + // transform edge points in box space + m_vEp0[0] -= m_vBoxPos[0]; + m_vEp0[1] -= m_vBoxPos[1]; + m_vEp0[2] -= m_vBoxPos[2]; + + m_vEp1[0] -= m_vBoxPos[0]; + m_vEp1[1] -= m_vBoxPos[1]; + m_vEp1[2] -= m_vBoxPos[2]; + + dVector3 vTemp1; + // clip the edge to box + dVector4 plPlane; + // plane 0 +x + dMat3GetCol(m_mBoxRot,0,vTemp1); + dConstructPlane(vTemp1,m_vBoxHalfSize[0],plPlane); + if(!dClipEdgeToPlane( m_vEp0, m_vEp1, plPlane )) + { + return 0; + } + + // plane 1 +y + dMat3GetCol(m_mBoxRot,1,vTemp1); + dConstructPlane(vTemp1,m_vBoxHalfSize[1],plPlane); + if(!dClipEdgeToPlane( m_vEp0, m_vEp1, plPlane )) + { + return 0; + } + + // plane 2 +z + dMat3GetCol(m_mBoxRot,2,vTemp1); + dConstructPlane(vTemp1,m_vBoxHalfSize[2],plPlane); + if(!dClipEdgeToPlane( m_vEp0, m_vEp1, plPlane )) + { + return 0; + } + + // plane 3 -x + dMat3GetCol(m_mBoxRot,0,vTemp1); + dVector3Inv(vTemp1); + dConstructPlane(vTemp1,m_vBoxHalfSize[0],plPlane); + if(!dClipEdgeToPlane( m_vEp0, m_vEp1, plPlane )) + { + return 0; + } + + // plane 4 -y + dMat3GetCol(m_mBoxRot,1,vTemp1); + dVector3Inv(vTemp1); + dConstructPlane(vTemp1,m_vBoxHalfSize[1],plPlane); + if(!dClipEdgeToPlane( m_vEp0, m_vEp1, plPlane )) + { + return 0; + } + + // plane 5 -z + dMat3GetCol(m_mBoxRot,2,vTemp1); + dVector3Inv(vTemp1); + dConstructPlane(vTemp1,m_vBoxHalfSize[2],plPlane); + if(!dClipEdgeToPlane( m_vEp0, m_vEp1, plPlane )) + { + return 0; + } + + // calculate depths for both contact points + m_fDepth0 = m_fBestrb + dVector3Dot(m_vEp0, m_vNormal); + m_fDepth1 = m_fBestrb + dVector3Dot(m_vEp1, m_vNormal); + + // clamp depths to 0 + if(m_fDepth0<0) + { + m_fDepth0 = REAL(0.0); + } + + if(m_fDepth1<0) + { + m_fDepth1 = REAL(0.0); + } + + // back transform edge points from box to absolute space + m_vEp0[0] += m_vBoxPos[0]; + m_vEp0[1] += m_vBoxPos[1]; + m_vEp0[2] += m_vBoxPos[2]; + + m_vEp1[0] += m_vBoxPos[0]; + m_vEp1[1] += m_vBoxPos[1]; + m_vEp1[2] += m_vBoxPos[2]; + + dContactGeom* Contact0 = SAFECONTACT(m_iFlags, m_gContact, m_nContacts, m_iSkip); + Contact0->depth = m_fDepth0; + dVector3Copy(m_vNormal,Contact0->normal); + dVector3Copy(m_vEp0,Contact0->pos); + Contact0->g1 = m_gCylinder; + Contact0->g2 = m_gBox; + Contact0->side1 = -1; + Contact0->side2 = -1; + dVector3Inv(Contact0->normal); + m_nContacts++; + + if (m_nContacts != (m_iFlags & NUMC_MASK)) + { + dContactGeom* Contact1 = SAFECONTACT(m_iFlags, m_gContact, m_nContacts, m_iSkip); + Contact1->depth = m_fDepth1; + dVector3Copy(m_vNormal,Contact1->normal); + dVector3Copy(m_vEp1,Contact1->pos); + Contact1->g1 = m_gCylinder; + Contact1->g2 = m_gBox; + Contact1->side1 = -1; + Contact1->side2 = -1; + dVector3Inv(Contact1->normal); + m_nContacts++; + } + + return 1; +} + + +void sCylinderBoxData::_cldClipBoxToCylinder() +{ + dIASSERT(m_nContacts != (m_iFlags & NUMC_MASK)); + + dVector3 vCylinderCirclePos, vCylinderCircleNormal_Rel; + // check which circle from cylinder we take for clipping + if ( dVector3Dot(m_vCylinderAxis, m_vNormal) > REAL(0.0) ) + { + // get top circle + vCylinderCirclePos[0] = m_vCylinderPos[0] + m_vCylinderAxis[0]*(m_fCylinderSize*REAL(0.5)); + vCylinderCirclePos[1] = m_vCylinderPos[1] + m_vCylinderAxis[1]*(m_fCylinderSize*REAL(0.5)); + vCylinderCirclePos[2] = m_vCylinderPos[2] + m_vCylinderAxis[2]*(m_fCylinderSize*REAL(0.5)); + + vCylinderCircleNormal_Rel[0] = REAL(0.0); + vCylinderCircleNormal_Rel[1] = REAL(0.0); + vCylinderCircleNormal_Rel[2] = REAL(0.0); + vCylinderCircleNormal_Rel[nCYLINDER_AXIS] = REAL(-1.0); + } + else + { + // get bottom circle + vCylinderCirclePos[0] = m_vCylinderPos[0] - m_vCylinderAxis[0]*(m_fCylinderSize*REAL(0.5)); + vCylinderCirclePos[1] = m_vCylinderPos[1] - m_vCylinderAxis[1]*(m_fCylinderSize*REAL(0.5)); + vCylinderCirclePos[2] = m_vCylinderPos[2] - m_vCylinderAxis[2]*(m_fCylinderSize*REAL(0.5)); + + vCylinderCircleNormal_Rel[0] = REAL(0.0); + vCylinderCircleNormal_Rel[1] = REAL(0.0); + vCylinderCircleNormal_Rel[2] = REAL(0.0); + vCylinderCircleNormal_Rel[nCYLINDER_AXIS] = REAL(1.0); + } + + // vNr is normal in Box frame, pointing from Cylinder to Box + dVector3 vNr; + dMatrix3 mBoxInv; + + // Find a way to use quaternion + dMatrix3Inv(m_mBoxRot,mBoxInv); + dMultiplyMat3Vec3(mBoxInv,m_vNormal,vNr); + + dVector3 vAbsNormal; + + vAbsNormal[0] = dFabs( vNr[0] ); + vAbsNormal[1] = dFabs( vNr[1] ); + vAbsNormal[2] = dFabs( vNr[2] ); + + // find which face in box is closest to cylinder + int iB0, iB1, iB2; + + // Different from Croteam's code + if (vAbsNormal[1] > vAbsNormal[0]) + { + // 1 > 0 + if (vAbsNormal[0]> vAbsNormal[2]) + { + // 0 > 2 -> 1 > 0 >2 + iB0 = 1; iB1 = 0; iB2 = 2; + } + else + { + // 2 > 0-> Must compare 1 and 2 + if (vAbsNormal[1] > vAbsNormal[2]) + { + // 1 > 2 -> 1 > 2 > 0 + iB0 = 1; iB1 = 2; iB2 = 0; + } + else + { + // 2 > 1 -> 2 > 1 > 0; + iB0 = 2; iB1 = 1; iB2 = 0; + } + } + } + else + { + // 0 > 1 + if (vAbsNormal[1] > vAbsNormal[2]) + { + // 1 > 2 -> 0 > 1 > 2 + iB0 = 0; iB1 = 1; iB2 = 2; + } + else + { + // 2 > 1 -> Must compare 0 and 2 + if (vAbsNormal[0] > vAbsNormal[2]) + { + // 0 > 2 -> 0 > 2 > 1; + iB0 = 0; iB1 = 2; iB2 = 1; + } + else + { + // 2 > 0 -> 2 > 0 > 1; + iB0 = 2; iB1 = 0; iB2 = 1; + } + } + } + + dVector3 vCenter; + // find center of box polygon + dVector3 vTemp; + if (vNr[iB0] > 0) + { + dMat3GetCol(m_mBoxRot,iB0,vTemp); + vCenter[0] = m_vBoxPos[0] - m_vBoxHalfSize[iB0]*vTemp[0]; + vCenter[1] = m_vBoxPos[1] - m_vBoxHalfSize[iB0]*vTemp[1]; + vCenter[2] = m_vBoxPos[2] - m_vBoxHalfSize[iB0]*vTemp[2]; + } + else + { + dMat3GetCol(m_mBoxRot,iB0,vTemp); + vCenter[0] = m_vBoxPos[0] + m_vBoxHalfSize[iB0]*vTemp[0]; + vCenter[1] = m_vBoxPos[1] + m_vBoxHalfSize[iB0]*vTemp[1]; + vCenter[2] = m_vBoxPos[2] + m_vBoxHalfSize[iB0]*vTemp[2]; + } + + // find the vertices of box polygon + dVector3 avPoints[4]; + dVector3 avTempArray1[MAX_CYLBOX_CLIP_POINTS]; + dVector3 avTempArray2[MAX_CYLBOX_CLIP_POINTS]; + + int i=0; + for(i=0; i<MAX_CYLBOX_CLIP_POINTS; i++) + { + avTempArray1[i][0] = REAL(0.0); + avTempArray1[i][1] = REAL(0.0); + avTempArray1[i][2] = REAL(0.0); + + avTempArray2[i][0] = REAL(0.0); + avTempArray2[i][1] = REAL(0.0); + avTempArray2[i][2] = REAL(0.0); + } + + dVector3 vAxis1, vAxis2; + + dMat3GetCol(m_mBoxRot,iB1,vAxis1); + dMat3GetCol(m_mBoxRot,iB2,vAxis2); + + avPoints[0][0] = vCenter[0] + m_vBoxHalfSize[iB1] * vAxis1[0] - m_vBoxHalfSize[iB2] * vAxis2[0]; + avPoints[0][1] = vCenter[1] + m_vBoxHalfSize[iB1] * vAxis1[1] - m_vBoxHalfSize[iB2] * vAxis2[1]; + avPoints[0][2] = vCenter[2] + m_vBoxHalfSize[iB1] * vAxis1[2] - m_vBoxHalfSize[iB2] * vAxis2[2]; + + avPoints[1][0] = vCenter[0] - m_vBoxHalfSize[iB1] * vAxis1[0] - m_vBoxHalfSize[iB2] * vAxis2[0]; + avPoints[1][1] = vCenter[1] - m_vBoxHalfSize[iB1] * vAxis1[1] - m_vBoxHalfSize[iB2] * vAxis2[1]; + avPoints[1][2] = vCenter[2] - m_vBoxHalfSize[iB1] * vAxis1[2] - m_vBoxHalfSize[iB2] * vAxis2[2]; + + avPoints[2][0] = vCenter[0] - m_vBoxHalfSize[iB1] * vAxis1[0] + m_vBoxHalfSize[iB2] * vAxis2[0]; + avPoints[2][1] = vCenter[1] - m_vBoxHalfSize[iB1] * vAxis1[1] + m_vBoxHalfSize[iB2] * vAxis2[1]; + avPoints[2][2] = vCenter[2] - m_vBoxHalfSize[iB1] * vAxis1[2] + m_vBoxHalfSize[iB2] * vAxis2[2]; + + avPoints[3][0] = vCenter[0] + m_vBoxHalfSize[iB1] * vAxis1[0] + m_vBoxHalfSize[iB2] * vAxis2[0]; + avPoints[3][1] = vCenter[1] + m_vBoxHalfSize[iB1] * vAxis1[1] + m_vBoxHalfSize[iB2] * vAxis2[1]; + avPoints[3][2] = vCenter[2] + m_vBoxHalfSize[iB1] * vAxis1[2] + m_vBoxHalfSize[iB2] * vAxis2[2]; + + // transform box points to space of cylinder circle + dMatrix3 mCylinderInv; + dMatrix3Inv(m_mCylinderRot,mCylinderInv); + + for(i=0; i<4; i++) + { + dVector3Subtract(avPoints[i],vCylinderCirclePos,vTemp); + dMultiplyMat3Vec3(mCylinderInv,vTemp,avPoints[i]); + } + + int iTmpCounter1 = 0; + int iTmpCounter2 = 0; + dVector4 plPlane; + + // plane of cylinder that contains circle for intersection + dConstructPlane(vCylinderCircleNormal_Rel,REAL(0.0),plPlane); + dClipPolyToPlane(avPoints, 4, avTempArray1, iTmpCounter1, plPlane); + + + // Body of base circle of Cylinder + int nCircleSegment = 0; + for (nCircleSegment = 0; nCircleSegment < nCYLINDER_SEGMENT; nCircleSegment++) + { + dConstructPlane(m_avCylinderNormals[nCircleSegment],m_fCylinderRadius,plPlane); + + if (0 == (nCircleSegment % 2)) + { + dClipPolyToPlane( avTempArray1 , iTmpCounter1 , avTempArray2, iTmpCounter2, plPlane); + } + else + { + dClipPolyToPlane( avTempArray2, iTmpCounter2, avTempArray1 , iTmpCounter1 , plPlane ); + } + + dIASSERT( iTmpCounter1 >= 0 && iTmpCounter1 <= MAX_CYLBOX_CLIP_POINTS ); + dIASSERT( iTmpCounter2 >= 0 && iTmpCounter2 <= MAX_CYLBOX_CLIP_POINTS ); + } + + // back transform clipped points to absolute space + dReal ftmpdot; + dReal fTempDepth; + dVector3 vPoint; + + if (nCircleSegment % 2) + { + for( i=0; i<iTmpCounter2; i++) + { + dMultiply0_331(vPoint,m_mCylinderRot,avTempArray2[i]); + vPoint[0] += vCylinderCirclePos[0]; + vPoint[1] += vCylinderCirclePos[1]; + vPoint[2] += vCylinderCirclePos[2]; + + dVector3Subtract(vPoint,m_vCylinderPos,vTemp); + ftmpdot = dVector3Dot(vTemp, m_vNormal); + fTempDepth = m_fBestrc - ftmpdot; + // Depth must be positive + if (fTempDepth > REAL(0.0)) + { + // generate contacts + dContactGeom* Contact0 = SAFECONTACT(m_iFlags, m_gContact, m_nContacts, m_iSkip); + Contact0->depth = fTempDepth; + dVector3Copy(m_vNormal,Contact0->normal); + dVector3Copy(vPoint,Contact0->pos); + Contact0->g1 = m_gCylinder; + Contact0->g2 = m_gBox; + Contact0->side1 = -1; + Contact0->side2 = -1; + dVector3Inv(Contact0->normal); + m_nContacts++; + + if (m_nContacts == (m_iFlags & NUMC_MASK)) + { + break; + } + } + } + } + else + { + for( i=0; i<iTmpCounter1; i++) + { + dMultiply0_331(vPoint,m_mCylinderRot,avTempArray1[i]); + vPoint[0] += vCylinderCirclePos[0]; + vPoint[1] += vCylinderCirclePos[1]; + vPoint[2] += vCylinderCirclePos[2]; + + dVector3Subtract(vPoint,m_vCylinderPos,vTemp); + ftmpdot = dVector3Dot(vTemp, m_vNormal); + fTempDepth = m_fBestrc - ftmpdot; + // Depth must be positive + if (fTempDepth > REAL(0.0)) + { + // generate contacts + dContactGeom* Contact0 = SAFECONTACT(m_iFlags, m_gContact, m_nContacts, m_iSkip); + Contact0->depth = fTempDepth; + dVector3Copy(m_vNormal,Contact0->normal); + dVector3Copy(vPoint,Contact0->pos); + Contact0->g1 = m_gCylinder; + Contact0->g2 = m_gBox; + Contact0->side1 = -1; + Contact0->side2 = -1; + dVector3Inv(Contact0->normal); + m_nContacts++; + + if (m_nContacts == (m_iFlags & NUMC_MASK)) + { + break; + } + } + } + } +} + +int sCylinderBoxData::PerformCollisionChecking() +{ + // initialize collider + _cldInitCylinderBox(); + + // do intersection test and find best separating axis + if ( !_cldTestSeparatingAxes() ) + { + // if not found do nothing + return 0; + } + + // if best separation axis is not found + if ( m_iBestAxis == 0 ) + { + // this should not happen (we should already exit in that case) + dIASSERT(0); + // do nothing + return 0; + } + + dReal fdot = dVector3Dot(m_vNormal,m_vCylinderAxis); + // choose which clipping method are we going to apply + if (dFabs(fdot) < REAL(0.9) ) + { + // clip cylinder over box + if(!_cldClipCylinderToBox()) + { + return 0; + } + } + else + { + _cldClipBoxToCylinder(); + } + + return m_nContacts; +} + +// Cylinder - Box by CroTeam +// Ported by Nguyen Binh +int dCollideCylinderBox(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dCylinderClass); + dIASSERT (o2->type == dBoxClass); + dIASSERT ((flags & NUMC_MASK) >= 1); + + sCylinderBoxData cData(o1, o2, flags, contact, skip); + + return cData.PerformCollisionChecking(); +} + + diff --git a/libs/ode-0.16.1/ode/src/collision_cylinder_plane.cpp b/libs/ode-0.16.1/ode/src/collision_cylinder_plane.cpp new file mode 100644 index 0000000..67424ad --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_cylinder_plane.cpp @@ -0,0 +1,266 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + + +/* + * Cylinder-Plane collider by Christoph Beyer ( boernerb@web.de ) + * + * This testing basically comes down to testing the intersection + * of the cylinder caps (discs) with the plane. + * + */ + +#include <ode/collision.h> +#include <ode/rotation.h> +#include <ode/objects.h> +#include "config.h" +#include "matrix.h" +#include "odemath.h" +#include "collision_kernel.h" // for dxGeom +#include "collision_util.h" + + +int dCollideCylinderPlane(dxGeom *Cylinder, dxGeom *Plane, int flags, dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (Cylinder->type == dCylinderClass); + dIASSERT (Plane->type == dPlaneClass); + dIASSERT ((flags & NUMC_MASK) >= 1); + + int GeomCount = 0; // count of used contactgeoms + +#ifdef dSINGLE + const dReal toleranz = REAL(0.0001); +#endif +#ifdef dDOUBLE + const dReal toleranz = REAL(0.0000001); +#endif + + // Get the properties of the cylinder (length+radius) + dReal radius, length; + dGeomCylinderGetParams(Cylinder, &radius, &length); + dVector3 &cylpos = Cylinder->final_posr->pos; + // and the plane + dVector4 planevec; + dGeomPlaneGetParams(Plane, planevec); + dVector3 PlaneNormal = {planevec[0],planevec[1],planevec[2]}; + //dVector3 PlanePos = {planevec[0] * planevec[3],planevec[1] * planevec[3],planevec[2] * planevec[3]}; + + dVector3 G1Pos1, G1Pos2, vDir1; + vDir1[0] = Cylinder->final_posr->R[2]; + vDir1[1] = Cylinder->final_posr->R[6]; + vDir1[2] = Cylinder->final_posr->R[10]; + + dReal s; + s = length * REAL(0.5); + G1Pos2[0] = vDir1[0] * s + cylpos[0]; + G1Pos2[1] = vDir1[1] * s + cylpos[1]; + G1Pos2[2] = vDir1[2] * s + cylpos[2]; + + G1Pos1[0] = vDir1[0] * -s + cylpos[0]; + G1Pos1[1] = vDir1[1] * -s + cylpos[1]; + G1Pos1[2] = vDir1[2] * -s + cylpos[2]; + + dVector3 C; + + // parallel-check + s = vDir1[0] * PlaneNormal[0] + vDir1[1] * PlaneNormal[1] + vDir1[2] * PlaneNormal[2]; + if(s < 0) + s += REAL(1.0); // is ca. 0, if vDir1 and PlaneNormal are parallel + else + s -= REAL(1.0); // is ca. 0, if vDir1 and PlaneNormal are parallel + if(s < toleranz && s > (-toleranz)) + { + // discs are parallel to the plane + + // 1.compute if, and where contacts are + dVector3 P; + s = planevec[3] - dVector3Dot(planevec, G1Pos1); + dReal t; + t = planevec[3] - dVector3Dot(planevec, G1Pos2); + if(s >= t) // s == t does never happen, + { + if(s >= 0) + { + // 1. Disc + dVector3Copy(G1Pos1, P); + } + else + return GeomCount; // no contacts + } + else + { + if(t >= 0) + { + // 2. Disc + dVector3Copy(G1Pos2, P); + } + else + return GeomCount; // no contacts + } + + // 2. generate a coordinate-system on the disc + dVector3 V1, V2; + if(vDir1[0] < toleranz && vDir1[0] > (-toleranz)) + { + // not x-axis + V1[0] = vDir1[0] + REAL(1.0); // random value + V1[1] = vDir1[1]; + V1[2] = vDir1[2]; + } + else + { + // maybe x-axis + V1[0] = vDir1[0]; + V1[1] = vDir1[1] + REAL(1.0); // random value + V1[2] = vDir1[2]; + } + // V1 is now another direction than vDir1 + // Cross-product + dVector3Cross(V1, vDir1, V2); + // make unit V2 + t = dVector3Length(V2); + t = radius / t; + dVector3Scale(V2, t); + // cross again + dVector3Cross(V2, vDir1, V1); + // |V2| is 'radius' and vDir1 unit, so |V1| is 'radius' + // V1 = first axis + // V2 = second axis + + // 3. generate contactpoints + + // Potential contact 1 + dVector3Add(P, V1, contact->pos); + contact->depth = planevec[3] - dVector3Dot(planevec, contact->pos); + if(contact->depth > 0) + { + dVector3Copy(PlaneNormal, contact->normal); + contact->g1 = Cylinder; + contact->g2 = Plane; + contact->side1 = -1; + contact->side2 = -1; + GeomCount++; + if( GeomCount >= (flags & NUMC_MASK)) + return GeomCount; // enough contactgeoms + contact = (dContactGeom *)((char *)contact + skip); + } + + // Potential contact 2 + dVector3Subtract(P, V1, contact->pos); + contact->depth = planevec[3] - dVector3Dot(planevec, contact->pos); + if(contact->depth > 0) + { + dVector3Copy(PlaneNormal, contact->normal); + contact->g1 = Cylinder; + contact->g2 = Plane; + contact->side1 = -1; + contact->side2 = -1; + GeomCount++; + if( GeomCount >= (flags & NUMC_MASK)) + return GeomCount; // enough contactgeoms + contact = (dContactGeom *)((char *)contact + skip); + } + + // Potential contact 3 + dVector3Add(P, V2, contact->pos); + contact->depth = planevec[3] - dVector3Dot(planevec, contact->pos); + if(contact->depth > 0) + { + dVector3Copy(PlaneNormal, contact->normal); + contact->g1 = Cylinder; + contact->g2 = Plane; + contact->side1 = -1; + contact->side2 = -1; + GeomCount++; + if( GeomCount >= (flags & NUMC_MASK)) + return GeomCount; // enough contactgeoms + contact = (dContactGeom *)((char *)contact + skip); + } + + // Potential contact 4 + dVector3Subtract(P, V2, contact->pos); + contact->depth = planevec[3] - dVector3Dot(planevec, contact->pos); + if(contact->depth > 0) + { + dVector3Copy(PlaneNormal, contact->normal); + contact->g1 = Cylinder; + contact->g2 = Plane; + contact->side1 = -1; + contact->side2 = -1; + GeomCount++; + if( GeomCount >= (flags & NUMC_MASK)) + return GeomCount; // enough contactgeoms + contact = (dContactGeom *)((char *)contact + skip); + } + } + else + { + dReal t = dVector3Dot(PlaneNormal, vDir1); + C[0] = vDir1[0] * t - PlaneNormal[0]; + C[1] = vDir1[1] * t - PlaneNormal[1]; + C[2] = vDir1[2] * t - PlaneNormal[2]; + s = dVector3Length(C); + // move C onto the circle + s = radius / s; + dVector3Scale(C, s); + + // deepest point of disc 1 + dVector3Add(C, G1Pos1, contact->pos); + + // depth of the deepest point + contact->depth = planevec[3] - dVector3Dot(planevec, contact->pos); + if(contact->depth >= 0) + { + dVector3Copy(PlaneNormal, contact->normal); + contact->g1 = Cylinder; + contact->g2 = Plane; + contact->side1 = -1; + contact->side2 = -1; + GeomCount++; + if( GeomCount >= (flags & NUMC_MASK)) + return GeomCount; // enough contactgeoms + contact = (dContactGeom *)((char *)contact + skip); + } + + // C is still computed + + // deepest point of disc 2 + dVector3Add(C, G1Pos2, contact->pos); + + // depth of the deepest point + contact->depth = planevec[3] - planevec[0] * contact->pos[0] - planevec[1] * contact->pos[1] - planevec[2] * contact->pos[2]; + if(contact->depth >= 0) + { + dVector3Copy(PlaneNormal, contact->normal); + contact->g1 = Cylinder; + contact->g2 = Plane; + contact->side1 = -1; + contact->side2 = -1; + GeomCount++; + if( GeomCount >= (flags & NUMC_MASK)) + return GeomCount; // enough contactgeoms + contact = (dContactGeom *)((char *)contact + skip); + } + } + return GeomCount; +} diff --git a/libs/ode-0.16.1/ode/src/collision_cylinder_sphere.cpp b/libs/ode-0.16.1/ode/src/collision_cylinder_sphere.cpp new file mode 100644 index 0000000..4a5f6ec --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_cylinder_sphere.cpp @@ -0,0 +1,277 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + + +/******************************************************************* + * * + * cylinder-sphere collider by Christoph Beyer (boernerb@web.de) * + * * + * In Cylinder/Sphere-collisions, there are three possibilies: * + * 1. collision with the cylinder's nappe * + * 2. collision with one of the cylinder's disc * + * 3. collision with one of the disc's border * + * * + * This collider computes two distances (s, t) and based on them, * + * it decides, which collision we have. * + * This collider always generates 1 (or 0, if we have no collison) * + * contacts. * + * It is able to "separate" cylinder and sphere in all * + * configurations, but it never pays attention to velocity. * + * So, in extrem situations, "tunneling-effect" is possible. * + * * + *******************************************************************/ + +#include <ode/collision.h> +#include <ode/rotation.h> +#include <ode/objects.h> +#include "config.h" +#include "matrix.h" +#include "odemath.h" +#include "collision_kernel.h" // for dxGeom +#include "collision_util.h" + +int dCollideCylinderSphere(dxGeom* Cylinder, dxGeom* Sphere, + int flags, dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (Cylinder->type == dCylinderClass); + dIASSERT (Sphere->type == dSphereClass); + dIASSERT ((flags & NUMC_MASK) >= 1); + + //unsigned char* pContactData = (unsigned char*)contact; + int GeomCount = 0; // count of used contacts + +#ifdef dSINGLE + const dReal toleranz = REAL(0.0001); +#endif +#ifdef dDOUBLE + const dReal toleranz = REAL(0.0000001); +#endif + + // get the data from the geoms + dReal radius, length; + dGeomCylinderGetParams(Cylinder, &radius, &length); + dVector3 &cylpos = Cylinder->final_posr->pos; + //const dReal* pfRot1 = dGeomGetRotation(Cylinder); + + dReal radius2; + radius2 = dGeomSphereGetRadius(Sphere); + const dReal* SpherePos = dGeomGetPosition(Sphere); + + // G1Pos1 is the middle of the first disc + // G1Pos2 is the middle of the second disc + // vDir1 is the unit direction of the cylinderaxis + dVector3 G1Pos1, G1Pos2, vDir1; + vDir1[0] = Cylinder->final_posr->R[2]; + vDir1[1] = Cylinder->final_posr->R[6]; + vDir1[2] = Cylinder->final_posr->R[10]; + + dReal s; + s = length * REAL(0.5); // just a precomputed factor + G1Pos2[0] = vDir1[0] * s + cylpos[0]; + G1Pos2[1] = vDir1[1] * s + cylpos[1]; + G1Pos2[2] = vDir1[2] * s + cylpos[2]; + + G1Pos1[0] = vDir1[0] * -s + cylpos[0]; + G1Pos1[1] = vDir1[1] * -s + cylpos[1]; + G1Pos1[2] = vDir1[2] * -s + cylpos[2]; + + dVector3 C; + dReal t; + // Step 1: compute the two distances 's' and 't' + // 's' is the distance from the first disc (in vDir1-/Zylinderaxis-direction), the disc with G1Pos1 in the middle + s = (SpherePos[0] - G1Pos1[0]) * vDir1[0] - (G1Pos1[1] - SpherePos[1]) * vDir1[1] - (G1Pos1[2] - SpherePos[2]) * vDir1[2]; + if(s < (-radius2) || s > (length + radius2) ) + { + // Sphere is too far away from the discs + // no collision + return 0; + } + + // C is the direction from Sphere-middle to the cylinder-axis (vDir1); C is orthogonal to the cylinder-axis + C[0] = s * vDir1[0] + G1Pos1[0] - SpherePos[0]; + C[1] = s * vDir1[1] + G1Pos1[1] - SpherePos[1]; + C[2] = s * vDir1[2] + G1Pos1[2] - SpherePos[2]; + // t is the distance from the Sphere-middle to the cylinder-axis! + t = dVector3Length(C); + if(t > (radius + radius2) ) + { + // Sphere is too far away from the cylinder axis! + // no collision + return 0; + } + + // decide which kind of collision we have: + if(t > radius && (s < 0 || s > length) ) + { + // 3. collision + if(s <= 0) + { + contact->depth = radius2 - dSqrt( (s) * (s) + (t - radius) * (t - radius) ); + if(contact->depth < 0) + { + // no collision! + return 0; + } + contact->pos[0] = C[0] / t * -radius + G1Pos1[0]; + contact->pos[1] = C[1] / t * -radius + G1Pos1[1]; + contact->pos[2] = C[2] / t * -radius + G1Pos1[2]; + contact->normal[0] = (contact->pos[0] - SpherePos[0]) / (radius2 - contact->depth); + contact->normal[1] = (contact->pos[1] - SpherePos[1]) / (radius2 - contact->depth); + contact->normal[2] = (contact->pos[2] - SpherePos[2]) / (radius2 - contact->depth); + contact->g1 = Cylinder; + contact->g2 = Sphere; + contact->side1 = -1; + contact->side2 = -1; + GeomCount++; + return GeomCount; + } + else + { + // now s is bigger than length here! + contact->depth = radius2 - dSqrt( (s - length) * (s - length) + (t - radius) * (t - radius) ); + if(contact->depth < 0) + { + // no collision! + return 0; + } + contact->pos[0] = C[0] / t * -radius + G1Pos2[0]; + contact->pos[1] = C[1] / t * -radius + G1Pos2[1]; + contact->pos[2] = C[2] / t * -radius + G1Pos2[2]; + contact->normal[0] = (contact->pos[0] - SpherePos[0]) / (radius2 - contact->depth); + contact->normal[1] = (contact->pos[1] - SpherePos[1]) / (radius2 - contact->depth); + contact->normal[2] = (contact->pos[2] - SpherePos[2]) / (radius2 - contact->depth); + contact->g1 = Cylinder; + contact->g2 = Sphere; + contact->side1 = -1; + contact->side2 = -1; + GeomCount++; + return GeomCount; + } + } + else if( (radius - t) <= s && (radius - t) <= (length - s) ) + { + // 1. collsision + if(t > (radius2 + toleranz)) + { + // cylinder-axis is outside the sphere + contact->depth = (radius2 + radius) - t; + if(contact->depth < 0) + { + // should never happen, but just for safeness + return 0; + } + else + { + C[0] /= t; + C[1] /= t; + C[2] /= t; + contact->pos[0] = C[0] * radius2 + SpherePos[0]; + contact->pos[1] = C[1] * radius2 + SpherePos[1]; + contact->pos[2] = C[2] * radius2 + SpherePos[2]; + contact->normal[0] = C[0]; + contact->normal[1] = C[1]; + contact->normal[2] = C[2]; + contact->g1 = Cylinder; + contact->g2 = Sphere; + contact->side1 = -1; + contact->side2 = -1; + GeomCount++; + return GeomCount; + } + } + else + { + // cylinder-axis is outside of the sphere + contact->depth = (radius2 + radius) - t; + if(contact->depth < 0) + { + // should never happen, but just for safeness + return 0; + } + else + { + contact->pos[0] = C[0] + SpherePos[0]; + contact->pos[1] = C[1] + SpherePos[1]; + contact->pos[2] = C[2] + SpherePos[2]; + contact->normal[0] = C[0] / t; + contact->normal[1] = C[1] / t; + contact->normal[2] = C[2] / t; + contact->g1 = Cylinder; + contact->g2 = Sphere; + contact->side1 = -1; + contact->side2 = -1; + GeomCount++; + return GeomCount; + } + } + } + else + { + // 2. collision + if(s <= (length * REAL(0.5)) ) + { + // collsision with the first disc + contact->depth = s + radius2; + if(contact->depth < 0) + { + // should never happen, but just for safeness + return 0; + } + contact->pos[0] = radius2 * vDir1[0] + SpherePos[0]; + contact->pos[1] = radius2 * vDir1[1] + SpherePos[1]; + contact->pos[2] = radius2 * vDir1[2] + SpherePos[2]; + contact->normal[0] = vDir1[0]; + contact->normal[1] = vDir1[1]; + contact->normal[2] = vDir1[2]; + contact->g1 = Cylinder; + contact->g2 = Sphere; + contact->side1 = -1; + contact->side2 = -1; + GeomCount++; + return GeomCount; + } + else + { + // collsision with the second disc + contact->depth = (radius2 + length - s); + if(contact->depth < 0) + { + // should never happen, but just for safeness + return 0; + } + contact->pos[0] = radius2 * -vDir1[0] + SpherePos[0]; + contact->pos[1] = radius2 * -vDir1[1] + SpherePos[1]; + contact->pos[2] = radius2 * -vDir1[2] + SpherePos[2]; + contact->normal[0] = -vDir1[0]; + contact->normal[1] = -vDir1[1]; + contact->normal[2] = -vDir1[2]; + contact->g1 = Cylinder; + contact->g2 = Sphere; + contact->side1 = -1; + contact->side2 = -1; + GeomCount++; + return GeomCount; + } + } + return GeomCount; +} diff --git a/libs/ode-0.16.1/ode/src/collision_cylinder_trimesh.cpp b/libs/ode-0.16.1/ode/src/collision_cylinder_trimesh.cpp new file mode 100644 index 0000000..fd22e1a --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_cylinder_trimesh.cpp @@ -0,0 +1,1171 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * Cylinder-trimesh collider by Alen Ladavac + * Ported to ODE by Nguyen Binh + */ + + +#include <ode/collision.h> +#include <ode/rotation.h> +#include "config.h" +#include "matrix.h" +#include "odemath.h" +#include "collision_util.h" +#include "collision_trimesh_internal.h" +#include "util.h" + +#if dTRIMESH_ENABLED + +#define MAX_REAL dInfinity +static const int nCYLINDER_AXIS = 2; +static const int nCYLINDER_CIRCLE_SEGMENTS = 8; +static const int nMAX_CYLINDER_TRIANGLE_CLIP_POINTS = 12; + +#define OPTIMIZE_CONTACTS 1 + +// Local contacts data +typedef struct _sLocalContactData +{ + dVector3 vPos; + dVector3 vNormal; + dReal fDepth; + int triIndex; + int nFlags; // 0 = filtered out, 1 = OK +}sLocalContactData; + +struct sCylinderTrimeshColliderData +{ + sCylinderTrimeshColliderData(int flags, int skip): m_iFlags(flags), m_iSkip(skip), m_nContacts(0), m_gLocalContacts(NULL) {} + +#ifdef OPTIMIZE_CONTACTS + void _OptimizeLocalContacts(); +#endif + void _InitCylinderTrimeshData(dxGeom *Cylinder, dxTriMesh *Trimesh); + int _ProcessLocalContacts(dContactGeom *contact, dxGeom *Cylinder, dxTriMesh *Trimesh); + + bool _cldTestAxis(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2, + dVector3& vAxis, int iAxis, bool bNoFlip = false); + bool _cldTestCircleToEdgeAxis( + const dVector3 &v0, const dVector3 &v1, const dVector3 &v2, + const dVector3 &vCenterPoint, const dVector3 &vCylinderAxis1, + const dVector3 &vVx0, const dVector3 &vVx1, int iAxis); + bool _cldTestSeparatingAxes(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2); + bool _cldClipCylinderEdgeToTriangle(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2); + void _cldClipCylinderToTriangle(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2); + void TestOneTriangleVsCylinder(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2, + const bool bDoubleSided); + int TestCollisionForSingleTriangle(int ctContacts0, int Triint, dVector3 dv[3], + bool &bOutFinishSearching); + + // cylinder data + dMatrix3 m_mCylinderRot; + dQuaternion m_qCylinderRot; + dQuaternion m_qInvCylinderRot; + dVector3 m_vCylinderPos; + dVector3 m_vCylinderAxis; + dReal m_fCylinderRadius; + dReal m_fCylinderSize; + dVector3 m_avCylinderNormals[nCYLINDER_CIRCLE_SEGMENTS]; + + // mesh data + dQuaternion m_qTrimeshRot; + dQuaternion m_qInvTrimeshRot; + dMatrix3 m_mTrimeshRot; + dVector3 m_vTrimeshPos; + + // global collider data + dVector3 m_vBestPoint; + dReal m_fBestDepth; + dReal m_fBestCenter; + dReal m_fBestrt; + int m_iBestAxis; + dVector3 m_vContactNormal; + dVector3 m_vNormal; + dVector3 m_vE0; + dVector3 m_vE1; + dVector3 m_vE2; + + // ODE stuff + int m_iFlags; + int m_iSkip; + int m_nContacts;// = 0; + sLocalContactData* m_gLocalContacts; +}; + + +#ifdef OPTIMIZE_CONTACTS + +// Use to classify contacts to be "near" in position +static const dReal fSameContactPositionEpsilon = REAL(0.0001); // 1e-4 +// Use to classify contacts to be "near" in normal direction +static const dReal fSameContactNormalEpsilon = REAL(0.0001); // 1e-4 + +// If this two contact can be classified as "near" +inline int _IsNearContacts(sLocalContactData& c1,sLocalContactData& c2) +{ + int bPosNear = 0; + int bSameDir = 0; + dVector3 vDiff; + + // First check if they are "near" in position + dVector3Subtract(c1.vPos,c2.vPos,vDiff); + if ( (dFabs(vDiff[0]) < fSameContactPositionEpsilon) + &&(dFabs(vDiff[1]) < fSameContactPositionEpsilon) + &&(dFabs(vDiff[2]) < fSameContactPositionEpsilon)) + { + bPosNear = 1; + } + + // Second check if they are "near" in normal direction + dVector3Subtract(c1.vNormal,c2.vNormal,vDiff); + if ( (dFabs(vDiff[0]) < fSameContactNormalEpsilon) + &&(dFabs(vDiff[1]) < fSameContactNormalEpsilon) + &&(dFabs(vDiff[2]) < fSameContactNormalEpsilon) ) + { + bSameDir = 1; + } + + // Will be "near" if position and normal direction are "near" + return (bPosNear && bSameDir); +} + +inline int _IsBetter(sLocalContactData& c1,sLocalContactData& c2) +{ + // The not better will be throw away + // You can change the selection criteria here + return (c1.fDepth > c2.fDepth); +} + +// iterate through gLocalContacts and filtered out "near contact" +void sCylinderTrimeshColliderData::_OptimizeLocalContacts() +{ + int nContacts = m_nContacts; + + for (int i = 0; i < nContacts-1; i++) + { + for (int j = i+1; j < nContacts; j++) + { + if (_IsNearContacts(m_gLocalContacts[i],m_gLocalContacts[j])) + { + // If they are seem to be the same then filtered + // out the least penetrate one + if (_IsBetter(m_gLocalContacts[j],m_gLocalContacts[i])) + { + m_gLocalContacts[i].nFlags = 0; // filtered 1st contact + } + else + { + m_gLocalContacts[j].nFlags = 0; // filtered 2nd contact + } + + // NOTE + // There is other way is to add two depth together but + // it not work so well. Why??? + } + } + } +} +#endif // OPTIMIZE_CONTACTS + +int sCylinderTrimeshColliderData::_ProcessLocalContacts(dContactGeom *contact, + dxGeom *Cylinder, dxTriMesh *Trimesh) +{ +#ifdef OPTIMIZE_CONTACTS + if (m_nContacts > 1 && !(m_iFlags & CONTACTS_UNIMPORTANT)) + { + // Can be optimized... + _OptimizeLocalContacts(); + } +#endif + + int iContact = 0; + dContactGeom* Contact = 0; + + int nFinalContact = 0; + + for (iContact = 0; iContact < m_nContacts; iContact ++) + { + if (1 == m_gLocalContacts[iContact].nFlags) + { + Contact = SAFECONTACT(m_iFlags, contact, nFinalContact, m_iSkip); + Contact->depth = m_gLocalContacts[iContact].fDepth; + dVector3Copy(m_gLocalContacts[iContact].vNormal,Contact->normal); + dVector3Copy(m_gLocalContacts[iContact].vPos,Contact->pos); + Contact->g1 = Cylinder; + Contact->g2 = Trimesh; + Contact->side1 = -1; + Contact->side2 = m_gLocalContacts[iContact].triIndex; + dVector3Inv(Contact->normal); + + nFinalContact++; + } + } + // debug + //if (nFinalContact != m_nContacts) + //{ + // printf("[Info] %d contacts generated,%d filtered.\n",m_nContacts,m_nContacts-nFinalContact); + //} + + return nFinalContact; +} + + +bool sCylinderTrimeshColliderData::_cldTestAxis( + const dVector3 &v0, + const dVector3 &v1, + const dVector3 &v2, + dVector3& vAxis, + int iAxis, + bool bNoFlip/* = false*/) +{ + + // calculate length of separating axis vector + dReal fL = dVector3Length(vAxis); + // if not long enough + if ( fL < REAL(1e-5) ) + { + // do nothing + return true; + } + + // otherwise normalize it + vAxis[0] /= fL; + vAxis[1] /= fL; + vAxis[2] /= fL; + + dReal fdot1 = dVector3Dot(m_vCylinderAxis,vAxis); + // project capsule on vAxis + dReal frc; + + if (dFabs(fdot1) > REAL(1.0) ) + { + // fdot1 = REAL(1.0); + frc = dFabs(m_fCylinderSize* REAL(0.5)); + } + else + { + frc = dFabs((m_fCylinderSize* REAL(0.5)) * fdot1) + + m_fCylinderRadius * dSqrt(REAL(1.0)-(fdot1*fdot1)); + } + + dVector3 vV0; + dVector3Subtract(v0,m_vCylinderPos,vV0); + dVector3 vV1; + dVector3Subtract(v1,m_vCylinderPos,vV1); + dVector3 vV2; + dVector3Subtract(v2,m_vCylinderPos,vV2); + + // project triangle on vAxis + dReal afv[3]; + afv[0] = dVector3Dot( vV0 , vAxis ); + afv[1] = dVector3Dot( vV1 , vAxis ); + afv[2] = dVector3Dot( vV2 , vAxis ); + + dReal fMin = MAX_REAL; + dReal fMax = -MAX_REAL; + + // for each vertex + for(int i = 0; i < 3; i++) + { + // find minimum + if (afv[i]<fMin) + { + fMin = afv[i]; + } + // find maximum + if (afv[i]>fMax) + { + fMax = afv[i]; + } + } + + // find capsule's center of interval on axis + dReal fCenter = (fMin+fMax)* REAL(0.5); + // calculate triangles halfinterval + dReal fTriangleRadius = (fMax-fMin)*REAL(0.5); + + // if they do not overlap, + if( dFabs(fCenter) > (frc+fTriangleRadius) ) + { + // exit, we have no intersection + return false; + } + + // calculate depth + dReal fDepth = -(dFabs(fCenter) - (frc + fTriangleRadius ) ); + + // if greater then best found so far + if ( fDepth < m_fBestDepth ) + { + // remember depth + m_fBestDepth = fDepth; + m_fBestCenter = fCenter; + m_fBestrt = frc; + dVector3Copy(vAxis,m_vContactNormal); + m_iBestAxis = iAxis; + + // flip normal if interval is wrong faced + if ( fCenter< REAL(0.0) && !bNoFlip) + { + dVector3Inv(m_vContactNormal); + m_fBestCenter = -fCenter; + } + } + + return true; +} + +// intersection test between edge and circle +bool sCylinderTrimeshColliderData::_cldTestCircleToEdgeAxis( + const dVector3 &v0, const dVector3 &v1, const dVector3 &v2, + const dVector3 &vCenterPoint, const dVector3 &vCylinderAxis1, + const dVector3 &vVx0, const dVector3 &vVx1, int iAxis) +{ + // calculate direction of edge + dVector3 vkl; + dVector3Subtract( vVx1 , vVx0 , vkl); + dNormalize3(vkl); + // starting point of edge + dVector3 vol; + dVector3Copy(vVx0,vol); + + // calculate angle cosine between cylinder axis and edge + dReal fdot2 = dVector3Dot(vkl , vCylinderAxis1); + + // if edge is perpendicular to cylinder axis + if(dFabs(fdot2)<REAL(1e-5)) + { + // this can't be separating axis, because edge is parallel to circle plane + return true; + } + + // find point of intersection between edge line and circle plane + dVector3 vTemp; + dVector3Subtract(vCenterPoint,vol,vTemp); + dReal fdot1 = dVector3Dot(vTemp,vCylinderAxis1); + dVector3 vpnt;// = vol + vkl * (fdot1/fdot2); + vpnt[0] = vol[0] + vkl[0] * fdot1/fdot2; + vpnt[1] = vol[1] + vkl[1] * fdot1/fdot2; + vpnt[2] = vol[2] + vkl[2] * fdot1/fdot2; + + // find tangent vector on circle with same center (vCenterPoint) that touches point of intersection (vpnt) + dVector3 vTangent; + dVector3Subtract(vCenterPoint,vpnt,vTemp); + dVector3Cross(vTemp,vCylinderAxis1,vTangent); + + // find vector orthogonal both to tangent and edge direction + dVector3 vAxis; + dVector3Cross(vTangent,vkl,vAxis); + + // use that vector as separating axis + return _cldTestAxis( v0, v1, v2, vAxis, iAxis ); +} + +// helper for less key strokes +// r = ( (v1 - v2) cross v3 ) cross v3 +inline void _CalculateAxis(const dVector3& v1, + const dVector3& v2, + const dVector3& v3, + dVector3& r) +{ + dVector3 t1; + dVector3 t2; + + dVector3Subtract(v1,v2,t1); + dVector3Cross(t1,v3,t2); + dVector3Cross(t2,v3,r); +} + +bool sCylinderTrimeshColliderData::_cldTestSeparatingAxes( + const dVector3 &v0, + const dVector3 &v1, + const dVector3 &v2) +{ + + // calculate edge vectors + dVector3Subtract(v1 ,v0 , m_vE0); + // m_vE1 has been calculated before -> so save some cycles here + dVector3Subtract(v0 ,v2 , m_vE2); + + // calculate caps centers in absolute space + dVector3 vCp0; + vCp0[0] = m_vCylinderPos[0] + m_vCylinderAxis[0]*(m_fCylinderSize* REAL(0.5)); + vCp0[1] = m_vCylinderPos[1] + m_vCylinderAxis[1]*(m_fCylinderSize* REAL(0.5)); + vCp0[2] = m_vCylinderPos[2] + m_vCylinderAxis[2]*(m_fCylinderSize* REAL(0.5)); + +#if 0 + dVector3 vCp1; + vCp1[0] = m_vCylinderPos[0] - m_vCylinderAxis[0]*(m_fCylinderSize* REAL(0.5)); + vCp1[1] = m_vCylinderPos[1] - m_vCylinderAxis[1]*(m_fCylinderSize* REAL(0.5)); + vCp1[2] = m_vCylinderPos[2] - m_vCylinderAxis[2]*(m_fCylinderSize* REAL(0.5)); +#endif + + // reset best axis + m_iBestAxis = 0; + dVector3 vAxis; + + // axis m_vNormal + //vAxis = -m_vNormal; + vAxis[0] = -m_vNormal[0]; + vAxis[1] = -m_vNormal[1]; + vAxis[2] = -m_vNormal[2]; + if (!_cldTestAxis(v0, v1, v2, vAxis, 1, true)) + { + return false; + } + + // axis CxE0 + // vAxis = ( m_vCylinderAxis cross m_vE0 ); + dVector3Cross(m_vCylinderAxis, m_vE0,vAxis); + if (!_cldTestAxis(v0, v1, v2, vAxis, 2)) + { + return false; + } + + // axis CxE1 + // vAxis = ( m_vCylinderAxis cross m_vE1 ); + dVector3Cross(m_vCylinderAxis, m_vE1,vAxis); + if (!_cldTestAxis(v0, v1, v2, vAxis, 3)) + { + return false; + } + + // axis CxE2 + // vAxis = ( m_vCylinderAxis cross m_vE2 ); + dVector3Cross(m_vCylinderAxis, m_vE2,vAxis); + if (!_cldTestAxis(v0, v1, v2, vAxis, 4)) + { + return false; + } + + // first vertex on triangle + // axis ((V0-Cp0) x C) x C + //vAxis = ( ( v0-vCp0 ) cross m_vCylinderAxis ) cross m_vCylinderAxis; + _CalculateAxis(v0 , vCp0 , m_vCylinderAxis , vAxis); + if (!_cldTestAxis(v0, v1, v2, vAxis, 11)) + { + return false; + } + + // second vertex on triangle + // axis ((V1-Cp0) x C) x C + // vAxis = ( ( v1-vCp0 ) cross m_vCylinderAxis ) cross m_vCylinderAxis; + _CalculateAxis(v1 , vCp0 , m_vCylinderAxis , vAxis); + if (!_cldTestAxis(v0, v1, v2, vAxis, 12)) + { + return false; + } + + // third vertex on triangle + // axis ((V2-Cp0) x C) x C + //vAxis = ( ( v2-vCp0 ) cross m_vCylinderAxis ) cross m_vCylinderAxis; + _CalculateAxis(v2 , vCp0 , m_vCylinderAxis , vAxis); + if (!_cldTestAxis(v0, v1, v2, vAxis, 13)) + { + return false; + } + + // test cylinder axis + // vAxis = m_vCylinderAxis; + dVector3Copy(m_vCylinderAxis , vAxis); + if (!_cldTestAxis(v0, v1, v2, vAxis, 14)) + { + return false; + } + + // Test top and bottom circle ring of cylinder for separation + dVector3 vccATop; + vccATop[0] = m_vCylinderPos[0] + m_vCylinderAxis[0]*(m_fCylinderSize * REAL(0.5)); + vccATop[1] = m_vCylinderPos[1] + m_vCylinderAxis[1]*(m_fCylinderSize * REAL(0.5)); + vccATop[2] = m_vCylinderPos[2] + m_vCylinderAxis[2]*(m_fCylinderSize * REAL(0.5)); + + dVector3 vccABottom; + vccABottom[0] = m_vCylinderPos[0] - m_vCylinderAxis[0]*(m_fCylinderSize * REAL(0.5)); + vccABottom[1] = m_vCylinderPos[1] - m_vCylinderAxis[1]*(m_fCylinderSize * REAL(0.5)); + vccABottom[2] = m_vCylinderPos[2] - m_vCylinderAxis[2]*(m_fCylinderSize * REAL(0.5)); + + + if (!_cldTestCircleToEdgeAxis(v0, v1, v2, vccATop, m_vCylinderAxis, v0, v1, 15)) + { + return false; + } + + if (!_cldTestCircleToEdgeAxis(v0, v1, v2, vccATop, m_vCylinderAxis, v1, v2, 16)) + { + return false; + } + + if (!_cldTestCircleToEdgeAxis(v0, v1, v2, vccATop, m_vCylinderAxis, v0, v2, 17)) + { + return false; + } + + if (!_cldTestCircleToEdgeAxis(v0, v1, v2, vccABottom, m_vCylinderAxis, v0, v1, 18)) + { + return false; + } + + if (!_cldTestCircleToEdgeAxis(v0, v1, v2, vccABottom, m_vCylinderAxis, v1, v2, 19)) + { + return false; + } + + if (!_cldTestCircleToEdgeAxis(v0, v1, v2, vccABottom, m_vCylinderAxis, v0, v2, 20)) + { + return false; + } + + return true; +} + +bool sCylinderTrimeshColliderData::_cldClipCylinderEdgeToTriangle( + const dVector3 &v0, const dVector3 &/*v1*/, const dVector3 &/*v2*/) +{ + // translate cylinder + dReal fTemp = dVector3Dot(m_vCylinderAxis , m_vContactNormal); + dVector3 vN2; + vN2[0] = m_vContactNormal[0] - m_vCylinderAxis[0]*fTemp; + vN2[1] = m_vContactNormal[1] - m_vCylinderAxis[1]*fTemp; + vN2[2] = m_vContactNormal[2] - m_vCylinderAxis[2]*fTemp; + + fTemp = dVector3Length(vN2); + if (fTemp < REAL(1e-5)) + { + return false; + } + + // Normalize it + vN2[0] /= fTemp; + vN2[1] /= fTemp; + vN2[2] /= fTemp; + + // calculate caps centers in absolute space + dVector3 vCposTrans; + vCposTrans[0] = m_vCylinderPos[0] + vN2[0]*m_fCylinderRadius; + vCposTrans[1] = m_vCylinderPos[1] + vN2[1]*m_fCylinderRadius; + vCposTrans[2] = m_vCylinderPos[2] + vN2[2]*m_fCylinderRadius; + + dVector3 vCEdgePoint0; + vCEdgePoint0[0] = vCposTrans[0] + m_vCylinderAxis[0] * (m_fCylinderSize* REAL(0.5)); + vCEdgePoint0[1] = vCposTrans[1] + m_vCylinderAxis[1] * (m_fCylinderSize* REAL(0.5)); + vCEdgePoint0[2] = vCposTrans[2] + m_vCylinderAxis[2] * (m_fCylinderSize* REAL(0.5)); + + dVector3 vCEdgePoint1; + vCEdgePoint1[0] = vCposTrans[0] - m_vCylinderAxis[0] * (m_fCylinderSize* REAL(0.5)); + vCEdgePoint1[1] = vCposTrans[1] - m_vCylinderAxis[1] * (m_fCylinderSize* REAL(0.5)); + vCEdgePoint1[2] = vCposTrans[2] - m_vCylinderAxis[2] * (m_fCylinderSize* REAL(0.5)); + + // transform cylinder edge points into triangle space + vCEdgePoint0[0] -= v0[0]; + vCEdgePoint0[1] -= v0[1]; + vCEdgePoint0[2] -= v0[2]; + + vCEdgePoint1[0] -= v0[0]; + vCEdgePoint1[1] -= v0[1]; + vCEdgePoint1[2] -= v0[2]; + + dVector4 plPlane; + dVector3 vPlaneNormal; + + // triangle plane + //plPlane = Plane4f( -m_vNormal, 0); + vPlaneNormal[0] = -m_vNormal[0]; + vPlaneNormal[1] = -m_vNormal[1]; + vPlaneNormal[2] = -m_vNormal[2]; + dConstructPlane(vPlaneNormal,REAL(0.0),plPlane); + if(!dClipEdgeToPlane( vCEdgePoint0, vCEdgePoint1, plPlane )) + { + return false; + } + + // plane with edge 0 + //plPlane = Plane4f( ( m_vNormal cross m_vE0 ), REAL(1e-5)); + dVector3Cross(m_vNormal,m_vE0,vPlaneNormal); + dConstructPlane(vPlaneNormal,REAL(1e-5),plPlane); + if(!dClipEdgeToPlane( vCEdgePoint0, vCEdgePoint1, plPlane )) + { + return false; + } + + // plane with edge 1 + //dVector3 vTemp = ( m_vNormal cross m_vE1 ); + dVector3Cross(m_vNormal,m_vE1,vPlaneNormal); + fTemp = dVector3Dot(m_vE0 , vPlaneNormal) - REAL(1e-5); + //plPlane = Plane4f( vTemp, -(( m_vE0 dot vTemp )-REAL(1e-5))); + dConstructPlane(vPlaneNormal,-fTemp,plPlane); + if(!dClipEdgeToPlane( vCEdgePoint0, vCEdgePoint1, plPlane )) + { + return false; + } + + // plane with edge 2 + // plPlane = Plane4f( ( m_vNormal cross m_vE2 ), REAL(1e-5)); + dVector3Cross(m_vNormal,m_vE2,vPlaneNormal); + dConstructPlane(vPlaneNormal,REAL(1e-5),plPlane); + if(!dClipEdgeToPlane( vCEdgePoint0, vCEdgePoint1, plPlane )) + { + return false; + } + + // return capsule edge points into absolute space + vCEdgePoint0[0] += v0[0]; + vCEdgePoint0[1] += v0[1]; + vCEdgePoint0[2] += v0[2]; + + vCEdgePoint1[0] += v0[0]; + vCEdgePoint1[1] += v0[1]; + vCEdgePoint1[2] += v0[2]; + + // calculate depths for both contact points + dVector3 vTemp; + dVector3Subtract(vCEdgePoint0,m_vCylinderPos, vTemp); + dReal fRestDepth0 = -dVector3Dot(vTemp,m_vContactNormal) + m_fBestrt; + dVector3Subtract(vCEdgePoint1,m_vCylinderPos, vTemp); + dReal fRestDepth1 = -dVector3Dot(vTemp,m_vContactNormal) + m_fBestrt; + + dReal fDepth0 = m_fBestDepth - (fRestDepth0); + dReal fDepth1 = m_fBestDepth - (fRestDepth1); + + // clamp depths to zero + if(fDepth0 < REAL(0.0) ) + { + fDepth0 = REAL(0.0); + } + + if(fDepth1<REAL(0.0)) + { + fDepth1 = REAL(0.0); + } + + // Generate contact 0 + { + m_gLocalContacts[m_nContacts].fDepth = fDepth0; + dVector3Copy(m_vContactNormal,m_gLocalContacts[m_nContacts].vNormal); + dVector3Copy(vCEdgePoint0,m_gLocalContacts[m_nContacts].vPos); + m_gLocalContacts[m_nContacts].nFlags = 1; + m_nContacts++; + if(m_nContacts >= (m_iFlags & NUMC_MASK)) + return true; + } + + // Generate contact 1 + { + // generate contacts + m_gLocalContacts[m_nContacts].fDepth = fDepth1; + dVector3Copy(m_vContactNormal,m_gLocalContacts[m_nContacts].vNormal); + dVector3Copy(vCEdgePoint1,m_gLocalContacts[m_nContacts].vPos); + m_gLocalContacts[m_nContacts].nFlags = 1; + m_nContacts++; + } + + return true; +} + +void sCylinderTrimeshColliderData::_cldClipCylinderToTriangle( + const dVector3 &v0, const dVector3 &v1, const dVector3 &v2) +{ + int i = 0; + dVector3 avPoints[3]; + dVector3 avTempArray1[nMAX_CYLINDER_TRIANGLE_CLIP_POINTS]; + dVector3 avTempArray2[nMAX_CYLINDER_TRIANGLE_CLIP_POINTS]; + + dSetZero(&avTempArray1[0][0],nMAX_CYLINDER_TRIANGLE_CLIP_POINTS * 4); + dSetZero(&avTempArray2[0][0],nMAX_CYLINDER_TRIANGLE_CLIP_POINTS * 4); + + // setup array of triangle vertices + dVector3Copy(v0,avPoints[0]); + dVector3Copy(v1,avPoints[1]); + dVector3Copy(v2,avPoints[2]); + + dVector3 vCylinderCirclePos, vCylinderCircleNormal_Rel; + dSetZero(vCylinderCircleNormal_Rel,4); + // check which circle from cylinder we take for clipping + if ( dVector3Dot(m_vCylinderAxis , m_vContactNormal) > REAL(0.0)) + { + // get top circle + vCylinderCirclePos[0] = m_vCylinderPos[0] + m_vCylinderAxis[0]*(m_fCylinderSize*REAL(0.5)); + vCylinderCirclePos[1] = m_vCylinderPos[1] + m_vCylinderAxis[1]*(m_fCylinderSize*REAL(0.5)); + vCylinderCirclePos[2] = m_vCylinderPos[2] + m_vCylinderAxis[2]*(m_fCylinderSize*REAL(0.5)); + + vCylinderCircleNormal_Rel[nCYLINDER_AXIS] = REAL(-1.0); + } + else + { + // get bottom circle + vCylinderCirclePos[0] = m_vCylinderPos[0] - m_vCylinderAxis[0]*(m_fCylinderSize*REAL(0.5)); + vCylinderCirclePos[1] = m_vCylinderPos[1] - m_vCylinderAxis[1]*(m_fCylinderSize*REAL(0.5)); + vCylinderCirclePos[2] = m_vCylinderPos[2] - m_vCylinderAxis[2]*(m_fCylinderSize*REAL(0.5)); + + vCylinderCircleNormal_Rel[nCYLINDER_AXIS] = REAL(1.0); + } + + dVector3 vTemp; + dQuatInv(m_qCylinderRot , m_qInvCylinderRot); + // transform triangle points to space of cylinder circle + for(i=0; i<3; i++) + { + dVector3Subtract(avPoints[i] , vCylinderCirclePos , vTemp); + dQuatTransform(m_qInvCylinderRot,vTemp,avPoints[i]); + } + + int iTmpCounter1 = 0; + int iTmpCounter2 = 0; + dVector4 plPlane; + + // plane of cylinder that contains circle for intersection + //plPlane = Plane4f( vCylinderCircleNormal_Rel, 0.0f ); + dConstructPlane(vCylinderCircleNormal_Rel,REAL(0.0),plPlane); + dClipPolyToPlane(avPoints, 3, avTempArray1, iTmpCounter1, plPlane); + + // Body of base circle of Cylinder + int nCircleSegment = 0; + for (nCircleSegment = 0; nCircleSegment < nCYLINDER_CIRCLE_SEGMENTS; nCircleSegment++) + { + dConstructPlane(m_avCylinderNormals[nCircleSegment],m_fCylinderRadius,plPlane); + + if (0 == (nCircleSegment % 2)) + { + dClipPolyToPlane( avTempArray1 , iTmpCounter1 , avTempArray2, iTmpCounter2, plPlane); + } + else + { + dClipPolyToPlane( avTempArray2, iTmpCounter2, avTempArray1 , iTmpCounter1 , plPlane ); + } + + dIASSERT( iTmpCounter1 >= 0 && iTmpCounter1 <= nMAX_CYLINDER_TRIANGLE_CLIP_POINTS ); + dIASSERT( iTmpCounter2 >= 0 && iTmpCounter2 <= nMAX_CYLINDER_TRIANGLE_CLIP_POINTS ); + } + + // back transform clipped points to absolute space + dReal ftmpdot; + dReal fTempDepth; + dVector3 vPoint; + + if (nCircleSegment %2) + { + for( i=0; i<iTmpCounter2; i++) + { + dQuatTransform(m_qCylinderRot,avTempArray2[i], vPoint); + vPoint[0] += vCylinderCirclePos[0]; + vPoint[1] += vCylinderCirclePos[1]; + vPoint[2] += vCylinderCirclePos[2]; + + dVector3Subtract(vPoint,m_vCylinderPos,vTemp); + ftmpdot = dFabs(dVector3Dot(vTemp, m_vContactNormal)); + fTempDepth = m_fBestrt - ftmpdot; + // Depth must be positive + if (fTempDepth > REAL(0.0)) + { + m_gLocalContacts[m_nContacts].fDepth = fTempDepth; + dVector3Copy(m_vContactNormal,m_gLocalContacts[m_nContacts].vNormal); + dVector3Copy(vPoint,m_gLocalContacts[m_nContacts].vPos); + m_gLocalContacts[m_nContacts].nFlags = 1; + m_nContacts++; + if(m_nContacts >= (m_iFlags & NUMC_MASK)) + return;; + } + } + } + else + { + for( i=0; i<iTmpCounter1; i++) + { + dQuatTransform(m_qCylinderRot,avTempArray1[i], vPoint); + vPoint[0] += vCylinderCirclePos[0]; + vPoint[1] += vCylinderCirclePos[1]; + vPoint[2] += vCylinderCirclePos[2]; + + dVector3Subtract(vPoint,m_vCylinderPos,vTemp); + ftmpdot = dFabs(dVector3Dot(vTemp, m_vContactNormal)); + fTempDepth = m_fBestrt - ftmpdot; + // Depth must be positive + if (fTempDepth > REAL(0.0)) + { + m_gLocalContacts[m_nContacts].fDepth = fTempDepth; + dVector3Copy(m_vContactNormal,m_gLocalContacts[m_nContacts].vNormal); + dVector3Copy(vPoint,m_gLocalContacts[m_nContacts].vPos); + m_gLocalContacts[m_nContacts].nFlags = 1; + m_nContacts++; + if(m_nContacts >= (m_iFlags & NUMC_MASK)) + return;; + } + } + } +} + +void sCylinderTrimeshColliderData::TestOneTriangleVsCylinder( + const dVector3 &v0, + const dVector3 &v1, + const dVector3 &v2, + const bool bDoubleSided) +{ + // calculate triangle normal + dVector3Subtract( v2 , v1 , m_vE1); + dVector3 vTemp; + dVector3Subtract( v0 , v1 ,vTemp); + dVector3Cross(m_vE1 , vTemp , m_vNormal ); + + // Even though all triangles might be initially valid, + // a triangle may degenerate into a segment after applying + // space transformation. + if (!dSafeNormalize3( m_vNormal)) + { + return; + } + + // create plane from triangle + //Plane4f plTrianglePlane = Plane4f( vPolyNormal, v0 ); + dReal plDistance = -dVector3Dot(v0, m_vNormal); + dVector4 plTrianglePlane; + dConstructPlane( m_vNormal,plDistance,plTrianglePlane); + + // calculate sphere distance to plane + dReal fDistanceCylinderCenterToPlane = dPointPlaneDistance(m_vCylinderPos , plTrianglePlane); + + // Sphere must be over positive side of triangle + if(fDistanceCylinderCenterToPlane < 0 && !bDoubleSided) + { + // if not don't generate contacts + return; + } + + dVector3 vPnt0; + dVector3 vPnt1; + dVector3 vPnt2; + + if (fDistanceCylinderCenterToPlane < REAL(0.0) ) + { + // flip it + dVector3Copy(v0 , vPnt0); + dVector3Copy(v1 , vPnt2); + dVector3Copy(v2 , vPnt1); + } + else + { + dVector3Copy(v0 , vPnt0); + dVector3Copy(v1 , vPnt1); + dVector3Copy(v2 , vPnt2); + } + + m_fBestDepth = MAX_REAL; + + // do intersection test and find best separating axis + if(!_cldTestSeparatingAxes(vPnt0, vPnt1, vPnt2) ) + { + // if not found do nothing + return; + } + + // if best separation axis is not found + if ( m_iBestAxis == 0 ) + { + // this should not happen (the function should have already returned in this case) + dIASSERT(false); + // do nothing + return; + } + + dReal fdot = dVector3Dot( m_vContactNormal , m_vCylinderAxis ); + + // choose which clipping method are we going to apply + if (dFabs(fdot) < REAL(0.9) ) + { + if (!_cldClipCylinderEdgeToTriangle(vPnt0, vPnt1, vPnt2)) + { + return; + } + } + else + { + _cldClipCylinderToTriangle(vPnt0, vPnt1, vPnt2); + } +} + +void sCylinderTrimeshColliderData::_InitCylinderTrimeshData(dxGeom *Cylinder, dxTriMesh *Trimesh) +{ + // get cylinder information + // Rotation + const dReal* pRotCyc = dGeomGetRotation(Cylinder); + dMatrix3Copy(pRotCyc,m_mCylinderRot); + dGeomGetQuaternion(Cylinder,m_qCylinderRot); + + // Position + const dVector3* pPosCyc = (const dVector3*)dGeomGetPosition(Cylinder); + dVector3Copy(*pPosCyc,m_vCylinderPos); + // Cylinder axis + dMat3GetCol(m_mCylinderRot,nCYLINDER_AXIS,m_vCylinderAxis); + // get cylinder radius and size + dGeomCylinderGetParams(Cylinder,&m_fCylinderRadius,&m_fCylinderSize); + + // get trimesh position and orientation + const dReal* pRotTris = dGeomGetRotation(Trimesh); + dMatrix3Copy(pRotTris,m_mTrimeshRot); + dGeomGetQuaternion(Trimesh,m_qTrimeshRot); + + // Position + const dVector3* pPosTris = (const dVector3*)dGeomGetPosition(Trimesh); + dVector3Copy(*pPosTris,m_vTrimeshPos); + + + // calculate basic angle for 8-gon + dReal fAngle = (dReal) (M_PI / nCYLINDER_CIRCLE_SEGMENTS); + // calculate angle increment + dReal fAngleIncrement = fAngle*REAL(2.0); + + // calculate plane normals + // axis dependant code + for(int i=0; i<nCYLINDER_CIRCLE_SEGMENTS; i++) + { + m_avCylinderNormals[i][0] = -dCos(fAngle); + m_avCylinderNormals[i][1] = -dSin(fAngle); + m_avCylinderNormals[i][2] = REAL(0.0); + + fAngle += fAngleIncrement; + } + + dSetZero(m_vBestPoint,4); + // reset best depth + m_fBestCenter = REAL(0.0); +} + +int sCylinderTrimeshColliderData::TestCollisionForSingleTriangle(int ctContacts0, + int Triint, dVector3 dv[3], bool &bOutFinishSearching) +{ + // test this triangle + TestOneTriangleVsCylinder(dv[0],dv[1],dv[2], false); + + // fill-in tri index for generated contacts + for (; ctContacts0<m_nContacts; ctContacts0++) + m_gLocalContacts[ctContacts0].triIndex = Triint; + + // Putting "break" at the end of loop prevents unnecessary checks on first pass and "continue" + bOutFinishSearching = (m_nContacts >= (m_iFlags & NUMC_MASK)); + + return ctContacts0; +} + +// OPCODE version of cylinder to mesh collider +#if dTRIMESH_OPCODE +static void dQueryCTLPotentialCollisionTriangles(OBBCollider &Collider, + sCylinderTrimeshColliderData &cData, dxGeom *Cylinder, dxTriMesh *Trimesh, + OBBCache &BoxCache) +{ + Matrix4x4 MeshMatrix; + const dVector3 vZeroVector3 = { REAL(0.0), }; + MakeMatrix(vZeroVector3, cData.m_mTrimeshRot, MeshMatrix); + + const dVector3 &vCylinderPos = cData.m_vCylinderPos; + const dMatrix3 &mCylinderRot = cData.m_mCylinderRot; + + dVector3 vCylinderOffsetPos; + dSubtractVectors3(vCylinderOffsetPos, vCylinderPos, cData.m_vTrimeshPos); + + const dReal fCylinderRadius = cData.m_fCylinderRadius, fCylinderHalfAxis = cData.m_fCylinderSize * REAL(0.5); + + OBB obbCylinder; + obbCylinder.mCenter.Set(vCylinderOffsetPos[0], vCylinderOffsetPos[1], vCylinderOffsetPos[2]); + obbCylinder.mExtents.Set( + 0 == nCYLINDER_AXIS ? fCylinderHalfAxis : fCylinderRadius, + 1 == nCYLINDER_AXIS ? fCylinderHalfAxis : fCylinderRadius, + 2 == nCYLINDER_AXIS ? fCylinderHalfAxis : fCylinderRadius); + obbCylinder.mRot.Set( + mCylinderRot[0], mCylinderRot[4], mCylinderRot[8], + mCylinderRot[1], mCylinderRot[5], mCylinderRot[9], + mCylinderRot[2], mCylinderRot[6], mCylinderRot[10]); + + // TC results + if (Trimesh->getDoTC(dxTriMesh::TTC_BOX)) + { + dxTriMesh::BoxTC* BoxTC = 0; + const int iBoxCacheSize = Trimesh->m_BoxTCCache.size(); + for (int i = 0; i != iBoxCacheSize; i++) + { + if (Trimesh->m_BoxTCCache[i].Geom == Cylinder) + { + BoxTC = &Trimesh->m_BoxTCCache[i]; + break; + } + } + if (!BoxTC) + { + Trimesh->m_BoxTCCache.push(dxTriMesh::BoxTC()); + + BoxTC = &Trimesh->m_BoxTCCache[Trimesh->m_BoxTCCache.size() - 1]; + BoxTC->Geom = Cylinder; + BoxTC->FatCoeff = REAL(1.0); + } + + // Intersect + Collider.SetTemporalCoherence(true); + Collider.Collide(*BoxTC, obbCylinder, Trimesh->retrieveMeshBVTreeRef(), null, &MeshMatrix); + } + else + { + Collider.SetTemporalCoherence(false); + Collider.Collide(BoxCache, obbCylinder, Trimesh->retrieveMeshBVTreeRef(), null, &MeshMatrix); + } +} + +int dCollideCylinderTrimesh(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) +{ + dIASSERT( skip >= (int)sizeof( dContactGeom ) ); + dIASSERT( o1->type == dCylinderClass ); + dIASSERT( o2->type == dTriMeshClass ); + dIASSERT ((flags & NUMC_MASK) >= 1); + + int nContactCount = 0; + + dxGeom *Cylinder = o1; + dxTriMesh *Trimesh = (dxTriMesh *)o2; + + // Main data holder + sCylinderTrimeshColliderData cData(flags, skip); + cData._InitCylinderTrimeshData(Cylinder, Trimesh); + + const unsigned uiTLSKind = Trimesh->getParentSpaceTLSKind(); + dIASSERT(uiTLSKind == Cylinder->getParentSpaceTLSKind()); // The colliding spaces must use matching cleanup method + TrimeshCollidersCache *pccColliderCache = GetTrimeshCollidersCache(uiTLSKind); + OBBCollider& Collider = pccColliderCache->m_OBBCollider; + + dQueryCTLPotentialCollisionTriangles(Collider, cData, Cylinder, Trimesh, pccColliderCache->m_DefaultBoxCache); + + // Retrieve data + int TriCount = Collider.GetNbTouchedPrimitives(); + + if (TriCount != 0) + { + const int* Triangles = (const int*)Collider.GetTouchedPrimitives(); + + if (Trimesh->m_ArrayCallback != NULL) + { + Trimesh->m_ArrayCallback(Trimesh, Cylinder, Triangles, TriCount); + } + + // allocate buffer for local contacts on stack + cData.m_gLocalContacts = (sLocalContactData*)dALLOCA16(sizeof(sLocalContactData)*(cData.m_iFlags & NUMC_MASK)); + + int ctContacts0 = 0; + + // loop through all intersecting triangles + for (int i = 0; i < TriCount; i++) + { + const int Triint = Triangles[i]; + if (!Trimesh->invokeCallback(Cylinder, Triint)) continue; + + + dVector3 dv[3]; + Trimesh->fetchMeshTriangle(dv, Triint, cData.m_vTrimeshPos, cData.m_mTrimeshRot); + + bool bFinishSearching; + ctContacts0 = cData.TestCollisionForSingleTriangle(ctContacts0, Triint, dv, bFinishSearching); + + if (bFinishSearching) + { + break; + } + } + + if (cData.m_nContacts != 0) + { + nContactCount = cData._ProcessLocalContacts(contact, Cylinder, Trimesh); + } + } + + return nContactCount; +} +#endif + +// GIMPACT version of cylinder to mesh collider +#if dTRIMESH_GIMPACT +int dCollideCylinderTrimesh(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) +{ + dIASSERT( skip >= (int)sizeof( dContactGeom ) ); + dIASSERT( o1->type == dCylinderClass ); + dIASSERT( o2->type == dTriMeshClass ); + dIASSERT ((flags & NUMC_MASK) >= 1); + + int nContactCount = 0; + + dxGeom *Cylinder = o1; + dxTriMesh *Trimesh = (dxTriMesh *)o2; + + // Main data holder + sCylinderTrimeshColliderData cData(flags, skip); + cData._InitCylinderTrimeshData(Cylinder, Trimesh); + + //*****at first , collide box aabb******// + + aabb3f test_aabb(o1->aabb[0], o1->aabb[1], o1->aabb[2], o1->aabb[3], o1->aabb[4], o1->aabb[5]); + + + GDYNAMIC_ARRAY collision_result; + GIM_CREATE_BOXQUERY_LIST(collision_result); + + gim_aabbset_box_collision(&test_aabb, &Trimesh->m_collision_trimesh.m_aabbset , &collision_result); + + if (collision_result.m_size != 0) + { + //*****Set globals for box collision******// + + int ctContacts0 = 0; + cData.m_gLocalContacts = (sLocalContactData*)dALLOCA16(sizeof(sLocalContactData)*(cData.m_iFlags & NUMC_MASK)); + + GUINT32 * boxesresult = GIM_DYNARRAY_POINTER(GUINT32,collision_result); + GIM_TRIMESH * ptrimesh = &Trimesh->m_collision_trimesh; + + gim_trimesh_locks_work_data(ptrimesh); + + for(unsigned int i=0;i<collision_result.m_size;i++) + { + const int Triint = boxesresult[i]; + + dVector3 dv[3]; + gim_trimesh_get_triangle_vertices(ptrimesh, Triint, dv[0], dv[1], dv[2]); + + bool bFinishSearching; + ctContacts0 = cData.TestCollisionForSingleTriangle(ctContacts0, Triint, dv, bFinishSearching); + + if (bFinishSearching) + { + break; + } + } + + gim_trimesh_unlocks_work_data(ptrimesh); + + if (cData.m_nContacts != 0) + { + nContactCount = cData._ProcessLocalContacts(contact, Cylinder, Trimesh); + } + } + + GIM_DYNARRAY_DESTROY(collision_result); + + return nContactCount; +} +#endif + +#endif // dTRIMESH_ENABLED + + diff --git a/libs/ode-0.16.1/ode/src/collision_kernel.cpp b/libs/ode-0.16.1/ode/src/collision_kernel.cpp new file mode 100644 index 0000000..527941a --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_kernel.cpp @@ -0,0 +1,1247 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +core collision functions and data structures, plus part of the public API +for geometry objects + +*/ + +#include <ode/common.h> +#include <ode/rotation.h> +#include <ode/objects.h> +#include "config.h" +#include "matrix.h" +#include "odemath.h" +#include "collision_kernel.h" +#include "collision_util.h" +#include "collision_std.h" +#include "collision_transform.h" +#include "collision_trimesh_internal.h" +#include "collision_space_internal.h" +#include "odeou.h" + +#ifdef dLIBCCD_ENABLED +# include "collision_libccd.h" +#endif /* dLIBCCD_ENABLED */ + + +#ifdef _MSC_VER +#pragma warning(disable:4291) // for VC++, no complaints about "no matching operator delete found" +#endif + +//**************************************************************************** +// helper functions for dCollide()ing a space with another geom + +// this struct records the parameters passed to dCollideSpaceGeom() + +#if dATOMICS_ENABLED +static volatile atomicptr s_cachedPosR = 0; // dxPosR * +#endif // dATOMICS_ENABLED + +static inline dxPosR* dAllocPosr() +{ + dxPosR *retPosR; + +#if dATOMICS_ENABLED + retPosR = (dxPosR *)AtomicExchangePointer(&s_cachedPosR, NULL); + + if (!retPosR) +#endif + { + retPosR = (dxPosR*) dAlloc (sizeof(dxPosR)); + } + + return retPosR; +} + +static inline void dFreePosr(dxPosR *oldPosR) +{ +#if dATOMICS_ENABLED + if (!AtomicCompareExchangePointer(&s_cachedPosR, NULL, (atomicptr)oldPosR)) +#endif + { + dFree(oldPosR, sizeof(dxPosR)); + } +} + +/*extern */void dClearPosrCache(void) +{ +#if dATOMICS_ENABLED + // No threads should be accessing ODE at this time already, + // hence variable may be read directly. + dxPosR *existingPosR = (dxPosR *)s_cachedPosR; + + if (existingPosR) + { + dFree(existingPosR, sizeof(dxPosR)); + + s_cachedPosR = 0; + } +#endif +} + +struct SpaceGeomColliderData { + int flags; // space left in contacts array + dContactGeom *contact; + int skip; +}; + + +static void space_geom_collider (void *data, dxGeom *o1, dxGeom *o2) +{ + SpaceGeomColliderData *d = (SpaceGeomColliderData*) data; + if (d->flags & NUMC_MASK) { + int n = dCollide (o1,o2,d->flags,d->contact,d->skip); + d->contact = CONTACT (d->contact,d->skip*n); + d->flags -= n; + } +} + + +static int dCollideSpaceGeom (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) +{ + SpaceGeomColliderData data; + data.flags = flags; + data.contact = contact; + data.skip = skip; + dSpaceCollide2 (o1,o2,&data,&space_geom_collider); + return (flags & NUMC_MASK) - (data.flags & NUMC_MASK); +} + +//**************************************************************************** +// dispatcher for the N^2 collider functions + +// function pointers and modes for n^2 class collider functions + +struct dColliderEntry { + dColliderFn *fn; // collider function, 0 = no function available + int reverse; // 1 = reverse o1 and o2 +}; +static dColliderEntry colliders[dGeomNumClasses][dGeomNumClasses]; +static int colliders_initialized = 0; + + +// setCollider() will refuse to write over a collider entry once it has +// been written. + +static void setCollider (int i, int j, dColliderFn *fn) +{ + if (colliders[i][j].fn == 0) { + colliders[i][j].fn = fn; + colliders[i][j].reverse = 0; + } + if (colliders[j][i].fn == 0) { + colliders[j][i].fn = fn; + colliders[j][i].reverse = 1; + } +} + + +static void setAllColliders (int i, dColliderFn *fn) +{ + for (int j=0; j<dGeomNumClasses; j++) setCollider (i,j,fn); +} + +/*extern */void dInitColliders() +{ + dIASSERT(!colliders_initialized); + colliders_initialized = 1; + + memset (colliders,0,sizeof(colliders)); + + int i,j; + + // setup space colliders + for (i=dFirstSpaceClass; i <= dLastSpaceClass; i++) { + for (j=0; j < dGeomNumClasses; j++) { + setCollider (i,j,&dCollideSpaceGeom); + } + } + + setCollider (dSphereClass,dSphereClass,&dCollideSphereSphere); + setCollider (dSphereClass,dBoxClass,&dCollideSphereBox); + setCollider (dSphereClass,dPlaneClass,&dCollideSpherePlane); + setCollider (dBoxClass,dBoxClass,&dCollideBoxBox); + setCollider (dBoxClass,dPlaneClass,&dCollideBoxPlane); + setCollider (dCapsuleClass,dSphereClass,&dCollideCapsuleSphere); + setCollider (dCapsuleClass,dBoxClass,&dCollideCapsuleBox); + setCollider (dCapsuleClass,dCapsuleClass,&dCollideCapsuleCapsule); + setCollider (dCapsuleClass,dPlaneClass,&dCollideCapsulePlane); + setCollider (dRayClass,dSphereClass,&dCollideRaySphere); + setCollider (dRayClass,dBoxClass,&dCollideRayBox); + setCollider (dRayClass,dCapsuleClass,&dCollideRayCapsule); + setCollider (dRayClass,dPlaneClass,&dCollideRayPlane); + setCollider (dRayClass,dCylinderClass,&dCollideRayCylinder); +#if dTRIMESH_ENABLED + setCollider (dTriMeshClass,dSphereClass,&dCollideSTL); + setCollider (dTriMeshClass,dBoxClass,&dCollideBTL); + setCollider (dTriMeshClass,dRayClass,&dCollideRTL); + setCollider (dTriMeshClass,dTriMeshClass,&dCollideTTL); + setCollider (dTriMeshClass,dCapsuleClass,&dCollideCCTL); + setCollider (dTriMeshClass,dPlaneClass,&dCollideTrimeshPlane); + setCollider (dCylinderClass,dTriMeshClass,&dCollideCylinderTrimesh); + setCollider (dConvexClass,dTriMeshClass,&dCollideConvexTrimesh); +#endif + +#ifdef dLIBCCD_BOX_CYL + setCollider (dBoxClass,dCylinderClass,&dCollideBoxCylinderCCD); +#else + setCollider (dCylinderClass,dBoxClass,&dCollideCylinderBox); +#endif + setCollider (dCylinderClass,dSphereClass,&dCollideCylinderSphere); + setCollider (dCylinderClass,dPlaneClass,&dCollideCylinderPlane); + +#ifdef dLIBCCD_CYL_CYL + setCollider (dCylinderClass, dCylinderClass, &dCollideCylinderCylinder); +#endif +#ifdef dLIBCCD_CAP_CYL + setCollider (dCapsuleClass, dCylinderClass, &dCollideCapsuleCylinder); +#endif + + //--> Convex Collision +#ifdef dLIBCCD_CONVEX_BOX + setCollider (dConvexClass, dBoxClass, &dCollideConvexBoxCCD); +#else + setCollider (dConvexClass,dBoxClass,&dCollideConvexBox); +#endif + +#ifdef dLIBCCD_CONVEX_CAP + setCollider (dConvexClass,dCapsuleClass,&dCollideConvexCapsuleCCD); +#else + setCollider (dConvexClass,dCapsuleClass,&dCollideConvexCapsule); +#endif + +#ifdef dLIBCCD_CONVEX_CYL + setCollider (dConvexClass,dCylinderClass,&dCollideConvexCylinderCCD); +#endif + +#ifdef dLIBCCD_CONVEX_SPHERE + setCollider (dConvexClass,dSphereClass,&dCollideConvexSphereCCD); +#else + setCollider (dSphereClass,dConvexClass,&dCollideSphereConvex); +#endif + +#ifdef dLIBCCD_CONVEX_CONVEX + setCollider (dConvexClass,dConvexClass,&dCollideConvexConvexCCD); +#else + setCollider (dConvexClass,dConvexClass,&dCollideConvexConvex); +#endif + + setCollider (dConvexClass,dPlaneClass,&dCollideConvexPlane); + setCollider (dRayClass,dConvexClass,&dCollideRayConvex); + //<-- Convex Collision + + //--> dHeightfield Collision + setCollider (dHeightfieldClass,dRayClass,&dCollideHeightfield); + setCollider (dHeightfieldClass,dSphereClass,&dCollideHeightfield); + setCollider (dHeightfieldClass,dBoxClass,&dCollideHeightfield); + setCollider (dHeightfieldClass,dCapsuleClass,&dCollideHeightfield); + setCollider (dHeightfieldClass,dCylinderClass,&dCollideHeightfield); + setCollider (dHeightfieldClass,dConvexClass,&dCollideHeightfield); +#if dTRIMESH_ENABLED + setCollider (dHeightfieldClass,dTriMeshClass,&dCollideHeightfield); +#endif + //<-- dHeightfield Collision + + setAllColliders (dGeomTransformClass,&dCollideTransform); +} + +/*extern */void dFinitColliders() +{ + colliders_initialized = 0; +} + +void dSetColliderOverride (int i, int j, dColliderFn *fn) +{ + dIASSERT( colliders_initialized ); + dAASSERT( i < dGeomNumClasses ); + dAASSERT( j < dGeomNumClasses ); + + colliders[i][j].fn = fn; + colliders[i][j].reverse = 0; + colliders[j][i].fn = fn; + colliders[j][i].reverse = 1; +} + +/* +* NOTE! +* If it is necessary to add special processing mode without contact generation +* use NULL contact parameter value as indicator, not zero in flags. +*/ +int dCollide (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) +{ + dAASSERT(o1 && o2 && contact); + dUASSERT(colliders_initialized,"Please call ODE initialization (dInitODE() or similar) before using the library"); + dUASSERT(o1->type >= 0 && o1->type < dGeomNumClasses,"bad o1 class number"); + dUASSERT(o2->type >= 0 && o2->type < dGeomNumClasses,"bad o2 class number"); + // Even though comparison for greater or equal to one is used in all the + // other places, here it is more logical to check for greater than zero + // because function does not require any specific number of contact slots - + // it must be just a positive. + dUASSERT((flags & NUMC_MASK) > 0, "no contacts requested"); + + // Extra precaution for zero contact count in parameters + if ((flags & NUMC_MASK) == 0) return 0; + // no contacts if both geoms are the same + if (o1 == o2) return 0; + + // no contacts if both geoms on the same body, and the body is not 0 + if (o1->body == o2->body && o1->body) return 0; + + o1->recomputePosr(); + o2->recomputePosr(); + + dColliderEntry *ce = &colliders[o1->type][o2->type]; + int count = 0; + if (ce->fn) { + if (ce->reverse) { + count = (*ce->fn) (o2,o1,flags,contact,skip); + for (int i=0; i<count; i++) { + dContactGeom *c = CONTACT(contact,skip*i); + c->normal[0] = -c->normal[0]; + c->normal[1] = -c->normal[1]; + c->normal[2] = -c->normal[2]; + dxGeom *tmp = c->g1; + c->g1 = c->g2; + c->g2 = tmp; + int tmpint = c->side1; + c->side1 = c->side2; + c->side2 = tmpint; + } + } + else { + count = (*ce->fn) (o1,o2,flags,contact,skip); + } + } + return count; +} + +//**************************************************************************** +// dxGeom + +dxGeom::dxGeom (dSpaceID _space, int is_placeable) +{ + // setup body vars. invalid type of -1 must be changed by the constructor. + type = -1; + gflags = GEOM_DIRTY | GEOM_AABB_BAD | GEOM_ENABLED; + if (is_placeable) gflags |= GEOM_PLACEABLE; + data = 0; + body = 0; + body_next = 0; + if (is_placeable) { + final_posr = dAllocPosr(); + dSetZero (final_posr->pos,4); + dRSetIdentity (final_posr->R); + } + else { + final_posr = 0; + } + offset_posr = 0; + + // setup space vars + next = 0; + tome = 0; + next_ex = 0; + tome_ex = 0; + parent_space = 0; + dSetZero (aabb,6); + category_bits = ~0; + collide_bits = ~0; + + // put this geom in a space if required + if (_space) dSpaceAdd (_space,this); +} + + +dxGeom::~dxGeom() +{ + if (parent_space) dSpaceRemove (parent_space,this); + if ((gflags & GEOM_PLACEABLE) && (!body || (body && offset_posr))) + dFreePosr(final_posr); + if (offset_posr) dFreePosr(offset_posr); + bodyRemove(); +} + +unsigned dxGeom::getParentSpaceTLSKind() const +{ + return parent_space ? parent_space->tls_kind : dSPACE_TLS_KIND_INIT_VALUE; +} + +int dxGeom::AABBTest (dxGeom *, dReal [6]) +{ + return 1; +} + + +void dxGeom::bodyRemove() +{ + if (body) { + // delete this geom from body list + dxGeom **last = &body->geom, *g = body->geom; + while (g) { + if (g == this) { + *last = g->body_next; + break; + } + last = &g->body_next; + g = g->body_next; + } + body = 0; + body_next = 0; + } +} + +inline void myswap(dReal& a, dReal& b) { dReal t=b; b=a; a=t; } + + +inline void matrixInvert(const dMatrix3& inMat, dMatrix3& outMat) +{ + memcpy(outMat, inMat, sizeof(dMatrix3)); + // swap _12 and _21 + myswap(outMat[0 + 4*1], outMat[1 + 4*0]); + // swap _31 and _13 + myswap(outMat[2 + 4*0], outMat[0 + 4*2]); + // swap _23 and _32 + myswap(outMat[1 + 4*2], outMat[2 + 4*1]); +} + +void getBodyPosr(const dxPosR& offset_posr, const dxPosR& final_posr, dxPosR& body_posr) +{ + dMatrix3 inv_offset; + matrixInvert(offset_posr.R, inv_offset); + + dMultiply0_333(body_posr.R, final_posr.R, inv_offset); + dVector3 world_offset; + dMultiply0_331(world_offset, body_posr.R, offset_posr.pos); + body_posr.pos[0] = final_posr.pos[0] - world_offset[0]; + body_posr.pos[1] = final_posr.pos[1] - world_offset[1]; + body_posr.pos[2] = final_posr.pos[2] - world_offset[2]; +} + +void getWorldOffsetPosr(const dxPosR& body_posr, const dxPosR& world_posr, dxPosR& offset_posr) +{ + dMatrix3 inv_body; + matrixInvert(body_posr.R, inv_body); + + dMultiply0_333(offset_posr.R, inv_body, world_posr.R); + dVector3 world_offset; + world_offset[0] = world_posr.pos[0] - body_posr.pos[0]; + world_offset[1] = world_posr.pos[1] - body_posr.pos[1]; + world_offset[2] = world_posr.pos[2] - body_posr.pos[2]; + dMultiply0_331(offset_posr.pos, inv_body, world_offset); +} + +void dxGeom::computePosr() +{ + // should only be recalced if we need to - ie offset from a body + dIASSERT(offset_posr); + dIASSERT(body); + + dMultiply0_331 (final_posr->pos,body->posr.R,offset_posr->pos); + final_posr->pos[0] += body->posr.pos[0]; + final_posr->pos[1] += body->posr.pos[1]; + final_posr->pos[2] += body->posr.pos[2]; + dMultiply0_333 (final_posr->R,body->posr.R,offset_posr->R); +} + +bool dxGeom::controlGeometry(int /*controlClass*/, int /*controlCode*/, void * /*dataValue*/, int *dataSize) +{ + dAASSERT(false && "Control class/code is not supported for current geom"); + + *dataSize = 0; + return false; +} + +//**************************************************************************** +// misc + +dxGeom *dGeomGetBodyNext (dxGeom *geom) +{ + return geom->body_next; +} + +//**************************************************************************** +// public API for geometry objects + +void dGeomDestroy (dxGeom *g) +{ + dAASSERT (g); + delete g; +} + + +void dGeomSetData (dxGeom *g, void *data) +{ + dAASSERT (g); + g->data = data; +} + + +void *dGeomGetData (dxGeom *g) +{ + dAASSERT (g); + return g->data; +} + + +void dGeomSetBody (dxGeom *g, dxBody *b) +{ + dAASSERT (g); + dUASSERT (b == NULL || (g->gflags & GEOM_PLACEABLE),"geom must be placeable"); + CHECK_NOT_LOCKED (g->parent_space); + + if (b) { + if (!g->body) dFreePosr(g->final_posr); + if (g->body != b) { + if (g->offset_posr) { + dFreePosr(g->offset_posr); + g->offset_posr = 0; + } + g->final_posr = &b->posr; + g->bodyRemove(); + g->bodyAdd (b); + } + dGeomMoved (g); + } + else { + if (g->body) { + if (g->offset_posr) + { + // if we're offset, we already have our own final position, make sure its updated + g->recomputePosr(); + dFreePosr(g->offset_posr); + g->offset_posr = 0; + } + else + { + g->final_posr = dAllocPosr(); + memcpy (g->final_posr->pos,g->body->posr.pos,sizeof(dVector3)); + memcpy (g->final_posr->R,g->body->posr.R,sizeof(dMatrix3)); + } + g->bodyRemove(); + } + // dGeomMoved() should not be called if the body is being set to 0, as the + // new position of the geom is set to the old position of the body, so the + // effective position of the geom remains unchanged. + } +} + + +dBodyID dGeomGetBody (dxGeom *g) +{ + dAASSERT (g); + return g->body; +} + + +void dGeomSetPosition (dxGeom *g, dReal x, dReal y, dReal z) +{ + dAASSERT (g); + dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); + CHECK_NOT_LOCKED (g->parent_space); + if (g->offset_posr) { + // move body such that body+offset = position + dVector3 world_offset; + dMultiply0_331(world_offset, g->body->posr.R, g->offset_posr->pos); + dBodySetPosition(g->body, + x - world_offset[0], + y - world_offset[1], + z - world_offset[2]); + } + else if (g->body) { + // this will call dGeomMoved (g), so we don't have to + dBodySetPosition (g->body,x,y,z); + } + else { + g->final_posr->pos[0] = x; + g->final_posr->pos[1] = y; + g->final_posr->pos[2] = z; + dGeomMoved (g); + } +} + + +void dGeomSetRotation (dxGeom *g, const dMatrix3 R) +{ + dAASSERT (g && R); + dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); + CHECK_NOT_LOCKED (g->parent_space); + if (g->offset_posr) { + g->recomputePosr(); + // move body such that body+offset = rotation + dxPosR new_final_posr; + dxPosR new_body_posr; + memcpy(new_final_posr.pos, g->final_posr->pos, sizeof(dVector3)); + memcpy(new_final_posr.R, R, sizeof(dMatrix3)); + getBodyPosr(*g->offset_posr, new_final_posr, new_body_posr); + dBodySetRotation(g->body, new_body_posr.R); + dBodySetPosition(g->body, new_body_posr.pos[0], new_body_posr.pos[1], new_body_posr.pos[2]); + } + else if (g->body) { + // this will call dGeomMoved (g), so we don't have to + dBodySetRotation (g->body,R); + } + else { + memcpy (g->final_posr->R,R,sizeof(dMatrix3)); + dGeomMoved (g); + } +} + + +void dGeomSetQuaternion (dxGeom *g, const dQuaternion quat) +{ + dAASSERT (g && quat); + dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); + CHECK_NOT_LOCKED (g->parent_space); + if (g->offset_posr) { + g->recomputePosr(); + // move body such that body+offset = rotation + dxPosR new_final_posr; + dxPosR new_body_posr; + dQtoR (quat, new_final_posr.R); + memcpy(new_final_posr.pos, g->final_posr->pos, sizeof(dVector3)); + + getBodyPosr(*g->offset_posr, new_final_posr, new_body_posr); + dBodySetRotation(g->body, new_body_posr.R); + dBodySetPosition(g->body, new_body_posr.pos[0], new_body_posr.pos[1], new_body_posr.pos[2]); + } + if (g->body) { + // this will call dGeomMoved (g), so we don't have to + dBodySetQuaternion (g->body,quat); + } + else { + dQtoR (quat, g->final_posr->R); + dGeomMoved (g); + } +} + + +const dReal * dGeomGetPosition (dxGeom *g) +{ + dAASSERT (g); + dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); + + return g->buildUpdatedPosition(); +} + + +void dGeomCopyPosition(dxGeom *g, dVector3 pos) +{ + dAASSERT (g); + dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); + + const dVector3 &src = g->buildUpdatedPosition(); + pos[0] = src[dV3E_X]; + pos[1] = src[dV3E_Y]; + pos[2] = src[dV3E_Z]; +} + + +const dReal * dGeomGetRotation (dxGeom *g) +{ + dAASSERT (g); + dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); + + return g->buildUpdatedRotation(); +} + + +void dGeomCopyRotation(dxGeom *g, dMatrix3 R) +{ + dAASSERT (g); + dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); + + const dMatrix3 &src = g->buildUpdatedRotation(); + R[0] = src[dM3E_XX]; + R[1] = src[dM3E_XY]; + R[2] = src[dM3E_XZ]; + R[4] = src[dM3E_YX]; + R[5] = src[dM3E_YY]; + R[6] = src[dM3E_YZ]; + R[8] = src[dM3E_ZX]; + R[9] = src[dM3E_ZY]; + R[10] = src[dM3E_ZZ]; +} + + +void dGeomGetQuaternion (dxGeom *g, dQuaternion quat) +{ + dAASSERT (g); + dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); + if (g->body && !g->offset_posr) { + const dReal * body_quat = dBodyGetQuaternion (g->body); + quat[0] = body_quat[0]; + quat[1] = body_quat[1]; + quat[2] = body_quat[2]; + quat[3] = body_quat[3]; + } + else { + g->recomputePosr(); + dRtoQ (g->final_posr->R, quat); + } +} + + +void dGeomGetAABB (dxGeom *g, dReal aabb[6]) +{ + dAASSERT (g); + dAASSERT (aabb); + g->recomputeAABB(); + memcpy (aabb,g->aabb,6 * sizeof(dReal)); +} + + +int dGeomIsSpace (dxGeom *g) +{ + dAASSERT (g); + return IS_SPACE(g); +} + + +dSpaceID dGeomGetSpace (dxGeom *g) +{ + dAASSERT (g); + return g->parent_space; +} + + +int dGeomGetClass (dxGeom *g) +{ + dAASSERT (g); + return g->type; +} + + +void dGeomSetCategoryBits (dxGeom *g, unsigned long bits) +{ + dAASSERT (g); + CHECK_NOT_LOCKED (g->parent_space); + g->category_bits = bits; +} + + +void dGeomSetCollideBits (dxGeom *g, unsigned long bits) +{ + dAASSERT (g); + CHECK_NOT_LOCKED (g->parent_space); + g->collide_bits = bits; +} + + +unsigned long dGeomGetCategoryBits (dxGeom *g) +{ + dAASSERT (g); + return g->category_bits; +} + + +unsigned long dGeomGetCollideBits (dxGeom *g) +{ + dAASSERT (g); + return g->collide_bits; +} + + +void dGeomEnable (dxGeom *g) +{ + dAASSERT (g); + g->gflags |= GEOM_ENABLED; +} + +void dGeomDisable (dxGeom *g) +{ + dAASSERT (g); + g->gflags &= ~GEOM_ENABLED; +} + +int dGeomIsEnabled (dxGeom *g) +{ + dAASSERT (g); + return (g->gflags & GEOM_ENABLED) != 0; +} + + +void dGeomGetRelPointPos (dGeomID g, dReal px, dReal py, dReal pz, dVector3 result) +{ + dAASSERT (g); + + if ((g->gflags & GEOM_PLACEABLE) == 0) { + result[0] = px; + result[1] = py; + result[2] = pz; + return; + } + + g->recomputePosr(); + + dVector3 prel,p; + prel[0] = px; + prel[1] = py; + prel[2] = pz; + prel[3] = 0; + dMultiply0_331 (p,g->final_posr->R,prel); + result[0] = p[0] + g->final_posr->pos[0]; + result[1] = p[1] + g->final_posr->pos[1]; + result[2] = p[2] + g->final_posr->pos[2]; +} + + +void dGeomGetPosRelPoint (dGeomID g, dReal px, dReal py, dReal pz, dVector3 result) +{ + dAASSERT (g); + if ((g->gflags & GEOM_PLACEABLE) == 0) { + result[0] = px; + result[1] = py; + result[2] = pz; + return; + } + + g->recomputePosr(); + + dVector3 prel; + prel[0] = px - g->final_posr->pos[0]; + prel[1] = py - g->final_posr->pos[1]; + prel[2] = pz - g->final_posr->pos[2]; + prel[3] = 0; + dMultiply1_331 (result,g->final_posr->R,prel); +} + + +void dGeomVectorToWorld (dGeomID g, dReal px, dReal py, dReal pz, dVector3 result) +{ + dAASSERT (g); + if ((g->gflags & GEOM_PLACEABLE) == 0) { + result[0] = px; + result[1] = py; + result[2] = pz; + return; + } + + g->recomputePosr(); + + dVector3 p; + p[0] = px; + p[1] = py; + p[2] = pz; + p[3] = 0; + dMultiply0_331 (result,g->final_posr->R,p); +} + + +void dGeomVectorFromWorld (dGeomID g, dReal px, dReal py, dReal pz, dVector3 result) +{ + dAASSERT (g); + if ((g->gflags & GEOM_PLACEABLE) == 0) { + result[0] = px; + result[1] = py; + result[2] = pz; + return; + } + + g->recomputePosr(); + + dVector3 p; + p[0] = px; + p[1] = py; + p[2] = pz; + p[3] = 0; + dMultiply1_331 (result,g->final_posr->R,p); +} + + + +int dGeomLowLevelControl (dxGeom *g, int controlClass, int controlCode, void *dataValue, int *dataSize) +{ + dAASSERT (g); + dAASSERT (dataSize); + + if (!dataSize) { + return false; + } + + bool result = g->controlGeometry(controlClass, controlCode, dataValue, dataSize); + return result; +} + +//**************************************************************************** +// C interface that lets the user make new classes. this interface is a lot +// more cumbersome than C++ subclassing, which is what is used internally +// in ODE. this API is mainly to support legacy code. + +static int num_user_classes = 0; +static dGeomClass user_classes [dMaxUserClasses]; + + +struct dxUserGeom : public dxGeom { + void *user_data; + + dxUserGeom (int class_num); + ~dxUserGeom(); + void computeAABB(); + int AABBTest (dxGeom *o, dReal aabb[6]); +}; + + +dxUserGeom::dxUserGeom (int class_num) : dxGeom (0,1) +{ + type = class_num; + int size = user_classes[type-dFirstUserClass].bytes; + user_data = dAlloc (size); + memset (user_data,0,size); +} + + +dxUserGeom::~dxUserGeom() +{ + dGeomClass *c = &user_classes[type-dFirstUserClass]; + if (c->dtor) c->dtor (this); + dFree (user_data,c->bytes); +} + + +void dxUserGeom::computeAABB() +{ + user_classes[type-dFirstUserClass].aabb (this,aabb); +} + + +int dxUserGeom::AABBTest (dxGeom *o, dReal aabb[6]) +{ + dGeomClass *c = &user_classes[type-dFirstUserClass]; + if (c->aabb_test) return c->aabb_test (this,o,aabb); + else return 1; +} + + +static int dCollideUserGeomWithGeom (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) +{ + // this generic collider function is called the first time that a user class + // tries to collide against something. it will find out the correct collider + // function and then set the colliders array so that the correct function is + // called directly the next time around. + + int t1 = o1->type; // note that o1 is a user geom + int t2 = o2->type; // o2 *may* be a user geom + + // find the collider function to use. if o1 does not know how to collide with + // o2, then o2 might know how to collide with o1 (provided that it is a user + // geom). + dColliderFn *fn = user_classes[t1-dFirstUserClass].collider (t2); + int reverse = 0; + if (!fn && t2 >= dFirstUserClass && t2 <= dLastUserClass) { + fn = user_classes[t2-dFirstUserClass].collider (t1); + reverse = 1; + } + + // set the colliders array so that the correct function is called directly + // the next time around. note that fn can be 0 here if no collider was found, + // which means that dCollide() will always return 0 for this case. + colliders[t1][t2].fn = fn; + colliders[t1][t2].reverse = reverse; + colliders[t2][t1].fn = fn; + colliders[t2][t1].reverse = !reverse; + + // now call the collider function indirectly through dCollide(), so that + // contact reversing is properly handled. + return dCollide (o1,o2,flags,contact,skip); +} + + +int dCreateGeomClass (const dGeomClass *c) +{ + dUASSERT(c && c->bytes >= 0 && c->collider && c->aabb,"bad geom class"); + + if (num_user_classes >= dMaxUserClasses) { + dDebug (0,"too many user classes, you must increase the limit and " + "recompile ODE"); + } + user_classes[num_user_classes] = *c; + int class_number = num_user_classes + dFirstUserClass; + setAllColliders (class_number,&dCollideUserGeomWithGeom); + + num_user_classes++; + return class_number; +} + +/*extern */void dFinitUserClasses() +{ + num_user_classes = 0; +} + +void * dGeomGetClassData (dxGeom *g) +{ + dUASSERT (g && g->type >= dFirstUserClass && + g->type <= dLastUserClass,"not a custom class"); + dxUserGeom *user = (dxUserGeom*) g; + return user->user_data; +} + + +dGeomID dCreateGeom (int classnum) +{ + dUASSERT (classnum >= dFirstUserClass && + classnum <= dLastUserClass,"not a custom class"); + return new dxUserGeom (classnum); +} + + + +/* ************************************************************************ */ +/* geom offset from body */ + +void dGeomCreateOffset (dxGeom *g) +{ + dAASSERT (g); + dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); + dUASSERT (g->body, "geom must be on a body"); + if (g->offset_posr) + { + return; // already created + } + dIASSERT (g->final_posr == &g->body->posr); + + g->final_posr = dAllocPosr(); + g->offset_posr = dAllocPosr(); + dSetZero (g->offset_posr->pos,4); + dRSetIdentity (g->offset_posr->R); + + g->gflags |= GEOM_POSR_BAD; +} + +void dGeomSetOffsetPosition (dxGeom *g, dReal x, dReal y, dReal z) +{ + dAASSERT (g); + dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); + dUASSERT (g->body, "geom must be on a body"); + CHECK_NOT_LOCKED (g->parent_space); + if (!g->offset_posr) + { + dGeomCreateOffset(g); + } + g->offset_posr->pos[0] = x; + g->offset_posr->pos[1] = y; + g->offset_posr->pos[2] = z; + dGeomMoved (g); +} + +void dGeomSetOffsetRotation (dxGeom *g, const dMatrix3 R) +{ + dAASSERT (g && R); + dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); + dUASSERT (g->body, "geom must be on a body"); + CHECK_NOT_LOCKED (g->parent_space); + if (!g->offset_posr) + { + dGeomCreateOffset (g); + } + memcpy (g->offset_posr->R,R,sizeof(dMatrix3)); + dGeomMoved (g); +} + +void dGeomSetOffsetQuaternion (dxGeom *g, const dQuaternion quat) +{ + dAASSERT (g && quat); + dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); + dUASSERT (g->body, "geom must be on a body"); + CHECK_NOT_LOCKED (g->parent_space); + if (!g->offset_posr) + { + dGeomCreateOffset (g); + } + dQtoR (quat, g->offset_posr->R); + dGeomMoved (g); +} + +void dGeomSetOffsetWorldPosition (dxGeom *g, dReal x, dReal y, dReal z) +{ + dAASSERT (g); + dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); + dUASSERT (g->body, "geom must be on a body"); + CHECK_NOT_LOCKED (g->parent_space); + if (!g->offset_posr) + { + dGeomCreateOffset(g); + } + dBodyGetPosRelPoint(g->body, x, y, z, g->offset_posr->pos); + dGeomMoved (g); +} + +void dGeomSetOffsetWorldRotation (dxGeom *g, const dMatrix3 R) +{ + dAASSERT (g && R); + dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); + dUASSERT (g->body, "geom must be on a body"); + CHECK_NOT_LOCKED (g->parent_space); + if (!g->offset_posr) + { + dGeomCreateOffset (g); + } + g->recomputePosr(); + + dxPosR new_final_posr; + memcpy(new_final_posr.pos, g->final_posr->pos, sizeof(dVector3)); + memcpy(new_final_posr.R, R, sizeof(dMatrix3)); + + getWorldOffsetPosr(g->body->posr, new_final_posr, *g->offset_posr); + dGeomMoved (g); +} + +void dGeomSetOffsetWorldQuaternion (dxGeom *g, const dQuaternion quat) +{ + dAASSERT (g && quat); + dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); + dUASSERT (g->body, "geom must be on a body"); + CHECK_NOT_LOCKED (g->parent_space); + if (!g->offset_posr) + { + dGeomCreateOffset (g); + } + + g->recomputePosr(); + + dxPosR new_final_posr; + memcpy(new_final_posr.pos, g->final_posr->pos, sizeof(dVector3)); + dQtoR (quat, new_final_posr.R); + + getWorldOffsetPosr(g->body->posr, new_final_posr, *g->offset_posr); + dGeomMoved (g); +} + +void dGeomClearOffset(dxGeom *g) +{ + dAASSERT (g); + dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); + if (g->offset_posr) + { + dIASSERT(g->body); + // no longer need an offset posr + dFreePosr(g->offset_posr); + g->offset_posr = 0; + // the geom will now share the position of the body + dFreePosr(g->final_posr); + g->final_posr = &g->body->posr; + // geom has moved + g->gflags &= ~GEOM_POSR_BAD; + dGeomMoved (g); + } +} + +int dGeomIsOffset(dxGeom *g) +{ + dAASSERT (g); + return ((0 != g->offset_posr) ? 1 : 0); +} + +static const dVector3 OFFSET_POSITION_ZERO = { 0.0f, 0.0f, 0.0f, 0.0f }; + +const dReal * dGeomGetOffsetPosition (dxGeom *g) +{ + dAASSERT (g); + if (g->offset_posr) + { + return g->offset_posr->pos; + } + return OFFSET_POSITION_ZERO; +} + +void dGeomCopyOffsetPosition (dxGeom *g, dVector3 pos) +{ + dAASSERT (g); + if (g->offset_posr) + { + const dReal* src = g->offset_posr->pos; + pos[0] = src[0]; + pos[1] = src[1]; + pos[2] = src[2]; + } + else + { + pos[0] = 0; + pos[1] = 0; + pos[2] = 0; + } +} + +static const dMatrix3 OFFSET_ROTATION_ZERO = +{ + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, +}; + +const dReal * dGeomGetOffsetRotation (dxGeom *g) +{ + dAASSERT (g); + if (g->offset_posr) + { + return g->offset_posr->R; + } + return OFFSET_ROTATION_ZERO; +} + +void dGeomCopyOffsetRotation (dxGeom *g, dMatrix3 R) +{ + dAASSERT (g); + if (g->offset_posr) + { + const dReal* src = g->offset_posr->R; + R[0] = src[0]; + R[1] = src[1]; + R[2] = src[2]; + R[4] = src[4]; + R[5] = src[5]; + R[6] = src[6]; + R[8] = src[8]; + R[9] = src[9]; + R[10] = src[10]; + } + else + { + R[0] = OFFSET_ROTATION_ZERO[0]; + R[1] = OFFSET_ROTATION_ZERO[1]; + R[2] = OFFSET_ROTATION_ZERO[2]; + R[4] = OFFSET_ROTATION_ZERO[4]; + R[5] = OFFSET_ROTATION_ZERO[5]; + R[6] = OFFSET_ROTATION_ZERO[6]; + R[8] = OFFSET_ROTATION_ZERO[8]; + R[9] = OFFSET_ROTATION_ZERO[9]; + R[10] = OFFSET_ROTATION_ZERO[10]; + } +} + +void dGeomGetOffsetQuaternion (dxGeom *g, dQuaternion result) +{ + dAASSERT (g); + if (g->offset_posr) + { + dRtoQ (g->offset_posr->R, result); + } + else + { + dSetZero (result,4); + result[0] = 1; + } +} + + diff --git a/libs/ode-0.16.1/ode/src/collision_kernel.h b/libs/ode-0.16.1/ode/src/collision_kernel.h new file mode 100644 index 0000000..c982972 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_kernel.h @@ -0,0 +1,293 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +internal data structures and functions for collision detection. + +*/ + +#ifndef _ODE_COLLISION_KERNEL_H_ +#define _ODE_COLLISION_KERNEL_H_ + +#include <ode/common.h> +#include <ode/contact.h> +#include <ode/collision.h> +#include "objects.h" +#include "odetls.h" +#include "common.h" + + +//**************************************************************************** +// constants and macros + +// mask for the number-of-contacts field in the dCollide() flags parameter +#define NUMC_MASK (0xffff) + +#define IS_SPACE(geom) \ + dIN_RANGE((geom)->type, dFirstSpaceClass, dLastSpaceClass + 1) + +#define CHECK_NOT_LOCKED(space) \ + dUASSERT ((space) == NULL || (space)->lock_count == 0, \ + "Invalid operation for locked space") + + +//**************************************************************************** +// geometry object base class + + +// geom flags. +// +// GEOM_DIRTY means that the space data structures for this geom are +// potentially not up to date. NOTE THAT all space parents of a dirty geom +// are themselves dirty. this is an invariant that must be enforced. +// +// GEOM_AABB_BAD means that the cached AABB for this geom is not up to date. +// note that GEOM_DIRTY does not imply GEOM_AABB_BAD, as the geom might +// recalculate its own AABB but does not know how to update the space data +// structures for the space it is in. but GEOM_AABB_BAD implies GEOM_DIRTY. +// the valid combinations are: +// 0 +// GEOM_DIRTY +// GEOM_DIRTY|GEOM_AABB_BAD +// GEOM_DIRTY|GEOM_AABB_BAD|GEOM_POSR_BAD + +enum { + GEOM_DIRTY = 1, // geom is 'dirty', i.e. position unknown + GEOM_POSR_BAD = 2, // geom's final posr is not valid + GEOM_AABB_BAD = 4, // geom's AABB is not valid + GEOM_PLACEABLE = 8, // geom is placeable + GEOM_ENABLED = 16, // geom is enabled + GEOM_ZERO_SIZED = 32, // geom is zero sized + + GEOM_ENABLE_TEST_MASK = GEOM_ENABLED | GEOM_ZERO_SIZED, + GEOM_ENABLE_TEST_VALUE = GEOM_ENABLED, + + // Ray specific + RAY_FIRSTCONTACT = 0x10000, + RAY_BACKFACECULL = 0x20000, + RAY_CLOSEST_HIT = 0x40000 +}; + +enum dxContactMergeOptions { + DONT_MERGE_CONTACTS, + MERGE_CONTACT_NORMALS, + MERGE_CONTACTS_FULLY +}; + + +// geometry object base class. pos and R will either point to a separately +// allocated buffer (if body is 0 - pos points to the dxPosR object) or to +// the pos and R of the body (if body nonzero). +// a dGeomID is a pointer to this object. + +struct dxGeom : public dBase { + int type; // geom type number, set by subclass constructor + int gflags; // flags used by geom and space + void *data; // user-defined data pointer + dBodyID body; // dynamics body associated with this object (if any) + dxGeom *body_next; // next geom in body's linked list of associated geoms + dxPosR *final_posr; // final position of the geom in world coordinates + dxPosR *offset_posr; // offset from body in local coordinates + + // information used by spaces + dxGeom *next; // next geom in linked list of geoms + dxGeom **tome; // linked list backpointer + dxGeom *next_ex; // next geom in extra linked list of geoms (for higher level structures) + dxGeom **tome_ex; // extra linked list backpointer (for higher level structures) + dxSpace *parent_space;// the space this geom is contained in, 0 if none + dReal aabb[6]; // cached AABB for this space + unsigned long category_bits,collide_bits; + + dxGeom (dSpaceID _space, int is_placeable); + virtual ~dxGeom(); + + // Set or clear GEOM_ZERO_SIZED flag + void updateZeroSizedFlag(bool is_zero_sized) { gflags = is_zero_sized ? (gflags | GEOM_ZERO_SIZED) : (gflags & ~GEOM_ZERO_SIZED); } + // Get parent space TLS kind + unsigned getParentSpaceTLSKind() const; + + const dVector3 &buildUpdatedPosition() + { + dIASSERT(gflags & GEOM_PLACEABLE); + + recomputePosr(); + return final_posr->pos; + } + + const dMatrix3 &buildUpdatedRotation() + { + dIASSERT(gflags & GEOM_PLACEABLE); + + recomputePosr(); + return final_posr->R; + } + + // recalculate our new final position if needed + void recomputePosr() + { + if (gflags & GEOM_POSR_BAD) { + computePosr(); + gflags &= ~GEOM_POSR_BAD; + } + } + + // calculate our new final position from our offset and body + void computePosr(); + + bool checkControlValueSizeValidity(void *dataValue, int *dataSize, int iRequiresSize) { return (*dataSize == iRequiresSize && dataValue != 0) ? true : !(*dataSize = iRequiresSize); } // Here it is the intent to return true for 0 required size in any case + virtual bool controlGeometry(int controlClass, int controlCode, void *dataValue, int *dataSize); + + virtual void computeAABB()=0; + // compute the AABB for this object and put it in aabb. this function + // always performs a fresh computation, it does not inspect the + // GEOM_AABB_BAD flag. + + virtual int AABBTest (dxGeom *o, dReal aabb[6]); + // test whether the given AABB object intersects with this object, return + // 1=yes, 0=no. this is used as an early-exit test in the space collision + // functions. the default implementation returns 1, which is the correct + // behavior if no more detailed implementation can be provided. + + // utility functions + + // compute the AABB only if it is not current. this function manipulates + // the GEOM_AABB_BAD flag. + + void recomputeAABB() { + if (gflags & GEOM_AABB_BAD) { + // our aabb functions assume final_posr is up to date + recomputePosr(); + computeAABB(); + gflags &= ~GEOM_AABB_BAD; + } + } + + inline void markAABBBad(); + + // add and remove this geom from a linked list maintained by a space. + + void spaceAdd (dxGeom **first_ptr) { + next = *first_ptr; + tome = first_ptr; + if (*first_ptr) (*first_ptr)->tome = &next; + *first_ptr = this; + } + void spaceRemove() { + if (next) next->tome = tome; + *tome = next; + } + + // add and remove this geom from a linked list maintained by a body. + + void bodyAdd (dxBody *b) { + body = b; + body_next = b->geom; + b->geom = this; + } + void bodyRemove(); +}; + +//**************************************************************************** +// the base space class +// +// the contained geoms are divided into two kinds: clean and dirty. +// the clean geoms have not moved since they were put in the list, +// and their AABBs are valid. the dirty geoms have changed position, and +// their AABBs are may not be valid. the two types are distinguished by the +// GEOM_DIRTY flag. all dirty geoms come *before* all clean geoms in the list. + +#if dTLS_ENABLED +#define dSPACE_TLS_KIND_INIT_VALUE OTK__DEFAULT +#define dSPACE_TLS_KIND_MANUAL_VALUE OTK_MANUALCLEANUP +#else +#define dSPACE_TLS_KIND_INIT_VALUE 0 +#define dSPACE_TLS_KIND_MANUAL_VALUE 0 +#endif + +struct dxSpace : public dxGeom { + int count; // number of geoms in this space + dxGeom *first; // first geom in list + int cleanup; // cleanup mode, 1=destroy geoms on exit + int sublevel; // space sublevel (used in dSpaceCollide2). NOT TRACKED AUTOMATICALLY!!! + unsigned tls_kind; // space TLS kind to be used for global caches retrieval + + // cached state for getGeom() + int current_index; // only valid if current_geom != 0 + dxGeom *current_geom; // if 0 then there is no information + + // locking stuff. the space is locked when it is currently traversing its + // internal data structures, e.g. in collide() and collide2(). operations + // that modify the contents of the space are not permitted when the space + // is locked. + int lock_count; + + dxSpace (dSpaceID _space); + ~dxSpace(); + + void computeAABB(); + + void setCleanup (int mode) { cleanup = (mode != 0); } + int getCleanup() const { return cleanup; } + void setSublevel(int value) { sublevel = value; } + int getSublevel() const { return sublevel; } + void setManulCleanup(int value) { tls_kind = (value ? dSPACE_TLS_KIND_MANUAL_VALUE : dSPACE_TLS_KIND_INIT_VALUE); } + int getManualCleanup() const { return (tls_kind == dSPACE_TLS_KIND_MANUAL_VALUE) ? 1 : 0; } + int query (dxGeom *geom) const { dAASSERT(geom); return (geom->parent_space == this); } + int getNumGeoms() const { return count; } + + virtual dxGeom *getGeom (int i); + + virtual void add (dxGeom *); + virtual void remove (dxGeom *); + virtual void dirty (dxGeom *); + + virtual void cleanGeoms()=0; + // turn all dirty geoms into clean geoms by computing their AABBs and any + // other space data structures that are required. this should clear the + // GEOM_DIRTY and GEOM_AABB_BAD flags of all geoms. + + virtual void collide (void *data, dNearCallback *callback)=0; + virtual void collide2 (void *data, dxGeom *geom, dNearCallback *callback)=0; +}; + + +////////////////////////////////////////////////////////////////////////// + +/*inline */ +void dxGeom::markAABBBad() { + gflags |= (GEOM_DIRTY | GEOM_AABB_BAD); + CHECK_NOT_LOCKED(parent_space); +} + + +//**************************************************************************** +// Initialization and finalization functions + +void dInitColliders(); +void dFinitColliders(); + +void dClearPosrCache(void); +void dFinitUserClasses(); + + +#endif diff --git a/libs/ode-0.16.1/ode/src/collision_libccd.cpp b/libs/ode-0.16.1/ode/src/collision_libccd.cpp new file mode 100644 index 0000000..ba15e83 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_libccd.cpp @@ -0,0 +1,1080 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <ode/collision.h> +#include <ccd/ccd.h> +#include "ccdcustom/vec3.h" +#include "ccdcustom/quat.h" +#include "config.h" +#include "odemath.h" +#include "collision_libccd.h" +#include "collision_trimesh_internal.h" +#include "collision_std.h" +#include "collision_util.h" +#include "error.h" + + +struct _ccd_obj_t { + ccd_vec3_t pos; + ccd_quat_t rot, rot_inv; +}; +typedef struct _ccd_obj_t ccd_obj_t; + +struct _ccd_box_t { + ccd_obj_t o; + ccd_real_t dim[3]; +}; +typedef struct _ccd_box_t ccd_box_t; + +struct _ccd_cap_t { + ccd_obj_t o; + ccd_real_t radius; + ccd_vec3_t axis; + ccd_vec3_t p1; + ccd_vec3_t p2; +}; +typedef struct _ccd_cap_t ccd_cap_t; + +struct _ccd_cyl_t { + ccd_obj_t o; + ccd_real_t radius; + ccd_vec3_t axis; + ccd_vec3_t p1; + ccd_vec3_t p2; +}; +typedef struct _ccd_cyl_t ccd_cyl_t; + +struct _ccd_sphere_t { + ccd_obj_t o; + ccd_real_t radius; +}; +typedef struct _ccd_sphere_t ccd_sphere_t; + +struct _ccd_convex_t { + ccd_obj_t o; + dxConvex *convex; +}; +typedef struct _ccd_convex_t ccd_convex_t; + +struct _ccd_triangle_t { + ccd_obj_t o; + ccd_vec3_t vertices[3]; +}; +typedef struct _ccd_triangle_t ccd_triangle_t; + +/** Transforms geom to ccd struct */ +static void ccdGeomToObj(const dGeomID g, ccd_obj_t *); +static void ccdGeomToBox(const dGeomID g, ccd_box_t *); +static void ccdGeomToCap(const dGeomID g, ccd_cap_t *); +static void ccdGeomToCyl(const dGeomID g, ccd_cyl_t *); +static void ccdGeomToSphere(const dGeomID g, ccd_sphere_t *); +static void ccdGeomToConvex(const dGeomID g, ccd_convex_t *); + +/** Support functions */ +static void ccdSupportBox(const void *obj, const ccd_vec3_t *_dir, ccd_vec3_t *v); +static void ccdSupportCap(const void *obj, const ccd_vec3_t *_dir, ccd_vec3_t *v); +static void ccdSupportCyl(const void *obj, const ccd_vec3_t *_dir, ccd_vec3_t *v); +static void ccdSupportSphere(const void *obj, const ccd_vec3_t *_dir, ccd_vec3_t *v); +static void ccdSupportConvex(const void *obj, const ccd_vec3_t *_dir, ccd_vec3_t *v); + +/** Center function */ +static void ccdCenter(const void *obj, ccd_vec3_t *c); + +/** General collide function */ +static int ccdCollide(dGeomID o1, dGeomID o2, int flags, + dContactGeom *contact, int skip, + void *obj1, ccd_support_fn supp1, ccd_center_fn cen1, + void *obj2, ccd_support_fn supp2, ccd_center_fn cen2); + +static int collideCylCyl(dxGeom *o1, dxGeom *o2, ccd_cyl_t* cyl1, ccd_cyl_t* cyl2, int flags, dContactGeom *contacts, int skip); +static bool testAndPrepareDiscContactForAngle(dReal angle, dReal radius, dReal length, dReal lSum, ccd_cyl_t *priCyl, ccd_cyl_t *secCyl, ccd_vec3_t &p, dReal &out_depth); +// Adds a contact between 2 cylinders +static int addCylCylContact(dxGeom *o1, dxGeom *o2, ccd_vec3_t* axis, dContactGeom *contacts, ccd_vec3_t* p, dReal normaldir, dReal depth, int j, int flags, int skip); + +static unsigned addTrianglePerturbedContacts(dxGeom *o1, dxGeom *o2, IFaceAngleStorageView *meshFaceAngleView, + const int *indices, unsigned numIndices, int flags, dContactGeom *contacts, int skip, + ccd_convex_t *c1, ccd_triangle_t *c2, dVector3 *triangle, dContactGeom *contact, unsigned contacCount); +static bool correctTriangleContactNormal(ccd_triangle_t *t, dContactGeom *contact, IFaceAngleStorageView *meshFaceAngleView, const int *indices, unsigned numIndices); +static unsigned addUniqueContact(dContactGeom *contacts, dContactGeom *c, unsigned contactcount, unsigned maxcontacts, int flags, int skip); +static void setObjPosToTriangleCenter(ccd_triangle_t *t); +static void ccdSupportTriangle(const void *obj, const ccd_vec3_t *_dir, ccd_vec3_t *v); + + +static +void ccdGeomToObj(const dGeomID g, ccd_obj_t *o) +{ + const dReal *ode_pos; + dQuaternion ode_rot; + + ode_pos = dGeomGetPosition(g); + dGeomGetQuaternion(g, ode_rot); + + ccdVec3Set(&o->pos, ode_pos[0], ode_pos[1], ode_pos[2]); + ccdQuatSet(&o->rot, ode_rot[1], ode_rot[2], ode_rot[3], ode_rot[0]); + + ccdQuatInvert2(&o->rot_inv, &o->rot); +} + +static +void ccdGeomToBox(const dGeomID g, ccd_box_t *box) +{ + dVector3 dim; + + ccdGeomToObj(g, (ccd_obj_t *)box); + + dGeomBoxGetLengths(g, dim); + box->dim[0] = (ccd_real_t)(dim[0] * 0.5); + box->dim[1] = (ccd_real_t)(dim[1] * 0.5); + box->dim[2] = (ccd_real_t)(dim[2] * 0.5); +} + +static +void ccdGeomToCap(const dGeomID g, ccd_cap_t *cap) +{ + dReal r, h; + ccdGeomToObj(g, (ccd_obj_t *)cap); + + dGeomCapsuleGetParams(g, &r, &h); + cap->radius = r; + ccdVec3Set(&cap->axis, 0.0, 0.0, h / 2); + ccdQuatRotVec(&cap->axis, &cap->o.rot); + ccdVec3Copy(&cap->p1, &cap->axis); + ccdVec3Copy(&cap->p2, &cap->axis); + ccdVec3Scale(&cap->p2, -1.0); + ccdVec3Add(&cap->p1, &cap->o.pos); + ccdVec3Add(&cap->p2, &cap->o.pos); +} + +static +void ccdGeomToCyl(const dGeomID g, ccd_cyl_t *cyl) +{ + dReal r, h; + ccdGeomToObj(g, (ccd_obj_t *)cyl); + + dGeomCylinderGetParams(g, &r, &h); + cyl->radius = r; + ccdVec3Set(&cyl->axis, 0.0, 0.0, h / 2); + ccdQuatRotVec(&cyl->axis, &cyl->o.rot); + ccdVec3Copy(&cyl->p1, &cyl->axis); + ccdVec3Copy(&cyl->p2, &cyl->axis); + int cylAxisNormalizationResult = ccdVec3SafeNormalize(&cyl->axis); + dUVERIFY(cylAxisNormalizationResult == 0, "Invalid cylinder has been passed"); + ccdVec3Scale(&cyl->p2, -1.0); + ccdVec3Add(&cyl->p1, &cyl->o.pos); + ccdVec3Add(&cyl->p2, &cyl->o.pos); +} + +static +void ccdGeomToSphere(const dGeomID g, ccd_sphere_t *s) +{ + ccdGeomToObj(g, (ccd_obj_t *)s); + s->radius = dGeomSphereGetRadius(g); +} + +static +void ccdGeomToConvex(const dGeomID g, ccd_convex_t *c) +{ + ccdGeomToObj(g, (ccd_obj_t *)c); + c->convex = (dxConvex *)g; +} + + +static +void ccdSupportBox(const void *obj, const ccd_vec3_t *_dir, ccd_vec3_t *v) +{ + const ccd_box_t *o = (const ccd_box_t *)obj; + ccd_vec3_t dir; + + ccdVec3Copy(&dir, _dir); + ccdQuatRotVec(&dir, &o->o.rot_inv); + + ccdVec3Set(v, ccdSign(ccdVec3X(&dir)) * o->dim[0], + ccdSign(ccdVec3Y(&dir)) * o->dim[1], + ccdSign(ccdVec3Z(&dir)) * o->dim[2]); + + // transform support vertex + ccdQuatRotVec(v, &o->o.rot); + ccdVec3Add(v, &o->o.pos); +} + +static +void ccdSupportCap(const void *obj, const ccd_vec3_t *_dir, ccd_vec3_t *v) +{ + const ccd_cap_t *o = (const ccd_cap_t *)obj; + + ccdVec3Copy(v, _dir); + ccdVec3Scale(v, o->radius); + + if (ccdVec3Dot(_dir, &o->axis) > 0.0){ + ccdVec3Add(v, &o->p1); + }else{ + ccdVec3Add(v, &o->p2); + } + +} + +static +void ccdSupportCyl(const void *obj, const ccd_vec3_t *_dir, ccd_vec3_t *v) +{ + const ccd_cyl_t *cyl = (const ccd_cyl_t *)obj; + ccd_vec3_t dir; + ccd_real_t len; + + ccd_real_t dot = ccdVec3Dot(_dir, &cyl->axis); + if (dot > 0.0){ + ccdVec3Copy(v, &cyl->p1); + } else{ + ccdVec3Copy(v, &cyl->p2); + } + // project dir onto cylinder's 'top'/'bottom' plane + ccdVec3Copy(&dir, &cyl->axis); + ccdVec3Scale(&dir, -dot); + ccdVec3Add(&dir, _dir); + len = CCD_SQRT(ccdVec3Len2(&dir)); + if (!ccdIsZero(len)) { + ccdVec3Scale(&dir, cyl->radius / len); + ccdVec3Add(v, &dir); + } +} + +static +void ccdSupportSphere(const void *obj, const ccd_vec3_t *_dir, ccd_vec3_t *v) +{ + const ccd_sphere_t *s = (const ccd_sphere_t *)obj; + + ccdVec3Copy(v, _dir); + ccdVec3Scale(v, s->radius); + dIASSERT(dFabs(CCD_SQRT(ccdVec3Len2(_dir)) - REAL(1.0)) < 1e-6); // ccdVec3Scale(v, CCD_ONE / CCD_SQRT(ccdVec3Len2(_dir))); + + ccdVec3Add(v, &s->o.pos); +} + +static +void ccdSupportConvex(const void *obj, const ccd_vec3_t *_dir, ccd_vec3_t *v) +{ + const ccd_convex_t *c = (const ccd_convex_t *)obj; + ccd_vec3_t dir, p; + ccd_real_t maxdot, dot; + sizeint i; + const dReal *curp; + + ccdVec3Copy(&dir, _dir); + ccdQuatRotVec(&dir, &c->o.rot_inv); + + maxdot = -CCD_REAL_MAX; + curp = c->convex->points; + for (i = 0; i < c->convex->pointcount; i++, curp += 3){ + ccdVec3Set(&p, curp[0], curp[1], curp[2]); + dot = ccdVec3Dot(&dir, &p); + if (dot > maxdot){ + ccdVec3Copy(v, &p); + maxdot = dot; + } + } + + + // transform support vertex + ccdQuatRotVec(v, &c->o.rot); + ccdVec3Add(v, &c->o.pos); +} + +static +void ccdCenter(const void *obj, ccd_vec3_t *c) +{ + const ccd_obj_t *o = (const ccd_obj_t *)obj; + ccdVec3Copy(c, &o->pos); +} + +static +int ccdCollide( + dGeomID o1, dGeomID o2, int flags, dContactGeom *contact, int skip, + void *obj1, ccd_support_fn supp1, ccd_center_fn cen1, + void *obj2, ccd_support_fn supp2, ccd_center_fn cen2) +{ + ccd_t ccd; + int res; + ccd_real_t depth; + ccd_vec3_t dir, pos; + int max_contacts = (flags & NUMC_MASK); + + if (max_contacts < 1) + return 0; + + CCD_INIT(&ccd); + ccd.support1 = supp1; + ccd.support2 = supp2; + ccd.center1 = cen1; + ccd.center2 = cen2; + ccd.max_iterations = 500; + ccd.mpr_tolerance = (ccd_real_t)1E-6; + + + if (flags & CONTACTS_UNIMPORTANT){ + if (ccdMPRIntersect(obj1, obj2, &ccd)){ + return 1; + }else{ + return 0; + } + } + + res = ccdMPRPenetration(obj1, obj2, &ccd, &depth, &dir, &pos); + if (res == 0){ + contact->g1 = o1; + contact->g2 = o2; + + contact->side1 = contact->side2 = -1; + + contact->depth = depth; + + contact->pos[0] = ccdVec3X(&pos); + contact->pos[1] = ccdVec3Y(&pos); + contact->pos[2] = ccdVec3Z(&pos); + + ccdVec3Scale(&dir, -1.); + contact->normal[0] = ccdVec3X(&dir); + contact->normal[1] = ccdVec3Y(&dir); + contact->normal[2] = ccdVec3Z(&dir); + + return 1; + } + + return 0; +} + +/*extern */ +int dCollideBoxCylinderCCD(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) +{ + ccd_cyl_t cyl; + ccd_box_t box; + + ccdGeomToBox(o1, &box); + ccdGeomToCyl(o2, &cyl); + + return ccdCollide(o1, o2, flags, contact, skip, + &box, ccdSupportBox, ccdCenter, + &cyl, ccdSupportCyl, ccdCenter); +} + +/*extern */ +int dCollideCapsuleCylinder(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) +{ + ccd_cap_t cap; + ccd_cyl_t cyl; + + ccdGeomToCap(o1, &cap); + ccdGeomToCyl(o2, &cyl); + + return ccdCollide(o1, o2, flags, contact, skip, + &cap, ccdSupportCap, ccdCenter, + &cyl, ccdSupportCyl, ccdCenter); +} + +/*extern */ +int dCollideConvexBoxCCD(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) +{ + ccd_box_t box; + ccd_convex_t conv; + + ccdGeomToConvex(o1, &conv); + ccdGeomToBox(o2, &box); + + return ccdCollide(o1, o2, flags, contact, skip, + &conv, ccdSupportConvex, ccdCenter, + &box, ccdSupportBox, ccdCenter); +} + +/*extern */ +int dCollideConvexCapsuleCCD(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) +{ + ccd_cap_t cap; + ccd_convex_t conv; + + ccdGeomToConvex(o1, &conv); + ccdGeomToCap(o2, &cap); + + return ccdCollide(o1, o2, flags, contact, skip, + &conv, ccdSupportConvex, ccdCenter, + &cap, ccdSupportCap, ccdCenter); +} + +/*extern */ +int dCollideConvexSphereCCD(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) +{ + ccd_sphere_t sphere; + ccd_convex_t conv; + + ccdGeomToConvex(o1, &conv); + ccdGeomToSphere(o2, &sphere); + + return ccdCollide(o1, o2, flags, contact, skip, + &conv, ccdSupportConvex, ccdCenter, + &sphere, ccdSupportSphere, ccdCenter); +} + +/*extern */ +int dCollideConvexCylinderCCD(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) +{ + ccd_cyl_t cyl; + ccd_convex_t conv; + + ccdGeomToConvex(o1, &conv); + ccdGeomToCyl(o2, &cyl); + + return ccdCollide(o1, o2, flags, contact, skip, + &conv, ccdSupportConvex, ccdCenter, + &cyl, ccdSupportCyl, ccdCenter); +} + +/*extern */ +int dCollideConvexConvexCCD(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) +{ + ccd_convex_t c1, c2; + + ccdGeomToConvex(o1, &c1); + ccdGeomToConvex(o2, &c2); + + return ccdCollide(o1, o2, flags, contact, skip, + &c1, ccdSupportConvex, ccdCenter, + &c2, ccdSupportConvex, ccdCenter); +} + + +/*extern */ +int dCollideCylinderCylinder(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) +{ + ccd_cyl_t cyl1, cyl2; + + ccdGeomToCyl(o1, &cyl1); + ccdGeomToCyl(o2, &cyl2); + + int numContacts = collideCylCyl(o1, o2, &cyl1, &cyl2, flags, contact, skip); + if (numContacts < 0) { + numContacts = ccdCollide(o1, o2, flags, contact, skip, + &cyl1, ccdSupportCyl, ccdCenter, + &cyl2, ccdSupportCyl, ccdCenter); + } + return numContacts; +} + +static +int collideCylCyl(dxGeom *o1, dxGeom *o2, ccd_cyl_t* cyl1, ccd_cyl_t* cyl2, int flags, dContactGeom *contacts, int skip) +{ + int maxContacts = (flags & NUMC_MASK); + dAASSERT(maxContacts != 0); + + maxContacts = maxContacts > 8 ? 8 : maxContacts; + + dReal axesProd = dFabs(ccdVec3Dot(&cyl1->axis, &cyl2->axis)); + // Check if cylinders' axes are in line + if (REAL(1.0) - axesProd < 1e-3f) { + ccd_vec3_t p, proj; + dReal r1, l1; + dReal r2, l2; + dGeomCylinderGetParams(o1, &r1, &l1); + dGeomCylinderGetParams(o2, &r2, &l2); + l1 *= 0.5f; + l2 *= 0.5f; + + // Determine the cylinder with smaller radius (minCyl) and bigger radius (maxCyl) and their respective properties: radius, length + bool r1IsMin; + dReal rmin, rmax; + ccd_cyl_t *minCyl, *maxCyl; + if (r1 <= r2) { + rmin = r1; rmax = r2; + minCyl = cyl1; maxCyl = cyl2; + r1IsMin = true; + } + else { + rmin = r2; rmax = r1; + minCyl = cyl2; maxCyl = cyl1; + r1IsMin = false; + } + + dReal lSum = l1 + l2; + + ccdVec3Copy(&p, &minCyl->o.pos); + ccdVec3Sub(&p, &maxCyl->o.pos); + dReal dot = ccdVec3Dot(&p, &maxCyl->axis); + + // Maximum possible contact depth + dReal depth_v = lSum - dFabs(dot) + dSqrt(dMax(0, REAL(1.0) - axesProd * axesProd)) * rmin; + if (depth_v < 0) { + return 0; + } + + // Project the smaller cylinder's center onto the larger cylinder's plane + ccdVec3Copy(&proj, &maxCyl->axis); + ccdVec3Scale(&proj, -dot); + ccdVec3Add(&proj, &p); + dReal radiiDiff = (dReal)sqrt(ccdVec3Len2(&proj)); + dReal depth_h = r1 + r2 - radiiDiff; + + // Check the distance between cylinders' centers + if (depth_h < 0) { + return 0; + } + + // Check if "vertical" contact depth is less than "horizontal" contact depth + if (depth_v < depth_h) { + int contactCount = 0; + dReal dot2 = -ccdVec3Dot(&p, &minCyl->axis); + // lmin, lmax - distances from cylinders' centers to potential contact points relative to cylinders' axes + dReal lmax = r1IsMin ? l2 : l1; + dReal lmin = r1IsMin ? l1 : l2; + lmin = dot2 < 0 ? -lmin : lmin; + lmax = dot < 0 ? -lmax : lmax; + // Contact normal direction, relative to o1's axis + dReal normaldir = (dot < 0) != r1IsMin ? REAL(1.0) : -REAL(1.0); + + if (rmin + radiiDiff <= rmax) { + // Case 1: The smaller disc is fully contained within the larger one + // Simply generate N points on the rim of the smaller disc + dReal maxContactsRecip = (dReal)(0 < maxContacts ? (2.0 * M_PI / maxContacts) : (2.0 * M_PI)); // The 'else' value does not matter. Just try helping the optimizer. + for (int i = 0; i < maxContacts; i++) { + dReal depth; + dReal a = maxContactsRecip * i; + if (testAndPrepareDiscContactForAngle(a, rmin, lmin, lSum, minCyl, maxCyl, p, depth)) { + contactCount = addCylCylContact(o1, o2, &maxCyl->axis, contacts, &p, normaldir, depth, contactCount, flags, skip); + if ((flags & CONTACTS_UNIMPORTANT) != 0) { + dIASSERT(contactCount != 0); + break; + } + } + } + return contactCount; + + } else { + // Case 2: Discs intersect + // Firstly, find intersections assuming the larger cylinder is placed at (0,0,0) + // http://math.stackexchange.com/questions/256100/how-can-i-find-the-points-at-which-two-circles-intersect + ccd_vec3_t proj2; + ccdVec3Copy(&proj2, &proj); + ccdQuatRotVec(&proj, &maxCyl->o.rot_inv); + dReal d = dSqrt(ccdVec3X(&proj) * ccdVec3X(&proj) + ccdVec3Y(&proj) * ccdVec3Y(&proj)); + dIASSERT(d != REAL(0.0)); + + dReal dRecip = REAL(1.0) / d; + dReal rmaxSquare = rmax * rmax, rminSquare = rmin * rmin, dSquare = d * d; + + dReal minA, diffA, minB, diffB; + + { + dReal l = (rmaxSquare - rminSquare + dSquare) * (REAL(0.5) * dRecip); + dReal h = dSqrt(rmaxSquare - l * l); + dReal divLbyD = l * dRecip, divHbyD = h * dRecip; + dReal x1 = divLbyD * ccdVec3X(&proj) + divHbyD * ccdVec3Y(&proj); + dReal y1 = divLbyD * ccdVec3Y(&proj) - divHbyD * ccdVec3X(&proj); + dReal x2 = divLbyD * ccdVec3X(&proj) - divHbyD * ccdVec3Y(&proj); + dReal y2 = divLbyD * ccdVec3Y(&proj) + divHbyD * ccdVec3X(&proj); + // Map the intersection points to angles + dReal ap1 = dAtan2(y1, x1); + dReal ap2 = dAtan2(y2, x2); + minA = dMin(ap1, ap2); + dReal maxA = dMax(ap1, ap2); + // If the segment connecting cylinders' centers does not intersect the arc, change the angles + dReal a = dAtan2(ccdVec3Y(&proj), ccdVec3X(&proj)); + if (a < minA || a > maxA) { + a = maxA; + maxA = (dReal)(minA + M_PI * 2.0); + minA = a; + } + diffA = maxA - minA; + } + + // Do the same for the smaller cylinder assuming it is placed at (0,0,0) now + ccdVec3Copy(&proj, &proj2); + ccdVec3Scale(&proj, -1); + ccdQuatRotVec(&proj, &minCyl->o.rot_inv); + + { + dReal l = (rminSquare - rmaxSquare + dSquare) * (REAL(0.5) * dRecip); + dReal h = dSqrt(rminSquare - l * l); + dReal divLbyD = l * dRecip, divHbyD = h * dRecip; + dReal x1 = divLbyD * ccdVec3X(&proj) + divHbyD * ccdVec3Y(&proj); + dReal y1 = divLbyD * ccdVec3Y(&proj) - divHbyD * ccdVec3X(&proj); + dReal x2 = divLbyD * ccdVec3X(&proj) - divHbyD * ccdVec3Y(&proj); + dReal y2 = divLbyD * ccdVec3Y(&proj) + divHbyD * ccdVec3X(&proj); + dReal ap1 = dAtan2(y1, x1); + dReal ap2 = dAtan2(y2, x2); + minB = dMin(ap1, ap2); + dReal maxB = dMax(ap1, ap2); + dReal a = dAtan2(ccdVec3Y(&proj), ccdVec3X(&proj)); + if (a < minB || a > maxB) { + a = maxB; + maxB = (dReal)(minB + M_PI * 2.0); + minB = a; + } + diffB = maxB - minB; + } + + // Find contact point distribution ratio based on arcs lengths + dReal ratio = diffA * rmax / (diffA * rmax + diffB * rmin); + dIASSERT(ratio <= REAL(1.0)); + dIASSERT(ratio >= REAL(0.0)); + + int nMax = (int)dFloor(ratio * maxContacts + REAL(0.5)); + int nMin = maxContacts - nMax; + dIASSERT(nMax <= maxContacts); + + // Make sure there is at least one point on the smaller radius rim + if (nMin < 1) { + nMin = 1; nMax -= 1; + } + // Otherwise transfer one point to the larger radius rim as it is going to fill the rim intersection points + else if (nMin > 1) { + nMin -= 1; nMax += 1; + } + + // Smaller disc first, skipping the overlapping points + dReal nMinRecip = 0 < nMin ? diffB / (nMin + 1) : diffB; // The 'else' value does not matter. Just try helping the optimizer. + for (int i = 1; i <= nMin; i++) { + dReal depth; + dReal a = minB + nMinRecip * i; + if (testAndPrepareDiscContactForAngle(a, rmin, lmin, lSum, minCyl, maxCyl, p, depth)) { + contactCount = addCylCylContact(o1, o2, &maxCyl->axis, contacts, &p, normaldir, depth, contactCount, flags, skip); + if ((flags & CONTACTS_UNIMPORTANT) != 0) { + dIASSERT(contactCount != 0); + break; + } + } + } + + if (contactCount == 0 || (flags & CONTACTS_UNIMPORTANT) == 0) { + // Then the larger disc, + additional point as the start/end points of arcs overlap + // (or a single contact at the arc middle point if just one is required) + dReal nMaxRecip = nMax > 1 ? diffA / (nMax - 1) : diffA; // The 'else' value does not matter. Just try helping the optimizer. + dReal adjustedMinA = nMax == 1 ? minA + REAL(0.5) * diffA : minA; + + for (int i = 0; i < nMax; i++) { + dReal depth; + dReal a = adjustedMinA + nMaxRecip * i; + if (testAndPrepareDiscContactForAngle(a, rmax, lmax, lSum, maxCyl, minCyl, p, depth)) { + contactCount = addCylCylContact(o1, o2, &maxCyl->axis, contacts, &p, normaldir, depth, contactCount, flags, skip); + if ((flags & CONTACTS_UNIMPORTANT) != 0) { + dIASSERT(contactCount != 0); + break; + } + } + } + } + + return contactCount; + } + } + } + return -1; +} + +static +bool testAndPrepareDiscContactForAngle(dReal angle, dReal radius, dReal length, dReal lSum, ccd_cyl_t *priCyl, ccd_cyl_t *secCyl, ccd_vec3_t &p, dReal &out_depth) +{ + bool ret = false; + + ccd_vec3_t p2; + ccdVec3Set(&p, dCos(angle) * radius, dSin(angle) * radius, 0); + ccdQuatRotVec(&p, &priCyl->o.rot); + ccdVec3Add(&p, &priCyl->o.pos); + ccdVec3Copy(&p2, &p); + ccdVec3Sub(&p2, &secCyl->o.pos); + dReal depth = lSum - dFabs(ccdVec3Dot(&p2, &secCyl->axis)); + + if (depth >= 0) { + ccdVec3Copy(&p2, &priCyl->axis); + ccdVec3Scale(&p2, length); + ccdVec3Add(&p, &p2); + + out_depth = depth; + ret = true; + } + + return ret; +} + +static +int addCylCylContact(dxGeom *o1, dxGeom *o2, ccd_vec3_t* axis, dContactGeom *contacts, + ccd_vec3_t* p, dReal normaldir, dReal depth, int j, int flags, int skip) +{ + dIASSERT(depth >= 0); + + dContactGeom* contact = SAFECONTACT(flags, contacts, j, skip); + contact->g1 = o1; + contact->g2 = o2; + contact->side1 = -1; + contact->side2 = -1; + contact->normal[0] = normaldir * ccdVec3X(axis); + contact->normal[1] = normaldir * ccdVec3Y(axis); + contact->normal[2] = normaldir * ccdVec3Z(axis); + contact->depth = depth; + contact->pos[0] = ccdVec3X(p); + contact->pos[1] = ccdVec3Y(p); + contact->pos[2] = ccdVec3Z(p); + + return j + 1; +} + + +#if dTRIMESH_ENABLED + +const static float CONTACT_DEPTH_EPSILON = 0.0001f; +const static float CONTACT_POS_EPSILON = 0.0001f; +const static float CONTACT_PERTURBATION_ANGLE = 0.001f; +const static float NORMAL_PROJ_EPSILON = 0.0001f; + + +/*extern */ +unsigned dCollideConvexTrimeshTrianglesCCD(dxGeom *o1, dxGeom *o2, const int *indices, unsigned numIndices, int flags, dContactGeom *contacts, int skip) +{ + ccd_convex_t c1; + ccd_triangle_t c2; + dVector3 triangle[dMTV__MAX]; + unsigned maxContacts = (flags & NUMC_MASK); + unsigned contactCount = 0; + ccdGeomToConvex(o1, &c1); + ccdGeomToObj(o2, (ccd_obj_t *)&c2); + + IFaceAngleStorageView *meshFaceAngleView = dxGeomTriMeshGetFaceAngleView(o2); + dUASSERT(meshFaceAngleView != NULL, "Please preprocess the trimesh data with dTRIDATAPREPROCESS_BUILD_FACE_ANGLES"); + + for (unsigned i = 0; i != numIndices; ++i) { + dContactGeom tempContact; + dGeomTriMeshGetTriangle(o2, indices[i], &triangle[dMTV_FIRST], &triangle[dMTV_SECOND], &triangle[dMTV_THIRD]); + + for (unsigned j = dMTV__MIN; j != dMTV__MAX; ++j) { + ccdVec3Set(&c2.vertices[j], (ccd_real_t)triangle[j][dV3E_X], (ccd_real_t)triangle[j][dV3E_Y], (ccd_real_t)triangle[j][dV3E_Z]); + } + + setObjPosToTriangleCenter(&c2); + + if (ccdCollide(o1, o2, flags, &tempContact, skip, &c1, &ccdSupportConvex, &ccdCenter, &c2, &ccdSupportTriangle, &ccdCenter) == 1) { + tempContact.side2 = i; + + if (meshFaceAngleView == NULL || correctTriangleContactNormal(&c2, &tempContact, meshFaceAngleView, indices, numIndices)) { + contactCount = addUniqueContact(contacts, &tempContact, contactCount, maxContacts, flags, skip); + + if ((flags & CONTACTS_UNIMPORTANT) != 0) { + break; + } + } + } + } + + if ((flags & CONTACTS_UNIMPORTANT) == 0 && contactCount == 1) { + dContactGeom *contact = SAFECONTACT(flags, contacts, 0, skip); + dGeomTriMeshGetTriangle(o2, contact->side2, &triangle[dMTV_FIRST], &triangle[dMTV_SECOND], &triangle[dMTV_THIRD]); + contactCount = addTrianglePerturbedContacts(o1, o2, meshFaceAngleView, indices, numIndices, flags, contacts, skip, &c1, &c2, triangle, contact, contactCount); + } + + // Normalize accumulated normals, if necessary + for (unsigned k = 0; k != contactCount; ) { + dContactGeom *contact = SAFECONTACT(flags, contacts, k, skip); + bool stayWithinThisIndex = false; + + // Only the merged contact normals need to be normalized + if (*_const_type_cast_union<bool>(&contact->normal[dV3E_PAD])) { + + if (!dxSafeNormalize3(contact->normal)) { + // If the contact normals have added up to zero, erase the contact + // Normally the time step is to be shorter so that the objects do not get into each other that deep + --contactCount; + + if (k != contactCount) { + dContactGeom *lastContact = SAFECONTACT(flags, contacts, contactCount, skip); + *contact = *lastContact; + } + + stayWithinThisIndex = true; + } + } + + if (!stayWithinThisIndex) { + ++k; + } + } + + return contactCount; +} + +static +unsigned addTrianglePerturbedContacts(dxGeom *o1, dxGeom *o2, IFaceAngleStorageView *meshFaceAngleView, + const int *indices, unsigned numIndices, int flags, dContactGeom *contacts, int skip, + ccd_convex_t *c1, ccd_triangle_t *c2, dVector3 *triangle, dContactGeom *contact, unsigned contacCount) +{ + unsigned maxContacts = (flags & NUMC_MASK); + + dVector3 pos; + dCopyVector3(pos, contact->pos); + + dQuaternion q1[2], q2[2]; + dReal perturbationAngle = CONTACT_PERTURBATION_ANGLE; + + dVector3 upAxis; + bool upAvailable = false; + if (fabs(contact->normal[dV3E_Y]) > 0.7) { + dAssignVector3(upAxis, 0, 0, 1); + } + else { + dAssignVector3(upAxis, 0, 1, 0); + } + + dVector3 cross; + dCalcVectorCross3(cross, contact->normal, upAxis); + + if (dSafeNormalize3(cross)) { + dCalcVectorCross3(upAxis, cross, contact->normal); + + if (dSafeNormalize3(upAxis)) { + upAvailable = true; + } + } + + for (unsigned j = upAvailable ? 0 : 2; j != 2; ++j) { + dQFromAxisAndAngle(q1[j], upAxis[dV3E_X], upAxis[dV3E_Y], upAxis[dV3E_Z], perturbationAngle); + dQFromAxisAndAngle(q2[j], cross[dV3E_X], cross[dV3E_Y], cross[dV3E_Z], perturbationAngle); + perturbationAngle = -perturbationAngle; + } + + for (unsigned k = upAvailable ? 0 : 4; k != 4; ++k) { + dQuaternion qr; + dQMultiply0(qr, q1[k % 2], q2[k / 2]); + + for (unsigned j = dMTV__MIN; j != dMTV__MAX; ++j) { + dVector3 p, perturbed; + dSubtractVectors3(p, triangle[j], pos); + dQuatTransform(qr, p, perturbed); + dAddVectors3(perturbed, perturbed, pos); + + ccdVec3Set(&c2->vertices[j], (ccd_real_t)perturbed[dV3E_X], (ccd_real_t)perturbed[dV3E_Y], (ccd_real_t)perturbed[dV3E_Z]); + } + + dContactGeom perturbedContact; + setObjPosToTriangleCenter(c2); + + if (ccdCollide(o1, o2, flags, &perturbedContact, skip, c1, &ccdSupportConvex, &ccdCenter, c2, &ccdSupportTriangle, &ccdCenter) == 1) { + perturbedContact.side2 = contact->side2; + + if (meshFaceAngleView == NULL || correctTriangleContactNormal(c2, &perturbedContact, meshFaceAngleView, indices, numIndices)) { + contacCount = addUniqueContact(contacts, &perturbedContact, contacCount, maxContacts, flags, skip); + } + } + } + + return contacCount; +} + +static +bool correctTriangleContactNormal(ccd_triangle_t *t, dContactGeom *contact, + IFaceAngleStorageView *meshFaceAngleView, const int *indices, unsigned numIndices) +{ + dIASSERT(meshFaceAngleView != NULL); + + bool anyFault = false; + + ccd_vec3_t cntOrigNormal, cntNormal; + ccdVec3Set(&cntNormal, contact->normal[0], contact->normal[1], contact->normal[2]); + ccdVec3Copy(&cntOrigNormal, &cntNormal); + + // Check if the contact point is located close to any edge - move it back and forth + // and check the resulting segment for intersection with the edge plane + ccd_vec3_t cntScaledNormal; + ccdVec3CopyScaled(&cntScaledNormal, &cntNormal, contact->depth); + + ccd_vec3_t edges[dMTV__MAX]; + ccdVec3Sub2(&edges[dMTV_THIRD], &t->vertices[0], &t->vertices[2]); + ccdVec3Sub2(&edges[dMTV_SECOND], &t->vertices[2], &t->vertices[1]); + ccdVec3Sub2(&edges[dMTV_FIRST], &t->vertices[1], &t->vertices[0]); + dSASSERT(dMTV__MAX == 3); + + bool contactGenerated = false, contactPreserved = false; + // Triangle face normal + ccd_vec3_t triNormal; + ccdVec3Cross(&triNormal, &edges[dMTV_FIRST], &edges[dMTV_SECOND]); + if (ccdVec3SafeNormalize(&triNormal) != 0) { + anyFault = true; + } + + // Check the edges to see if one of them is involved + for (unsigned testEdgeIndex = !anyFault ? dMTV__MIN : dMTV__MAX; testEdgeIndex != dMTV__MAX; ++testEdgeIndex) { + ccd_vec3_t edgeNormal, vertexToPos, v; + ccd_vec3_t &edgeAxis = edges[testEdgeIndex]; + + // Edge axis + if (ccdVec3SafeNormalize(&edgeAxis) != 0) { + // This should not happen normally as in the case on of edges is degenerated + // the triangle normal calculation would have to fail above. If for some + // reason the above calculation succeeds and this one would not, it is + // OK to break as this point as well. + anyFault = true; + break; + } + + // Edge Normal + ccdVec3Cross(&edgeNormal, &edgeAxis, &triNormal); + // ccdVec3Normalize(&edgeNormal); -- the two vectors above were already normalized and perpendicular + + // Check if the contact point is located close to any edge - move it back and forth + // and check the resulting segment for intersection with the edge plane + ccdVec3Set(&vertexToPos, contact->pos[0], contact->pos[1], contact->pos[2]); + ccdVec3Sub(&vertexToPos, &t->vertices[testEdgeIndex]); + ccdVec3Sub2(&v, &vertexToPos, &cntScaledNormal); + + if (ccdVec3Dot(&edgeNormal, &v) < 0) { + ccdVec3Add2(&v, &vertexToPos, &cntScaledNormal); + + if (ccdVec3Dot(&edgeNormal, &v) > 0) { + // This is an edge contact + + ccd_real_t x = ccdVec3Dot(&triNormal, &cntNormal); + ccd_real_t y = ccdVec3Dot(&edgeNormal, &cntNormal); + ccd_real_t contactNormalToTriangleNormalAngle = CCD_ATAN2(y, x); + + dReal angleValueAsDRead; + FaceAngleDomain angleDomain = meshFaceAngleView->retrieveFacesAngleFromStorage(angleValueAsDRead, contact->side2, (dMeshTriangleVertex)testEdgeIndex); + ccd_real_t angleValue = (ccd_real_t)angleValueAsDRead; + + ccd_real_t targetAngle; + contactGenerated = false, contactPreserved = false; // re-assign to make optimizer's task easier + + if (angleDomain != FAD_CONCAVE) { + // Convex or flat - ensure the contact normal is within the allowed range + // formed by the two triangles' normals. + if (contactNormalToTriangleNormalAngle < CCD_ZERO) { + targetAngle = CCD_ZERO; + } + else if (contactNormalToTriangleNormalAngle > angleValue) { + targetAngle = angleValue; + } + else { + contactPreserved = true; + } + } + else { + // Concave - rotate the contact normal to the face angle bisect plane + // (or to triangle normal-edge plane if negative angles are not stored) + targetAngle = angleValue != 0 ? CCD_REAL(0.5) * angleValue : CCD_ZERO; + // There is little chance the normal will initially match the correct plane, but still, a small check could save lots of calculations + if (contactNormalToTriangleNormalAngle == targetAngle) { + contactPreserved = true; + } + } + + if (!contactPreserved) { + ccd_quat_t q; + ccdQuatSetAngleAxis(&q, targetAngle - contactNormalToTriangleNormalAngle, &edgeAxis); + ccdQuatRotVec2(&cntNormal, &cntNormal, &q); + contactGenerated = true; + } + + // Calculated successfully + break; + } + } + } + + if (!anyFault && !contactPreserved) { + // No edge contact detected, set contact normal to triangle normal + const ccd_vec3_t &cntNormalToUse = !contactGenerated ? triNormal : cntNormal; + + contact->normal[dV3E_X] = ccdVec3X(&cntNormalToUse); + contact->normal[dV3E_Y] = ccdVec3Y(&cntNormalToUse); + contact->normal[dV3E_Z] = ccdVec3Z(&cntNormalToUse); + contact->depth *= CCD_FMAX(0.0, ccdVec3Dot(&cntOrigNormal, &cntNormalToUse)); + } + + bool result = !anyFault; + return result; +} + + +static +unsigned addUniqueContact(dContactGeom *contacts, dContactGeom *c, unsigned contactcount, unsigned maxcontacts, int flags, int skip) +{ + dReal minDepth = c->depth; + unsigned index = contactcount; + bool isDuplicate = false; + + dReal c_posX = c->pos[dV3E_X], c_posY = c->pos[dV3E_Y], c_posZ = c->pos[dV3E_Z]; + for (unsigned k = 0; k != contactcount; k++) { + dContactGeom* pc = SAFECONTACT(flags, contacts, k, skip); + + if (fabs(c_posX - pc->pos[dV3E_X]) < CONTACT_POS_EPSILON + && fabs(c_posY - pc->pos[dV3E_Y]) < CONTACT_POS_EPSILON + && fabs(c_posZ - pc->pos[dV3E_Z]) < CONTACT_POS_EPSILON) { + dSASSERT(dV3E__AXES_MAX - dV3E__AXES_MIN == 3); + + // Accumulate similar contacts + dAddVectors3(pc->normal, pc->normal, c->normal); + pc->depth = dMax(pc->depth, c->depth); + *_type_cast_union<bool>(&pc->normal[dV3E_PAD]) = true; // Mark the contact as a merged one + + isDuplicate = true; + break; + } + + if (contactcount == maxcontacts && pc->depth < minDepth) { + minDepth = pc->depth; + index = k; + } + } + + if (!isDuplicate && index < maxcontacts) { + dContactGeom* contact = SAFECONTACT(flags, contacts, index, skip); + contact->g1 = c->g1; + contact->g2 = c->g2; + contact->depth = c->depth; + contact->side1 = c->side1; + contact->side2 = c->side2; + dCopyVector3(contact->pos, c->pos); + dCopyVector3(contact->normal, c->normal); + *_type_cast_union<bool>(&contact->normal[dV3E_PAD]) = false; // Indicates whether the contact is merged or not + contactcount = index == contactcount ? contactcount + 1 : contactcount; + } + + return contactcount; +} + +static +void setObjPosToTriangleCenter(ccd_triangle_t *t) +{ + ccdVec3Set(&t->o.pos, 0, 0, 0); + for (int j = 0; j < 3; j++) { + ccdVec3Add(&t->o.pos, &t->vertices[j]); + } + ccdVec3Scale(&t->o.pos, 1.0f / 3.0f); +} + +static +void ccdSupportTriangle(const void *obj, const ccd_vec3_t *_dir, ccd_vec3_t *v) +{ + const ccd_triangle_t* o = (ccd_triangle_t *) obj; + ccd_real_t maxdot, dot; + maxdot = -CCD_REAL_MAX; + for (unsigned i = 0; i != 3; i++) { + dot = ccdVec3Dot(_dir, &o->vertices[i]); + if (dot > maxdot) { + ccdVec3Copy(v, &o->vertices[i]); + maxdot = dot; + } + } +} + + +#endif // dTRIMESH_ENABLED diff --git a/libs/ode-0.16.1/ode/src/collision_libccd.h b/libs/ode-0.16.1/ode/src/collision_libccd.h new file mode 100644 index 0000000..13c67ba --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_libccd.h @@ -0,0 +1,44 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _LIBCCD_COLLISION_H_ +#define _LIBCCD_COLLISION_H_ + +int dCollideCylinderCylinder(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); + +int dCollideBoxCylinderCCD(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); + +int dCollideCapsuleCylinder(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); + +int dCollideConvexBoxCCD(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); + +int dCollideConvexCapsuleCCD(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); + +int dCollideConvexCylinderCCD(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); + +int dCollideConvexSphereCCD(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); + +int dCollideConvexConvexCCD(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); + +unsigned dCollideConvexTrimeshTrianglesCCD(dxGeom *o1, dxGeom *o2, const int *indices, unsigned numIndices, int flags, dContactGeom *contacts, int skip); + +#endif /* _LIBCCD_COLLISION_H_ */ diff --git a/libs/ode-0.16.1/ode/src/collision_quadtreespace.cpp b/libs/ode-0.16.1/ode/src/collision_quadtreespace.cpp new file mode 100644 index 0000000..200b20f --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_quadtreespace.cpp @@ -0,0 +1,609 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// QuadTreeSpace by Erwin de Vries. +// With math corrections by Oleh Derevenko. ;) + +#include <ode/common.h> +#include <ode/collision_space.h> +#include <ode/collision.h> +#include "config.h" +#include "matrix.h" +#include "collision_kernel.h" + +#include "collision_space_internal.h" + + +#define AXIS0 0 +#define AXIS1 1 +#define UP 2 + +//#define DRAWBLOCKS + +const int SPLITAXIS = 2; +const int SPLITS = SPLITAXIS * SPLITAXIS; + +#define GEOM_ENABLED(g) (((g)->gflags & GEOM_ENABLE_TEST_MASK) == GEOM_ENABLE_TEST_VALUE) + +class Block{ +public: + dReal mMinX, mMaxX; + dReal mMinZ, mMaxZ; + + dGeomID mFirst; + int mGeomCount; + + Block* mParent; + Block* mChildren; + + void Create(const dReal MinX, const dReal MaxX, const dReal MinZ, const dReal MaxZ, Block* Parent, int Depth, Block*& Blocks); + + void Collide(void* UserData, dNearCallback* Callback); + void Collide(dGeomID g1, dGeomID g2, void* UserData, dNearCallback* Callback); + + void CollideLocal(dGeomID g2, void* UserData, dNearCallback* Callback); + + void AddObject(dGeomID Object); + void DelObject(dGeomID Object); + void Traverse(dGeomID Object); + + bool Inside(const dReal* AABB); + + Block* GetBlock(const dReal* AABB); + Block* GetBlockChild(const dReal* AABB); +}; + + +#ifdef DRAWBLOCKS +#include "..\..\Include\drawstuff\\drawstuff.h" + +static void DrawBlock(Block* Block){ + dVector3 v[8]; + v[0][AXIS0] = Block->mMinX; + v[0][UP] = REAL(-1.0); + v[0][AXIS1] = Block->mMinZ; + + v[1][AXIS0] = Block->mMinX; + v[1][UP] = REAL(-1.0); + v[1][AXIS1] = Block->mMaxZ; + + v[2][AXIS0] = Block->mMaxX; + v[2][UP] = REAL(-1.0); + v[2][AXIS1] = Block->mMinZ; + + v[3][AXIS0] = Block->mMaxX; + v[3][UP] = REAL(-1.0); + v[3][AXIS1] = Block->mMaxZ; + + v[4][AXIS0] = Block->mMinX; + v[4][UP] = REAL(1.0); + v[4][AXIS1] = Block->mMinZ; + + v[5][AXIS0] = Block->mMinX; + v[5][UP] = REAL(1.0); + v[5][AXIS1] = Block->mMaxZ; + + v[6][AXIS0] = Block->mMaxX; + v[6][UP] = REAL(1.0); + v[6][AXIS1] = Block->mMinZ; + + v[7][AXIS0] = Block->mMaxX; + v[7][UP] = REAL(1.0); + v[7][AXIS1] = Block->mMaxZ; + + // Bottom + dsDrawLine(v[0], v[1]); + dsDrawLine(v[1], v[3]); + dsDrawLine(v[3], v[2]); + dsDrawLine(v[2], v[0]); + + // Top + dsDrawLine(v[4], v[5]); + dsDrawLine(v[5], v[7]); + dsDrawLine(v[7], v[6]); + dsDrawLine(v[6], v[4]); + + // Sides + dsDrawLine(v[0], v[4]); + dsDrawLine(v[1], v[5]); + dsDrawLine(v[2], v[6]); + dsDrawLine(v[3], v[7]); +} +#endif //DRAWBLOCKS + + +void Block::Create(const dReal MinX, const dReal MaxX, const dReal MinZ, const dReal MaxZ, Block* Parent, int Depth, Block*& Blocks){ + dIASSERT(MinX <= MaxX); + dIASSERT(MinZ <= MaxZ); + + mGeomCount = 0; + mFirst = 0; + + mMinX = MinX; + mMaxX = MaxX; + + mMinZ = MinZ; + mMaxZ = MaxZ; + + this->mParent = Parent; + + if (Depth > 0){ + mChildren = Blocks; + Blocks += SPLITS; + + const dReal ChildExtentX = (MaxX - MinX) / SPLITAXIS; + const dReal ChildExtentZ = (MaxZ - MinZ) / SPLITAXIS; + + const int ChildDepth = Depth - 1; + int Index = 0; + + dReal ChildRightX = MinX; + for (int i = 0; i < SPLITAXIS; i++){ + const dReal ChildLeftX = ChildRightX; + ChildRightX = (i != SPLITAXIS - 1) ? ChildLeftX + ChildExtentX : MaxX; + + dReal ChildRightZ = MinZ; + for (int j = 0; j < SPLITAXIS; j++){ + const dReal ChildLeftZ = ChildRightZ; + ChildRightZ = (j != SPLITAXIS - 1) ? ChildLeftZ + ChildExtentZ : MaxZ; + + mChildren[Index].Create(ChildLeftX, ChildRightX, ChildLeftZ, ChildRightZ, this, ChildDepth, Blocks); + ++Index; + } + } + } + else mChildren = 0; +} + +void Block::Collide(void* UserData, dNearCallback* Callback){ +#ifdef DRAWBLOCKS + DrawBlock(this); +#endif + // Collide the local list + dxGeom* g = mFirst; + while (g){ + if (GEOM_ENABLED(g)){ + Collide(g, g->next_ex, UserData, Callback); + } + g = g->next_ex; + } + + // Recurse for children + if (mChildren){ + for (int i = 0; i < SPLITS; i++){ + Block &CurrentChild = mChildren[i]; + if (CurrentChild.mGeomCount <= 1){ // Early out + continue; + } + CurrentChild.Collide(UserData, Callback); + } + } +} + +// Note: g2 is assumed to be in this Block +void Block::Collide(dxGeom* g1, dxGeom* g2, void* UserData, dNearCallback* Callback){ +#ifdef DRAWBLOCKS + DrawBlock(this); +#endif + // Collide against local list + while (g2){ + if (GEOM_ENABLED(g2)){ + collideAABBs (g1, g2, UserData, Callback); + } + g2 = g2->next_ex; + } + + // Collide against children + if (mChildren){ + for (int i = 0; i < SPLITS; i++){ + Block &CurrentChild = mChildren[i]; + // Early out for empty blocks + if (CurrentChild.mGeomCount == 0){ + continue; + } + + // Does the geom's AABB collide with the block? + // Don't do AABB tests for single geom blocks. + if (CurrentChild.mGeomCount == 1){ + // + } + else if (true){ + if (g1->aabb[AXIS0 * 2 + 0] >= CurrentChild.mMaxX || + g1->aabb[AXIS0 * 2 + 1] < CurrentChild.mMinX || + g1->aabb[AXIS1 * 2 + 0] >= CurrentChild.mMaxZ || + g1->aabb[AXIS1 * 2 + 1] < CurrentChild.mMinZ) continue; + } + CurrentChild.Collide(g1, CurrentChild.mFirst, UserData, Callback); + } + } +} + +void Block::CollideLocal(dxGeom* g2, void* UserData, dNearCallback* Callback){ + // Collide against local list + dxGeom* g1 = mFirst; + while (g1){ + if (GEOM_ENABLED(g1)){ + collideAABBs (g1, g2, UserData, Callback); + } + g1 = g1->next_ex; + } +} + +void Block::AddObject(dGeomID Object){ + // Add the geom + Object->next_ex = mFirst; + mFirst = Object; + Object->tome_ex = (dxGeom**)this; + + // Now traverse upwards to tell that we have a geom + Block* Block = this; + do{ + Block->mGeomCount++; + Block = Block->mParent; + } + while (Block); +} + +void Block::DelObject(dGeomID Object){ + // Del the geom + dxGeom* g = mFirst; + dxGeom* Last = 0; + while (g){ + if (g == Object){ + if (Last){ + Last->next_ex = g->next_ex; + } + else mFirst = g->next_ex; + + break; + } + Last = g; + g = g->next_ex; + } + + Object->tome_ex = 0; + + // Now traverse upwards to tell that we have lost a geom + Block* Block = this; + do{ + Block->mGeomCount--; + Block = Block->mParent; + } + while (Block); +} + +void Block::Traverse(dGeomID Object){ + Block* NewBlock = GetBlock(Object->aabb); + + if (NewBlock != this){ + // Remove the geom from the old block and add it to the new block. + // This could be more optimal, but the loss should be very small. + DelObject(Object); + NewBlock->AddObject(Object); + } +} + +bool Block::Inside(const dReal* AABB){ + return AABB[AXIS0 * 2 + 0] >= mMinX && AABB[AXIS0 * 2 + 1] < mMaxX && AABB[AXIS1 * 2 + 0] >= mMinZ && AABB[AXIS1 * 2 + 1] < mMaxZ; +} + +Block* Block::GetBlock(const dReal* AABB){ + if (Inside(AABB)){ + return GetBlockChild(AABB); // Child or this will have a good block + } + else if (mParent){ + return mParent->GetBlock(AABB); // Parent has a good block + } + else return this; // We are at the root, so we have little choice +} + +Block* Block::GetBlockChild(const dReal* AABB){ + if (mChildren){ + for (int i = 0; i < SPLITS; i++){ + Block &CurrentChild = mChildren[i]; + if (CurrentChild.Inside(AABB)){ + return CurrentChild.GetBlockChild(AABB); // Child will have good block + } + } + } + return this; // This is the best block +} + +//**************************************************************************** +// quadtree space + +struct dxQuadTreeSpace : public dxSpace{ + Block* Blocks; // Blocks[0] is the root + + dArray<dxGeom*> DirtyList; + + dxQuadTreeSpace(dSpaceID _space, const dVector3 Center, const dVector3 Extents, int Depth); + ~dxQuadTreeSpace(); + + dxGeom* getGeom(int i); + + void add(dxGeom* g); + void remove(dxGeom* g); + void dirty(dxGeom* g); + + void computeAABB(); + + void cleanGeoms(); + void collide(void* UserData, dNearCallback* Callback); + void collide2(void* UserData, dxGeom* g1, dNearCallback* Callback); + + // Temp data + Block* CurrentBlock; // Only used while enumerating + int* CurrentChild; // Only used while enumerating + int CurrentLevel; // Only used while enumerating + dxGeom* CurrentObject; // Only used while enumerating + int CurrentIndex; +}; + +namespace { + + inline + sizeint numNodes(int depth) + { + // A 4-ary tree has (4^(depth+1) - 1)/3 nodes + // Note: split up into multiple constant expressions for readability + const int k = depth+1; + const sizeint fourToNthPlusOne = (sizeint)1 << (2*k); // 4^k = 2^(2k) + return (fourToNthPlusOne - 1) / 3; + } + +} + + + +dxQuadTreeSpace::dxQuadTreeSpace(dSpaceID _space, const dVector3 Center, const dVector3 Extents, int Depth) : dxSpace(_space){ + type = dQuadTreeSpaceClass; + + sizeint BlockCount = numNodes(Depth); + + Blocks = (Block*)dAlloc(BlockCount * sizeof(Block)); + Block* Blocks = this->Blocks + 1; // This pointer gets modified! + + dReal MinX = Center[AXIS0] - Extents[AXIS0]; + dReal MaxX = dNextAfter((Center[AXIS0] + Extents[AXIS0]), (dReal)dInfinity); + dReal MinZ = Center[AXIS1] - Extents[AXIS1]; + dReal MaxZ = dNextAfter((Center[AXIS1] + Extents[AXIS1]), (dReal)dInfinity); + this->Blocks[0].Create(MinX, MaxX, MinZ, MaxZ, 0, Depth, Blocks); + + CurrentBlock = 0; + CurrentChild = (int*)dAlloc((Depth + 1) * sizeof(int)); + CurrentLevel = 0; + CurrentObject = 0; + CurrentIndex = -1; + + // Init AABB. We initialize to infinity because it is not illegal for an object to be outside of the tree. Its simply inserted in the root block + aabb[0] = -dInfinity; + aabb[1] = dInfinity; + aabb[2] = -dInfinity; + aabb[3] = dInfinity; + aabb[4] = -dInfinity; + aabb[5] = dInfinity; +} + +dxQuadTreeSpace::~dxQuadTreeSpace(){ + int Depth = 0; + Block* Current = &Blocks[0]; + while (Current){ + Depth++; + Current = Current->mChildren; + } + + sizeint BlockCount = numNodes(Depth); + + dFree(Blocks, BlockCount * sizeof(Block)); + dFree(CurrentChild, (Depth + 1) * sizeof(int)); +} + +dxGeom* dxQuadTreeSpace::getGeom(int Index){ + dUASSERT(Index >= 0 && Index < count, "index out of range"); + + //@@@ + dDebug (0,"dxQuadTreeSpace::getGeom() not yet implemented"); + + return 0; + + // This doesnt work +/* + if (CurrentIndex == Index){ + // Loop through all objects in the local list +CHILDRECURSE: + if (CurrentObject){ + dGeomID g = CurrentObject; + CurrentObject = CurrentObject->next_ex; + CurrentIndex++; + +#ifdef DRAWBLOCKS + DrawBlock(CurrentBlock); +#endif //DRAWBLOCKS + return g; + } + else{ + // Now lets loop through our children. Starting at index 0. + if (CurrentBlock->Children){ + CurrentChild[CurrentLevel] = 0; +PARENTRECURSE: + for (int& i = CurrentChild[CurrentLevel]; i < SPLITS; i++){ + if (CurrentBlock->Children[i].GeomCount == 0){ + continue; + } + CurrentBlock = &CurrentBlock->Children[i]; + CurrentObject = CurrentBlock->First; + + i++; + + CurrentLevel++; + goto CHILDRECURSE; + } + } + } + + // Now lets go back to the parent so it can continue processing its other children. + if (CurrentBlock->Parent){ + CurrentBlock = CurrentBlock->Parent; + CurrentLevel--; + goto PARENTRECURSE; + } + } + else{ + CurrentBlock = &Blocks[0]; + CurrentLevel = 0; + CurrentObject = CurrentObject; + CurrentIndex = 0; + + // Other states are already set + CurrentObject = CurrentBlock->First; + } + + + if (current_geom && current_index == Index - 1){ + //current_geom = current_geom->next_ex; // next + current_index = Index; + return current_geom; + } + else for (int i = 0; i < Index; i++){ // this will be verrrrrrry slow + getGeom(i); + } +*/ + + return 0; +} + +void dxQuadTreeSpace::add(dxGeom* g){ + CHECK_NOT_LOCKED (this); + dAASSERT(g); + dUASSERT(g->tome_ex == 0 && g->next_ex == 0, "geom is already in a space"); + + DirtyList.push(g); + Blocks[0].GetBlock(g->aabb)->AddObject(g); // Add to best block + + dxSpace::add(g); +} + +void dxQuadTreeSpace::remove(dxGeom* g){ + CHECK_NOT_LOCKED(this); + dAASSERT(g); + dUASSERT(g->parent_space == this,"object is not in this space"); + + // remove + ((Block*)g->tome_ex)->DelObject(g); + + for (int i = 0; i < DirtyList.size(); i++){ + if (DirtyList[i] == g){ + DirtyList.remove(i); + // (mg) there can be multiple instances of a dirty object on stack be sure to remove ALL and not just first, for this we decrement i + --i; + } + } + + dxSpace::remove(g); +} + +void dxQuadTreeSpace::dirty(dxGeom* g){ + DirtyList.push(g); +} + +void dxQuadTreeSpace::computeAABB(){ + // +} + +void dxQuadTreeSpace::cleanGeoms(){ + // compute the AABBs of all dirty geoms, and clear the dirty flags + lock_count++; + + for (int i = 0; i < DirtyList.size(); i++){ + dxGeom* g = DirtyList[i]; + if (IS_SPACE(g)){ + ((dxSpace*)g)->cleanGeoms(); + } + + g->recomputeAABB(); + dIASSERT((g->gflags & GEOM_AABB_BAD) == 0); + + g->gflags &= ~GEOM_DIRTY; + + ((Block*)g->tome_ex)->Traverse(g); + } + DirtyList.setSize(0); + + lock_count--; +} + +void dxQuadTreeSpace::collide(void* UserData, dNearCallback* Callback){ + dAASSERT(Callback); + + lock_count++; + cleanGeoms(); + + Blocks[0].Collide(UserData, Callback); + + lock_count--; +} + + +struct DataCallback { + void *data; + dNearCallback *callback; +}; +// Invokes the callback with arguments swapped +static void swap_callback(void *data, dxGeom *g1, dxGeom *g2) +{ + DataCallback *dc = (DataCallback*)data; + dc->callback(dc->data, g2, g1); +} + + +void dxQuadTreeSpace::collide2(void* UserData, dxGeom* g2, dNearCallback* Callback){ + dAASSERT(g2 && Callback); + + lock_count++; + cleanGeoms(); + g2->recomputeAABB(); + + if (g2->parent_space == this){ + // The block the geom is in + Block* CurrentBlock = (Block*)g2->tome_ex; + + // Collide against block and its children + DataCallback dc = {UserData, Callback}; + CurrentBlock->Collide(g2, CurrentBlock->mFirst, &dc, swap_callback); + + // Collide against parents + while ((CurrentBlock = CurrentBlock->mParent)) + CurrentBlock->CollideLocal(g2, UserData, Callback); + + } + else { + DataCallback dc = {UserData, Callback}; + Blocks[0].Collide(g2, Blocks[0].mFirst, &dc, swap_callback); + } + + lock_count--; +} + +dSpaceID dQuadTreeSpaceCreate(dxSpace* space, const dVector3 Center, const dVector3 Extents, int Depth){ + return new dxQuadTreeSpace(space, Center, Extents, Depth); +} diff --git a/libs/ode-0.16.1/ode/src/collision_sapspace.cpp b/libs/ode-0.16.1/ode/src/collision_sapspace.cpp new file mode 100644 index 0000000..76258bf --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_sapspace.cpp @@ -0,0 +1,853 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * Sweep and Prune adaptation/tweaks for ODE by Aras Pranckevicius. + * Additional work by David Walters + * Original code: + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + * + * This version does complete radix sort, not "classical" SAP. So, we + * have no temporal coherence, but are able to handle any movement + * velocities equally well. + */ + +#include <ode/common.h> +#include <ode/collision_space.h> +#include <ode/collision.h> + +#include "config.h" +#include "matrix.h" +#include "collision_kernel.h" +#include "collision_space_internal.h" + +// Reference counting helper for radix sort global data. +//static void RadixSortRef(); +//static void RadixSortDeref(); + + +// -------------------------------------------------------------------------- +// Radix Sort Context +// -------------------------------------------------------------------------- + +struct RaixSortContext +{ +public: + RaixSortContext(): mCurrentSize(0), mCurrentUtilization(0), mRanksValid(false), mRanksBuffer(NULL), mPrimaryRanks(NULL) {} + ~RaixSortContext() { FreeRanks(); } + + // OPCODE's Radix Sorting, returns a list of indices in sorted order + const uint32* RadixSort( const float* input2, uint32 nb ); + +private: + void FreeRanks(); + void AllocateRanks(sizeint nNewSize); + + void ReallocateRanksIfNecessary(sizeint nNewSize); + +private: + void SetCurrentSize(sizeint nValue) { mCurrentSize = nValue; } + sizeint GetCurrentSize() const { return mCurrentSize; } + + void SetCurrentUtilization(sizeint nValue) { mCurrentUtilization = nValue; } + sizeint GetCurrentUtilization() const { return mCurrentUtilization; } + + uint32 *GetRanks1() const { return mPrimaryRanks; } + uint32 *GetRanks2() const { return mRanksBuffer + ((mRanksBuffer + mCurrentSize) - mPrimaryRanks); } + void SwapRanks() { mPrimaryRanks = GetRanks2(); } + + bool AreRanksValid() const { return mRanksValid; } + void InvalidateRanks() { mRanksValid = false; } + void ValidateRanks() { mRanksValid = true; } + +private: + sizeint mCurrentSize; //!< Current size of the indices list + sizeint mCurrentUtilization; //!< Current utilization of the indices list + bool mRanksValid; + uint32* mRanksBuffer; //!< Two lists allocated sequentially in a single block + uint32* mPrimaryRanks; +}; + +void RaixSortContext::AllocateRanks(sizeint nNewSize) +{ + dIASSERT(GetCurrentSize() == 0); + + mRanksBuffer = new uint32[2 * nNewSize]; + mPrimaryRanks = mRanksBuffer; + + SetCurrentSize(nNewSize); +} + +void RaixSortContext::FreeRanks() +{ + SetCurrentSize(0); + + delete[] mRanksBuffer; +} + +void RaixSortContext::ReallocateRanksIfNecessary(sizeint nNewSize) +{ + sizeint nCurUtilization = GetCurrentUtilization(); + + if (nNewSize != nCurUtilization) + { + sizeint nCurSize = GetCurrentSize(); + + if ( nNewSize > nCurSize ) + { + // Free previously used ram + FreeRanks(); + + // Get some fresh one + AllocateRanks(nNewSize); + } + + InvalidateRanks(); + SetCurrentUtilization(nNewSize); + } +} + +// -------------------------------------------------------------------------- +// SAP space code +// -------------------------------------------------------------------------- + +struct dxSAPSpace : public dxSpace +{ + // Constructor / Destructor + dxSAPSpace( dSpaceID _space, int sortaxis ); + ~dxSAPSpace(); + + // dxSpace + virtual dxGeom* getGeom(int i); + virtual void add(dxGeom* g); + virtual void remove(dxGeom* g); + virtual void dirty(dxGeom* g); + virtual void computeAABB(); + virtual void cleanGeoms(); + virtual void collide( void *data, dNearCallback *callback ); + virtual void collide2( void *data, dxGeom *geom, dNearCallback *callback ); + +private: + + //-------------------------------------------------------------------------- + // Local Declarations + //-------------------------------------------------------------------------- + + //! A generic couple structure + struct Pair + { + uint32 id0; //!< First index of the pair + uint32 id1; //!< Second index of the pair + + // Default and Value Constructor + Pair() {} + Pair( uint32 i0, uint32 i1 ) : id0( i0 ), id1( i1 ) {} + }; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Complete box pruning. + * Returns a list of overlapping pairs of boxes, each box of the pair + * belongs to the same set. + * + * @param count [in] number of boxes. + * @param geoms [in] geoms of boxes. + * @param pairs [out] array of overlapping pairs. + */ + void BoxPruning( int count, const dxGeom** geoms, dArray< Pair >& pairs ); + + + //-------------------------------------------------------------------------- + // Implementation Data + //-------------------------------------------------------------------------- + + // We have two lists (arrays of pointers) to dirty and clean + // geoms. Each geom knows it's index into the corresponding list + // (see macros above). + dArray<dxGeom*> DirtyList; // dirty geoms + dArray<dxGeom*> GeomList; // clean geoms + + // For SAP, we ultimately separate "normal" geoms and the ones that have + // infinite AABBs. No point doing SAP on infinite ones (and it doesn't handle + // infinite geoms anyway). + dArray<dxGeom*> TmpGeomList; // temporary for normal geoms + dArray<dxGeom*> TmpInfGeomList; // temporary for geoms with infinite AABBs + + // Our sorting axes. (X,Z,Y is often best). Stored *2 for minor speedup + // Axis indices into geom's aabb are: min=idx, max=idx+1 + uint32 ax0idx; + uint32 ax1idx; + uint32 ax2idx; + + // pruning position array scratch pad + // NOTE: this is float not dReal because of the OPCODE radix sorter + dArray< float > poslist; + RaixSortContext sortContext; +}; + +// Creation +dSpaceID dSweepAndPruneSpaceCreate( dxSpace* space, int axisorder ) { + return new dxSAPSpace( space, axisorder ); +} + + +//============================================================================== + +#define GEOM_ENABLED(g) (((g)->gflags & GEOM_ENABLE_TEST_MASK) == GEOM_ENABLE_TEST_VALUE) + +// HACK: We abuse 'next' and 'tome' members of dxGeom to store indices into dirty/geom lists. +#define GEOM_SET_DIRTY_IDX(g,idx) { (g)->next_ex = (dxGeom*)(sizeint)(idx); } +#define GEOM_SET_GEOM_IDX(g,idx) { (g)->tome_ex = (dxGeom**)(sizeint)(idx); } +#define GEOM_GET_DIRTY_IDX(g) ((int)(sizeint)(g)->next_ex) +#define GEOM_GET_GEOM_IDX(g) ((int)(sizeint)(g)->tome_ex) +#define GEOM_INVALID_IDX (-1) + + +/* +* A bit of repetitive work - similar to collideAABBs, but doesn't check +* if AABBs intersect (because SAP returns pairs with overlapping AABBs). +*/ +static void collideGeomsNoAABBs( dxGeom *g1, dxGeom *g2, void *data, dNearCallback *callback ) +{ + dIASSERT( (g1->gflags & GEOM_AABB_BAD)==0 ); + dIASSERT( (g2->gflags & GEOM_AABB_BAD)==0 ); + + // no contacts if both geoms on the same body, and the body is not 0 + if (g1->body == g2->body && g1->body) return; + + // test if the category and collide bitfields match + if ( ((g1->category_bits & g2->collide_bits) || + (g2->category_bits & g1->collide_bits)) == 0) { + return; + } + + dReal *bounds1 = g1->aabb; + dReal *bounds2 = g2->aabb; + + // check if either object is able to prove that it doesn't intersect the + // AABB of the other + if (g1->AABBTest (g2,bounds2) == 0) return; + if (g2->AABBTest (g1,bounds1) == 0) return; + + // the objects might actually intersect - call the space callback function + callback (data,g1,g2); +} + + +dxSAPSpace::dxSAPSpace( dSpaceID _space, int axisorder ) : dxSpace( _space ) +{ + type = dSweepAndPruneSpaceClass; + + // Init AABB to infinity + aabb[0] = -dInfinity; + aabb[1] = dInfinity; + aabb[2] = -dInfinity; + aabb[3] = dInfinity; + aabb[4] = -dInfinity; + aabb[5] = dInfinity; + + ax0idx = ( ( axisorder ) & 3 ) << 1; + ax1idx = ( ( axisorder >> 2 ) & 3 ) << 1; + ax2idx = ( ( axisorder >> 4 ) & 3 ) << 1; +} + +dxSAPSpace::~dxSAPSpace() +{ + CHECK_NOT_LOCKED(this); + if ( cleanup ) { + // note that destroying each geom will call remove() + for ( ; DirtyList.size(); dGeomDestroy( DirtyList[ 0 ] ) ) {} + for ( ; GeomList.size(); dGeomDestroy( GeomList[ 0 ] ) ) {} + } + else { + // just unhook them + for ( ; DirtyList.size(); remove( DirtyList[ 0 ] ) ) {} + for ( ; GeomList.size(); remove( GeomList[ 0 ] ) ) {} + } +} + +dxGeom* dxSAPSpace::getGeom( int i ) +{ + dUASSERT( i >= 0 && i < count, "index out of range" ); + int dirtySize = DirtyList.size(); + if( i < dirtySize ) + return DirtyList[i]; + else + return GeomList[i-dirtySize]; +} + +void dxSAPSpace::add( dxGeom* g ) +{ + CHECK_NOT_LOCKED (this); + dAASSERT(g); + dUASSERT(g->tome_ex == 0 && g->next_ex == 0, "geom is already in a space"); + + + // add to dirty list + GEOM_SET_DIRTY_IDX( g, DirtyList.size() ); + GEOM_SET_GEOM_IDX( g, GEOM_INVALID_IDX ); + DirtyList.push( g ); + + dxSpace::add(g); +} + +void dxSAPSpace::remove( dxGeom* g ) +{ + CHECK_NOT_LOCKED(this); + dAASSERT(g); + dUASSERT(g->parent_space == this,"object is not in this space"); + + // remove + int dirtyIdx = GEOM_GET_DIRTY_IDX(g); + int geomIdx = GEOM_GET_GEOM_IDX(g); + // must be in one list, not in both + dUASSERT( + (dirtyIdx==GEOM_INVALID_IDX && geomIdx>=0 && geomIdx<GeomList.size()) || + (geomIdx==GEOM_INVALID_IDX && dirtyIdx>=0 && dirtyIdx<DirtyList.size()), + "geom indices messed up" ); + if( dirtyIdx != GEOM_INVALID_IDX ) { + // we're in dirty list, remove + int dirtySize = DirtyList.size(); + if (dirtyIdx != dirtySize-1) { + dxGeom* lastG = DirtyList[dirtySize-1]; + DirtyList[dirtyIdx] = lastG; + GEOM_SET_DIRTY_IDX(lastG,dirtyIdx); + } + GEOM_SET_DIRTY_IDX(g,GEOM_INVALID_IDX); + DirtyList.setSize( dirtySize-1 ); + } else { + // we're in geom list, remove + int geomSize = GeomList.size(); + if (geomIdx != geomSize-1) { + dxGeom* lastG = GeomList[geomSize-1]; + GeomList[geomIdx] = lastG; + GEOM_SET_GEOM_IDX(lastG,geomIdx); + } + GEOM_SET_GEOM_IDX(g,GEOM_INVALID_IDX); + GeomList.setSize( geomSize-1 ); + } + + dxSpace::remove(g); +} + +void dxSAPSpace::dirty( dxGeom* g ) +{ + dAASSERT(g); + dUASSERT(g->parent_space == this, "object is not in this space"); + + // check if already dirtied + int dirtyIdx = GEOM_GET_DIRTY_IDX(g); + if( dirtyIdx != GEOM_INVALID_IDX ) + return; + + int geomIdx = GEOM_GET_GEOM_IDX(g); + dUASSERT( geomIdx>=0 && geomIdx<GeomList.size(), "geom indices messed up" ); + + // remove from geom list, place last in place of this + int geomSize = GeomList.size(); + if (geomIdx != geomSize-1) { + dxGeom* lastG = GeomList[geomSize-1]; + GeomList[geomIdx] = lastG; + GEOM_SET_GEOM_IDX(lastG,geomIdx); + } + GeomList.setSize( geomSize-1 ); + + // add to dirty list + GEOM_SET_GEOM_IDX( g, GEOM_INVALID_IDX ); + GEOM_SET_DIRTY_IDX( g, DirtyList.size() ); + DirtyList.push( g ); +} + +void dxSAPSpace::computeAABB() +{ + // TODO? +} + +void dxSAPSpace::cleanGeoms() +{ + int dirtySize = DirtyList.size(); + if( !dirtySize ) + return; + + // compute the AABBs of all dirty geoms, clear the dirty flags, + // remove from dirty list, place into geom list + lock_count++; + + int geomSize = GeomList.size(); + GeomList.setSize( geomSize + dirtySize ); // ensure space in geom list + + for( int i = 0; i < dirtySize; ++i ) { + dxGeom* g = DirtyList[i]; + if( IS_SPACE(g) ) { + ((dxSpace*)g)->cleanGeoms(); + } + + g->recomputeAABB(); + dIASSERT((g->gflags & GEOM_AABB_BAD) == 0); + + g->gflags &= ~GEOM_DIRTY; + + // remove from dirty list, add to geom list + GEOM_SET_DIRTY_IDX( g, GEOM_INVALID_IDX ); + GEOM_SET_GEOM_IDX( g, geomSize + i ); + GeomList[geomSize+i] = g; + } + // clear dirty list + DirtyList.setSize( 0 ); + + lock_count--; +} + +void dxSAPSpace::collide( void *data, dNearCallback *callback ) +{ + dAASSERT (callback); + + lock_count++; + + cleanGeoms(); + + // by now all geoms are in GeomList, and DirtyList must be empty + int geom_count = GeomList.size(); + dUASSERT( geom_count == count, "geom counts messed up" ); + + // separate all ENABLED geoms into infinite AABBs and normal AABBs + TmpGeomList.setSize(0); + TmpInfGeomList.setSize(0); + int axis0max = ax0idx + 1; + for( int i = 0; i < geom_count; ++i ) { + dxGeom* g = GeomList[i]; + if( !GEOM_ENABLED(g) ) // skip disabled ones + continue; + const dReal& amax = g->aabb[axis0max]; + if( amax == dInfinity ) // HACK? probably not... + TmpInfGeomList.push( g ); + else + TmpGeomList.push( g ); + } + + // do SAP on normal AABBs + dArray< Pair > overlapBoxes; + int tmp_geom_count = TmpGeomList.size(); + if ( tmp_geom_count > 0 ) + { + // Generate a list of overlapping boxes + BoxPruning( tmp_geom_count, (const dxGeom**)TmpGeomList.data(), overlapBoxes ); + } + + // collide overlapping + int overlapCount = overlapBoxes.size(); + for( int j = 0; j < overlapCount; ++j ) + { + const Pair& pair = overlapBoxes[ j ]; + dxGeom* g1 = TmpGeomList[ pair.id0 ]; + dxGeom* g2 = TmpGeomList[ pair.id1 ]; + collideGeomsNoAABBs( g1, g2, data, callback ); + } + + int infSize = TmpInfGeomList.size(); + int normSize = TmpGeomList.size(); + int m, n; + + for ( m = 0; m < infSize; ++m ) + { + dxGeom* g1 = TmpInfGeomList[ m ]; + + // collide infinite ones + for( n = m+1; n < infSize; ++n ) { + dxGeom* g2 = TmpInfGeomList[n]; + collideGeomsNoAABBs( g1, g2, data, callback ); + } + + // collide infinite ones with normal ones + for( n = 0; n < normSize; ++n ) { + dxGeom* g2 = TmpGeomList[n]; + collideGeomsNoAABBs( g1, g2, data, callback ); + } + } + + lock_count--; +} + +void dxSAPSpace::collide2( void *data, dxGeom *geom, dNearCallback *callback ) +{ + dAASSERT (geom && callback); + + // TODO: This is just a simple N^2 implementation + + lock_count++; + + cleanGeoms(); + geom->recomputeAABB(); + + // intersect bounding boxes + int geom_count = GeomList.size(); + for ( int i = 0; i < geom_count; ++i ) { + dxGeom* g = GeomList[i]; + if ( GEOM_ENABLED(g) ) + collideAABBs (g,geom,data,callback); + } + + lock_count--; +} + + +void dxSAPSpace::BoxPruning( int count, const dxGeom** geoms, dArray< Pair >& pairs ) +{ + // Size the poslist (+1 for infinity end cap) + poslist.setSize( count ); + + // 1) Build main list using the primary axis + // NOTE: uses floats instead of dReals because that's what radix sort wants + for( int i = 0; i < count; ++i ) + poslist[ i ] = (float)TmpGeomList[i]->aabb[ ax0idx ]; + + // 2) Sort the list + const uint32* Sorted = sortContext.RadixSort( poslist.data(), count ); + + // 3) Prune the list + const uint32* const LastSorted = Sorted + count; + const uint32* RunningAddress = Sorted; + + bool bExitLoop; + Pair IndexPair; + while ( Sorted < LastSorted ) + { + IndexPair.id0 = *Sorted++; + + // empty, this loop just advances RunningAddress + for (bExitLoop = false; poslist[*RunningAddress++] < poslist[IndexPair.id0]; ) + { + if (RunningAddress == LastSorted) + { + bExitLoop = true; + break; + } + } + + if ( bExitLoop || RunningAddress == LastSorted) // Not a bug!!! + { + break; + } + + const float idx0ax0max = (float)geoms[IndexPair.id0]->aabb[ax0idx+1]; // To avoid wrong decisions caused by rounding errors, cast the AABB element to float similarly as we did at the function beginning + const dReal idx0ax1max = geoms[IndexPair.id0]->aabb[ax1idx+1]; + const dReal idx0ax2max = geoms[IndexPair.id0]->aabb[ax2idx+1]; + + for (const uint32* RunningAddress2 = RunningAddress; poslist[ IndexPair.id1 = *RunningAddress2++ ] <= idx0ax0max; ) + { + const dReal* aabb0 = geoms[ IndexPair.id0 ]->aabb; + const dReal* aabb1 = geoms[ IndexPair.id1 ]->aabb; + + // Intersection? + if ( idx0ax1max >= aabb1[ax1idx] && aabb1[ax1idx+1] >= aabb0[ax1idx] + && idx0ax2max >= aabb1[ax2idx] && aabb1[ax2idx+1] >= aabb0[ax2idx] ) + { + pairs.push( IndexPair ); + } + + if (RunningAddress2 == LastSorted) + { + break; + } + } + + } // while ( RunningAddress < LastSorted && Sorted < LastSorted ) +} + + +//============================================================================== + +//------------------------------------------------------------------------------ +// Radix Sort +//------------------------------------------------------------------------------ + + + +#define CHECK_PASS_VALIDITY(pass) \ + /* Shortcut to current counters */ \ + const uint32* CurCount = &mHistogram[pass<<8]; \ + \ + /* Reset flag. The sorting pass is supposed to be performed. (default) */ \ + bool PerformPass = true; \ + \ + /* Check pass validity */ \ + \ + /* If all values have the same byte, sorting is useless. */ \ + /* It may happen when sorting bytes or words instead of dwords. */ \ + /* This routine actually sorts words faster than dwords, and bytes */ \ + /* faster than words. Standard running time (O(4*n))is reduced to O(2*n) */ \ + /* for words and O(n) for bytes. Running time for floats depends on actual values... */ \ + \ + /* Get first byte */ \ + uint8 UniqueVal = *(((const uint8*)input)+pass); \ + \ + /* Check that byte's counter */ \ + if(CurCount[UniqueVal]==nb) PerformPass=false; + +// WARNING ONLY SORTS IEEE FLOATING-POINT VALUES +const uint32* RaixSortContext::RadixSort( const float* input2, uint32 nb ) +{ + union _type_cast_union + { + _type_cast_union(const float *floats): asFloats(floats) {} + _type_cast_union(const uint32 *uints32): asUInts32(uints32) {} + + const float *asFloats; + const uint32 *asUInts32; + const uint8 *asUInts8; + }; + + const uint32* input = _type_cast_union(input2).asUInts32; + + // Resize lists if needed + ReallocateRanksIfNecessary(nb); + + // Allocate histograms & offsets on the stack + uint32 mHistogram[256*4]; + uint32* mLink[256]; + + // Create histograms (counters). Counters for all passes are created in one run. + // Pros: read input buffer once instead of four times + // Cons: mHistogram is 4Kb instead of 1Kb + // Floating-point values are always supposed to be signed values, so there's only one code path there. + // Please note the floating point comparison needed for temporal coherence! Although the resulting asm code + // is dreadful, this is surprisingly not such a performance hit - well, I suppose that's a big one on first + // generation Pentiums....We can't make comparison on integer representations because, as Chris said, it just + // wouldn't work with mixed positive/negative values.... + { + /* Clear counters/histograms */ + memset(mHistogram, 0, 256*4*sizeof(uint32)); + + /* Prepare to count */ + const uint8* p = _type_cast_union(input).asUInts8; + const uint8* pe = &p[nb*4]; + uint32* h0= &mHistogram[0]; /* Histogram for first pass (LSB) */ + uint32* h1= &mHistogram[256]; /* Histogram for second pass */ + uint32* h2= &mHistogram[512]; /* Histogram for third pass */ + uint32* h3= &mHistogram[768]; /* Histogram for last pass (MSB) */ + + bool AlreadySorted = true; /* Optimism... */ + + if (!AreRanksValid()) + { + /* Prepare for temporal coherence */ + const float* Running = input2; + float PrevVal = *Running; + + while(p!=pe) + { + /* Read input input2 in previous sorted order */ + float Val = *Running++; + /* Check whether already sorted or not */ + if(Val<PrevVal) { AlreadySorted = false; break; } /* Early out */ + /* Update for next iteration */ + PrevVal = Val; + + /* Create histograms */ + h0[*p++]++; h1[*p++]++; h2[*p++]++; h3[*p++]++; + } + + /* If all input values are already sorted, we just have to return and leave the */ + /* previous list unchanged. That way the routine may take advantage of temporal */ + /* coherence, for example when used to sort transparent faces. */ + if(AlreadySorted) + { + uint32* const Ranks1 = GetRanks1(); + for(uint32 i=0;i<nb;i++) Ranks1[i] = i; + return Ranks1; + } + } + else + { + /* Prepare for temporal coherence */ + uint32* const Ranks1 = GetRanks1(); + + uint32* Indices = Ranks1; + float PrevVal = input2[*Indices]; + + while(p!=pe) + { + /* Read input input2 in previous sorted order */ + float Val = input2[*Indices++]; + /* Check whether already sorted or not */ + if(Val<PrevVal) { AlreadySorted = false; break; } /* Early out */ + /* Update for next iteration */ + PrevVal = Val; + + /* Create histograms */ + h0[*p++]++; h1[*p++]++; h2[*p++]++; h3[*p++]++; + } + + /* If all input values are already sorted, we just have to return and leave the */ + /* previous list unchanged. That way the routine may take advantage of temporal */ + /* coherence, for example when used to sort transparent faces. */ + if(AlreadySorted) { return Ranks1; } + } + + /* Else there has been an early out and we must finish computing the histograms */ + while(p!=pe) + { + /* Create histograms without the previous overhead */ + h0[*p++]++; h1[*p++]++; h2[*p++]++; h3[*p++]++; + } + } + + // Compute #negative values involved if needed + uint32 NbNegativeValues = 0; + + // An efficient way to compute the number of negatives values we'll have to deal with is simply to sum the 128 + // last values of the last histogram. Last histogram because that's the one for the Most Significant Byte, + // responsible for the sign. 128 last values because the 128 first ones are related to positive numbers. + uint32* h3= &mHistogram[768]; + for(uint32 i=128;i<256;i++) NbNegativeValues += h3[i]; // 768 for last histogram, 128 for negative part + + // Radix sort, j is the pass number (0=LSB, 3=MSB) + for(uint32 j=0;j<4;j++) + { + // Should we care about negative values? + if(j!=3) + { + // Here we deal with positive values only + CHECK_PASS_VALIDITY(j); + + if(PerformPass) + { + uint32* const Ranks2 = GetRanks2(); + // Create offsets + mLink[0] = Ranks2; + for(uint32 i=1;i<256;i++) mLink[i] = mLink[i-1] + CurCount[i-1]; + + // Perform Radix Sort + const uint8* InputBytes = _type_cast_union(input).asUInts8; + InputBytes += j; + if (!AreRanksValid()) + { + for(uint32 i=0;i<nb;i++) + { + *mLink[InputBytes[i<<2]]++ = i; + } + + ValidateRanks(); + } + else + { + uint32* const Ranks1 = GetRanks1(); + + uint32* Indices = Ranks1; + uint32* const IndicesEnd = Ranks1 + nb; + while(Indices!=IndicesEnd) + { + uint32 id = *Indices++; + *mLink[InputBytes[id<<2]]++ = id; + } + } + + // Swap pointers for next pass. Valid indices - the most recent ones - are in mRanks after the swap. + SwapRanks(); + } + } + else + { + // This is a special case to correctly handle negative values + CHECK_PASS_VALIDITY(j); + + if(PerformPass) + { + uint32* const Ranks2 = GetRanks2(); + + // Create biased offsets, in order for negative numbers to be sorted as well + mLink[0] = Ranks2 + NbNegativeValues; // First positive number takes place after the negative ones + for(uint32 i=1;i<128;i++) mLink[i] = mLink[i-1] + CurCount[i-1]; // 1 to 128 for positive numbers + + // We must reverse the sorting order for negative numbers! + mLink[255] = Ranks2; + for(uint32 i=0;i<127;i++) mLink[254-i] = mLink[255-i] + CurCount[255-i]; // Fixing the wrong order for negative values + for(uint32 i=128;i<256;i++) mLink[i] += CurCount[i]; // Fixing the wrong place for negative values + + // Perform Radix Sort + if (!AreRanksValid()) + { + for(uint32 i=0;i<nb;i++) + { + uint32 Radix = input[i]>>24; // Radix byte, same as above. AND is useless here (uint32). + // ### cmp to be killed. Not good. Later. + if(Radix<128) *mLink[Radix]++ = i; // Number is positive, same as above + else *(--mLink[Radix]) = i; // Number is negative, flip the sorting order + } + + ValidateRanks(); + } + else + { + uint32* const Ranks1 = GetRanks1(); + + for(uint32 i=0;i<nb;i++) + { + uint32 Radix = input[Ranks1[i]]>>24; // Radix byte, same as above. AND is useless here (uint32). + // ### cmp to be killed. Not good. Later. + if(Radix<128) *mLink[Radix]++ = Ranks1[i]; // Number is positive, same as above + else *(--mLink[Radix]) = Ranks1[i]; // Number is negative, flip the sorting order + } + } + // Swap pointers for next pass. Valid indices - the most recent ones - are in mRanks after the swap. + SwapRanks(); + } + else + { + // The pass is useless, yet we still have to reverse the order of current list if all values are negative. + if(UniqueVal>=128) + { + if (!AreRanksValid()) + { + uint32* const Ranks2 = GetRanks2(); + // ###Possible? + for(uint32 i=0;i<nb;i++) + { + Ranks2[i] = nb-i-1; + } + + ValidateRanks(); + } + else + { + uint32* const Ranks1 = GetRanks1(); + uint32* const Ranks2 = GetRanks2(); + for(uint32 i=0;i<nb;i++) Ranks2[i] = Ranks1[nb-i-1]; + } + + // Swap pointers for next pass. Valid indices - the most recent ones - are in mRanks after the swap. + SwapRanks(); + } + } + } + } + + // Return indices + uint32* const Ranks1 = GetRanks1(); + return Ranks1; +} + diff --git a/libs/ode-0.16.1/ode/src/collision_space.cpp b/libs/ode-0.16.1/ode/src/collision_space.cpp new file mode 100644 index 0000000..2ec4247 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_space.cpp @@ -0,0 +1,864 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +spaces + +*/ + +#include <vector> + +#include <ode/common.h> +#include <ode/collision_space.h> +#include <ode/collision.h> +#include "config.h" +#include "matrix.h" +#include "collision_kernel.h" +#include "collision_space_internal.h" +#include "util.h" + +#ifdef _MSC_VER +#pragma warning(disable:4291) // for VC++, no complaints about "no matching operator delete found" +#endif + +//**************************************************************************** +// make the geom dirty by setting the GEOM_DIRTY and GEOM_BAD_AABB flags +// and moving it to the front of the space's list. all the parents of a +// dirty geom also become dirty. + +void dGeomMoved (dxGeom *geom) +{ + dAASSERT (geom); + + // if geom is offset, mark it as needing a calculate + if (geom->offset_posr) { + geom->gflags |= GEOM_POSR_BAD; + } + + // from the bottom of the space heirarchy up, process all clean geoms + // turning them into dirty geoms. + dxSpace *parent = geom->parent_space; + + while (parent && (geom->gflags & GEOM_DIRTY)==0) { + geom->markAABBBad(); + parent->dirty (geom); + geom = parent; + parent = parent->parent_space; + } + + // all the remaining dirty geoms must have their AABB_BAD flags set, to + // ensure that their AABBs get recomputed + while (geom) { + geom->markAABBBad(); + geom = geom->parent_space; + } +} + +#define GEOM_ENABLED(g) (((g)->gflags & GEOM_ENABLE_TEST_MASK) == GEOM_ENABLE_TEST_VALUE) + +//**************************************************************************** +// dxSpace + +dxSpace::dxSpace (dSpaceID _space) : dxGeom (_space,0) +{ + count = 0; + first = 0; + cleanup = 1; + sublevel = 0; + tls_kind = dSPACE_TLS_KIND_INIT_VALUE; + current_index = 0; + current_geom = 0; + lock_count = 0; +} + + +dxSpace::~dxSpace() +{ + CHECK_NOT_LOCKED (this); + if (cleanup) { + // note that destroying each geom will call remove() + dxGeom *g,*n; + for (g = first; g; g=n) { + n = g->next; + dGeomDestroy (g); + } + } + else { + dxGeom *g,*n; + for (g = first; g; g=n) { + n = g->next; + remove (g); + } + } +} + + +void dxSpace::computeAABB() +{ + if (first) { + int i; + dReal a[6]; + a[0] = dInfinity; + a[1] = -dInfinity; + a[2] = dInfinity; + a[3] = -dInfinity; + a[4] = dInfinity; + a[5] = -dInfinity; + for (dxGeom *g=first; g; g=g->next) { + g->recomputeAABB(); + for (i=0; i<6; i += 2) if (g->aabb[i] < a[i]) a[i] = g->aabb[i]; + for (i=1; i<6; i += 2) if (g->aabb[i] > a[i]) a[i] = g->aabb[i]; + } + memcpy(aabb,a,6*sizeof(dReal)); + } + else { + dSetZero (aabb,6); + } +} + + +// the dirty geoms are numbered 0..k, the clean geoms are numbered k+1..count-1 + +dxGeom *dxSpace::getGeom (int i) +{ + dUASSERT (i >= 0 && i < count,"index out of range"); + if (current_geom && current_index == i-1) { + current_geom = current_geom->next; + current_index = i; + return current_geom; + } + else { + dxGeom *g=first; + for (int j=0; j<i; j++) { + if (g) g = g->next; else return 0; + } + current_geom = g; + current_index = i; + return g; + } +} + + +void dxSpace::add (dxGeom *geom) +{ + CHECK_NOT_LOCKED (this); + dAASSERT (geom); + dUASSERT (geom->parent_space == 0 && geom->next == 0, + "geom is already in a space"); + + // add + geom->parent_space = this; + geom->spaceAdd (&first); + count++; + + // enumerator has been invalidated + current_geom = 0; + + dGeomMoved (this); +} + + +void dxSpace::remove (dxGeom *geom) +{ + CHECK_NOT_LOCKED (this); + dAASSERT (geom); + dUASSERT (geom->parent_space == this,"object is not in this space"); + + // remove + geom->spaceRemove(); + count--; + + // safeguard + geom->next = 0; + geom->tome = 0; + geom->parent_space = 0; + + // enumerator has been invalidated + current_geom = 0; + + // the bounding box of this space (and that of all the parents) may have + // changed as a consequence of the removal. + dGeomMoved (this); +} + + +void dxSpace::dirty (dxGeom *geom) +{ + geom->spaceRemove(); + geom->spaceAdd (&first); +} + +//**************************************************************************** +// simple space - reports all n^2 object intersections + +struct dxSimpleSpace : public dxSpace { + dxSimpleSpace (dSpaceID _space); + void cleanGeoms(); + void collide (void *data, dNearCallback *callback); + void collide2 (void *data, dxGeom *geom, dNearCallback *callback); +}; + + +dxSimpleSpace::dxSimpleSpace (dSpaceID _space) : dxSpace (_space) +{ + type = dSimpleSpaceClass; +} + + +void dxSimpleSpace::cleanGeoms() +{ + // compute the AABBs of all dirty geoms, and clear the dirty flags + lock_count++; + for (dxGeom *g=first; g && (g->gflags & GEOM_DIRTY); g=g->next) { + if (IS_SPACE(g)) { + ((dxSpace*)g)->cleanGeoms(); + } + + g->recomputeAABB(); + dIASSERT((g->gflags & GEOM_AABB_BAD) == 0); + + g->gflags &= ~GEOM_DIRTY; + } + lock_count--; +} + + +void dxSimpleSpace::collide (void *data, dNearCallback *callback) +{ + dAASSERT (callback); + + lock_count++; + cleanGeoms(); + + // intersect all bounding boxes + for (dxGeom *g1=first; g1; g1=g1->next) { + if (GEOM_ENABLED(g1)){ + for (dxGeom *g2=g1->next; g2; g2=g2->next) { + if (GEOM_ENABLED(g2)){ + collideAABBs (g1,g2,data,callback); + } + } + } + } + + lock_count--; +} + + +void dxSimpleSpace::collide2 (void *data, dxGeom *geom, + dNearCallback *callback) +{ + dAASSERT (geom && callback); + + lock_count++; + cleanGeoms(); + geom->recomputeAABB(); + + // intersect bounding boxes + for (dxGeom *g=first; g; g=g->next) { + if (GEOM_ENABLED(g)){ + collideAABBs (g,geom,data,callback); + } + } + + lock_count--; +} + +//**************************************************************************** +// utility stuff for hash table space + +// kind of silly, but oh well... +#ifndef MAXINT +#define MAXINT ((int)((((unsigned int)(-1)) << 1) >> 1)) +#endif + + +// prime[i] is the largest prime smaller than 2^i +#define NUM_PRIMES 31 +static const unsigned long int prime[NUM_PRIMES] = {1L,2L,3L,7L,13L,31L,61L,127L,251L,509L, +1021L,2039L,4093L,8191L,16381L,32749L,65521L,131071L,262139L, +524287L,1048573L,2097143L,4194301L,8388593L,16777213L,33554393L, +67108859L,134217689L,268435399L,536870909L,1073741789L}; + + +// an axis aligned bounding box in the hash table +struct dxAABB { + int level; // the level this is stored in (cell size = 2^level) + int dbounds[6]; // AABB bounds, discretized to cell size + dxGeom *geom; // corresponding geometry object (AABB stored here) + sizeint index; // index of this AABB, starting from 0 +}; + + +// a hash table node that represents an AABB that intersects a particular cell +// at a particular level +struct Node { + Node *next; // next node in hash table collision list, 0 if none + int x,y,z; // cell position in space, discretized to cell size + dxAABB *aabb; // axis aligned bounding box that intersects this cell +}; + + +// return the `level' of an AABB. the AABB will be put into cells at this +// level - the cell size will be 2^level. the level is chosen to be the +// smallest value such that the AABB occupies no more than 8 cells, regardless +// of its placement. this means that: +// size/2 < q <= size +// where q is the maximum AABB dimension. + +static int findLevel (dReal bounds[6]) +{ + if (bounds[0] <= -dInfinity || bounds[1] >= dInfinity || + bounds[2] <= -dInfinity || bounds[3] >= dInfinity || + bounds[4] <= -dInfinity || bounds[5] >= dInfinity) { + return MAXINT; + } + + // compute q + dReal q,q2; + q = bounds[1] - bounds[0]; // x bounds + q2 = bounds[3] - bounds[2]; // y bounds + if (q2 > q) q = q2; + q2 = bounds[5] - bounds[4]; // z bounds + if (q2 > q) q = q2; + + // find level such that 0.5 * 2^level < q <= 2^level + int level; + frexp (q,&level); // q = (0.5 .. 1.0) * 2^level (definition of frexp) + return level; +} + + +// find a virtual memory address for a cell at the given level and x,y,z +// position. +// @@@ currently this is not very sophisticated, e.g. the scaling +// factors could be better designed to avoid collisions, and they should +// probably depend on the hash table physical size. + +static unsigned long getVirtualAddressBase (unsigned int level, unsigned int x, unsigned int y) +{ + return level * 1000UL + x * 100UL + y * 10UL; +} + +//**************************************************************************** +// hash space + +struct dxHashSpace : public dxSpace { + int global_minlevel; // smallest hash table level to put AABBs in + int global_maxlevel; // objects that need a level larger than this will be + // put in a "big objects" list instead of a hash table + + dxHashSpace (dSpaceID _space); + void setLevels (int minlevel, int maxlevel); + void getLevels (int *minlevel, int *maxlevel); + void cleanGeoms(); + void collide (void *data, dNearCallback *callback); + void collide2 (void *data, dxGeom *geom, dNearCallback *callback); +}; + + +dxHashSpace::dxHashSpace (dSpaceID _space) : dxSpace (_space) +{ + type = dHashSpaceClass; + global_minlevel = -3; + global_maxlevel = 10; +} + + +void dxHashSpace::setLevels (int minlevel, int maxlevel) +{ + dAASSERT (minlevel <= maxlevel); + global_minlevel = minlevel; + global_maxlevel = maxlevel; +} + + +void dxHashSpace::getLevels (int *minlevel, int *maxlevel) +{ + if (minlevel) *minlevel = global_minlevel; + if (maxlevel) *maxlevel = global_maxlevel; +} + + +void dxHashSpace::cleanGeoms() +{ + // compute the AABBs of all dirty geoms, and clear the dirty flags + lock_count++; + for (dxGeom *g=first; g && (g->gflags & GEOM_DIRTY); g=g->next) { + if (IS_SPACE(g)) { + ((dxSpace*)g)->cleanGeoms(); + } + + g->recomputeAABB(); + dIASSERT((g->gflags & GEOM_AABB_BAD) == 0); + + g->gflags &= ~GEOM_DIRTY; + } + lock_count--; +} + + +void dxHashSpace::collide (void *data, dNearCallback *callback) +{ + dAASSERT(this && callback); + dxGeom *geom; + int i,maxlevel; + + // 0 or 1 geoms can't collide with anything + if (count < 2) return; + + lock_count++; + cleanGeoms(); + + // create a list of auxiliary information for all geom axis aligned bounding + // boxes. set the level for all AABBs. put AABBs larger than the space's + // global_maxlevel in the big_boxes list, check everything else against + // that list at the end. for AABBs that are not too big, record the maximum + // level that we need. + + typedef std::vector<dxAABB> AABBlist; + AABBlist hash_boxes; // list of AABBs in hash table + AABBlist big_boxes; // list of AABBs too big for hash table + maxlevel = global_minlevel - 1; + for (geom = first; geom; geom=geom->next) { + if (!GEOM_ENABLED(geom)){ + continue; + } + dxAABB aabb; + aabb.geom = geom; + // compute level, but prevent cells from getting too small + int level = findLevel (geom->aabb); + if (level < global_minlevel) level = global_minlevel; + if (level <= global_maxlevel) { + aabb.level = level; + if (level > maxlevel) maxlevel = level; + // cellsize = 2^level + dReal cellSizeRecip = dRecip(ldexp(REAL(1.0), level)); // No computational errors here! + // discretize AABB position to cell size + for (i=0; i < 6; i++) { + dReal aabbBound = geom->aabb[i] * cellSizeRecip; // No computational errors so far! + dICHECK(aabbBound >= dMinIntExact && aabbBound </*=*/ dMaxIntExact); // Otherwise the scene is too large for integer types used + + aabb.dbounds[i] = (int) dFloor(aabbBound); + } + // set AABB index + aabb.index = hash_boxes.size(); + // aabb goes in main list + hash_boxes.push_back(aabb); + } + else { + // aabb is too big, put it in the big_boxes list. we don't care about + // setting level, dbounds, index, or the maxlevel + big_boxes.push_back(aabb); + } + } + + sizeint n = hash_boxes.size(); // number of AABBs in main list + + // for `n' objects, an n*n array of bits is used to record if those objects + // have been intersection-tested against each other yet. this array can + // grow large with high n, but oh well... + int tested_rowsize = (n+7) >> 3; // number of bytes needed for n bits + std::vector<uint8> tested(n * tested_rowsize); + + // create a hash table to store all AABBs. each AABB may take up to 8 cells. + // we use chaining to resolve collisions, but we use a relatively large table + // to reduce the chance of collisions. + + // compute hash table size sz to be a prime > 8*n + for (i=0; i<NUM_PRIMES; i++) { + if ((sizeint)prime[i] >= (8*n)) break; + } + if (i >= NUM_PRIMES) { + i = NUM_PRIMES-1; // probably pointless + } + + const unsigned long sz = prime[i]; + + // allocate and initialize hash table node pointers + typedef std::vector<Node*> HashTable; + HashTable table(sz); + + // add each AABB to the hash table (may need to add it to up to 8 cells) + const AABBlist::iterator hashend = hash_boxes.end(); + for (AABBlist::iterator aabb = hash_boxes.begin(); aabb != hashend; ++aabb) { + const int *dbounds = aabb->dbounds; + const int xend = dbounds[1]; + for (int xi = dbounds[0]; xi <= xend; xi++) { + const int yend = dbounds[3]; + for (int yi = dbounds[2]; yi <= yend; yi++) { + int zbegin = dbounds[4]; + unsigned long hi = (getVirtualAddressBase(aabb->level,xi,yi) + zbegin) % sz; + const int zend = dbounds[5]; + for (int zi = zbegin; zi <= zend; (hi = hi + 1U != sz ? hi + 1U : 0UL), zi++) { + // get the hash index + // add a new node to the hash table + Node *node = new Node; + node->x = xi; + node->y = yi; + node->z = zi; + node->aabb = &*aabb; + node->next = table[hi]; + table[hi] = node; + } + } + } + } + + // now that all AABBs are loaded into the hash table, we do the actual + // collision detection. for all AABBs, check for other AABBs in the + // same cells for collisions, and then check for other AABBs in all + // intersecting higher level cells. + + int db[6]; // discrete bounds at current level + for (AABBlist::iterator aabb = hash_boxes.begin(); aabb != hashend; ++aabb) { + // we are searching for collisions with aabb + for (i=0; i<6; i++) db[i] = aabb->dbounds[i]; + for (int level = aabb->level; ; ) { + dIASSERT(level <= maxlevel); + const int xend = db[1]; + for (int xi = db[0]; xi <= xend; xi++) { + const int yend = db[3]; + for (int yi = db[2]; yi <= yend; yi++) { + int zbegin = db[4]; + // get the hash index + unsigned long hi = (getVirtualAddressBase(level, xi, yi) + zbegin) % sz; + const int zend = db[5]; + for (int zi = zbegin; zi <= zend; (hi = hi + 1U != sz ? hi + 1U : 0UL), zi++) { + // search all nodes at this index + for (Node* node = table[hi]; node; node=node->next) { + // node points to an AABB that may intersect aabb + if (node->aabb == &*aabb) + continue; + if (node->aabb->level == level && + node->x == xi && node->y == yi && node->z == zi) { + // see if aabb and node->aabb have already been tested + // against each other + unsigned char mask; + if (aabb->index <= node->aabb->index) { + i = (aabb->index * tested_rowsize)+(node->aabb->index >> 3); + mask = 1 << (node->aabb->index & 7); + } + else { + i = (node->aabb->index * tested_rowsize)+(aabb->index >> 3); + mask = 1 << (aabb->index & 7); + } + dIASSERT (i >= 0 && (sizeint)i < (tested_rowsize*n)); + if ((tested[i] & mask)==0) { + tested[i] |= mask; + collideAABBs (aabb->geom,node->aabb->geom,data,callback); + } + } + } + } + } + } + + if (level == maxlevel) { + break; + } + ++level; + // get the discrete bounds for the next level up + for (i=0; i<6; i++) db[i] >>= 1; + } + } + + // every AABB in the normal list must now be intersected against every + // AABB in the big_boxes list. so let's hope there are not too many objects + // in the big_boxes list. + const AABBlist::iterator bigend = big_boxes.end(); + for (AABBlist::iterator aabb = hash_boxes.begin(); aabb != hashend; ++aabb) { + for (AABBlist::iterator aabb2 = big_boxes.begin(); aabb2 != bigend; ++aabb2) { + collideAABBs (aabb->geom, aabb2->geom, data, callback); + } + } + + // intersected all AABBs in the big_boxes list together + for (AABBlist::iterator aabb = big_boxes.begin(); aabb != bigend; ++aabb) { + AABBlist::iterator aabb2 = aabb; + while (++aabb2 != bigend) { + collideAABBs (aabb->geom, aabb2->geom, data, callback); + } + } + + // deallocate table + const HashTable::iterator tableend = table.end(); + for (HashTable::iterator el = table.begin(); el != tableend; ++el) + for (Node* node = *el; node; ) { + Node* next = node->next; + delete node; + node = next; + } + + lock_count--; +} + + +void dxHashSpace::collide2 (void *data, dxGeom *geom, + dNearCallback *callback) +{ + dAASSERT (geom && callback); + + // this could take advantage of the hash structure to avoid + // O(n2) complexity, but it does not yet. + + lock_count++; + cleanGeoms(); + geom->recomputeAABB(); + + // intersect bounding boxes + for (dxGeom *g=first; g; g=g->next) { + if (GEOM_ENABLED(g)) collideAABBs (g,geom,data,callback); + } + + lock_count--; +} + +//**************************************************************************** +// space functions + +dxSpace *dSimpleSpaceCreate (dxSpace *space) +{ + return new dxSimpleSpace (space); +} + + +dxSpace *dHashSpaceCreate (dxSpace *space) +{ + return new dxHashSpace (space); +} + + +void dHashSpaceSetLevels (dxSpace *space, int minlevel, int maxlevel) +{ + dAASSERT (space); + dUASSERT (minlevel <= maxlevel,"must have minlevel <= maxlevel"); + dUASSERT (space->type == dHashSpaceClass,"argument must be a hash space"); + dxHashSpace *hspace = (dxHashSpace*) space; + hspace->setLevels (minlevel,maxlevel); +} + + +void dHashSpaceGetLevels (dxSpace *space, int *minlevel, int *maxlevel) +{ + dAASSERT (space); + dUASSERT (space->type == dHashSpaceClass,"argument must be a hash space"); + dxHashSpace *hspace = (dxHashSpace*) space; + hspace->getLevels (minlevel,maxlevel); +} + + +void dSpaceDestroy (dxSpace *space) +{ + dAASSERT (space); + dUASSERT (dGeomIsSpace(space),"argument not a space"); + dGeomDestroy (space); +} + + +void dSpaceSetCleanup (dxSpace *space, int mode) +{ + dAASSERT (space); + dUASSERT (dGeomIsSpace(space),"argument not a space"); + space->setCleanup (mode); +} + + +int dSpaceGetCleanup (dxSpace *space) +{ + dAASSERT (space); + dUASSERT (dGeomIsSpace(space),"argument not a space"); + return space->getCleanup(); +} + + +void dSpaceSetSublevel (dSpaceID space, int sublevel) +{ + dAASSERT (space); + dUASSERT (dGeomIsSpace(space),"argument not a space"); + space->setSublevel (sublevel); +} + + +int dSpaceGetSublevel (dSpaceID space) +{ + dAASSERT (space); + dUASSERT (dGeomIsSpace(space),"argument not a space"); + return space->getSublevel(); +} + +void dSpaceSetManualCleanup (dSpaceID space, int mode) +{ + dAASSERT (space); + dUASSERT (dGeomIsSpace(space),"argument not a space"); + space->setManulCleanup(mode); +} + +int dSpaceGetManualCleanup (dSpaceID space) +{ + dAASSERT (space); + dUASSERT (dGeomIsSpace(space),"argument not a space"); + return space->getManualCleanup(); +} + +void dSpaceAdd (dxSpace *space, dxGeom *g) +{ + dAASSERT (space); + dUASSERT (dGeomIsSpace(space),"argument not a space"); + CHECK_NOT_LOCKED (space); + space->add (g); +} + + +void dSpaceRemove (dxSpace *space, dxGeom *g) +{ + dAASSERT (space); + dUASSERT (dGeomIsSpace(space),"argument not a space"); + CHECK_NOT_LOCKED (space); + space->remove (g); +} + + +int dSpaceQuery (dxSpace *space, dxGeom *g) +{ + dAASSERT (space); + dUASSERT (dGeomIsSpace(space),"argument not a space"); + return space->query (g); +} + +void dSpaceClean (dxSpace *space){ + dAASSERT (space); + dUASSERT (dGeomIsSpace(space),"argument not a space"); + + space->cleanGeoms(); +} + +int dSpaceGetNumGeoms (dxSpace *space) +{ + dAASSERT (space); + dUASSERT (dGeomIsSpace(space),"argument not a space"); + return space->getNumGeoms(); +} + + +dGeomID dSpaceGetGeom (dxSpace *space, int i) +{ + dAASSERT (space); + dUASSERT (dGeomIsSpace(space),"argument not a space"); + return space->getGeom (i); +} + +int dSpaceGetClass (dxSpace *space) +{ + dAASSERT (space); + dUASSERT (dGeomIsSpace(space),"argument not a space"); + return space->type; +} + + +void dSpaceCollide (dxSpace *space, void *data, dNearCallback *callback) +{ + dAASSERT (space && callback); + dUASSERT (dGeomIsSpace(space),"argument not a space"); + space->collide (data,callback); +} + + +struct DataCallback { + void *data; + dNearCallback *callback; +}; +// Invokes the callback with arguments swapped +static void swap_callback(void *data, dxGeom *g1, dxGeom *g2) +{ + DataCallback *dc = (DataCallback*)data; + dc->callback(dc->data, g2, g1); +} + + +void dSpaceCollide2 (dxGeom *g1, dxGeom *g2, void *data, + dNearCallback *callback) +{ + dAASSERT (g1 && g2 && callback); + dxSpace *s1,*s2; + + // see if either geom is a space + if (IS_SPACE(g1)) s1 = (dxSpace*) g1; else s1 = 0; + if (IS_SPACE(g2)) s2 = (dxSpace*) g2; else s2 = 0; + + if (s1 && s2) { + int l1 = s1->getSublevel(); + int l2 = s2->getSublevel(); + if (l1 != l2) { + if (l1 > l2) { + s2 = 0; + } else { + s1 = 0; + } + } + } + + // handle the four space/geom cases + if (s1) { + if (s2) { + // g1 and g2 are spaces. + if (s1==s2) { + // collide a space with itself --> interior collision + s1->collide (data,callback); + } + else { + // iterate through the space that has the fewest geoms, calling + // collide2 in the other space for each one. + if (s1->count < s2->count) { + DataCallback dc = {data, callback}; + for (dxGeom *g = s1->first; g; g=g->next) { + s2->collide2 (&dc,g,swap_callback); + } + } + else { + for (dxGeom *g = s2->first; g; g=g->next) { + s1->collide2 (data,g,callback); + } + } + } + } + else { + // g1 is a space, g2 is a geom + s1->collide2 (data,g2,callback); + } + } + else { + if (s2) { + // g1 is a geom, g2 is a space + DataCallback dc = {data, callback}; + s2->collide2 (&dc,g1,swap_callback); + } + else { + // g1 and g2 are geoms + // make sure they have valid AABBs + g1->recomputeAABB(); + g2->recomputeAABB(); + collideAABBs(g1,g2, data, callback); + } + } +} diff --git a/libs/ode-0.16.1/ode/src/collision_space_internal.h b/libs/ode-0.16.1/ode/src/collision_space_internal.h new file mode 100644 index 0000000..be69b81 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_space_internal.h @@ -0,0 +1,80 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +stuff common to all spaces + +*/ + +#ifndef _ODE_COLLISION_SPACE_INTERNAL_H_ +#define _ODE_COLLISION_SPACE_INTERNAL_H_ + +#define ALLOCA(x) dALLOCA16(x) + + +// collide two geoms together. for the hash table space, this is +// called if the two AABBs inhabit the same hash table cells. +// this only calls the callback function if the AABBs actually +// intersect. if a geom has an AABB test function, that is called to +// provide a further refinement of the intersection. +// +// NOTE: this assumes that the geom AABBs are valid on entry +// and that both geoms are enabled. + +static inline void collideAABBs (dxGeom *g1, dxGeom *g2, + void *data, dNearCallback *callback) +{ + dIASSERT((g1->gflags & GEOM_AABB_BAD)==0); + dIASSERT((g2->gflags & GEOM_AABB_BAD)==0); + + // no contacts if both geoms on the same body, and the body is not 0 + if (g1->body == g2->body && g1->body) return; + + // test if the category and collide bitfields match + if ( ((g1->category_bits & g2->collide_bits) || + (g2->category_bits & g1->collide_bits)) == 0) { + return; + } + + // if the bounding boxes are disjoint then don't do anything + dReal *bounds1 = g1->aabb; + dReal *bounds2 = g2->aabb; + if (bounds1[0] > bounds2[1] || + bounds1[1] < bounds2[0] || + bounds1[2] > bounds2[3] || + bounds1[3] < bounds2[2] || + bounds1[4] > bounds2[5] || + bounds1[5] < bounds2[4]) { + return; + } + + // check if either object is able to prove that it doesn't intersect the + // AABB of the other + if (g1->AABBTest (g2,bounds2) == 0) return; + if (g2->AABBTest (g1,bounds1) == 0) return; + + // the objects might actually intersect - call the space callback function + callback (data,g1,g2); +} + +#endif diff --git a/libs/ode-0.16.1/ode/src/collision_std.h b/libs/ode-0.16.1/ode/src/collision_std.h new file mode 100644 index 0000000..710e580 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_std.h @@ -0,0 +1,238 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +the standard ODE geometry primitives. + +*/ + +#ifndef _ODE_COLLISION_STD_H_ +#define _ODE_COLLISION_STD_H_ + +#include <ode/common.h> +#include "collision_kernel.h" + + +// primitive collision functions - these have the dColliderFn interface, i.e. +// the same interface as dCollide(). the first and second geom arguments must +// have the specified types. + +int dCollideSphereSphere (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip); +int dCollideSphereBox (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip); +int dCollideSpherePlane (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip); +int dCollideBoxBox (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip); +int dCollideBoxPlane (dxGeom *o1, dxGeom *o2, + int flags, dContactGeom *contact, int skip); +int dCollideCapsuleSphere (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip); +int dCollideCapsuleBox (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip); +int dCollideCapsuleCapsule (dxGeom *o1, dxGeom *o2, + int flags, dContactGeom *contact, int skip); +int dCollideCapsulePlane (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip); +int dCollideRaySphere (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip); +int dCollideRayBox (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip); +int dCollideRayCapsule (dxGeom *o1, dxGeom *o2, + int flags, dContactGeom *contact, int skip); +int dCollideRayPlane (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip); +int dCollideRayCylinder (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip); + +// Cylinder - Box/Sphere by (C) CroTeam +// Ported by Nguyen Binh +int dCollideCylinderBox(dxGeom *o1, dxGeom *o2, + int flags, dContactGeom *contact, int skip); +int dCollideCylinderSphere(dxGeom *gCylinder, dxGeom *gSphere, + int flags, dContactGeom *contact, int skip); +int dCollideCylinderPlane(dxGeom *gCylinder, dxGeom *gPlane, + int flags, dContactGeom *contact, int skip); + +//--> Convex Collision +int dCollideConvexPlane (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip); +int dCollideSphereConvex (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip); +int dCollideConvexBox (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip); +int dCollideConvexCapsule (dxGeom *o1, dxGeom *o2, + int flags, dContactGeom *contact, int skip); +int dCollideConvexConvex (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip); +int dCollideRayConvex (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip); +//<-- Convex Collision + +// dHeightfield +int dCollideHeightfield( dxGeom *o1, dxGeom *o2, + int flags, dContactGeom *contact, int skip ); + +//**************************************************************************** +// the basic geometry objects + +struct dxSphere : public dxGeom { + dReal radius; // sphere radius + dxSphere (dSpaceID space, dReal _radius); + void computeAABB(); +}; + + +struct dxBox : public dxGeom { + dVector3 side; // side lengths (x,y,z) + dxBox (dSpaceID space, dReal lx, dReal ly, dReal lz); + void computeAABB(); +}; + + +struct dxCapsule : public dxGeom { + dReal radius,lz; // radius, length along z axis + dxCapsule (dSpaceID space, dReal _radius, dReal _length); + void computeAABB(); +}; + + +struct dxCylinder : public dxGeom { + dReal radius,lz; // radius, length along z axis + dxCylinder (dSpaceID space, dReal _radius, dReal _length); + void computeAABB(); +}; + + +struct dxPlane : public dxGeom { + dReal p[4]; + dxPlane (dSpaceID space, dReal a, dReal b, dReal c, dReal d); + void computeAABB(); +}; + + +struct dxRay : public dxGeom { + dReal length; + dxRay (dSpaceID space, dReal _length); + void computeAABB(); +}; + +struct dxConvex : public dxGeom +{ + const dReal *planes; /*!< An array of planes in the form: + normal X, normal Y, normal Z,Distance + */ + const dReal *points; /*!< An array of points X,Y,Z */ + const unsigned int *polygons; /*! An array of indices to the points of each polygon, it should be the number of vertices followed by that amount of indices to "points" in counter clockwise order*/ + unsigned int planecount; /*!< Amount of planes in planes */ + unsigned int pointcount;/*!< Amount of points in points */ + unsigned int edgecount;/*!< Amount of edges in convex */ + dReal saabb[6];/*!< Static AABB */ + dxConvex(dSpaceID space, + const dReal *planes, + unsigned int planecount, + const dReal *points, + unsigned int pointcount, + const unsigned int *polygons); + ~dxConvex() + { + if((edgecount!=0)&&(edges!=NULL)) delete[] edges; + } + void computeAABB(); + struct edge + { + unsigned int first; + unsigned int second; + }; + edge* edges; + + /*! \brief A Support mapping function for convex shapes + \param dir [IN] direction to find the Support Point for + \return the index of the support vertex. + */ + inline unsigned int SupportIndex(dVector3 dir) + { + dVector3 rdir; + unsigned int index=0; + dMultiply1_331 (rdir,final_posr->R,dir); + dReal max = dCalcVectorDot3(points,rdir); + dReal tmp; + for (unsigned int i = 1; i < pointcount; ++i) + { + tmp = dCalcVectorDot3(points+(i*3),rdir); + if (tmp > max) + { + index=i; + max = tmp; + } + } + return index; + } + +private: + // For Internal Use Only + /*! \brief Fills the edges dynamic array based on points and polygons. + */ + void FillEdges(); +#if 0 + /* + What this does is the same as the Support function by doing some preprocessing + for optimization. Not complete yet. + */ + // Based on Eberly's Game Physics Book page 307 + struct Arc + { + // indices of polyhedron normals that form the spherical arc + int normals[2]; + // index of edge shared by polyhedron faces + int edge; + }; + struct Polygon + { + // indices of polyhedron normals that form the spherical polygon + std::vector<int> normals; + // index of extreme vertex corresponding to this polygon + int vertex; + }; + // This is for extrem feature query and not the usual level BSP structure (that comes later) + struct BSPNode + { + // Normal index (interior node), vertex index (leaf node) + int normal; + // if Dot (E,D)>=0, D gets propagated to this child + BSPNode* right; + // if Dot (E,D)<0, D gets propagated to this child + BSPNode* left; + }; + void CreateTree(); + BSPNode* CreateNode(std::vector<Arc> Arcs,std::vector<Polygon> Polygons); + void GetFacesSharedByVertex(int i, std::vector<int> f); + void GetFacesSharedByEdge(int i, int* f); + void GetFaceNormal(int i, dVector3 normal); + BSPNode* tree; +#endif +}; + + +#endif diff --git a/libs/ode-0.16.1/ode/src/collision_transform.cpp b/libs/ode-0.16.1/ode/src/collision_transform.cpp new file mode 100644 index 0000000..ece3d53 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_transform.cpp @@ -0,0 +1,234 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +geom transform + +*/ + +#include <ode/collision.h> +#include <ode/rotation.h> +#include "config.h" +#include "matrix.h" +#include "odemath.h" +#include "collision_transform.h" +#include "collision_util.h" + +#ifdef _MSC_VER +#pragma warning(disable:4291) // for VC++, no complaints about "no matching operator delete found" +#endif + +//**************************************************************************** +// dxGeomTransform class + +struct dxGeomTransform : public dxGeom { + dxGeom *obj; // object that is being transformed + int cleanup; // 1 to destroy obj when destroyed + int infomode; // 1 to put Tx geom in dContactGeom g1 + + // cached final object transform (body tx + relative tx). this is set by + // computeAABB(), and it is valid while the AABB is valid. + dxPosR transform_posr; + + dxGeomTransform (dSpaceID space); + ~dxGeomTransform(); + void computeAABB(); + void computeFinalTx(); +}; +/* +void RunMe() +{ +printf("sizeof body = %i\n", sizeof(dxBody)); +printf("sizeof geom = %i\n", sizeof(dxGeom)); +printf("sizeof geomtransform = %i\n", sizeof(dxGeomTransform)); +printf("sizeof posr = %i\n", sizeof(dxPosR)); +} +*/ + +dxGeomTransform::dxGeomTransform (dSpaceID space) : dxGeom (space,1) +{ + type = dGeomTransformClass; + obj = 0; + cleanup = 0; + infomode = 0; + dSetZero (transform_posr.pos,4); + dRSetIdentity (transform_posr.R); +} + + +dxGeomTransform::~dxGeomTransform() +{ + if (obj && cleanup) delete obj; +} + + +void dxGeomTransform::computeAABB() +{ + if (!obj) { + dSetZero (aabb,6); + return; + } + + // backup the relative pos and R pointers of the encapsulated geom object + dxPosR* posr_bak = obj->final_posr; + + // compute temporary pos and R for the encapsulated geom object + computeFinalTx(); + obj->final_posr = &transform_posr; + + // compute the AABB + obj->computeAABB(); + memcpy (aabb,obj->aabb,6*sizeof(dReal)); + + // restore the pos and R + obj->final_posr = posr_bak; +} + + +// utility function for dCollideTransform() : compute final pos and R +// for the encapsulated geom object + +void dxGeomTransform::computeFinalTx() +{ + dMultiply0_331 (transform_posr.pos,final_posr->R,obj->final_posr->pos); + transform_posr.pos[0] += final_posr->pos[0]; + transform_posr.pos[1] += final_posr->pos[1]; + transform_posr.pos[2] += final_posr->pos[2]; + dMultiply0_333 (transform_posr.R,final_posr->R,obj->final_posr->R); +} + +//**************************************************************************** +// collider function: +// this collides a transformed geom with another geom. the other geom can +// also be a transformed geom, but this case is not handled specially. + +int dCollideTransform (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dGeomTransformClass); + + dxGeomTransform *tr = (dxGeomTransform*) o1; + if (!tr->obj) return 0; + dUASSERT (tr->obj->parent_space==0, + "GeomTransform encapsulated object must not be in a space"); + dUASSERT (tr->obj->body==0, + "GeomTransform encapsulated object must not be attached " + "to a body"); + + // backup the relative pos and R pointers of the encapsulated geom object, + // and the body pointer + dxPosR *posr_bak = tr->obj->final_posr; + dxBody *bodybak = tr->obj->body; + + // compute temporary pos and R for the encapsulated geom object. + // note that final_pos and final_R are valid if no GEOM_AABB_BAD flag, + // because computeFinalTx() will have already been called in + // dxGeomTransform::computeAABB() + + if (tr->gflags & GEOM_AABB_BAD) tr->computeFinalTx(); + tr->obj->final_posr = &tr->transform_posr; + tr->obj->body = o1->body; + + // do the collision + int n = dCollide (tr->obj,o2,flags,contact,skip); + + // if required, adjust the 'g1' values in the generated contacts so that + // thay indicated the GeomTransform object instead of the encapsulated + // object. + if (tr->infomode) { + for (int i=0; i<n; i++) { + dContactGeom *c = CONTACT(contact,skip*i); + c->g1 = o1; + } + } + + // restore the pos, R and body + tr->obj->final_posr = posr_bak; + tr->obj->body = bodybak; + return n; +} + +//**************************************************************************** +// public API + +dGeomID dCreateGeomTransform (dSpaceID space) +{ + return new dxGeomTransform (space); +} + + +void dGeomTransformSetGeom (dGeomID g, dGeomID obj) +{ + dUASSERT (g && g->type == dGeomTransformClass, + "argument not a geom transform"); + dxGeomTransform *tr = (dxGeomTransform*) g; + if (tr->obj && tr->cleanup) delete tr->obj; + tr->obj = obj; +} + + +dGeomID dGeomTransformGetGeom (dGeomID g) +{ + dUASSERT (g && g->type == dGeomTransformClass, + "argument not a geom transform"); + dxGeomTransform *tr = (dxGeomTransform*) g; + return tr->obj; +} + + +void dGeomTransformSetCleanup (dGeomID g, int mode) +{ + dUASSERT (g && g->type == dGeomTransformClass, + "argument not a geom transform"); + dxGeomTransform *tr = (dxGeomTransform*) g; + tr->cleanup = mode; +} + + +int dGeomTransformGetCleanup (dGeomID g) +{ + dUASSERT (g && g->type == dGeomTransformClass, + "argument not a geom transform"); + dxGeomTransform *tr = (dxGeomTransform*) g; + return tr->cleanup; +} + + +void dGeomTransformSetInfo (dGeomID g, int mode) +{ + dUASSERT (g && g->type == dGeomTransformClass, + "argument not a geom transform"); + dxGeomTransform *tr = (dxGeomTransform*) g; + tr->infomode = mode; +} + + +int dGeomTransformGetInfo (dGeomID g) +{ + dUASSERT (g && g->type == dGeomTransformClass, + "argument not a geom transform"); + dxGeomTransform *tr = (dxGeomTransform*) g; + return tr->infomode; +} + diff --git a/libs/ode-0.16.1/ode/src/collision_transform.h b/libs/ode-0.16.1/ode/src/collision_transform.h new file mode 100644 index 0000000..c3cd27c --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_transform.h @@ -0,0 +1,39 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +geom transform + +*/ + +#ifndef _ODE_COLLISION_TRANSFORM_H_ +#define _ODE_COLLISION_TRANSFORM_H_ + +#include <ode/common.h> +#include "collision_kernel.h" + + +int dCollideTransform (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); + + +#endif diff --git a/libs/ode-0.16.1/ode/src/collision_trimesh_box.cpp b/libs/ode-0.16.1/ode/src/collision_trimesh_box.cpp new file mode 100644 index 0000000..521ed43 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_trimesh_box.cpp @@ -0,0 +1,1380 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + + +/************************************************************************* + * * + * Triangle-box collider by Alen Ladavac and Vedran Klanac. * + * Ported to ODE by Oskari Nyman. * + * * + *************************************************************************/ + + +#include <ode/collision.h> +#include <ode/rotation.h> +#include "config.h" +#include "matrix.h" +#include "odemath.h" +#include "collision_util.h" +#include "collision_trimesh_internal.h" + +#if dTRIMESH_ENABLED + + +// largest number, double or float +#if defined(dSINGLE) +#define MAXVALUE FLT_MAX +#else +#define MAXVALUE DBL_MAX +#endif + + +// dVector3 +// r=a-b +#define SUBTRACT(a,b,r) dSubtractVectors3(r, a, b) + + +// dVector3 +// a=b +#define SET(a,b) dCopyVector3(a, b) + + +// dMatrix3 +// a=b +#define SETM(a,b) dCopyMatrix4x4(a, b) + + +// dVector3 +// r=a+b +#define ADD(a,b,r) dAddVectors3(r, a, b) + + +// dMatrix3, int, dVector3 +// v=column a from m +#define GETCOL(m,a,v) dGetMatrixColumn3(v, m, a) + + +// dVector4, dVector3 +// distance between plane p and point v +#define POINTDISTANCE(p,v) dPointPlaneDistance(v, p) + + +// dVector4, dVector3, dReal +// construct plane from normal and d +#define CONSTRUCTPLANE(plane,normal,d) dConstructPlane(normal, d, plane) + + +// dVector3 +// length of vector a +#define LENGTHOF(a) dCalcVectorLength3(a) + + +struct sTrimeshBoxColliderData +{ + sTrimeshBoxColliderData(): m_iBestAxis(0), m_iExitAxis(0), m_ctContacts(0) {} + + void SetupInitialContext(dxTriMesh *TriMesh, dxGeom *BoxGeom, + int Flags, dContactGeom* Contacts, int Stride); + void TestCollisionForSingleTriangle(int Triint, dVector3 dv[3], bool &bOutFinishSearching); + + bool _cldTestNormal(dReal fp0, dReal fR, dVector3 vNormal, int iAxis); + bool _cldTestFace(dReal fp0, dReal fp1, dReal fp2, dReal fR, dReal fD, + dVector3 vNormal, int iAxis); + bool _cldTestEdge(dReal fp0, dReal fp1, dReal fR, dReal fD, + dVector3 vNormal, int iAxis); + bool _cldTestSeparatingAxes(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2); + void _cldClipping(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2, int TriIndex); + bool _cldTestOneTriangle(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2, int TriIndex); + + void GenerateContact(int TriIndex, const dVector3 in_ContactPos, const dVector3 in_Normal, dReal in_Depth); + + // box data + dMatrix3 m_mHullBoxRot; + dVector3 m_vHullBoxPos; + dVector3 m_vBoxHalfSize; + + // mesh data + dVector3 m_vHullDstPos; + + // global collider data + dVector3 m_vBestNormal; + dReal m_fBestDepth; + int m_iBestAxis; + int m_iExitAxis; + dVector3 m_vE0, m_vE1, m_vE2, m_vN; + + // global info for contact creation + int m_iFlags; + dContactGeom *m_ContactGeoms; + int m_iStride; + dxGeom *m_Geom1; + dxGeom *m_Geom2; + int m_ctContacts; +}; + +// Test normal of mesh face as separating axis for intersection +bool sTrimeshBoxColliderData::_cldTestNormal(dReal fp0, dReal fR, dVector3 vNormal, int iAxis) +{ + // calculate overlapping interval of box and triangle + dReal fDepth = fR+fp0; + + // if we do not overlap + if ( fDepth<0 ) { + // do nothing + return false; + } + + // calculate normal's length + dReal fLength = LENGTHOF(vNormal); + // if long enough + if ( fLength > 0.0f ) { + + dReal fOneOverLength = 1.0f/fLength; + // normalize depth + fDepth = fDepth*fOneOverLength; + + // get minimum depth + if (fDepth < m_fBestDepth) { + m_vBestNormal[0] = -vNormal[0]*fOneOverLength; + m_vBestNormal[1] = -vNormal[1]*fOneOverLength; + m_vBestNormal[2] = -vNormal[2]*fOneOverLength; + m_iBestAxis = iAxis; + //dAASSERT(fDepth>=0); + m_fBestDepth = fDepth; + } + } + + return true; +} + + + + +// Test box axis as separating axis +bool sTrimeshBoxColliderData::_cldTestFace(dReal fp0, dReal fp1, dReal fp2, dReal fR, dReal fD, + dVector3 vNormal, int iAxis) +{ + dReal fMin, fMax; + + // find min of triangle interval + if ( fp0 < fp1 ) { + if ( fp0 < fp2 ) { + fMin = fp0; + } else { + fMin = fp2; + } + } else { + if( fp1 < fp2 ) { + fMin = fp1; + } else { + fMin = fp2; + } + } + + // find max of triangle interval + if ( fp0 > fp1 ) { + if ( fp0 > fp2 ) { + fMax = fp0; + } else { + fMax = fp2; + } + } else { + if( fp1 > fp2 ) { + fMax = fp1; + } else { + fMax = fp2; + } + } + + // calculate minimum and maximum depth + dReal fDepthMin = fR - fMin; + dReal fDepthMax = fMax + fR; + + // if we dont't have overlapping interval + if ( fDepthMin < 0 || fDepthMax < 0 ) { + // do nothing + return false; + } + + dReal fDepth = 0; + + // if greater depth is on negative side + if ( fDepthMin > fDepthMax ) { + // use smaller depth (one from positive side) + fDepth = fDepthMax; + // flip normal direction + vNormal[0] = -vNormal[0]; + vNormal[1] = -vNormal[1]; + vNormal[2] = -vNormal[2]; + fD = -fD; + // if greater depth is on positive side + } else { + // use smaller depth (one from negative side) + fDepth = fDepthMin; + } + + // if lower depth than best found so far + if (fDepth < m_fBestDepth) { + // remember current axis as best axis + m_vBestNormal[0] = vNormal[0]; + m_vBestNormal[1] = vNormal[1]; + m_vBestNormal[2] = vNormal[2]; + m_iBestAxis = iAxis; + //dAASSERT(fDepth>=0); + m_fBestDepth = fDepth; + } + + return true; +} + +// Test cross products of box axis and triangle edges as separating axis +bool sTrimeshBoxColliderData::_cldTestEdge(dReal fp0, dReal fp1, dReal fR, dReal fD, + dVector3 vNormal, int iAxis) +{ + dReal fMin, fMax; + + // ===== Begin Patch by Francisco Leon, 2006/10/28 ===== + + // Fixed Null Normal. This prevents boxes passing + // through trimeshes at certain contact angles + + fMin = vNormal[0] * vNormal[0] + + vNormal[1] * vNormal[1] + + vNormal[2] * vNormal[2]; + + if ( fMin <= dEpsilon ) /// THIS NORMAL WOULD BE DANGEROUS + return true; + + // ===== Ending Patch by Francisco Leon ===== + + + // calculate min and max interval values + if ( fp0 < fp1 ) { + fMin = fp0; + fMax = fp1; + } else { + fMin = fp1; + fMax = fp0; + } + + // check if we overlapp + dReal fDepthMin = fR - fMin; + dReal fDepthMax = fMax + fR; + + // if we don't overlapp + if ( fDepthMin < 0 || fDepthMax < 0 ) { + // do nothing + return false; + } + + dReal fDepth; + + // if greater depth is on negative side + if ( fDepthMin > fDepthMax ) { + // use smaller depth (one from positive side) + fDepth = fDepthMax; + // flip normal direction + vNormal[0] = -vNormal[0]; + vNormal[1] = -vNormal[1]; + vNormal[2] = -vNormal[2]; + fD = -fD; + // if greater depth is on positive side + } else { + // use smaller depth (one from negative side) + fDepth = fDepthMin; + } + + // calculate normal's length + dReal fLength = LENGTHOF(vNormal); + + // if long enough + if ( fLength > 0.0f ) { + + // normalize depth + dReal fOneOverLength = 1.0f/fLength; + fDepth = fDepth*fOneOverLength; + fD*=fOneOverLength; + + // if lower depth than best found so far (favor face over edges) + if (fDepth*1.5f < m_fBestDepth) { + // remember current axis as best axis + m_vBestNormal[0] = vNormal[0]*fOneOverLength; + m_vBestNormal[1] = vNormal[1]*fOneOverLength; + m_vBestNormal[2] = vNormal[2]*fOneOverLength; + m_iBestAxis = iAxis; + //dAASSERT(fDepth>=0); + m_fBestDepth = fDepth; + } + } + + return true; +} + + +// clip polygon with plane and generate new polygon points +static void _cldClipPolyToPlane( dVector3 avArrayIn[], int ctIn, + dVector3 avArrayOut[], int &ctOut, + const dVector4 &plPlane ) +{ + // start with no output points + ctOut = 0; + + int i0 = ctIn-1; + + // for each edge in input polygon + for (int i1=0; i1<ctIn; i0=i1, i1++) { + + + // calculate distance of edge points to plane + dReal fDistance0 = POINTDISTANCE( plPlane ,avArrayIn[i0] ); + dReal fDistance1 = POINTDISTANCE( plPlane ,avArrayIn[i1] ); + + + // if first point is in front of plane + if( fDistance0 >= 0 ) { + // emit point + avArrayOut[ctOut][0] = avArrayIn[i0][0]; + avArrayOut[ctOut][1] = avArrayIn[i0][1]; + avArrayOut[ctOut][2] = avArrayIn[i0][2]; + ctOut++; + } + + // if points are on different sides + if( (fDistance0 > 0 && fDistance1 < 0) || ( fDistance0 < 0 && fDistance1 > 0) ) { + + // find intersection point of edge and plane + dVector3 vIntersectionPoint; + vIntersectionPoint[0]= avArrayIn[i0][0] - (avArrayIn[i0][0]-avArrayIn[i1][0])*fDistance0/(fDistance0-fDistance1); + vIntersectionPoint[1]= avArrayIn[i0][1] - (avArrayIn[i0][1]-avArrayIn[i1][1])*fDistance0/(fDistance0-fDistance1); + vIntersectionPoint[2]= avArrayIn[i0][2] - (avArrayIn[i0][2]-avArrayIn[i1][2])*fDistance0/(fDistance0-fDistance1); + + // emit intersection point + avArrayOut[ctOut][0] = vIntersectionPoint[0]; + avArrayOut[ctOut][1] = vIntersectionPoint[1]; + avArrayOut[ctOut][2] = vIntersectionPoint[2]; + ctOut++; + } + } + +} + + + + +bool sTrimeshBoxColliderData::_cldTestSeparatingAxes(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2) { + // reset best axis + m_iBestAxis = 0; + m_iExitAxis = -1; + m_fBestDepth = MAXVALUE; + + // calculate edges + SUBTRACT(v1,v0,m_vE0); + SUBTRACT(v2,v0,m_vE1); + SUBTRACT(m_vE1,m_vE0,m_vE2); + + // calculate poly normal + dCalcVectorCross3(m_vN,m_vE0,m_vE1); + + // calculate length of face normal + dReal fNLen = LENGTHOF(m_vN); + + // Even though all triangles might be initially valid, + // a triangle may degenerate into a segment after applying + // space transformation. + if (!fNLen) { + return false; + } + + // extract box axes as vectors + dVector3 vA0,vA1,vA2; + GETCOL(m_mHullBoxRot,0,vA0); + GETCOL(m_mHullBoxRot,1,vA1); + GETCOL(m_mHullBoxRot,2,vA2); + + // box halfsizes + dReal fa0 = m_vBoxHalfSize[0]; + dReal fa1 = m_vBoxHalfSize[1]; + dReal fa2 = m_vBoxHalfSize[2]; + + // calculate relative position between box and triangle + dVector3 vD; + SUBTRACT(v0,m_vHullBoxPos,vD); + + dVector3 vL; + dReal fp0, fp1, fp2, fR, fD; + + // Test separating axes for intersection + // ************************************************ + // Axis 1 - Triangle Normal + SET(vL,m_vN); + fp0 = dCalcVectorDot3(vL,vD); + fp1 = fp0; + fp2 = fp0; + fR=fa0*dFabs( dCalcVectorDot3(m_vN,vA0) ) + fa1 * dFabs( dCalcVectorDot3(m_vN,vA1) ) + fa2 * dFabs( dCalcVectorDot3(m_vN,vA2) ); + + if (!_cldTestNormal(fp0, fR, vL, 1)) { + m_iExitAxis=1; + return false; + } + + // ************************************************ + + // Test Faces + // ************************************************ + // Axis 2 - Box X-Axis + SET(vL,vA0); + fD = dCalcVectorDot3(vL,m_vN)/fNLen; + fp0 = dCalcVectorDot3(vL,vD); + fp1 = fp0 + dCalcVectorDot3(vA0,m_vE0); + fp2 = fp0 + dCalcVectorDot3(vA0,m_vE1); + fR = fa0; + + if (!_cldTestFace(fp0, fp1, fp2, fR, fD, vL, 2)) { + m_iExitAxis=2; + return false; + } + // ************************************************ + + // ************************************************ + // Axis 3 - Box Y-Axis + SET(vL,vA1); + fD = dCalcVectorDot3(vL,m_vN)/fNLen; + fp0 = dCalcVectorDot3(vL,vD); + fp1 = fp0 + dCalcVectorDot3(vA1,m_vE0); + fp2 = fp0 + dCalcVectorDot3(vA1,m_vE1); + fR = fa1; + + if (!_cldTestFace(fp0, fp1, fp2, fR, fD, vL, 3)) { + m_iExitAxis=3; + return false; + } + + // ************************************************ + + // ************************************************ + // Axis 4 - Box Z-Axis + SET(vL,vA2); + fD = dCalcVectorDot3(vL,m_vN)/fNLen; + fp0 = dCalcVectorDot3(vL,vD); + fp1 = fp0 + dCalcVectorDot3(vA2,m_vE0); + fp2 = fp0 + dCalcVectorDot3(vA2,m_vE1); + fR = fa2; + + if (!_cldTestFace(fp0, fp1, fp2, fR, fD, vL, 4)) { + m_iExitAxis=4; + return false; + } + + // ************************************************ + + // Test Edges + // ************************************************ + // Axis 5 - Box X-Axis cross Edge0 + dCalcVectorCross3(vL,vA0,m_vE0); + fD = dCalcVectorDot3(vL,m_vN)/fNLen; + fp0 = dCalcVectorDot3(vL,vD); + fp1 = fp0; + fp2 = fp0 + dCalcVectorDot3(vA0,m_vN); + fR = fa1 * dFabs(dCalcVectorDot3(vA2,m_vE0)) + fa2 * dFabs(dCalcVectorDot3(vA1,m_vE0)); + + if (!_cldTestEdge(fp1, fp2, fR, fD, vL, 5)) { + m_iExitAxis=5; + return false; + } + // ************************************************ + + // ************************************************ + // Axis 6 - Box X-Axis cross Edge1 + dCalcVectorCross3(vL,vA0,m_vE1); + fD = dCalcVectorDot3(vL,m_vN)/fNLen; + fp0 = dCalcVectorDot3(vL,vD); + fp1 = fp0 - dCalcVectorDot3(vA0,m_vN); + fp2 = fp0; + fR = fa1 * dFabs(dCalcVectorDot3(vA2,m_vE1)) + fa2 * dFabs(dCalcVectorDot3(vA1,m_vE1)); + + if (!_cldTestEdge(fp0, fp1, fR, fD, vL, 6)) { + m_iExitAxis=6; + return false; + } + // ************************************************ + + // ************************************************ + // Axis 7 - Box X-Axis cross Edge2 + dCalcVectorCross3(vL,vA0,m_vE2); + fD = dCalcVectorDot3(vL,m_vN)/fNLen; + fp0 = dCalcVectorDot3(vL,vD); + fp1 = fp0 - dCalcVectorDot3(vA0,m_vN); + fp2 = fp0 - dCalcVectorDot3(vA0,m_vN); + fR = fa1 * dFabs(dCalcVectorDot3(vA2,m_vE2)) + fa2 * dFabs(dCalcVectorDot3(vA1,m_vE2)); + + if (!_cldTestEdge(fp0, fp1, fR, fD, vL, 7)) { + m_iExitAxis=7; + return false; + } + + // ************************************************ + + // ************************************************ + // Axis 8 - Box Y-Axis cross Edge0 + dCalcVectorCross3(vL,vA1,m_vE0); + fD = dCalcVectorDot3(vL,m_vN)/fNLen; + fp0 = dCalcVectorDot3(vL,vD); + fp1 = fp0; + fp2 = fp0 + dCalcVectorDot3(vA1,m_vN); + fR = fa0 * dFabs(dCalcVectorDot3(vA2,m_vE0)) + fa2 * dFabs(dCalcVectorDot3(vA0,m_vE0)); + + if (!_cldTestEdge(fp0, fp2, fR, fD, vL, 8)) { + m_iExitAxis=8; + return false; + } + + // ************************************************ + + // ************************************************ + // Axis 9 - Box Y-Axis cross Edge1 + dCalcVectorCross3(vL,vA1,m_vE1); + fD = dCalcVectorDot3(vL,m_vN)/fNLen; + fp0 = dCalcVectorDot3(vL,vD); + fp1 = fp0 - dCalcVectorDot3(vA1,m_vN); + fp2 = fp0; + fR = fa0 * dFabs(dCalcVectorDot3(vA2,m_vE1)) + fa2 * dFabs(dCalcVectorDot3(vA0,m_vE1)); + + if (!_cldTestEdge(fp0, fp1, fR, fD, vL, 9)) { + m_iExitAxis=9; + return false; + } + + // ************************************************ + + // ************************************************ + // Axis 10 - Box Y-Axis cross Edge2 + dCalcVectorCross3(vL,vA1,m_vE2); + fD = dCalcVectorDot3(vL,m_vN)/fNLen; + fp0 = dCalcVectorDot3(vL,vD); + fp1 = fp0 - dCalcVectorDot3(vA1,m_vN); + fp2 = fp0 - dCalcVectorDot3(vA1,m_vN); + fR = fa0 * dFabs(dCalcVectorDot3(vA2,m_vE2)) + fa2 * dFabs(dCalcVectorDot3(vA0,m_vE2)); + + if (!_cldTestEdge(fp0, fp1, fR, fD, vL, 10)) { + m_iExitAxis=10; + return false; + } + + // ************************************************ + + // ************************************************ + // Axis 11 - Box Z-Axis cross Edge0 + dCalcVectorCross3(vL,vA2,m_vE0); + fD = dCalcVectorDot3(vL,m_vN)/fNLen; + fp0 = dCalcVectorDot3(vL,vD); + fp1 = fp0; + fp2 = fp0 + dCalcVectorDot3(vA2,m_vN); + fR = fa0 * dFabs(dCalcVectorDot3(vA1,m_vE0)) + fa1 * dFabs(dCalcVectorDot3(vA0,m_vE0)); + + if (!_cldTestEdge(fp0, fp2, fR, fD, vL, 11)) { + m_iExitAxis=11; + return false; + } + // ************************************************ + + // ************************************************ + // Axis 12 - Box Z-Axis cross Edge1 + dCalcVectorCross3(vL,vA2,m_vE1); + fD = dCalcVectorDot3(vL,m_vN)/fNLen; + fp0 = dCalcVectorDot3(vL,vD); + fp1 = fp0 - dCalcVectorDot3(vA2,m_vN); + fp2 = fp0; + fR = fa0 * dFabs(dCalcVectorDot3(vA1,m_vE1)) + fa1 * dFabs(dCalcVectorDot3(vA0,m_vE1)); + + if (!_cldTestEdge(fp0, fp1, fR, fD, vL, 12)) { + m_iExitAxis=12; + return false; + } + // ************************************************ + + // ************************************************ + // Axis 13 - Box Z-Axis cross Edge2 + dCalcVectorCross3(vL,vA2,m_vE2); + fD = dCalcVectorDot3(vL,m_vN)/fNLen; + fp0 = dCalcVectorDot3(vL,vD); + fp1 = fp0 - dCalcVectorDot3(vA2,m_vN); + fp2 = fp0 - dCalcVectorDot3(vA2,m_vN); + fR = fa0 * dFabs(dCalcVectorDot3(vA1,m_vE2)) + fa1 * dFabs(dCalcVectorDot3(vA0,m_vE2)); + + if (!_cldTestEdge(fp0, fp1, fR, fD, vL, 13)) { + m_iExitAxis=13; + return false; + } + + // ************************************************ + return true; +} + + + + + +// find two closest points on two lines +static bool _cldClosestPointOnTwoLines( + dVector3 vPoint1, dVector3 vLenVec1, dVector3 vPoint2, dVector3 vLenVec2, + dReal &fvalue1, dReal &fvalue2) +{ + // calculate denominator + dVector3 vp; + SUBTRACT(vPoint2,vPoint1,vp); + dReal fuaub = dCalcVectorDot3(vLenVec1,vLenVec2); + dReal fq1 = dCalcVectorDot3(vLenVec1,vp); + dReal fq2 = -dCalcVectorDot3(vLenVec2,vp); + dReal fd = 1.0f - fuaub * fuaub; + + // if denominator is positive + if (fd > 0.0f) { + // calculate points of closest approach + fd = 1.0f/fd; + fvalue1 = (fq1 + fuaub*fq2)*fd; + fvalue2 = (fuaub*fq1 + fq2)*fd; + return true; + // otherwise + } else { + // lines are parallel + fvalue1 = 0.0f; + fvalue2 = 0.0f; + return false; + } +} + + + + + +// clip and generate contacts +void sTrimeshBoxColliderData::_cldClipping(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2, int TriIndex) { + dIASSERT( !(m_iFlags & CONTACTS_UNIMPORTANT) || m_ctContacts < (m_iFlags & NUMC_MASK) ); // Do not call the function if there is no room to store results + + // if we have edge/edge intersection + if (m_iBestAxis > 4 ) { + dVector3 vub,vPb,vPa; + + SET(vPa,m_vHullBoxPos); + + // calculate point on box edge + for( int i=0; i<3; i++) { + dVector3 vRotCol; + GETCOL(m_mHullBoxRot,i,vRotCol); + dReal fSign = dCalcVectorDot3(m_vBestNormal,vRotCol) > 0 ? 1.0f : -1.0f; + + vPa[0] += fSign * m_vBoxHalfSize[i] * vRotCol[0]; + vPa[1] += fSign * m_vBoxHalfSize[i] * vRotCol[1]; + vPa[2] += fSign * m_vBoxHalfSize[i] * vRotCol[2]; + } + + int iEdge = (m_iBestAxis-5)%3; + + // decide which edge is on triangle + if ( iEdge == 0 ) { + SET(vPb,v0); + SET(vub,m_vE0); + } else if ( iEdge == 1) { + SET(vPb,v2); + SET(vub,m_vE1); + } else { + SET(vPb,v1); + SET(vub,m_vE2); + } + + + // setup direction parameter for face edge + dNormalize3(vub); + + dReal fParam1, fParam2; + + // setup direction parameter for box edge + dVector3 vua; + int col=(m_iBestAxis-5)/3; + GETCOL(m_mHullBoxRot,col,vua); + + // find two closest points on both edges + _cldClosestPointOnTwoLines( vPa, vua, vPb, vub, fParam1, fParam2 ); + vPa[0] += vua[0]*fParam1; + vPa[1] += vua[1]*fParam1; + vPa[2] += vua[2]*fParam1; + + vPb[0] += vub[0]*fParam2; + vPb[1] += vub[1]*fParam2; + vPb[2] += vub[2]*fParam2; + + // calculate collision point + dVector3 vPntTmp; + ADD(vPa,vPb,vPntTmp); + + vPntTmp[0]*=0.5f; + vPntTmp[1]*=0.5f; + vPntTmp[2]*=0.5f; + + // generate contact point between two closest points + GenerateContact(TriIndex, vPntTmp, m_vBestNormal, m_fBestDepth); + + + // if triangle is the referent face then clip box to triangle face + } else if (m_iBestAxis == 1) { + + dVector3 vNormal2; + vNormal2[0]=-m_vBestNormal[0]; + vNormal2[1]=-m_vBestNormal[1]; + vNormal2[2]=-m_vBestNormal[2]; + + + // vNr is normal in box frame, pointing from triangle to box + dMatrix3 mTransposed; + mTransposed[0*4+0]=m_mHullBoxRot[0*4+0]; + mTransposed[0*4+1]=m_mHullBoxRot[1*4+0]; + mTransposed[0*4+2]=m_mHullBoxRot[2*4+0]; + + mTransposed[1*4+0]=m_mHullBoxRot[0*4+1]; + mTransposed[1*4+1]=m_mHullBoxRot[1*4+1]; + mTransposed[1*4+2]=m_mHullBoxRot[2*4+1]; + + mTransposed[2*4+0]=m_mHullBoxRot[0*4+2]; + mTransposed[2*4+1]=m_mHullBoxRot[1*4+2]; + mTransposed[2*4+2]=m_mHullBoxRot[2*4+2]; + + dVector3 vNr; + vNr[0]=mTransposed[0*4+0]*vNormal2[0]+ mTransposed[0*4+1]*vNormal2[1]+ mTransposed[0*4+2]*vNormal2[2]; + vNr[1]=mTransposed[1*4+0]*vNormal2[0]+ mTransposed[1*4+1]*vNormal2[1]+ mTransposed[1*4+2]*vNormal2[2]; + vNr[2]=mTransposed[2*4+0]*vNormal2[0]+ mTransposed[2*4+1]*vNormal2[1]+ mTransposed[2*4+2]*vNormal2[2]; + + + dVector3 vAbsNormal; + vAbsNormal[0] = dFabs( vNr[0] ); + vAbsNormal[1] = dFabs( vNr[1] ); + vAbsNormal[2] = dFabs( vNr[2] ); + + // get closest face from box + int iB0, iB1, iB2; + if (vAbsNormal[1] > vAbsNormal[0]) { + if (vAbsNormal[1] > vAbsNormal[2]) { + iB1 = 0; iB0 = 1; iB2 = 2; + } else { + iB1 = 0; iB2 = 1; iB0 = 2; + } + } else { + + if (vAbsNormal[0] > vAbsNormal[2]) { + iB0 = 0; iB1 = 1; iB2 = 2; + } else { + iB1 = 0; iB2 = 1; iB0 = 2; + } + } + + // Here find center of box face we are going to project + dVector3 vCenter; + dVector3 vRotCol; + GETCOL(m_mHullBoxRot,iB0,vRotCol); + + if (vNr[iB0] > 0) { + vCenter[0] = m_vHullBoxPos[0] - v0[0] - m_vBoxHalfSize[iB0] * vRotCol[0]; + vCenter[1] = m_vHullBoxPos[1] - v0[1] - m_vBoxHalfSize[iB0] * vRotCol[1]; + vCenter[2] = m_vHullBoxPos[2] - v0[2] - m_vBoxHalfSize[iB0] * vRotCol[2]; + } else { + vCenter[0] = m_vHullBoxPos[0] - v0[0] + m_vBoxHalfSize[iB0] * vRotCol[0]; + vCenter[1] = m_vHullBoxPos[1] - v0[1] + m_vBoxHalfSize[iB0] * vRotCol[1]; + vCenter[2] = m_vHullBoxPos[2] - v0[2] + m_vBoxHalfSize[iB0] * vRotCol[2]; + } + + // Here find 4 corner points of box + dVector3 avPoints[4]; + + dVector3 vRotCol2; + GETCOL(m_mHullBoxRot,iB1,vRotCol); + GETCOL(m_mHullBoxRot,iB2,vRotCol2); + + for(int x=0;x<3;x++) { + avPoints[0][x] = vCenter[x] + (m_vBoxHalfSize[iB1] * vRotCol[x]) - (m_vBoxHalfSize[iB2] * vRotCol2[x]); + avPoints[1][x] = vCenter[x] - (m_vBoxHalfSize[iB1] * vRotCol[x]) - (m_vBoxHalfSize[iB2] * vRotCol2[x]); + avPoints[2][x] = vCenter[x] - (m_vBoxHalfSize[iB1] * vRotCol[x]) + (m_vBoxHalfSize[iB2] * vRotCol2[x]); + avPoints[3][x] = vCenter[x] + (m_vBoxHalfSize[iB1] * vRotCol[x]) + (m_vBoxHalfSize[iB2] * vRotCol2[x]); + } + + // clip Box face with 4 planes of triangle (1 face plane, 3 egde planes) + dVector3 avTempArray1[9]; + dVector3 avTempArray2[9]; + dVector4 plPlane; + + int iTempCnt1=0; + int iTempCnt2=0; + + // zeroify vectors - necessary? + for(int i=0; i<9; i++) { + avTempArray1[i][0]=0; + avTempArray1[i][1]=0; + avTempArray1[i][2]=0; + + avTempArray2[i][0]=0; + avTempArray2[i][1]=0; + avTempArray2[i][2]=0; + } + + + // Normal plane + dVector3 vTemp; + vTemp[0]=-m_vN[0]; + vTemp[1]=-m_vN[1]; + vTemp[2]=-m_vN[2]; + dNormalize3(vTemp); + CONSTRUCTPLANE(plPlane,vTemp,0); + + _cldClipPolyToPlane( avPoints, 4, avTempArray1, iTempCnt1, plPlane ); + + + // Plane p0 + dVector3 vTemp2; + SUBTRACT(v1,v0,vTemp2); + dCalcVectorCross3(vTemp,m_vN,vTemp2); + dNormalize3(vTemp); + CONSTRUCTPLANE(plPlane,vTemp,0); + + _cldClipPolyToPlane( avTempArray1, iTempCnt1, avTempArray2, iTempCnt2, plPlane ); + + // Plane p1 + SUBTRACT(v2,v1,vTemp2); + dCalcVectorCross3(vTemp,m_vN,vTemp2); + dNormalize3(vTemp); + SUBTRACT(v0,v2,vTemp2); + CONSTRUCTPLANE(plPlane,vTemp,dCalcVectorDot3(vTemp2,vTemp)); + + _cldClipPolyToPlane( avTempArray2, iTempCnt2, avTempArray1, iTempCnt1, plPlane ); + + // Plane p2 + SUBTRACT(v0,v2,vTemp2); + dCalcVectorCross3(vTemp,m_vN,vTemp2); + dNormalize3(vTemp); + CONSTRUCTPLANE(plPlane,vTemp,0); + + _cldClipPolyToPlane( avTempArray1, iTempCnt1, avTempArray2, iTempCnt2, plPlane ); + + // END of clipping polygons + + // for each generated contact point + for ( int i=0; i<iTempCnt2; i++ ) { + // calculate depth + dReal fTempDepth = dCalcVectorDot3(vNormal2,avTempArray2[i]); + + // clamp depth to zero + if (fTempDepth > 0) { + fTempDepth = 0; + } + + dVector3 vPntTmp; + ADD(avTempArray2[i],v0,vPntTmp); + + GenerateContact(TriIndex, vPntTmp, m_vBestNormal, -fTempDepth); + + if ((m_ctContacts | CONTACTS_UNIMPORTANT) == (m_iFlags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) { + break; + } + } + + //dAASSERT(m_ctContacts>0); + + // if box face is the referent face, then clip triangle on box face + } else { // 2 <= if iBestAxis <= 4 + + // get normal of box face + dVector3 vNormal2; + SET(vNormal2,m_vBestNormal); + + // get indices of box axes in correct order + int iA0,iA1,iA2; + iA0 = m_iBestAxis-2; + if ( iA0 == 0 ) { + iA1 = 1; iA2 = 2; + } else if ( iA0 == 1 ) { + iA1 = 0; iA2 = 2; + } else { + iA1 = 0; iA2 = 1; + } + + dVector3 avPoints[3]; + // calculate triangle vertices in box frame + SUBTRACT(v0,m_vHullBoxPos,avPoints[0]); + SUBTRACT(v1,m_vHullBoxPos,avPoints[1]); + SUBTRACT(v2,m_vHullBoxPos,avPoints[2]); + + // CLIP Polygons + // define temp data for clipping + dVector3 avTempArray1[9]; + dVector3 avTempArray2[9]; + + int iTempCnt1, iTempCnt2; + + // zeroify vectors - necessary? + for(int i=0; i<9; i++) { + avTempArray1[i][0]=0; + avTempArray1[i][1]=0; + avTempArray1[i][2]=0; + + avTempArray2[i][0]=0; + avTempArray2[i][1]=0; + avTempArray2[i][2]=0; + } + + // clip triangle with 5 box planes (1 face plane, 4 edge planes) + + dVector4 plPlane; + + // Normal plane + dVector3 vTemp; + vTemp[0]=-vNormal2[0]; + vTemp[1]=-vNormal2[1]; + vTemp[2]=-vNormal2[2]; + CONSTRUCTPLANE(plPlane,vTemp,m_vBoxHalfSize[iA0]); + + _cldClipPolyToPlane( avPoints, 3, avTempArray1, iTempCnt1, plPlane ); + + + // Plane p0 + GETCOL(m_mHullBoxRot,iA1,vTemp); + CONSTRUCTPLANE(plPlane,vTemp,m_vBoxHalfSize[iA1]); + + _cldClipPolyToPlane( avTempArray1, iTempCnt1, avTempArray2, iTempCnt2, plPlane ); + + + // Plane p1 + GETCOL(m_mHullBoxRot,iA1,vTemp); + vTemp[0]=-vTemp[0]; + vTemp[1]=-vTemp[1]; + vTemp[2]=-vTemp[2]; + CONSTRUCTPLANE(plPlane,vTemp,m_vBoxHalfSize[iA1]); + + _cldClipPolyToPlane( avTempArray2, iTempCnt2, avTempArray1, iTempCnt1, plPlane ); + + // Plane p2 + GETCOL(m_mHullBoxRot,iA2,vTemp); + CONSTRUCTPLANE(plPlane,vTemp,m_vBoxHalfSize[iA2]); + + _cldClipPolyToPlane( avTempArray1, iTempCnt1, avTempArray2, iTempCnt2, plPlane ); + + // Plane p3 + GETCOL(m_mHullBoxRot,iA2,vTemp); + vTemp[0]=-vTemp[0]; + vTemp[1]=-vTemp[1]; + vTemp[2]=-vTemp[2]; + CONSTRUCTPLANE(plPlane,vTemp,m_vBoxHalfSize[iA2]); + + _cldClipPolyToPlane( avTempArray2, iTempCnt2, avTempArray1, iTempCnt1, plPlane ); + + + // for each generated contact point + for ( int i=0; i<iTempCnt1; i++ ) { + // calculate depth + dReal fTempDepth = dCalcVectorDot3(vNormal2,avTempArray1[i])-m_vBoxHalfSize[iA0]; + + // clamp depth to zero + if (fTempDepth > 0) { + fTempDepth = 0; + } + + // generate contact data + dVector3 vPntTmp; + ADD(avTempArray1[i],m_vHullBoxPos,vPntTmp); + + GenerateContact(TriIndex, vPntTmp, m_vBestNormal, -fTempDepth); + + if ((m_ctContacts | CONTACTS_UNIMPORTANT) == (m_iFlags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) { + break; + } + } + + //dAASSERT(m_ctContacts>0); + } +} + +// GenerateContact - Written by Jeff Smith (jeff@burri.to) +// Generate a "unique" contact. A unique contact has a unique +// position or normal. If the potential contact has the same +// position and normal as an existing contact, but a larger +// penetration depth, this new depth is used instead +// +void sTrimeshBoxColliderData::GenerateContact(int TriIndex, const dVector3 in_ContactPos, const dVector3 in_Normal, dReal in_Depth) +{ + int TriCount = m_ctContacts; + + do + { + dContactGeom* TgtContact = NULL; + bool deeper = false; + + if (!(m_iFlags & CONTACTS_UNIMPORTANT)) + { + dReal MinDepth = dInfinity; + dContactGeom* MinContact = NULL; + + bool duplicate = false; + for (int i = 0; i < TriCount; i++) + { + dContactGeom* Contact = SAFECONTACT(m_iFlags, m_ContactGeoms, i, m_iStride); + + // same position? + dVector3 diff; + dSubtractVectors3(diff, in_ContactPos, Contact->pos); + + if (dCalcVectorDot3(diff, diff) < dEpsilon) + { + // same normal? + if (REAL(1.0) - dCalcVectorDot3(in_Normal, Contact->normal) < dEpsilon) + { + if (in_Depth > Contact->depth) + { + Contact->depth = in_Depth; + Contact->side1 = TriIndex; + } + + duplicate = true; + break; + } + } + + if (Contact->depth < MinDepth) + { + MinDepth = Contact->depth; + MinContact = Contact; + } + } + if (duplicate) + { + break; + } + + if (TriCount == (m_iFlags & NUMC_MASK)) + { + if (!(MinDepth < in_Depth)) + { + break; + } + + TgtContact = MinContact; + deeper = true; + } + } + else + { + dIASSERT(TriCount < (m_iFlags & NUMC_MASK)); + } + + if (!deeper) + { + // Add a new contact + TgtContact = SAFECONTACT(m_iFlags, m_ContactGeoms, TriCount, m_iStride); + TriCount++; + + TgtContact->pos[3] = 0.0; + + TgtContact->normal[3] = 0.0; + + TgtContact->g1 = m_Geom1; + TgtContact->g2 = m_Geom2; + + TgtContact->side2 = -1; + } + + TgtContact->pos[0] = in_ContactPos[0]; + TgtContact->pos[1] = in_ContactPos[1]; + TgtContact->pos[2] = in_ContactPos[2]; + + TgtContact->normal[0] = in_Normal[0]; + TgtContact->normal[1] = in_Normal[1]; + TgtContact->normal[2] = in_Normal[2]; + + TgtContact->depth = in_Depth; + + TgtContact->side1 = TriIndex; + + m_ctContacts = TriCount; + } + while (false); +} + + + + + +void sTrimeshBoxColliderData::SetupInitialContext(dxTriMesh *TriMesh, dxGeom *BoxGeom, + int Flags, dContactGeom* Contacts, int Stride) +{ + // get source hull position, orientation and half size + const dMatrix3& mRotBox=*(const dMatrix3*)dGeomGetRotation(BoxGeom); + const dVector3& vPosBox=*(const dVector3*)dGeomGetPosition(BoxGeom); + + // to global + SETM(m_mHullBoxRot,mRotBox); + SET(m_vHullBoxPos,vPosBox); + + dGeomBoxGetLengths(BoxGeom, m_vBoxHalfSize); + m_vBoxHalfSize[0] *= 0.5f; + m_vBoxHalfSize[1] *= 0.5f; + m_vBoxHalfSize[2] *= 0.5f; + + // get destination hull position and orientation + const dVector3& vPosMesh=*(const dVector3*)dGeomGetPosition(TriMesh); + + // to global + SET(m_vHullDstPos,vPosMesh); + + // global info for contact creation + m_ctContacts = 0; + m_iStride=Stride; + m_iFlags=Flags; + m_ContactGeoms=Contacts; + m_Geom1=TriMesh; + m_Geom2=BoxGeom; + + // reset stuff + m_fBestDepth = MAXVALUE; + m_vBestNormal[0]=0; + m_vBestNormal[1]=0; + m_vBestNormal[2]=0; +} + +void sTrimeshBoxColliderData::TestCollisionForSingleTriangle(int Triint, dVector3 dv[3], bool &bOutFinishSearching) +{ + bool finish = false; + + // test this triangle + if (_cldTestOneTriangle(dv[0], dv[1], dv[2], Triint)) + { + /* + NOTE by Oleh_Derevenko: + The function continues checking triangles after maximal number + of contacts is reached because it selects maximal penetration depths. + See also comments in GenerateContact() + */ + finish = ((m_ctContacts | CONTACTS_UNIMPORTANT) == (m_iFlags & (NUMC_MASK | CONTACTS_UNIMPORTANT))); + } + + bOutFinishSearching = finish; +} + +// test one mesh triangle on intersection with given box +bool sTrimeshBoxColliderData::_cldTestOneTriangle(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2, int TriIndex)//, void *pvUser) +{ + // do intersection test and find best separating axis + if (!_cldTestSeparatingAxes(v0, v1, v2)) { + // if not found do nothing + return false; + } + + // if best separation axis is not found + if (m_iBestAxis == 0) { + // this should not happen (we should already exit in that case) + //dMessage (0, "best separation axis not found"); + // do nothing + return false; + } + + _cldClipping(v0, v1, v2, TriIndex); + return true; +} + + +// OPCODE version of box to mesh collider +#if dTRIMESH_OPCODE +static void dQueryBTLPotentialCollisionTriangles(OBBCollider &Collider, + const sTrimeshBoxColliderData &cData, dxTriMesh *TriMesh, dxGeom *BoxGeom, + OBBCache &BoxCache) +{ + // get destination hull position and orientation + const dMatrix3& mRotMesh=*(const dMatrix3*)dGeomGetRotation(TriMesh); + const dVector3& vPosMesh=*(const dVector3*)dGeomGetPosition(TriMesh); + + Matrix4x4 MeshMatrix; + const dVector3 vZeroVector3 = { REAL(0.0), }; + MakeMatrix(vZeroVector3, mRotMesh, MeshMatrix); + + // get source hull position, orientation and half size + const dMatrix3& mRotBox=*(const dMatrix3*)dGeomGetRotation(BoxGeom); + const dVector3& vPosBox=*(const dVector3*)dGeomGetPosition(BoxGeom); + + dVector3 vOffsetPosBox; + dSubtractVectors3(vOffsetPosBox, vPosBox, vPosMesh); + + // Make OBB + OBB Box; + Box.mCenter.Set(vOffsetPosBox[0], vOffsetPosBox[1], vOffsetPosBox[2]); + Box.mExtents.Set(cData.m_vBoxHalfSize[0], cData.m_vBoxHalfSize[1], cData.m_vBoxHalfSize[2]); + Box.mRot.Set( + mRotBox[0], mRotBox[4], mRotBox[8], + mRotBox[1], mRotBox[5], mRotBox[9], + mRotBox[2], mRotBox[6], mRotBox[10]); + + // TC results + if (TriMesh->getDoTC(dxTriMesh::TTC_BOX)) { + dxTriMesh::BoxTC* BoxTC = 0; + const int iBoxCacheSize = TriMesh->m_BoxTCCache.size(); + for (int i = 0; i != iBoxCacheSize; i++){ + if (TriMesh->m_BoxTCCache[i].Geom == BoxGeom){ + BoxTC = &TriMesh->m_BoxTCCache[i]; + break; + } + } + if (!BoxTC){ + TriMesh->m_BoxTCCache.push(dxTriMesh::BoxTC()); + + BoxTC = &TriMesh->m_BoxTCCache[TriMesh->m_BoxTCCache.size() - 1]; + BoxTC->Geom = BoxGeom; + BoxTC->FatCoeff = 1.1f; // Pierre recommends this, instead of 1.0 + } + + // Intersect + Collider.SetTemporalCoherence(true); + Collider.Collide(*BoxTC, Box, TriMesh->retrieveMeshBVTreeRef(), null, &MeshMatrix); + } + else { + Collider.SetTemporalCoherence(false); + Collider.Collide(BoxCache, Box, TriMesh->retrieveMeshBVTreeRef(), null, &MeshMatrix); + } +} + +int dCollideBTL(dxGeom* g1, dxGeom* BoxGeom, int Flags, dContactGeom* Contacts, int Stride){ + dIASSERT (Stride >= (int)sizeof(dContactGeom)); + dIASSERT (g1->type == dTriMeshClass); + dIASSERT (BoxGeom->type == dBoxClass); + dIASSERT ((Flags & NUMC_MASK) >= 1); + + dxTriMesh* TriMesh = (dxTriMesh*)g1; + + sTrimeshBoxColliderData cData; + cData.SetupInitialContext(TriMesh, BoxGeom, Flags, Contacts, Stride); + + const unsigned uiTLSKind = TriMesh->getParentSpaceTLSKind(); + dIASSERT(uiTLSKind == BoxGeom->getParentSpaceTLSKind()); // The colliding spaces must use matching cleanup method + TrimeshCollidersCache *pccColliderCache = GetTrimeshCollidersCache(uiTLSKind); + OBBCollider& Collider = pccColliderCache->m_OBBCollider; + + dQueryBTLPotentialCollisionTriangles(Collider, cData, TriMesh, BoxGeom, + pccColliderCache->m_DefaultBoxCache); + + if (!Collider.GetContactStatus()) { + // no collision occurred + return 0; + } + + // Retrieve data + int TriCount = Collider.GetNbTouchedPrimitives(); + const int* Triangles = (const int*)Collider.GetTouchedPrimitives(); + + if (TriCount != 0){ + if (TriMesh->m_ArrayCallback != null){ + TriMesh->m_ArrayCallback(TriMesh, BoxGeom, Triangles, TriCount); + } + + // get destination hull position and orientation + const dMatrix3& mRotMesh=*(const dMatrix3*)dGeomGetRotation(TriMesh); + const dVector3& vPosMesh=*(const dVector3*)dGeomGetPosition(TriMesh); + + // loop through all intersecting triangles + for (int i = 0; i < TriCount; i++){ + const int Triint = Triangles[i]; + if (!TriMesh->invokeCallback(BoxGeom, Triint)) continue; + + dVector3 dv[3]; + TriMesh->fetchMeshTriangle(dv, Triint, vPosMesh, mRotMesh); + + bool bFinishSearching; + cData.TestCollisionForSingleTriangle(Triint, dv, bFinishSearching); + + if (bFinishSearching) { + break; + } + } + } + + return cData.m_ctContacts; +} +#endif + +// GIMPACT version of box to mesh collider +#if dTRIMESH_GIMPACT +int dCollideBTL(dxGeom* g1, dxGeom* BoxGeom, int Flags, dContactGeom* Contacts, int Stride) +{ + dIASSERT (Stride >= (int)sizeof(dContactGeom)); + dIASSERT (g1->type == dTriMeshClass); + dIASSERT (BoxGeom->type == dBoxClass); + dIASSERT ((Flags & NUMC_MASK) >= 1); + + + dxTriMesh* TriMesh = (dxTriMesh*)g1; + + g1 -> recomputeAABB(); + BoxGeom -> recomputeAABB(); + + + sTrimeshBoxColliderData cData; + cData.SetupInitialContext(TriMesh, BoxGeom, Flags, Contacts, Stride); + + //*****at first , collide box aabb******// + + GIM_TRIMESH * ptrimesh = &TriMesh->m_collision_trimesh; + aabb3f test_aabb(BoxGeom->aabb[0], BoxGeom->aabb[1], BoxGeom->aabb[2], BoxGeom->aabb[3], BoxGeom->aabb[4], BoxGeom->aabb[5]); + + GDYNAMIC_ARRAY collision_result; + GIM_CREATE_BOXQUERY_LIST(collision_result); + + gim_aabbset_box_collision(&test_aabb, &ptrimesh->m_aabbset , &collision_result); + + if(collision_result.m_size==0) + { + GIM_DYNARRAY_DESTROY(collision_result); + return 0; + } + //*****Set globals for box collision******// + + //collide triangles + + GUINT32 * boxesresult = GIM_DYNARRAY_POINTER(GUINT32,collision_result); + gim_trimesh_locks_work_data(ptrimesh); + + for(unsigned int i=0;i<collision_result.m_size;i++) + { + dVector3 dv[3]; + + int Triint = boxesresult[i]; + gim_trimesh_get_triangle_vertices(ptrimesh, Triint, dv[0], dv[1], dv[2]); + + bool bFinishSearching; + cData.TestCollisionForSingleTriangle(Triint, dv, bFinishSearching); + + if (bFinishSearching) + { + break; + } + } + + gim_trimesh_unlocks_work_data(ptrimesh); + GIM_DYNARRAY_DESTROY(collision_result); + + return cData.m_ctContacts; +} +#endif + + + +#endif // dTRIMESH_ENABLED diff --git a/libs/ode-0.16.1/ode/src/collision_trimesh_ccylinder.cpp b/libs/ode-0.16.1/ode/src/collision_trimesh_ccylinder.cpp new file mode 100644 index 0000000..6681cc6 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_trimesh_ccylinder.cpp @@ -0,0 +1,1183 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * Triangle-Capsule(Capsule) collider by Alen Ladavac + * Ported to ODE by Nguyen Binh + */ + +// NOTES from Nguyen Binh +// 14 Apr : Seem to be robust +// There is a problem when you use original Step and set contact friction +// surface.mu = dInfinity; +// More description : +// When I dropped Capsule over the bunny ears, it seems to stuck +// there for a while. I think the cause is when you set surface.mu = dInfinity; +// the friction force is too high so it just hang the capsule there. +// So the good cure for this is to set mu = around 1.5 (in my case) +// For StepFast1, this become as solid as rock : StepFast1 just approximate +// friction force. + +// NOTES from Croteam's Alen +//As a side note... there are some extra contacts that can be generated +//on the edge between two triangles, and if the capsule penetrates deeply into +//the triangle (usually happens with large mass or low FPS), some such +//contacts can in some cases push the capsule away from the edge instead of +//away from the two triangles. This shows up as capsule slowing down a bit +//when hitting an edge while sliding along a flat tesselated grid of +//triangles. This is only if capsule is standing upwards. + +//Same thing can appear whenever a smooth object (e.g sphere) hits such an +//edge, and it needs to be solved as a special case probably. This is a +//problem we are looking forward to address soon. + +#include <ode/collision.h> +#include <ode/rotation.h> +#include "config.h" +#include "matrix.h" +#include "odemath.h" +#include "collision_util.h" +#include "collision_trimesh_internal.h" +#include "util.h" + + +#if dTRIMESH_ENABLED + +// OPCODE version +#if dTRIMESH_OPCODE + +// largest number, double or float +#if defined(dSINGLE) +#define MAX_REAL FLT_MAX +#define MIN_REAL (-FLT_MAX) +#else +#define MAX_REAL DBL_MAX +#define MIN_REAL (-DBL_MAX) +#endif + +// To optimize before send contacts to dynamic part +#define OPTIMIZE_CONTACTS 1 + +// dVector3 +// r=a-b +#define SUBTRACT(a,b,r) dSubtractVectors3(r, a, b) + + +// dVector3 +// a=b +#define SET(a,b) dCopyVector3(a, b) + + +// dMatrix3 +// a=b +#define SETM(a,b) dCopyMatrix4x4(a, b) + + +// dVector3 +// r=a+b +#define ADD(a,b,r) dAddVectors3(r, a, b) + + +// dMatrix3, int, dVector3 +// v=column a from m +#define GETCOL(m,a,v) dGetMatrixColumn3(v, m, a) + + +// dVector4, dVector3 +// distance between plane p and point v +#define POINTDISTANCE(p,v) dPointPlaneDistance(v, p) + + +// dVector4, dVector3, dReal +// construct plane from normal and d +#define CONSTRUCTPLANE(plane,normal,d) dConstructPlane(normal, d, plane) + + +// dVector3 +// length of vector a +#define LENGTHOF(a) dCalcVectorLength3(a) + + +static inline dReal _length2OfVector3(dVector3 v) +{ + return dCalcVectorLengthSquare3(v); +} + + +// Local contacts data +typedef struct _sLocalContactData +{ + dVector3 vPos; + dVector3 vNormal; + dReal fDepth; + int triIndex; + int nFlags; // 0 = filtered out, 1 = OK +}sLocalContactData; + +struct sTrimeshCapsuleColliderData +{ + sTrimeshCapsuleColliderData(): m_gLocalContacts(NULL), m_ctContacts(0) { memset(m_vN, 0, sizeof(dVector3)); } + + void SetupInitialContext(dxTriMesh *TriMesh, dxGeom *Capsule, int flags, int skip); + int TestCollisionForSingleTriangle(int ctContacts0, int Triint, dVector3 dv[3], + uint8 flags, bool &bOutFinishSearching); + +#if OPTIMIZE_CONTACTS + void _OptimizeLocalContacts(); +#endif + int _ProcessLocalContacts(dContactGeom *contact, dxTriMesh *TriMesh, dxGeom *Capsule); + + static BOOL _cldClipEdgeToPlane(dVector3 &vEpnt0, dVector3 &vEpnt1, const dVector4& plPlane); + BOOL _cldTestAxis(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2, + dVector3 vAxis, int iAxis, BOOL bNoFlip = FALSE); + BOOL _cldTestSeparatingAxesOfCapsule(const dVector3 &v0, const dVector3 &v1, + const dVector3 &v2, uint8 flags); + void _cldTestOneTriangleVSCapsule(const dVector3 &v0, const dVector3 &v1, + const dVector3 &v2, uint8 flags); + + sLocalContactData *m_gLocalContacts; + unsigned int m_ctContacts; + + // capsule data + // real time data + dMatrix3 m_mCapsuleRotation; + dVector3 m_vCapsulePosition; + dVector3 m_vCapsuleAxis; + // static data + dReal m_vCapsuleRadius; + dReal m_fCapsuleSize; + + // mesh data + // dMatrix4 mHullDstPl; + dMatrix3 m_mTriMeshRot; + dVector3 m_vTriMeshPos; + dVector3 m_vE0, m_vE1, m_vE2; + + // global collider data + dVector3 m_vNormal; + dReal m_fBestDepth; + dReal m_fBestCenter; + dReal m_fBestrt; + int m_iBestAxis; + dVector3 m_vN; + + dVector3 m_vV0; + dVector3 m_vV1; + dVector3 m_vV2; + + // ODE contact's specific + unsigned int m_iFlags; + int m_iStride; +}; + +// Capsule lie on axis number 3 = (Z axis) +static const int nCAPSULE_AXIS = 2; + + +#if OPTIMIZE_CONTACTS + +// Use to classify contacts to be "near" in position +static const dReal fSameContactPositionEpsilon = REAL(0.0001); // 1e-4 +// Use to classify contacts to be "near" in normal direction +static const dReal fSameContactNormalEpsilon = REAL(0.0001); // 1e-4 + +// If this two contact can be classified as "near" +inline int _IsNearContacts(sLocalContactData& c1,sLocalContactData& c2) +{ + int bPosNear = 0; + int bSameDir = 0; + dVector3 vDiff; + + // First check if they are "near" in position + SUBTRACT(c1.vPos,c2.vPos,vDiff); + if ( (dFabs(vDiff[0]) < fSameContactPositionEpsilon) + &&(dFabs(vDiff[1]) < fSameContactPositionEpsilon) + &&(dFabs(vDiff[2]) < fSameContactPositionEpsilon)) + { + bPosNear = 1; + } + + // Second check if they are "near" in normal direction + SUBTRACT(c1.vNormal,c2.vNormal,vDiff); + if ( (dFabs(vDiff[0]) < fSameContactNormalEpsilon) + &&(dFabs(vDiff[1]) < fSameContactNormalEpsilon) + &&(dFabs(vDiff[2]) < fSameContactNormalEpsilon) ) + { + bSameDir = 1; + } + + // Will be "near" if position and normal direction are "near" + return (bPosNear && bSameDir); +} + +inline int _IsBetter(sLocalContactData& c1,sLocalContactData& c2) +{ + // The not better will be throw away + // You can change the selection criteria here + return (c1.fDepth > c2.fDepth); +} + +// iterate through gLocalContacts and filtered out "near contact" +void sTrimeshCapsuleColliderData::_OptimizeLocalContacts() +{ + int nContacts = m_ctContacts; + + for (int i = 0; i < nContacts-1; i++) + { + for (int j = i+1; j < nContacts; j++) + { + if (_IsNearContacts(m_gLocalContacts[i],m_gLocalContacts[j])) + { + // If they are seem to be the samed then filtered + // out the least penetrate one + if (_IsBetter(m_gLocalContacts[j],m_gLocalContacts[i])) + { + m_gLocalContacts[i].nFlags = 0; // filtered 1st contact + } + else + { + m_gLocalContacts[j].nFlags = 0; // filtered 2nd contact + } + + // NOTE + // There is other way is to add two depth together but + // it not work so well. Why??? + } + } + } +} +#endif // OPTIMIZE_CONTACTS + +int sTrimeshCapsuleColliderData::_ProcessLocalContacts(dContactGeom *contact, + dxTriMesh *TriMesh, dxGeom *Capsule) +{ +#if OPTIMIZE_CONTACTS + if (m_ctContacts > 1 && !(m_iFlags & CONTACTS_UNIMPORTANT)) + { + // Can be optimized... + _OptimizeLocalContacts(); + } +#endif + + unsigned int iContact = 0; + dContactGeom* Contact = 0; + + unsigned int nFinalContact = 0; + + for (iContact = 0; iContact < m_ctContacts; iContact ++) + { + // Ensure that we haven't created too many contacts + if( nFinalContact >= (m_iFlags & NUMC_MASK)) + { + break; + } + + if (1 == m_gLocalContacts[iContact].nFlags) + { + Contact = SAFECONTACT(m_iFlags, contact, nFinalContact, m_iStride); + Contact->depth = m_gLocalContacts[iContact].fDepth; + SET(Contact->normal,m_gLocalContacts[iContact].vNormal); + SET(Contact->pos,m_gLocalContacts[iContact].vPos); + Contact->g1 = TriMesh; + Contact->g2 = Capsule; + Contact->side1 = m_gLocalContacts[iContact].triIndex; + Contact->side2 = -1; + + nFinalContact++; + } + } + // debug + //if (nFinalContact != m_ctContacts) + //{ + // printf("[Info] %d contacts generated,%d filtered.\n",m_ctContacts,m_ctContacts-nFinalContact); + //} + + return nFinalContact; +} + +BOOL sTrimeshCapsuleColliderData::_cldClipEdgeToPlane( + dVector3 &vEpnt0, dVector3 &vEpnt1, const dVector4& plPlane) +{ + // calculate distance of edge points to plane + dReal fDistance0 = POINTDISTANCE( plPlane, vEpnt0 ); + dReal fDistance1 = POINTDISTANCE( plPlane, vEpnt1 ); + + // if both points are behind the plane + if ( fDistance0 < 0 && fDistance1 < 0 ) + { + // do nothing + return FALSE; + // if both points in front of the plane + } else if ( fDistance0 > 0 && fDistance1 > 0 ) + { + // accept them + return TRUE; + // if we have edge/plane intersection + } else if ((fDistance0 > 0 && fDistance1 < 0) || ( fDistance0 < 0 && fDistance1 > 0)) + { + // find intersection point of edge and plane + dVector3 vIntersectionPoint; + vIntersectionPoint[0]= vEpnt0[0]-(vEpnt0[0]-vEpnt1[0])*fDistance0/(fDistance0-fDistance1); + vIntersectionPoint[1]= vEpnt0[1]-(vEpnt0[1]-vEpnt1[1])*fDistance0/(fDistance0-fDistance1); + vIntersectionPoint[2]= vEpnt0[2]-(vEpnt0[2]-vEpnt1[2])*fDistance0/(fDistance0-fDistance1); + + // clamp correct edge to intersection point + if ( fDistance0 < 0 ) + { + SET(vEpnt0,vIntersectionPoint); + } else + { + SET(vEpnt1,vIntersectionPoint); + } + return TRUE; + } + return TRUE; +} + +BOOL sTrimeshCapsuleColliderData::_cldTestAxis( + const dVector3 &/*v0*/, + const dVector3 &/*v1*/, + const dVector3 &/*v2*/, + dVector3 vAxis, + int iAxis, + BOOL bNoFlip/* = FALSE*/) +{ + + // calculate length of separating axis vector + dReal fL = LENGTHOF(vAxis); + // if not long enough + // TODO : dReal epsilon please + if ( fL < REAL(1e-5) ) + { + // do nothing + //iLastOutAxis = 0; + return TRUE; + } + + // otherwise normalize it + dNormalize3(vAxis); + + // project capsule on vAxis + dReal frc = dFabs(dCalcVectorDot3(m_vCapsuleAxis,vAxis))*(m_fCapsuleSize*REAL(0.5)-m_vCapsuleRadius) + m_vCapsuleRadius; + + // project triangle on vAxis + dReal afv[3]; + afv[0] = dCalcVectorDot3(m_vV0, vAxis); + afv[1] = dCalcVectorDot3(m_vV1, vAxis); + afv[2] = dCalcVectorDot3(m_vV2, vAxis); + + dReal fMin = MAX_REAL; + dReal fMax = MIN_REAL; + + // for each vertex + for(int i=0; i<3; i++) + { + // find minimum + if (afv[i]<fMin) + { + fMin = afv[i]; + } + // find maximum + if (afv[i]>fMax) + { + fMax = afv[i]; + } + } + + // find triangle's center of interval on axis + dReal fCenter = (fMin+fMax)*REAL(0.5); + // calculate triangles half interval + dReal fTriangleRadius = (fMax-fMin)*REAL(0.5); + + // if they do not overlap, + if (dFabs(fCenter) > ( frc + fTriangleRadius )) + { + // exit, we have no intersection + return FALSE; + } + + // calculate depth + dReal fDepth = dFabs(fCenter) - (frc+fTriangleRadius); + + // if greater then best found so far + if ( fDepth > m_fBestDepth ) + { + // remember depth + m_fBestDepth = fDepth; + m_fBestCenter = fCenter; + m_fBestrt = fTriangleRadius; + + m_vNormal[0] = vAxis[0]; + m_vNormal[1] = vAxis[1]; + m_vNormal[2] = vAxis[2]; + + m_iBestAxis = iAxis; + + // flip normal if interval is wrong faced + if (fCenter<0 && !bNoFlip) + { + m_vNormal[0] = -m_vNormal[0]; + m_vNormal[1] = -m_vNormal[1]; + m_vNormal[2] = -m_vNormal[2]; + + m_fBestCenter = -fCenter; + } + } + + return TRUE; +} + +// helper for less key strokes +inline void _CalculateAxis(const dVector3& v1, + const dVector3& v2, + const dVector3& v3, + const dVector3& v4, + dVector3& r) +{ + dVector3 t1; + dVector3 t2; + + SUBTRACT(v1,v2,t1); + dCalcVectorCross3(t2,t1,v3); + dCalcVectorCross3(r,t2,v4); +} + +BOOL sTrimeshCapsuleColliderData::_cldTestSeparatingAxesOfCapsule( + const dVector3 &v0, + const dVector3 &v1, + const dVector3 &v2, + uint8 flags) +{ + // calculate caps centers in absolute space + dVector3 vCp0; + vCp0[0] = m_vCapsulePosition[0] + m_vCapsuleAxis[0]*(m_fCapsuleSize*REAL(0.5)-m_vCapsuleRadius); + vCp0[1] = m_vCapsulePosition[1] + m_vCapsuleAxis[1]*(m_fCapsuleSize*REAL(0.5)-m_vCapsuleRadius); + vCp0[2] = m_vCapsulePosition[2] + m_vCapsuleAxis[2]*(m_fCapsuleSize*REAL(0.5)-m_vCapsuleRadius); + + dVector3 vCp1; + vCp1[0] = m_vCapsulePosition[0] - m_vCapsuleAxis[0]*(m_fCapsuleSize*REAL(0.5)-m_vCapsuleRadius); + vCp1[1] = m_vCapsulePosition[1] - m_vCapsuleAxis[1]*(m_fCapsuleSize*REAL(0.5)-m_vCapsuleRadius); + vCp1[2] = m_vCapsulePosition[2] - m_vCapsuleAxis[2]*(m_fCapsuleSize*REAL(0.5)-m_vCapsuleRadius); + + // reset best axis + m_iBestAxis = 0; + // reset best depth + m_fBestDepth = -MAX_REAL; + // reset separating axis vector + dVector3 vAxis = {REAL(0.0),REAL(0.0),REAL(0.0),REAL(0.0)}; + + // Epsilon value for checking axis vector length + const dReal fEpsilon = 1e-6f; + + // Translate triangle to Cc cord. + SUBTRACT(v0, m_vCapsulePosition, m_vV0); + SUBTRACT(v1, m_vCapsulePosition, m_vV1); + SUBTRACT(v2, m_vCapsulePosition, m_vV2); + + // We begin to test for 19 separating axis now + // I wonder does it help if we employ the method like ISA-GJK??? + // Or at least we should do experiment and find what axis will + // be most likely to be separating axis to check it first. + + // Original + // axis m_vN + //vAxis = -m_vN; + vAxis[0] = - m_vN[0]; + vAxis[1] = - m_vN[1]; + vAxis[2] = - m_vN[2]; + if (!_cldTestAxis(v0, v1, v2, vAxis, 1, TRUE)) + { + return FALSE; + } + + if (flags & dxTriMeshData::CUF_USE_FIRST_EDGE) + { + // axis CxE0 - Edge 0 + dCalcVectorCross3(vAxis,m_vCapsuleAxis,m_vE0); + //vAxis = dCalcVectorCross3( m_vCapsuleAxis cross vE0 ); + if (_length2OfVector3( vAxis ) > fEpsilon) { + if (!_cldTestAxis(v0, v1, v2, vAxis, 2)) { + return FALSE; + } + } + } + + if (flags & dxTriMeshData::CUF_USE_SECOND_EDGE) + { + // axis CxE1 - Edge 1 + dCalcVectorCross3(vAxis,m_vCapsuleAxis,m_vE1); + //vAxis = ( m_vCapsuleAxis cross m_vE1 ); + if (_length2OfVector3( vAxis ) > fEpsilon) { + if (!_cldTestAxis(v0, v1, v2, vAxis, 3)) { + return FALSE; + } + } + } + + if (flags & dxTriMeshData::CUF_USE_THIRD_EDGE) + { + // axis CxE2 - Edge 2 + //vAxis = ( m_vCapsuleAxis cross m_vE2 ); + dCalcVectorCross3(vAxis,m_vCapsuleAxis,m_vE2); + if (_length2OfVector3( vAxis ) > fEpsilon) { + if (!_cldTestAxis(v0, v1, v2, vAxis, 4)) { + return FALSE; + } + } + } + + if (flags & dxTriMeshData::CUF_USE_FIRST_EDGE) + { + // first capsule point + // axis ((Cp0-V0) x E0) x E0 + _CalculateAxis(vCp0,v0,m_vE0,m_vE0,vAxis); + // vAxis = ( ( vCp0-v0) cross vE0 ) cross vE0; + if (_length2OfVector3( vAxis ) > fEpsilon) { + if (!_cldTestAxis(v0, v1, v2, vAxis, 5)) { + return FALSE; + } + } + } + + if (flags & dxTriMeshData::CUF_USE_SECOND_EDGE) + { + // axis ((Cp0-V1) x E1) x E1 + _CalculateAxis(vCp0,v1,m_vE1,m_vE1,vAxis); + //vAxis = ( ( vCp0-v1) cross vE1 ) cross vE1; + if (_length2OfVector3( vAxis ) > fEpsilon) { + if (!_cldTestAxis(v0, v1, v2, vAxis, 6)) { + return FALSE; + } + } + } + + if (flags & dxTriMeshData::CUF_USE_THIRD_EDGE) + { + // axis ((Cp0-V2) x E2) x E2 + _CalculateAxis(vCp0,v2,m_vE2,m_vE2,vAxis); + //vAxis = ( ( vCp0-v2) cross vE2 ) cross vE2; + if (_length2OfVector3( vAxis ) > fEpsilon) { + if (!_cldTestAxis(v0, v1, v2, vAxis, 7)) { + return FALSE; + } + } + } + + if (flags & dxTriMeshData::CUF_USE_FIRST_EDGE) + { + // second capsule point + // axis ((Cp1-V0) x E0) x E0 + _CalculateAxis(vCp1,v0,m_vE0,m_vE0,vAxis); + //vAxis = ( ( vCp1-v0 ) cross vE0 ) cross vE0; + if (_length2OfVector3( vAxis ) > fEpsilon) { + if (!_cldTestAxis(v0, v1, v2, vAxis, 8)) { + return FALSE; + } + } + } + + if (flags & dxTriMeshData::CUF_USE_SECOND_EDGE) + { + // axis ((Cp1-V1) x E1) x E1 + _CalculateAxis(vCp1,v1,m_vE1,m_vE1,vAxis); + //vAxis = ( ( vCp1-v1 ) cross vE1 ) cross vE1; + if (_length2OfVector3( vAxis ) > fEpsilon) { + if (!_cldTestAxis(v0, v1, v2, vAxis, 9)) { + return FALSE; + } + } + } + + if (flags & dxTriMeshData::CUF_USE_THIRD_EDGE) + { + // axis ((Cp1-V2) x E2) x E2 + _CalculateAxis(vCp1,v2,m_vE2,m_vE2,vAxis); + //vAxis = ( ( vCp1-v2 ) cross vE2 ) cross vE2; + if (_length2OfVector3( vAxis ) > fEpsilon) { + if (!_cldTestAxis(v0, v1, v2, vAxis, 10)) { + return FALSE; + } + } + } + + if (flags & dxTriMeshData::CUF_USE_FIRST_VERTEX) + { + // first vertex on triangle + // axis ((V0-Cp0) x C) x C + _CalculateAxis(v0,vCp0,m_vCapsuleAxis,m_vCapsuleAxis,vAxis); + //vAxis = ( ( v0-vCp0 ) cross m_vCapsuleAxis ) cross m_vCapsuleAxis; + if (_length2OfVector3( vAxis ) > fEpsilon) { + if (!_cldTestAxis(v0, v1, v2, vAxis, 11)) { + return FALSE; + } + } + } + + if (flags & dxTriMeshData::CUF_USE_SECOND_VERTEX) + { + // second vertex on triangle + // axis ((V1-Cp0) x C) x C + _CalculateAxis(v1,vCp0,m_vCapsuleAxis,m_vCapsuleAxis,vAxis); + //vAxis = ( ( v1-vCp0 ) cross vCapsuleAxis ) cross vCapsuleAxis; + if (_length2OfVector3( vAxis ) > fEpsilon) { + if (!_cldTestAxis(v0, v1, v2, vAxis, 12)) { + return FALSE; + } + } + } + + if (flags & dxTriMeshData::CUF_USE_THIRD_VERTEX) + { + // third vertex on triangle + // axis ((V2-Cp0) x C) x C + _CalculateAxis(v2,vCp0,m_vCapsuleAxis,m_vCapsuleAxis,vAxis); + //vAxis = ( ( v2-vCp0 ) cross vCapsuleAxis ) cross vCapsuleAxis; + if (_length2OfVector3( vAxis ) > fEpsilon) { + if (!_cldTestAxis(v0, v1, v2, vAxis, 13)) { + return FALSE; + } + } + } + + // Test as separating axes direction vectors between each triangle + // edge and each capsule's cap center + + if (flags & dxTriMeshData::CUF_USE_FIRST_VERTEX) + { + // first triangle vertex and first capsule point + //vAxis = v0 - vCp0; + SUBTRACT(v0,vCp0,vAxis); + if (_length2OfVector3( vAxis ) > fEpsilon) { + if (!_cldTestAxis(v0, v1, v2, vAxis, 14)) { + return FALSE; + } + } + } + + if (flags & dxTriMeshData::CUF_USE_SECOND_VERTEX) + { + // second triangle vertex and first capsule point + //vAxis = v1 - vCp0; + SUBTRACT(v1,vCp0,vAxis); + if (_length2OfVector3( vAxis ) > fEpsilon) { + if (!_cldTestAxis(v0, v1, v2, vAxis, 15)) { + return FALSE; + } + } + } + + if (flags & dxTriMeshData::CUF_USE_THIRD_VERTEX) + { + // third triangle vertex and first capsule point + //vAxis = v2 - vCp0; + SUBTRACT(v2,vCp0,vAxis); + if (_length2OfVector3( vAxis ) > fEpsilon) { + if (!_cldTestAxis(v0, v1, v2, vAxis, 16)) { + return FALSE; + } + } + } + + if (flags & dxTriMeshData::CUF_USE_FIRST_VERTEX) + { + // first triangle vertex and second capsule point + //vAxis = v0 - vCp1; + SUBTRACT(v0,vCp1,vAxis); + if (_length2OfVector3( vAxis ) > fEpsilon) { + if (!_cldTestAxis(v0, v1, v2, vAxis, 17)) { + return FALSE; + } + } + } + + if (flags & dxTriMeshData::CUF_USE_SECOND_VERTEX) + { + // second triangle vertex and second capsule point + //vAxis = v1 - vCp1; + SUBTRACT(v1,vCp1,vAxis); + if (_length2OfVector3( vAxis ) > fEpsilon) { + if (!_cldTestAxis(v0, v1, v2, vAxis, 18)) { + return FALSE; + } + } + } + + if (flags & dxTriMeshData::CUF_USE_THIRD_VERTEX) + { + // third triangle vertex and second capsule point + //vAxis = v2 - vCp1; + SUBTRACT(v2,vCp1,vAxis); + if (_length2OfVector3( vAxis ) > fEpsilon) { + if (!_cldTestAxis(v0, v1, v2, vAxis, 19)) { + return FALSE; + } + } + } + + return TRUE; +} + +// test one mesh triangle on intersection with capsule +void sTrimeshCapsuleColliderData::_cldTestOneTriangleVSCapsule( + const dVector3 &v0, const dVector3 &v1, const dVector3 &v2, + uint8 flags) +{ + // calculate edges + SUBTRACT(v1,v0,m_vE0); + SUBTRACT(v2,v1,m_vE1); + SUBTRACT(v0,v2,m_vE2); + + dVector3 _minus_vE0; + SUBTRACT(v0,v1,_minus_vE0); + + // calculate poly normal + dCalcVectorCross3(m_vN,m_vE1,_minus_vE0); + + // Even though all triangles might be initially valid, + // a triangle may degenerate into a segment after applying + // space transformation. + if (!dSafeNormalize3(m_vN)) + { + return; + } + + // create plane from triangle + dReal plDistance = -dCalcVectorDot3(v0,m_vN); + dVector4 plTrianglePlane; + CONSTRUCTPLANE(plTrianglePlane,m_vN,plDistance); + + // calculate capsule distance to plane + dReal fDistanceCapsuleCenterToPlane = POINTDISTANCE(plTrianglePlane,m_vCapsulePosition); + + // Capsule must be over positive side of triangle + if (fDistanceCapsuleCenterToPlane < 0 /* && !bDoubleSided*/) + { + // if not don't generate contacts + return; + } + + dVector3 vPnt0, vPnt1, vPnt2; + SET (vPnt0,v0); + + if (fDistanceCapsuleCenterToPlane < 0) + { + SET (vPnt1,v2); + SET (vPnt2,v1); + } + else + { + SET (vPnt1,v1); + SET (vPnt2,v2); + } + + // do intersection test and find best separating axis + if (!_cldTestSeparatingAxesOfCapsule(vPnt0, vPnt1, vPnt2, flags)) + { + // if not found do nothing + return; + } + + // if best separation axis is not found + if (m_iBestAxis == 0 ) + { + // this should not happen (we should already exit in that case) + dIASSERT(FALSE); + // do nothing + return; + } + + // calculate caps centers in absolute space + dVector3 vCposTrans; + vCposTrans[0] = m_vCapsulePosition[0] + m_vNormal[0]*m_vCapsuleRadius; + vCposTrans[1] = m_vCapsulePosition[1] + m_vNormal[1]*m_vCapsuleRadius; + vCposTrans[2] = m_vCapsulePosition[2] + m_vNormal[2]*m_vCapsuleRadius; + + dVector3 vCEdgePoint0; + vCEdgePoint0[0] = vCposTrans[0] + m_vCapsuleAxis[0]*(m_fCapsuleSize*REAL(0.5)-m_vCapsuleRadius); + vCEdgePoint0[1] = vCposTrans[1] + m_vCapsuleAxis[1]*(m_fCapsuleSize*REAL(0.5)-m_vCapsuleRadius); + vCEdgePoint0[2] = vCposTrans[2] + m_vCapsuleAxis[2]*(m_fCapsuleSize*REAL(0.5)-m_vCapsuleRadius); + + dVector3 vCEdgePoint1; + vCEdgePoint1[0] = vCposTrans[0] - m_vCapsuleAxis[0]*(m_fCapsuleSize*REAL(0.5)-m_vCapsuleRadius); + vCEdgePoint1[1] = vCposTrans[1] - m_vCapsuleAxis[1]*(m_fCapsuleSize*REAL(0.5)-m_vCapsuleRadius); + vCEdgePoint1[2] = vCposTrans[2] - m_vCapsuleAxis[2]*(m_fCapsuleSize*REAL(0.5)-m_vCapsuleRadius); + + // transform capsule edge points into triangle space + vCEdgePoint0[0] -= vPnt0[0]; + vCEdgePoint0[1] -= vPnt0[1]; + vCEdgePoint0[2] -= vPnt0[2]; + + vCEdgePoint1[0] -= vPnt0[0]; + vCEdgePoint1[1] -= vPnt0[1]; + vCEdgePoint1[2] -= vPnt0[2]; + + dVector4 plPlane; + dVector3 _minus_vN; + _minus_vN[0] = -m_vN[0]; + _minus_vN[1] = -m_vN[1]; + _minus_vN[2] = -m_vN[2]; + // triangle plane + CONSTRUCTPLANE(plPlane,_minus_vN,0); + //plPlane = Plane4f( -m_vN, 0); + + if (!_cldClipEdgeToPlane( vCEdgePoint0, vCEdgePoint1, plPlane )) + { + return; + } + + // plane with edge 0 + dVector3 vTemp; + dCalcVectorCross3(vTemp,m_vN,m_vE0); + CONSTRUCTPLANE(plPlane, vTemp, REAL(1e-5)); + if (!_cldClipEdgeToPlane( vCEdgePoint0, vCEdgePoint1, plPlane )) + { + return; + } + + dCalcVectorCross3(vTemp,m_vN,m_vE1); + CONSTRUCTPLANE(plPlane, vTemp, -(dCalcVectorDot3(m_vE0,vTemp)-REAL(1e-5))); + if (!_cldClipEdgeToPlane( vCEdgePoint0, vCEdgePoint1, plPlane )) + { + return; + } + + dCalcVectorCross3(vTemp,m_vN,m_vE2); + CONSTRUCTPLANE(plPlane, vTemp, REAL(1e-5)); + if (!_cldClipEdgeToPlane( vCEdgePoint0, vCEdgePoint1, plPlane )) { + return; + } + + // return capsule edge points into absolute space + vCEdgePoint0[0] += vPnt0[0]; + vCEdgePoint0[1] += vPnt0[1]; + vCEdgePoint0[2] += vPnt0[2]; + + vCEdgePoint1[0] += vPnt0[0]; + vCEdgePoint1[1] += vPnt0[1]; + vCEdgePoint1[2] += vPnt0[2]; + + // calculate depths for both contact points + SUBTRACT(vCEdgePoint0,m_vCapsulePosition,vTemp); + dReal fDepth0 = dCalcVectorDot3(vTemp,m_vNormal) - (m_fBestCenter-m_fBestrt); + SUBTRACT(vCEdgePoint1,m_vCapsulePosition,vTemp); + dReal fDepth1 = dCalcVectorDot3(vTemp,m_vNormal) - (m_fBestCenter-m_fBestrt); + + // clamp depths to zero + if (fDepth0 < 0) + { + fDepth0 = 0.0f; + } + + if (fDepth1 < 0 ) + { + fDepth1 = 0.0f; + } + + // Cached contacts's data + // contact 0 + dIASSERT(m_ctContacts < (m_iFlags & NUMC_MASK)); // Do not call function if there is no room to store result + m_gLocalContacts[m_ctContacts].fDepth = fDepth0; + SET(m_gLocalContacts[m_ctContacts].vNormal,m_vNormal); + SET(m_gLocalContacts[m_ctContacts].vPos,vCEdgePoint0); + m_gLocalContacts[m_ctContacts].nFlags = 1; + m_ctContacts++; + + if (m_ctContacts < (m_iFlags & NUMC_MASK)) { + // contact 1 + m_gLocalContacts[m_ctContacts].fDepth = fDepth1; + SET(m_gLocalContacts[m_ctContacts].vNormal,m_vNormal); + SET(m_gLocalContacts[m_ctContacts].vPos,vCEdgePoint1); + m_gLocalContacts[m_ctContacts].nFlags = 1; + m_ctContacts++; + } +} + +void sTrimeshCapsuleColliderData::SetupInitialContext(dxTriMesh *TriMesh, dxGeom *Capsule, + int flags, int skip) +{ + const dMatrix3* pRot = (const dMatrix3*)dGeomGetRotation(Capsule); + memcpy(m_mCapsuleRotation, pRot, sizeof(dMatrix3)); + + const dVector3* pDst = (const dVector3*)dGeomGetPosition(Capsule); + memcpy(m_vCapsulePosition, pDst, sizeof(dVector3)); + + m_vCapsuleAxis[0] = m_mCapsuleRotation[0*4 + nCAPSULE_AXIS]; + m_vCapsuleAxis[1] = m_mCapsuleRotation[1*4 + nCAPSULE_AXIS]; + m_vCapsuleAxis[2] = m_mCapsuleRotation[2*4 + nCAPSULE_AXIS]; + + // Get size of Capsule + dGeomCapsuleGetParams(Capsule, &m_vCapsuleRadius, &m_fCapsuleSize); + m_fCapsuleSize += 2*m_vCapsuleRadius; + + const dMatrix3* pTriRot = (const dMatrix3*)dGeomGetRotation(TriMesh); + memcpy(m_mTriMeshRot, pTriRot, sizeof(dMatrix3)); + + const dVector3* pTriPos = (const dVector3*)dGeomGetPosition(TriMesh); + memcpy(m_vTriMeshPos, pTriPos, sizeof(dVector3)); + + // global info for contact creation + m_iStride =skip; + m_iFlags =flags; + + // reset contact counter + m_ctContacts = 0; + + // reset best depth + m_fBestDepth = - MAX_REAL; + m_fBestCenter = 0; + m_fBestrt = 0; + + // reset collision normal + m_vNormal[0] = REAL(0.0); + m_vNormal[1] = REAL(0.0); + m_vNormal[2] = REAL(0.0); +} + +int sTrimeshCapsuleColliderData::TestCollisionForSingleTriangle(int ctContacts0, + int Triint, dVector3 dv[3], uint8 flags, bool &bOutFinishSearching) +{ + // test this triangle + _cldTestOneTriangleVSCapsule(dv[0],dv[1],dv[2], flags); + + // fill-in tri index for generated contacts + for (; ctContacts0 < (int)m_ctContacts; ctContacts0++) + m_gLocalContacts[ctContacts0].triIndex = Triint; + + // Putting "break" at the end of loop prevents unnecessary checks on first pass and "continue" + bOutFinishSearching = (m_ctContacts >= (m_iFlags & NUMC_MASK)); + + return ctContacts0; +} + + +static void dQueryCCTLPotentialCollisionTriangles(OBBCollider &Collider, + const sTrimeshCapsuleColliderData &cData, dxTriMesh *TriMesh, dxGeom *Capsule, + OBBCache &BoxCache) +{ + Matrix4x4 MeshMatrix; + const dVector3 vZeroVector3 = { REAL(0.0), }; + MakeMatrix(vZeroVector3, cData.m_mTriMeshRot, MeshMatrix); + + const dVector3 &vCapsulePos = cData.m_vCapsulePosition; + const dMatrix3 &mCapsuleRot = cData.m_mCapsuleRotation; + + dVector3 vCapsuleOffsetPos; + dSubtractVectors3(vCapsuleOffsetPos, vCapsulePos, cData.m_vTriMeshPos); + + const dReal fCapsuleRadius = cData.m_vCapsuleRadius, fCapsuleHalfAxis = cData.m_fCapsuleSize * REAL(0.5); + + OBB obbCapsule; + obbCapsule.mCenter.Set(vCapsuleOffsetPos[0], vCapsuleOffsetPos[1], vCapsuleOffsetPos[2]); + obbCapsule.mExtents.Set( + 0 == nCAPSULE_AXIS ? fCapsuleHalfAxis : fCapsuleRadius, + 1 == nCAPSULE_AXIS ? fCapsuleHalfAxis : fCapsuleRadius, + 2 == nCAPSULE_AXIS ? fCapsuleHalfAxis : fCapsuleRadius); + obbCapsule.mRot.Set( + mCapsuleRot[0], mCapsuleRot[4], mCapsuleRot[8], + mCapsuleRot[1], mCapsuleRot[5], mCapsuleRot[9], + mCapsuleRot[2], mCapsuleRot[6], mCapsuleRot[10]); + + // TC results + if (TriMesh->getDoTC(dxTriMesh::TTC_BOX)) { + dxTriMesh::BoxTC* BoxTC = 0; + const int iBoxCacheSize = TriMesh->m_BoxTCCache.size(); + for (int i = 0; i != iBoxCacheSize; i++){ + if (TriMesh->m_BoxTCCache[i].Geom == Capsule){ + BoxTC = &TriMesh->m_BoxTCCache[i]; + break; + } + } + if (!BoxTC){ + TriMesh->m_BoxTCCache.push(dxTriMesh::BoxTC()); + + BoxTC = &TriMesh->m_BoxTCCache[TriMesh->m_BoxTCCache.size() - 1]; + BoxTC->Geom = Capsule; + BoxTC->FatCoeff = 1.0f; + } + + // Intersect + Collider.SetTemporalCoherence(true); + Collider.Collide(*BoxTC, obbCapsule, TriMesh->retrieveMeshBVTreeRef(), null, &MeshMatrix); + } + else { + Collider.SetTemporalCoherence(false); + Collider.Collide(BoxCache, obbCapsule, TriMesh->retrieveMeshBVTreeRef(), null, &MeshMatrix); + } +} + +// capsule - trimesh by CroTeam +// Ported by Nguyem Binh +int dCollideCCTL(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dTriMeshClass); + dIASSERT (o2->type == dCapsuleClass); + dIASSERT ((flags & NUMC_MASK) >= 1); + + int nContactCount = 0; + + dxTriMesh *TriMesh = (dxTriMesh*)o1; + dxGeom *Capsule = o2; + + sTrimeshCapsuleColliderData cData; + cData.SetupInitialContext(TriMesh, Capsule, flags, skip); + + const unsigned uiTLSKind = TriMesh->getParentSpaceTLSKind(); + dIASSERT(uiTLSKind == Capsule->getParentSpaceTLSKind()); // The colliding spaces must use matching cleanup method + TrimeshCollidersCache *pccColliderCache = GetTrimeshCollidersCache(uiTLSKind); + OBBCollider& Collider = pccColliderCache->m_OBBCollider; + + // Will it better to use LSS here? -> confirm Pierre. + dQueryCCTLPotentialCollisionTriangles(Collider, cData, + TriMesh, Capsule, pccColliderCache->m_DefaultBoxCache); + + if (Collider.GetContactStatus()) + { + // Retrieve data + int TriCount = Collider.GetNbTouchedPrimitives(); + + if (TriCount != 0) + { + const int* Triangles = (const int*)Collider.GetTouchedPrimitives(); + + if (TriMesh->m_ArrayCallback != null) + { + TriMesh->m_ArrayCallback(TriMesh, Capsule, Triangles, TriCount); + } + + // allocate buffer for local contacts on stack + cData.m_gLocalContacts = (sLocalContactData*)dALLOCA16(sizeof(sLocalContactData)*(cData.m_iFlags & NUMC_MASK)); + + unsigned int ctContacts0 = cData.m_ctContacts; + + const uint8 *useFlags = TriMesh->retrieveMeshSmartUseFlags(); + + // loop through all intersecting triangles + for (int i = 0; i < TriCount; i++) + { + const int Triint = Triangles[i]; + if (!TriMesh->invokeCallback(Capsule, Triint)) continue; + + dVector3 dv[3]; + TriMesh->fetchMeshTriangle(dv, Triint, cData.m_vTriMeshPos, cData.m_mTriMeshRot); + + uint8 flags = useFlags != NULL ? useFlags[Triint] : (uint8)dxTriMeshData::CUF__USE_ALL_COMPONENTS; + + bool bFinishSearching; + ctContacts0 = cData.TestCollisionForSingleTriangle(ctContacts0, Triint, dv, flags, bFinishSearching); + + if (bFinishSearching) + { + break; + } + } + + if (cData.m_ctContacts != 0) + { + nContactCount = cData._ProcessLocalContacts(contact, TriMesh, Capsule); + } + } + } + + return nContactCount; +} + + +#endif + + +// GIMPACT version +#if dTRIMESH_GIMPACT + +#include "gimpact_contact_export_helper.h" +#include "gimpact_gim_contact_accessor.h" + +#define nCAPSULE_AXIS 2 + +// capsule - trimesh By francisco leon +int dCollideCCTL(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dTriMeshClass); + dIASSERT (o2->type == dCapsuleClass); + dIASSERT ((flags & NUMC_MASK) >= 1); + + dxTriMesh* TriMesh = (dxTriMesh*)o1; + dxGeom* gCylinder = o2; + + //Get capsule params + dMatrix3 mCapsuleRotation; + dVector3 vCapsulePosition; + dVector3 vCapsuleAxis; + dReal vCapsuleRadius; + dReal fCapsuleSize; + dMatrix3* pRot = (dMatrix3*) dGeomGetRotation(gCylinder); + memcpy(mCapsuleRotation,pRot,sizeof(dMatrix3)); + dVector3* pDst = (dVector3*)dGeomGetPosition(gCylinder); + memcpy(vCapsulePosition,pDst,sizeof(dVector3)); + //Axis + vCapsuleAxis[0] = mCapsuleRotation[0*4 + nCAPSULE_AXIS]; + vCapsuleAxis[1] = mCapsuleRotation[1*4 + nCAPSULE_AXIS]; + vCapsuleAxis[2] = mCapsuleRotation[2*4 + nCAPSULE_AXIS]; + // Get size of CCylinder + dGeomCCylinderGetParams(gCylinder,&vCapsuleRadius,&fCapsuleSize); + fCapsuleSize*=0.5f; + //Set Capsule params + GIM_CAPSULE_DATA capsule; + + capsule.m_radius = vCapsuleRadius; + VEC_SCALE(capsule.m_point1,fCapsuleSize,vCapsuleAxis); + VEC_SUM(capsule.m_point1,vCapsulePosition,capsule.m_point1); + VEC_SCALE(capsule.m_point2,-fCapsuleSize,vCapsuleAxis); + VEC_SUM(capsule.m_point2,vCapsulePosition,capsule.m_point2); + + + //Create contact list + GDYNAMIC_ARRAY trimeshcontacts; + GIM_CREATE_CONTACT_LIST(trimeshcontacts); + + //Collide trimeshe vs capsule + gim_trimesh_capsule_collision(&TriMesh->m_collision_trimesh,&capsule,&trimeshcontacts); + + + if(trimeshcontacts.m_size == 0) + { + GIM_DYNARRAY_DESTROY(trimeshcontacts); + return 0; + } + + GIM_CONTACT * ptrimeshcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,trimeshcontacts); + unsigned contactcount = trimeshcontacts.m_size; + + dxGIMCContactAccessor contactaccessor(ptrimeshcontacts, TriMesh, gCylinder, -1); + contactcount = dxGImpactContactsExportHelper::ExportMaxDepthGImpactContacts(contactaccessor, contactcount, flags, contact, skip); + + GIM_DYNARRAY_DESTROY(trimeshcontacts); + + return (int)contactcount; +} + + +#endif // dTRIMESH_GIMPACT + + +#endif // dTRIMESH_ENABLED diff --git a/libs/ode-0.16.1/ode/src/collision_trimesh_colliders.h b/libs/ode-0.16.1/ode/src/collision_trimesh_colliders.h new file mode 100644 index 0000000..9452f90 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_trimesh_colliders.h @@ -0,0 +1,47 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_COLLISION_TRIMESH_COLLIDERS_H_ +#define _ODE_COLLISION_TRIMESH_COLLIDERS_H_ + + +int dCollideCylinderTrimesh(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); +int dCollideTrimeshPlane(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); + +int dCollideSTL(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); +int dCollideBTL(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); +int dCollideRTL(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); +int dCollideTTL(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); +int dCollideCCTL(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); +int dCollideConvexTrimesh(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); + +ODE_PURE_INLINE int dCollideRayTrimesh( dxGeom *ray, dxGeom *trimesh, int flags, + dContactGeom *contact, int skip ) +{ + // Swapped case, for code that needs it (heightfield initially) + // The other ray-geom colliders take geoms in a swapped order to the + // dCollideRTL function which is annoying when using function pointers. + return dCollideRTL( trimesh, ray, flags, contact, skip ); +} + + +#endif // _ODE_COLLISION_TRIMESH_COLLIDERS_H_ diff --git a/libs/ode-0.16.1/ode/src/collision_trimesh_disabled.cpp b/libs/ode-0.16.1/ode/src/collision_trimesh_disabled.cpp new file mode 100644 index 0000000..69203a0 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_trimesh_disabled.cpp @@ -0,0 +1,302 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <ode/collision.h> +#include "config.h" +#include "matrix.h" + + +#if !dTRIMESH_ENABLED + +#include "collision_util.h" +#include "collision_trimesh_internal.h" + + +static const dMatrix4 identity = +{ + REAL( 0.0 ), REAL( 0.0 ), REAL( 0.0 ), REAL( 0.0 ), + REAL( 0.0 ), REAL( 0.0 ), REAL( 0.0 ), REAL( 0.0 ), + REAL( 0.0 ), REAL( 0.0 ), REAL( 0.0 ), REAL( 0.0 ), + REAL( 0.0 ), REAL( 0.0 ), REAL( 0.0 ), REAL( 0.0 ) +}; + + +typedef dxMeshBase dxDisabledTriMesh_Parent; +struct dxDisabledTriMesh: + public dxDisabledTriMesh_Parent +{ +public: + // Functions + dxDisabledTriMesh(dxSpace *Space, + dTriCallback *Callback, dTriArrayCallback *ArrayCallback, dTriRayCallback *RayCallback): + dxDisabledTriMesh_Parent(Space, NULL, Callback, ArrayCallback, RayCallback, false) + { + } + + virtual void computeAABB(); // This is an abstract method in the base class +}; + +/*virtual */ +void dxDisabledTriMesh::computeAABB() +{ + // Do nothing +} + + +////////////////////////////////////////////////////////////////////////// +// Stub functions for trimesh calls + +/*extern */ +dTriMeshDataID dGeomTriMeshDataCreate(void) +{ + return NULL; +} + +/*extern */ +void dGeomTriMeshDataDestroy(dTriMeshDataID g) +{ + // Do nothing +} + + +/*extern */ +void dGeomTriMeshDataSet(dTriMeshDataID g, int data_id, void* in_data) +{ + // Do nothing +} + +/*extern */ +void *dGeomTriMeshDataGet(dTriMeshDataID g, int data_id) +{ + return NULL; +} + +/*extern */ +void *dGeomTriMeshDataGet2(dTriMeshDataID g, int data_id, sizeint *pout_size/*=NULL*/) +{ + if (pout_size != NULL) + { + *pout_size = 0; + } + + return NULL; +} + + +/*extern */ +void dGeomTriMeshSetLastTransform( dGeomID g, const dMatrix4 last_trans ) +{ + // Do nothing +} + +/*extern */ +const dReal *dGeomTriMeshGetLastTransform( dGeomID g ) +{ + return identity; +} + + +/*extern */ +dGeomID dCreateTriMesh(dSpaceID space, + dTriMeshDataID Data, + dTriCallback* Callback, + dTriArrayCallback* ArrayCallback, + dTriRayCallback* RayCallback) +{ + return new dxDisabledTriMesh(space, Callback, ArrayCallback, RayCallback); // Oleh_Derevenko: I'm not sure if a NULL can be returned here -- keep on returning an object for backward compatibility +} + + +/*extern */ +void dGeomTriMeshSetData(dGeomID g, dTriMeshDataID Data) +{ + // Do nothing +} + +/*extern */ +dTriMeshDataID dGeomTriMeshGetData(dGeomID g) +{ + return NULL; +} + + +/*extern */ +void dGeomTriMeshDataBuildSingle(dTriMeshDataID g, + const void* Vertices, int VertexStride, int VertexCount, + const void* Indices, int IndexCount, int TriStride) +{ + // Do nothing +} + +/*extern */ +void dGeomTriMeshDataBuildSingle1(dTriMeshDataID g, + const void* Vertices, int VertexStride, int VertexCount, + const void* Indices, int IndexCount, int TriStride, + const void* Normals) +{ + // Do nothing +} + +/*extern */ +void dGeomTriMeshDataBuildDouble(dTriMeshDataID g, + const void* Vertices, int VertexStride, int VertexCount, + const void* Indices, int IndexCount, int TriStride) +{ + // Do nothing +} + +/*extern */ +void dGeomTriMeshDataBuildDouble1(dTriMeshDataID g, + const void* Vertices, int VertexStride, int VertexCount, + const void* Indices, int IndexCount, int TriStride, + const void* Normals) +{ + // Do nothing +} + +/*extern */ +void dGeomTriMeshDataBuildSimple(dTriMeshDataID g, + const dReal* Vertices, int VertexCount, + const dTriIndex* Indices, int IndexCount) +{ + // Do nothing +} + +/*extern */ +void dGeomTriMeshDataBuildSimple1(dTriMeshDataID g, + const dReal* Vertices, int VertexCount, + const dTriIndex* Indices, int IndexCount, + const int* Normals) +{ + // Do nothing +} + + +/*extern ODE_API */ +int dGeomTriMeshDataPreprocess(dTriMeshDataID g) +{ + // Do nothing + return 1; +} + +/*extern ODE_API */ +int dGeomTriMeshDataPreprocess2(dTriMeshDataID g, unsigned int buildRequestFlags, const intptr *requestExtraData/*=NULL | const intptr (*)[dTRIDATAPREPROCESS_BUILD__MAX]*/) +{ + // Do nothing + return 1; +} + +/*extern */ +void dGeomTriMeshSetCallback(dGeomID g, dTriCallback* Callback) +{ + // Do nothing +} + +/*extern */ +dTriCallback* dGeomTriMeshGetCallback(dGeomID g) +{ + return NULL; +} + + +/*extern */ +void dGeomTriMeshSetArrayCallback(dGeomID g, dTriArrayCallback* ArrayCallback) +{ + // Do nothing +} + +/*extern */ +dTriArrayCallback* dGeomTriMeshGetArrayCallback(dGeomID g) +{ + return NULL; +} + + +/*extern */ +void dGeomTriMeshSetRayCallback(dGeomID g, dTriRayCallback* Callback) +{ + // Do nothing +} + +/*extern */ +dTriRayCallback* dGeomTriMeshGetRayCallback(dGeomID g) +{ + return NULL; +} + + +/*extern */ +void dGeomTriMeshSetTriMergeCallback(dGeomID g, dTriTriMergeCallback* Callback) +{ + // Do nothing +} + +/*extern */ +dTriTriMergeCallback* dGeomTriMeshGetTriMergeCallback(dGeomID g) +{ + return NULL; +} + + +/*extern */ +void dGeomTriMeshEnableTC(dGeomID g, int geomClass, int enable) +{ + // Do nothing +} + +/*extern */ +int dGeomTriMeshIsTCEnabled(dGeomID g, int geomClass) +{ + return 0; +} + + +/*extern */ +void dGeomTriMeshClearTCCache(dGeomID g) +{ + // Do nothing +} + + +/*extern */ +dTriMeshDataID dGeomTriMeshGetTriMeshDataID(dGeomID g) +{ + return NULL; +} + + +/*extern */ +int dGeomTriMeshGetTriangleCount (dGeomID g) +{ + return 0; +} + +/*extern */ +void dGeomTriMeshDataUpdate(dTriMeshDataID g) +{ + // Do nothing +} + + +#endif // !dTRIMESH_ENABLED + + diff --git a/libs/ode-0.16.1/ode/src/collision_trimesh_gimpact.cpp b/libs/ode-0.16.1/ode/src/collision_trimesh_gimpact.cpp new file mode 100644 index 0000000..d9b5ecd --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_trimesh_gimpact.cpp @@ -0,0 +1,424 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// TriMesh storage classes refactoring and face angle computation code by Oleh Derevenko (C) 2016-2017 + +#include <ode/collision.h> +#include <ode/rotation.h> +#include "config.h" +#include "matrix.h" +#include "odemath.h" +#include "util.h" + + +#if dTRIMESH_ENABLED && dTRIMESH_GIMPACT + +#include "collision_util.h" +#include "collision_trimesh_gimpact.h" +#include "collision_trimesh_internal_impl.h" + + +////////////////////////////////////////////////////////////////////////// +// dxTriMeshData + +bool dxTriMeshData::preprocessData(bool /*buildUseFlags*//*=false*/, FaceAngleStorageMethod faceAndgesRequirement/*=ASM__INVALID*/) +{ + FaceAngleStorageMethod faceAndgesRequirementToUse = faceAndgesRequirement; + + if (faceAndgesRequirement != ASM__INVALID && haveFaceAnglesBeenBuilt()) + { + dUASSERT(false, "Another request to build face angles after they had already been built"); + + faceAndgesRequirementToUse = ASM__INVALID; + } + + // If this mesh has already been preprocessed, exit + bool result = faceAndgesRequirementToUse == ASM__INVALID || retrieveTriangleCount() == 0 + || meaningfulPreprocessData(faceAndgesRequirementToUse); + return result; +} + +struct TrimeshDataVertexIndexAccessor_GIMPACT +{ + enum + { + TRIANGLEINDEX_STRIDE = dxTriMesh::TRIANGLEINDEX_STRIDE, + }; + + explicit TrimeshDataVertexIndexAccessor_GIMPACT(dxTriMeshData *meshData): + m_TriangleVertexIndices(meshData->retrieveTriangleVertexIndices()) + { + dIASSERT(meshData->retrieveTriangleStride() == TRIANGLEINDEX_STRIDE); + } + + void getTriangleVertexIndices(unsigned out_VertexIndices[dMTV__MAX], unsigned triangleIdx) const + { + const GUINT32 *triIndicesBegin = m_TriangleVertexIndices; + const unsigned triStride = TRIANGLEINDEX_STRIDE; + + const GUINT32 *triIndicesOfInterest = (const GUINT32 *)((const uint8 *)triIndicesBegin + (sizeint)triangleIdx * triStride); + std::copy(triIndicesOfInterest, triIndicesOfInterest + dMTV__MAX, out_VertexIndices); + } + + const GUINT32 *m_TriangleVertexIndices; +}; + +struct TrimeshDataTrianglePointAccessor_GIMPACT +{ + enum + { + VERTEXINSTANCE_STRIDE = dxTriMesh::VERTEXINSTANCE_STRIDE, + TRIANGLEINDEX_STRIDE = dxTriMesh::TRIANGLEINDEX_STRIDE, + }; + + TrimeshDataTrianglePointAccessor_GIMPACT(dxTriMeshData *meshData): + m_VertexInstances(meshData->retrieveVertexInstances()), + m_TriangleVertexIndices(meshData->retrieveTriangleVertexIndices()) + { + dIASSERT((unsigned)meshData->retrieveVertexStride() == (unsigned)VERTEXINSTANCE_STRIDE); + dIASSERT((unsigned)meshData->retrieveTriangleStride() == (unsigned)TRIANGLEINDEX_STRIDE); + } + + void getTriangleVertexPoints(dVector3 out_Points[dMTV__MAX], unsigned triangleIndex) const + { + dxTriMeshData::retrieveTriangleVertexPoints(out_Points, triangleIndex, + &m_VertexInstances[0][0], VERTEXINSTANCE_STRIDE, m_TriangleVertexIndices, TRIANGLEINDEX_STRIDE); + } + + const vec3f *m_VertexInstances; + const GUINT32 *m_TriangleVertexIndices; +}; + +bool dxTriMeshData::meaningfulPreprocessData(FaceAngleStorageMethod faceAndgesRequirement/*=ASM__INVALID*/) +{ + const bool buildFaceAngles = true; dIASSERT(faceAndgesRequirement != ASM__INVALID); + // dIASSERT(buildFaceAngles); + dIASSERT(/*!buildFaceAngles || */!haveFaceAnglesBeenBuilt()); + + bool result = false; + + bool anglesAllocated = false; + + do + { + if (buildFaceAngles) + { + if (!allocateFaceAngles(faceAndgesRequirement)) + { + break; + } + } + + anglesAllocated = true; + + const unsigned int numTris = retrieveTriangleCount(); + const unsigned int numVertices = retrieveVertexCount(); + sizeint numEdges = (sizeint)numTris * dMTV__MAX; + dIASSERT(numVertices <= numEdges); // Edge records are going to be used for vertex data as well + + const sizeint recordsMemoryRequired = dEFFICIENT_SIZE(numEdges * sizeof(EdgeRecord)); + const sizeint verticesMemoryRequired = /*dEFFICIENT_SIZE*/(numVertices * sizeof(VertexRecord)); // Skip alignment for the last chunk + const sizeint totalTempMemoryRequired = recordsMemoryRequired + verticesMemoryRequired; + void *tempBuffer = dAlloc(totalTempMemoryRequired); + + if (tempBuffer == NULL) + { + break; + } + + EdgeRecord *edges = (EdgeRecord *)tempBuffer; + VertexRecord *vertices = (VertexRecord *)((uint8 *)tempBuffer + recordsMemoryRequired); + + TrimeshDataVertexIndexAccessor_GIMPACT indexAccessor(this); + meaningfulPreprocess_SetupEdgeRecords(edges, numEdges, indexAccessor); + + // Sort the edges, so the ones sharing the same verts are beside each other + std::sort(edges, edges + numEdges); + + TrimeshDataTrianglePointAccessor_GIMPACT pointAccessor(this); + const dReal *const externalNormals = retrieveNormals(); + IFaceAngleStorageControl *faceAngles = retrieveFaceAngles(); + meaningfulPreprocess_buildEdgeFlags(NULL, faceAngles, edges, numEdges, vertices, externalNormals, pointAccessor); + + dFree(tempBuffer, totalTempMemoryRequired); + + result = true; + } + while (false); + + if (!result) + { + if (anglesAllocated) + { + if (buildFaceAngles) + { + freeFaceAngles(); + } + } + } + + return result; +} + + +////////////////////////////////////////////////////////////////////////// +// Trimesh + +dxTriMesh::~dxTriMesh() +{ + //Terminate Trimesh + gim_trimesh_destroy(&m_collision_trimesh); + gim_terminate_buffer_managers(m_buffer_managers); +} + + +/*virtual */ +void dxTriMesh::computeAABB() +{ + //update trimesh transform + mat4f transform; + IDENTIFY_MATRIX_4X4(transform); + MakeMatrix(this, transform); + gim_trimesh_set_tranform(&m_collision_trimesh, transform); + + //Update trimesh boxes + gim_trimesh_update(&m_collision_trimesh); + + GIM_AABB_COPY( &m_collision_trimesh.m_aabbset.m_global_bound, aabb ); +} + + +void dxTriMesh::assignMeshData(dxTriMeshData *Data) +{ + // GIMPACT only supports stride 12, so we need to catch the error early. + dUASSERT( + (unsigned int)Data->retrieveVertexStride() == (unsigned)VERTEXINSTANCE_STRIDE + && (unsigned int)Data->retrieveTriangleStride() == (unsigned)TRIANGLEINDEX_STRIDE, + "Gimpact trimesh only supports a stride of 3 float/int\n" + "This means that you cannot use dGeomTriMeshDataBuildSimple() with Gimpact.\n" + "Change the stride, or use Opcode trimeshes instead.\n" + ); + + dxTriMesh_Parent::assignMeshData(Data); + + //Create trimesh + const vec3f *vertexInstances = Data->retrieveVertexInstances(); + if ( vertexInstances != NULL ) + { + const GUINT32 *triangleVertexIndices = Data->retrieveTriangleVertexIndices(); + + sizeint vertexInstanceCount = Data->retrieveVertexCount(); + sizeint triangleVertexCount = (sizeint)Data->retrieveTriangleCount() * dMTV__MAX; + + gim_trimesh_create_from_data( + m_buffer_managers, + &m_collision_trimesh, // gimpact mesh + const_cast<vec3f *>(vertexInstances), // vertices + dCAST_TO_SMALLER(GUINT32, vertexInstanceCount), // nr of verts + 0, // copy verts? + const_cast<GUINT32 *>(triangleVertexIndices), // indices + dCAST_TO_SMALLER(GUINT32, triangleVertexCount), // nr of indices + 0, // copy indices? + 1 // transformed reply + ); + } +} + + +////////////////////////////////////////////////////////////////////////// + +/*extern */ +dTriMeshDataID dGeomTriMeshDataCreate() +{ + return new dxTriMeshData(); +} + +/*extern */ +void dGeomTriMeshDataDestroy(dTriMeshDataID g) +{ + dxTriMeshData *data = g; + delete data; +} + +/*extern */ +void dGeomTriMeshDataSet(dTriMeshDataID g, int dataId, void *pDataLocation) +{ + dUASSERT(g, "The argument is not a trimesh data"); + + dxTriMeshData *data = g; + + switch (dataId) + { + case dTRIMESHDATA_FACE_NORMALS: + { + data->assignNormals((const dReal *)pDataLocation); + break; + } + + case dTRIMESHDATA_USE_FLAGS: // Not used for GIMPACT + { + break; + } + + // case dTRIMESHDATA__MAX: -- To be located by Find in Files + default: + { + dUASSERT(dataId, "invalid data type"); + break; + } + } +} + +static void *geomTriMeshDataGet(dTriMeshDataID g, int dataId, sizeint *pOutDataSize) ; + +/*extern */ +void *dGeomTriMeshDataGet(dTriMeshDataID g, int dataId) +{ + return geomTriMeshDataGet(g, dataId, NULL); +} + +/*extern */ +void *dGeomTriMeshDataGet2(dTriMeshDataID g, int dataId, sizeint *pOutDataSize) +{ + return geomTriMeshDataGet(g, dataId, pOutDataSize); +} + +static +void *geomTriMeshDataGet(dTriMeshDataID g, int dataId, sizeint *pOutDataSize) +{ + dUASSERT(g, "The argument is not a trimesh data"); + + const dxTriMeshData *data = g; + + void *result = NULL; + + switch (dataId) + { + case dTRIMESHDATA_FACE_NORMALS: + { + if (pOutDataSize != NULL) + { + *pOutDataSize = data->calculateNormalsMemoryRequirement(); + } + + result = (void *)data->retrieveNormals(); + break; + } + + case dTRIMESHDATA_USE_FLAGS: // Not not used for GIMPACT + { + if (pOutDataSize != NULL) + { + *pOutDataSize = 0; + } + + break; + } + + // case dTRIMESHDATA__MAX: -- To be located by Find in Files + default: + { + if (pOutDataSize != NULL) + { + *pOutDataSize = 0; + } + + dUASSERT(dataId, "invalid data type"); + break; + } + } + + return result; +} + +/*extern */ +void dGeomTriMeshDataBuildSingle1(dTriMeshDataID g, + const void* Vertices, int VertexStride, int VertexCount, + const void* Indices, int IndexCount, int TriStride, + const void* Normals) +{ + dUASSERT(g, "The argument is not a trimesh data"); + dAASSERT(Vertices); + dAASSERT(Indices); + + dxTriMeshData *data = g; + + data->buildData(Vertices, VertexStride, VertexCount, + Indices, IndexCount, TriStride, + Normals, + true); +} + +/*extern */ +void dGeomTriMeshDataBuildDouble1(dTriMeshDataID g, + const void* Vertices, int VertexStride, int VertexCount, + const void* Indices, int IndexCount, int TriStride, + const void* Normals) +{ + dUASSERT(g, "The argument is not a trimesh data"); + dAASSERT(Vertices); + dAASSERT(Indices); + + dxTriMeshData *data = g; + + data->buildData(Vertices, VertexStride, VertexCount, + Indices, IndexCount, TriStride, + Normals, + false); +} + + +////////////////////////////////////////////////////////////////////////// + +/*extern */ +dGeomID dCreateTriMesh(dSpaceID space, + dTriMeshDataID Data, + dTriCallback* Callback, + dTriArrayCallback* ArrayCallback, + dTriRayCallback* RayCallback) +{ + dxTriMesh *mesh = new dxTriMesh(space, Data, Callback, ArrayCallback, RayCallback); + return mesh; +} + + +/*extern */ +void dGeomTriMeshSetLastTransform(dGeomID g, const dMatrix4 last_trans ) +{ + dAASSERT(g); + dUASSERT(g->type == dTriMeshClass, "The geom is not a trimesh"); + + //stub +} + +/*extern */ +const dReal *dGeomTriMeshGetLastTransform(dGeomID g) +{ + dAASSERT(g); + dUASSERT(g->type == dTriMeshClass, "The geom is not a trimesh"); + + return NULL; // stub +} + + +#endif // #if dTRIMESH_ENABLED && dTRIMESH_GIMPACT + diff --git a/libs/ode-0.16.1/ode/src/collision_trimesh_gimpact.h b/libs/ode-0.16.1/ode/src/collision_trimesh_gimpact.h new file mode 100644 index 0000000..b928e97 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_trimesh_gimpact.h @@ -0,0 +1,278 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// TriMesh code by Erwin de Vries. +// Modified for FreeSOLID Compatibility by Rodrigo Hernandez +// Trimesh caches separation by Oleh Derevenko +// TriMesh storage classes refactoring and face angle computation code by Oleh Derevenko (C) 2016-2019 + + +#ifndef _ODE_COLLISION_TRIMESH_GIMPACT_H_ +#define _ODE_COLLISION_TRIMESH_GIMPACT_H_ + + +#if dTRIMESH_ENABLED && dTRIMESH_GIMPACT + + +//**************************************************************************** +// dxTriMesh class + + +#include "collision_kernel.h" +#include "collision_trimesh_colliders.h" +#include "collision_util.h" +#include <ode/collision_trimesh.h> + +#include "collision_trimesh_internal.h" +#include <GIMPACT/gimpact.h> + + +struct TrimeshCollidersCache // Required for compatibility with OPCODE +{ +}; + + +typedef dxTriDataBase dxTriMeshData_Parent; +struct dxTriMeshData: + public dxTriMeshData_Parent +{ +public: + dxTriMeshData(): + dxTriMeshData_Parent() + { + } + + ~dxTriMeshData() { /* Do nothing */ } + + using dxTriMeshData_Parent::buildData; + + /* Setup the UseFlags array and/or build face angles*/ + bool preprocessData(bool buildUseFlags/*=false*/, FaceAngleStorageMethod faceAndgesRequirement/*=ASM__INVALID*/); + +private: + bool meaningfulPreprocessData(FaceAngleStorageMethod faceAndgesRequirement/*=ASM__INVALID*/); + +public: + /* For when app changes the vertices */ + void updateData() { /* Do nothing */ } + +public: + const vec3f *retrieveVertexInstances() const { return (const vec3f *)dxTriMeshData_Parent::retrieveVertexInstances(); } + const GUINT32 *retrieveTriangleVertexIndices() const { return (const GUINT32 *)dxTriMeshData_Parent::retrieveTriangleVertexIndices(); } + +public: + void assignNormals(const dReal *normals) { dxTriMeshData_Parent::assignNormals(normals); } + const dReal *retrieveNormals() const { return (const dReal *)dxTriMeshData_Parent::retrieveNormals(); } + sizeint calculateNormalsMemoryRequirement() const { return retrieveTriangleCount() * (sizeof(dReal) * dSA__MAX); } +}; + + + +#ifdef dDOUBLE +// To use GIMPACT with doubles, we need to patch a couple of the GIMPACT functions to +// convert arguments to floats before sending them in + + +/// Convert an gimpact vec3f to a ODE dVector3d: dVector3[i] = vec3f[i] +#define dVECTOR3_VEC3F_COPY(b,a) { \ + (b)[0] = (a)[0]; \ + (b)[1] = (a)[1]; \ + (b)[2] = (a)[2]; \ + (b)[3] = 0; \ +} + +static inline +void gim_trimesh_get_triangle_verticesODE(GIM_TRIMESH * trimesh, GUINT32 triangle_index, dVector3 v1, dVector3 v2, dVector3 v3) +{ + vec3f src1, src2, src3; + GREAL *psrc1 = v1 != NULL ? src1 : NULL; + GREAL *psrc2 = v2 != NULL ? src2 : NULL; + GREAL *psrc3 = v3 != NULL ? src3 : NULL; + gim_trimesh_get_triangle_vertices(trimesh, triangle_index, psrc1, psrc2, psrc3); + + if (v1 != NULL) + { + dVECTOR3_VEC3F_COPY(v1, src1); + } + + if (v2 != NULL) + { + dVECTOR3_VEC3F_COPY(v2, src2); + } + + if (v3 != NULL) + { + dVECTOR3_VEC3F_COPY(v3, src3); + } +} + +// Anything calling gim_trimesh_get_triangle_vertices from within ODE +// should be patched through to the dDOUBLE version above + +#define gim_trimesh_get_triangle_vertices gim_trimesh_get_triangle_verticesODE + +static inline +int gim_trimesh_ray_closest_collisionODE( GIM_TRIMESH *mesh, dVector3 origin, dVector3 dir, dReal tmax, GIM_TRIANGLE_RAY_CONTACT_DATA *contact ) +{ + vec3f dir_vec3f = { (GREAL)dir[ 0 ], (GREAL)dir[ 1 ], (GREAL)dir[ 2 ] }; + vec3f origin_vec3f = { (GREAL)origin[ 0 ], (GREAL)origin[ 1 ], (GREAL)origin[ 2 ] }; + + return gim_trimesh_ray_closest_collision( mesh, origin_vec3f, dir_vec3f, (GREAL)tmax, contact ); +} + +static inline +int gim_trimesh_ray_collisionODE( GIM_TRIMESH *mesh, const dVector3 origin, const dVector3 dir, dReal tmax, GIM_TRIANGLE_RAY_CONTACT_DATA *contact ) +{ + vec3f dir_vec3f = { (GREAL)dir[ 0 ], (GREAL)dir[ 1 ], (GREAL)dir[ 2 ] }; + vec3f origin_vec3f = { (GREAL)origin[ 0 ], (GREAL)origin[ 1 ], (GREAL)origin[ 2 ] }; + + return gim_trimesh_ray_collision( mesh, origin_vec3f, dir_vec3f, (GREAL)tmax, contact ); +} + +static inline +void gim_trimesh_sphere_collisionODE( GIM_TRIMESH *mesh, const dVector3 Position, dReal Radius, GDYNAMIC_ARRAY *contact ) +{ + vec3f pos_vec3f = { (GREAL)Position[ 0 ], (GREAL)Position[ 1 ], (GREAL)Position[ 2 ] }; + gim_trimesh_sphere_collision( mesh, pos_vec3f, (GREAL)Radius, contact ); +} + +static inline +void gim_trimesh_plane_collisionODE( GIM_TRIMESH *mesh, const dVector4 plane, GDYNAMIC_ARRAY *contact ) +{ + vec4f plane_vec4f = { (GREAL)plane[ 0 ], (GREAL)plane[ 1 ], (GREAL)plane[ 2 ], (GREAL)plane[ 3 ] }; \ + gim_trimesh_plane_collision( mesh, plane_vec4f, contact ); \ +} + +#define GIM_AABB_COPY( src, dst ) { \ + (dst)[ 0 ]= (src) -> minX; \ + (dst)[ 1 ]= (src) -> maxX; \ + (dst)[ 2 ]= (src) -> minY; \ + (dst)[ 3 ]= (src) -> maxY; \ + (dst)[ 4 ]= (src) -> minZ; \ + (dst)[ 5 ]= (src) -> maxZ; \ +} + + +#else // #ifdef !dDOUBLE + +// With single precision, we can pass native ODE vectors directly to GIMPACT + +#define gim_trimesh_ray_closest_collisionODE gim_trimesh_ray_closest_collision +#define gim_trimesh_ray_collisionODE gim_trimesh_ray_collision +#define gim_trimesh_sphere_collisionODE gim_trimesh_sphere_collision +#define gim_trimesh_plane_collisionODE gim_trimesh_plane_collision + +#define GIM_AABB_COPY( src, dst ) memcpy( dst, src, 6 * sizeof( GREAL ) ) + + +#endif // #ifdef !dDOUBLE + + +typedef dxMeshBase dxTriMesh_Parent; +struct dxTriMesh: + public dxTriMesh_Parent +{ +public: + // Functions + dxTriMesh(dxSpace *Space, dxTriMeshData *Data, + dTriCallback *Callback, dTriArrayCallback *ArrayCallback, dTriRayCallback *RayCallback): + dxTriMesh_Parent(Space, NULL, Callback, ArrayCallback, RayCallback, true) // TC has speed/space 'issues' that don't make it a clear win by default on spheres/boxes. + { + gim_init_buffer_managers(m_buffer_managers); + assignMeshData(Data); + } + + ~dxTriMesh(); + + void clearTCCache() { /* do nothing */ } + + virtual void computeAABB(); + +public: + dxTriMeshData *retrieveMeshData() const { return getMeshData(); } + + unsigned getMeshTriangleCount() const { return gim_trimesh_get_triangle_count(const_cast<GIM_TRIMESH *>(&m_collision_trimesh)); } + + void fetchMeshTransformedTriangle(dVector3 *const pout_triangle[3], unsigned index) + { + gim_trimesh_locks_work_data(&m_collision_trimesh); + gim_trimesh_get_triangle_vertices(&m_collision_trimesh, (GUINT32)index, *pout_triangle[0], *pout_triangle[1], *pout_triangle[2]); + gim_trimesh_unlocks_work_data(&m_collision_trimesh); + } + + void fetchMeshTransformedTriangle(dVector3 out_triangle[3], unsigned index) + { + gim_trimesh_locks_work_data(&m_collision_trimesh); + gim_trimesh_get_triangle_vertices(&m_collision_trimesh, (GUINT32)index, out_triangle[0], out_triangle[1], out_triangle[2]); + gim_trimesh_unlocks_work_data(&m_collision_trimesh); + } + +private: + dxTriMeshData *getMeshData() const { return static_cast<dxTriMeshData *>(dxTriMesh_Parent::getMeshData()); } + +public: + enum + { + VERTEXINSTANCE_STRIDE = sizeof(vec3f), + TRIANGLEINDEX_STRIDE = sizeof(GUINT32) * dMTV__MAX, + }; + + void assignMeshData(dxTriMeshData *Data); + +public: + GIM_TRIMESH m_collision_trimesh; + GBUFFER_MANAGER_DATA m_buffer_managers[G_BUFFER_MANAGER__MAX]; +}; + + +static inline +void MakeMatrix(const dVector3 position, const dMatrix3 rotation, mat4f m) +{ + m[0][0] = (GREAL)rotation[dM3E_XX]; + m[0][1] = (GREAL)rotation[dM3E_XY]; + m[0][2] = (GREAL)rotation[dM3E_XZ]; + + m[1][0] = (GREAL)rotation[dM3E_YX]; + m[1][1] = (GREAL)rotation[dM3E_YY]; + m[1][2] = (GREAL)rotation[dM3E_YZ]; + + m[2][0] = (GREAL)rotation[dM3E_ZX]; + m[2][1] = (GREAL)rotation[dM3E_ZY]; + m[2][2] = (GREAL)rotation[dM3E_ZZ]; + + m[0][3] = (GREAL)position[dV3E_X]; + m[1][3] = (GREAL)position[dV3E_Y]; + m[2][3] = (GREAL)position[dV3E_Z]; +} + +static inline +void MakeMatrix(dxGeom *g, mat4f m) +{ + const dVector3 &position = g->buildUpdatedPosition(); + const dMatrix3 &rotation = g->buildUpdatedRotation(); + MakeMatrix(position, rotation, m); +} + + +#endif // #if dTRIMESH_ENABLED && dTRIMESH_GIMPACT + +#endif //_ODE_COLLISION_TRIMESH_GIMPACT_H_ diff --git a/libs/ode-0.16.1/ode/src/collision_trimesh_internal.cpp b/libs/ode-0.16.1/ode/src/collision_trimesh_internal.cpp new file mode 100644 index 0000000..b96e25f --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_trimesh_internal.cpp @@ -0,0 +1,804 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// TriMesh storage classes refactoring and face angle computation code by Oleh Derevenko (C) 2016-2019 + +#include <ode/collision.h> +#include <ode/rotation.h> +#include "config.h" +#include "matrix.h" +#include "odemath.h" + + +#if dTRIMESH_ENABLED + +#include "collision_trimesh_internal.h" +#include "odeou.h" + +#include <algorithm> + + + +////////////////////////////////////////////////////////////////////////// + +enum EdgeStorageSignInclusion +{ + SSI__MIN, + + SSI_SIGNED_STORED = SSI__MIN, + SSI_POSITIVE_STORED, + + SSI__MAX, +}; + +template<typename TStorageType, EdgeStorageSignInclusion t_SignInclusion> +class FaceAngleStorageCodec; + +template<typename TStorageType> +class FaceAngleStorageCodec<TStorageType, SSI_SIGNED_STORED> +{ +public: + typedef typename _make_signed<TStorageType>::type storage_type; + enum + { + STORAGE_TYPE_MAX = (typename _make_unsigned<TStorageType>::type)(~(typename _make_unsigned<TStorageType>::type)0) >> 1, + }; + + static bool areNegativeAnglesCoded() + { + return true; + } + + static storage_type encodeForStorage(dReal angleValue) + { + unsigned angleAsInt = (unsigned)dFloor(dFabs(angleValue) * (dReal)(STORAGE_TYPE_MAX / M_PI)); + unsigned limitedAngleAsInt = dMACRO_MIN(angleAsInt, STORAGE_TYPE_MAX); + storage_type result = angleValue < REAL(0.0) ? -(storage_type)limitedAngleAsInt : (storage_type)limitedAngleAsInt; + return result; + } + + static FaceAngleDomain classifyStorageValue(storage_type storedValue) + { + dSASSERT(EAD__MAX == 3); + + return storedValue < 0 ? FAD_CONCAVE : (storedValue == 0 ? FAD_FLAT : FAD_CONVEX); + } + + static bool isAngleDomainStored(FaceAngleDomain domainValue) + { + return !dTMPL_IN_RANGE(domainValue, FAD__SIGNSTORED_IMPLICITVALUE_MIN, FAD__SIGNSTORED_IMPLICITVALUE_MAX); + } + + static dReal decodeStorageValue(storage_type storedValue) + { + return storedValue * (dReal)(M_PI / STORAGE_TYPE_MAX); + } +}; + +template<typename TStorageType> +class FaceAngleStorageCodec<TStorageType, SSI_POSITIVE_STORED> +{ +public: + typedef typename _make_unsigned<TStorageType>::type storage_type; + enum + { + STORAGE_TYPE_MIN = 0, + STORAGE_TYPE_MAX = (storage_type)(~(storage_type)0), + }; + + static bool areNegativeAnglesCoded() + { + return false; + } + + static storage_type encodeForStorage(dReal angleValue) + { + storage_type result = STORAGE_TYPE_MIN; + + if (angleValue >= REAL(0.0)) + { + unsigned angleAsInt = (unsigned)dFloor(angleValue * (dReal)(((STORAGE_TYPE_MAX - STORAGE_TYPE_MIN - 1) / M_PI))); + result = (STORAGE_TYPE_MIN + 1) + dMACRO_MIN(angleAsInt, STORAGE_TYPE_MAX - STORAGE_TYPE_MIN - 1); + } + + return result; + } + + static FaceAngleDomain classifyStorageValue(storage_type storedValue) + { + dSASSERT(EAD__MAX == 3); + + return storedValue < STORAGE_TYPE_MIN + 1 ? FAD_CONCAVE : (storedValue == STORAGE_TYPE_MIN + 1 ? FAD_FLAT : FAD_CONVEX); + } + + static bool isAngleDomainStored(FaceAngleDomain domainValue) + { + return dTMPL_IN_RANGE(domainValue, FAD__BYTEPOS_STORED_MIN, FAD__BYTEPOS_STORED_MAX); + } + + static dReal decodeStorageValue(storage_type storedValue) + { + dIASSERT(storedValue >= (STORAGE_TYPE_MIN + 1)); + + return (storedValue - (STORAGE_TYPE_MIN + 1)) * (dReal)(M_PI / (STORAGE_TYPE_MAX - STORAGE_TYPE_MIN - 1)); + } +}; + +template<class TStorageCodec> +class FaceAnglesWrapper: + public IFaceAngleStorageControl, + public IFaceAngleStorageView +{ +protected: + FaceAnglesWrapper(unsigned triangleCount) { setAllocatedTriangleCount(triangleCount); } + +public: + virtual ~FaceAnglesWrapper(); + + static IFaceAngleStorageControl *allocateInstance(unsigned triangleCount, IFaceAngleStorageView *&out_storageView); + + static bool calculateInstanceSizeRequired(sizeint &out_sizeRequired, unsigned triangleCount); + +private: + void freeInstance(); + +private: + typedef typename TStorageCodec::storage_type storage_type; + typedef storage_type TriangleFaceAngles[dMTV__MAX]; + + struct StorageRecord + { + StorageRecord(): m_triangleCount(0) {} + + unsigned m_triangleCount; + TriangleFaceAngles m_triangleFaceAngles[1]; + }; + + static sizeint calculateStorageSizeForTriangleCount(unsigned triangleCount) + { + const unsigned baseIncludedTriangleCount = dSTATIC_ARRAY_SIZE(FaceAnglesWrapper<TStorageCodec>::StorageRecord, m_triangleFaceAngles); + const sizeint singleTriangleSize = membersize(FaceAnglesWrapper<TStorageCodec>::StorageRecord, m_triangleFaceAngles[0]); + return sizeof(FaceAnglesWrapper<TStorageCodec>) + (triangleCount > baseIncludedTriangleCount ? (triangleCount - baseIncludedTriangleCount) * singleTriangleSize : 0U); + } + + static sizeint calculateTriangleCountForStorageSize(sizeint storageSize) + { + dIASSERT(storageSize >= sizeof(FaceAnglesWrapper<TStorageCodec>)); + + const unsigned baseIncludedTriangleCount = dSTATIC_ARRAY_SIZE(FaceAnglesWrapper<TStorageCodec>::StorageRecord, m_triangleFaceAngles); + const sizeint singleTriangleSize = membersize(FaceAnglesWrapper<TStorageCodec>::StorageRecord, m_triangleFaceAngles[0]); + return (storageSize - sizeof(FaceAnglesWrapper<TStorageCodec>)) / singleTriangleSize + baseIncludedTriangleCount; + } + +private: // IFaceAngleStorageControl + virtual void disposeStorage(); + + virtual bool areNegativeAnglesStored() const; + + virtual void assignFacesAngleIntoStorage(unsigned triangleIndex, dMeshTriangleVertex vertexIndex, dReal dAngleValue); + +private: // IFaceAngleStorageView + virtual FaceAngleDomain retrieveFacesAngleFromStorage(dReal &out_angleValue, unsigned triangleIndex, dMeshTriangleVertex vertexIndex); + +public: + void setFaceAngle(unsigned triangleIndex, dMeshTriangleVertex vertexIndex, dReal dAngleValue) + { + dIASSERT(dTMPL_IN_RANGE(triangleIndex, 0, getAllocatedTriangleCount())); + dIASSERT(dTMPL_IN_RANGE(vertexIndex, dMTV__MIN, dMTV__MAX)); + + m_record.m_triangleFaceAngles[triangleIndex][vertexIndex] = TStorageCodec::encodeForStorage(dAngleValue); + } + + FaceAngleDomain getFaceAngle(dReal &out_angleValue, unsigned triangleIndex, dMeshTriangleVertex vertexIndex) const + { + dIASSERT(dTMPL_IN_RANGE(triangleIndex, 0, getAllocatedTriangleCount())); + dIASSERT(dTMPL_IN_RANGE(vertexIndex, dMTV__MIN, dMTV__MAX)); + + storage_type storedValue = m_record.m_triangleFaceAngles[triangleIndex][vertexIndex]; + FaceAngleDomain resultDomain = TStorageCodec::classifyStorageValue(storedValue); + + out_angleValue = TStorageCodec::isAngleDomainStored(resultDomain) ? TStorageCodec::decodeStorageValue(storedValue) : REAL(0.0); + return resultDomain; + } + +private: + unsigned getAllocatedTriangleCount() const { return m_record.m_triangleCount; } + void setAllocatedTriangleCount(unsigned triangleCount) { m_record.m_triangleCount = triangleCount; } + +private: + StorageRecord m_record; +}; + + +template<class TStorageCodec> +FaceAnglesWrapper<TStorageCodec>::~FaceAnglesWrapper() +{ +} + + +template<class TStorageCodec> +/*static */ +IFaceAngleStorageControl *FaceAnglesWrapper<TStorageCodec>::allocateInstance(unsigned triangleCount, IFaceAngleStorageView *&out_storageView) +{ + FaceAnglesWrapper<TStorageCodec> *result = NULL; + + do + { + sizeint sizeRequired; + if (!FaceAnglesWrapper<TStorageCodec>::calculateInstanceSizeRequired(sizeRequired, triangleCount)) + { + break; + } + + void *bufferPointer = dAlloc(sizeRequired); + if (bufferPointer == NULL) + { + break; + } + + result = (FaceAnglesWrapper<TStorageCodec> *)bufferPointer; + new(result) FaceAnglesWrapper<TStorageCodec>(triangleCount); + + out_storageView = result; + } + while (false); + + return result; +} + +template<class TStorageCodec> +/*static */ +bool FaceAnglesWrapper<TStorageCodec>::calculateInstanceSizeRequired(sizeint &out_sizeRequired, unsigned triangleCount) +{ + bool result = false; + + do + { + sizeint triangleMaximumCount = calculateTriangleCountForStorageSize(SIZE_MAX); + dIASSERT(triangleCount <= triangleMaximumCount); + + if (triangleCount > triangleMaximumCount) // Check for overflow + { + break; + } + + out_sizeRequired = calculateStorageSizeForTriangleCount(triangleCount); // Trailing alignment is going to be added by memory manager automatically + result = true; + } + while (false); + + return result; +} + +template<class TStorageCodec> +void FaceAnglesWrapper<TStorageCodec>::freeInstance() +{ + unsigned triangleCount = getAllocatedTriangleCount(); + + this->FaceAnglesWrapper<TStorageCodec>::~FaceAnglesWrapper(); + + sizeint memoryBlockSize = calculateStorageSizeForTriangleCount(triangleCount); + dFree(this, memoryBlockSize); +} + + +template<class TStorageCodec> +/*virtual */ +void FaceAnglesWrapper<TStorageCodec>::disposeStorage() +{ + freeInstance(); +} + +template<class TStorageCodec> +/*virtual */ +bool FaceAnglesWrapper<TStorageCodec>::areNegativeAnglesStored() const +{ + return TStorageCodec::areNegativeAnglesCoded(); +} + +template<class TStorageCodec> +/*virtual */ +void FaceAnglesWrapper<TStorageCodec>::assignFacesAngleIntoStorage(unsigned triangleIndex, dMeshTriangleVertex vertexIndex, dReal dAngleValue) +{ + setFaceAngle(triangleIndex, vertexIndex, dAngleValue); +} + +template<class TStorageCodec> +/*virtual */ +FaceAngleDomain FaceAnglesWrapper<TStorageCodec>::retrieveFacesAngleFromStorage(dReal &out_angleValue, unsigned triangleIndex, dMeshTriangleVertex vertexIndex) +{ + return getFaceAngle(out_angleValue, triangleIndex, vertexIndex); +} + + +typedef IFaceAngleStorageControl *(FAngleStorageAllocProc)(unsigned triangleCount, IFaceAngleStorageView *&out_storageView); + +BEGIN_NAMESPACE_OU(); +template<> +FAngleStorageAllocProc *const CEnumUnsortedElementArray<FaceAngleStorageMethod, ASM__MAX, FAngleStorageAllocProc *, 0x161211AD>::m_aetElementArray[] = +{ + &FaceAnglesWrapper<FaceAngleStorageCodec<uint8, SSI_SIGNED_STORED> >::allocateInstance, // ASM_BYTE_SIGNED, + &FaceAnglesWrapper<FaceAngleStorageCodec<uint8, SSI_POSITIVE_STORED> >::allocateInstance, // ASM_BYTE_POSITIVE, + &FaceAnglesWrapper<FaceAngleStorageCodec<uint16, SSI_SIGNED_STORED> >::allocateInstance, // ASM_WORD_SIGNED, +}; +END_NAMESPACE_OU(); +static const CEnumUnsortedElementArray<FaceAngleStorageMethod, ASM__MAX, FAngleStorageAllocProc *, 0x161211AD> g_AngleStorageAllocProcs; + + +////////////////////////////////////////////////////////////////////////// + +dxTriDataBase::~dxTriDataBase() +{ + freeFaceAngles(); +} + + +void dxTriDataBase::buildData(const void *vertices, int vertexStride, unsigned vertexCount, + const void *indices, unsigned indexCount, int triStride, + const void *normals, + bool single) +{ + dIASSERT(vertices); + dIASSERT(indices); + dIASSERT(vertexStride); + dIASSERT(triStride); + dIASSERT(indexCount); + dIASSERT(indexCount % dMTV__MAX == 0); + + m_vertices = vertices; + m_vertexStride = vertexStride; + m_vertexCount = vertexCount; + m_indices = indices; + m_triangleCount = indexCount / dMTV__MAX; + m_triStride = triStride; + m_single = single; + + m_normals = normals; +} + + +bool dxTriDataBase::allocateFaceAngles(FaceAngleStorageMethod storageMethod) +{ + bool result = false; + + dIASSERT(m_faceAngles == NULL); + + IFaceAngleStorageView *storageView; + + unsigned triangleCount = m_triangleCount; + + FAngleStorageAllocProc *allocProc = g_AngleStorageAllocProcs.Encode(storageMethod); + IFaceAngleStorageControl *storageInstance = allocProc(triangleCount, storageView); + + if (storageInstance != NULL) + { + m_faceAngles = storageInstance; + m_faceAngleView = storageView; + result = true; + } + + return result; +} + +void dxTriDataBase::freeFaceAngles() +{ + if (m_faceAngles != NULL) + { + m_faceAngles->disposeStorage(); + m_faceAngles = NULL; + m_faceAngleView = NULL; + } +} + + +void dxTriDataBase::EdgeRecord::setupEdge(dMeshTriangleVertex edgeIdx, int triIdx, const unsigned vertexIndices[dMTV__MAX]) +{ + if (edgeIdx < dMTV_SECOND) + { + dIASSERT(edgeIdx == dMTV_FIRST); + + m_edgeFlags = dxTriMeshData::CUF_USE_FIRST_EDGE; + m_vert1Flags = dxTriMeshData::CUF_USE_FIRST_VERTEX; + m_vert2Flags = dxTriMeshData::CUF_USE_SECOND_VERTEX; + m_vertIdx1 = vertexIndices[dMTV_FIRST]; + m_vertIdx2 = vertexIndices[dMTV_SECOND]; + } + else if (edgeIdx == dMTV_SECOND) + { + m_edgeFlags = dxTriMeshData::CUF_USE_SECOND_EDGE; + m_vert1Flags = dxTriMeshData::CUF_USE_SECOND_VERTEX; + m_vert2Flags = dxTriMeshData::CUF_USE_THIRD_VERTEX; + m_vertIdx1 = vertexIndices[dMTV_SECOND]; + m_vertIdx2 = vertexIndices[dMTV_THIRD]; + } + else + { + dIASSERT(edgeIdx == dMTV_THIRD); + + m_edgeFlags = dxTriMeshData::CUF_USE_THIRD_EDGE; + m_vert1Flags = dxTriMeshData::CUF_USE_THIRD_VERTEX; + m_vert2Flags = dxTriMeshData::CUF_USE_FIRST_VERTEX; + m_vertIdx1 = vertexIndices[dMTV_THIRD]; + m_vertIdx2 = vertexIndices[dMTV_FIRST]; + } + + // Make sure vertex index 1 is less than index 2 (for easier sorting) + if (m_vertIdx1 > m_vertIdx2) + { + dxSwap(m_vertIdx1, m_vertIdx2); + dxSwap(m_vert1Flags, m_vert2Flags); + } + + m_triIdx = triIdx; + m_absVertexFlags = 0; +} + + +BEGIN_NAMESPACE_OU(); +template<> +const dMeshTriangleVertex CEnumUnsortedElementArray<unsigned, dxTriDataBase::CUF__USE_VERTICES_LAST / dxTriDataBase::CUF__USE_VERTICES_MIN, dMeshTriangleVertex, 0x161116DC>::m_aetElementArray[] = +{ + dMTV_FIRST, // kVert0 / kVert_Base + dMTV_SECOND, // kVert1 / kVert_Base + dMTV__MAX, + dMTV_THIRD, // kVert2 / kVert_Base +}; +END_NAMESPACE_OU(); +/*extern */const CEnumUnsortedElementArray<unsigned, dxTriDataBase::CUF__USE_VERTICES_LAST / dxTriDataBase::CUF__USE_VERTICES_MIN, dMeshTriangleVertex, 0x161116DC> g_VertFlagOppositeIndices; + +BEGIN_NAMESPACE_OU(); +template<> +const dMeshTriangleVertex CEnumUnsortedElementArray<unsigned, dxTriDataBase::CUF__USE_VERTICES_LAST / dxTriDataBase::CUF__USE_VERTICES_MIN, dMeshTriangleVertex, 0x161225E9>::m_aetElementArray[] = +{ + dMTV_SECOND, // kVert0 / kVert_Base + dMTV_THIRD, // kVert1 / kVert_Base + dMTV__MAX, + dMTV_FIRST, // kVert2 / kVert_Base +}; +END_NAMESPACE_OU(); +/*extern */const CEnumUnsortedElementArray<unsigned, dxTriDataBase::CUF__USE_VERTICES_LAST / dxTriDataBase::CUF__USE_VERTICES_MIN, dMeshTriangleVertex, 0x161225E9> g_VertFlagEdgeStartIndices; + + +////////////////////////////////////////////////////////////////////////// + +/*extern ODE_API */ +void dGeomTriMeshDataBuildSimple1(dTriMeshDataID g, + const dReal* Vertices, int VertexCount, + const dTriIndex* Indices, int IndexCount, + const int *Normals) +{ +#ifdef dSINGLE + dGeomTriMeshDataBuildSingle1(g, + Vertices, 4 * sizeof(dReal), VertexCount, + Indices, IndexCount, 3 * sizeof(dTriIndex), + Normals); +#else + dGeomTriMeshDataBuildDouble1(g, Vertices, 4 * sizeof(dReal), VertexCount, + Indices, IndexCount, 3 * sizeof(dTriIndex), + Normals); +#endif +} + + +/*extern ODE_API */ +void dGeomTriMeshDataBuildSingle(dTriMeshDataID g, + const void* Vertices, int VertexStride, int VertexCount, + const void* Indices, int IndexCount, int TriStride) +{ + dGeomTriMeshDataBuildSingle1(g, Vertices, VertexStride, VertexCount, + Indices, IndexCount, TriStride, (const void *)NULL); +} + +/*extern ODE_API */ +void dGeomTriMeshDataBuildDouble(dTriMeshDataID g, + const void* Vertices, int VertexStride, int VertexCount, + const void* Indices, int IndexCount, int TriStride) +{ + dGeomTriMeshDataBuildDouble1(g, Vertices, VertexStride, VertexCount, + Indices, IndexCount, TriStride, NULL); +} + +/*extern ODE_API */ +void dGeomTriMeshDataBuildSimple(dTriMeshDataID g, + const dReal* Vertices, int VertexCount, + const dTriIndex* Indices, int IndexCount) +{ + dGeomTriMeshDataBuildSimple1(g, + Vertices, VertexCount, Indices, IndexCount, + (int *)NULL); +} + + +/*extern ODE_API */ +int dGeomTriMeshDataPreprocess(dTriMeshDataID g) +{ + unsigned buildRequestFlags = (1U << dTRIDATAPREPROCESS_BUILD_CONCAVE_EDGES); + return dGeomTriMeshDataPreprocess2(g, buildRequestFlags, NULL); +} + + +BEGIN_NAMESPACE_OU(); +template<> +const FaceAngleStorageMethod CEnumUnsortedElementArray<unsigned, dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA__MAX, FaceAngleStorageMethod, 0x17010902>::m_aetElementArray[] = +{ + ASM_BYTE_POSITIVE, // dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA_BYTE_POSITIVE, + ASM_BYTE_SIGNED, // dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA_BYTE_ALL, + ASM_WORD_SIGNED, // dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA_WORD_ALL, +}; +END_NAMESPACE_OU(); +static const CEnumUnsortedElementArray<unsigned, dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA__MAX, FaceAngleStorageMethod, 0x17010902> g_TriMeshDataPreprocess_FaceAndlesExtraDataAngleStorageMethods; + +/*extern ODE_API */ +int dGeomTriMeshDataPreprocess2(dTriMeshDataID g, unsigned int buildRequestFlags, const intptr *requestExtraData/*=NULL | const intptr (*)[dTRIDATAPREPROCESS_BUILD__MAX]*/) +{ + dUASSERT(g, "The argument is not a trimesh data"); + dAASSERT((buildRequestFlags & (1U << dTRIDATAPREPROCESS_BUILD_FACE_ANGLES)) == 0 || requestExtraData == NULL || dIN_RANGE(requestExtraData[dTRIDATAPREPROCESS_BUILD_FACE_ANGLES], dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA__MIN, dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA__MAX)); + + dxTriMeshData *data = g; + + bool buildUseFlags = (buildRequestFlags & (1U << dTRIDATAPREPROCESS_BUILD_CONCAVE_EDGES)) != 0; + FaceAngleStorageMethod faceAnglesRequirement = (buildRequestFlags & (1U << dTRIDATAPREPROCESS_BUILD_FACE_ANGLES)) != 0 + ? g_TriMeshDataPreprocess_FaceAndlesExtraDataAngleStorageMethods.Encode(requestExtraData != NULL && dIN_RANGE(requestExtraData[dTRIDATAPREPROCESS_BUILD_FACE_ANGLES], dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA__MIN, dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA__MAX) ? (unsigned)requestExtraData[dTRIDATAPREPROCESS_BUILD_FACE_ANGLES] : dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA__DEFAULT) + : ASM__INVALID; + return data->preprocessData(buildUseFlags, faceAnglesRequirement); +} + +/*extern ODE_API */ +void dGeomTriMeshDataUpdate(dTriMeshDataID g) +{ + dUASSERT(g, "The argument is not a trimesh data"); + + dxTriMeshData *data = g; + data->updateData(); +} + + +////////////////////////////////////////////////////////////////////////// + +/*extern ODE_API */ +void dGeomTriMeshSetCallback(dGeomID g, dTriCallback* Callback) +{ + dUASSERT(g && g->type == dTriMeshClass, "The argument is not a trimesh"); + + dxTriMesh *mesh = static_cast<dxTriMesh *>(g); + mesh->assignCallback(Callback); +} + +/*extern ODE_API */ +dTriCallback* dGeomTriMeshGetCallback(dGeomID g) +{ + dUASSERT(g && g->type == dTriMeshClass, "The argument is not a trimesh"); + + const dxTriMesh *mesh = static_cast<dxTriMesh *>(g); + return mesh->retrieveCallback(); +} + +/*extern ODE_API */ +void dGeomTriMeshSetArrayCallback(dGeomID g, dTriArrayCallback* ArrayCallback) +{ + dUASSERT(g && g->type == dTriMeshClass, "The argument is not a trimesh"); + + dxTriMesh *mesh = static_cast<dxTriMesh *>(g); + mesh->assignArrayCallback(ArrayCallback); +} + +/*extern ODE_API */ +dTriArrayCallback *dGeomTriMeshGetArrayCallback(dGeomID g) +{ + dUASSERT(g && g->type == dTriMeshClass, "The argument is not a trimesh"); + + const dxTriMesh *mesh = static_cast<dxTriMesh *>(g); + return mesh->retrieveArrayCallback(); +} + +/*extern ODE_API */ +void dGeomTriMeshSetRayCallback(dGeomID g, dTriRayCallback* Callback) +{ + dUASSERT(g && g->type == dTriMeshClass, "The argument is not a trimesh"); + + dxTriMesh *mesh = static_cast<dxTriMesh *>(g); + mesh->assignRayCallback(Callback); +} + +/*extern ODE_API */ +dTriRayCallback* dGeomTriMeshGetRayCallback(dGeomID g) +{ + dUASSERT(g && g->type == dTriMeshClass, "The argument is not a trimesh"); + + const dxTriMesh *mesh = static_cast<dxTriMesh *>(g); + return mesh->retrieveRayCallback(); +} + +/*extern ODE_API */ +void dGeomTriMeshSetTriMergeCallback(dGeomID g, dTriTriMergeCallback* Callback) +{ + dUASSERT(g && g->type == dTriMeshClass, "The argument is not a trimesh"); + + dxTriMesh *mesh = static_cast<dxTriMesh *>(g); + mesh->assignTriMergeCallback(Callback); +} + +/*extern ODE_API */ +dTriTriMergeCallback *dGeomTriMeshGetTriMergeCallback(dGeomID g) +{ + dUASSERT(g && g->type == dTriMeshClass, "The argument is not a trimesh"); + + const dxTriMesh *mesh = static_cast<dxTriMesh *>(g); + return mesh->retrieveTriMergeCallback(); +} + +/*extern ODE_API */ +void dGeomTriMeshSetData(dGeomID g, dTriMeshDataID Data) +{ + dUASSERT(g && g->type == dTriMeshClass, "The argument is not a trimesh"); + + dxTriMesh *mesh = static_cast<dxTriMesh *>(g); + mesh->assignMeshData(Data); +} + +/*extern ODE_API */ +dTriMeshDataID dGeomTriMeshGetData(dGeomID g) +{ + dUASSERT(g && g->type == dTriMeshClass, "The argument is not a trimesh"); + + const dxTriMesh *mesh = static_cast<dxTriMesh *>(g); + return mesh->retrieveMeshData(); +} + + +BEGIN_NAMESPACE_OU(); +template<> +const int CEnumSortedElementArray<dxTriMesh::TRIMESHTC, dxTriMesh::TTC__MAX, int, 0x161003D5>::m_aetElementArray[] = +{ + dSphereClass, // TTC_SPHERE, + dBoxClass, // TTC_BOX, + dCapsuleClass, // TTC_CAPSULE, +}; +END_NAMESPACE_OU(); +static const CEnumSortedElementArray<dxTriMesh::TRIMESHTC, dxTriMesh::TTC__MAX, int, 0x161003D5> g_asiMeshTCGeomClasses; + +/*extern ODE_API */ +void dGeomTriMeshEnableTC(dGeomID g, int geomClass, int enable) +{ + dUASSERT(g && g->type == dTriMeshClass, "The argument is not a trimesh"); + + dxTriMesh *mesh = static_cast<dxTriMesh *>(g); + + dxTriMesh::TRIMESHTC tc = g_asiMeshTCGeomClasses.Decode(geomClass); + + if (g_asiMeshTCGeomClasses.IsValidDecode(tc)) + { + mesh->assignDoTC(tc, enable != 0); + } +} + +/*extern ODE_API */ +int dGeomTriMeshIsTCEnabled(dGeomID g, int geomClass) +{ + dUASSERT(g && g->type == dTriMeshClass, "The argument is not a trimesh"); + + const dxTriMesh *mesh = static_cast<dxTriMesh *>(g); + + dxTriMesh::TRIMESHTC tc = g_asiMeshTCGeomClasses.Decode(geomClass); + + bool result = g_asiMeshTCGeomClasses.IsValidDecode(tc) + && mesh->retrieveDoTC(tc); + return result; +} + + +/*extern ODE_API */ +dTriMeshDataID dGeomTriMeshGetTriMeshDataID(dGeomID g) +{ + dUASSERT(g && g->type == dTriMeshClass, "The argument is not a trimesh"); + + const dxTriMesh *mesh = static_cast<dxTriMesh *>(g); + return mesh->retrieveMeshData(); +} + + +/*extern ODE_API */ +void dGeomTriMeshClearTCCache(dGeomID g) +{ + dUASSERT(g && g->type == dTriMeshClass, "The argument is not a trimesh"); + + dxTriMesh *mesh = static_cast<dxTriMesh *>(g); + mesh->clearTCCache(); +} + + +/*extern ODE_API */ +int dGeomTriMeshGetTriangleCount(dGeomID g) +{ + dUASSERT(g && g->type == dTriMeshClass, "The argument is not a trimesh"); + + const dxTriMesh *mesh = static_cast<dxTriMesh *>(g); + unsigned result = mesh->getMeshTriangleCount(); + return result; +} + + +/*extern ODE_API */ +void dGeomTriMeshGetTriangle(dGeomID g, int index, dVector3 *v0/*=NULL*/, dVector3 *v1/*=NULL*/, dVector3 *v2/*=NULL*/) +{ + dUASSERT(g && g->type == dTriMeshClass, "The argument is not a trimesh"); + dUASSERT(v0 != NULL || v1 != NULL || v2 != NULL, "A meaningless call"); + + dxTriMesh *mesh = static_cast<dxTriMesh *>(g); + + dVector3 *pv[3] = { v0, v1, v2 }; + mesh->fetchMeshTransformedTriangle(pv, index); +} + +/*extern ODE_API */ +void dGeomTriMeshGetPoint(dGeomID g, int index, dReal u, dReal v, dVector3 Out) +{ + dUASSERT(g && g->type == dTriMeshClass, "The argument is not a trimesh"); + + dxTriMesh *mesh = static_cast<dxTriMesh *>(g); + + dVector3 dv[3]; + mesh->fetchMeshTransformedTriangle(dv, index); + + GetPointFromBarycentric(dv, u, v, Out); +} + + +/*extern */ +IFaceAngleStorageView *dxGeomTriMeshGetFaceAngleView(dxGeom *triMeshGeom) +{ + dUASSERT(triMeshGeom && triMeshGeom->type == dTriMeshClass, "The argument is not a trimesh"); + + dxTriMesh *mesh = static_cast<dxTriMesh *>(triMeshGeom); + return mesh->retrieveFaceAngleView(); +} + + +#endif // #if dTRIMESH_ENABLED + + +////////////////////////////////////////////////////////////////////////// +// Deprecated functions + +/*extern */ +void dGeomTriMeshDataGetBuffer(dTriMeshDataID g, unsigned char **buf, int *bufLen) +{ + sizeint dataSizeStorage; + void *dataPointer = dGeomTriMeshDataGet2(g, dTRIMESHDATA_USE_FLAGS, (bufLen != NULL ? &dataSizeStorage : NULL)); + + if (bufLen != NULL) + { + *bufLen = (int)dataSizeStorage; + } + + if (buf != NULL) + { + *buf = (unsigned char *)dataPointer; + } +} + +/*extern */ +void dGeomTriMeshDataSetBuffer(dTriMeshDataID g, unsigned char* buf) +{ + dGeomTriMeshDataSet(g, dTRIMESHDATA_USE_FLAGS, (void *)buf); +} + diff --git a/libs/ode-0.16.1/ode/src/collision_trimesh_internal.h b/libs/ode-0.16.1/ode/src/collision_trimesh_internal.h new file mode 100644 index 0000000..477b770 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_trimesh_internal.h @@ -0,0 +1,399 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// TriMesh code by Erwin de Vries. +// Modified for FreeSOLID Compatibility by Rodrigo Hernandez +// TriMesh caches separation by Oleh Derevenko +// TriMesh storage classes refactoring and face angle computation code by Oleh Derevenko (C) 2016-2019 + + +#ifndef _ODE_COLLISION_TRIMESH_INTERNAL_H_ +#define _ODE_COLLISION_TRIMESH_INTERNAL_H_ + + +//**************************************************************************** +// dxTriMesh class + + +#include "collision_kernel.h" +#include "collision_trimesh_colliders.h" +#include "collision_util.h" +#include <ode/collision_trimesh.h> + +#if dTLS_ENABLED +#include "odetls.h" +#endif + + +struct TrimeshCollidersCache; +struct dxTriMeshData; + + +static inline +TrimeshCollidersCache *GetTrimeshCollidersCache(unsigned uiTLSKind) +{ +#if dTLS_ENABLED + EODETLSKIND tkTLSKind = (EODETLSKIND)uiTLSKind; + return COdeTls::GetTrimeshCollidersCache(tkTLSKind); +#else // dTLS_ENABLED + (void)uiTLSKind; // unused + extern TrimeshCollidersCache g_ccTrimeshCollidersCache; + return &g_ccTrimeshCollidersCache; +#endif // dTLS_ENABLED +} + + +enum FaceAngleStorageMethod +{ + ASM__MIN, + + ASM_BYTE_SIGNED = ASM__MIN, + ASM_BYTE_POSITIVE, + ASM_WORD_SIGNED, + + ASM__MAX, + + ASM__INVALID = ASM__MAX, +}; + +enum FaceAngleDomain +{ + FAD__MIN, + + FAD_CONCAVE = FAD__MIN, + + FAD__SIGNSTORED_IMPLICITVALUE_MIN, + + FAD_FLAT = FAD__SIGNSTORED_IMPLICITVALUE_MIN, + + FAD__SIGNSTORED_IMPLICITVALUE_MAX, + + FAD__BYTEPOS_STORED_MIN = FAD__SIGNSTORED_IMPLICITVALUE_MAX, + + FAD_CONVEX = FAD__BYTEPOS_STORED_MIN, + + FAD__BYTEPOS_STORED_MAX, + + EAD__MAX = FAD__BYTEPOS_STORED_MAX, +}; + +class IFaceAngleStorageControl +{ +public: + virtual void disposeStorage() = 0; + + virtual bool areNegativeAnglesStored() const = 0; + + // This is to store angles between neighbor triangle normals as positive value for convex and negative for concave edges + virtual void assignFacesAngleIntoStorage(unsigned triangleIndex, dMeshTriangleVertex vertexIndex, dReal dAngleValue) = 0; +}; + +class IFaceAngleStorageView +{ +public: + virtual FaceAngleDomain retrieveFacesAngleFromStorage(dReal &out_AngleValue, unsigned triangleIndex, dMeshTriangleVertex vertexIndex) = 0; +}; + + +typedef dBase dxTriDataBase_Parent; +struct dxTriDataBase: + public dxTriDataBase_Parent +{ +public: + dxTriDataBase(): + dxTriDataBase_Parent(), + m_vertices(NULL), + m_vertexStride(0), + m_vertexCount(0), + m_indices(NULL), + m_triangleCount(0), + m_triStride(0), + m_single(false), + m_normals(NULL), + m_faceAngles(NULL), + m_faceAngleView(NULL) + { +#if !dTRIMESH_ENABLED + dUASSERT(false, "dTRIMESH_ENABLED is not defined. Trimesh geoms will not work"); +#endif + } + + ~dxTriDataBase(); + + void buildData(const void *Vertices, int VertexStide, unsigned VertexCount, + const void *Indices, unsigned IndexCount, int TriStride, + const void *Normals, + bool Single); + + +public: + unsigned retrieveVertexCount() const { return m_vertexCount; } + int retrieveVertexStride() const { return m_vertexStride; } + + unsigned retrieveTriangleCount() const { return m_triangleCount; } + int retrieveTriangleStride() const { return m_triStride; } + +protected: + const void *retrieveVertexInstances() const { return m_vertices; } + const void *retrieveTriangleVertexIndices() const { return m_indices; } + bool isSingle() const { return m_single; } + +public: + template<typename tcoordfloat, typename tindexint> + static void retrieveTriangleVertexPoints(dVector3 out_Points[dMTV__MAX], unsigned triangleIndex, + const tcoordfloat *vertexInstances, int vertexStride, const tindexint *triangleVertexIndices, int triangleStride); + +public: + void assignNormals(const void *normals) { m_normals = normals; } + const void *retrieveNormals() const { return m_normals; } + + IFaceAngleStorageControl *retrieveFaceAngles() const { return m_faceAngles; } + IFaceAngleStorageView *retrieveFaceAngleView() const { return m_faceAngleView; } + +protected: + bool allocateFaceAngles(FaceAngleStorageMethod storageMethod); + void freeFaceAngles(); + + bool haveFaceAnglesBeenBuilt() const { return m_faceAngles != NULL; } + +public: + enum MeshComponentUseFlags + { + CUF__USE_EDGES_MIN = 0x01, + CUF_USE_FIRST_EDGE = CUF__USE_EDGES_MIN << dMTV_FIRST, + CUF_USE_SECOND_EDGE = CUF__USE_EDGES_MIN << dMTV_SECOND, + CUF_USE_THIRD_EDGE = CUF__USE_EDGES_MIN << dMTV_THIRD, + CUF__USE_EDGES_MAX = CUF__USE_EDGES_MIN << dMTV__MAX, + CUF__USE_ALL_EDGES = CUF_USE_FIRST_EDGE | CUF_USE_SECOND_EDGE | CUF_USE_THIRD_EDGE, + + CUF__USE_VERTICES_MIN = CUF__USE_EDGES_MAX, + CUF_USE_FIRST_VERTEX = CUF__USE_VERTICES_MIN << dMTV_FIRST, + CUF_USE_SECOND_VERTEX = CUF__USE_VERTICES_MIN << dMTV_SECOND, + CUF_USE_THIRD_VERTEX = CUF__USE_VERTICES_MIN << dMTV_THIRD, + CUF__USE_VERTICES_LAST = CUF__USE_VERTICES_MIN << (dMTV__MAX - 1), + CUF__USE_VERTICES_MAX = CUF__USE_VERTICES_MIN << dMTV__MAX, + CUF__USE_ALL_VERTICES = CUF_USE_FIRST_VERTEX | CUF_USE_SECOND_VERTEX | CUF_USE_THIRD_VERTEX, + + CUF__USE_ALL_COMPONENTS = CUF__USE_ALL_VERTICES | CUF__USE_ALL_EDGES, + }; + + // Make sure that the flags match the values declared in public interface + dSASSERT((unsigned)CUF_USE_FIRST_EDGE == dMESHDATAUSE_EDGE1); + dSASSERT((unsigned)CUF_USE_SECOND_EDGE == dMESHDATAUSE_EDGE2); + dSASSERT((unsigned)CUF_USE_THIRD_EDGE == dMESHDATAUSE_EDGE3); + dSASSERT((unsigned)CUF_USE_FIRST_VERTEX == dMESHDATAUSE_VERTEX1); + dSASSERT((unsigned)CUF_USE_SECOND_VERTEX == dMESHDATAUSE_VERTEX2); + dSASSERT((unsigned)CUF_USE_THIRD_VERTEX == dMESHDATAUSE_VERTEX3); + +protected: + struct EdgeRecord + { + public: + void setupEdge(dMeshTriangleVertex edgeIdx, int triIdx, const unsigned vertexIndices[dMTV__MAX]); + + // Get the vertex opposite this edge in the triangle + dMeshTriangleVertex getOppositeVertexIndex() const + { + extern const CEnumUnsortedElementArray<unsigned, dxTriDataBase::CUF__USE_VERTICES_LAST / dxTriDataBase::CUF__USE_VERTICES_MIN, dMeshTriangleVertex, 0x161116DC> g_VertFlagOppositeIndices; + + dMeshTriangleVertex oppositeIndex = g_VertFlagOppositeIndices.Encode(((m_vert1Flags | m_vert2Flags) ^ CUF__USE_ALL_VERTICES) / CUF__USE_VERTICES_MIN - 1); + dIASSERT(dIN_RANGE(oppositeIndex, dMTV__MIN, dMTV__MAX)); + + return oppositeIndex; + } + + dMeshTriangleVertex getEdgeStartVertexIndex() const + { + extern const CEnumUnsortedElementArray<unsigned, dxTriDataBase::CUF__USE_VERTICES_LAST / dxTriDataBase::CUF__USE_VERTICES_MIN, dMeshTriangleVertex, 0x161225E9> g_VertFlagEdgeStartIndices; + + dMeshTriangleVertex startIndex = g_VertFlagEdgeStartIndices.Encode(((m_vert1Flags | m_vert2Flags) ^ CUF__USE_ALL_VERTICES) / CUF__USE_VERTICES_MIN - 1); + dIASSERT(dIN_RANGE(startIndex, dMTV__MIN, dMTV__MAX)); + + return startIndex; + } + + public: + bool operator <(const EdgeRecord &anotherEdge) const { return m_vertIdx1 < anotherEdge.m_vertIdx1 || (m_vertIdx1 == anotherEdge.m_vertIdx1 && m_vertIdx2 < anotherEdge.m_vertIdx2); } + + public: + enum + { + AVF_VERTEX_USED = 0x01, + AVF_VERTEX_HAS_CONCAVE_EDGE = 0x02, + }; + + public: + unsigned m_vertIdx1; // Index into vertex array for this edges vertices + unsigned m_vertIdx2; + unsigned m_triIdx; // Index into triangle array for triangle this edge belongs to + + uint8 m_edgeFlags; + uint8 m_vert1Flags; + uint8 m_vert2Flags; + uint8 m_absVertexFlags; + }; + + struct VertexRecord + { + unsigned m_UsedFromEdgeIndex; + }; + + template<class TMeshDataAccessor> + static void meaningfulPreprocess_SetupEdgeRecords(EdgeRecord *edges, sizeint numEdges, const TMeshDataAccessor &dataAccessor); + template<class TMeshDataAccessor> + static void meaningfulPreprocess_buildEdgeFlags(uint8 *useFlags/*=NULL*/, IFaceAngleStorageControl *faceAngles/*=NULL*/, + EdgeRecord *edges, sizeint numEdges, VertexRecord *vertices, + const dReal *externalNormals, const TMeshDataAccessor &dataAccessor); + static void buildBoundaryEdgeAngle(IFaceAngleStorageControl *faceAngles, EdgeRecord *currEdge); + template<class TMeshDataAccessor> + static void buildConcaveEdgeAngle(IFaceAngleStorageControl *faceAngles, bool negativeAnglesStored, + EdgeRecord *currEdge, const dReal &normalSegmentDot, const dReal &lengthSquareProduct, + const dVector3 &triangleNormal, const dVector3 &secondOppositeVertexSegment, + const dVector3 *pSecondTriangleMatchingEdge/*=NULL*/, const dVector3 *pFirstTriangle/*=NULL*/, + const TMeshDataAccessor &dataAccessor); + template<class TMeshDataAccessor> + static + void buildConvexEdgeAngle(IFaceAngleStorageControl *faceAngles, + EdgeRecord *currEdge, const dReal &normalSegmentDot, const dReal &lengthSquareProduct, + const dVector3 &triangleNormal, const dVector3 &secondOppositeVertexSegment, + const dVector3 *pSecondTriangleMatchingEdge/*=NULL*/, const dVector3 *pFirstTriangle/*=NULL*/, + const TMeshDataAccessor &dataAccessor); + template<class TMeshDataAccessor> + static dReal calculateEdgeAngleValidated(unsigned firstVertexStartIndex, + EdgeRecord *currEdge, const dReal &normalSegmentDot, const dReal &lengthSquareProduct, + const dVector3 &triangleNormal, const dVector3 &secondOppositeVertexSegment, + const dVector3 *pSecondTriangleMatchingEdge/*=NULL*/, const dVector3 *pFirstTriangle/*=NULL*/, + const TMeshDataAccessor &dataAccessor); + +private: + const void *m_vertices; + int m_vertexStride; + unsigned m_vertexCount; + const void *m_indices; + unsigned m_triangleCount; + int m_triStride; + bool m_single; + +private: + const void *m_normals; + IFaceAngleStorageControl *m_faceAngles; + IFaceAngleStorageView *m_faceAngleView; +}; + + +typedef dxGeom dxMeshBase_Parent; +struct dxMeshBase: + public dxMeshBase_Parent +{ +public: + dxMeshBase(dxSpace *Space, dxTriDataBase *Data, + dTriCallback *Callback, dTriArrayCallback *ArrayCallback, dTriRayCallback *RayCallback, + bool doTCs=false): + dxMeshBase_Parent(Space, 1), + m_Callback(Callback), + m_ArrayCallback(ArrayCallback), + m_RayCallback(RayCallback), + m_TriMergeCallback(NULL), + m_Data(Data) + { + std::fill(m_DoTCs, m_DoTCs + dARRAY_SIZE(m_DoTCs), doTCs); + type = dTriMeshClass; + } + + bool invokeCallback(dxGeom *Object, int TriIndex) + { + return m_Callback == NULL || m_Callback(this, Object, TriIndex) != 0; + } + +public: + enum TRIMESHTC + { + TTC__MIN, + + TTC_SPHERE = TTC__MIN, + TTC_BOX, + TTC_CAPSULE, + + TTC__MAX, + }; + +public: + void assignCallback(dTriCallback *value) { m_Callback = value; } + dTriCallback *retrieveCallback() const { return m_Callback; } + + void assignArrayCallback(dTriArrayCallback *value) { m_ArrayCallback = value; } + dTriArrayCallback *retrieveArrayCallback() const { return m_ArrayCallback; } + + void assignRayCallback(dTriRayCallback *value) { m_RayCallback = value; } + dTriRayCallback *retrieveRayCallback() const { return m_RayCallback; } + + void assignTriMergeCallback(dTriTriMergeCallback *value) { m_TriMergeCallback = value; } + dTriTriMergeCallback *retrieveTriMergeCallback() const { return m_TriMergeCallback; } + + void assignMeshData(dxTriDataBase *instance) + { + setMeshData(instance); + // I changed my data -- I know nothing about my own AABB anymore. + markAABBBad(); + } + dxTriDataBase *retrieveMeshData() const { return getMeshData(); } + + IFaceAngleStorageControl *retrieveFaceAngleStorage() const { return m_Data->retrieveFaceAngles(); } + IFaceAngleStorageView *retrieveFaceAngleView() const { return m_Data->retrieveFaceAngleView(); } + + void assignDoTC(TRIMESHTC tc, bool value) { setDoTC(tc, value); } + bool retrieveDoTC(TRIMESHTC tc) const { return getDoTC(tc); } + +public: + void setDoTC(TRIMESHTC tc, bool value) { dIASSERT(dIN_RANGE(tc, TTC__MIN, TTC__MAX)); m_DoTCs[tc] = value; } + bool getDoTC(TRIMESHTC tc) const { dIASSERT(dIN_RANGE(tc, TTC__MIN, TTC__MAX)); return m_DoTCs[tc]; } + +private: + void setMeshData(dxTriDataBase *Data) { m_Data = Data; } + +protected: + dxTriDataBase *getMeshData() const { return m_Data; } + +public: + // Callbacks + dTriCallback *m_Callback; + dTriArrayCallback *m_ArrayCallback; + dTriRayCallback *m_RayCallback; + dTriTriMergeCallback *m_TriMergeCallback; + +private: + // Data types + dxTriDataBase *m_Data; + +public: + bool m_DoTCs[TTC__MAX]; +}; + + +IFaceAngleStorageView *dxGeomTriMeshGetFaceAngleView(dxGeom *triMeshGeom); + + +#include "collision_trimesh_gimpact.h" +#include "collision_trimesh_opcode.h" + + +#endif //_ODE_COLLISION_TRIMESH_INTERNAL_H_ diff --git a/libs/ode-0.16.1/ode/src/collision_trimesh_internal_impl.h b/libs/ode-0.16.1/ode/src/collision_trimesh_internal_impl.h new file mode 100644 index 0000000..be41ff5 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_trimesh_internal_impl.h @@ -0,0 +1,463 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// TriMesh base template method implementations by Oleh Derevenko (C) 2016-2019 + + +#ifndef _ODE_COLLISION_TRIMESH_INTERNAL_IMPL_H_ +#define _ODE_COLLISION_TRIMESH_INTERNAL_IMPL_H_ + + +#include "collision_trimesh_internal.h" + + +#if dTRIMESH_ENABLED + + +template<typename tcoordfloat, typename tindexint> +/*static */ +void dxTriDataBase::retrieveTriangleVertexPoints(dVector3 out_Points[dMTV__MAX], unsigned triangleIndex, + const tcoordfloat *vertexInstances, int vertexStride, const tindexint *triangleVertexIndices, int triangleStride) +{ + const tindexint *triangleIndicesOfInterest = (const tindexint *)((uint8 *)triangleVertexIndices + (sizeint)triangleIndex * triangleStride); + for (unsigned trianglePoint = dMTV__MIN; trianglePoint != dMTV__MAX; ++trianglePoint) + { + unsigned vertexIndex = triangleIndicesOfInterest[trianglePoint]; + tcoordfloat *pointVertex = (tcoordfloat *)((uint8 *)vertexInstances + (sizeint)vertexIndex * vertexStride); + dAssignVector3(out_Points[trianglePoint], (dReal)pointVertex[dSA_X], (dReal)pointVertex[dSA_Y], (dReal)pointVertex[dSA_Z]); + dSASSERT(dSA_X == 0); + dSASSERT(dSA_Y == 1); + dSASSERT(dSA_Z == 2); + } +} + + +template<class TMeshDataAccessor> +/*static */ +void dxTriDataBase::meaningfulPreprocess_SetupEdgeRecords(EdgeRecord *edges, sizeint numEdges, const TMeshDataAccessor &dataAccessor) +{ + unsigned vertexIndices[dMTV__MAX]; + // Make a list of every edge in the mesh + unsigned triangleIdx = 0; + for (sizeint edgeIdx = 0; edgeIdx != numEdges; ++triangleIdx, edgeIdx += dMTV__MAX) + { + dataAccessor.getTriangleVertexIndices(vertexIndices, triangleIdx); + edges[edgeIdx + dMTV_FIRST].setupEdge(dMTV_FIRST, triangleIdx, vertexIndices); + edges[edgeIdx + dMTV_SECOND].setupEdge(dMTV_SECOND, triangleIdx, vertexIndices); + edges[edgeIdx + dMTV_THIRD].setupEdge(dMTV_THIRD, triangleIdx, vertexIndices); + } +} + +template<class TMeshDataAccessor> +/*static */ +void dxTriDataBase::meaningfulPreprocess_buildEdgeFlags(uint8 *useFlags/*=NULL*/, IFaceAngleStorageControl *faceAngles/*=NULL*/, + EdgeRecord *edges, sizeint numEdges, VertexRecord *vertices, + const dReal *externalNormals/*=NULL*/, const TMeshDataAccessor &dataAccessor) +{ + dIASSERT(useFlags != NULL || faceAngles != NULL); + dIASSERT(numEdges != 0); + + const bool negativeAnglesStored = faceAngles != NULL && faceAngles->areNegativeAnglesStored(); + + // Go through the sorted list of edges and flag all the edges and vertices that we need to use + EdgeRecord *const lastEdge = edges + (numEdges - 1); + for (EdgeRecord *currEdge = edges; ; ++currEdge) + { + // Handle the last edge separately to have an optimizer friendly loop + if (currEdge >= lastEdge) + { + // This is a boundary edge + if (currEdge == lastEdge) + { + if (faceAngles != NULL) + { + buildBoundaryEdgeAngle(faceAngles, currEdge); + } + + if (useFlags != NULL) + { + // For the last element EdgeRecord::kAbsVertexUsed assignment can be skipped as noone is going to need it any more + useFlags[currEdge[0].m_triIdx] |= ((edges[currEdge[0].m_vertIdx1].m_absVertexFlags & EdgeRecord::AVF_VERTEX_USED) == 0 ? currEdge[0].m_vert1Flags : 0) + | ((edges[currEdge[0].m_vertIdx2].m_absVertexFlags & EdgeRecord::AVF_VERTEX_USED) == 0 ? currEdge[0].m_vert2Flags : 0) + | currEdge[0].m_edgeFlags; + } + } + + break; + } + + unsigned vertIdx1 = currEdge[0].m_vertIdx1; + unsigned vertIdx2 = currEdge[0].m_vertIdx2; + + if (vertIdx2 == currEdge[1].m_vertIdx2 // Check second vertex first as it is more likely to change taking the sorting rules into account + && vertIdx1 == currEdge[1].m_vertIdx1) + { + // We let the dot threshold for concavity get slightly negative to allow for rounding errors + const float kConcaveThreshold = 0.000001f; + + const dVector3 *pSecondTriangleEdgeToUse = NULL, *pFirstTriangleToUse = NULL; + dVector3 secondTriangleMatchingEdge; + dVector3 firstTriangle[dMTV__MAX]; + dVector3 secondOppositeVertexSegment, triangleNormal; + dReal lengthSquareProduct, secondOppositeSegmentLengthSquare; + + // Calculate orthogonal vector from the matching edge of the second triangle to its opposite point + { + dVector3 secondTriangle[dMTV__MAX]; + dataAccessor.getTriangleVertexPoints(secondTriangle, currEdge[1].m_triIdx); + + // Get the vertex opposite this edge in the second triangle + dMeshTriangleVertex secondOppositeVertex = currEdge[1].getOppositeVertexIndex(); + dMeshTriangleVertex secondEdgeStart = secondOppositeVertex + 1 != dMTV__MAX ? (dMeshTriangleVertex)(secondOppositeVertex + 1) : dMTV__MIN; + dMeshTriangleVertex secondEdgeEnd = (dMeshTriangleVertex)(dMTV_FIRST + dMTV_SECOND + dMTV_THIRD - secondEdgeStart - secondOppositeVertex); + + dSubtractVectors3(secondTriangleMatchingEdge, secondTriangle[secondEdgeEnd], secondTriangle[secondEdgeStart]); + + if (dSafeNormalize3(secondTriangleMatchingEdge)) + { + pSecondTriangleEdgeToUse = &secondTriangleMatchingEdge; + + dVector3 secondTriangleOppositeEdge; + dSubtractVectors3(secondTriangleOppositeEdge, secondTriangle[secondOppositeVertex], secondTriangle[secondEdgeStart]); + dReal dProjectionLength = dCalcVectorDot3(secondTriangleOppositeEdge, secondTriangleMatchingEdge); + dAddVectorScaledVector3(secondOppositeVertexSegment, secondTriangleOppositeEdge, secondTriangleMatchingEdge, -dProjectionLength); + } + else + { + dSubtractVectors3(secondOppositeVertexSegment, secondTriangle[secondOppositeVertex], secondTriangle[secondEdgeStart]); + } + + secondOppositeSegmentLengthSquare = dCalcVectorLengthSquare3(secondOppositeVertexSegment); + } + + // Either calculate the normal from triangle vertices... + if (externalNormals == NULL) + { + // Get the normal of the first triangle + dataAccessor.getTriangleVertexPoints(firstTriangle, currEdge[0].m_triIdx); + pFirstTriangleToUse = &firstTriangle[dMTV__MIN]; + + dVector3 firstEdge, secondEdge; + dSubtractVectors3(secondEdge, firstTriangle[dMTV_THIRD], firstTriangle[dMTV_SECOND]); + dSubtractVectors3(firstEdge, firstTriangle[dMTV_FIRST], firstTriangle[dMTV_SECOND]); + dCalcVectorCross3(triangleNormal, secondEdge, firstEdge); + dReal normalLengthSuqare = dCalcVectorLengthSquare3(triangleNormal); + lengthSquareProduct = secondOppositeSegmentLengthSquare * normalLengthSuqare; + } + // ...or use the externally supplied normals + else + { + const dReal *pTriangleExternalNormal = externalNormals + currEdge[0].m_triIdx * dSA__MAX; + dAssignVector3(triangleNormal, pTriangleExternalNormal[dSA_X], pTriangleExternalNormal[dSA_Y], pTriangleExternalNormal[dSA_Z]); + // normalLengthSuqare = REAL(1.0); + dUASSERT(dFabs(dCalcVectorLengthSquare3(triangleNormal) - REAL(1.0)) < REAL(0.25) * kConcaveThreshold * kConcaveThreshold, "Mesh triangle normals must be normalized"); + + lengthSquareProduct = secondOppositeSegmentLengthSquare/* * normalLengthSuqare*/; + } + + dReal normalSegmentDot = dCalcVectorDot3(triangleNormal, secondOppositeVertexSegment); + + // This is a concave edge, leave it for the next pass + // OD: This is the "dot >= kConcaveThresh" check, but since the vectros were not normalized to save on roots and divisions, + // the check against zero is performed first and then the dot product is squared and compared against the threshold multiplied by lengths' squares + // OD: Originally, there was dot > -kConcaveThresh check, but this does not seem to be a good idea + // as it can mark all edges on potentially large (nearly) flat surfaces concave. + if (normalSegmentDot > REAL(0.0) && normalSegmentDot * normalSegmentDot >= kConcaveThreshold * kConcaveThreshold * lengthSquareProduct) + { + if (faceAngles != NULL) + { + buildConcaveEdgeAngle(faceAngles, negativeAnglesStored, currEdge, normalSegmentDot, lengthSquareProduct, + triangleNormal, secondOppositeVertexSegment, + pSecondTriangleEdgeToUse, pFirstTriangleToUse, dataAccessor); + } + + if (useFlags != NULL) + { + // Mark the vertices of a concave edge to prevent their use + unsigned absVertexFlags1 = edges[vertIdx1].m_absVertexFlags; + edges[vertIdx1].m_absVertexFlags |= absVertexFlags1 | EdgeRecord::AVF_VERTEX_HAS_CONCAVE_EDGE | EdgeRecord::AVF_VERTEX_USED; + + if ((absVertexFlags1 & (EdgeRecord::AVF_VERTEX_HAS_CONCAVE_EDGE | EdgeRecord::AVF_VERTEX_USED)) == EdgeRecord::AVF_VERTEX_USED) + { + // If the vertex was already used from other triangles but then discovered + // to have a concave edge, unmark the previous use + unsigned usedFromEdgeIndex = vertices[vertIdx1].m_UsedFromEdgeIndex; + const EdgeRecord *usedFromEdge = edges + usedFromEdgeIndex; + unsigned usedInTriangleIndex = usedFromEdge->m_triIdx; + uint8 usedVertFlags = usedFromEdge->m_vertIdx1 == vertIdx1 ? usedFromEdge->m_vert1Flags : usedFromEdge->m_vert2Flags; + useFlags[usedInTriangleIndex] ^= usedVertFlags; + dIASSERT((useFlags[usedInTriangleIndex] & usedVertFlags) == 0); + } + + unsigned absVertexFlags2 = edges[vertIdx2].m_absVertexFlags; + edges[vertIdx2].m_absVertexFlags = absVertexFlags2 | EdgeRecord::AVF_VERTEX_HAS_CONCAVE_EDGE | EdgeRecord::AVF_VERTEX_USED; + + if ((absVertexFlags2 & (EdgeRecord::AVF_VERTEX_HAS_CONCAVE_EDGE | EdgeRecord::AVF_VERTEX_USED)) == EdgeRecord::AVF_VERTEX_USED) + { + // Similarly unmark the possible previous use of the edge's second vertex + unsigned usedFromEdgeIndex = vertices[vertIdx2].m_UsedFromEdgeIndex; + const EdgeRecord *usedFromEdge = edges + usedFromEdgeIndex; + unsigned usedInTriangleIndex = usedFromEdge->m_triIdx; + uint8 usedVertFlags = usedFromEdge->m_vertIdx1 == vertIdx2 ? usedFromEdge->m_vert1Flags : usedFromEdge->m_vert2Flags; + useFlags[usedInTriangleIndex] ^= usedVertFlags; + dIASSERT((useFlags[usedInTriangleIndex] & usedVertFlags) == 0); + } + } + } + // If this is a convex edge, mark its vertices and edge as used + else + { + if (faceAngles != NULL) + { + buildConvexEdgeAngle(faceAngles, currEdge, normalSegmentDot, lengthSquareProduct, + triangleNormal, secondOppositeVertexSegment, + pSecondTriangleEdgeToUse, pFirstTriangleToUse, dataAccessor); + } + + if (useFlags != NULL) + { + EdgeRecord *edgeToUse = currEdge; + unsigned triIdx = edgeToUse[0].m_triIdx; + unsigned triIdx1 = edgeToUse[1].m_triIdx; + + unsigned triUseFlags = useFlags[triIdx]; + unsigned triUseFlags1 = useFlags[triIdx1]; + + // Choose to add flags to the bitmask that already has more edges + // (to group flags in selected triangles rather than scattering them evenly) + if ((triUseFlags1 & CUF__USE_ALL_EDGES) > (triUseFlags & CUF__USE_ALL_EDGES)) + { + triIdx = triIdx1; + triUseFlags = triUseFlags1; + edgeToUse = edgeToUse + 1; + } + + if ((edges[vertIdx1].m_absVertexFlags & EdgeRecord::AVF_VERTEX_USED) == 0) + { + // Only add each vertex once and set a mark to prevent further additions + edges[vertIdx1].m_absVertexFlags |= EdgeRecord::AVF_VERTEX_USED; + // Also remember the index the vertex flags are going to be applied to + // to allow easily clear the vertex from the use flags if any concave edges are found to connect to it + vertices[vertIdx1].m_UsedFromEdgeIndex = (unsigned)(edgeToUse - edges); + triUseFlags |= edgeToUse[0].m_vert1Flags; + } + + // Same processing for the second vertex... + if ((edges[vertIdx2].m_absVertexFlags & EdgeRecord::AVF_VERTEX_USED) == 0) + { + edges[vertIdx2].m_absVertexFlags |= EdgeRecord::AVF_VERTEX_USED; + vertices[vertIdx2].m_UsedFromEdgeIndex = (unsigned)(edgeToUse - edges); + triUseFlags |= edgeToUse[0].m_vert2Flags; + } + + // And finally store the use flags adding the edge flags in + useFlags[triIdx] = triUseFlags | edgeToUse[0].m_edgeFlags; + } + } + + // Skip the second edge + ++currEdge; + } + // This is a boundary edge + else + { + if (faceAngles != NULL) + { + buildBoundaryEdgeAngle(faceAngles, currEdge); + } + + if (useFlags != NULL) + { + unsigned triIdx = currEdge[0].m_triIdx; + unsigned triUseExtraFlags = 0; + + if ((edges[vertIdx1].m_absVertexFlags & EdgeRecord::AVF_VERTEX_USED) == 0) + { + edges[vertIdx1].m_absVertexFlags |= EdgeRecord::AVF_VERTEX_USED; + vertices[vertIdx1].m_UsedFromEdgeIndex = (unsigned)(currEdge - edges); + triUseExtraFlags |= currEdge[0].m_vert1Flags; + } + + if ((edges[vertIdx2].m_absVertexFlags & EdgeRecord::AVF_VERTEX_USED) == 0) + { + edges[vertIdx2].m_absVertexFlags |= EdgeRecord::AVF_VERTEX_USED; + vertices[vertIdx2].m_UsedFromEdgeIndex = (unsigned)(currEdge - edges); + triUseExtraFlags |= currEdge[0].m_vert2Flags; + } + + useFlags[triIdx] |= triUseExtraFlags | currEdge[0].m_edgeFlags; + } + } + } +} + +/*static */ +void dxTriDataBase::buildBoundaryEdgeAngle(IFaceAngleStorageControl *faceAngles, + EdgeRecord *currEdge) +{ + const dReal faceAngle = REAL(0.0); + + dMeshTriangleVertex firstVertexStartIndex = currEdge[0].getEdgeStartVertexIndex(); + faceAngles->assignFacesAngleIntoStorage(currEdge[0].m_triIdx, firstVertexStartIndex, faceAngle); + // -- For boundary edges, only the first element is valid + // dMeshTriangleVertex secondVertexStartIndex = currEdge[1].getEdgeStartVertexIndex(); + // faceAngles->assignFacesAngleIntoStorage(currEdge[1].m_TriIdx, secondVertexStartIndex, faceAngle); +} + +template<class TMeshDataAccessor> +/*static */ +void dxTriDataBase::buildConcaveEdgeAngle(IFaceAngleStorageControl *faceAngles, bool negativeAnglesStored, + EdgeRecord *currEdge, const dReal &normalSegmentDot, const dReal &lengthSquareProduct, + const dVector3 &triangleNormal, const dVector3 &secondOppositeVertexSegment, + const dVector3 *pSecondTriangleMatchingEdge/*=NULL*/, const dVector3 *pFirstTriangle/*=NULL*/, + const TMeshDataAccessor &dataAccessor) +{ + dReal faceAngle; + dMeshTriangleVertex firstVertexStartIndex = currEdge[0].getEdgeStartVertexIndex(); + + // Check if concave angles are stored at all + if (negativeAnglesStored) + { + // The length square product can become zero due to precision loss + // when both the normal and the opposite edge vectors are very small. + if (lengthSquareProduct != REAL(0.0)) + { + faceAngle = -calculateEdgeAngleValidated(firstVertexStartIndex, + currEdge, normalSegmentDot, lengthSquareProduct, triangleNormal, secondOppositeVertexSegment, + pSecondTriangleMatchingEdge, pFirstTriangle, dataAccessor); + } + else + { + faceAngle = REAL(0.0); + } + } + else + { + // If concave angles ate not stored, set an arbitrary negative value + faceAngle = -(dReal)M_PI; + } + + faceAngles->assignFacesAngleIntoStorage(currEdge[0].m_triIdx, firstVertexStartIndex, faceAngle); + dMeshTriangleVertex secondVertexStartIndex = currEdge[1].getEdgeStartVertexIndex(); + faceAngles->assignFacesAngleIntoStorage(currEdge[1].m_triIdx, secondVertexStartIndex, faceAngle); +} + +template<class TMeshDataAccessor> +/*static */ +void dxTriDataBase::buildConvexEdgeAngle(IFaceAngleStorageControl *faceAngles, + EdgeRecord *currEdge, const dReal &normalSegmentDot, const dReal &lengthSquareProduct, + const dVector3 &triangleNormal, const dVector3 &secondOppositeVertexSegment, + const dVector3 *pSecondTriangleMatchingEdge/*=NULL*/, const dVector3 *pFirstTriangle/*=NULL*/, + const TMeshDataAccessor &dataAccessor) +{ + dReal faceAngle; + dMeshTriangleVertex firstVertexStartIndex = currEdge[0].getEdgeStartVertexIndex(); + + // The length square product can become zero due to precision loss + // when both the normal and the opposite edge vectors are very small. + if (normalSegmentDot < REAL(0.0) && lengthSquareProduct != REAL(0.0)) + { + faceAngle = calculateEdgeAngleValidated(firstVertexStartIndex, + currEdge, -normalSegmentDot, lengthSquareProduct, triangleNormal, secondOppositeVertexSegment, + pSecondTriangleMatchingEdge, pFirstTriangle, dataAccessor); + } + else + { + faceAngle = REAL(0.0); + } + + faceAngles->assignFacesAngleIntoStorage(currEdge[0].m_triIdx, firstVertexStartIndex, faceAngle); + dMeshTriangleVertex secondVertexStartIndex = currEdge[1].getEdgeStartVertexIndex(); + faceAngles->assignFacesAngleIntoStorage(currEdge[1].m_triIdx, secondVertexStartIndex, faceAngle); +} + +template<class TMeshDataAccessor> +/*static */ +dReal dxTriDataBase::calculateEdgeAngleValidated(unsigned firstVertexStartIndex, + EdgeRecord *currEdge, const dReal &normalSegmentDot, const dReal &lengthSquareProduct, + const dVector3 &triangleNormal, const dVector3 &secondOppositeVertexSegment, + const dVector3 *pSecondTriangleMatchingEdge/*=NULL*/, const dVector3 *pFirstTriangle/*=NULL*/, + const TMeshDataAccessor &dataAccessor) +{ + dIASSERT(lengthSquareProduct >= REAL(0.0)); + + dReal result; + dReal angleCosine = normalSegmentDot / dSqrt(lengthSquareProduct); + + if (angleCosine < REAL(1.0)) + { + dVector3 normalSecondOppositeSegmentCross; + dCalcVectorCross3(normalSecondOppositeSegmentCross, triangleNormal, secondOppositeVertexSegment); + + dReal secondTriangleEdgeDirectionCheck; + + if (pSecondTriangleMatchingEdge != NULL) + { + // Check the cross product against the second triangle edge, if possible... + secondTriangleEdgeDirectionCheck = dCalcVectorDot3(normalSecondOppositeSegmentCross, *pSecondTriangleMatchingEdge); + } + else + { + // ...if not, calculate the supposed direction of the second triangle's edge + // as negative of first triangle edge. For that cross-multiply the precomputed + // first triangle normal by vector from the degenerate edge to its opposite vertex. + + // Retrieve the first triangle points if necessary + dVector3 firstTriangleStorage[dMTV__MAX]; + const dVector3 *pFirstTriangleToUse = pFirstTriangle; + + if (pFirstTriangle == NULL) + { + dataAccessor.getTriangleVertexPoints(firstTriangleStorage, currEdge[0].m_triIdx); + pFirstTriangleToUse = &firstTriangleStorage[dMTV__MIN]; + } + + // Calculate the opposite vector + unsigned firstTriangleOppositeIndex = firstVertexStartIndex != dMTV__MIN ? firstVertexStartIndex - 1 : dMTV__MAX - 1; + + dVector3 firstOppositeVertexSegment; + dSubtractVectors3(firstOppositeVertexSegment, pFirstTriangleToUse[firstTriangleOppositeIndex], pFirstTriangleToUse[firstVertexStartIndex]); + + dVector3 normalFirstOppositeSegmentCross; + dCalcVectorCross3(normalFirstOppositeSegmentCross, triangleNormal, firstOppositeVertexSegment); + + // And finally calculate the dot product to compare vector directions + secondTriangleEdgeDirectionCheck = dCalcVectorDot3(normalSecondOppositeSegmentCross, normalFirstOppositeSegmentCross); + } + + // Negative product means the angle absolute value is less than M_PI_2, positive - greater. + result = secondTriangleEdgeDirectionCheck < REAL(0.0) ? dAsin(angleCosine) : (dReal)M_PI_2 + dAcos(angleCosine); + } + else + { + result = (dReal)M_PI_2; + dIASSERT(angleCosine - REAL(1.0) < 1e-4); // The computational error can not be too high because the dot product had been verified to be greater than the concave threshold above + } + + return result; +} + + +#endif // #if dTRIMESH_ENABLED + + +#endif // #ifndef _ODE_COLLISION_TRIMESH_INTERNAL_IMPL_H_ diff --git a/libs/ode-0.16.1/ode/src/collision_trimesh_opcode.cpp b/libs/ode-0.16.1/ode/src/collision_trimesh_opcode.cpp new file mode 100644 index 0000000..53d8b0f --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_trimesh_opcode.cpp @@ -0,0 +1,767 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// TriMesh code by Erwin de Vries. +// TriMesh storage classes refactoring and face angle computation code by Oleh Derevenko (C) 2016-2019 + +#include <ode/collision.h> +#include <ode/rotation.h> +#include "config.h" +#include "matrix.h" +#include "odemath.h" + + +#if dTRIMESH_ENABLED && dTRIMESH_OPCODE + +#include "collision_util.h" +#include "collision_trimesh_opcode.h" +#include "collision_trimesh_internal_impl.h" +#include <algorithm> + + +////////////////////////////////////////////////////////////////////////// +// TrimeshCollidersCache + +void TrimeshCollidersCache::initOPCODECaches() +{ + m_RayCollider.SetDestination(&m_Faces); + + /* -- not used + _PlanesCollider.SetTemporalCoherence(true); + */ + + m_SphereCollider.SetTemporalCoherence(true); + m_SphereCollider.SetPrimitiveTests(false); + + m_OBBCollider.SetTemporalCoherence(true); + + // no first-contact test (i.e. return full contact info) + m_AABBTreeCollider.SetFirstContact( false ); + // temporal coherence only works with "first contact" tests + m_AABBTreeCollider.SetTemporalCoherence(false); + // Perform full BV-BV tests (true) or SAT-lite tests (false) + m_AABBTreeCollider.SetFullBoxBoxTest( true ); + // Perform full Primitive-BV tests (true) or SAT-lite tests (false) + m_AABBTreeCollider.SetFullPrimBoxTest( true ); + const char* msg; + if ((msg =m_AABBTreeCollider.ValidateSettings())) + { + dDebug (d_ERR_UASSERT, msg, " (%s:%d)", __FILE__,__LINE__); + } + + /* -- not used + _LSSCollider.SetTemporalCoherence(false); + _LSSCollider.SetPrimitiveTests(false); + _LSSCollider.SetFirstContact(false); + */ +} + +void TrimeshCollidersCache::clearOPCODECaches() +{ + m_Faces.Empty(); + m_DefaultSphereCache.TouchedPrimitives.Empty(); + m_DefaultBoxCache.TouchedPrimitives.Empty(); + m_DefaultCapsuleCache.TouchedPrimitives.Empty(); +} + + +////////////////////////////////////////////////////////////////////////// +// Trimesh data + +dxTriMeshData::~dxTriMeshData() +{ + if ( m_InternalUseFlags != NULL ) + { + sizeint flagsMemoryRequired = calculateUseFlagsMemoryRequirement(); + dFree(m_InternalUseFlags, flagsMemoryRequired); + } +} + +void dxTriMeshData::buildData(const Point *Vertices, int VertexStide, unsigned VertexCount, + const IndexedTriangle *Indices, unsigned IndexCount, int TriStride, + const dReal *in_Normals, + bool Single) +{ + dxTriMeshData_Parent::buildData(Vertices, VertexStide, VertexCount, Indices, IndexCount, TriStride, in_Normals, Single); + dAASSERT(IndexCount % dMTV__MAX == 0); + + m_Mesh.SetNbTriangles(IndexCount / dMTV__MAX); + m_Mesh.SetNbVertices(VertexCount); + m_Mesh.SetPointers(Indices, Vertices); + m_Mesh.SetStrides(TriStride, VertexStide); + m_Mesh.SetSingle(Single); + + // Build tree + // recommended in Opcode User Manual + //Settings.mRules = SPLIT_COMPLETE | SPLIT_SPLATTERPOINTS | SPLIT_GEOMCENTER; + // used in ODE, why? + //Settings.mRules = SPLIT_BEST_AXIS; + // best compromise? + BuildSettings Settings(SPLIT_BEST_AXIS | SPLIT_SPLATTER_POINTS | SPLIT_GEOM_CENTER); + + OPCODECREATE TreeBuilder(&m_Mesh, Settings, true, false); + + m_BVTree.Build(TreeBuilder); + + // compute model space AABB + dVector3 AABBMax, AABBMin; + calculateDataAABB(AABBMax, AABBMin); + + dAddVectors3(m_AABBCenter, AABBMin, AABBMax); + dScaleVector3(m_AABBCenter, REAL(0.5)); + + dSubtractVectors3(m_AABBExtents, AABBMax, m_AABBCenter); + + // user data (not used by OPCODE) + dIASSERT(m_InternalUseFlags == NULL); +} + + +void dxTriMeshData::calculateDataAABB(dVector3 &AABBMax, dVector3 &AABBMin) +{ + if (isSingle()) + { + templateCalculateDataAABB<float>(AABBMax, AABBMin); + } + else + { + templateCalculateDataAABB<double>(AABBMax, AABBMin); + } +} + +template<typename treal> +void dxTriMeshData::templateCalculateDataAABB(dVector3 &AABBMax, dVector3 &AABBMin) +{ + dIASSERT(isSingle() == (sizeof(treal) == sizeof(float))); + + const Point *vertices = retrieveVertexInstances(); + const int vertexStide = retrieveVertexStride(); + const unsigned vertexCount = retrieveVertexCount(); + + AABBMax[dV3E_X] = AABBMax[dV3E_Y] = AABBMax[dV3E_Z] = -dInfinity; + AABBMin[dV3E_X] = AABBMin[dV3E_Y] = AABBMin[dV3E_Z] = dInfinity; + dSASSERT(dV3E__AXES_COUNT == 3); + + const uint8 *verts = (const uint8 *)vertices; + for( unsigned i = 0; i < vertexCount; ++i ) + { + const treal *v = (const treal *)verts; + if( v[dSA_X] > AABBMax[dV3E_X] ) AABBMax[dV3E_X] = (dReal)v[dSA_X]; + if( v[dSA_X] < AABBMin[dV3E_X] ) AABBMin[dV3E_X] = (dReal)v[dSA_X]; + if( v[dSA_Y] > AABBMax[dV3E_Y] ) AABBMax[dV3E_Y] = (dReal)v[dSA_Y]; + if( v[dSA_Y] < AABBMin[dV3E_Y] ) AABBMin[dV3E_Y] = (dReal)v[dSA_Y]; + if( v[dSA_Z] > AABBMax[dV3E_Z] ) AABBMax[dV3E_Z] = (dReal)v[dSA_Z]; + if( v[dSA_Z] < AABBMin[dV3E_Z] ) AABBMin[dV3E_Z] = (dReal)v[dSA_Z]; + verts += vertexStide; + } +} + + +bool dxTriMeshData::preprocessData(bool buildUseFlags/*=false*/, FaceAngleStorageMethod faceAndgesRequirement/*=ASM__INVALID*/) +{ + bool buildUseFlagsToUse = buildUseFlags; + FaceAngleStorageMethod faceAndgesRequirementToUse = faceAndgesRequirement; + + if (buildUseFlags && haveUseFlagsBeenBuilt()) + { + dUASSERT(false, "Another request to build edge/vertex use flags after they had already been built"); + + buildUseFlagsToUse = false; + } + + if (faceAndgesRequirement != ASM__INVALID && haveFaceAnglesBeenBuilt()) + { + dUASSERT(false, "Another request to build face angles after they had already been built"); + + faceAndgesRequirementToUse = ASM__INVALID; + } + + // If this mesh has already been preprocessed, exit + bool result = (!buildUseFlagsToUse && faceAndgesRequirementToUse == ASM__INVALID) || m_Mesh.GetNbTriangles() == 0 + || meaningfulPreprocessData(buildUseFlagsToUse, faceAndgesRequirementToUse); + return result; +} + +struct TrimeshDataVertexIndexAccessor_OPCODE +{ + TrimeshDataVertexIndexAccessor_OPCODE(const IndexedTriangle *triIndicesBegin, unsigned triStride): + m_TriIndicesBegin(triIndicesBegin), + m_TriStride(triStride) + { + } + + void getTriangleVertexIndices(unsigned out_VertexIndices[dMTV__MAX], unsigned triangleIdx) const + { + const IndexedTriangle *triIndicesBegin = m_TriIndicesBegin; + const unsigned triStride = m_TriStride; + + const IndexedTriangle *triIndicesOfInterest = (const IndexedTriangle *)((const uint8 *)triIndicesBegin + triangleIdx * (sizeint)triStride); + std::copy(triIndicesOfInterest->mVRef, triIndicesOfInterest->mVRef + dMTV__MAX, out_VertexIndices); + dSASSERT(dMTV__MAX == dARRAY_SIZE(triIndicesOfInterest->mVRef)); + dSASSERT(dMTV_FIRST == 0); + dSASSERT(dMTV_SECOND == 1); + dSASSERT(dMTV_THIRD == 2); + dSASSERT(dMTV__MAX == 3); + } + + + const IndexedTriangle *m_TriIndicesBegin; + unsigned m_TriStride; +}; + +struct TrimeshDataTrianglePointAccessor_OPCODE +{ + TrimeshDataTrianglePointAccessor_OPCODE(const MeshInterface &mesh): + m_Mesh(mesh) + { + } + + void getTriangleVertexPoints(dVector3 out_Points[dMTV__MAX], unsigned triangleIndex) const + { + VertexPointers vpTriangle; + ConversionArea vc; + m_Mesh.GetTriangle(vpTriangle, triangleIndex, vc); + + for (unsigned pointIndex = 0; pointIndex != 3; ++pointIndex) + { + dAssignVector3(out_Points[pointIndex], vpTriangle.Vertex[pointIndex]->x, vpTriangle.Vertex[pointIndex]->y, vpTriangle.Vertex[pointIndex]->z); + } + dSASSERT(dMTV_FIRST == 0); + dSASSERT(dMTV_SECOND == 1); + dSASSERT(dMTV_THIRD == 2); + dSASSERT(dMTV__MAX == 3); + } + + const MeshInterface &m_Mesh; +}; + +bool dxTriMeshData::meaningfulPreprocessData(bool buildUseFlags/*=false*/, FaceAngleStorageMethod faceAndgesRequirement/*=ASM__INVALID*/) +{ + const bool buildFaceAngles = faceAndgesRequirement != ASM__INVALID; + dIASSERT(buildUseFlags || buildFaceAngles); + dIASSERT(!buildUseFlags || !haveUseFlagsBeenBuilt()); + dIASSERT(!buildFaceAngles || !haveFaceAnglesBeenBuilt()); + + bool result = false; + + uint8 *useFlags = NULL; + sizeint flagsMemoryRequired = 0; + bool flagsAllocated = false, anglesAllocated = false; + + do + { + if (buildUseFlags) + { + flagsMemoryRequired = calculateUseFlagsMemoryRequirement(); + useFlags = (uint8 *)dAlloc(flagsMemoryRequired); + + if (useFlags == NULL) + { + break; + } + } + + flagsAllocated = true; + + if (buildFaceAngles) + { + if (!allocateFaceAngles(faceAndgesRequirement)) + { + break; + } + } + + anglesAllocated = true; + + const unsigned int numTris = m_Mesh.GetNbTriangles(); + const unsigned int numVertices = m_Mesh.GetNbVertices(); + sizeint numEdges = (sizeint)numTris * dMTV__MAX; + dIASSERT(numVertices <= numEdges); // Edge records are going to be used for vertex data as well + + const sizeint recordsMemoryRequired = dEFFICIENT_SIZE(numEdges * sizeof(EdgeRecord)); + const sizeint verticesMemoryRequired = /*dEFFICIENT_SIZE*/(numVertices * sizeof(VertexRecord)); // Skip alignment for the last chunk + const sizeint totalTempMemoryRequired = recordsMemoryRequired + verticesMemoryRequired; + void *tempBuffer = dAlloc(totalTempMemoryRequired); + + if (tempBuffer == NULL) + { + break; + } + + EdgeRecord *edges = (EdgeRecord *)tempBuffer; + VertexRecord *vertices = (VertexRecord *)((uint8 *)tempBuffer + recordsMemoryRequired); + + // Delay zero-filling until all the allocations succeed + if (useFlags != NULL) + { + memset(useFlags, 0, flagsMemoryRequired); + } + + const IndexedTriangle *triIndicesBegin = m_Mesh.GetTris(); + unsigned triStride = m_Mesh.GetTriStride(); + TrimeshDataVertexIndexAccessor_OPCODE indexAccessor(triIndicesBegin, triStride); + meaningfulPreprocess_SetupEdgeRecords(edges, numEdges, indexAccessor); + + // Sort the edges, so the ones sharing the same verts are beside each other + std::sort(edges, edges + numEdges); + + TrimeshDataTrianglePointAccessor_OPCODE pointAccessor(m_Mesh); + const dReal *const externalNormals = retrieveNormals(); + IFaceAngleStorageControl *faceAngles = retrieveFaceAngles(); + meaningfulPreprocess_buildEdgeFlags(useFlags, faceAngles, edges, numEdges, vertices, externalNormals, pointAccessor); + + dFree(tempBuffer, totalTempMemoryRequired); + + if (buildUseFlags) + { + m_InternalUseFlags = useFlags; + } + + result = true; + } + while (false); + + if (!result) + { + if (flagsAllocated) + { + if (anglesAllocated) + { + if (buildFaceAngles) + { + freeFaceAngles(); + } + } + + if (buildUseFlags) + { + dFree(useFlags, flagsMemoryRequired); + } + } + } + + return result; +} + + +void dxTriMeshData::updateData() +{ + m_BVTree.Refit(); +} + + + +////////////////////////////////////////////////////////////////////////// +// dxTriMesh + +dxTriMesh::~dxTriMesh() +{ + // +} + +void dxTriMesh::clearTCCache() +{ + /* dxTriMesh::ClearTCCache uses dArray's setSize(0) to clear the caches - + but the destructor isn't called when doing this, so we would leak. + So, call the previous caches' containers' destructors by hand first. */ + int i, n; + + n = m_SphereTCCache.size(); + for( i = 0; i != n; ++i ) + { + m_SphereTCCache[i].~SphereTC(); + } + m_SphereTCCache.setSize(0); + + n = m_BoxTCCache.size(); + for( i = 0; i != n; ++i ) + { + m_BoxTCCache[i].~BoxTC(); + } + m_BoxTCCache.setSize(0); + + n = m_CapsuleTCCache.size(); + for( i = 0; i != n; ++i ) + { + m_CapsuleTCCache[i].~CapsuleTC(); + } + m_CapsuleTCCache.setSize(0); +} + + +bool dxTriMesh::controlGeometry(int controlClass, int controlCode, void *dataValue, int *dataSize) +{ + if (controlClass == dGeomColliderControlClass) + { + if (controlCode == dGeomCommonAnyControlCode) + { + return checkControlValueSizeValidity(dataValue, dataSize, 0); + } + else if (controlCode == dGeomColliderSetMergeSphereContactsControlCode) + { + return checkControlValueSizeValidity(dataValue, dataSize, sizeof(int)) + && controlGeometry_SetMergeSphereContacts(*(int *)dataValue); + } + else if (controlCode == dGeomColliderGetMergeSphereContactsControlCode) + { + return checkControlValueSizeValidity(dataValue, dataSize, sizeof(int)) + && controlGeometry_GetMergeSphereContacts(*(int *)dataValue); + } + } + + return dxTriMesh_Parent::controlGeometry(controlClass, controlCode, dataValue, dataSize); +} + +bool dxTriMesh::controlGeometry_SetMergeSphereContacts(int dataValue) +{ + if (dataValue == dGeomColliderMergeContactsValue__Default) + { + m_SphereContactsMergeOption = (dxContactMergeOptions)MERGE_NORMALS__SPHERE_DEFAULT; + } + else if (dataValue == dGeomColliderMergeContactsValue_None) + { + m_SphereContactsMergeOption = DONT_MERGE_CONTACTS; + } + else if (dataValue == dGeomColliderMergeContactsValue_Normals) + { + m_SphereContactsMergeOption = MERGE_CONTACT_NORMALS; + } + else if (dataValue == dGeomColliderMergeContactsValue_Full) + { + m_SphereContactsMergeOption = MERGE_CONTACTS_FULLY; + } + else + { + dAASSERT(false && "Invalid contact merge control value"); + return false; + } + + return true; +} + +bool dxTriMesh::controlGeometry_GetMergeSphereContacts(int &returnValue) +{ + if (m_SphereContactsMergeOption == DONT_MERGE_CONTACTS) { + returnValue = dGeomColliderMergeContactsValue_None; + } + else if (m_SphereContactsMergeOption == MERGE_CONTACT_NORMALS) { + returnValue = dGeomColliderMergeContactsValue_Normals; + } + else if (m_SphereContactsMergeOption == MERGE_CONTACTS_FULLY) { + returnValue = dGeomColliderMergeContactsValue_Full; + } + else { + dIASSERT(false && "Internal error: unexpected contact merge option field value"); + return false; + } + + return true; +} + + +/*virtual */ +void dxTriMesh::computeAABB() +{ + const dxTriMeshData *meshData = getMeshData(); + dVector3 c; + const dMatrix3& R = final_posr->R; + const dVector3& pos = final_posr->pos; + + dMultiply0_331( c, R, meshData->m_AABBCenter ); + + dReal xrange = dFabs(R[0] * meshData->m_AABBExtents[0]) + + dFabs(R[1] * meshData->m_AABBExtents[1]) + + dFabs(R[2] * meshData->m_AABBExtents[2]); + dReal yrange = dFabs(R[4] * meshData->m_AABBExtents[0]) + + dFabs(R[5] * meshData->m_AABBExtents[1]) + + dFabs(R[6] * meshData->m_AABBExtents[2]); + dReal zrange = dFabs(R[8] * meshData->m_AABBExtents[0]) + + dFabs(R[9] * meshData->m_AABBExtents[1]) + + dFabs(R[10] * meshData->m_AABBExtents[2]); + + aabb[0] = c[0] + pos[0] - xrange; + aabb[1] = c[0] + pos[0] + xrange; + aabb[2] = c[1] + pos[1] - yrange; + aabb[3] = c[1] + pos[1] + yrange; + aabb[4] = c[2] + pos[2] - zrange; + aabb[5] = c[2] + pos[2] + zrange; +} + + +void dxTriMesh::fetchMeshTransformedTriangle(dVector3 *const pout_triangle[3], unsigned index) +{ + const dVector3 &position = buildUpdatedPosition(); + const dMatrix3 &rotation = buildUpdatedRotation(); + fetchMeshTriangle(pout_triangle, index, position, rotation); +} + +void dxTriMesh::fetchMeshTransformedTriangle(dVector3 out_triangle[3], unsigned index) +{ + const dVector3 &position = buildUpdatedPosition(); + const dMatrix3 &rotation = buildUpdatedRotation(); + fetchMeshTriangle(out_triangle, index, position, rotation); +} + +void dxTriMesh::fetchMeshTriangle(dVector3 *const pout_triangle[3], unsigned index, const dVector3 position, const dMatrix3 rotation) const +{ + dIASSERT(dIN_RANGE(index, 0, getMeshTriangleCount())); + + VertexPointers VP; + ConversionArea VC; + + const dxTriMeshData *meshData = getMeshData(); + meshData->m_Mesh.GetTriangle(VP, index, VC); + + for (unsigned i = 0; i != 3; ++i) + { + if (pout_triangle[i] != NULL) + { + dVector3 v; + v[dV3E_X] = VP.Vertex[i]->x; + v[dV3E_Y] = VP.Vertex[i]->y; + v[dV3E_Z] = VP.Vertex[i]->z; + + dVector3 &out_triangle = *(pout_triangle[i]); + dMultiply0_331(out_triangle, rotation, v); + dAddVectors3(out_triangle, out_triangle, position); + out_triangle[dV3E_PAD] = REAL(0.0); + } + } +} + +void dxTriMesh::fetchMeshTriangle(dVector3 out_triangle[3], unsigned index, const dVector3 position, const dMatrix3 rotation) const +{ + dIASSERT(dIN_RANGE(index, 0, getMeshTriangleCount())); + + VertexPointers VP; + ConversionArea VC; + + const dxTriMeshData *meshData = getMeshData(); + meshData->m_Mesh.GetTriangle(VP, index, VC); + + for (unsigned i = 0; i != 3; ++i) + { + dVector3 v; + v[dV3E_X] = VP.Vertex[i]->x; + v[dV3E_Y] = VP.Vertex[i]->y; + v[dV3E_Z] = VP.Vertex[i]->z; + + dMultiply0_331(out_triangle[i], rotation, v); + dAddVectors3(out_triangle[i], out_triangle[i], position); + out_triangle[i][dV3E_PAD] = REAL(0.0); + } +} + + +////////////////////////////////////////////////////////////////////////// + +/*extern */ +dTriMeshDataID dGeomTriMeshDataCreate() +{ + return new dxTriMeshData(); +} + +/*extern */ +void dGeomTriMeshDataDestroy(dTriMeshDataID g) +{ + dxTriMeshData *mesh = g; + delete mesh; +} + + +/*extern */ +void dGeomTriMeshDataSet(dTriMeshDataID g, int dataId, void *pDataLocation) +{ + dUASSERT(g, "The argument is not a trimesh data"); + + dxTriMeshData *data = g; + + switch (dataId) + { + case dTRIMESHDATA_FACE_NORMALS: + { + data->assignNormals((const dReal *)pDataLocation); + break; + } + + case dTRIMESHDATA_USE_FLAGS: + { + data->assignExternalUseFlagsBuffer((uint8 *)pDataLocation); + break; + } + + // case dTRIMESHDATA__MAX: -- To be located by Find in Files + default: + { + dUASSERT(dataId, "invalid data type"); + break; + } + } +} + +static void *geomTriMeshDataGet(dTriMeshDataID g, int dataId, sizeint *pOutDataSize); + +/*extern */ +void *dGeomTriMeshDataGet(dTriMeshDataID g, int dataId, sizeint *pOutDataSize) +{ + return geomTriMeshDataGet(g, dataId, NULL); +} + +/*extern */ +void *dGeomTriMeshDataGet2(dTriMeshDataID g, int dataId, sizeint *pOutDataSize) +{ + return geomTriMeshDataGet(g, dataId, pOutDataSize); +} + +static +void *geomTriMeshDataGet(dTriMeshDataID g, int dataId, sizeint *pOutDataSize) +{ + dUASSERT(g, "The argument is not a trimesh data"); + + const dxTriMeshData *data = g; + + void *result = NULL; + + switch (dataId) + { + case dTRIMESHDATA_FACE_NORMALS: + { + if (pOutDataSize != NULL) + { + *pOutDataSize = data->calculateNormalsMemoryRequirement(); + } + + result = (void *)data->retrieveNormals(); + break; + } + + case dTRIMESHDATA_USE_FLAGS: + { + if (pOutDataSize != NULL) + { + *pOutDataSize = data->calculateUseFlagsMemoryRequirement(); + } + + result = const_cast<uint8 *>(data->smartRetrieveUseFlags()); + break; + } + + // case dTRIMESHDATA__MAX: -- To be located by Find in Files + default: + { + if (pOutDataSize != NULL) + { + *pOutDataSize = 0; + } + + dUASSERT(dataId, "invalid data type"); + break; + } + } + + return result; +} + + +/*extern */ +void dGeomTriMeshDataBuildSingle1(dTriMeshDataID g, + const void* Vertices, int VertexStride, int VertexCount, + const void* Indices, int IndexCount, int TriStride, + const void* Normals) +{ + dUASSERT(g, "The argument is not a trimesh data"); + + dxTriMeshData *data = g; + data->buildData((const Point *)Vertices, VertexStride, VertexCount, + (const IndexedTriangle *)Indices, IndexCount, TriStride, + (const dReal *)Normals, + true); +} + +/*extern */ +void dGeomTriMeshDataBuildDouble1(dTriMeshDataID g, + const void* Vertices, int VertexStride, int VertexCount, + const void* Indices, int IndexCount, int TriStride, + const void* Normals) +{ + dUASSERT(g, "The argument is not a trimesh data"); + + g->buildData((const Point *)Vertices, VertexStride, VertexCount, + (const IndexedTriangle *)Indices, IndexCount, TriStride, + (const dReal *)Normals, + false); +} + + +////////////////////////////////////////////////////////////////////////// + +/*extern */ +dGeomID dCreateTriMesh(dSpaceID space, + dTriMeshDataID Data, + dTriCallback* Callback, + dTriArrayCallback* ArrayCallback, + dTriRayCallback* RayCallback) +{ + dxTriMesh *mesh = new dxTriMesh(space, Data, Callback, ArrayCallback, RayCallback); + return mesh; +} + + +/*extern */ +void dGeomTriMeshSetLastTransform(dGeomID g, const dMatrix4 last_trans ) +{ + dAASSERT(g); + dUASSERT(g->type == dTriMeshClass, "The geom is not a trimesh"); + + dxTriMesh *mesh = static_cast<dxTriMesh *>(g); + mesh->assignLastTransform(last_trans); +} + +/*extern */ +const dReal *dGeomTriMeshGetLastTransform(dGeomID g) +{ + dAASSERT(g); + dUASSERT(g->type == dTriMeshClass, "The geom is not a trimesh"); + + dxTriMesh *mesh = static_cast<dxTriMesh *>(g); + return mesh->retrieveLastTransform(); +} + + +////////////////////////////////////////////////////////////////////////// + +// Cleanup for allocations when shutting down ODE +/*extern */ +void opcode_collider_cleanup() +{ +#if !dTLS_ENABLED + + // Clear TC caches + TrimeshCollidersCache *pccColliderCache = GetTrimeshCollidersCache(0); + pccColliderCache->clearOPCODECaches(); + +#endif // dTLS_ENABLED +} + + +#endif // dTRIMESH_ENABLED && dTRIMESH_OPCODE + diff --git a/libs/ode-0.16.1/ode/src/collision_trimesh_opcode.h b/libs/ode-0.16.1/ode/src/collision_trimesh_opcode.h new file mode 100644 index 0000000..fdce2f1 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_trimesh_opcode.h @@ -0,0 +1,333 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// TriMesh code by Erwin de Vries. +// Modified for FreeSOLID Compatibility by Rodrigo Hernandez +// Trimesh caches separation by Oleh Derevenko +// TriMesh storage classes refactoring and face angle computation code by Oleh Derevenko (C) 2016-2019 + + +#ifndef _ODE_COLLISION_TRIMESH_OPCODE_H_ +#define _ODE_COLLISION_TRIMESH_OPCODE_H_ + + +#if dTRIMESH_ENABLED && dTRIMESH_OPCODE + +//**************************************************************************** +// dxTriMesh class + + +#include "collision_kernel.h" +#include "collision_trimesh_colliders.h" +#include "collision_util.h" +#include <ode/collision_trimesh.h> + +#include "collision_trimesh_internal.h" + +#define BAN_OPCODE_AUTOLINK +#include "Opcode.h" +using namespace Opcode; + + +#if !dTRIMESH_OPCODE_USE_OLD_TRIMESH_TRIMESH_COLLIDER + +// New trimesh collider hash table types +enum +{ + MAXCONTACT_X_NODE = 4, + CONTACTS_HASHSIZE = 256 +}; + +struct CONTACT_KEY +{ + dContactGeom * m_contact; + unsigned int m_key; +}; + +struct CONTACT_KEY_HASH_NODE +{ + CONTACT_KEY m_keyarray[MAXCONTACT_X_NODE]; + int m_keycount; +}; + +struct CONTACT_KEY_HASH_TABLE +{ +public: + CONTACT_KEY_HASH_NODE &operator[](unsigned int index) { return m_storage[index]; } + +private: + CONTACT_KEY_HASH_NODE m_storage[CONTACTS_HASHSIZE]; +}; + +#endif // !dTRIMESH_OPCODE_USE_OLD_TRIMESH_TRIMESH_COLLIDER + + +struct VertexUseCache +{ +public: + VertexUseCache(): m_VertexUseBits(NULL), m_VertexUseElements(0) {} + ~VertexUseCache() { freeVertexUSEDFlags(); } + + bool resizeAndResetVertexUSEDFlags(unsigned VertexCount) + { + bool Result = false; + sizeint VertexNewElements = (VertexCount + 7) / 8; + if (VertexNewElements <= m_VertexUseElements || reallocVertexUSEDFlags(VertexNewElements)) { + memset(m_VertexUseBits, 0, VertexNewElements); + Result = true; + } + return Result; + } + + bool getVertexUSEDFlag(unsigned VertexIndex) const { return (m_VertexUseBits[VertexIndex / 8] & (1 << (VertexIndex % 8))) != 0; } + void setVertexUSEDFlag(unsigned VertexIndex) { m_VertexUseBits[VertexIndex / 8] |= (1 << (VertexIndex % 8)); } + +private: + bool reallocVertexUSEDFlags(sizeint VertexNewElements) + { + bool Result = false; + uint8 *VertexNewBits = (uint8 *)dRealloc(m_VertexUseBits, m_VertexUseElements * sizeof(m_VertexUseBits[0]), VertexNewElements * sizeof(m_VertexUseBits[0])); + if (VertexNewBits) { + m_VertexUseBits = VertexNewBits; + m_VertexUseElements = VertexNewElements; + Result = true; + } + return Result; + } + + void freeVertexUSEDFlags() + { + dFree(m_VertexUseBits, m_VertexUseElements * sizeof(m_VertexUseBits[0])); + m_VertexUseBits = NULL; + m_VertexUseElements = 0; + } + +private: + uint8 *m_VertexUseBits; + sizeint m_VertexUseElements; +}; + + +struct TrimeshCollidersCache +{ + TrimeshCollidersCache() + { + initOPCODECaches(); + } + + void initOPCODECaches(); + void clearOPCODECaches(); + + // Collider caches + BVTCache ColCache; + +#if !dTRIMESH_OPCODE_USE_OLD_TRIMESH_TRIMESH_COLLIDER + CONTACT_KEY_HASH_TABLE m_hashcontactset; +#endif + + // Colliders + /* -- not used -- also uncomment in InitOPCODECaches() + PlanesCollider _PlanesCollider; -- not used + */ + SphereCollider m_SphereCollider; + OBBCollider m_OBBCollider; + RayCollider m_RayCollider; + AABBTreeCollider m_AABBTreeCollider; + /* -- not used -- also uncomment in InitOPCODECaches() + LSSCollider _LSSCollider; + */ + // Trimesh caches + CollisionFaces m_Faces; + SphereCache m_DefaultSphereCache; + OBBCache m_DefaultBoxCache; + LSSCache m_DefaultCapsuleCache; + + // Trimesh-plane collision vertex use cache + VertexUseCache m_VertexUses; +}; + + +typedef dxTriDataBase dxTriMeshData_Parent; +struct dxTriMeshData: + public dxTriMeshData_Parent +{ +public: + dxTriMeshData(): + dxTriMeshData_Parent(), + m_ExternalUseFlags(NULL), + m_InternalUseFlags(NULL) + { + } + + ~dxTriMeshData(); + + void buildData(const Point *Vertices, int VertexStide, unsigned VertexCount, + const IndexedTriangle *Indices, unsigned IndexCount, int TriStride, + const dReal *in_Normals, + bool Single); + +private: + void calculateDataAABB(dVector3 &AABBMax, dVector3 &AABBMin); + template<typename treal> + void templateCalculateDataAABB(dVector3 &AABBMax, dVector3 &AABBMin); + +public: + /* Setup the UseFlags array and/or build face angles*/ + bool preprocessData(bool buildUseFlags/*=false*/, FaceAngleStorageMethod faceAndgesRequirement/*=ASM__INVALID*/); + +private: + bool meaningfulPreprocessData(bool buildUseFlags/*=false*/, FaceAngleStorageMethod faceAndgesRequirement/*=ASM__INVALID*/); + +public: + /* For when app changes the vertices */ + void updateData(); + +public: + const Point *retrieveVertexInstances() const { return (const Point *)dxTriMeshData_Parent::retrieveVertexInstances(); } + +public: + void assignNormals(const dReal *normals) { dxTriMeshData_Parent::assignNormals(normals); } + const dReal *retrieveNormals() const { return (const dReal *)dxTriMeshData_Parent::retrieveNormals(); } + sizeint calculateNormalsMemoryRequirement() const { return retrieveTriangleCount() * (sizeof(dReal) * dSA__MAX); } + +public: + void assignExternalUseFlagsBuffer(uint8 *buffer) { m_ExternalUseFlags = buffer != m_InternalUseFlags ? buffer : NULL; } + const uint8 *smartRetrieveUseFlags() const { return m_ExternalUseFlags != NULL ? m_ExternalUseFlags : m_InternalUseFlags; } + bool haveUseFlagsBeenBuilt() const { return m_InternalUseFlags != NULL; } + sizeint calculateUseFlagsMemoryRequirement() const { return m_Mesh.GetNbTriangles() * sizeof(m_InternalUseFlags[0]); } + +public: + Model m_BVTree; + MeshInterface m_Mesh; + + /* aabb in model space */ + dVector3 m_AABBCenter; + dVector3 m_AABBExtents; + + // data for use in collision resolution + uint8 *m_ExternalUseFlags; + uint8 *m_InternalUseFlags; + +}; + + +typedef dxMeshBase dxTriMesh_Parent; +struct dxTriMesh: + public dxTriMesh_Parent +{ +public: + // Functions + dxTriMesh(dxSpace *Space, dxTriMeshData *Data, + dTriCallback *Callback, dTriArrayCallback *ArrayCallback, dTriRayCallback *RayCallback): + dxTriMesh_Parent(Space, Data, Callback, ArrayCallback, RayCallback, false) + { + m_SphereContactsMergeOption = (dxContactMergeOptions)MERGE_NORMALS__SPHERE_DEFAULT; + + dZeroMatrix4(m_last_trans); + } + + ~dxTriMesh(); + + void clearTCCache(); + + bool controlGeometry(int controlClass, int controlCode, void *dataValue, int *dataSize); + + virtual void computeAABB(); + +public: + dxTriMeshData *retrieveMeshData() const { return getMeshData(); } + const dReal *retrieveMeshNormals() const { return getMeshData()->retrieveNormals(); } + Model &retrieveMeshBVTreeRef() const { return getMeshData()->m_BVTree; } + const uint8 *retrieveMeshSmartUseFlags() const { return getMeshData()->smartRetrieveUseFlags(); } + + unsigned getMeshTriangleCount() const { return getMeshData()->m_Mesh.GetNbTriangles(); } + void fetchMeshTransformedTriangle(dVector3 *const pout_triangle[3], unsigned index)/* const*/; + void fetchMeshTransformedTriangle(dVector3 out_triangle[3], unsigned index)/* const*/; + void fetchMeshTriangle(dVector3 *const pout_triangle[3], unsigned index, const dVector3 position, const dMatrix3 rotation) const; + void fetchMeshTriangle(dVector3 out_triangle[3], unsigned index, const dVector3 position, const dMatrix3 rotation) const; + +public: + void assignLastTransform(const dMatrix4 last_trans) { dCopyMatrix4x4(m_last_trans, last_trans); } + const dReal *retrieveLastTransform() const { return m_last_trans; } + +private: + enum + { + MERGE_NORMALS__SPHERE_DEFAULT = DONT_MERGE_CONTACTS + }; + + bool controlGeometry_SetMergeSphereContacts(int dataValue); + bool controlGeometry_GetMergeSphereContacts(int &returnValue); + +private: + dxTriMeshData *getMeshData() const { return static_cast<dxTriMeshData *>(dxTriMesh_Parent::getMeshData()); } + +public: + // Some constants + // Temporal coherence + struct SphereTC : public SphereCache{ + dxGeom* Geom; + }; + + struct BoxTC : public OBBCache{ + dxGeom* Geom; + }; + + struct CapsuleTC : public LSSCache{ + dxGeom* Geom; + }; + +public: + // Contact merging option + dxContactMergeOptions m_SphereContactsMergeOption; + // Instance data for last transform. + dMatrix4 m_last_trans; + + dArray<SphereTC> m_SphereTCCache; + dArray<BoxTC> m_BoxTCCache; + dArray<CapsuleTC> m_CapsuleTCCache; +}; + + +static inline +Matrix4x4 &MakeMatrix(const dVector3 Position, const dMatrix3 Rotation, Matrix4x4 &Out) +{ + return Out.Set( + Rotation[0], Rotation[4], Rotation[8], 0.0f, + Rotation[1], Rotation[5], Rotation[9], 0.0f, + Rotation[2], Rotation[6], Rotation[10],0.0f, + Position[0], Position[1], Position[2], 1.0f); +} + +static inline +Matrix4x4 &MakeMatrix(dxGeom* g, Matrix4x4 &Out) +{ + const dVector3 &position = g->buildUpdatedPosition(); + const dMatrix3 &rotation = g->buildUpdatedRotation(); + return MakeMatrix(position, rotation, Out); +} + + +#endif // #if dTRIMESH_ENABLED && dTRIMESH_OPCODE + + +#endif //_ODE_COLLISION_TRIMESH_OPCODE_H_ diff --git a/libs/ode-0.16.1/ode/src/collision_trimesh_plane.cpp b/libs/ode-0.16.1/ode/src/collision_trimesh_plane.cpp new file mode 100644 index 0000000..5c3c67a --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_trimesh_plane.cpp @@ -0,0 +1,226 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// TriMesh - Plane collider by David Walters, July 2006 + +#include <ode/collision.h> +#include <ode/rotation.h> +#include "config.h" +#include "matrix.h" +#include "odemath.h" + +#if dTRIMESH_ENABLED + +#include "collision_util.h" +#include "collision_std.h" +#include "collision_trimesh_internal.h" + + +#if dTRIMESH_OPCODE + +int dCollideTrimeshPlane( dxGeom *o1, dxGeom *o2, int flags, dContactGeom* contacts, int skip ) +{ + dIASSERT( skip >= (int)sizeof( dContactGeom ) ); + dIASSERT( o1->type == dTriMeshClass ); + dIASSERT( o2->type == dPlaneClass ); + dIASSERT ((flags & NUMC_MASK) >= 1); + + // Alias pointers to the plane and trimesh + dxTriMesh* trimesh = (dxTriMesh*)( o1 ); + dxPlane* plane = (dxPlane*)( o2 ); + + int contact_count = 0; + + // Cache the maximum contact count. + const int contact_max = ( flags & NUMC_MASK ); + + // Cache trimesh position and rotation. + const dVector3& trimesh_pos = *(const dVector3*)dGeomGetPosition( trimesh ); + const dMatrix3& trimesh_R = *(const dMatrix3*)dGeomGetRotation( trimesh ); + + // + // For all triangles. + // + + VertexPointersEx VPE; + VertexPointers &VP = VPE.vp; + ConversionArea VC; + dReal alpha; + dVector3 vertex; + +#if !defined(dSINGLE) || 1 + dVector3 int_vertex; // Intermediate vertex for double precision mode. +#endif // dSINGLE + + const unsigned uiTLSKind = trimesh->getParentSpaceTLSKind(); + dIASSERT(uiTLSKind == plane->getParentSpaceTLSKind()); // The colliding spaces must use matching cleanup method + TrimeshCollidersCache *pccColliderCache = GetTrimeshCollidersCache(uiTLSKind); + VertexUseCache &vertex_use_cache = pccColliderCache->m_VertexUses; + + // Reallocate vertex use cache if necessary + const dxTriMeshData *meshData = trimesh->retrieveMeshData(); + const int vertex_count = meshData->m_Mesh.GetNbVertices(); + const bool cache_status = vertex_use_cache.resizeAndResetVertexUSEDFlags(vertex_count); + + // Cache the triangle count. + const int tri_count = meshData->m_Mesh.GetNbTriangles(); + + // For each triangle + for ( int t = 0; t < tri_count; ++t ) + { + // Get triangle, which should also use callback. + bool ex_avail = meshData->m_Mesh.GetExTriangle( VPE, t, VC); + + // For each vertex. + for ( int v = 0; v < 3; ++v ) + { + // point already used ? + if (cache_status && ex_avail) + { + unsigned VIndex = VPE.Index[v]; + if (vertex_use_cache.getVertexUSEDFlag(VIndex)) + continue; + // mark this point as used + vertex_use_cache.setVertexUSEDFlag(VIndex); + } + + // + // Get Vertex + // + +#if defined(dSINGLE) && 0 // Always assign via intermediate array as otherwise it is an incapsulation violation + + dMultiply0_331( vertex, trimesh_R, (float*)( VP.Vertex[ v ] ) ); + +#else // dDOUBLE || 1 + + // OPCODE data is in single precision format. + int_vertex[ 0 ] = VP.Vertex[ v ]->x; + int_vertex[ 1 ] = VP.Vertex[ v ]->y; + int_vertex[ 2 ] = VP.Vertex[ v ]->z; + + dMultiply0_331( vertex, trimesh_R, int_vertex ); + +#endif // dSINGLE/dDOUBLE + + vertex[ 0 ] += trimesh_pos[ 0 ]; + vertex[ 1 ] += trimesh_pos[ 1 ]; + vertex[ 2 ] += trimesh_pos[ 2 ]; + + + // + // Collision? + // + + // If alpha < 0 then point is if front of plane. i.e. no contact + // If alpha = 0 then the point is on the plane + alpha = plane->p[ 3 ] - dCalcVectorDot3( plane->p, vertex ); + + // If alpha > 0 the point is behind the plane. CONTACT! + if ( alpha > 0 ) + { + // Alias the contact + dContactGeom* contact = SAFECONTACT( flags, contacts, contact_count, skip ); + + contact->pos[ 0 ] = vertex[ 0 ]; + contact->pos[ 1 ] = vertex[ 1 ]; + contact->pos[ 2 ] = vertex[ 2 ]; + + contact->normal[ 0 ] = plane->p[ 0 ]; + contact->normal[ 1 ] = plane->p[ 1 ]; + contact->normal[ 2 ] = plane->p[ 2 ]; + + contact->depth = alpha; + contact->g1 = trimesh; + contact->g2 = plane; + contact->side1 = t; + contact->side2 = -1; + + ++contact_count; + + // All contact slots are full? + if ( contact_count >= contact_max ) + return contact_count; // <=== STOP HERE + } + } + } + + // Return contact count. + return contact_count; +} + + +#endif // dTRIMESH_OPCODE + + +#if dTRIMESH_GIMPACT + +#include "gimpact_contact_export_helper.h" +#include "gimpact_plane_contact_accessor.h" + + +int dCollideTrimeshPlane( dxGeom *o1, dxGeom *o2, int flags, dContactGeom* contacts, int skip ) +{ + dIASSERT( skip >= (int)sizeof( dContactGeom ) ); + dIASSERT( o1->type == dTriMeshClass ); + dIASSERT( o2->type == dPlaneClass ); + dIASSERT ((flags & NUMC_MASK) >= 1); + + // Alias pointers to the plane and trimesh + dxTriMesh* trimesh = (dxTriMesh*)( o1 ); + dVector4 plane; + dGeomPlaneGetParams(o2, plane); + + o1 -> recomputeAABB(); + o2 -> recomputeAABB(); + + //Find collision + + GDYNAMIC_ARRAY collision_result; + GIM_CREATE_TRIMESHPLANE_CONTACTS(collision_result); + + gim_trimesh_plane_collisionODE(&trimesh->m_collision_trimesh,plane,&collision_result); + + if(collision_result.m_size == 0 ) + { + GIM_DYNARRAY_DESTROY(collision_result); + return 0; + } + + + vec4f * planecontact_results = GIM_DYNARRAY_POINTER(vec4f, collision_result); + unsigned int contactcount = collision_result.m_size; + + dxPlaneContactAccessor contactaccessor(planecontact_results, plane, o1, o2); + contactcount = dxGImpactContactsExportHelper::ExportMaxDepthGImpactContacts(contactaccessor, contactcount, flags, contacts, skip); + + GIM_DYNARRAY_DESTROY(collision_result); + + return (int)contactcount; +} + + +#endif // dTRIMESH_GIMPACT + + +#endif // dTRIMESH_ENABLED + diff --git a/libs/ode-0.16.1/ode/src/collision_trimesh_ray.cpp b/libs/ode-0.16.1/ode/src/collision_trimesh_ray.cpp new file mode 100644 index 0000000..866758a --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_trimesh_ray.cpp @@ -0,0 +1,207 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// TriMesh code by Erwin de Vries. + +#include <ode/collision.h> +#include <ode/rotation.h> +#include "config.h" +#include "matrix.h" +#include "odemath.h" + +#if dTRIMESH_ENABLED + +#include "collision_util.h" +#include "collision_trimesh_internal.h" + +#if dTRIMESH_OPCODE +int dCollideRTL(dxGeom* g1, dxGeom* RayGeom, int Flags, dContactGeom* Contacts, int Stride){ + dIASSERT (Stride >= (int)sizeof(dContactGeom)); + dIASSERT (g1->type == dTriMeshClass); + dIASSERT (RayGeom->type == dRayClass); + dIASSERT ((Flags & NUMC_MASK) >= 1); + + dxTriMesh* TriMesh = (dxTriMesh*)g1; + + const unsigned uiTLSKind = TriMesh->getParentSpaceTLSKind(); + dIASSERT(uiTLSKind == RayGeom->getParentSpaceTLSKind()); // The colliding spaces must use matching cleanup method + TrimeshCollidersCache *pccColliderCache = GetTrimeshCollidersCache(uiTLSKind); + RayCollider& Collider = pccColliderCache->m_RayCollider; + + dReal Length = dGeomRayGetLength(RayGeom); + + int FirstContact = dGeomRayGetFirstContact(RayGeom); + int BackfaceCull = dGeomRayGetBackfaceCull(RayGeom); + int ClosestHit = dGeomRayGetClosestHit(RayGeom); + + Collider.SetFirstContact(FirstContact != 0); + Collider.SetClosestHit(ClosestHit != 0); + Collider.SetCulling(BackfaceCull != 0); + Collider.SetMaxDist(Length); + + const dVector3& TLPosition = *(const dVector3*)dGeomGetPosition(TriMesh); + const dMatrix3& TLRotation = *(const dMatrix3*)dGeomGetRotation(TriMesh); + + Matrix4x4 MeshMatrix; + const dVector3 ZeroVector3 = { REAL(0.0), }; + MakeMatrix(ZeroVector3, TLRotation, MeshMatrix); + + dVector3 Origin, Direction; + dGeomRayGet(RayGeom, Origin, Direction); + + dVector3 OffsetOrigin; + dSubtractVectors3(OffsetOrigin, Origin, TLPosition); + + /* Make Ray */ + Ray WorldRay; + WorldRay.mOrig.Set(OffsetOrigin[0], OffsetOrigin[1], OffsetOrigin[2]); + WorldRay.mDir.Set(Direction[0], Direction[1], Direction[2]); + + /* Intersect */ + int TriCount = 0; + if (Collider.Collide(WorldRay, TriMesh->retrieveMeshBVTreeRef(), &MeshMatrix)) { + TriCount = pccColliderCache->m_Faces.GetNbFaces(); + } + + if (TriCount == 0) { + return 0; + } + + const CollisionFace* Faces = pccColliderCache->m_Faces.GetFaces(); + + int OutTriCount = 0; + for (int i = 0; i < TriCount; i++) { + if (TriMesh->m_RayCallback == null || + TriMesh->m_RayCallback(TriMesh, RayGeom, Faces[i].mFaceID, + Faces[i].mU, Faces[i].mV)) { + const int& TriIndex = Faces[i].mFaceID; + if (!TriMesh->invokeCallback(RayGeom, TriIndex)) { + continue; + } + + dContactGeom* Contact = SAFECONTACT(Flags, Contacts, OutTriCount, Stride); + + dVector3 dv[3]; + TriMesh->fetchMeshTriangle(dv, TriIndex, TLPosition, TLRotation); + + dVector3 vu; + vu[0] = dv[1][0] - dv[0][0]; + vu[1] = dv[1][1] - dv[0][1]; + vu[2] = dv[1][2] - dv[0][2]; + vu[3] = REAL(0.0); + + dVector3 vv; + vv[0] = dv[2][0] - dv[0][0]; + vv[1] = dv[2][1] - dv[0][1]; + vv[2] = dv[2][2] - dv[0][2]; + vv[3] = REAL(0.0); + + dCalcVectorCross3(Contact->normal, vv, vu); // Reversed + + // Even though all triangles might be initially valid, + // a triangle may degenerate into a segment after applying + // space transformation. + if (dSafeNormalize3(Contact->normal)) + { + // No sense to save on single type conversion in algorithm of this size. + // If there would be a custom typedef for distance type it could be used + // instead of dReal. However using float directly is the loss of abstraction + // and possible loss of precision in future. + /*float*/ dReal T = Faces[i].mDistance; + Contact->pos[0] = Origin[0] + (Direction[0] * T); + Contact->pos[1] = Origin[1] + (Direction[1] * T); + Contact->pos[2] = Origin[2] + (Direction[2] * T); + Contact->pos[3] = REAL(0.0); + + Contact->depth = T; + Contact->g1 = TriMesh; + Contact->g2 = RayGeom; + Contact->side1 = TriIndex; + Contact->side2 = -1; + + OutTriCount++; + + // Putting "break" at the end of loop prevents unnecessary checks on first pass and "continue" + if (OutTriCount >= (Flags & NUMC_MASK)) { + break; + } + } + } + } + return OutTriCount; +} +#endif // dTRIMESH_OPCODE + +#if dTRIMESH_GIMPACT +int dCollideRTL(dxGeom* g1, dxGeom* RayGeom, int Flags, dContactGeom* Contacts, int Stride) +{ + dIASSERT (Stride >= (int)sizeof(dContactGeom)); + dIASSERT (g1->type == dTriMeshClass); + dIASSERT (RayGeom->type == dRayClass); + dIASSERT ((Flags & NUMC_MASK) >= 1); + + dxTriMesh* TriMesh = (dxTriMesh*)g1; + + dReal Length = dGeomRayGetLength(RayGeom); + int FirstContact = dGeomRayGetFirstContact(RayGeom); + int BackfaceCull = dGeomRayGetBackfaceCull(RayGeom); + int ClosestHit = dGeomRayGetClosestHit(RayGeom); + dVector3 Origin, Direction; + dGeomRayGet(RayGeom, Origin, Direction); + + char intersect=0; + GIM_TRIANGLE_RAY_CONTACT_DATA contact_data; + + if(ClosestHit) + { + intersect = gim_trimesh_ray_closest_collisionODE(&TriMesh->m_collision_trimesh,Origin,Direction,Length,&contact_data); + } + else + { + intersect = gim_trimesh_ray_collisionODE(&TriMesh->m_collision_trimesh,Origin,Direction,Length,&contact_data); + } + + if(intersect == 0) + { + return 0; + } + + + if(!TriMesh->m_RayCallback || + TriMesh->m_RayCallback(TriMesh, RayGeom, contact_data.m_face_id, contact_data.u , contact_data.v)) + { + dContactGeom* Contact = &( Contacts[ 0 ] ); + VEC_COPY(Contact->pos,contact_data.m_point); + VEC_COPY(Contact->normal,contact_data.m_normal); + Contact->depth = contact_data.tparam; + Contact->g1 = TriMesh; + Contact->g2 = RayGeom; + Contact->side1 = contact_data.m_face_id; + Contact->side2 = -1; + return 1; + } + + return 0; +} +#endif // dTRIMESH_GIMPACT + +#endif // dTRIMESH_ENABLED diff --git a/libs/ode-0.16.1/ode/src/collision_trimesh_sphere.cpp b/libs/ode-0.16.1/ode/src/collision_trimesh_sphere.cpp new file mode 100644 index 0000000..8076411 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_trimesh_sphere.cpp @@ -0,0 +1,596 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// TriMesh code by Erwin de Vries. + +#include <ode/collision.h> +#include <ode/rotation.h> +#include "config.h" +#include "matrix.h" +#include "odemath.h" +#include "collision_util.h" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +#if dTRIMESH_ENABLED + +#include "collision_trimesh_internal.h" + + +#if dTRIMESH_OPCODE + +// Ripped from Opcode 1.1. +static bool GetContactData(const dVector3& Center, dReal Radius, const dVector3 Origin, const dVector3 Edge0, const dVector3 Edge1, dReal& Dist, dReal& u, dReal& v){ + + // now onto the bulk of the collision... + + dVector3 Diff; + Diff[0] = Origin[0] - Center[0]; + Diff[1] = Origin[1] - Center[1]; + Diff[2] = Origin[2] - Center[2]; + Diff[3] = Origin[3] - Center[3]; + + dReal A00 = dCalcVectorDot3(Edge0, Edge0); + dReal A01 = dCalcVectorDot3(Edge0, Edge1); + dReal A11 = dCalcVectorDot3(Edge1, Edge1); + + dReal B0 = dCalcVectorDot3(Diff, Edge0); + dReal B1 = dCalcVectorDot3(Diff, Edge1); + + dReal C = dCalcVectorDot3(Diff, Diff); + + dReal Det = dFabs(A00 * A11 - A01 * A01); + u = A01 * B1 - A11 * B0; + v = A01 * B0 - A00 * B1; + + dReal DistSq; + + if (u + v <= Det){ + if(u < REAL(0.0)){ + if(v < REAL(0.0)){ // region 4 + if(B0 < REAL(0.0)){ + v = REAL(0.0); + if (-B0 >= A00){ + u = REAL(1.0); + DistSq = A00 + REAL(2.0) * B0 + C; + } + else{ + u = -B0 / A00; + DistSq = B0 * u + C; + } + } + else{ + u = REAL(0.0); + if(B1 >= REAL(0.0)){ + v = REAL(0.0); + DistSq = C; + } + else if(-B1 >= A11){ + v = REAL(1.0); + DistSq = A11 + REAL(2.0) * B1 + C; + } + else{ + v = -B1 / A11; + DistSq = B1 * v + C; + } + } + } + else{ // region 3 + u = REAL(0.0); + if(B1 >= REAL(0.0)){ + v = REAL(0.0); + DistSq = C; + } + else if(-B1 >= A11){ + v = REAL(1.0); + DistSq = A11 + REAL(2.0) * B1 + C; + } + else{ + v = -B1 / A11; + DistSq = B1 * v + C; + } + } + } + else if(v < REAL(0.0)){ // region 5 + v = REAL(0.0); + if (B0 >= REAL(0.0)){ + u = REAL(0.0); + DistSq = C; + } + else if (-B0 >= A00){ + u = REAL(1.0); + DistSq = A00 + REAL(2.0) * B0 + C; + } + else{ + u = -B0 / A00; + DistSq = B0 * u + C; + } + } + else{ // region 0 + // minimum at interior point + if (Det == REAL(0.0)){ + u = REAL(0.0); + v = REAL(0.0); + DistSq = FLT_MAX; + } + else{ + dReal InvDet = REAL(1.0) / Det; + u *= InvDet; + v *= InvDet; + DistSq = u * (A00 * u + A01 * v + REAL(2.0) * B0) + v * (A01 * u + A11 * v + REAL(2.0) * B1) + C; + } + } + } + else{ + dReal Tmp0, Tmp1, Numer, Denom; + + if(u < REAL(0.0)){ // region 2 + Tmp0 = A01 + B0; + Tmp1 = A11 + B1; + if (Tmp1 > Tmp0){ + Numer = Tmp1 - Tmp0; + Denom = A00 - REAL(2.0) * A01 + A11; + if (Numer >= Denom){ + u = REAL(1.0); + v = REAL(0.0); + DistSq = A00 + REAL(2.0) * B0 + C; + } + else{ + u = Numer / Denom; + v = REAL(1.0) - u; + DistSq = u * (A00 * u + A01 * v + REAL(2.0) * B0) + v * (A01 * u + A11 * v + REAL(2.0) * B1) + C; + } + } + else{ + u = REAL(0.0); + if(Tmp1 <= REAL(0.0)){ + v = REAL(1.0); + DistSq = A11 + REAL(2.0) * B1 + C; + } + else if(B1 >= REAL(0.0)){ + v = REAL(0.0); + DistSq = C; + } + else{ + v = -B1 / A11; + DistSq = B1 * v + C; + } + } + } + else if(v < REAL(0.0)){ // region 6 + Tmp0 = A01 + B1; + Tmp1 = A00 + B0; + if (Tmp1 > Tmp0){ + Numer = Tmp1 - Tmp0; + Denom = A00 - REAL(2.0) * A01 + A11; + if (Numer >= Denom){ + v = REAL(1.0); + u = REAL(0.0); + DistSq = A11 + REAL(2.0) * B1 + C; + } + else{ + v = Numer / Denom; + u = REAL(1.0) - v; + DistSq = u * (A00 * u + A01 * v + REAL(2.0) * B0) + v * (A01 * u + A11 * v + REAL(2.0) * B1) + C; + } + } + else{ + v = REAL(0.0); + if (Tmp1 <= REAL(0.0)){ + u = REAL(1.0); + DistSq = A00 + REAL(2.0) * B0 + C; + } + else if(B0 >= REAL(0.0)){ + u = REAL(0.0); + DistSq = C; + } + else{ + u = -B0 / A00; + DistSq = B0 * u + C; + } + } + } + else{ // region 1 + Numer = A11 + B1 - A01 - B0; + if (Numer <= REAL(0.0)){ + u = REAL(0.0); + v = REAL(1.0); + DistSq = A11 + REAL(2.0) * B1 + C; + } + else{ + Denom = A00 - REAL(2.0) * A01 + A11; + if (Numer >= Denom){ + u = REAL(1.0); + v = REAL(0.0); + DistSq = A00 + REAL(2.0) * B0 + C; + } + else{ + u = Numer / Denom; + v = REAL(1.0) - u; + DistSq = u * (A00 * u + A01 * v + REAL(2.0) * B0) + v * (A01 * u + A11 * v + REAL(2.0) * B1) + C; + } + } + } + } + + Dist = dSqrt(dFabs(DistSq)); + + if (Dist <= Radius){ + Dist = Radius - Dist; + return true; + } + else return false; +} + +int dCollideSTL(dxGeom* g1, dxGeom* SphereGeom, int Flags, dContactGeom* Contacts, int Stride){ + dIASSERT (Stride >= (int)sizeof(dContactGeom)); + dIASSERT (g1->type == dTriMeshClass); + dIASSERT (SphereGeom->type == dSphereClass); + dIASSERT ((Flags & NUMC_MASK) >= 1); + + dxTriMesh* TriMesh = (dxTriMesh*)g1; + + const unsigned uiTLSKind = TriMesh->getParentSpaceTLSKind(); + dIASSERT(uiTLSKind == SphereGeom->getParentSpaceTLSKind()); // The colliding spaces must use matching cleanup method + TrimeshCollidersCache *pccColliderCache = GetTrimeshCollidersCache(uiTLSKind); + SphereCollider& Collider = pccColliderCache->m_SphereCollider; + + const dVector3& TLPosition = *(const dVector3*)dGeomGetPosition(TriMesh); + const dMatrix3& TLRotation = *(const dMatrix3*)dGeomGetRotation(TriMesh); + + Matrix4x4 MeshMatrix; + const dVector3 ZeroVector3 = { REAL(0.0), }; + MakeMatrix(ZeroVector3, TLRotation, MeshMatrix); + + const dVector3& Position = *(const dVector3*)dGeomGetPosition(SphereGeom); + dReal Radius = dGeomSphereGetRadius(SphereGeom); + + dVector3 OffsetPosition; + dSubtractVectors3(OffsetPosition, Position, TLPosition); + + // Sphere + Sphere Sphere; + Sphere.mCenter.Set(OffsetPosition[0], OffsetPosition[1], OffsetPosition[2]); + Sphere.mRadius = Radius; + + + // TC results + if (TriMesh->getDoTC(dxTriMesh::TTC_SPHERE)) { + dxTriMesh::SphereTC* sphereTC = 0; + const int sphereCacheSize = TriMesh->m_SphereTCCache.size(); + for (int i = 0; i != sphereCacheSize; i++){ + if (TriMesh->m_SphereTCCache[i].Geom == SphereGeom){ + sphereTC = &TriMesh->m_SphereTCCache[i]; + break; + } + } + + if (!sphereTC) { + TriMesh->m_SphereTCCache.push(dxTriMesh::SphereTC()); + + sphereTC = &TriMesh->m_SphereTCCache[TriMesh->m_SphereTCCache.size() - 1]; + sphereTC->Geom = SphereGeom; + } + + // Intersect + Collider.SetTemporalCoherence(true); + Collider.Collide(*sphereTC, Sphere, TriMesh->retrieveMeshBVTreeRef(), null, &MeshMatrix); + } + else { + Collider.SetTemporalCoherence(false); + Collider.Collide(pccColliderCache->m_DefaultSphereCache, Sphere, TriMesh->retrieveMeshBVTreeRef(), null, &MeshMatrix); + } + + if (! Collider.GetContactStatus()) { + // no collision occurred + return 0; + } + + // get results + int TriCount = Collider.GetNbTouchedPrimitives(); + const int* Triangles = (const int*)Collider.GetTouchedPrimitives(); + + if (TriCount != 0){ + if (TriMesh->m_ArrayCallback != null){ + TriMesh->m_ArrayCallback(TriMesh, SphereGeom, Triangles, TriCount); + } + + int OutTriCount = 0; + for (int i = 0; i < TriCount; i++){ + if (OutTriCount == (Flags & NUMC_MASK)){ + break; + } + + const int TriIndex = Triangles[i]; + + dVector3 dv[3]; + if (!TriMesh->invokeCallback(SphereGeom, TriIndex)) + continue; + + TriMesh->fetchMeshTriangle(dv, TriIndex, TLPosition, TLRotation); + + dVector3& v0 = dv[0]; + dVector3& v1 = dv[1]; + dVector3& v2 = dv[2]; + + dVector3 vu; + vu[0] = v1[0] - v0[0]; + vu[1] = v1[1] - v0[1]; + vu[2] = v1[2] - v0[2]; + vu[3] = REAL(0.0); + + dVector3 vv; + vv[0] = v2[0] - v0[0]; + vv[1] = v2[1] - v0[1]; + vv[2] = v2[2] - v0[2]; + vv[3] = REAL(0.0); + + // Get plane coefficients + dVector4 Plane; + dCalcVectorCross3(Plane, vu, vv); + + // Even though all triangles might be initially valid, + // a triangle may degenerate into a segment after applying + // space transformation. + if (!dSafeNormalize3(Plane)) { + continue; + } + + /* If the center of the sphere is within the positive halfspace of the + * triangle's plane, allow a contact to be generated. + * If the center of the sphere made it into the positive halfspace of a + * back-facing triangle, then the physics update and/or velocity needs + * to be adjusted (penetration has occured anyway). + */ + + dReal side = dCalcVectorDot3(Plane,Position) - dCalcVectorDot3(Plane, v0); + + if(side < REAL(0.0)) { + continue; + } + + dReal Depth; + dReal u, v; + if (!GetContactData(Position, Radius, v0, vu, vv, Depth, u, v)){ + continue; // Sphere doesn't hit triangle + } + + if (Depth < REAL(0.0)){ + continue; // Negative depth does not produce a contact + } + + dVector3 ContactPos; + + dReal w = REAL(1.0) - u - v; + ContactPos[0] = (v0[0] * w) + (v1[0] * u) + (v2[0] * v); + ContactPos[1] = (v0[1] * w) + (v1[1] * u) + (v2[1] * v); + ContactPos[2] = (v0[2] * w) + (v1[2] * u) + (v2[2] * v); + + // Depth returned from GetContactData is depth along + // contact point - sphere center direction + // we'll project it to contact normal + dVector3 dir; + dir[0] = Position[0]-ContactPos[0]; + dir[1] = Position[1]-ContactPos[1]; + dir[2] = Position[2]-ContactPos[2]; + dReal dirProj = dCalcVectorDot3(dir, Plane) / dSqrt(dCalcVectorDot3(dir, dir)); + + // Since Depth already had a requirement to be non-negative, + // negative direction projections should not be allowed as well, + // as otherwise the multiplication will result in negative contact depth. + if (dirProj < REAL(0.0)){ + continue; // Zero contact depth could be ignored + } + + dContactGeom* Contact = SAFECONTACT(Flags, Contacts, OutTriCount, Stride); + + Contact->pos[0] = ContactPos[0]; + Contact->pos[1] = ContactPos[1]; + Contact->pos[2] = ContactPos[2]; + Contact->pos[3] = REAL(0.0); + + // Using normal as plane (reversed) + Contact->normal[0] = -Plane[0]; + Contact->normal[1] = -Plane[1]; + Contact->normal[2] = -Plane[2]; + Contact->normal[3] = REAL(0.0); + + Contact->depth = Depth * dirProj; + //Contact->depth = Radius - side; // (mg) penetration depth is distance along normal not shortest distance + + // We need to set these unconditionally, as the merging may fail! - Bram + Contact->g1 = TriMesh; + Contact->g2 = SphereGeom; + Contact->side2 = -1; + + Contact->side1 = TriIndex; + + OutTriCount++; + } + if (OutTriCount > 0){ + if (TriMesh->m_SphereContactsMergeOption == MERGE_CONTACTS_FULLY) { + dContactGeom* Contact = SAFECONTACT(Flags, Contacts, 0, Stride); + Contact->g1 = TriMesh; + Contact->g2 = SphereGeom; + Contact->side2 = -1; + + if (OutTriCount > 1 && !(Flags & CONTACTS_UNIMPORTANT)){ + dVector3 pos; + pos[0] = Contact->pos[0]; + pos[1] = Contact->pos[1]; + pos[2] = Contact->pos[2]; + + dVector3 normal; + normal[0] = Contact->normal[0] * Contact->depth; + normal[1] = Contact->normal[1] * Contact->depth; + normal[2] = Contact->normal[2] * Contact->depth; + normal[3] = REAL(0.0); + + int TriIndex = Contact->side1; + + for (int i = 1; i < OutTriCount; i++){ + dContactGeom* TempContact = SAFECONTACT(Flags, Contacts, i, Stride); + + pos[0] += TempContact->pos[0]; + pos[1] += TempContact->pos[1]; + pos[2] += TempContact->pos[2]; + + normal[0] += TempContact->normal[0] * TempContact->depth; + normal[1] += TempContact->normal[1] * TempContact->depth; + normal[2] += TempContact->normal[2] * TempContact->depth; + + TriIndex = (TriMesh->m_TriMergeCallback) ? TriMesh->m_TriMergeCallback(TriMesh, TriIndex, TempContact->side1) : -1; + } + + Contact->side1 = TriIndex; + + Contact->pos[0] = pos[0] / OutTriCount; + Contact->pos[1] = pos[1] / OutTriCount; + Contact->pos[2] = pos[2] / OutTriCount; + + if ( !dSafeNormalize3(normal) ) + return OutTriCount; // Cannot merge in this pathological case + + // Using a merged normal, means that for each intersection, this new normal will be less effective in solving the intersection. + // That is why we need to correct this by increasing the depth for each intersection. + // The maximum of the adjusted depths is our newly merged depth value - Bram. + + dReal mergedDepth = REAL(0.0); + dReal minEffectiveness = REAL(0.5); + for ( int i = 0; i < OutTriCount; ++i ) + { + dContactGeom* TempContact = SAFECONTACT(Flags, Contacts, i, Stride); + dReal effectiveness = dCalcVectorDot3(normal, TempContact->normal); + if ( effectiveness < dEpsilon ) + return OutTriCount; // Cannot merge this pathological case + // Cap our adjustment for the new normal to a factor 2, meaning a 60 deg change in normal. + effectiveness = ( effectiveness < minEffectiveness ) ? minEffectiveness : effectiveness; + dReal adjusted = TempContact->depth / effectiveness; + mergedDepth = ( mergedDepth < adjusted ) ? adjusted : mergedDepth; + } + Contact->depth = mergedDepth; + Contact->normal[0] = normal[0]; + Contact->normal[1] = normal[1]; + Contact->normal[2] = normal[2]; + Contact->normal[3] = normal[3]; + } + + return 1; + } + else if (TriMesh->m_SphereContactsMergeOption == MERGE_CONTACT_NORMALS) { + if (OutTriCount != 1 && !(Flags & CONTACTS_UNIMPORTANT)){ + dVector3 Normal; + + dContactGeom* FirstContact = SAFECONTACT(Flags, Contacts, 0, Stride); + Normal[0] = FirstContact->normal[0] * FirstContact->depth; + Normal[1] = FirstContact->normal[1] * FirstContact->depth; + Normal[2] = FirstContact->normal[2] * FirstContact->depth; + Normal[3] = FirstContact->normal[3] * FirstContact->depth; + + for (int i = 1; i < OutTriCount; i++){ + dContactGeom* Contact = SAFECONTACT(Flags, Contacts, i, Stride); + + Normal[0] += Contact->normal[0] * Contact->depth; + Normal[1] += Contact->normal[1] * Contact->depth; + Normal[2] += Contact->normal[2] * Contact->depth; + Normal[3] += Contact->normal[3] * Contact->depth; + } + + dNormalize3(Normal); + + for (int i = 0; i < OutTriCount; i++){ + dContactGeom* Contact = SAFECONTACT(Flags, Contacts, i, Stride); + + Contact->normal[0] = Normal[0]; + Contact->normal[1] = Normal[1]; + Contact->normal[2] = Normal[2]; + Contact->normal[3] = Normal[3]; + } + } + + return OutTriCount; + } + else { + dIASSERT(TriMesh->m_SphereContactsMergeOption == DONT_MERGE_CONTACTS); + return OutTriCount; + } + } + else return 0; + } + else return 0; +} + + +#endif // dTRIMESH_OPCODE + + +#if dTRIMESH_GIMPACT + +#include "gimpact_contact_export_helper.h" +#include "gimpact_gim_contact_accessor.h" + + +int dCollideSTL(dxGeom* g1, dxGeom* SphereGeom, int Flags, dContactGeom* Contacts, int Stride) +{ + dIASSERT (Stride >= (int)sizeof(dContactGeom)); + dIASSERT (g1->type == dTriMeshClass); + dIASSERT (SphereGeom->type == dSphereClass); + dIASSERT ((Flags & NUMC_MASK) >= 1); + + dxTriMesh* TriMesh = (dxTriMesh*)g1; + dVector3& Position = *(dVector3*)dGeomGetPosition(SphereGeom); + dReal Radius = dGeomSphereGetRadius(SphereGeom); + //Create contact list + GDYNAMIC_ARRAY trimeshcontacts; + GIM_CREATE_CONTACT_LIST(trimeshcontacts); + + g1 -> recomputeAABB(); + SphereGeom -> recomputeAABB(); + + //Collide trimeshes + gim_trimesh_sphere_collisionODE(&TriMesh->m_collision_trimesh,Position,Radius,&trimeshcontacts); + + if(trimeshcontacts.m_size == 0) + { + GIM_DYNARRAY_DESTROY(trimeshcontacts); + return 0; + } + + GIM_CONTACT * ptrimeshcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,trimeshcontacts); + unsigned contactcount = trimeshcontacts.m_size; + + dxGIMCContactAccessor contactaccessor(ptrimeshcontacts, g1, SphereGeom, -1); + contactcount = dxGImpactContactsExportHelper::ExportMaxDepthGImpactContacts(contactaccessor, contactcount, Flags, Contacts, Stride); + + GIM_DYNARRAY_DESTROY(trimeshcontacts); + + return (int)contactcount; +} + + +#endif // dTRIMESH_GIMPACT + + +#endif // dTRIMESH_ENABLED diff --git a/libs/ode-0.16.1/ode/src/collision_trimesh_trimesh.cpp b/libs/ode-0.16.1/ode/src/collision_trimesh_trimesh.cpp new file mode 100644 index 0000000..27c90bc --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_trimesh_trimesh.cpp @@ -0,0 +1,1367 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// OPCODE TriMesh/TriMesh collision code +// Written at 2006-10-28 by Francisco León (http://gimpact.sourceforge.net) + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + +#include <ode/collision.h> +#include <ode/rotation.h> +#include "config.h" +#include "matrix.h" +#include "odemath.h" + + +#if dTRIMESH_ENABLED + +#include "collision_util.h" +#include "collision_trimesh_internal.h" + + +#if !dTLS_ENABLED +// Have collider cache instance unconditionally of OPCODE or GIMPACT selection +/*extern */TrimeshCollidersCache g_ccTrimeshCollidersCache; +#endif + + +#if dTRIMESH_OPCODE + +// New Implementation +#if !dTRIMESH_OPCODE_USE_OLD_TRIMESH_TRIMESH_COLLIDER + +#define SMALL_ELT REAL(2.5e-4) +#define EXPANDED_ELT_THRESH REAL(1.0e-3) +#define DISTANCE_EPSILON REAL(1.0e-8) +#define VELOCITY_EPSILON REAL(1.0e-5) +#define TINY_PENETRATION REAL(5.0e-6) + +struct LineContactSet +{ + enum + { + MAX_POINTS = 8 + }; + + dVector3 Points[MAX_POINTS]; + int Count; +}; + + +// static void GetTriangleGeometryCallback(udword, VertexPointers&, udword); -- not used +static inline void dMakeMatrix4(const dVector3 Position, const dMatrix3 Rotation, dMatrix4 &B); +//static void dInvertMatrix4( dMatrix4& B, dMatrix4& Binv ); +//static int IntersectLineSegmentRay(dVector3, dVector3, dVector3, dVector3, dVector3); +static void ClipConvexPolygonAgainstPlane( const dVector3, dReal, LineContactSet& ); + + +///returns the penetration depth +static dReal MostDeepPoints( + LineContactSet & points, + const dVector3 plane_normal, + dReal plane_dist, + LineContactSet & deep_points); + +static bool TriTriContacts(const dVector3 tr1[3], + const dVector3 tr2[3], + int TriIndex1, int TriIndex2, + dxGeom* g1, dxGeom* g2, int Flags, + CONTACT_KEY_HASH_TABLE &hashcontactset, + dContactGeom* Contacts, int Stride, + int &contactcount); + + +/* some math macros */ +#define IS_ZERO(v) (!(v)[0] && !(v)[1] && !(v)[2]) + +#define CROSS(dest,v1,v2) dCalcVectorCross3(dest, v1, v2) + +#define DOT(v1,v2) dCalcVectorDot3(v1, v2) + +#define SUB(dest,v1,v2) dSubtractVectors3(dest, v1, v2) + +#define ADD(dest,v1,v2) dAddVectors3(dest, v1, v2) + +#define MULT(dest,v,factor) dCopyScaledVector3(dest, v, factor) + +#define SET(dest,src) dCopyVector3(dest, src) + +#define SMULT(p,q,s) dCopyScaledVector3(p, q, s) + +#define COMBO(combo,p,t,q) dAddVectorScaledVector3(combo, p, q, t) + +#define LENGTH(x) dCalcVectorLength3(x) + +#define DEPTH(d, p, q, n) d = dCalcPointDepth3(q, p, n) + + +static inline +void SwapNormals(dVector3 *&pen_v, dVector3 *&col_v, dVector3* v1, dVector3* v2, + dVector3 *&pen_elt, dVector3 *elt_f1, dVector3 *elt_f2, + dVector3 n, dVector3 n1, dVector3 n2) +{ + if (pen_v == v1) { + pen_v = v2; + pen_elt = elt_f2; + col_v = v1; + SET(n, n1); + } + else { + pen_v = v1; + pen_elt = elt_f1; + col_v = v2; + SET(n, n2); + } +} + +///////////////////////MECHANISM FOR AVOID CONTACT REDUNDANCE/////////////////////////////// +////* Written by Francisco León (http://gimpact.sourceforge.net) */// +#define CONTACT_DIFF_EPSILON REAL(0.00001) +#if defined(dDOUBLE) +#define CONTACT_NORMAL_ZERO REAL(0.0000001) +#else // if defined(dSINGLE) +#define CONTACT_NORMAL_ZERO REAL(0.00001) +#endif +#define CONTACT_POS_HASH_QUOTIENT REAL(10000.0) +#define dSQRT3 REAL(1.7320508075688773) + +static +void UpdateContactKey(CONTACT_KEY & key, dContactGeom * contact) +{ + key.m_contact = contact; + + unsigned int hash=0; + + int i = 0; + + while (true) + { + dReal coord = contact->pos[i]; + coord = dFloor(coord * CONTACT_POS_HASH_QUOTIENT); + + const int sz = sizeof(coord) / sizeof(unsigned); + dIASSERT(sizeof(coord) % sizeof(unsigned) == 0); + + unsigned hash_v[ sz ]; + memcpy(hash_v, &coord, sizeof(coord)); + + unsigned int hash_input = hash_v[0]; + for (int i=1; i<sz; ++i) + hash_input ^= hash_v[i]; + + hash = (( hash << 4 ) + (hash_input >> 24)) ^ ( hash >> 28 ); + hash = (( hash << 4 ) + ((hash_input >> 16) & 0xFF)) ^ ( hash >> 28 ); + hash = (( hash << 4 ) + ((hash_input >> 8) & 0xFF)) ^ ( hash >> 28 ); + hash = (( hash << 4 ) + (hash_input & 0xFF)) ^ ( hash >> 28 ); + + if (++i == 3) + { + break; + } + + hash = (hash << 11) | (hash >> 21); + } + + key.m_key = hash; +} + + +static inline +unsigned int MakeContactIndex(unsigned int key) +{ + dIASSERT(CONTACTS_HASHSIZE == 256); + + unsigned int index = key ^ (key >> 16); + index = (index ^ (index >> 8)) & 0xFF; + + return index; +} + +static +dContactGeom *AddContactToNode(const CONTACT_KEY * contactkey,CONTACT_KEY_HASH_NODE * node) +{ + for(int i=0;i<node->m_keycount;i++) + { + if(node->m_keyarray[i].m_key == contactkey->m_key) + { + dContactGeom *contactfound = node->m_keyarray[i].m_contact; + if (dCalcPointsDistance3(contactfound->pos, contactkey->m_contact->pos) < REAL(1.00001) /*for comp. errors*/ * dSQRT3 / CONTACT_POS_HASH_QUOTIENT /*cube diagonal*/) + { + return contactfound; + } + } + } + + if (node->m_keycount < MAXCONTACT_X_NODE) + { + node->m_keyarray[node->m_keycount].m_contact = contactkey->m_contact; + node->m_keyarray[node->m_keycount].m_key = contactkey->m_key; + node->m_keycount++; + } + else + { + dDEBUGMSG("Trimesh-trimesh contach hash table bucket overflow - close contacts might not be culled"); + } + + return contactkey->m_contact; +} + +static +void RemoveNewContactFromNode(const CONTACT_KEY * contactkey, CONTACT_KEY_HASH_NODE * node) +{ + dIASSERT(node->m_keycount > 0); + + if (node->m_keyarray[node->m_keycount - 1].m_contact == contactkey->m_contact) + { + node->m_keycount -= 1; + } + else + { + dIASSERT(node->m_keycount == MAXCONTACT_X_NODE); + } +} + +static +void RemoveArbitraryContactFromNode(const CONTACT_KEY *contactkey, CONTACT_KEY_HASH_NODE *node) +{ + dIASSERT(node->m_keycount > 0); + + int keyindex, lastkeyindex = node->m_keycount - 1; + + // Do not check the last contact + for (keyindex = 0; keyindex < lastkeyindex; keyindex++) + { + if (node->m_keyarray[keyindex].m_contact == contactkey->m_contact) + { + node->m_keyarray[keyindex] = node->m_keyarray[lastkeyindex]; + break; + } + } + + dIASSERT(keyindex < lastkeyindex || + node->m_keyarray[keyindex].m_contact == contactkey->m_contact); // It has been either the break from loop or last element should match + + node->m_keycount = lastkeyindex; +} + +static +void UpdateArbitraryContactInNode(const CONTACT_KEY *contactkey, CONTACT_KEY_HASH_NODE *node, + dContactGeom *pwithcontact) +{ + dIASSERT(node->m_keycount > 0); + + int keyindex, lastkeyindex = node->m_keycount - 1; + + // Do not check the last contact + for (keyindex = 0; keyindex < lastkeyindex; keyindex++) + { + if (node->m_keyarray[keyindex].m_contact == contactkey->m_contact) + { + break; + } + } + + dIASSERT(keyindex < lastkeyindex || + node->m_keyarray[keyindex].m_contact == contactkey->m_contact); // It has been either the break from loop or last element should match + + node->m_keyarray[keyindex].m_contact = pwithcontact; +} + +static +void ClearContactSet(CONTACT_KEY_HASH_TABLE &hashcontactset) +{ + memset(&hashcontactset, 0, sizeof(CONTACT_KEY_HASH_TABLE)); +} + +//return true if found +static +dContactGeom *InsertContactInSet(CONTACT_KEY_HASH_TABLE &hashcontactset, const CONTACT_KEY &newkey) +{ + unsigned int index = MakeContactIndex(newkey.m_key); + + return AddContactToNode(&newkey, &hashcontactset[index]); +} + +static +void RemoveNewContactFromSet(CONTACT_KEY_HASH_TABLE &hashcontactset, const CONTACT_KEY &contactkey) +{ + unsigned int index = MakeContactIndex(contactkey.m_key); + + RemoveNewContactFromNode(&contactkey, &hashcontactset[index]); +} + +static +void RemoveArbitraryContactFromSet(CONTACT_KEY_HASH_TABLE &hashcontactset, const CONTACT_KEY &contactkey) +{ + unsigned int index = MakeContactIndex(contactkey.m_key); + + RemoveArbitraryContactFromNode(&contactkey, &hashcontactset[index]); +} + +static +void UpdateArbitraryContactInSet(CONTACT_KEY_HASH_TABLE &hashcontactset, const CONTACT_KEY &contactkey, + dContactGeom *pwithcontact) +{ + unsigned int index = MakeContactIndex(contactkey.m_key); + + UpdateArbitraryContactInNode(&contactkey, &hashcontactset[index], pwithcontact); +} + +static +bool AllocNewContact( + const dVector3 newpoint, dContactGeom *& out_pcontact, + int Flags, CONTACT_KEY_HASH_TABLE &hashcontactset, + dContactGeom* Contacts, int Stride, int &contactcount) +{ + bool allocated_new = false; + + dContactGeom dLocalContact; + + dContactGeom * pcontact = contactcount != (Flags & NUMC_MASK) ? + SAFECONTACT(Flags, Contacts, contactcount, Stride) : &dLocalContact; + + pcontact->pos[0] = newpoint[0]; + pcontact->pos[1] = newpoint[1]; + pcontact->pos[2] = newpoint[2]; + pcontact->pos[3] = 1.0f; + + CONTACT_KEY newkey; + UpdateContactKey(newkey, pcontact); + + dContactGeom *pcontactfound = InsertContactInSet(hashcontactset, newkey); + if (pcontactfound == pcontact) + { + if (pcontactfound != &dLocalContact) + { + contactcount++; + } + else + { + RemoveNewContactFromSet(hashcontactset, newkey); + pcontactfound = NULL; + } + + allocated_new = true; + } + + out_pcontact = pcontactfound; + return allocated_new; +} + +static +void FreeExistingContact(dContactGeom *pcontact, + int Flags, CONTACT_KEY_HASH_TABLE &hashcontactset, + dContactGeom *Contacts, int Stride, int &contactcount) +{ + CONTACT_KEY contactKey; + UpdateContactKey(contactKey, pcontact); + + RemoveArbitraryContactFromSet(hashcontactset, contactKey); + + int lastContactIndex = contactcount - 1; + dContactGeom *plastContact = SAFECONTACT(Flags, Contacts, lastContactIndex, Stride); + + if (pcontact != plastContact) + { + *pcontact = *plastContact; + + CONTACT_KEY lastContactKey; + UpdateContactKey(lastContactKey, plastContact); + + UpdateArbitraryContactInSet(hashcontactset, lastContactKey, pcontact); + } + + contactcount = lastContactIndex; +} + + +static +dContactGeom * PushNewContact( dxGeom* g1, dxGeom* g2, int TriIndex1, int TriIndex2, + const dVector3 point, + dVector3 normal, + dReal depth, + int Flags, + CONTACT_KEY_HASH_TABLE &hashcontactset, + dContactGeom* Contacts, int Stride, + int &contactcount) +{ + dIASSERT(dFabs(dVector3Length((const dVector3 &)(*normal)) - REAL(1.0)) < REAL(1e-6)); // This assumption is used in the code + + dContactGeom * pcontact; + + if (!AllocNewContact(point, pcontact, Flags, hashcontactset, Contacts, Stride, contactcount)) + { + const dReal depthDifference = depth - pcontact->depth; + + if (depthDifference > CONTACT_DIFF_EPSILON) + { + pcontact->normal[0] = normal[0]; + pcontact->normal[1] = normal[1]; + pcontact->normal[2] = normal[2]; + pcontact->normal[3] = REAL(1.0); // used to store length of vector sum for averaging + pcontact->depth = depth; + + pcontact->g1 = g1; + pcontact->g2 = g2; + pcontact->side1 = TriIndex1; + pcontact->side2 = TriIndex2; + } + else if (depthDifference >= -CONTACT_DIFF_EPSILON) ///average + { + if(pcontact->g1 == g2) + { + MULT(normal,normal, REAL(-1.0)); + int tempInt = TriIndex1; TriIndex1 = TriIndex2; TriIndex2 = tempInt; + // This should be discarded by optimizer as g1 and g2 are + // not used any more but it's preferable to keep this line for + // the sake of consistency in variable values. + dxGeom *tempGeom = g1; g1 = g2; g2 = tempGeom; + } + + const dReal oldLen = pcontact->normal[3]; + COMBO(pcontact->normal, normal, oldLen, pcontact->normal); + + const dReal len = LENGTH(pcontact->normal); + if (len > CONTACT_NORMAL_ZERO) + { + MULT(pcontact->normal, pcontact->normal, REAL(1.0) / len); + pcontact->normal[3] = len; + + pcontact->side1 = ((dxTriMesh *)pcontact->g1)->m_TriMergeCallback ? ((dxTriMesh *)pcontact->g1)->m_TriMergeCallback((dxTriMesh *)pcontact->g1, pcontact->side1, TriIndex1) : -1; + pcontact->side2 = ((dxTriMesh *)pcontact->g2)->m_TriMergeCallback ? ((dxTriMesh *)pcontact->g2)->m_TriMergeCallback((dxTriMesh *)pcontact->g2, pcontact->side2, TriIndex2) : -1; + } + else + { + FreeExistingContact(pcontact, Flags, hashcontactset, Contacts, Stride, contactcount); + } + } + } + // Contact can be not available if buffer is full + else if (pcontact) + { + pcontact->normal[0] = normal[0]; + pcontact->normal[1] = normal[1]; + pcontact->normal[2] = normal[2]; + pcontact->normal[3] = REAL(1.0); // used to store length of vector sum for averaging + pcontact->depth = depth; + pcontact->g1 = g1; + pcontact->g2 = g2; + pcontact->side1 = TriIndex1; + pcontact->side2 = TriIndex2; + } + + return pcontact; +} + +//////////////////////////////////////////////////////////////////////////////////////////// + + + + +/*extern */ +int dCollideTTL(dxGeom* g1, dxGeom* g2, int Flags, dContactGeom* Contacts, int Stride) +{ + dIASSERT (Stride >= (int)sizeof(dContactGeom)); + dIASSERT (g1->type == dTriMeshClass); + dIASSERT (g2->type == dTriMeshClass); + dIASSERT ((Flags & NUMC_MASK) >= 1); + + dxTriMesh* TriMesh1 = (dxTriMesh*) g1; + dxTriMesh* TriMesh2 = (dxTriMesh*) g2; + + //dReal * TriNormals1 = (dReal *) TriMesh1->Data->Normals; + //dReal * TriNormals2 = (dReal *) TriMesh2->Data->Normals; + + const dVector3& TLPosition1 = *(const dVector3*) dGeomGetPosition(TriMesh1); + // TLRotation1 = column-major order + const dMatrix3& TLRotation1 = *(const dMatrix3*) dGeomGetRotation(TriMesh1); + + const dVector3& TLPosition2 = *(const dVector3*) dGeomGetPosition(TriMesh2); + // TLRotation2 = column-major order + const dMatrix3& TLRotation2 = *(const dMatrix3*) dGeomGetRotation(TriMesh2); + + const unsigned uiTLSKind = TriMesh1->getParentSpaceTLSKind(); + dIASSERT(uiTLSKind == TriMesh2->getParentSpaceTLSKind()); // The colliding spaces must use matching cleanup method + TrimeshCollidersCache *pccColliderCache = GetTrimeshCollidersCache(uiTLSKind); + AABBTreeCollider& Collider = pccColliderCache->m_AABBTreeCollider; + BVTCache &ColCache = pccColliderCache->ColCache; + CONTACT_KEY_HASH_TABLE &hashcontactset = pccColliderCache->m_hashcontactset; + + ColCache.Model0 = &TriMesh1->retrieveMeshBVTreeRef(); + ColCache.Model1 = &TriMesh2->retrieveMeshBVTreeRef(); + + ////Prepare contact list + ClearContactSet(hashcontactset); + + // Collision query + Matrix4x4 amatrix, bmatrix; + dVector3 TLOffsetPosition1 = { REAL(0.0), }; + dVector3 TLOffsetPosition2; + dSubtractVectors3(TLOffsetPosition2, TLPosition2, TLPosition1); + MakeMatrix(TLOffsetPosition1, TLRotation1, amatrix); + MakeMatrix(TLOffsetPosition2, TLRotation2, bmatrix); + bool IsOk = Collider.Collide(ColCache, &amatrix, &bmatrix); + + + if (IsOk) { + // Get collision status => if true, objects overlap + if ( Collider.GetContactStatus() ) { + // Number of colliding pairs and list of pairs + int TriCount = Collider.GetNbPairs(); + const Pair* CollidingPairs = Collider.GetPairs(); + + if (TriCount > 0) { + // step through the pairs, adding contacts + int id1, id2; + int OutTriCount = 0; + dVector3 v1[3], v2[3]; + + for (int i = 0; i < TriCount; i++) + { + id1 = CollidingPairs[i].id0; + id2 = CollidingPairs[i].id1; + + // grab the colliding triangles + static_cast<dxTriMesh *>(g1)->fetchMeshTriangle(v1, id1, TLPosition1, TLRotation1); + static_cast<dxTriMesh *>(g2)->fetchMeshTriangle(v2, id2, TLPosition2, TLRotation2); + + // Since we'll be doing matrix transformations, we need to + // make sure that all vertices have four elements + for (int j=0; j<3; j++) { + v1[j][3] = 1.0; + v2[j][3] = 1.0; + } + + TriTriContacts(v1,v2, id1,id2, + g1, g2, Flags, hashcontactset, + Contacts,Stride,OutTriCount); + + // Continue loop even after contacts are full + // as existing contacts' normals/depths might be updated + // Break only if contacts are not important + if ((OutTriCount | CONTACTS_UNIMPORTANT) == (Flags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) + { + break; + } + } + + // Return the number of contacts + return OutTriCount; + + } + } + } + + + // There was some kind of failure during the Collide call or + // there are no faces overlapping + return 0; +} + + +/* -- not used +static void +GetTriangleGeometryCallback(udword triangleindex, VertexPointers& triangle, udword user_data) +{ + dVector3 Out[3]; + + FetchTriangle((dxTriMesh*) user_data, (int) triangleindex, Out); + + for (int i = 0; i < 3; i++) + triangle.Vertex[i] = (const Point*) ((dReal*) Out[i]); +} +*/ + +// +// +// +#define B11 B[0] +#define B12 B[1] +#define B13 B[2] +#define B14 B[3] +#define B21 B[4] +#define B22 B[5] +#define B23 B[6] +#define B24 B[7] +#define B31 B[8] +#define B32 B[9] +#define B33 B[10] +#define B34 B[11] +#define B41 B[12] +#define B42 B[13] +#define B43 B[14] +#define B44 B[15] + +#define Binv11 Binv[0] +#define Binv12 Binv[1] +#define Binv13 Binv[2] +#define Binv14 Binv[3] +#define Binv21 Binv[4] +#define Binv22 Binv[5] +#define Binv23 Binv[6] +#define Binv24 Binv[7] +#define Binv31 Binv[8] +#define Binv32 Binv[9] +#define Binv33 Binv[10] +#define Binv34 Binv[11] +#define Binv41 Binv[12] +#define Binv42 Binv[13] +#define Binv43 Binv[14] +#define Binv44 Binv[15] + +static inline +void dMakeMatrix4(const dVector3 Position, const dMatrix3 Rotation, dMatrix4 &B) +{ + B11 = Rotation[0]; B21 = Rotation[1]; B31 = Rotation[2]; B41 = Position[0]; + B12 = Rotation[4]; B22 = Rotation[5]; B32 = Rotation[6]; B42 = Position[1]; + B13 = Rotation[8]; B23 = Rotation[9]; B33 = Rotation[10]; B43 = Position[2]; + + B14 = 0.0; B24 = 0.0; B34 = 0.0; B44 = 1.0; +} + +#if 0 +static void +dInvertMatrix4( dMatrix4& B, dMatrix4& Binv ) +{ + dReal det = (B11 * B22 - B12 * B21) * (B33 * B44 - B34 * B43) + -(B11 * B23 - B13 * B21) * (B32 * B44 - B34 * B42) + +(B11 * B24 - B14 * B21) * (B32 * B43 - B33 * B42) + +(B12 * B23 - B13 * B22) * (B31 * B44 - B34 * B41) + -(B12 * B24 - B14 * B22) * (B31 * B43 - B33 * B41) + +(B13 * B24 - B14 * B23) * (B31 * B42 - B32 * B41); + + dAASSERT (det != 0.0); + + det = 1.0 / det; + + Binv11 = (dReal) (det * ((B22 * B33) - (B23 * B32))); + Binv12 = (dReal) (det * ((B32 * B13) - (B33 * B12))); + Binv13 = (dReal) (det * ((B12 * B23) - (B13 * B22))); + Binv14 = 0.0f; + Binv21 = (dReal) (det * ((B23 * B31) - (B21 * B33))); + Binv22 = (dReal) (det * ((B33 * B11) - (B31 * B13))); + Binv23 = (dReal) (det * ((B13 * B21) - (B11 * B23))); + Binv24 = 0.0f; + Binv31 = (dReal) (det * ((B21 * B32) - (B22 * B31))); + Binv32 = (dReal) (det * ((B31 * B12) - (B32 * B11))); + Binv33 = (dReal) (det * ((B11 * B22) - (B12 * B21))); + Binv34 = 0.0f; + Binv41 = (dReal) (det * (B21*(B33*B42 - B32*B43) + B22*(B31*B43 - B33*B41) + B23*(B32*B41 - B31*B42))); + Binv42 = (dReal) (det * (B31*(B13*B42 - B12*B43) + B32*(B11*B43 - B13*B41) + B33*(B12*B41 - B11*B42))); + Binv43 = (dReal) (det * (B41*(B13*B22 - B12*B23) + B42*(B11*B23 - B13*B21) + B43*(B12*B21 - B11*B22))); + Binv44 = 1.0f; +} +#endif + + +// Find the intersectiojn point between a coplanar line segement, +// defined by X1 and X2, and a ray defined by X3 and direction N. +// +// This forumla for this calculation is: +// (c x b) . (a x b) +// Q = x1 + a ------------------- +// | a x b | ^2 +// +// where a = x2 - x1 +// b = x4 - x3 +// c = x3 - x1 +// x1 and x2 are the edges of the triangle, and x3 is CoplanarPt +// and x4 is (CoplanarPt - n) +#if 0 +static int +IntersectLineSegmentRay(dVector3 x1, dVector3 x2, dVector3 x3, dVector3 n, + dVector3 out_pt) +{ + dVector3 a, b, c, x4; + + ADD(x4, x3, n); // x4 = x3 + n + + SUB(a, x2, x1); // a = x2 - x1 + SUB(b, x4, x3); + SUB(c, x3, x1); + + dVector3 tmp1, tmp2; + CROSS(tmp1, c, b); + CROSS(tmp2, a, b); + + dReal num, denom; + num = dCalcVectorDot3(tmp1, tmp2); + denom = LENGTH( tmp2 ); + + dReal s; + s = num /(denom*denom); + + for (int i=0; i<3; i++) + out_pt[i] = x1[i] + a[i]*s; + + // Test if this intersection is "behind" x3, w.r.t. n + SUB(a, x3, out_pt); + if (dCalcVectorDot3(a, n) > 0.0) + return 0; + + // Test if this intersection point is outside the edge limits, + // if (dot( (out_pt-x1), (out_pt-x2) ) < 0) it's inside + // else outside + SUB(a, out_pt, x1); + SUB(b, out_pt, x2); + if (dCalcVectorDot3(a,b) < 0.0) + return 1; + else + return 0; +} +#endif + + +void PlaneClipSegment( const dVector3 s1, const dVector3 s2, + const dVector3 N, dReal C, dVector3 clipped) +{ + dReal dis1,dis2; + dis1 = DOT(s1,N)-C; + SUB(clipped,s2,s1); + dis2 = DOT(clipped,N); + MULT(clipped,clipped,-dis1/dis2); + ADD(clipped,clipped,s1); + clipped[3] = 1.0f; +} + +/* ClipConvexPolygonAgainstPlane - Clip a a convex polygon, described by +CONTACTS, with a plane (described by N and C distance from origin). +Note: the input vertices are assumed to be in invcounterclockwise order. +changed by Francisco Leon (http://gimpact.sourceforge.net) */ +static void +ClipConvexPolygonAgainstPlane( const dVector3 N, dReal C, + LineContactSet& Contacts ) +{ + int i, vi, prevclassif=32000, classif; + /* + classif 0 : back, 1 : front + */ + + dReal d; + dVector3 clipped[8]; + int clippedcount =0; + + if(Contacts.Count==0) + { + return; + } + for(i=0;i<=Contacts.Count;i++) + { + vi = i%Contacts.Count; + + d = DOT(N,Contacts.Points[vi]) - C; + ////classify point + if(d>REAL(1.0e-8)) classif = 1; + else classif = 0; + + if(classif == 0)//back + { + if(i>0) + { + if(prevclassif==1)///in front + { + + ///add clipped point + if(clippedcount<8) + { + PlaneClipSegment(Contacts.Points[i-1],Contacts.Points[vi], + N,C,clipped[clippedcount]); + clippedcount++; + } + } + } + ///add point + if(clippedcount<8&&i<Contacts.Count) + { + clipped[clippedcount][0] = Contacts.Points[vi][0]; + clipped[clippedcount][1] = Contacts.Points[vi][1]; + clipped[clippedcount][2] = Contacts.Points[vi][2]; + clipped[clippedcount][3] = 1.0f; + clippedcount++; + } + } + else + { + + if(i>0) + { + if(prevclassif==0) + { + ///add point + if(clippedcount<8) + { + PlaneClipSegment(Contacts.Points[i-1],Contacts.Points[vi], + N,C,clipped[clippedcount]); + clippedcount++; + } + } + } + } + + prevclassif = classif; + } + + if(clippedcount==0) + { + Contacts.Count = 0; + return; + } + Contacts.Count = clippedcount; + memcpy( Contacts.Points, clipped, clippedcount * sizeof(dVector3) ); + return; +} + + +bool BuildPlane(const dVector3 s0, const dVector3 s1,const dVector3 s2, + dVector3 Normal, dReal & Dist) +{ + dVector3 e0,e1; + SUB(e0,s1,s0); + SUB(e1,s2,s0); + + CROSS(Normal,e0,e1); + + if (!dSafeNormalize3(Normal)) + { + return false; + } + + Dist = DOT(Normal,s0); + return true; + +} + +// bool BuildEdgesDir(const dVector3 s0, const dVector3 s1, +// const dVector3 t0, const dVector3 t1, +// dVector3 crossdir) +// { +// dVector3 e0,e1; +// +// SUB(e0,s1,s0); +// SUB(e1,t1,t0); +// CROSS(crossdir,e0,e1); +// +// if (!dSafeNormalize3(crossdir)) +// { +// return false; +// } +// return true; +// } + + + +bool BuildEdgePlane( + const dVector3 s0, const dVector3 s1, + const dVector3 normal, + dVector3 plane_normal, + dReal & plane_dist) +{ + dVector3 e0; + + SUB(e0,s1,s0); + CROSS(plane_normal,e0,normal); + if (!dSafeNormalize3(plane_normal)) + { + return false; + } + plane_dist = DOT(plane_normal,s0); + return true; +} + + + + +/* +Positive penetration +Negative number: they are separated +*/ +dReal IntervalPenetration(dReal &vmin1,dReal &vmax1, + dReal &vmin2,dReal &vmax2) +{ + if(vmax1<=vmin2) + { + return -(vmin2-vmax1); + } + else + { + if(vmax2<=vmin1) + { + return -(vmin1-vmax2); + } + else + { + if(vmax1<=vmax2) + { + return vmax1-vmin2; + } + + return vmax2-vmin1; + } + + } + return 0; +} + +void FindInterval( + const dVector3 * vertices, int verticecount, + dVector3 dir,dReal &vmin,dReal &vmax) +{ + + dReal dist; + int i; + vmin = DOT(vertices[0],dir); + vmax = vmin; + for(i=1;i<verticecount;i++) + { + dist = DOT(vertices[i],dir); + if(vmin>dist) vmin=dist; + else if(vmax<dist) vmax=dist; + } +} + +///returns the penetration depth +dReal MostDeepPoints( + LineContactSet & points, + const dVector3 plane_normal, + dReal plane_dist, + LineContactSet & deep_points) +{ + int i; + int max_candidates[8]; + dReal maxdeep=-dInfinity; + dReal dist; + + deep_points.Count = 0; + for(i=0;i<points.Count;i++) + { + dist = DOT(plane_normal,points.Points[i]) - plane_dist; + dist *= -1.0f; + if(dist>maxdeep) + { + maxdeep = dist; + deep_points.Count=1; + max_candidates[deep_points.Count-1] = i; + } + else if(dist+REAL(0.000001)>=maxdeep) + { + deep_points.Count++; + max_candidates[deep_points.Count-1] = i; + } + } + + for(i=0;i<deep_points.Count;i++) + { + SET(deep_points.Points[i],points.Points[max_candidates[i]]); + } + return maxdeep; + +} + +void ClipPointsByTri( + const dVector3 * points, int pointcount, + const dVector3 tri[3], + const dVector3 triplanenormal, + dReal triplanedist, + LineContactSet & clipped_points, + bool triplane_clips) +{ + ///build edges planes + int i; + dVector4 plane; + + clipped_points.Count = pointcount; + memcpy(&clipped_points.Points[0],&points[0],pointcount*sizeof(dVector3)); + for(i=0;i<3;i++) + { + if (BuildEdgePlane( + tri[i],tri[(i+1)%3],triplanenormal, + plane,plane[3])) + { + ClipConvexPolygonAgainstPlane( + plane, + plane[3], + clipped_points); + } + } + + if(triplane_clips) + { + ClipConvexPolygonAgainstPlane( + triplanenormal, + triplanedist, + clipped_points); + } +} + + +///returns the penetration depth +dReal FindTriangleTriangleCollision( + const dVector3 tri1[3], + const dVector3 tri2[3], + dVector3 separating_normal, + LineContactSet & deep_points) +{ + dReal maxdeep=dInfinity; + dReal dist; + int mostdir=0, /*mostface=0,*/ currdir=0; + // dReal vmin1,vmax1,vmin2,vmax2; + // dVector3 crossdir, pt1,pt2; + dVector4 tri1plane,tri2plane; + separating_normal[3] = 0.0f; + bool bl; + LineContactSet clipped_points1,clipped_points2; + LineContactSet deep_points1,deep_points2; + // It is necessary to initialize the count because both conditional statements + // might be skipped leading to uninitialized count being used for memcpy in if(mostdir==0) + deep_points1.Count = 0; + + ////find interval face1 + + bl = BuildPlane(tri1[0],tri1[1],tri1[2], + tri1plane,tri1plane[3]); + clipped_points1.Count = 0; + + if(bl) + { + ClipPointsByTri( + tri2, 3, + tri1, + tri1plane, + tri1plane[3], + clipped_points1,false); + + + + maxdeep = MostDeepPoints( + clipped_points1, + tri1plane, + tri1plane[3], + deep_points1); + SET(separating_normal,tri1plane); + + } + currdir++; + + ////find interval face2 + + bl = BuildPlane(tri2[0],tri2[1],tri2[2], + tri2plane,tri2plane[3]); + + + clipped_points2.Count = 0; + if(bl) + { + ClipPointsByTri( + tri1, 3, + tri2, + tri2plane, + tri2plane[3], + clipped_points2,false); + + + + dist = MostDeepPoints( + clipped_points2, + tri2plane, + tri2plane[3], + deep_points2); + + + + if(dist<maxdeep) + { + maxdeep = dist; + mostdir = currdir; + //mostface = 1; + SET(separating_normal,tri2plane); + } + } + currdir++; + + + ///find edge edge distances + ///test each edge plane + + /*for(i=0;i<3;i++) + { + + + for(j=0;j<3;j++) + { + + + bl = BuildEdgesDir( + tri1[i],tri1[(i+1)%3], + tri2[j],tri2[(j+1)%3], + crossdir); + + ////find plane distance + + if(bl) + { + FindInterval(tri1,3,crossdir,vmin1,vmax1); + FindInterval(tri2,3,crossdir,vmin2,vmax2); + + dist = IntervalPenetration( + vmin1, + vmax1, + vmin2, + vmax2); + if(dist<maxdeep) + { + maxdeep = dist; + mostdir = currdir; + SET(separating_normal,crossdir); + } + } + currdir++; + } + }*/ + + + ////check most dir for contacts + if(mostdir==0) + { + ///find most deep points + deep_points.Count = deep_points1.Count; + memcpy( + &deep_points.Points[0], + &deep_points1.Points[0], + deep_points1.Count*sizeof(dVector3)); + + ///invert normal for point to tri1 + MULT(separating_normal,separating_normal,-1.0f); + } + else if(mostdir==1) + { + deep_points.Count = deep_points2.Count; + memcpy( + &deep_points.Points[0], + &deep_points2.Points[0], + deep_points2.Count*sizeof(dVector3)); + + } + /*else + {///edge separation + mostdir -= 2; + + //edge 2 + j = mostdir%3; + //edge 1 + i = mostdir/3; + + ///find edge closest points + dClosestLineSegmentPoints( + tri1[i],tri1[(i+1)%3], + tri2[j],tri2[(j+1)%3], + pt1,pt2); + ///find correct direction + + SUB(crossdir,pt2,pt1); + + vmin1 = LENGTH(crossdir); + if(vmin1<REAL(0.000001)) + { + + if(mostface==0) + { + vmin1 = DOT(separating_normal,tri1plane); + if(vmin1>0.0) + { + MULT(separating_normal,separating_normal,-1.0f); + deep_points.Count = 1; + SET(deep_points.Points[0],pt2); + } + else + { + deep_points.Count = 1; + SET(deep_points.Points[0],pt2); + } + + } + else + { + vmin1 = DOT(separating_normal,tri2plane); + if(vmin1<0.0) + { + MULT(separating_normal,separating_normal,-1.0f); + deep_points.Count = 1; + SET(deep_points.Points[0],pt2); + } + else + { + deep_points.Count = 1; + SET(deep_points.Points[0],pt2); + } + + } + + + + + } + else + { + MULT(separating_normal,crossdir,1.0f/vmin1); + + vmin1 = DOT(separating_normal,tri1plane); + if(vmin1>0.0) + { + MULT(separating_normal,separating_normal,-1.0f); + deep_points.Count = 1; + SET(deep_points.Points[0],pt2); + } + else + { + deep_points.Count = 1; + SET(deep_points.Points[0],pt2); + } + + + } + + + }*/ + return maxdeep; +} + + + +///SUPPORT UP TO 8 CONTACTS +bool TriTriContacts(const dVector3 tr1[3], + const dVector3 tr2[3], + int TriIndex1, int TriIndex2, + dxGeom* g1, dxGeom* g2, int Flags, + CONTACT_KEY_HASH_TABLE &hashcontactset, + dContactGeom* Contacts, int Stride, + int &contactcount) +{ + + + dVector4 normal; + dReal depth; + ///Test Tri Vs Tri + // dContactGeom* pcontact; + int ccount = 0; + LineContactSet contactpoints; + contactpoints.Count = 0; + + + + ///find best direction + + depth = FindTriangleTriangleCollision( + tr1, + tr2, + normal, + contactpoints); + + + + if(depth<0.0f) return false; + + ccount = 0; + while (ccount<contactpoints.Count) + { + PushNewContact( g1, g2, TriIndex1, TriIndex2, + contactpoints.Points[ccount], + normal, depth, Flags, hashcontactset, + Contacts,Stride,contactcount); + + // Continue loop even after contacts are full + // as existing contacts' normals/depths might be updated + // Break only if contacts are not important + if ((contactcount | CONTACTS_UNIMPORTANT) == (Flags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) + { + break; + } + + ccount++; + } + return true; +} + + +#endif // !dTRIMESH_OPCODE_USE_OLD_TRIMESH_TRIMESH_COLLIDER + + +#endif // dTRIMESH_OPCODE + + +////////////////////////////////////////////////////////////////////////// + +#if dTRIMESH_GIMPACT + +#include "gimpact_contact_export_helper.h" +#include "gimpact_gim_contact_accessor.h" + + +// +// GIMPACT TRIMESH-TRIMESH COLLIDER +// + +/*extern */ +int dCollideTTL(dxGeom* g1, dxGeom* g2, int Flags, dContactGeom* Contacts, int Stride) +{ + dIASSERT (Stride >= (int)sizeof(dContactGeom)); + dIASSERT (g1->type == dTriMeshClass); + dIASSERT (g2->type == dTriMeshClass); + dIASSERT ((Flags & NUMC_MASK) >= 1); + + int result = 0; + + dxTriMesh *triMesh1 = static_cast<dxTriMesh *>(g1); + dxTriMesh *triMesh2 = static_cast<dxTriMesh *>(g2); + //Create contact list + GDYNAMIC_ARRAY trimeshContacts; + GIM_CREATE_CONTACT_LIST(trimeshContacts); + + triMesh1->recomputeAABB(); + triMesh2->recomputeAABB(); + + //Collide trimeshes + gim_trimesh_trimesh_collision(&triMesh1->m_collision_trimesh, &triMesh2->m_collision_trimesh, &trimeshContacts); + + unsigned contactCount = trimeshContacts.m_size; + + if (contactCount != 0) + { + GIM_CONTACT *pTriMeshContacts = GIM_DYNARRAY_POINTER(GIM_CONTACT, trimeshContacts); + + dxGIMCContactAccessor contactAccessor(pTriMeshContacts, g1, g2); + unsigned culledContactCount = dxGImpactContactsExportHelper::ExportMaxDepthGImpactContacts(contactAccessor, contactCount, Flags, Contacts, Stride); + + result = culledContactCount; + } + + GIM_DYNARRAY_DESTROY(trimeshContacts); + + return result; +} + + +#endif // dTRIMESH_GIMPACT + +#endif // dTRIMESH_ENABLED + diff --git a/libs/ode-0.16.1/ode/src/collision_trimesh_trimesh_old.cpp b/libs/ode-0.16.1/ode/src/collision_trimesh_trimesh_old.cpp new file mode 100644 index 0000000..23d04a1 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_trimesh_trimesh_old.cpp @@ -0,0 +1,2071 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// OPCODE TriMesh/TriMesh collision code by Jeff Smith (c) 2004 + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + +#include <ode/collision.h> +#include <ode/rotation.h> +#include "config.h" +#include "matrix.h" +#include "odemath.h" + + +#if dTRIMESH_ENABLED + +#include "collision_util.h" +#include "collision_trimesh_internal.h" + + +#if dTRIMESH_OPCODE + +// Classic Implementation +#if dTRIMESH_OPCODE_USE_OLD_TRIMESH_TRIMESH_COLLIDER + +#define SMALL_ELT REAL(2.5e-4) +#define EXPANDED_ELT_THRESH REAL(1.0e-3) +#define DISTANCE_EPSILON REAL(1.0e-8) +#define VELOCITY_EPSILON REAL(1.0e-5) +#define TINY_PENETRATION REAL(5.0e-6) + +struct LineContactSet +{ + enum + { + MAX_POINTS = 8 + }; + + dVector3 Points[MAX_POINTS]; + int Count; +}; + + +// static void GetTriangleGeometryCallback(udword, VertexPointers&, udword); -- not used +static void GenerateContact(int, dContactGeom*, int, dxTriMesh*, dxTriMesh*, + int TriIndex1, int TriIndex2, + const dVector3, const dVector3, dReal, int&); +static int TriTriIntersectWithIsectLine(dReal V0[3],dReal V1[3],dReal V2[3], + dReal U0[3],dReal U1[3],dReal U2[3],int *coplanar, + dReal isectpt1[3],dReal isectpt2[3]); +inline void dMakeMatrix4(const dVector3 Position, const dMatrix3 Rotation, dMatrix4 &B); +static void dInvertMatrix4( dMatrix4& B, dMatrix4& Binv ); +//static int IntersectLineSegmentRay(dVector3, dVector3, dVector3, dVector3, dVector3); +static bool FindTriSolidIntrsection(const dVector3 Tri[3], + const dVector4 Planes[6], int numSides, + LineContactSet& ClippedPolygon ); +static void ClipConvexPolygonAgainstPlane( const dVector3, dReal, LineContactSet& ); +static bool SimpleUnclippedTest(dVector3 in_CoplanarPt, dVector3 in_v, dVector3 in_elt, + dVector3 in_n, dVector3* in_col_v, dReal &out_depth); +static int ExamineContactPoint(dVector3* v_col, dVector3 in_n, dVector3 in_point); +static int RayTriangleIntersect(const dVector3 orig, const dVector3 dir, + const dVector3 vert0, const dVector3 vert1,const dVector3 vert2, + dReal *t,dReal *u,dReal *v); + + + + +/* some math macros */ +#define IS_ZERO(v) (!(v)[0] && !(v)[1] && !(v)[2]) + +#define CROSS(dest,v1,v2) dCalcVectorCross3(dest, v1, v2) + +#define DOT(v1,v2) dCalcVectorDot3(v1, v2) + +#define SUB(dest,v1,v2) dSubtractVectors3(dest, v1, v2) + +#define ADD(dest,v1,v2) dAddVectors3(dest, v1, v2) + +#define MULT(dest,v,factor) dCopyScaledVector3(dest, v, factor) + +#define SET(dest,src) dCopyVector3(dest, src) + +#define SMULT(p,q,s) dCopyScaledVector3(p, q, s) + +#define LENGTH(x) dCalcVectorLength3(x) + +#define DEPTH(d, p, q, n) d = dCalcPointDepth3(q, p, n) + + +inline void +SwapNormals(dVector3 *&pen_v, dVector3 *&col_v, dVector3* v1, dVector3* v2, + dVector3 *&pen_elt, dVector3 *elt_f1, dVector3 *elt_f2, + dVector3 n, dVector3 n1, dVector3 n2) +{ + if (pen_v == v1) { + pen_v = v2; + pen_elt = elt_f2; + col_v = v1; + SET(n, n1); + } + else { + pen_v = v1; + pen_elt = elt_f1; + col_v = v2; + SET(n, n2); + } +} + + + + +int +dCollideTTL(dxGeom* g1, dxGeom* g2, int Flags, dContactGeom* Contacts, int Stride) +{ + dIASSERT (Stride >= (int)sizeof(dContactGeom)); + dIASSERT (g1->type == dTriMeshClass); + dIASSERT (g2->type == dTriMeshClass); + dIASSERT ((Flags & NUMC_MASK) >= 1); + + dxTriMesh* TriMesh1 = (dxTriMesh*) g1; + dxTriMesh* TriMesh2 = (dxTriMesh*) g2; + + const dReal* TriNormals1 = TriMesh1->retrieveMeshNormals(); + const dReal* TriNormals2 = TriMesh2->retrieveMeshNormals(); + + const dVector3& TLPosition1 = *(const dVector3*) dGeomGetPosition(TriMesh1); + // TLRotation1 = column-major order + const dMatrix3& TLRotation1 = *(const dMatrix3*) dGeomGetRotation(TriMesh1); + + const dVector3& TLPosition2 = *(const dVector3*) dGeomGetPosition(TriMesh2); + // TLRotation2 = column-major order + const dMatrix3& TLRotation2 = *(const dMatrix3*) dGeomGetRotation(TriMesh2); + + const unsigned uiTLSKind = TriMesh1->getParentSpaceTLSKind(); + dIASSERT(uiTLSKind == TriMesh2->getParentSpaceTLSKind()); // The colliding spaces must use matching cleanup method + TrimeshCollidersCache *pccColliderCache = GetTrimeshCollidersCache(uiTLSKind); + AABBTreeCollider& Collider = pccColliderCache->m_AABBTreeCollider; + BVTCache &ColCache = pccColliderCache->ColCache; + + ColCache.Model0 = &TriMesh1->retrieveMeshBVTreeRef(); + ColCache.Model1 = &TriMesh2->retrieveMeshBVTreeRef(); + + // Collision query + Matrix4x4 amatrix, bmatrix; + dVector3 TLOffsetPosition1 = { REAL(0.0), }; + dVector3 TLOffsetPosition2; + dSubtractVectors3(TLOffsetPosition2, TLPosition2, TLPosition1); + MakeMatrix(TLOffsetPosition1, TLRotation1, amatrix); + MakeMatrix(TLOffsetPosition2, TLRotation2, bmatrix); + BOOL IsOk = Collider.Collide(ColCache, &amatrix, &bmatrix); + + + // Make "double" versions of these matrices, if appropriate + dMatrix4 A, B; + dMakeMatrix4(TLPosition1, TLRotation1, A); + dMakeMatrix4(TLPosition2, TLRotation2, B); + + + if (IsOk) { + // Get collision status => if true, objects overlap + if ( Collider.GetContactStatus() ) { + // Number of colliding pairs and list of pairs + int TriCount = Collider.GetNbPairs(); + const Pair* CollidingPairs = Collider.GetPairs(); + + if (TriCount > 0) { + // step through the pairs, adding contacts + int id1, id2; + int OutTriCount = 0; + dVector3 v1[3], v2[3], CoplanarPt; + dVector3 e1, e2, e3, n1, n2, n, ContactNormal; + dReal depth; + dVector3 orig_pos, old_pos1, old_pos2, elt1, elt2, elt_sum; + dVector3 elt_f1[3], elt_f2[3]; + dReal contact_elt_length = SMALL_ELT; + LineContactSet firstClippedTri, secondClippedTri; + dVector3 *firstClippedElt = new dVector3[LineContactSet::MAX_POINTS]; + dVector3 *secondClippedElt = new dVector3[LineContactSet::MAX_POINTS]; + + + // only do these expensive inversions once + dMatrix4 InvMatrix1, InvMatrix2; + dInvertMatrix4(A, InvMatrix1); + dInvertMatrix4(B, InvMatrix2); + + + for (int i = 0; i < TriCount; i++) { + + id1 = CollidingPairs[i].id0; + id2 = CollidingPairs[i].id1; + + // grab the colliding triangles + static_cast<dxTriMesh *>(g1)->fetchMeshTriangle(v1, id1, TLPosition1, TLRotation1); + static_cast<dxTriMesh *>(g2)->fetchMeshTriangle(v2, id2, TLPosition2, TLRotation2); + + // Since we'll be doing matrix transformations, we need to + // make sure that all vertices have four elements + for (int j=0; j<3; j++) { + v1[j][3] = 1.0; + v2[j][3] = 1.0; + } + + + int IsCoplanar = 0; + dReal IsectPt1[3], IsectPt2[3]; + + // Sometimes OPCODE makes mistakes, so we look at the return + // value for TriTriIntersectWithIsectLine. A retcode of "0" + // means no intersection took place + if ( TriTriIntersectWithIsectLine( v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], + &IsCoplanar, + IsectPt1, IsectPt2) ) { + + // Compute the normals of the colliding faces + // + if (TriNormals1 == NULL) { + SUB( e1, v1[1], v1[0] ); + SUB( e2, v1[2], v1[0] ); + CROSS( n1, e1, e2 ); + dNormalize3(n1); + } + else { + // If we were passed normals, we need to adjust them to take into + // account the objects' current rotations + e1[0] = TriNormals1[id1*3]; + e1[1] = TriNormals1[id1*3 + 1]; + e1[2] = TriNormals1[id1*3 + 2]; + e1[3] = 0.0; + + //dMultiply1(n1, TLRotation1, e1, 3, 3, 1); + dMultiply0(n1, TLRotation1, e1, 3, 3, 1); + n1[3] = 1.0; + } + + if (TriNormals2 == NULL) { + SUB( e1, v2[1], v2[0] ); + SUB( e2, v2[2], v2[0] ); + CROSS( n2, e1, e2); + dNormalize3(n2); + } + else { + // If we were passed normals, we need to adjust them to take into + // account the objects' current rotations + e2[0] = TriNormals2[id2*3]; + e2[1] = TriNormals2[id2*3 + 1]; + e2[2] = TriNormals2[id2*3 + 2]; + e2[3] = 0.0; + + //dMultiply1(n2, TLRotation2, e2, 3, 3, 1); + dMultiply0(n2, TLRotation2, e2, 3, 3, 1); + n2[3] = 1.0; + } + + + if (IsCoplanar) { + // We can reach this case if the faces are coplanar, OR + // if they don't actually intersect. (OPCODE can make + // mistakes) + if (dFabs(dCalcVectorDot3(n1, n2)) > REAL(0.999)) { + // If the faces are coplanar, we declare that the point of + // contact is at the average location of the vertices of + // both faces + dVector3 ContactPt; + for (int j=0; j<3; j++) { + ContactPt[j] = 0.0; + for (int k=0; k<3; k++) + ContactPt[j] += v1[k][j] + v2[k][j]; + ContactPt[j] /= 6.0; + } + ContactPt[3] = 1.0; + + // and the contact normal is the normal of face 2 + // (could be face 1, because they are the same) + SET(n, n2); + + // and the penetration depth is the co-normal + // distance between any two vertices A and B, + // i.e. d = DOT(n, (A-B)) + DEPTH(depth, v1[1], v2[1], n); + if (depth < 0) + depth *= -1.0; + + GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, + ContactPt, n, depth, OutTriCount); + } + } + else { + // Otherwise (in non-co-planar cases), we create a coplanar + // point -- the middle of the line of intersection -- that + // will be used for various computations down the road + for (int j=0; j<3; j++) + CoplanarPt[j] = ( (IsectPt1[j] + IsectPt2[j]) / REAL(2.0) ); + CoplanarPt[3] = 1.0; + + // Find the ELT of the coplanar point + // + dMultiply1(orig_pos, InvMatrix1, CoplanarPt, 4, 4, 1); + dMultiply1(old_pos1, ((dxTriMesh*)g1)->m_last_trans, orig_pos, 4, 4, 1); + SUB(elt1, CoplanarPt, old_pos1); + + dMultiply1(orig_pos, InvMatrix2, CoplanarPt, 4, 4, 1); + dMultiply1(old_pos2, ((dxTriMesh*)g2)->m_last_trans, orig_pos, 4, 4, 1); + SUB(elt2, CoplanarPt, old_pos2); + + SUB(elt_sum, elt1, elt2); // net motion of the coplanar point + dReal elt_sum_len = LENGTH(elt_sum); // Could be calculated on demand but there is no good place... + + + // Calculate how much the vertices of each face moved in the + // direction of the opposite face's normal + // + dReal total_dp1, total_dp2; + total_dp1 = 0.0; + total_dp2 = 0.0; + + for (int ii=0; ii<3; ii++) { + // find the estimated linear translation (ELT) of the vertices + // on face 1, wrt to the center of face 2. + + // un-transform this vertex by the current transform + dMultiply1(orig_pos, InvMatrix1, v1[ii], 4, 4, 1 ); + + // re-transform this vertex by last_trans (to get its old + // position) + dMultiply1(old_pos1, ((dxTriMesh*)g1)->m_last_trans, orig_pos, 4, 4, 1); + + // Then subtract this position from our current one to find + // the elapsed linear translation (ELT) + for (int k=0; k<3; k++) { + elt_f1[ii][k] = (v1[ii][k] - old_pos1[k]) - elt2[k]; + } + + // Take the dot product of the ELT for each vertex (wrt the + // center of face2) + total_dp1 += dFabs( dCalcVectorDot3(elt_f1[ii], n2) ); + } + + for (int ii=0; ii<3; ii++) { + // find the estimated linear translation (ELT) of the vertices + // on face 2, wrt to the center of face 1. + dMultiply1(orig_pos, InvMatrix2, v2[ii], 4, 4, 1); + dMultiply1(old_pos2, ((dxTriMesh*)g2)->m_last_trans, orig_pos, 4, 4, 1); + for (int k=0; k<3; k++) { + elt_f2[ii][k] = (v2[ii][k] - old_pos2[k]) - elt1[k]; + } + + // Take the dot product of the ELT for each vertex (wrt the + // center of face2) and add them + total_dp2 += dFabs( dCalcVectorDot3(elt_f2[ii], n1) ); + } + + + //////// + // Estimate the penetration depth. + // + dReal dp; + BOOL badPen = true; + dVector3 *pen_v; // the "penetrating vertices" + dVector3 *pen_elt; // the elt_f of the penetrating face + dVector3 *col_v; // the "collision vertices" (the penetrated face) + + SMULT(n2, n2, -1.0); // SF PATCH #1335183 + depth = 0.0; + if ((total_dp1 > DISTANCE_EPSILON) || (total_dp2 > DISTANCE_EPSILON)) { + //////// + // Find the collision normal, by finding the face + // that is pointed "most" in the direction of travel + // of the two triangles + // + if (total_dp2 > total_dp1) { + pen_v = v2; + pen_elt = elt_f2; + col_v = v1; + SET(n, n1); + } + else { + pen_v = v1; + pen_elt = elt_f1; + col_v = v2; + SET(n, n2); + } + } + else { + // the total_dp is very small, so let's fall back + // to a different test + if (LENGTH(elt2) > LENGTH(elt1)) { + pen_v = v2; + pen_elt = elt_f2; + col_v = v1; + SET(n, n1); + } + else { + pen_v = v1; + pen_elt = elt_f1; + col_v = v2; + SET(n, n2); + } + } + + + for (int j=0; j<3; j++) { + if (SimpleUnclippedTest(CoplanarPt, pen_v[j], pen_elt[j], n, col_v, depth)) { + GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, + pen_v[j], n, depth, OutTriCount); + badPen = false; + + if ((OutTriCount | CONTACTS_UNIMPORTANT) == (Flags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) { + break; + } + } + } + + if (badPen) { + // try the other normal + SwapNormals(pen_v, col_v, v1, v2, pen_elt, elt_f1, elt_f2, n, n1, n2); + + for (int j=0; j<3; j++) + if (SimpleUnclippedTest(CoplanarPt, pen_v[j], pen_elt[j], n, col_v, depth)) { + GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, + pen_v[j], n, depth, OutTriCount); + badPen = false; + + if ((OutTriCount | CONTACTS_UNIMPORTANT) == (Flags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) { + break; + } + } + } + + + + //////////////////////////////////////// + // + // If we haven't found a good penetration, then we're probably straddling + // the edge of one of the objects, or the penetraing face is big + // enough that all of its vertices are outside the bounds of the + // penetrated face. + // In these cases, we do a more expensive test. We clip the penetrating + // triangle with a solid defined by the penetrated triangle, and repeat + // the tests above on this new polygon + if (badPen) { + + // Switch pen_v and n back again + SwapNormals(pen_v, col_v, v1, v2, pen_elt, elt_f1, elt_f2, n, n1, n2); + + + // Find the three sides (no top or bottom) of the solid defined by + // the edges of the penetrated triangle. + + // The dVector4 "plane" structures contain the following information: + // [0]-[2]: The normal of the face, pointing INWARDS (i.e. + // the inverse normal + // [3]: The distance between the face and the center of the + // solid, along the normal + dVector4 SolidPlanes[3]; + dVector3 tmp1; + dVector3 sn; + + for (int j=0; j<3; j++) { + e1[j] = col_v[1][j] - col_v[0][j]; + e2[j] = col_v[0][j] - col_v[2][j]; + e3[j] = col_v[2][j] - col_v[1][j]; + } + + // side 1 + CROSS(sn, e1, n); + dNormalize3(sn); + SMULT( SolidPlanes[0], sn, -1.0 ); + + ADD(tmp1, col_v[0], col_v[1]); + SMULT(tmp1, tmp1, 0.5); // center of edge + // distance from center to edge along normal + SolidPlanes[0][3] = dCalcVectorDot3(tmp1, SolidPlanes[0]); + + + // side 2 + CROSS(sn, e2, n); + dNormalize3(sn); + SMULT( SolidPlanes[1], sn, -1.0 ); + + ADD(tmp1, col_v[0], col_v[2]); + SMULT(tmp1, tmp1, 0.5); // center of edge + // distance from center to edge along normal + SolidPlanes[1][3] = dCalcVectorDot3(tmp1, SolidPlanes[1]); + + + // side 3 + CROSS(sn, e3, n); + dNormalize3(sn); + SMULT( SolidPlanes[2], sn, -1.0 ); + + ADD(tmp1, col_v[2], col_v[1]); + SMULT(tmp1, tmp1, 0.5); // center of edge + // distance from center to edge along normal + SolidPlanes[2][3] = dCalcVectorDot3(tmp1, SolidPlanes[2]); + + + FindTriSolidIntrsection(pen_v, SolidPlanes, 3, firstClippedTri); + + for (int j=0; j<firstClippedTri.Count; j++) { + firstClippedTri.Points[j][3] = 1.0; // because we will be doing matrix mults + + DEPTH(dp, CoplanarPt, firstClippedTri.Points[j], n); + + // if the penetration depth (calculated above) is more than the contact + // point's ELT, then we've chosen the wrong face and should switch faces + if (pen_v == v1) { + dMultiply1(orig_pos, InvMatrix1, firstClippedTri.Points[j], 4, 4, 1); + dMultiply1(old_pos1, ((dxTriMesh*)g1)->m_last_trans, orig_pos, 4, 4, 1); + for (int k=0; k<3; k++) { + firstClippedElt[j][k] = (firstClippedTri.Points[j][k] - old_pos1[k]) - elt2[k]; + } + } + else { + dMultiply1(orig_pos, InvMatrix2, firstClippedTri.Points[j], 4, 4, 1); + dMultiply1(old_pos2, ((dxTriMesh*)g2)->m_last_trans, orig_pos, 4, 4, 1); + for (int k=0; k<3; k++) { + firstClippedElt[j][k] = (firstClippedTri.Points[j][k] - old_pos2[k]) - elt1[k]; + } + } + + if (dp >= 0.0) { + contact_elt_length = dFabs(dCalcVectorDot3(firstClippedElt[j], n)); + + depth = dp; + if (depth == 0.0) + depth = dMin(DISTANCE_EPSILON, contact_elt_length); + + if ((contact_elt_length < SMALL_ELT) && (depth < EXPANDED_ELT_THRESH)) + depth = contact_elt_length; + + if (depth <= contact_elt_length) { + // Add a contact + GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, + firstClippedTri.Points[j], n, depth, OutTriCount); + badPen = false; + + if ((OutTriCount | CONTACTS_UNIMPORTANT) == (Flags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) { + break; + } + } + } + + } + } + + if (badPen) { + // Switch pen_v and n (again!) + SwapNormals(pen_v, col_v, v1, v2, pen_elt, elt_f1, elt_f2, n, n1, n2); + + + // Find the three sides (no top or bottom) of the solid created by + // the penetrated triangle. + // The dVector4 "plane" structures contain the following information: + // [0]-[2]: The normal of the face, pointing INWARDS (i.e. + // the inverse normal + // [3]: The distance between the face and the center of the + // solid, along the normal + dVector4 SolidPlanes[3]; + dVector3 tmp1; + + dVector3 sn; + for (int j=0; j<3; j++) { + e1[j] = col_v[1][j] - col_v[0][j]; + e2[j] = col_v[0][j] - col_v[2][j]; + e3[j] = col_v[2][j] - col_v[1][j]; + } + + // side 1 + CROSS(sn, e1, n); + dNormalize3(sn); + SMULT( SolidPlanes[0], sn, -1.0 ); + + ADD(tmp1, col_v[0], col_v[1]); + SMULT(tmp1, tmp1, 0.5); // center of edge + // distance from center to edge along normal + SolidPlanes[0][3] = dCalcVectorDot3(tmp1, SolidPlanes[0]); + + + // side 2 + CROSS(sn, e2, n); + dNormalize3(sn); + SMULT( SolidPlanes[1], sn, -1.0 ); + + ADD(tmp1, col_v[0], col_v[2]); + SMULT(tmp1, tmp1, 0.5); // center of edge + // distance from center to edge along normal + SolidPlanes[1][3] = dCalcVectorDot3(tmp1, SolidPlanes[1]); + + + // side 3 + CROSS(sn, e3, n); + dNormalize3(sn); + SMULT( SolidPlanes[2], sn, -1.0 ); + + ADD(tmp1, col_v[2], col_v[1]); + SMULT(tmp1, tmp1, 0.5); // center of edge + // distance from center to edge along normal + SolidPlanes[2][3] = dCalcVectorDot3(tmp1, SolidPlanes[2]); + + FindTriSolidIntrsection(pen_v, SolidPlanes, 3, secondClippedTri); + + for (int j=0; j<secondClippedTri.Count; j++) { + secondClippedTri.Points[j][3] = 1.0; // because we will be doing matrix mults + + DEPTH(dp, CoplanarPt, secondClippedTri.Points[j], n); + + if (pen_v == v1) { + dMultiply1(orig_pos, InvMatrix1, secondClippedTri.Points[j], 4, 4, 1); + dMultiply1(old_pos1, ((dxTriMesh*)g1)->m_last_trans, orig_pos, 4, 4, 1); + for (int k=0; k<3; k++) { + secondClippedElt[j][k] = (secondClippedTri.Points[j][k] - old_pos1[k]) - elt2[k]; + } + } + else { + dMultiply1(orig_pos, InvMatrix2, secondClippedTri.Points[j], 4, 4, 1); + dMultiply1(old_pos2, ((dxTriMesh*)g2)->m_last_trans, orig_pos, 4, 4, 1); + for (int k=0; k<3; k++) { + secondClippedElt[j][k] = (secondClippedTri.Points[j][k] - old_pos2[k]) - elt1[k]; + } + } + + + if (dp >= 0.0) { + contact_elt_length = dFabs(dCalcVectorDot3(secondClippedElt[j],n)); + + depth = dp; + if (depth == 0.0) + depth = dMin(DISTANCE_EPSILON, contact_elt_length); + + if ((contact_elt_length < SMALL_ELT) && (depth < EXPANDED_ELT_THRESH)) + depth = contact_elt_length; + + if (depth <= contact_elt_length) { + // Add a contact + GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, + secondClippedTri.Points[j], n, depth, OutTriCount); + badPen = false; + + if ((OutTriCount | CONTACTS_UNIMPORTANT) == (Flags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) { + break; + } + } + } + + + } + } + + + + ///////////////// + // All conventional tests have failed at this point, so now we deal with + // cases on a more "heuristic" basis + // + + if (badPen) { + // Switch pen_v and n (for the fourth time, so they're + // what my original guess said they were) + SwapNormals(pen_v, col_v, v1, v2, pen_elt, elt_f1, elt_f2, n, n1, n2); + + if (dFabs(dCalcVectorDot3(n1, n2)) < REAL(0.01)) { + // If we reach this point, we have (close to) perpindicular + // faces, either resting on each other or sliding in a + // direction orthogonal to both surface normals. + if (elt_sum_len < DISTANCE_EPSILON) { + depth = dFabs(dCalcVectorDot3(n, elt_sum)); + + if (depth > REAL(1e-12)) { + dNormalize3(n); + GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, + CoplanarPt, n, depth, OutTriCount); + badPen = false; + } + else { + // If the two faces are (nearly) perfectly at rest with + // respect to each other, then we ignore the contact, + // allowing the objects to slip a little in the hopes + // that next frame, they'll give us something to work + // with. + badPen = false; + } + } + else { + // The faces are perpindicular, but moving significantly + // This can be sliding, or an unusual edge-straddling + // penetration. + dVector3 cn; + + CROSS(cn, n1, n2); + dNormalize3(cn); + SET(n, cn); + + // The shallowest ineterpenetration of the faces + // is the depth + dVector3 ContactPt; + dVector3 dvTmp; + dReal rTmp; + depth = dInfinity; + for (int j=0; j<3; j++) { + for (int k=0; k<3; k++) { + SUB(dvTmp, col_v[k], pen_v[j]); + + rTmp = dCalcVectorDot3(dvTmp, n); + if ( dFabs(rTmp) < dFabs(depth) ) { + depth = rTmp; + SET( ContactPt, pen_v[j] ); + contact_elt_length = dFabs(dCalcVectorDot3(pen_elt[j], n)); + } + } + } + if (depth < 0.0) { + SMULT(n, n, -1.0); + depth *= -1.0; + } + + if ((depth > 0.0) && (depth <= contact_elt_length)) { + GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, + ContactPt, n, depth, OutTriCount); + badPen = false; + } + + } + } + } + + + if (badPen && elt_sum_len != 0.0) { + // Use as the normal the direction of travel, rather than any particular + // face normal + // + dVector3 esn; + + if (pen_v == v1) { + SMULT(esn, elt_sum, -1.0); + } + else { + SET(esn, elt_sum); + } + dNormalize3(esn); + + + // The shallowest ineterpenetration of the faces + // is the depth + dVector3 ContactPt; + depth = dInfinity; + for (int j=0; j<3; j++) { + for (int k=0; k<3; k++) { + DEPTH(dp, col_v[k], pen_v[j], esn); + if ( (ExamineContactPoint(col_v, esn, pen_v[j])) && + ( dFabs(dp) < dFabs(depth)) ) { + depth = dp; + SET( ContactPt, pen_v[j] ); + contact_elt_length = dFabs(dCalcVectorDot3(pen_elt[j], esn)); + } + } + } + + if ((depth > 0.0) && (depth <= contact_elt_length)) { + GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, + ContactPt, esn, depth, OutTriCount); + badPen = false; + } + } + + + if (badPen && elt_sum_len != 0.0) { + // If the direction of motion is perpindicular to both normals + if ( (dFabs(dCalcVectorDot3(n1, elt_sum)) < REAL(0.01)) && (dFabs(dCalcVectorDot3(n2, elt_sum)) < REAL(0.01)) ) { + dVector3 esn; + if (pen_v == v1) { + SMULT(esn, elt_sum, -1.0); + } + else { + SET(esn, elt_sum); + } + + dNormalize3(esn); + + + // Look at the clipped points again, checking them against this + // new normal + for (int j=0; j<firstClippedTri.Count; j++) { + DEPTH(dp, CoplanarPt, firstClippedTri.Points[j], esn); + + if (dp >= 0.0) { + contact_elt_length = dFabs(dCalcVectorDot3(firstClippedElt[j], esn)); + + depth = dp; + //if (depth == 0.0) + //depth = dMin(DISTANCE_EPSILON, contact_elt_length); + + if ((contact_elt_length < SMALL_ELT) && (depth < EXPANDED_ELT_THRESH)) + depth = contact_elt_length; + + if (depth <= contact_elt_length) { + // Add a contact + GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, + firstClippedTri.Points[j], esn, depth, OutTriCount); + badPen = false; + + if ((OutTriCount | CONTACTS_UNIMPORTANT) == (Flags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) { + break; + } + } + } + } + + if (badPen) { + // If this test failed, try it with the second set of clipped faces + for (int j=0; j<secondClippedTri.Count; j++) { + DEPTH(dp, CoplanarPt, secondClippedTri.Points[j], esn); + + if (dp >= 0.0) { + contact_elt_length = dFabs(dCalcVectorDot3(secondClippedElt[j], esn)); + + depth = dp; + //if (depth == 0.0) + //depth = dMin(DISTANCE_EPSILON, contact_elt_length); + + if ((contact_elt_length < SMALL_ELT) && (depth < EXPANDED_ELT_THRESH)) + depth = contact_elt_length; + + if (depth <= contact_elt_length) { + // Add a contact + GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, + secondClippedTri.Points[j], esn, depth, OutTriCount); + badPen = false; + + if ((OutTriCount | CONTACTS_UNIMPORTANT) == (Flags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) { + break; + } + } + } + } + } + } + } + + + + if (badPen) { + // if we have very little motion, we're dealing with resting contact + // and shouldn't reference the ELTs at all + // + if (elt_sum_len < VELOCITY_EPSILON) { + + // instead of a "contact_elt_length" threshhold, we'll use an + // arbitrary, small one + for (int j=0; j<3; j++) { + DEPTH(dp, CoplanarPt, pen_v[j], n); + + if (dp == 0.0) + dp = TINY_PENETRATION; + + if ( (dp > 0.0) && (dp <= SMALL_ELT)) { + // Add a contact + GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, + pen_v[j], n, dp, OutTriCount); + badPen = false; + + if ((OutTriCount | CONTACTS_UNIMPORTANT) == (Flags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) { + break; + } + } + } + + + if (badPen) { + // try the other normal + SwapNormals(pen_v, col_v, v1, v2, pen_elt, elt_f1, elt_f2, n, n1, n2); + + for (int j=0; j<3; j++) { + DEPTH(dp, CoplanarPt, pen_v[j], n); + + if (dp == 0.0) + dp = TINY_PENETRATION; + + if ( (dp > 0.0) && (dp <= SMALL_ELT)) { + GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, + pen_v[j], n, dp, OutTriCount); + badPen = false; + + if ((OutTriCount | CONTACTS_UNIMPORTANT) == (Flags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) { + break; + } + } + } + } + + + + } + } + + if (badPen) { + // find the nearest existing contact, and replicate it's + // normal and depth + // + dContactGeom* Contact; + dVector3 pos_diff; + dReal min_dist, dist; + + min_dist = dInfinity; + depth = 0.0; + for (int j=0; j<OutTriCount; j++) { + Contact = SAFECONTACT(Flags, Contacts, j, Stride); + + SUB(pos_diff, Contact->pos, CoplanarPt); + + dist = dCalcVectorDot3(pos_diff, pos_diff); + if (dist < min_dist) { + min_dist = dist; + depth = Contact->depth; + SMULT(ContactNormal, Contact->normal, -1.0); + } + } + + if (depth > 0.0) { + // Add a tiny contact at the coplanar point + GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, + CoplanarPt, ContactNormal, depth, OutTriCount); + badPen = false; + } + } + + + if (badPen) { + // Add a tiny contact at the coplanar point + if (-dCalcVectorDot3(elt_sum, n1) > -dCalcVectorDot3(elt_sum, n2)) { + SET(ContactNormal, n1); + } + else { + SET(ContactNormal, n2); + } + + GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, id1, id2, + CoplanarPt, ContactNormal, TINY_PENETRATION, OutTriCount); + badPen = false; + } + + + } // not coplanar (main loop) + } // TriTriIntersectWithIsectLine + + if ((OutTriCount | CONTACTS_UNIMPORTANT) == (Flags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) { + break; + } + } + + // Free memory + delete[] firstClippedElt; + delete[] secondClippedElt; + + // Return the number of contacts + return OutTriCount; + } + } + } + + + // There was some kind of failure during the Collide call or + // there are no faces overlapping + return 0; +} + + +/* -- not used +static void +GetTriangleGeometryCallback(udword triangleindex, VertexPointers& triangle, udword user_data) +{ +dVector3 Out[3]; + +FetchTriangle((dxTriMesh*) user_data, (int) triangleindex, Out); + +for (int i = 0; i < 3; i++) +triangle.Vertex[i] = (const Point*) ((dReal*) Out[i]); +} +*/ + +// +// +// +#define B11 B[0] +#define B12 B[1] +#define B13 B[2] +#define B14 B[3] +#define B21 B[4] +#define B22 B[5] +#define B23 B[6] +#define B24 B[7] +#define B31 B[8] +#define B32 B[9] +#define B33 B[10] +#define B34 B[11] +#define B41 B[12] +#define B42 B[13] +#define B43 B[14] +#define B44 B[15] + +#define Binv11 Binv[0] +#define Binv12 Binv[1] +#define Binv13 Binv[2] +#define Binv14 Binv[3] +#define Binv21 Binv[4] +#define Binv22 Binv[5] +#define Binv23 Binv[6] +#define Binv24 Binv[7] +#define Binv31 Binv[8] +#define Binv32 Binv[9] +#define Binv33 Binv[10] +#define Binv34 Binv[11] +#define Binv41 Binv[12] +#define Binv42 Binv[13] +#define Binv43 Binv[14] +#define Binv44 Binv[15] + +inline void +dMakeMatrix4(const dVector3 Position, const dMatrix3 Rotation, dMatrix4 &B) +{ + B11 = Rotation[0]; B21 = Rotation[1]; B31 = Rotation[2]; B41 = Position[0]; + B12 = Rotation[4]; B22 = Rotation[5]; B32 = Rotation[6]; B42 = Position[1]; + B13 = Rotation[8]; B23 = Rotation[9]; B33 = Rotation[10]; B43 = Position[2]; + + B14 = 0.0; B24 = 0.0; B34 = 0.0; B44 = 1.0; +} + + +static void +dInvertMatrix4( dMatrix4& B, dMatrix4& Binv ) +{ + dReal det = (B11 * B22 - B12 * B21) * (B33 * B44 - B34 * B43) + -(B11 * B23 - B13 * B21) * (B32 * B44 - B34 * B42) + +(B11 * B24 - B14 * B21) * (B32 * B43 - B33 * B42) + +(B12 * B23 - B13 * B22) * (B31 * B44 - B34 * B41) + -(B12 * B24 - B14 * B22) * (B31 * B43 - B33 * B41) + +(B13 * B24 - B14 * B23) * (B31 * B42 - B32 * B41); + + dAASSERT (det != 0.0); + + det = 1.0 / det; + + Binv11 = (dReal) (det * ((B22 * B33) - (B23 * B32))); + Binv12 = (dReal) (det * ((B32 * B13) - (B33 * B12))); + Binv13 = (dReal) (det * ((B12 * B23) - (B13 * B22))); + Binv14 = 0.0f; + Binv21 = (dReal) (det * ((B23 * B31) - (B21 * B33))); + Binv22 = (dReal) (det * ((B33 * B11) - (B31 * B13))); + Binv23 = (dReal) (det * ((B13 * B21) - (B11 * B23))); + Binv24 = 0.0f; + Binv31 = (dReal) (det * ((B21 * B32) - (B22 * B31))); + Binv32 = (dReal) (det * ((B31 * B12) - (B32 * B11))); + Binv33 = (dReal) (det * ((B11 * B22) - (B12 * B21))); + Binv34 = 0.0f; + Binv41 = (dReal) (det * (B21*(B33*B42 - B32*B43) + B22*(B31*B43 - B33*B41) + B23*(B32*B41 - B31*B42))); + Binv42 = (dReal) (det * (B31*(B13*B42 - B12*B43) + B32*(B11*B43 - B13*B41) + B33*(B12*B41 - B11*B42))); + Binv43 = (dReal) (det * (B41*(B13*B22 - B12*B23) + B42*(B11*B23 - B13*B21) + B43*(B12*B21 - B11*B22))); + Binv44 = 1.0f; +} + + + +///////////////////////////////////////////////// +// +// Triangle/Triangle intersection utilities +// +// From the article "A Fast Triangle-Triangle Intersection Test", +// Journal of Graphics Tools, 2(2), 1997 +// +// Some of this functionality is duplicated in OPCODE (see +// OPC_TriTriOverlap.h) but we have replicated it here so we don't +// have to mess with the internals of OPCODE, as well as so we can +// further optimize some of the functions. +// +// This version computes the line of intersection as well (if they +// are not coplanar): +// int TriTriIntersectWithIsectLine(dReal V0[3],dReal V1[3],dReal V2[3], +// dReal U0[3],dReal U1[3],dReal U2[3], +// int *coplanar, +// dReal isectpt1[3],dReal isectpt2[3]); +// +// parameters: vertices of triangle 1: V0,V1,V2 +// vertices of triangle 2: U0,U1,U2 +// +// result : returns 1 if the triangles intersect, otherwise 0 +// "coplanar" returns whether the tris are coplanar +// isectpt1, isectpt2 are the endpoints of the line of +// intersection +// + + + +/* if USE_EPSILON_TEST is true then we do a check: + if |dv|<EPSILON then dv=0.0; + else no check is done (which is less robust) +*/ +#define USE_EPSILON_TEST TRUE +#define EPSILON REAL(0.000001) + + +/* sort so that a<=b */ +#define SORT(a,b) \ + if(a>b) \ + { \ + dReal c; \ + c=a; \ + a=b; \ + b=c; \ + } + +#define ISECT(VV0,VV1,VV2,D0,D1,D2,isect0,isect1) \ + isect0=VV0+(VV1-VV0)*D0/(D0-D1); \ + isect1=VV0+(VV2-VV0)*D0/(D0-D2); + + +#define COMPUTE_INTERVALS(VV0,VV1,VV2,D0,D1,D2,D0D1,D0D2,isect0,isect1) \ + 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 */ \ + ISECT(VV2,VV0,VV1,D2,D0,D1,isect0,isect1); \ + } \ + else if(D0D2>0.0f) \ + { \ + /* here we know that d0d1<=0.0 */ \ + ISECT(VV1,VV0,VV2,D1,D0,D2,isect0,isect1); \ + } \ + else if(D1*D2>0.0f || D0!=0.0f) \ + { \ + /* here we know that d0d1<=0.0 or that D0!=0.0 */ \ + ISECT(VV0,VV1,VV2,D0,D1,D2,isect0,isect1); \ + } \ + else if(D1!=0.0f) \ + { \ + ISECT(VV1,VV0,VV2,D1,D0,D2,isect0,isect1); \ + } \ + else if(D2!=0.0f) \ + { \ + ISECT(VV2,VV0,VV1,D2,D0,D1,isect0,isect1); \ + } \ + else \ + { \ + /* triangles are coplanar */ \ + return coplanar_tri_tri(N1,V0,V1,V2,U0,U1,U2); \ + } + + + +/* this edge to edge test is based on Franlin Antonio's gem: +"Faster Line Segment Intersection", in Graphics Gems III, +pp. 199-202 */ +#define EDGE_EDGE_TEST(V0,U0,U1) \ + Bx=U0[i0]-U1[i0]; \ + By=U0[i1]-U1[i1]; \ + Cx=V0[i0]-U0[i0]; \ + Cy=V0[i1]-U0[i1]; \ + f=Ay*Bx-Ax*By; \ + d=By*Cx-Bx*Cy; \ + if((f>0 && d>=0 && d<=f) || (f<0 && d<=0 && d>=f)) \ + { \ + e=Ax*Cy-Ay*Cx; \ + if(f>0) \ + { \ + if(e>=0 && e<=f) return 1; \ + } \ + else \ + { \ + if(e<=0 && e>=f) return 1; \ + } \ +} + +#define EDGE_AGAINST_TRI_EDGES(V0,V1,U0,U1,U2) \ +{ \ + dReal Ax,Ay,Bx,By,Cx,Cy,e,d,f; \ + Ax=V1[i0]-V0[i0]; \ + Ay=V1[i1]-V0[i1]; \ + /* test edge U0,U1 against V0,V1 */ \ + EDGE_EDGE_TEST(V0,U0,U1); \ + /* test edge U1,U2 against V0,V1 */ \ + EDGE_EDGE_TEST(V0,U1,U2); \ + /* test edge U2,U1 against V0,V1 */ \ + EDGE_EDGE_TEST(V0,U2,U0); \ +} + +#define POINT_IN_TRI(V0,U0,U1,U2) \ +{ \ + dReal a,b,c,d0,d1,d2; \ + /* is T1 completly inside T2? */ \ + /* check if V0 is inside tri(U0,U1,U2) */ \ + a=U1[i1]-U0[i1]; \ + b=-(U1[i0]-U0[i0]); \ + c=-a*U0[i0]-b*U0[i1]; \ + d0=a*V0[i0]+b*V0[i1]+c; \ + \ + a=U2[i1]-U1[i1]; \ + b=-(U2[i0]-U1[i0]); \ + c=-a*U1[i0]-b*U1[i1]; \ + d1=a*V0[i0]+b*V0[i1]+c; \ + \ + a=U0[i1]-U2[i1]; \ + b=-(U0[i0]-U2[i0]); \ + c=-a*U2[i0]-b*U2[i1]; \ + d2=a*V0[i0]+b*V0[i1]+c; \ + if(d0*d1>0.0) \ + { \ + if(d0*d2>0.0) return 1; \ + } \ +} + +int coplanar_tri_tri(dReal N[3],dReal V0[3],dReal V1[3],dReal V2[3], + dReal U0[3],dReal U1[3],dReal U2[3]) +{ + dReal A[3]; + short i0,i1; + /* first project onto an axis-aligned plane, that maximizes the area */ + /* of the triangles, compute indices: i0,i1. */ + A[0]= dFabs(N[0]); + A[1]= dFabs(N[1]); + A[2]= dFabs(N[2]); + if(A[0]>A[1]) + { + if(A[0]>A[2]) + { + i0=1; /* A[0] is greatest */ + i1=2; + } + else + { + i0=0; /* A[2] is greatest */ + i1=1; + } + } + else /* A[0]<=A[1] */ + { + if(A[2]>A[1]) + { + i0=0; /* A[2] is greatest */ + i1=1; + } + else + { + i0=0; /* A[1] is greatest */ + i1=2; + } + } + + /* test all edges of triangle 1 against the edges of triangle 2 */ + EDGE_AGAINST_TRI_EDGES(V0,V1,U0,U1,U2); + EDGE_AGAINST_TRI_EDGES(V1,V2,U0,U1,U2); + EDGE_AGAINST_TRI_EDGES(V2,V0,U0,U1,U2); + + /* finally, test if tri1 is totally contained in tri2 or vice versa */ + POINT_IN_TRI(V0,U0,U1,U2); + POINT_IN_TRI(U0,V0,V1,V2); + + return 0; +} + + + +#define NEWCOMPUTE_INTERVALS(VV0,VV1,VV2,D0,D1,D2,D0D1,D0D2,A,B,C,X0,X1) \ +{ \ + 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 */ \ + A=VV2; B=(VV0-VV2)*D2; C=(VV1-VV2)*D2; X0=D2-D0; X1=D2-D1; \ + } \ + else if(D0D2>0.0f)\ + { \ + /* here we know that d0d1<=0.0 */ \ + A=VV1; B=(VV0-VV1)*D1; C=(VV2-VV1)*D1; X0=D1-D0; X1=D1-D2; \ + } \ + else if(D1*D2>0.0f || D0!=0.0f) \ + { \ + /* here we know that d0d1<=0.0 or that D0!=0.0 */ \ + A=VV0; B=(VV1-VV0)*D0; C=(VV2-VV0)*D0; X0=D0-D1; X1=D0-D2; \ + } \ + else if(D1!=0.0f) \ + { \ + A=VV1; B=(VV0-VV1)*D1; C=(VV2-VV1)*D1; X0=D1-D0; X1=D1-D2; \ + } \ + else if(D2!=0.0f) \ + { \ + A=VV2; B=(VV0-VV2)*D2; C=(VV1-VV2)*D2; X0=D2-D0; X1=D2-D1; \ + } \ + else \ + { \ + /* triangles are coplanar */ \ + return coplanar_tri_tri(N1,V0,V1,V2,U0,U1,U2); \ + } \ +} + + + + +/* sort so that a<=b */ +#define SORT2(a,b,smallest) \ + if(a>b) \ + { \ + dReal c; \ + c=a; \ + a=b; \ + b=c; \ + smallest=1; \ + } \ + else smallest=0; + + +inline void isect2(dReal VTX0[3],dReal VTX1[3],dReal VTX2[3],dReal VV0,dReal VV1,dReal VV2, + dReal D0,dReal D1,dReal D2,dReal *isect0,dReal *isect1,dReal isectpoint0[3],dReal isectpoint1[3]) +{ + dReal tmp=D0/(D0-D1); + dReal diff[3]; + *isect0=VV0+(VV1-VV0)*tmp; + SUB(diff,VTX1,VTX0); + MULT(diff,diff,tmp); + ADD(isectpoint0,diff,VTX0); + tmp=D0/(D0-D2); + *isect1=VV0+(VV2-VV0)*tmp; + SUB(diff,VTX2,VTX0); + MULT(diff,diff,tmp); + ADD(isectpoint1,VTX0,diff); +} + + +#if 0 +#define ISECT2(VTX0,VTX1,VTX2,VV0,VV1,VV2,D0,D1,D2,isect0,isect1,isectpoint0,isectpoint1) \ + tmp=D0/(D0-D1); \ + isect0=VV0+(VV1-VV0)*tmp; \ + SUB(diff,VTX1,VTX0); \ + MULT(diff,diff,tmp); \ + ADD(isectpoint0,diff,VTX0); \ + tmp=D0/(D0-D2); + /*isect1=VV0+(VV2-VV0)*tmp; \ */ + /*SUB(diff,VTX2,VTX0); \ */ + /*MULT(diff,diff,tmp); \ */ + /*ADD(isectpoint1,VTX0,diff); */ +#endif + +inline int compute_intervals_isectline(dReal VERT0[3],dReal VERT1[3],dReal VERT2[3], + dReal VV0,dReal VV1,dReal VV2,dReal D0,dReal D1,dReal D2, + dReal D0D1,dReal D0D2,dReal *isect0,dReal *isect1, + dReal isectpoint0[3],dReal isectpoint1[3]) +{ + 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 */ + isect2(VERT2,VERT0,VERT1,VV2,VV0,VV1,D2,D0,D1,isect0,isect1,isectpoint0,isectpoint1); + } + else if(D0D2>0.0f) + { + /* here we know that d0d1<=0.0 */ + isect2(VERT1,VERT0,VERT2,VV1,VV0,VV2,D1,D0,D2,isect0,isect1,isectpoint0,isectpoint1); + } + else if(D1*D2>0.0f || D0!=0.0f) + { + /* here we know that d0d1<=0.0 or that D0!=0.0 */ + isect2(VERT0,VERT1,VERT2,VV0,VV1,VV2,D0,D1,D2,isect0,isect1,isectpoint0,isectpoint1); + } + else if(D1!=0.0f) + { + isect2(VERT1,VERT0,VERT2,VV1,VV0,VV2,D1,D0,D2,isect0,isect1,isectpoint0,isectpoint1); + } + else if(D2!=0.0f) + { + isect2(VERT2,VERT0,VERT1,VV2,VV0,VV1,D2,D0,D1,isect0,isect1,isectpoint0,isectpoint1); + } + else + { + /* triangles are coplanar */ + return 1; + } + return 0; +} + +#define COMPUTE_INTERVALS_ISECTLINE(VERT0,VERT1,VERT2,VV0,VV1,VV2,D0,D1,D2,D0D1,D0D2,isect0,isect1,isectpoint0,isectpoint1) \ + 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 */ \ + isect2(VERT2,VERT0,VERT1,VV2,VV0,VV1,D2,D0,D1,&isect0,&isect1,isectpoint0,isectpoint1); \ + } +#if 0 + else if(D0D2>0.0f) \ + { \ + /* here we know that d0d1<=0.0 */ \ + isect2(VERT1,VERT0,VERT2,VV1,VV0,VV2,D1,D0,D2,&isect0,&isect1,isectpoint0,isectpoint1); \ + } \ + else if(D1*D2>0.0f || D0!=0.0f) \ + { \ + /* here we know that d0d1<=0.0 or that D0!=0.0 */ \ + isect2(VERT0,VERT1,VERT2,VV0,VV1,VV2,D0,D1,D2,&isect0,&isect1,isectpoint0,isectpoint1); \ + } \ + else if(D1!=0.0f) \ + { \ + isect2(VERT1,VERT0,VERT2,VV1,VV0,VV2,D1,D0,D2,&isect0,&isect1,isectpoint0,isectpoint1); \ + } \ + else if(D2!=0.0f) \ + { \ + isect2(VERT2,VERT0,VERT1,VV2,VV0,VV1,D2,D0,D1,&isect0,&isect1,isectpoint0,isectpoint1); \ + } \ + else \ + { \ + /* triangles are coplanar */ \ + coplanar=1; \ + return coplanar_tri_tri(N1,V0,V1,V2,U0,U1,U2); \ + } +#endif + + + +static int TriTriIntersectWithIsectLine(dReal V0[3],dReal V1[3],dReal V2[3], + dReal U0[3],dReal U1[3],dReal U2[3],int *coplanar, + dReal isectpt1[3],dReal isectpt2[3]) +{ + dReal E1[3],E2[3]; + dReal N1[3],N2[3],d1,d2; + dReal du0,du1,du2,dv0,dv1,dv2; + dReal D[3]; + dReal isect1[2]={0,0}, isect2[2]={0,0}; + dReal isectpointA1[3],isectpointA2[3]; + dReal isectpointB1[3]={0,0,0},isectpointB2[3]={0,0,0}; + dReal du0du1,du0du2,dv0dv1,dv0dv2; + short index; + dReal vp0,vp1,vp2; + dReal up0,up1,up2; + dReal b,c,max; + int smallest1,smallest2; + + /* compute plane equation of triangle(V0,V1,V2) */ + SUB(E1,V1,V0); + SUB(E2,V2,V0); + CROSS(N1,E1,E2); + + // Even though all triangles might be initially valid, + // a triangle may degenerate into a segment after applying + // space transformation. + // + // Oleh_Derevenko: + // I'm not quite sure if this routine will fail/assert for zero normal + // (it's too large and complex to be fully analyzed). + // However in such a large code block three extra float comparisons + // will not have any noticeable influence on performance. + if (IS_ZERO(N1)) + return 0; + + d1=-DOT(N1,V0); + /* plane equation 1: N1.X+d1=0 */ + + /* put U0,U1,U2 into plane equation 1 to compute signed distances to the plane*/ + du0=DOT(N1,U0)+d1; + du1=DOT(N1,U1)+d1; + du2=DOT(N1,U2)+d1; + + /* coplanarity robustness check */ +#if USE_EPSILON_TEST==TRUE + if(dFabs(du0)<EPSILON) du0=0.0; + if(dFabs(du1)<EPSILON) du1=0.0; + if(dFabs(du2)<EPSILON) du2=0.0; +#endif + du0du1=du0*du1; + du0du2=du0*du2; + + if(du0du1>0.0f && du0du2>0.0f) /* same sign on all of them + not equal 0 ? */ + return 0; /* no intersection occurs */ + + /* compute plane of triangle (U0,U1,U2) */ + SUB(E1,U1,U0); + SUB(E2,U2,U0); + CROSS(N2,E1,E2); + + // Even though all triangles might be initially valid, + // a triangle may degenerate into a segment after applying + // space transformation. + // + // Oleh_Derevenko: + // I'm not quite sure if this routine will fail/assert for zero normal + // (it's too large and complex to be fully analyzed). + // However in such a large code block three extra float comparisons + // will not have any noticeable influence on performance. + if (IS_ZERO(N2)) + return 0; + + d2=-DOT(N2,U0); + /* plane equation 2: N2.X+d2=0 */ + + /* put V0,V1,V2 into plane equation 2 */ + dv0=DOT(N2,V0)+d2; + dv1=DOT(N2,V1)+d2; + dv2=DOT(N2,V2)+d2; + +#if USE_EPSILON_TEST==TRUE + if(dFabs(dv0)<EPSILON) dv0=0.0; + if(dFabs(dv1)<EPSILON) dv1=0.0; + if(dFabs(dv2)<EPSILON) dv2=0.0; +#endif + + dv0dv1=dv0*dv1; + dv0dv2=dv0*dv2; + + if(dv0dv1>0.0f && dv0dv2>0.0f) /* same sign on all of them + not equal 0 ? */ + return 0; /* no intersection occurs */ + + /* compute direction of intersection line */ + CROSS(D,N1,N2); + + /* compute and index to the largest component of D */ + max= dFabs(D[0]); + index=0; + b= dFabs(D[1]); + c= dFabs(D[2]); + if(b>max) max=b,index=1; + if(c>max) max=c,index=2; + + /* this is the simplified projection onto L*/ + vp0=V0[index]; + vp1=V1[index]; + vp2=V2[index]; + + up0=U0[index]; + up1=U1[index]; + up2=U2[index]; + + /* compute interval for triangle 1 */ + *coplanar=compute_intervals_isectline(V0,V1,V2,vp0,vp1,vp2,dv0,dv1,dv2, + dv0dv1,dv0dv2,&isect1[0],&isect1[1],isectpointA1,isectpointA2); + if(*coplanar) return coplanar_tri_tri(N1,V0,V1,V2,U0,U1,U2); + + + /* compute interval for triangle 2 */ + compute_intervals_isectline(U0,U1,U2,up0,up1,up2,du0,du1,du2, + du0du1,du0du2,&isect2[0],&isect2[1],isectpointB1,isectpointB2); + + SORT2(isect1[0],isect1[1],smallest1); + SORT2(isect2[0],isect2[1],smallest2); + + if(isect1[1]<isect2[0] || isect2[1]<isect1[0]) return 0; + + /* at this point, we know that the triangles intersect */ + + if(isect2[0]<isect1[0]) + { + if(smallest1==0) { SET(isectpt1,isectpointA1); } + else { SET(isectpt1,isectpointA2); } + + if(isect2[1]<isect1[1]) + { + if(smallest2==0) { SET(isectpt2,isectpointB2); } + else { SET(isectpt2,isectpointB1); } + } + else + { + if(smallest1==0) { SET(isectpt2,isectpointA2); } + else { SET(isectpt2,isectpointA1); } + } + } + else + { + if(smallest2==0) { SET(isectpt1,isectpointB1); } + else { SET(isectpt1,isectpointB2); } + + if(isect2[1]>isect1[1]) + { + if(smallest1==0) { SET(isectpt2,isectpointA2); } + else { SET(isectpt2,isectpointA1); } + } + else + { + if(smallest2==0) { SET(isectpt2,isectpointB2); } + else { SET(isectpt2,isectpointB1); } + } + } + return 1; +} + + + + + +// Find the intersectiojn point between a coplanar line segement, +// defined by X1 and X2, and a ray defined by X3 and direction N. +// +// This forumla for this calculation is: +// (c x b) . (a x b) +// Q = x1 + a ------------------- +// | a x b | ^2 +// +// where a = x2 - x1 +// b = x4 - x3 +// c = x3 - x1 +// x1 and x2 are the edges of the triangle, and x3 is CoplanarPt +// and x4 is (CoplanarPt - n) +#if 0 // not used anywhere +static int + IntersectLineSegmentRay(dVector3 x1, dVector3 x2, dVector3 x3, dVector3 n, + dVector3 out_pt) +{ + dVector3 a, b, c, x4; + + ADD(x4, x3, n); // x4 = x3 + n + + SUB(a, x2, x1); // a = x2 - x1 + SUB(b, x4, x3); + SUB(c, x3, x1); + + dVector3 tmp1, tmp2; + CROSS(tmp1, c, b); + CROSS(tmp2, a, b); + + dReal num, denom; + num = dCalcVectorDot3(tmp1, tmp2); + denom = LENGTH( tmp2 ); + + dReal s; + s = num /(denom*denom); + + for (int i=0; i<3; i++) + out_pt[i] = x1[i] + a[i]*s; + + // Test if this intersection is "behind" x3, w.r.t. n + SUB(a, x3, out_pt); + if (dCalcVectorDot3(a, n) > 0.0) + return 0; + + // Test if this intersection point is outside the edge limits, + // if (dot( (out_pt-x1), (out_pt-x2) ) < 0) it's inside + // else outside + SUB(a, out_pt, x1); + SUB(b, out_pt, x2); + if (dCalcVectorDot3(a,b) < 0.0) + return 1; + else + return 0; +} +#endif + +// FindTriSolidIntersection - Clips the input trinagle TRI with the +// sides of a convex bounding solid, described by PLANES, returning +// the (convex) clipped polygon in CLIPPEDPOLYGON +// +static bool + FindTriSolidIntrsection(const dVector3 Tri[3], + const dVector4 Planes[6], int numSides, + LineContactSet& ClippedPolygon ) +{ + // Set up the LineContactSet structure + for (int k=0; k<3; k++) { + SET(ClippedPolygon.Points[k], Tri[k]); + } + ClippedPolygon.Count = 3; + + // Clip wrt the sides + for ( int i = 0; i < numSides; i++ ) + ClipConvexPolygonAgainstPlane( Planes[i], Planes[i][3], ClippedPolygon ); + + return (ClippedPolygon.Count > 0); +} + + + + +// ClipConvexPolygonAgainstPlane - Clip a a convex polygon, described by +// CONTACTS, with a plane (described by N and C). Note: the input +// vertices are assumed to be in counterclockwise order. +// +// This code is taken from The Nebula Device: +// http://nebuladevice.sourceforge.net/cgi-bin/twiki/view/Nebula/WebHome +// and is licensed under the following license: +// http://nebuladevice.sourceforge.net/doc/source/license.txt +// +static void ClipConvexPolygonAgainstPlane( const dVector3 N, dReal C, LineContactSet& Contacts ) +{ + // test on which side of line are the vertices + int Positive = 0, Negative = 0, PIndex = -1; + int Quantity = Contacts.Count; + + dReal Test[8]; + for ( int i = 0; i < Contacts.Count; i++ ) { + // An epsilon is used here because it is possible for the dot product + // and C to be exactly equal to each other (in theory), but differ + // slightly because of floating point problems. Thus, add a little + // to the test number to push actually equal numbers over the edge + // towards the positive. This should probably be somehow a relative + // tolerance, and I don't think multiplying by the constant is the best + // way to do this. + Test[i] = dCalcVectorDot3(N, Contacts.Points[i]) - C + dFabs(C)*REAL(1e-08); + + if (Test[i] >= REAL(0.0)) { + Positive++; + if (PIndex < 0) { + PIndex = i; + } + } + else Negative++; + } + + if (Positive > 0) { + if (Negative > 0) { + // plane transversely intersects polygon + dVector3 CV[8]; + int CQuantity = 0, Cur, Prv; + dReal T; + + if (PIndex > 0) { + // first clip vertex on line + Cur = PIndex; + Prv = Cur - 1; + T = Test[Cur] / (Test[Cur] - Test[Prv]); + CV[CQuantity][0] = Contacts.Points[Cur][0] + + T * (Contacts.Points[Prv][0] - Contacts.Points[Cur][0]); + CV[CQuantity][1] = Contacts.Points[Cur][1] + + T * (Contacts.Points[Prv][1] - Contacts.Points[Cur][1]); + CV[CQuantity][2] = Contacts.Points[Cur][2] + + T * (Contacts.Points[Prv][2] - Contacts.Points[Cur][2]); + CV[CQuantity][3] = Contacts.Points[Cur][3] + + T * (Contacts.Points[Prv][3] - Contacts.Points[Cur][3]); + CQuantity++; + + // vertices on positive side of line + while (Cur < Quantity && Test[Cur] >= REAL(0.0)) { + CV[CQuantity][0] = Contacts.Points[Cur][0]; + CV[CQuantity][1] = Contacts.Points[Cur][1]; + CV[CQuantity][2] = Contacts.Points[Cur][2]; + CV[CQuantity][3] = Contacts.Points[Cur][3]; + CQuantity++; + Cur++; + } + + // last clip vertex on line + if (Cur < Quantity) { + Prv = Cur - 1; + } + else { + Cur = 0; + Prv = Quantity - 1; + } + + T = Test[Cur] / (Test[Cur] - Test[Prv]); + CV[CQuantity][0] = Contacts.Points[Cur][0] + + T * (Contacts.Points[Prv][0] - Contacts.Points[Cur][0]); + CV[CQuantity][1] = Contacts.Points[Cur][1] + + T * (Contacts.Points[Prv][1] - Contacts.Points[Cur][1]); + CV[CQuantity][2] = Contacts.Points[Cur][2] + + T * (Contacts.Points[Prv][2] - Contacts.Points[Cur][2]); + CV[CQuantity][3] = Contacts.Points[Cur][3] + + T * (Contacts.Points[Prv][3] - Contacts.Points[Cur][3]); + CQuantity++; + } + else { + // iPIndex is 0 + // vertices on positive side of line + Cur = 0; + while (Cur < Quantity && Test[Cur] >= REAL(0.0)) { + CV[CQuantity][0] = Contacts.Points[Cur][0]; + CV[CQuantity][1] = Contacts.Points[Cur][1]; + CV[CQuantity][2] = Contacts.Points[Cur][2]; + CV[CQuantity][3] = Contacts.Points[Cur][3]; + CQuantity++; + Cur++; + } + + // last clip vertex on line + Prv = Cur - 1; + T = Test[Cur] / (Test[Cur] - Test[Prv]); + CV[CQuantity][0] = Contacts.Points[Cur][0] + + T * (Contacts.Points[Prv][0] - Contacts.Points[Cur][0]); + CV[CQuantity][1] = Contacts.Points[Cur][1] + + T * (Contacts.Points[Prv][1] - Contacts.Points[Cur][1]); + CV[CQuantity][2] = Contacts.Points[Cur][2] + + T * (Contacts.Points[Prv][2] - Contacts.Points[Cur][2]); + CV[CQuantity][3] = Contacts.Points[Cur][3] + + T * (Contacts.Points[Prv][3] - Contacts.Points[Cur][3]); + CQuantity++; + + // skip vertices on negative side + while (Cur < Quantity && Test[Cur] < REAL(0.0)) { + Cur++; + } + + // first clip vertex on line + if (Cur < Quantity) { + Prv = Cur - 1; + T = Test[Cur] / (Test[Cur] - Test[Prv]); + CV[CQuantity][0] = Contacts.Points[Cur][0] + + T * (Contacts.Points[Prv][0] - Contacts.Points[Cur][0]); + CV[CQuantity][1] = Contacts.Points[Cur][1] + + T * (Contacts.Points[Prv][1] - Contacts.Points[Cur][1]); + CV[CQuantity][2] = Contacts.Points[Cur][2] + + T * (Contacts.Points[Prv][2] - Contacts.Points[Cur][2]); + CV[CQuantity][3] = Contacts.Points[Cur][3] + + T * (Contacts.Points[Prv][3] - Contacts.Points[Cur][3]); + CQuantity++; + + // vertices on positive side of line + while (Cur < Quantity && Test[Cur] >= REAL(0.0)) { + CV[CQuantity][0] = Contacts.Points[Cur][0]; + CV[CQuantity][1] = Contacts.Points[Cur][1]; + CV[CQuantity][2] = Contacts.Points[Cur][2]; + CV[CQuantity][3] = Contacts.Points[Cur][3]; + CQuantity++; + Cur++; + } + } + else { + // iCur = 0 + Prv = Quantity - 1; + T = Test[0] / (Test[0] - Test[Prv]); + CV[CQuantity][0] = Contacts.Points[0][0] + + T * (Contacts.Points[Prv][0] - Contacts.Points[0][0]); + CV[CQuantity][1] = Contacts.Points[0][1] + + T * (Contacts.Points[Prv][1] - Contacts.Points[0][1]); + CV[CQuantity][2] = Contacts.Points[0][2] + + T * (Contacts.Points[Prv][2] - Contacts.Points[0][2]); + CV[CQuantity][3] = Contacts.Points[0][3] + + T * (Contacts.Points[Prv][3] - Contacts.Points[0][3]); + CQuantity++; + } + } + Quantity = CQuantity; + memcpy( Contacts.Points, CV, CQuantity * sizeof(dVector3) ); + } + // else polygon fully on positive side of plane, nothing to do + Contacts.Count = Quantity; + } + else { + Contacts.Count = 0; // This should not happen, but for safety + } + +} + + + +// Determine if a potential collision point is +// +// +static int +ExamineContactPoint(dVector3* v_col, dVector3 in_n, dVector3 in_point) +{ + // Cast a ray from in_point, along the collison normal. Does it intersect the + // collision face. + dReal t, u, v; + + if (!RayTriangleIntersect(in_point, in_n, v_col[0], v_col[1], v_col[2], + &t, &u, &v)) + return 0; + else + return 1; +} + + + +// RayTriangleIntersect - If an intersection is found, t contains the +// distance along the ray (dir) and u/v contain u/v coordinates into +// the triangle. Returns 0 if no hit is found +// From "Real-Time Rendering," page 305 +// +static int +RayTriangleIntersect(const dVector3 orig, const dVector3 dir, + const dVector3 vert0, const dVector3 vert1,const dVector3 vert2, + dReal *t,dReal *u,dReal *v) + +{ + dReal edge1[3], edge2[3], tvec[3], pvec[3], qvec[3]; + dReal det,inv_det; + + // find vectors for two edges sharing vert0 + SUB(edge1, vert1, vert0); + SUB(edge2, vert2, vert0); + + // begin calculating determinant - also used to calculate U parameter + CROSS(pvec, dir, edge2); + + // if determinant is near zero, ray lies in plane of triangle + det = DOT(edge1, pvec); + + if ((det > REAL(-0.001)) && (det < REAL(0.001))) + return 0; + inv_det = 1.0 / det; + + // calculate distance from vert0 to ray origin + SUB(tvec, orig, vert0); + + // calculate U parameter and test bounds + *u = DOT(tvec, pvec) * inv_det; + if ((*u < 0.0) || (*u > 1.0)) + return 0; + + // prepare to test V parameter + CROSS(qvec, tvec, edge1); + + // calculate V parameter and test bounds + *v = DOT(dir, qvec) * inv_det; + if ((*v < 0.0) || ((*u + *v) > 1.0)) + return 0; + + // calculate t, ray intersects triangle + *t = DOT(edge2, qvec) * inv_det; + + return 1; +} + + + +static bool +SimpleUnclippedTest(dVector3 in_CoplanarPt, dVector3 in_v, dVector3 in_elt, + dVector3 in_n, dVector3* in_col_v, dReal &out_depth) +{ + dReal dp = 0.0; + dReal contact_elt_length; + + DEPTH(dp, in_CoplanarPt, in_v, in_n); + + if (dp >= 0.0) { + // if the penetration depth (calculated above) is more than + // the contact point's ELT, then we've chosen the wrong face + // and should switch faces + contact_elt_length = dFabs(dCalcVectorDot3(in_elt, in_n)); + + if (dp == 0.0) + dp = dMin(DISTANCE_EPSILON, contact_elt_length); + + if ((contact_elt_length < SMALL_ELT) && (dp < EXPANDED_ELT_THRESH)) + dp = contact_elt_length; + + if ( (dp > 0.0) && (dp <= contact_elt_length)) { + // Add a contact + + if ( ExamineContactPoint(in_col_v, in_n, in_v) ) { + out_depth = dp; + return true; + } + } + } + + return false; +} + + + + +// Generate a "unique" contact. A unique contact has a unique +// position or normal. If the potential contact has the same +// position and normal as an existing contact, but a larger +// penetration depth, this new depth is used instead +// +static void +GenerateContact(int in_Flags, dContactGeom* in_Contacts, int in_Stride, + dxTriMesh* in_TriMesh1, dxTriMesh* in_TriMesh2, + int TriIndex1, int TriIndex2, + const dVector3 in_ContactPos, const dVector3 in_Normal, dReal in_Depth, + int& OutTriCount) +{ + /* + NOTE by Oleh_Derevenko: + This function is called after maximal number of contacts has already been + collected because it has a side effect of replacing penetration depth of + existing contact with larger penetration depth of another matching normal contact. + If this logic is not necessary any more, you can bail out on reach of contact + number maximum immediately in dCollideTTL(). You will also need to correct + conditional statements after invocations of GenerateContact() in dCollideTTL(). + */ + dIASSERT(in_Depth >= 0.0); + //if (in_Depth < 0.0) -- the function is always called with depth >= 0 + // return; + + do + { + dContactGeom* Contact; + dVector3 diff; + + if (!(in_Flags & CONTACTS_UNIMPORTANT)) + { + bool duplicate = false; + + for (int i=0; i<OutTriCount; i++) + { + Contact = SAFECONTACT(in_Flags, in_Contacts, i, in_Stride); + + // same position? + SUB(diff, in_ContactPos, Contact->pos); + if (dCalcVectorDot3(diff, diff) < dEpsilon) + { + // same normal? + if (REAL(1.0) - dFabs(dCalcVectorDot3(in_Normal, Contact->normal)) < dEpsilon) + { + if (in_Depth > Contact->depth) { + Contact->depth = in_Depth; + SMULT( Contact->normal, in_Normal, -1.0); + Contact->normal[3] = 0.0; + } + duplicate = true; + /* + NOTE by Oleh_Derevenko: + There may be a case when two normals are close to each other but no duplicate + while third normal is detected to be duplicate for both of them. + This is the only reason I can think of, there is no "break" statement. + Perhaps author considered it to be logical that the third normal would + replace the depth in both of initial contacts. + However, I consider it a questionable practice which should not + be applied without deep understanding of underlaying physics. + Even more, is this situation with close normal triplet acceptable at all? + Should not be two initial contacts reduced to one (replaced with the latter)? + If you know the answers for these questions, you may want to change this code. + See the same statement in GenerateContact() of collision_trimesh_box.cpp + */ + } + } + } + + if (duplicate || OutTriCount == (in_Flags & NUMC_MASK)) + { + break; + } + } + else + { + dIASSERT(OutTriCount < (in_Flags & NUMC_MASK)); + } + + // Add a new contact + Contact = SAFECONTACT(in_Flags, in_Contacts, OutTriCount, in_Stride); + + SET( Contact->pos, in_ContactPos ); + Contact->pos[3] = 0.0; + + SMULT( Contact->normal, in_Normal, -1.0); + Contact->normal[3] = 0.0; + + Contact->depth = in_Depth; + + Contact->g1 = in_TriMesh1; + Contact->g2 = in_TriMesh2; + + Contact->side1 = TriIndex1; + Contact->side2 = TriIndex2; + + OutTriCount++; + } + while (false); +} + + +#endif // dTRIMESH_OPCODE_USE_OLD_TRIMESH_TRIMESH_COLLIDER + + +#endif // dTRIMESH_OPCODE + + +#endif // dTRIMESH_ENABLED diff --git a/libs/ode-0.16.1/ode/src/collision_util.cpp b/libs/ode-0.16.1/ode/src/collision_util.cpp new file mode 100644 index 0000000..39ac87e --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_util.cpp @@ -0,0 +1,613 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +some useful collision utility stuff. this includes some API utility +functions that are defined in the public header files. + +*/ + +#include <ode/common.h> +#include <ode/collision.h> +#include "config.h" +#include "odemath.h" +#include "collision_util.h" + +//**************************************************************************** + +int dCollideSpheres (dVector3 p1, dReal r1, + dVector3 p2, dReal r2, dContactGeom *c) +{ + // printf ("d=%.2f (%.2f %.2f %.2f) (%.2f %.2f %.2f) r1=%.2f r2=%.2f\n", + // d,p1[0],p1[1],p1[2],p2[0],p2[1],p2[2],r1,r2); + + dReal d = dCalcPointsDistance3(p1,p2); + if (d > (r1 + r2)) return 0; + if (d <= 0) { + c->pos[0] = p1[0]; + c->pos[1] = p1[1]; + c->pos[2] = p1[2]; + c->normal[0] = 1; + c->normal[1] = 0; + c->normal[2] = 0; + c->depth = r1 + r2; + } + else { + dReal d1 = dRecip (d); + c->normal[0] = (p1[0]-p2[0])*d1; + c->normal[1] = (p1[1]-p2[1])*d1; + c->normal[2] = (p1[2]-p2[2])*d1; + dReal k = REAL(0.5) * (r2 - r1 - d); + c->pos[0] = p1[0] + c->normal[0]*k; + c->pos[1] = p1[1] + c->normal[1]*k; + c->pos[2] = p1[2] + c->normal[2]*k; + c->depth = r1 + r2 - d; + } + return 1; +} + + +void dLineClosestApproach (const dVector3 pa, const dVector3 ua, + const dVector3 pb, const dVector3 ub, + dReal *alpha, dReal *beta) +{ + dVector3 p; + p[0] = pb[0] - pa[0]; + p[1] = pb[1] - pa[1]; + p[2] = pb[2] - pa[2]; + dReal uaub = dCalcVectorDot3(ua,ub); + dReal q1 = dCalcVectorDot3(ua,p); + dReal q2 = -dCalcVectorDot3(ub,p); + dReal d = 1-uaub*uaub; + if (d <= REAL(0.0001)) { + // @@@ this needs to be made more robust + *alpha = 0; + *beta = 0; + } + else { + d = dRecip(d); + *alpha = (q1 + uaub*q2)*d; + *beta = (uaub*q1 + q2)*d; + } +} + + +// given two line segments A and B with endpoints a1-a2 and b1-b2, return the +// points on A and B that are closest to each other (in cp1 and cp2). +// in the case of parallel lines where there are multiple solutions, a +// solution involving the endpoint of at least one line will be returned. +// this will work correctly for zero length lines, e.g. if a1==a2 and/or +// b1==b2. +// +// the algorithm works by applying the voronoi clipping rule to the features +// of the line segments. the three features of each line segment are the two +// endpoints and the line between them. the voronoi clipping rule states that, +// for feature X on line A and feature Y on line B, the closest points PA and +// PB between X and Y are globally the closest points if PA is in V(Y) and +// PB is in V(X), where V(X) is the voronoi region of X. + +void dClosestLineSegmentPoints (const dVector3 a1, const dVector3 a2, + const dVector3 b1, const dVector3 b2, + dVector3 cp1, dVector3 cp2) +{ + dVector3 a1a2,b1b2,a1b1,a1b2,a2b1,a2b2,n; + dReal la,lb,k,da1,da2,da3,da4,db1,db2,db3,db4,det; + +#define SET2(a,b) a[0]=b[0]; a[1]=b[1]; a[2]=b[2]; +#define SET3(a,b,op,c) a[0]=b[0] op c[0]; a[1]=b[1] op c[1]; a[2]=b[2] op c[2]; + + // check vertex-vertex features + + SET3 (a1a2,a2,-,a1); + SET3 (b1b2,b2,-,b1); + SET3 (a1b1,b1,-,a1); + da1 = dCalcVectorDot3(a1a2,a1b1); + db1 = dCalcVectorDot3(b1b2,a1b1); + if (da1 <= 0 && db1 >= 0) { + SET2 (cp1,a1); + SET2 (cp2,b1); + return; + } + + SET3 (a1b2,b2,-,a1); + da2 = dCalcVectorDot3(a1a2,a1b2); + db2 = dCalcVectorDot3(b1b2,a1b2); + if (da2 <= 0 && db2 <= 0) { + SET2 (cp1,a1); + SET2 (cp2,b2); + return; + } + + SET3 (a2b1,b1,-,a2); + da3 = dCalcVectorDot3(a1a2,a2b1); + db3 = dCalcVectorDot3(b1b2,a2b1); + if (da3 >= 0 && db3 >= 0) { + SET2 (cp1,a2); + SET2 (cp2,b1); + return; + } + + SET3 (a2b2,b2,-,a2); + da4 = dCalcVectorDot3(a1a2,a2b2); + db4 = dCalcVectorDot3(b1b2,a2b2); + if (da4 >= 0 && db4 <= 0) { + SET2 (cp1,a2); + SET2 (cp2,b2); + return; + } + + // check edge-vertex features. + // if one or both of the lines has zero length, we will never get to here, + // so we do not have to worry about the following divisions by zero. + + la = dCalcVectorDot3(a1a2,a1a2); + if (da1 >= 0 && da3 <= 0) { + k = da1 / la; + SET3 (n,a1b1,-,k*a1a2); + if (dCalcVectorDot3(b1b2,n) >= 0) { + SET3 (cp1,a1,+,k*a1a2); + SET2 (cp2,b1); + return; + } + } + + if (da2 >= 0 && da4 <= 0) { + k = da2 / la; + SET3 (n,a1b2,-,k*a1a2); + if (dCalcVectorDot3(b1b2,n) <= 0) { + SET3 (cp1,a1,+,k*a1a2); + SET2 (cp2,b2); + return; + } + } + + lb = dCalcVectorDot3(b1b2,b1b2); + if (db1 <= 0 && db2 >= 0) { + k = -db1 / lb; + SET3 (n,-a1b1,-,k*b1b2); + if (dCalcVectorDot3(a1a2,n) >= 0) { + SET2 (cp1,a1); + SET3 (cp2,b1,+,k*b1b2); + return; + } + } + + if (db3 <= 0 && db4 >= 0) { + k = -db3 / lb; + SET3 (n,-a2b1,-,k*b1b2); + if (dCalcVectorDot3(a1a2,n) <= 0) { + SET2 (cp1,a2); + SET3 (cp2,b1,+,k*b1b2); + return; + } + } + + // it must be edge-edge + + k = dCalcVectorDot3(a1a2,b1b2); + det = la*lb - k*k; + if (det <= 0) { + // this should never happen, but just in case... + SET2(cp1,a1); + SET2(cp2,b1); + return; + } + det = dRecip (det); + dReal alpha = (lb*da1 - k*db1) * det; + dReal beta = ( k*da1 - la*db1) * det; + SET3 (cp1,a1,+,alpha*a1a2); + SET3 (cp2,b1,+,beta*b1b2); + +# undef SET2 +# undef SET3 +} + + +// a simple root finding algorithm is used to find the value of 't' that +// satisfies: +// d|D(t)|^2/dt = 0 +// where: +// |D(t)| = |p(t)-b(t)| +// where p(t) is a point on the line parameterized by t: +// p(t) = p1 + t*(p2-p1) +// and b(t) is that same point clipped to the boundary of the box. in box- +// relative coordinates d|D(t)|^2/dt is the sum of three x,y,z components +// each of which looks like this: +// +// t_lo / +// ______/ -->t +// / t_hi +// / +// +// t_lo and t_hi are the t values where the line passes through the planes +// corresponding to the sides of the box. the algorithm computes d|D(t)|^2/dt +// in a piecewise fashion from t=0 to t=1, stopping at the point where +// d|D(t)|^2/dt crosses from negative to positive. + +void dClosestLineBoxPoints (const dVector3 p1, const dVector3 p2, + const dVector3 c, const dMatrix3 R, + const dVector3 side, + dVector3 lret, dVector3 bret) +{ + int i; + + // compute the start and delta of the line p1-p2 relative to the box. + // we will do all subsequent computations in this box-relative coordinate + // system. we have to do a translation and rotation for each point. + dVector3 tmp,s,v; + tmp[0] = p1[0] - c[0]; + tmp[1] = p1[1] - c[1]; + tmp[2] = p1[2] - c[2]; + dMultiply1_331 (s,R,tmp); + tmp[0] = p2[0] - p1[0]; + tmp[1] = p2[1] - p1[1]; + tmp[2] = p2[2] - p1[2]; + dMultiply1_331 (v,R,tmp); + + // mirror the line so that v has all components >= 0 + dVector3 sign; + for (i=0; i<3; i++) { + if (v[i] < 0) { + s[i] = -s[i]; + v[i] = -v[i]; + sign[i] = -1; + } + else sign[i] = 1; + } + + // compute v^2 + dVector3 v2; + v2[0] = v[0]*v[0]; + v2[1] = v[1]*v[1]; + v2[2] = v[2]*v[2]; + + // compute the half-sides of the box + dReal h[3]; + h[0] = REAL(0.5) * side[0]; + h[1] = REAL(0.5) * side[1]; + h[2] = REAL(0.5) * side[2]; + + // region is -1,0,+1 depending on which side of the box planes each + // coordinate is on. tanchor is the next t value at which there is a + // transition, or the last one if there are no more. + int region[3]; + dReal tanchor[3]; + + // Denormals are a problem, because we divide by v[i], and then + // multiply that by 0. Alas, infinity times 0 is infinity (!) + // We also use v2[i], which is v[i] squared. Here's how the epsilons + // are chosen: + // float epsilon = 1.175494e-038 (smallest non-denormal number) + // double epsilon = 2.225074e-308 (smallest non-denormal number) + // For single precision, choose an epsilon such that v[i] squared is + // not a denormal; this is for performance. + // For double precision, choose an epsilon such that v[i] is not a + // denormal; this is for correctness. (Jon Watte on mailinglist) + +#if defined( dSINGLE ) + const dReal tanchor_eps = REAL(1e-19); +#else + const dReal tanchor_eps = REAL(1e-307); +#endif + + // find the region and tanchor values for p1 + for (i=0; i<3; i++) { + if (v[i] > tanchor_eps) { + if (s[i] < -h[i]) { + region[i] = -1; + tanchor[i] = (-h[i]-s[i])/v[i]; + } + else { + region[i] = (s[i] > h[i]); + tanchor[i] = (h[i]-s[i])/v[i]; + } + } + else { + region[i] = 0; + tanchor[i] = 2; // this will never be a valid tanchor + } + } + + // compute d|d|^2/dt for t=0. if it's >= 0 then p1 is the closest point + dReal t=0; + dReal dd2dt = 0; + for (i=0; i<3; i++) dd2dt -= (region[i] ? v2[i] : 0) * tanchor[i]; + if (dd2dt >= 0) goto got_answer; + + do { + // find the point on the line that is at the next clip plane boundary + dReal next_t = 1; + for (i=0; i<3; i++) { + if (tanchor[i] > t && tanchor[i] < 1 && tanchor[i] < next_t) + next_t = tanchor[i]; + } + + // compute d|d|^2/dt for the next t + dReal next_dd2dt = 0; + for (i=0; i<3; i++) { + next_dd2dt += (region[i] ? v2[i] : 0) * (next_t - tanchor[i]); + } + + // if the sign of d|d|^2/dt has changed, solution = the crossover point + if (next_dd2dt >= 0) { + dReal m = (next_dd2dt-dd2dt)/(next_t - t); + t -= dd2dt/m; + goto got_answer; + } + + // advance to the next anchor point / region + for (i=0; i<3; i++) { + if (tanchor[i] == next_t) { + tanchor[i] = (h[i]-s[i])/v[i]; + region[i]++; + } + } + t = next_t; + dd2dt = next_dd2dt; + } + while (t < 1); + t = 1; + +got_answer: + + // compute closest point on the line + for (i=0; i<3; i++) lret[i] = p1[i] + t*tmp[i]; // note: tmp=p2-p1 + + // compute closest point on the box + for (i=0; i<3; i++) { + tmp[i] = sign[i] * (s[i] + t*v[i]); + if (tmp[i] < -h[i]) tmp[i] = -h[i]; + else if (tmp[i] > h[i]) tmp[i] = h[i]; + } + dMultiply0_331 (s,R,tmp); + for (i=0; i<3; i++) bret[i] = s[i] + c[i]; +} + + +// given boxes (p1,R1,side1) and (p1,R1,side1), return 1 if they intersect +// or 0 if not. + +int dBoxTouchesBox (const dVector3 p1, const dMatrix3 R1, + const dVector3 side1, const dVector3 p2, + const dMatrix3 R2, const dVector3 side2) +{ + // two boxes are disjoint if (and only if) there is a separating axis + // perpendicular to a face from one box or perpendicular to an edge from + // either box. the following tests are derived from: + // "OBB Tree: A Hierarchical Structure for Rapid Interference Detection", + // S.Gottschalk, M.C.Lin, D.Manocha., Proc of ACM Siggraph 1996. + + // Rij is R1'*R2, i.e. the relative rotation between R1 and R2. + // Qij is abs(Rij) + dVector3 p,pp; + dReal A1,A2,A3,B1,B2,B3,R11,R12,R13,R21,R22,R23,R31,R32,R33, + Q11,Q12,Q13,Q21,Q22,Q23,Q31,Q32,Q33; + + // get vector from centers of box 1 to box 2, relative to box 1 + p[0] = p2[0] - p1[0]; + p[1] = p2[1] - p1[1]; + p[2] = p2[2] - p1[2]; + dMultiply1_331 (pp,R1,p); // get pp = p relative to body 1 + + // get side lengths / 2 + A1 = side1[0]*REAL(0.5); A2 = side1[1]*REAL(0.5); A3 = side1[2]*REAL(0.5); + B1 = side2[0]*REAL(0.5); B2 = side2[1]*REAL(0.5); B3 = side2[2]*REAL(0.5); + + // for the following tests, excluding computation of Rij, in the worst case, + // 15 compares, 60 adds, 81 multiplies, and 24 absolutes. + // notation: R1=[u1 u2 u3], R2=[v1 v2 v3] + + // separating axis = u1,u2,u3 + R11 = dCalcVectorDot3_44(R1+0,R2+0); R12 = dCalcVectorDot3_44(R1+0,R2+1); R13 = dCalcVectorDot3_44(R1+0,R2+2); + Q11 = dFabs(R11); Q12 = dFabs(R12); Q13 = dFabs(R13); + if (dFabs(pp[0]) > (A1 + B1*Q11 + B2*Q12 + B3*Q13)) return 0; + R21 = dCalcVectorDot3_44(R1+1,R2+0); R22 = dCalcVectorDot3_44(R1+1,R2+1); R23 = dCalcVectorDot3_44(R1+1,R2+2); + Q21 = dFabs(R21); Q22 = dFabs(R22); Q23 = dFabs(R23); + if (dFabs(pp[1]) > (A2 + B1*Q21 + B2*Q22 + B3*Q23)) return 0; + R31 = dCalcVectorDot3_44(R1+2,R2+0); R32 = dCalcVectorDot3_44(R1+2,R2+1); R33 = dCalcVectorDot3_44(R1+2,R2+2); + Q31 = dFabs(R31); Q32 = dFabs(R32); Q33 = dFabs(R33); + if (dFabs(pp[2]) > (A3 + B1*Q31 + B2*Q32 + B3*Q33)) return 0; + + // separating axis = v1,v2,v3 + if (dFabs(dCalcVectorDot3_41(R2+0,p)) > (A1*Q11 + A2*Q21 + A3*Q31 + B1)) return 0; + if (dFabs(dCalcVectorDot3_41(R2+1,p)) > (A1*Q12 + A2*Q22 + A3*Q32 + B2)) return 0; + if (dFabs(dCalcVectorDot3_41(R2+2,p)) > (A1*Q13 + A2*Q23 + A3*Q33 + B3)) return 0; + + // separating axis = u1 x (v1,v2,v3) + if (dFabs(pp[2]*R21-pp[1]*R31) > A2*Q31 + A3*Q21 + B2*Q13 + B3*Q12) return 0; + if (dFabs(pp[2]*R22-pp[1]*R32) > A2*Q32 + A3*Q22 + B1*Q13 + B3*Q11) return 0; + if (dFabs(pp[2]*R23-pp[1]*R33) > A2*Q33 + A3*Q23 + B1*Q12 + B2*Q11) return 0; + + // separating axis = u2 x (v1,v2,v3) + if (dFabs(pp[0]*R31-pp[2]*R11) > A1*Q31 + A3*Q11 + B2*Q23 + B3*Q22) return 0; + if (dFabs(pp[0]*R32-pp[2]*R12) > A1*Q32 + A3*Q12 + B1*Q23 + B3*Q21) return 0; + if (dFabs(pp[0]*R33-pp[2]*R13) > A1*Q33 + A3*Q13 + B1*Q22 + B2*Q21) return 0; + + // separating axis = u3 x (v1,v2,v3) + if (dFabs(pp[1]*R11-pp[0]*R21) > A1*Q21 + A2*Q11 + B2*Q33 + B3*Q32) return 0; + if (dFabs(pp[1]*R12-pp[0]*R22) > A1*Q22 + A2*Q12 + B1*Q33 + B3*Q31) return 0; + if (dFabs(pp[1]*R13-pp[0]*R23) > A1*Q23 + A2*Q13 + B1*Q32 + B2*Q31) return 0; + + return 1; +} + +//**************************************************************************** +// other utility functions + +/*ODE_API */void dInfiniteAABB (dxGeom *geom, dReal aabb[6]) +{ + aabb[0] = -dInfinity; + aabb[1] = dInfinity; + aabb[2] = -dInfinity; + aabb[3] = dInfinity; + aabb[4] = -dInfinity; + aabb[5] = dInfinity; +} + + +//**************************************************************************** +// Helpers for Croteam's collider - by Nguyen Binh + +int dClipEdgeToPlane( dVector3 &vEpnt0, dVector3 &vEpnt1, const dVector4& plPlane) +{ + // calculate distance of edge points to plane + dReal fDistance0 = dPointPlaneDistance( vEpnt0 ,plPlane ); + dReal fDistance1 = dPointPlaneDistance( vEpnt1 ,plPlane ); + + // if both points are behind the plane + if ( fDistance0 < 0 && fDistance1 < 0 ) + { + // do nothing + return 0; + // if both points in front of the plane + } + else if ( fDistance0 > 0 && fDistance1 > 0 ) + { + // accept them + return 1; + // if we have edge/plane intersection + } else if ((fDistance0 > 0 && fDistance1 < 0) || ( fDistance0 < 0 && fDistance1 > 0)) + { + + // find intersection point of edge and plane + dVector3 vIntersectionPoint; + vIntersectionPoint[0]= vEpnt0[0]-(vEpnt0[0]-vEpnt1[0])*fDistance0/(fDistance0-fDistance1); + vIntersectionPoint[1]= vEpnt0[1]-(vEpnt0[1]-vEpnt1[1])*fDistance0/(fDistance0-fDistance1); + vIntersectionPoint[2]= vEpnt0[2]-(vEpnt0[2]-vEpnt1[2])*fDistance0/(fDistance0-fDistance1); + + // clamp correct edge to intersection point + if ( fDistance0 < 0 ) + { + dVector3Copy(vIntersectionPoint,vEpnt0); + } else + { + dVector3Copy(vIntersectionPoint,vEpnt1); + } + return 1; + } + return 1; +} + +// clip polygon with plane and generate new polygon points +void dClipPolyToPlane( const dVector3 avArrayIn[], const int ctIn, + dVector3 avArrayOut[], int &ctOut, + const dVector4 &plPlane ) +{ + // start with no output points + ctOut = 0; + + int i0 = ctIn-1; + + // for each edge in input polygon + for (int i1=0; i1<ctIn; i0=i1, i1++) { + + + // calculate distance of edge points to plane + dReal fDistance0 = dPointPlaneDistance( avArrayIn[i0],plPlane ); + dReal fDistance1 = dPointPlaneDistance( avArrayIn[i1],plPlane ); + + // if first point is in front of plane + if( fDistance0 >= 0 ) { + // emit point + avArrayOut[ctOut][0] = avArrayIn[i0][0]; + avArrayOut[ctOut][1] = avArrayIn[i0][1]; + avArrayOut[ctOut][2] = avArrayIn[i0][2]; + ctOut++; + } + + // if points are on different sides + if( (fDistance0 > 0 && fDistance1 < 0) || ( fDistance0 < 0 && fDistance1 > 0) ) { + + // find intersection point of edge and plane + dVector3 vIntersectionPoint; + vIntersectionPoint[0]= avArrayIn[i0][0] - + (avArrayIn[i0][0]-avArrayIn[i1][0])*fDistance0/(fDistance0-fDistance1); + vIntersectionPoint[1]= avArrayIn[i0][1] - + (avArrayIn[i0][1]-avArrayIn[i1][1])*fDistance0/(fDistance0-fDistance1); + vIntersectionPoint[2]= avArrayIn[i0][2] - + (avArrayIn[i0][2]-avArrayIn[i1][2])*fDistance0/(fDistance0-fDistance1); + + // emit intersection point + avArrayOut[ctOut][0] = vIntersectionPoint[0]; + avArrayOut[ctOut][1] = vIntersectionPoint[1]; + avArrayOut[ctOut][2] = vIntersectionPoint[2]; + ctOut++; + } + } + +} + +void dClipPolyToCircle(const dVector3 avArrayIn[], const int ctIn, + dVector3 avArrayOut[], int &ctOut, + const dVector4 &plPlane ,dReal fRadius) +{ + // start with no output points + ctOut = 0; + + int i0 = ctIn-1; + + // for each edge in input polygon + for (int i1=0; i1<ctIn; i0=i1, i1++) + { + // calculate distance of edge points to plane + dReal fDistance0 = dPointPlaneDistance( avArrayIn[i0],plPlane ); + dReal fDistance1 = dPointPlaneDistance( avArrayIn[i1],plPlane ); + + // if first point is in front of plane + if( fDistance0 >= 0 ) + { + // emit point + if (dVector3LengthSquare(avArrayIn[i0]) <= fRadius*fRadius) + { + avArrayOut[ctOut][0] = avArrayIn[i0][0]; + avArrayOut[ctOut][1] = avArrayIn[i0][1]; + avArrayOut[ctOut][2] = avArrayIn[i0][2]; + ctOut++; + } + } + + // if points are on different sides + if( (fDistance0 > 0 && fDistance1 < 0) || ( fDistance0 < 0 && fDistance1 > 0) ) + { + + // find intersection point of edge and plane + dVector3 vIntersectionPoint; + vIntersectionPoint[0]= avArrayIn[i0][0] - + (avArrayIn[i0][0]-avArrayIn[i1][0])*fDistance0/(fDistance0-fDistance1); + vIntersectionPoint[1]= avArrayIn[i0][1] - + (avArrayIn[i0][1]-avArrayIn[i1][1])*fDistance0/(fDistance0-fDistance1); + vIntersectionPoint[2]= avArrayIn[i0][2] - + (avArrayIn[i0][2]-avArrayIn[i1][2])*fDistance0/(fDistance0-fDistance1); + + // emit intersection point + if (dVector3LengthSquare(avArrayIn[i0]) <= fRadius*fRadius) + { + avArrayOut[ctOut][0] = vIntersectionPoint[0]; + avArrayOut[ctOut][1] = vIntersectionPoint[1]; + avArrayOut[ctOut][2] = vIntersectionPoint[2]; + ctOut++; + } + } + } +} + diff --git a/libs/ode-0.16.1/ode/src/collision_util.h b/libs/ode-0.16.1/ode/src/collision_util.h new file mode 100644 index 0000000..57e116a --- /dev/null +++ b/libs/ode-0.16.1/ode/src/collision_util.h @@ -0,0 +1,358 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +some useful collision utility stuff. + +*/ + +#ifndef _ODE_COLLISION_UTIL_H_ +#define _ODE_COLLISION_UTIL_H_ + +#include <ode/common.h> +#include <ode/contact.h> +#include <ode/rotation.h> +#include "odemath.h" + + +// given a pointer `p' to a dContactGeom, return the dContactGeom at +// p + skip bytes. +#define CONTACT(p,skip) ((dContactGeom*) (((char*)p) + (skip))) + +#if 1 +#include "collision_kernel.h" +// Fetches a contact +static inline +dContactGeom* SAFECONTACT(int Flags, dContactGeom* Contacts, int Index, int Stride){ + dIASSERT(Index >= 0 && Index < (Flags & NUMC_MASK)); + return ((dContactGeom*)(((char*)Contacts) + (Index * Stride))); +} +#endif + + +// if the spheres (p1,r1) and (p2,r2) collide, set the contact `c' and +// return 1, else return 0. + +int dCollideSpheres (dVector3 p1, dReal r1, + dVector3 p2, dReal r2, dContactGeom *c); + + +// given two lines +// qa = pa + alpha* ua +// qb = pb + beta * ub +// where pa,pb are two points, ua,ub are two unit length vectors, and alpha, +// beta go from [-inf,inf], return alpha and beta such that qa and qb are +// as close as possible + +void dLineClosestApproach (const dVector3 pa, const dVector3 ua, + const dVector3 pb, const dVector3 ub, + dReal *alpha, dReal *beta); + + +// given a line segment p1-p2 and a box (center 'c', rotation 'R', side length +// vector 'side'), compute the points of closest approach between the box +// and the line. return these points in 'lret' (the point on the line) and +// 'bret' (the point on the box). if the line actually penetrates the box +// then the solution is not unique, but only one solution will be returned. +// in this case the solution points will coincide. + +void dClosestLineBoxPoints (const dVector3 p1, const dVector3 p2, + const dVector3 c, const dMatrix3 R, + const dVector3 side, + dVector3 lret, dVector3 bret); + +// 20 Apr 2004 +// Start code by Nguyen Binh +int dClipEdgeToPlane(dVector3 &vEpnt0, dVector3 &vEpnt1, const dVector4& plPlane); +// clip polygon with plane and generate new polygon points +void dClipPolyToPlane(const dVector3 avArrayIn[], const int ctIn, dVector3 avArrayOut[], int &ctOut, const dVector4 &plPlane ); + +void dClipPolyToCircle(const dVector3 avArrayIn[], const int ctIn, dVector3 avArrayOut[], int &ctOut, const dVector4 &plPlane ,dReal fRadius); + +// Some vector math +static inline +void dVector3Subtract(const dVector3& a,const dVector3& b,dVector3& c) +{ + dSubtractVectors3(c, a, b); +} + +static inline +void dVector3Scale(dVector3& a,dReal nScale) +{ + dScaleVector3(a, nScale); +} + +static inline +void dVector3Add(const dVector3& a,const dVector3& b,dVector3& c) +{ + dAddVectors3(c, a, b); +} + +static inline +void dVector3Copy(const dVector3& a,dVector3& c) +{ + dCopyVector3(c, a); +} + +static inline +void dVector4Copy(const dVector4& a,dVector4& c) +{ + dCopyVector4(c, a); +} + +static inline +void dVector3Cross(const dVector3& a,const dVector3& b,dVector3& c) +{ + dCalcVectorCross3(c, a, b); +} + +static inline +dReal dVector3Length(const dVector3& a) +{ + return dCalcVectorLength3(a); +} + +static inline +dReal dVector3LengthSquare(const dVector3& a) +{ + return dCalcVectorLengthSquare3(a); +} + +static inline +dReal dVector3Dot(const dVector3& a,const dVector3& b) +{ + return dCalcVectorDot3(a, b); +} + +static inline +void dVector3Inv(dVector3& a) +{ + dNegateVector3(a); +} + +static inline +void dMat3GetCol(const dMatrix3& m,const int col, dVector3& v) +{ + dGetMatrixColumn3(v, m, col); +} + +static inline +void dVector3CrossMat3Col(const dMatrix3& m,const int col,const dVector3& v,dVector3& r) +{ + dCalcVectorCross3_114(r, v, m + col); +} + +static inline +void dMat3ColCrossVector3(const dMatrix3& m,const int col,const dVector3& v,dVector3& r) +{ + dCalcVectorCross3_141(r, m + col, v); +} + +static inline +void dMultiplyMat3Vec3(const dMatrix3& m,const dVector3& v, dVector3& r) +{ + dMultiply0_331(r, m, v); +} + +static inline +dReal dPointPlaneDistance(const dVector3& point,const dVector4& plane) +{ + return (plane[0]*point[0] + plane[1]*point[1] + plane[2]*point[2] + plane[3]); +} + +static inline +void dConstructPlane(const dVector3& normal,const dReal& distance, dVector4& plane) +{ + plane[0] = normal[0]; + plane[1] = normal[1]; + plane[2] = normal[2]; + plane[3] = distance; +} + +static inline +void dMatrix3Copy(const dReal* source,dMatrix3& dest) +{ + dCopyMatrix4x3(dest, source); +} + +static inline +dReal dMatrix3Det( const dMatrix3& mat ) +{ + dReal det; + + det = mat[0] * ( mat[5]*mat[10] - mat[9]*mat[6] ) + - mat[1] * ( mat[4]*mat[10] - mat[8]*mat[6] ) + + mat[2] * ( mat[4]*mat[9] - mat[8]*mat[5] ); + + return( det ); +} + + +static inline +void dMatrix3Inv( const dMatrix3& ma, dMatrix3& dst ) +{ + dReal det = dMatrix3Det( ma ); + + if ( dFabs( det ) < REAL(0.0005) ) + { + dRSetIdentity( dst ); + return; + } + + double detRecip = REAL(1.0) / det; + + dst[0] = (dReal)(( ma[5]*ma[10] - ma[6]*ma[9] ) * detRecip); + dst[1] = (dReal)(( ma[9]*ma[2] - ma[1]*ma[10] ) * detRecip); + dst[2] = (dReal)(( ma[1]*ma[6] - ma[5]*ma[2] ) * detRecip); + + dst[4] = (dReal)(( ma[6]*ma[8] - ma[4]*ma[10] ) * detRecip); + dst[5] = (dReal)(( ma[0]*ma[10] - ma[8]*ma[2] ) * detRecip); + dst[6] = (dReal)(( ma[4]*ma[2] - ma[0]*ma[6] ) * detRecip); + + dst[8] = (dReal)(( ma[4]*ma[9] - ma[8]*ma[5] ) * detRecip); + dst[9] = (dReal)(( ma[8]*ma[1] - ma[0]*ma[9] ) * detRecip); + dst[10] = (dReal)(( ma[0]*ma[5] - ma[1]*ma[4] ) * detRecip); +} + +static inline +void dQuatTransform(const dQuaternion& quat,const dVector3& source,dVector3& dest) +{ + + // Nguyen Binh : this code seem to be the fastest. + dReal x0 = source[0] * quat[0] + source[2] * quat[2] - source[1] * quat[3]; + dReal x1 = source[1] * quat[0] + source[0] * quat[3] - source[2] * quat[1]; + dReal x2 = source[2] * quat[0] + source[1] * quat[1] - source[0] * quat[2]; + dReal x3 = source[0] * quat[1] + source[1] * quat[2] + source[2] * quat[3]; + + dest[0] = quat[0] * x0 + quat[1] * x3 + quat[2] * x2 - quat[3] * x1; + dest[1] = quat[0] * x1 + quat[2] * x3 + quat[3] * x0 - quat[1] * x2; + dest[2] = quat[0] * x2 + quat[3] * x3 + quat[1] * x1 - quat[2] * x0; + + /* + // nVidia SDK implementation + dVector3 uv, uuv; + dVector3 qvec; + qvec[0] = quat[1]; + qvec[1] = quat[2]; + qvec[2] = quat[3]; + + dVector3Cross(qvec,source,uv); + dVector3Cross(qvec,uv,uuv); + + dVector3Scale(uv,REAL(2.0)*quat[0]); + dVector3Scale(uuv,REAL(2.0)); + + dest[0] = source[0] + uv[0] + uuv[0]; + dest[1] = source[1] + uv[1] + uuv[1]; + dest[2] = source[2] + uv[2] + uuv[2]; + */ +} + +static inline +void dQuatInvTransform(const dQuaternion& quat,const dVector3& source,dVector3& dest) +{ + + dReal norm = quat[0]*quat[0] + quat[1]*quat[1] + quat[2]*quat[2] + quat[3]*quat[3]; + + if (norm > REAL(0.0)) + { + dQuaternion invQuat; + invQuat[0] = quat[0] / norm; + invQuat[1] = -quat[1] / norm; + invQuat[2] = -quat[2] / norm; + invQuat[3] = -quat[3] / norm; + + dQuatTransform(invQuat,source,dest); + + } + else + { + // Singular -> return identity + dVector3Copy(source,dest); + } +} + +static inline +void dGetEulerAngleFromRot(const dMatrix3& mRot,dReal& rX,dReal& rY,dReal& rZ) +{ + rY = asin(mRot[0 * 4 + 2]); + if (rY < M_PI /2) + { + if (rY > -M_PI /2) + { + rX = atan2(-mRot[1*4 + 2], mRot[2*4 + 2]); + rZ = atan2(-mRot[0*4 + 1], mRot[0*4 + 0]); + } + else + { + // not unique + rX = -atan2(mRot[1*4 + 0], mRot[1*4 + 1]); + rZ = REAL(0.0); + } + } + else + { + // not unique + rX = atan2(mRot[1*4 + 0], mRot[1*4 + 1]); + rZ = REAL(0.0); + } +} + +static inline +void dQuatInv(const dQuaternion& source, dQuaternion& dest) +{ + dReal norm = source[0]*source[0] + source[1]*source[1] + source[2]*source[2] + source[3]*source[3]; + + if (norm > 0.0f) + { + dReal neg_norm_recip = -REAL(1.0) / norm; + dest[0] = -source[0] * neg_norm_recip; + dest[1] = source[1] * neg_norm_recip; + dest[2] = source[2] * neg_norm_recip; + dest[3] = source[3] * neg_norm_recip; + } + else + { + // Singular -> return identity + dest[0] = REAL(1.0); + dest[1] = REAL(0.0); + dest[2] = REAL(0.0); + dest[3] = REAL(0.0); + } +} + +// Finds barycentric +static inline +void GetPointFromBarycentric(const dVector3 dv[3], dReal u, dReal v, dVector3 Out){ + dReal w = REAL(1.0) - u - v; + + Out[0] = (dv[0][0] * w) + (dv[1][0] * u) + (dv[2][0] * v); + Out[1] = (dv[0][1] * w) + (dv[1][1] * u) + (dv[2][1] * v); + Out[2] = (dv[0][2] * w) + (dv[1][2] * u) + (dv[2][2] * v); + Out[3] = (dv[0][3] * w) + (dv[1][3] * u) + (dv[2][3] * v); +} + + + + +#endif diff --git a/libs/ode-0.16.1/ode/src/common.h b/libs/ode-0.16.1/ode/src/common.h new file mode 100644 index 0000000..0d67c2e --- /dev/null +++ b/libs/ode-0.16.1/ode/src/common.h @@ -0,0 +1,351 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_PRIVATE_COMMON_H_ +#define _ODE_PRIVATE_COMMON_H_ + + +#include "typedefs.h" +#include "error.h" +#include <ode/memory.h> +#include <algorithm> + + +#ifndef SIZE_MAX +#define SIZE_MAX ((sizeint)(-1)) +#endif + +#define dMACRO_MAX(a, b) ((a) > (b) ? (a) : (b)) +#define dMACRO_MIN(a, b) ((a) < (b) ? (a) : (b)) + + +#ifdef dSINGLE
+#define dEpsilon FLT_EPSILON
+#else
+#define dEpsilon DBL_EPSILON
+#endif
+ + +#ifdef dSINGLE
+ +#if !defined(FLT_MANT_DIG) +#define FLT_MANT_DIG 24 +#endif +
+#define dMaxExact ((float)((1UL << FLT_MANT_DIG) - 1))
+#define dMinExact ((float)(-dMaxExact))
+
+
+#else // #ifndef dSINGLE
+ +#if !defined(DBL_MANT_DIG) +#define DBL_MANT_DIG 53 +#endif + +#define dMaxExact (double)((1ULL << DBL_MANT_DIG) - 1)
+#define dMinExact ((double)(-dMaxExact))
+
+
+#endif // #ifndef dSINGLE
+
+
+#define dMaxIntExact dMACRO_MIN(dMaxExact, (dReal)INT_MAX)
+#define dMinIntExact dMACRO_MAX(dMinExact, (dReal)INT_MIN)
+
+ +#ifndef offsetof +#define offsetof(s, m) ((sizeint)&(((s *)8)->m) - (sizeint)8) +#endif +#ifndef membersize +#define membersize(s, m) (sizeof(((s *)8)->m)) +#endif +#ifndef endoffsetof +#define endoffsetof(s, m) ((sizeint)((sizeint)&(((s *)8)->m) - (sizeint)8) + sizeof(((s *)8)->m)) +#endif + + +/* the efficient alignment. most platforms align data structures to some + * number of bytes, but this is not always the most efficient alignment. + * for example, many x86 compilers align to 4 bytes, but on a pentium it + * is important to align doubles to 8 byte boundaries (for speed), and + * the 4 floats in a SIMD register to 16 byte boundaries. many other + * platforms have similar behavior. setting a larger alignment can waste + * a (very) small amount of memory. NOTE: this number must be a power of + * two. this is set to 16 by default. + */ +#ifndef EFFICIENT_ALIGNMENT +#define EFFICIENT_ALIGNMENT 16 +#endif + +#define dALIGN_SIZE(buf_size, alignment) (((buf_size) + (alignment - 1)) & (int)(~(alignment - 1))) // Casting the mask to int ensures sign-extension to larger integer sizes +#define dALIGN_PTR(buf_ptr, alignment) ((void *)(((uintptr)(buf_ptr) + ((alignment) - 1)) & (int)(~(alignment - 1)))) // Casting the mask to int ensures sign-extension to larger integer sizes + +/* round something up to be a multiple of the EFFICIENT_ALIGNMENT */ +#define dEFFICIENT_SIZE(x) dALIGN_SIZE(x, EFFICIENT_ALIGNMENT) +#define dEFFICIENT_PTR(p) dALIGN_PTR(p, EFFICIENT_ALIGNMENT) +#define dOFFSET_EFFICIENTLY(p, b) ((void *)((uintptr)(p) + dEFFICIENT_SIZE(b))) + +#define dOVERALIGNED_SIZE(size, alignment) dEFFICIENT_SIZE((size) + ((alignment) - EFFICIENT_ALIGNMENT)) +#define dOVERALIGNED_PTR(buf_ptr, alignment) dALIGN_PTR(buf_ptr, alignment) +#define dOFFSET_OVERALIGNEDLY(buf_ptr, size, alignment) ((void *)((uintptr)(buf_ptr) + dOVERALIGNED_SIZE(size, alignment))) + + + +#define dDERIVE_SIZE_UNION_PADDING_ELEMENTS(DataSize, ElementType) (((DataSize) + sizeof(ElementType) - 1) / sizeof(ElementType)) +#define dDERIVE_TYPE_UNION_PADDING_ELEMENTS(DataType, ElementType) dDERIVE_SIZE_UNION_PADDING_ELEMENTS(sizeof(DataType), ElementType) +#define dDERIVE_SIZE_EXTRA_PADDING_ELEMENTS(DataSize, AlignmentSize, ElementType) (((dALIGN_SIZE(DataSize, dMACRO_MAX(AlignmentSize, sizeof(ElementType))) - (DataSize)) / sizeof(ElementType)) + + + +/* alloca aligned to the EFFICIENT_ALIGNMENT. note that this can waste + * up to 15 bytes per allocation, depending on what alloca() returns. + */ +#define dALLOCA16(n) \ + dEFFICIENT_PTR(alloca((n)+(EFFICIENT_ALIGNMENT))) + + +class dxAlignedAllocation +{ +public: + dxAlignedAllocation(): m_userAreaPointer(NULL), m_bufferAllocated(NULL), m_sizeUsed(0) {} + ~dxAlignedAllocation() { freeAllocation(); } + + void *allocAligned(sizeint sizeRequired, unsigned alignmentRequired) + { + dIASSERT((alignmentRequired & (alignmentRequired - 1)) == 0); + dIASSERT(alignmentRequired <= SIZE_MAX - sizeRequired); + + sizeint sizeToUse = sizeRequired + alignmentRequired; + void *bufferPointer = dAlloc(sizeToUse); + void *userAreaPointer = bufferPointer != NULL && alignmentRequired != 0 ? dALIGN_PTR(bufferPointer, alignmentRequired) : bufferPointer; + assignData(userAreaPointer, bufferPointer, sizeToUse); + + return userAreaPointer; + } + + void *getUserAreaPointer() const { return m_userAreaPointer; } + sizeint getUserAreaSize() const { return m_sizeUsed - ((uint8 *)m_userAreaPointer - (uint8 *)m_bufferAllocated); } + + void freeAllocation() + { + sizeint sizeUsed; + void *bufferPointer = extractData(sizeUsed); + + if (bufferPointer != NULL) + { + dFree(bufferPointer, sizeUsed); + } + } + +private: + void assignData(void *userAreaPointer, void *bufferAllocated, sizeint sizeUsed) + { + dIASSERT(m_userAreaPointer == NULL); + dIASSERT(m_bufferAllocated == NULL); + dIASSERT(m_sizeUsed == 0); + + m_userAreaPointer = userAreaPointer; + m_bufferAllocated = bufferAllocated; + m_sizeUsed = sizeUsed; + } + + void *extractData(sizeint &out_sizeUsed) + { + void *bufferPointer = m_bufferAllocated; + + if (bufferPointer != NULL) + { + out_sizeUsed = m_sizeUsed; + + m_userAreaPointer = NULL; + m_bufferAllocated = NULL; + m_sizeUsed = 0; + } + + return bufferPointer; + } + +private: + void *m_userAreaPointer; + void *m_bufferAllocated; + sizeint m_sizeUsed; +}; + + +template<typename DstType, typename SrcType> +inline +bool _cast_to_smaller(DstType &dtOutResult, const SrcType &stArgument) +{ + return (SrcType)(dtOutResult = (DstType)stArgument) == stArgument; +} + +#if defined(__GNUC__) + +#define dCAST_TO_SMALLER(TargetType, SourceValue) ({ TargetType ttCastSmallerValue; dIVERIFY(_cast_to_smaller(ttCastSmallerValue, SourceValue)); ttCastSmallerValue; }) + + +#else // #if !defined(__GNUC__) + +#define dCAST_TO_SMALLER(TargetType, SourceValue) templateCAST_TO_SMALLER<TargetType>(SourceValue) + +template <typename TTargetType, typename TSourceType> +inline TTargetType templateCAST_TO_SMALLER(const TSourceType &stSourceValue) +{ + TTargetType ttCastSmallerValue; + dIVERIFY(_cast_to_smaller(ttCastSmallerValue, stSourceValue)); + return ttCastSmallerValue; +} + + +#endif // #if !defined(__GNUC__) + + +template<typename value_type> +inline +void dxSwap(value_type &one, value_type &another) +{ + std::swap(one, another); +} + +template<typename value_type, typename lo_type, typename hi_type> +inline +value_type dxClamp(const value_type &value, const lo_type &lo, const hi_type &hi) +{ + return value < lo ? (value_type)lo : value > hi ? (value_type)hi : value; +} + + +template <typename Type> +union _const_type_cast_union +{ + explicit _const_type_cast_union(const void *psvCharBuffer): m_psvCharBuffer(psvCharBuffer) {} + + operator const Type *() const { return m_pstTypedPointer; } + const Type &operator *() const { return *m_pstTypedPointer; } + const Type *operator ->() const { return m_pstTypedPointer; } + const Type &operator [](diffint diElementIndex) const { return m_pstTypedPointer[diElementIndex]; } + const Type &operator [](sizeint siElementIndex) const { return m_pstTypedPointer[siElementIndex]; } + + const void *m_psvCharBuffer; + const Type *m_pstTypedPointer; +}; + +template <typename Type> +union _type_cast_union +{ + explicit _type_cast_union(void *psvCharBuffer): m_psvCharBuffer(psvCharBuffer) {} + + operator Type *() const { return m_pstTypedPointer; } + Type &operator *() const { return *m_pstTypedPointer; } + Type *operator ->() const { return m_pstTypedPointer; } + Type &operator [](diffint diElementIndex) const { return m_pstTypedPointer[diElementIndex]; } + Type &operator [](sizeint siElementIndex) const { return m_pstTypedPointer[siElementIndex]; } + + void *m_psvCharBuffer; + Type *m_pstTypedPointer; +}; + + +template<sizeint tsiTypeSize> +struct _sized_signed; + +template<> +struct _sized_signed<sizeof(uint8)> +{ + typedef int8 type; +}; + +template<> +struct _sized_signed<sizeof(uint16)> +{ + typedef int16 type; +}; + +template<> +struct _sized_signed<sizeof(uint32)> +{ + typedef int32 type; +}; + +template<> +struct _sized_signed<sizeof(uint64)> +{ + typedef int64 type; +}; + +template<typename tintergraltype> +struct _make_signed +{ + typedef typename _sized_signed<sizeof(tintergraltype)>::type type; +}; + + +template<sizeint tsiTypeSize> +struct _sized_unsigned; + +template<> +struct _sized_unsigned<sizeof(int8)> +{ + typedef uint8 type; +}; + +template<> +struct _sized_unsigned<sizeof(int16)> +{ + typedef uint16 type; +}; + +template<> +struct _sized_unsigned<sizeof(int32)> +{ + typedef uint32 type; +}; + +template<> +struct _sized_unsigned<sizeof(int64)> +{ + typedef uint64 type; +}; + +template<typename tintergraltype> +struct _make_unsigned +{ + typedef typename _sized_unsigned<sizeof(tintergraltype)>::type type; +}; + + +// template<typename tvalueint, typename tminint, typename tmaxint> +// inline +// bool dxInRange(tvalueint viValue, tminint miMin, tmaxint miMax) +// { +// return (typename _sized_unsigned<dMACRO_MAX(sizeof(tvalueint), sizeof(tminint))>::type)(viValue - miMin) < (typename _sized_unsigned<dMACRO_MAX(sizeof(tmaxint), sizeof(tminint))>::type)(miMax - miMin); +// } +// #define dIN_RANGE(aval, amin, amax) dxInRange(aval, amin, amax) + +#define dIN_RANGE(aval, amin, amax) ((_sized_unsigned<dMACRO_MAX(sizeof(aval), sizeof(amin))>::type)((_sized_unsigned<dMACRO_MAX(sizeof(aval), sizeof(amin))>::type)(aval) - (_sized_unsigned<dMACRO_MAX(sizeof(aval), sizeof(amin))>::type)(amin)) < (_sized_unsigned<dMACRO_MAX(sizeof(amax), sizeof(amin))>::type)((_sized_unsigned<dMACRO_MAX(sizeof(amax), sizeof(amin))>::type)(amax) - (_sized_unsigned<dMACRO_MAX(sizeof(amax), sizeof(amin))>::type)(amin))) +#define dTMPL_IN_RANGE(aval, amin, amax) ((typename _sized_unsigned<dMACRO_MAX(sizeof(aval), sizeof(amin))>::type)((typename _sized_unsigned<dMACRO_MAX(sizeof(aval), sizeof(amin))>::type)(aval) - (typename _sized_unsigned<dMACRO_MAX(sizeof(aval), sizeof(amin))>::type)(amin)) < (typename _sized_unsigned<dMACRO_MAX(sizeof(amax), sizeof(amin))>::type)((typename _sized_unsigned<dMACRO_MAX(sizeof(amax), sizeof(amin))>::type)(amax) - (typename _sized_unsigned<dMACRO_MAX(sizeof(amax), sizeof(amin))>::type)(amin))) +#define dCLAMP(aval, alo, ahi) dxClamp(aval, alo, ahi) +#define dARRAY_SIZE(aarr) (sizeof(aarr) / sizeof((aarr)[0])) +#define dSTATIC_ARRAY_SIZE(aclass, aarr) dARRAY_SIZE(((aclass *)sizeof(void *))->aarr) + + +#endif diff --git a/libs/ode-0.16.1/ode/src/config.h.in b/libs/ode-0.16.1/ode/src/config.h.in new file mode 100644 index 0000000..e6c0256 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/config.h.in @@ -0,0 +1,329 @@ +/* ode/src/config.h.in. Generated from configure.ac by autoheader. */ + + +#ifndef ODE_CONFIG_H +#define ODE_CONFIG_H + + +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +#undef CRAY_STACKSEG_END + +/* Define to 1 if using `alloca.c'. */ +#undef C_ALLOCA + +/* Define to 1 if you have `alloca', as a function or macro. */ +#undef HAVE_ALLOCA + +/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix). + */ +#undef HAVE_ALLOCA_H + +/* Use the Apple OpenGL framework. */ +#undef HAVE_APPLE_OPENGL_FRAMEWORK + +/* Define to 1 if you have the `atan2f' function. */ +#undef HAVE_ATAN2F + +/* Define to 1 if you have the `clock_gettime' function. */ +#undef HAVE_CLOCK_GETTIME + +/* Define to 1 if you have the `copysign' function. */ +#undef HAVE_COPYSIGN + +/* Define to 1 if you have the `copysignf' function. */ +#undef HAVE_COPYSIGNF + +/* Define to 1 if you have the `cosf' function. */ +#undef HAVE_COSF + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the `fabsf' function. */ +#undef HAVE_FABSF + +/* Define to 1 if you have the <float.h> header file. */ +#undef HAVE_FLOAT_H + +/* Define to 1 if you have the `floor' function. */ +#undef HAVE_FLOOR + +/* Define to 1 if you have the `fmodf' function. */ +#undef HAVE_FMODF + +/* Define to 1 if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define to 1 if you have the <GL/glext.h> header file. */ +#undef HAVE_GL_GLEXT_H + +/* Define to 1 if you have the <GL/glu.h> header file. */ +#undef HAVE_GL_GLU_H + +/* Define to 1 if you have the <GL/gl.h> header file. */ +#undef HAVE_GL_GL_H + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `isnan' function. */ +#undef HAVE_ISNAN + +/* Define to 1 if you have the `isnanf' function. */ +#undef HAVE_ISNANF + +/* Define to 1 if you have the `m' library (-lm). */ +#undef HAVE_LIBM + +/* Define to 1 if you have the `rt' library (-lrt). */ +#undef HAVE_LIBRT + +/* Define to 1 if you have the `sunmath' library (-lsunmath). */ +#undef HAVE_LIBSUNMATH + +/* Define to 1 if you have the <limits.h> header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if you have the <malloc.h> header file. */ +#undef HAVE_MALLOC_H + +/* Define to 1 if you have the <math.h> header file. */ +#undef HAVE_MATH_H + +/* Define to 1 if you have the `memmove' function. */ +#undef HAVE_MEMMOVE + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `memset' function. */ +#undef HAVE_MEMSET + +/* Define to 1 if you have the `no_pthread_condattr_setclock' function. */ +#undef HAVE_NO_PTHREAD_CONDATTR_SETCLOCK + +/* Define to 1 if libc includes obstacks. */ +#undef HAVE_OBSTACK + +/* Define to 1 if you have the `pthread_attr_setinheritsched' function. */ +#undef HAVE_PTHREAD_ATTR_SETINHERITSCHED + +/* Define to 1 if you have the `pthread_attr_setstacklazy' function. */ +#undef HAVE_PTHREAD_ATTR_SETSTACKLAZY + +/* Define to 1 if you have the `pthread_condattr_setclock' function. */ +#undef HAVE_PTHREAD_CONDATTR_SETCLOCK + +/* Define to 1 if you have the `sinf' function. */ +#undef HAVE_SINF + +/* Define to 1 if you have the `snprintf' function. */ +#undef HAVE_SNPRINTF + +/* Define to 1 if you have the `sqrt' function. */ +#undef HAVE_SQRT + +/* Define to 1 if you have the `sqrtf' function. */ +#undef HAVE_SQRTF + +/* Define to 1 if you have the <stdarg.h> header file. */ +#undef HAVE_STDARG_H + +/* Define to 1 if stdbool.h conforms to C99. */ +#undef HAVE_STDBOOL_H + +/* Define to 1 if you have the <stddef.h> header file. */ +#undef HAVE_STDDEF_H + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdio.h> header file. */ +#undef HAVE_STDIO_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strstr' function. */ +#undef HAVE_STRSTR + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/time.h> header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the <time.h> header file. */ +#undef HAVE_TIME_H + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `vsnprintf' function. */ +#undef HAVE_VSNPRINTF + +/* Define to 1 if the system has the type `_Bool'. */ +#undef HAVE__BOOL + +/* Define to 1 if you have the `_isnan' function. */ +#undef HAVE__ISNAN + +/* Define to 1 if you have the `_isnanf' function. */ +#undef HAVE__ISNANF + +/* Define to 1 if you have the `__isnan' function. */ +#undef HAVE___ISNAN + +/* Define to 1 if you have the `__isnanf' function. */ +#undef HAVE___ISNANF + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#undef LT_OBJDIR + +/* Mac OS X version setting for OU Library */ +#undef MAC_OS_X_VERSION + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* compiling for a pentium on a gcc-based platform? */ +#undef PENTIUM + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +#undef STACK_DIRECTION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +# undef WORDS_BIGENDIAN +# endif +#endif + +/* compiling for a X86_64 system on a gcc-based platform? */ +#undef X86_64_SYSTEM + +/* OU features enabled */ +#undef _OU_FEATURE_SET + +/* libou namespace for ODE */ +#undef _OU_NAMESPACE + +/* Target OS setting for OU Library */ +#undef _OU_TARGET_OS + +/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>, + <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +#undef _UINT32_T + +/* Atomic API of OU is enabled */ +#undef dATOMICS_ENABLED + +/* Built-in multithreaded threading implementation is included */ +#undef dBUILTIN_THREADING_IMPL_ENABLED + +/* Generic OU features are enabled */ +#undef dOU_ENABLED + +/* Threading interface is disabled */ +#undef dTHREADING_INTF_DISABLED + +/* Thread Local Storage API of OU is enabled */ +#undef dTLS_ENABLED + +/* Use the old trimesh-trimesh collider */ +#undef dTRIMESH_OPCODE_USE_OLD_TRIMESH_TRIMESH_COLLIDER + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to the type of a signed integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ +#undef int32_t + +/* Define to `unsigned int' if <sys/types.h> does not define. */ +#undef size_t + +/* Define to the type of an unsigned integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ +#undef uint32_t + +/* Define to empty if the keyword `volatile' does not work. Warning: valid + code using `volatile' can become incorrect without. Disable with care. */ +#undef volatile + + + +#ifdef HAVE_ALLOCA_H +#include <alloca.h> +#endif +#ifdef HAVE_MALLOC_H +#include <malloc.h> +#endif +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif +#ifdef HAVE_INTTYPES_H +#include <inttypes.h> +#endif + + +#include "typedefs.h" + + +#endif /* #define ODE_CONFIG_H */ + diff --git a/libs/ode-0.16.1/ode/src/convex.cpp b/libs/ode-0.16.1/ode/src/convex.cpp new file mode 100644 index 0000000..7a17941 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/convex.cpp @@ -0,0 +1,1621 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ +/* +Code for Convex Collision Detection +By Rodrigo Hernandez +*/ +#include <ode/common.h> +#include <ode/collision.h> +#include <ode/rotation.h> +#include "config.h" +#include "matrix.h" +#include "odemath.h" +#include "collision_kernel.h" +#include "collision_std.h" +#include "collision_util.h" + +#ifdef _MSC_VER +#pragma warning(disable:4291) // for VC++, no complaints about "no matching operator delete found" +#endif + +#if 1 +#define dMIN(A,B) ((A)>(B) ? (B) : (A)) +#define dMAX(A,B) ((A)>(B) ? (A) : (B)) +#else +#define dMIN(A,B) std::min(A,B) +#define dMAX(A,B) std::max(A,B) +#endif + +//**************************************************************************** +// Convex public API +dxConvex::dxConvex (dSpaceID space, + const dReal *_planes, + unsigned int _planecount, + const dReal *_points, + unsigned int _pointcount, + const unsigned int *_polygons) : +dxGeom (space,1) +{ + dAASSERT (_planes != NULL); + dAASSERT (_points != NULL); + dAASSERT (_polygons != NULL); + //fprintf(stdout,"dxConvex Constructor planes %X\n",_planes); + type = dConvexClass; + planes = _planes; + planecount = _planecount; + // we need points as well + points = _points; + pointcount = _pointcount; + polygons=_polygons; + edges = NULL; + FillEdges(); +#ifndef dNODEBUG + // Check for properly build polygons by calculating the determinant + // of the 3x3 matrix composed of the first 3 points in the polygon. + const unsigned int *points_in_poly=polygons; + const unsigned int *index=polygons+1; + + for(unsigned int i=0;i<planecount;++i) + { + dAASSERT (*points_in_poly > 2 ); + if(( + points[(index[0]*3)+0]*points[(index[1]*3)+1]*points[(index[2]*3)+2] + + points[(index[0]*3)+1]*points[(index[1]*3)+2]*points[(index[2]*3)+0] + + points[(index[0]*3)+2]*points[(index[1]*3)+0]*points[(index[2]*3)+1] - + points[(index[0]*3)+2]*points[(index[1]*3)+1]*points[(index[2]*3)+0] - + points[(index[0]*3)+1]*points[(index[1]*3)+0]*points[(index[2]*3)+2] - + points[(index[0]*3)+0]*points[(index[1]*3)+2]*points[(index[2]*3)+1])<0) + { + fprintf(stdout,"WARNING: Polygon %d is not defined counterclockwise\n",i); + } + points_in_poly+=(*points_in_poly+1); + index=points_in_poly+1; + if(planes[(i*4)+3]<0) fprintf(stdout,"WARNING: Plane %d does not contain the origin\n",i); + } +#endif + + //CreateTree(); +} + + +void dxConvex::computeAABB() +{ + // this can, and should be optimized + dVector3 point; + dMultiply0_331 (point,final_posr->R,points); + aabb[0] = point[0]+final_posr->pos[0]; + aabb[1] = point[0]+final_posr->pos[0]; + aabb[2] = point[1]+final_posr->pos[1]; + aabb[3] = point[1]+final_posr->pos[1]; + aabb[4] = point[2]+final_posr->pos[2]; + aabb[5] = point[2]+final_posr->pos[2]; + for(unsigned int i=3;i<(pointcount*3);i+=3) + { + dMultiply0_331 (point,final_posr->R,&points[i]); + aabb[0] = dMIN(aabb[0],point[0]+final_posr->pos[0]); + aabb[1] = dMAX(aabb[1],point[0]+final_posr->pos[0]); + aabb[2] = dMIN(aabb[2],point[1]+final_posr->pos[1]); + aabb[3] = dMAX(aabb[3],point[1]+final_posr->pos[1]); + aabb[4] = dMIN(aabb[4],point[2]+final_posr->pos[2]); + aabb[5] = dMAX(aabb[5],point[2]+final_posr->pos[2]); + } +} + +/*! \brief Populates the edges set, should be called only once whenever the polygon array gets updated */ +void dxConvex::FillEdges() +{ + const unsigned int *points_in_poly=polygons; + const unsigned int *index=polygons+1; + if (edges!=NULL) delete[] edges; + edgecount = 0; + edge e; + bool isinset; + for(unsigned int i=0;i<planecount;++i) + { + for(unsigned int j=0;j<*points_in_poly;++j) + { + e.first = dMIN(index[j],index[(j+1)%*points_in_poly]); + e.second = dMAX(index[j],index[(j+1)%*points_in_poly]); + isinset=false; + for(unsigned int k=0;k<edgecount;++k) + { + if((edges[k].first==e.first)&&(edges[k].second==e.second)) + { + isinset=true; + break; + } + } + if(!isinset) + { + edge* tmp = new edge[edgecount+1]; + if(edgecount!=0) + { + memcpy(tmp,edges,(edgecount)*sizeof(edge)); + delete[] edges; + } + tmp[edgecount].first=e.first; + tmp[edgecount].second=e.second; + edges = tmp; + ++edgecount; + } + } + points_in_poly+=(*points_in_poly+1); + index=points_in_poly+1; + } +} +#if 0 +dxConvex::BSPNode* dxConvex::CreateNode(std::vector<Arc> Arcs,std::vector<Polygon> Polygons) +{ +#if 0 + dVector3 ea,eb,e; + dVector3Copy(points+((edges.begin()+Arcs[0].edge)first*3),ea); + dMultiply0_331(e1b,cvx1.final_posr->R,cvx1.points+(i->second*3)); + + dVector3Copy(points[edges[Arcs[0].edge] +#endif + return NULL; +} + +void dxConvex::CreateTree() +{ + std::vector<Arc> A; + A.reserve(edgecount); + for(unsigned int i=0;i<edgecount;++i) + { + this->GetFacesSharedByEdge(i,A[i].normals); + A[i].edge = i; + } + std::vector<Polygon> S; + S.reserve(pointcount); + for(unsigned int i=0;i<pointcount;++i) + { + this->GetFacesSharedByVertex(i,S[i].normals); + S[i].vertex=i; + } + this->tree = CreateNode(A,S); +} + +void dxConvex::GetFacesSharedByVertex(int i, std::vector<int> f) +{ +} +void dxConvex::GetFacesSharedByEdge(int i, int* f) +{ +} +void dxConvex::GetFaceNormal(int i, dVector3 normal) +{ +} +#endif + +dGeomID dCreateConvex (dSpaceID space,const dReal *_planes,unsigned int _planecount, + const dReal *_points, + unsigned int _pointcount, + const unsigned int *_polygons) +{ + //fprintf(stdout,"dxConvex dCreateConvex\n"); + return new dxConvex(space,_planes, _planecount, + _points, + _pointcount, + _polygons); +} + +void dGeomSetConvex (dGeomID g,const dReal *_planes,unsigned int _planecount, + const dReal *_points, + unsigned int _pointcount, + const unsigned int *_polygons) +{ + //fprintf(stdout,"dxConvex dGeomSetConvex\n"); + dUASSERT (g && g->type == dConvexClass,"argument not a convex shape"); + dxConvex *s = (dxConvex*) g; + s->planes = _planes; + s->planecount = _planecount; + s->points = _points; + s->pointcount = _pointcount; + s->polygons=_polygons; +} + +//**************************************************************************** +// Helper Inlines +// + +/*! \brief Returns Whether or not the segment ab intersects plane p + \param a origin of the segment + \param b segment destination + \param p plane to test for intersection + \param t returns the time "t" in the segment ray that gives us the intersecting + point + \param q returns the intersection point + \return true if there is an intersection, otherwise false. +*/ +bool IntersectSegmentPlane(dVector3 a, + dVector3 b, + dVector4 p, + dReal &t, + dVector3 q) +{ + // Compute the t value for the directed line ab intersecting the plane + dVector3 ab; + ab[0]= b[0] - a[0]; + ab[1]= b[1] - a[1]; + ab[2]= b[2] - a[2]; + + t = (p[3] - dCalcVectorDot3(p,a)) / dCalcVectorDot3(p,ab); + + // If t in [0..1] compute and return intersection point + if (t >= 0.0 && t <= 1.0) + { + q[0] = a[0] + t * ab[0]; + q[1] = a[1] + t * ab[1]; + q[2] = a[2] + t * ab[2]; + return true; + } + // Else no intersection + return false; +} + +/*! \brief Returns the Closest Point in Ray 1 to Ray 2 + \param Origin1 The origin of Ray 1 + \param Direction1 The direction of Ray 1 + \param Origin1 The origin of Ray 2 + \param Direction1 The direction of Ray 3 + \param t the time "t" in Ray 1 that gives us the closest point + (closest_point=Origin1+(Direction1*t). + \return true if there is a closest point, false if the rays are paralell. +*/ +inline bool ClosestPointInRay(const dVector3 Origin1, + const dVector3 Direction1, + const dVector3 Origin2, + const dVector3 Direction2, + dReal& t) +{ + dVector3 w = {Origin1[0]-Origin2[0], + Origin1[1]-Origin2[1], + Origin1[2]-Origin2[2]}; + dReal a = dCalcVectorDot3(Direction1 , Direction1); + dReal b = dCalcVectorDot3(Direction1 , Direction2); + dReal c = dCalcVectorDot3(Direction2 , Direction2); + dReal d = dCalcVectorDot3(Direction1 , w); + dReal e = dCalcVectorDot3(Direction2 , w); + dReal denominator = (a*c)-(b*b); + if(denominator==0.0f) + { + return false; + } + t = ((a*e)-(b*d))/denominator; + return true; +} + +/*! \brief Returns the Closest Points from Segment 1 to Segment 2 + \param p1 start of segment 1 + \param q1 end of segment 1 + \param p2 start of segment 2 + \param q2 end of segment 2 + \param t the time "t" in Ray 1 that gives us the closest point + (closest_point=Origin1+(Direction1*t). + \return true if there is a closest point, false if the rays are paralell. + \note Adapted from Christer Ericson's Real Time Collision Detection Book. +*/ +inline void ClosestPointBetweenSegments(dVector3& p1, + dVector3& q1, + dVector3& p2, + dVector3& q2, + dVector3& c1, + dVector3& c2) +{ + // s & t were originaly part of the output args, but since + // we don't really need them, we'll just declare them in here + dReal s; + dReal t; + dVector3 d1 = {q1[0] - p1[0], + q1[1] - p1[1], + q1[2] - p1[2]}; + dVector3 d2 = {q2[0] - p2[0], + q2[1] - p2[1], + q2[2] - p2[2]}; + dVector3 r = {p1[0] - p2[0], + p1[1] - p2[1], + p1[2] - p2[2]}; + dReal a = dCalcVectorDot3(d1, d1); + dReal e = dCalcVectorDot3(d2, d2); + dReal f = dCalcVectorDot3(d2, r); + // Check if either or both segments degenerate into points + if (a <= dEpsilon && e <= dEpsilon) + { + // Both segments degenerate into points + s = t = 0.0f; + dVector3Copy(p1,c1); + dVector3Copy(p2,c2); + return; + } + if (a <= dEpsilon) + { + // First segment degenerates into a point + s = 0.0f; + t = f / e; // s = 0 => t = (b*s + f) / e = f / e + t = dxClamp(t, 0.0f, 1.0f); + } + else + { + dReal c = dCalcVectorDot3(d1, r); + if (e <= dEpsilon) + { + // Second segment degenerates into a point + t = 0.0f; + s = dxClamp(-c / a, 0.0f, 1.0f); // t = 0 => s = (b*t - c) / a = -c / a + } + else + { + // The general non degenerate case starts here + dReal b = dCalcVectorDot3(d1, d2); + dReal denom = a*e-b*b; // Always nonnegative + + // If segments not parallel, compute closest point on L1 to L2, and + // clamp to segment S1. Else pick arbitrary s (here 0) + if (denom != 0.0f) + { + s = dxClamp((b*f - c*e) / denom, 0.0f, 1.0f); + } + else s = 0.0f; +#if 0 + // Compute point on L2 closest to S1(s) using + // t = Dot((P1+D1*s)-P2,D2) / Dot(D2,D2) = (b*s + f) / e + t = (b*s + f) / e; + + // If t in [0,1] done. Else clamp t, recompute s for the new value + // of t using s = Dot((P2+D2*t)-P1,D1) / Dot(D1,D1)= (t*b - c) / a + // and clamp s to [0, 1] + if (t < 0.0f) { + t = 0.0f; + s = dxClamp(-c / a, 0.0f, 1.0f); + } else if (t > 1.0f) { + t = 1.0f; + s = dxClamp((b - c) / a, 0.0f, 1.0f); + } +#else + dReal tnom = b*s + f; + if (tnom < 0.0f) + { + t = 0.0f; + s = dxClamp(-c / a, 0.0f, 1.0f); + } + else if (tnom > e) + { + t = 1.0f; + s = dxClamp((b - c) / a, 0.0f, 1.0f); + } + else + { + t = tnom / e; + } +#endif + } + } + + c1[0] = p1[0] + d1[0] * s; + c1[1] = p1[1] + d1[1] * s; + c1[2] = p1[2] + d1[2] * s; + c2[0] = p2[0] + d2[0] * t; + c2[1] = p2[1] + d2[1] * t; + c2[2] = p2[2] + d2[2] * t; +} + +#if 0 +dReal tnom = b*s + f; +if (tnom < 0.0f) { + t = 0.0f; + s = dxClamp(-c / a, 0.0f, 1.0f); +} else if (tnom > e) { + t = 1.0f; + s = dxClamp((b - c) / a, 0.0f, 1.0f); +} else { + t = tnom / e; +} +#endif + +/*! \brief Returns the Ray on which 2 planes intersect if they do. + \param p1 Plane 1 + \param p2 Plane 2 + \param p Contains the origin of the ray upon returning if planes intersect + \param d Contains the direction of the ray upon returning if planes intersect + \return true if the planes intersect, false if paralell. +*/ +inline bool IntersectPlanes(const dVector4 p1, const dVector4 p2, dVector3 p, dVector3 d) +{ + // Compute direction of intersection line + dCalcVectorCross3(d,p1,p2); + // If d is (near) zero, the planes are parallel (and separated) + // or coincident, so they're not considered intersecting + dReal denom = dCalcVectorDot3(d, d); + if (denom < dEpsilon) return false; + dVector3 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]; + // Compute point on intersection line + dCalcVectorCross3(p,n,d); + p[0]/=denom; + p[1]/=denom; + p[2]/=denom; + return true; +} + + +#if 0 +/*! \brief Finds out if a point lies inside a convex + \param p Point to test + \param convex a pointer to convex to test against + \return true if the point lies inside the convex, false if not. +*/ +inline bool IsPointInConvex(dVector3 p, + dxConvex *convex) +{ + dVector3 lp,tmp; + // move point into convex space to avoid plane local to world calculations + tmp[0] = p[0] - convex->final_posr->pos[0]; + tmp[1] = p[1] - convex->final_posr->pos[1]; + tmp[2] = p[2] - convex->final_posr->pos[2]; + dMultiply1_331 (lp,convex->final_posr->R,tmp); + for(unsigned int i=0;i<convex->planecount;++i) + { + if(( + ((convex->planes+(i*4))[0]*lp[0])+ + ((convex->planes+(i*4))[1]*lp[1])+ + ((convex->planes+(i*4))[2]*lp[2])+ + -(convex->planes+(i*4))[3] + )>0) + { + return false; + } + } + return true; +} +#endif + +/*! \brief Finds out if a point lies inside a 2D polygon + \param p Point to test + \param polygon a pointer to the start of the convex polygon index buffer + \param out the closest point in the polygon if the point is not inside + \return true if the point lies inside of the polygon, false if not. +*/ +inline bool IsPointInPolygon(dVector3 p, + const unsigned int *polygon, + dReal *plane, + dxConvex *convex, + dVector3 out) +{ + // p is the point we want to check, + // polygon is a pointer to the polygon we + // are checking against, remember it goes + // number of vertices then that many indexes + // out returns the closest point on the border of the + // polygon if the point is not inside it. + dVector3 a; + dVector3 b; + dVector3 ab; + dVector3 ap; + dVector3 v; + + unsigned pointcount=polygon[0]; + dIASSERT(pointcount != 0); + polygon++; // skip past pointcount + + dMultiply0_331 (b,convex->final_posr->R, + &convex->points[(polygon[pointcount-1]*3)]); + b[0]=convex->final_posr->pos[0]+b[0]; + b[1]=convex->final_posr->pos[1]+b[1]; + b[2]=convex->final_posr->pos[2]+b[2]; + + for(unsigned i=0; i != pointcount; ++i) + { + a[0] = b[0]; + a[1] = b[1]; + a[2] = b[2]; + + dMultiply0_331 (b,convex->final_posr->R,&convex->points[(polygon[i]*3)]); + b[0]=convex->final_posr->pos[0]+b[0]; + b[1]=convex->final_posr->pos[1]+b[1]; + b[2]=convex->final_posr->pos[2]+b[2]; + + ab[0] = b[0] - a[0]; + ab[1] = b[1] - a[1]; + ab[2] = b[2] - a[2]; + ap[0] = p[0] - a[0]; + ap[1] = p[1] - a[1]; + ap[2] = p[2] - a[2]; + + dCalcVectorCross3(v, ab, plane); + + if (dCalcVectorDot3(ap, v) > REAL(0.0)) + { + dReal ab_m2 = dCalcVectorDot3(ab, ab); + dReal s = ab_m2 != REAL(0.0) ? dCalcVectorDot3(ab, ap) / ab_m2 : REAL(0.0); + + if (s <= REAL(0.0)) + { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + } + else if (s >= REAL(1.0)) + { + out[0] = b[0]; + out[1] = b[1]; + out[2] = b[2]; + } + else + { + out[0] = a[0] + ab[0] * s; + out[1] = a[1] + ab[1] * s; + out[2] = a[2] + ab[2] * s; + } + + return false; + } + } + + return true; +} + +int dCollideConvexPlane (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dConvexClass); + dIASSERT (o2->type == dPlaneClass); + dIASSERT ((flags & NUMC_MASK) >= 1); + + dxConvex *Convex = (dxConvex*) o1; + dxPlane *Plane = (dxPlane*) o2; + unsigned int contacts=0; + unsigned int maxc = flags & NUMC_MASK; + dVector3 v2; + +#define LTEQ_ZERO 0x10000000 +#define GTEQ_ZERO 0x20000000 +#define BOTH_SIGNS (LTEQ_ZERO | GTEQ_ZERO) + dIASSERT((BOTH_SIGNS & NUMC_MASK) == 0); // used in conditional operator later + + unsigned int totalsign = 0; + for(unsigned int i=0;i<Convex->pointcount;++i) + { + dMultiply0_331 (v2,Convex->final_posr->R,&Convex->points[(i*3)]); + dVector3Add(Convex->final_posr->pos, v2, v2); + + unsigned int distance2sign = GTEQ_ZERO; + dReal distance2 = dVector3Dot(Plane->p, v2) - Plane->p[3]; // Ax + By + Cz - D + if((distance2 <= REAL(0.0))) + { + distance2sign = distance2 != REAL(0.0) ? LTEQ_ZERO : BOTH_SIGNS; + + if (contacts != maxc) + { + dContactGeom *target = SAFECONTACT(flags, contact, contacts, skip); + dVector3Copy(Plane->p, target->normal); + dVector3Copy(v2, target->pos); + target->depth = -distance2; + target->g1 = Convex; + target->g2 = Plane; + target->side1 = -1; // TODO: set plane index? + target->side2 = -1; + contacts++; + } + } + + // Take new sign into account + totalsign |= distance2sign; + // Check if contacts are full and both signs have been already found + if (((contacts ^ maxc) | totalsign) == BOTH_SIGNS) // harder to comprehend but requires one register less + { + break; // Nothing can be changed any more + } + } + if (totalsign == BOTH_SIGNS) return contacts; + return 0; +#undef BOTH_SIGNS +#undef GTEQ_ZERO +#undef LTEQ_ZERO +} + +int dCollideSphereConvex (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dSphereClass); + dIASSERT (o2->type == dConvexClass); + dIASSERT ((flags & NUMC_MASK) >= 1); + + dxSphere *Sphere = (dxSphere*) o1; + dxConvex *Convex = (dxConvex*) o2; + dReal dist,closestdist=dInfinity; + dVector4 plane; + // dVector3 contactpoint; + dVector3 offsetpos,out,temp; + const unsigned int *pPoly=Convex->polygons; + int closestplane=-1; + bool sphereinside=true; + /* + Do a good old sphere vs plane check first, + if a collision is found then check if the contact point + is within the polygon + */ + // offset the sphere final_posr->position into the convex space + offsetpos[0]=Sphere->final_posr->pos[0]-Convex->final_posr->pos[0]; + offsetpos[1]=Sphere->final_posr->pos[1]-Convex->final_posr->pos[1]; + offsetpos[2]=Sphere->final_posr->pos[2]-Convex->final_posr->pos[2]; + for(unsigned int i=0;i<Convex->planecount;++i) + { + // apply rotation to the plane + dMultiply0_331(plane,Convex->final_posr->R,&Convex->planes[(i*4)]); + plane[3]=(&Convex->planes[(i*4)])[3]; + // Get the distance from the sphere origin to the plane + dist = dVector3Dot(plane, offsetpos) - plane[3]; // Ax + By + Cz - D + if(dist>0) + { + // if we get here, we know the center of the sphere is + // outside of the convex hull. + if(dist<Sphere->radius) + { + // if we get here we know the sphere surface penetrates + // the plane + if(IsPointInPolygon(Sphere->final_posr->pos,pPoly,plane,Convex,out)) + { + // finally if we get here we know that the + // sphere is directly touching the inside of the polyhedron + contact->normal[0] = plane[0]; + contact->normal[1] = plane[1]; + contact->normal[2] = plane[2]; + contact->pos[0] = Sphere->final_posr->pos[0]+ + (-contact->normal[0]*Sphere->radius); + contact->pos[1] = Sphere->final_posr->pos[1]+ + (-contact->normal[1]*Sphere->radius); + contact->pos[2] = Sphere->final_posr->pos[2]+ + (-contact->normal[2]*Sphere->radius); + contact->depth = Sphere->radius-dist; + contact->g1 = Sphere; + contact->g2 = Convex; + contact->side1 = -1; + contact->side2 = -1; // TODO: set plane index? + return 1; + } + else + { + // the sphere may not be directly touching + // the polyhedron, but it may be touching + // a point or an edge, if the distance between + // the closest point on the poly (out) and the + // center of the sphere is less than the sphere + // radius we have a hit. + temp[0] = (Sphere->final_posr->pos[0]-out[0]); + temp[1] = (Sphere->final_posr->pos[1]-out[1]); + temp[2] = (Sphere->final_posr->pos[2]-out[2]); + dist=(temp[0]*temp[0])+(temp[1]*temp[1])+(temp[2]*temp[2]); + // avoid the sqrt unless really necesary + if(dist<(Sphere->radius*Sphere->radius)) + { + // We got an indirect hit + dist=dSqrt(dist); + contact->normal[0] = temp[0]/dist; + contact->normal[1] = temp[1]/dist; + contact->normal[2] = temp[2]/dist; + contact->pos[0] = Sphere->final_posr->pos[0]+ + (-contact->normal[0]*Sphere->radius); + contact->pos[1] = Sphere->final_posr->pos[1]+ + (-contact->normal[1]*Sphere->radius); + contact->pos[2] = Sphere->final_posr->pos[2]+ + (-contact->normal[2]*Sphere->radius); + contact->depth = Sphere->radius-dist; + contact->g1 = Sphere; + contact->g2 = Convex; + contact->side1 = -1; + contact->side2 = -1; // TODO: set plane index? + return 1; + } + } + } + sphereinside=false; + } + if(sphereinside) + { + if(closestdist>dFabs(dist)) + { + closestdist=dFabs(dist); + closestplane=i; + } + } + pPoly+=pPoly[0]+1; + } + if(sphereinside) + { + // if the center of the sphere is inside + // the Convex, we need to pop it out + dMultiply0_331(contact->normal, + Convex->final_posr->R, + &Convex->planes[(closestplane*4)]); + contact->pos[0] = Sphere->final_posr->pos[0]; + contact->pos[1] = Sphere->final_posr->pos[1]; + contact->pos[2] = Sphere->final_posr->pos[2]; + contact->depth = closestdist+Sphere->radius; + contact->g1 = Sphere; + contact->g2 = Convex; + contact->side1 = -1; + contact->side2 = -1; // TODO: set plane index? + return 1; + } + return 0; +} + +int dCollideConvexBox (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom * /*contact*/, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dConvexClass); + dIASSERT (o2->type == dBoxClass); + dIASSERT ((flags & NUMC_MASK) >= 1); + + //dxConvex *Convex = (dxConvex*) o1; + //dxBox *Box = (dxBox*) o2; + + return 0; +} + +int dCollideConvexCapsule (dxGeom *o1, dxGeom *o2, + int flags, dContactGeom * /*contact*/, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dConvexClass); + dIASSERT (o2->type == dCapsuleClass); + dIASSERT ((flags & NUMC_MASK) >= 1); + + //dxConvex *Convex = (dxConvex*) o1; + //dxCapsule *Capsule = (dxCapsule*) o2; + + return 0; +} + +inline void ComputeInterval(dxConvex& cvx,dVector4 axis,dReal& min,dReal& max) +{ + /* TODO: Use Support points here */ + dVector3 point; + dReal value; + //fprintf(stdout,"Compute Interval Axis %f,%f,%f\n",axis[0],axis[1],axis[2]); + dMultiply0_331(point,cvx.final_posr->R,cvx.points); + //fprintf(stdout,"initial point %f,%f,%f\n",point[0],point[1],point[2]); + point[0]+=cvx.final_posr->pos[0]; + point[1]+=cvx.final_posr->pos[1]; + point[2]+=cvx.final_posr->pos[2]; + max = min = dCalcVectorDot3(point,axis)-axis[3];//(*) + for (unsigned int i = 1; i < cvx.pointcount; ++i) + { + dMultiply0_331(point,cvx.final_posr->R,cvx.points+(i*3)); + point[0]+=cvx.final_posr->pos[0]; + point[1]+=cvx.final_posr->pos[1]; + point[2]+=cvx.final_posr->pos[2]; + value=dCalcVectorDot3(point,axis)-axis[3];//(*) + if(value<min) + { + min=value; + } + else if(value>max) + { + max=value; + } + } + // *: usually using the distance part of the plane (axis) is + // not necesary, however, here we need it here in order to know + // which face to pick when there are 2 parallel sides. +} + +bool CheckEdgeIntersection(dxConvex& cvx1,dxConvex& cvx2, int flags,int& curc, + dContactGeom *contact, int skip) +{ + int maxc = flags & NUMC_MASK; + dIASSERT(maxc != 0); + dVector3 e1,e2,q; + dVector4 plane,depthplane; + dReal t; + for(unsigned int i = 0;i<cvx1.edgecount;++i) + { + // Rotate + dMultiply0_331(e1,cvx1.final_posr->R,cvx1.points+(cvx1.edges[i].first*3)); + // translate + e1[0]+=cvx1.final_posr->pos[0]; + e1[1]+=cvx1.final_posr->pos[1]; + e1[2]+=cvx1.final_posr->pos[2]; + // Rotate + dMultiply0_331(e2,cvx1.final_posr->R,cvx1.points+(cvx1.edges[i].second*3)); + // translate + e2[0]+=cvx1.final_posr->pos[0]; + e2[1]+=cvx1.final_posr->pos[1]; + e2[2]+=cvx1.final_posr->pos[2]; + const unsigned int* pPoly=cvx2.polygons; + for(sizeint j=0;j<cvx2.planecount;++j) + { + // Rotate + dMultiply0_331(plane,cvx2.final_posr->R,cvx2.planes+(j*4)); + dNormalize3(plane); + // Translate + plane[3]= + (cvx2.planes[(j*4)+3])+ + ((plane[0] * cvx2.final_posr->pos[0]) + + (plane[1] * cvx2.final_posr->pos[1]) + + (plane[2] * cvx2.final_posr->pos[2])); + dContactGeom *target = SAFECONTACT(flags, contact, curc, skip); + target->g1=&cvx1; // g1 is the one pushed + target->g2=&cvx2; + if(IntersectSegmentPlane(e1,e2,plane,t,target->pos)) + { + if(IsPointInPolygon(target->pos,pPoly,plane,&cvx2,q)) + { + target->depth = dInfinity; + for(sizeint k=0;k<cvx2.planecount;++k) + { + if(k==j) continue; // we're already at 0 depth on this plane + // Rotate + dMultiply0_331(depthplane,cvx2.final_posr->R,cvx2.planes+(k*4)); + dNormalize3(depthplane); + // Translate + depthplane[3]= + (cvx2.planes[(k*4)+3])+ + ((plane[0] * cvx2.final_posr->pos[0]) + + (plane[1] * cvx2.final_posr->pos[1]) + + (plane[2] * cvx2.final_posr->pos[2])); + dReal depth = (dVector3Dot(depthplane, target->pos) - depthplane[3]); // Ax + By + Cz - D + if((fabs(depth)<fabs(target->depth))&&((depth<-dEpsilon)||(depth>dEpsilon))) + { + target->depth=depth; + dVector3Copy(depthplane,target->normal); + } + } + ++curc; + if(curc==maxc) + return true; + } + } + pPoly+=pPoly[0]+1; + } + } + return false; +} + +/* +Helper struct +*/ +struct ConvexConvexSATOutput +{ + dReal min_depth; + int depth_type; + dVector3 dist; // distance from center to center, from cvx1 to cvx2 + dVector3 e1a,e1b,e2a,e2b; // e1a to e1b = edge in cvx1,e2a to e2b = edge in cvx2. +}; + +/*! \brief Does an axis separation test using cvx1 planes on cvx1 and cvx2, returns true for a collision false for no collision + \param cvx1 [IN] First Convex object, its planes are used to do the tests + \param cvx2 [IN] Second Convex object + \param min_depth [IN/OUT] Used to input as well as output the minimum depth so far, must be set to a huge value such as dInfinity for initialization. + \param g1 [OUT] Pointer to the convex which should be used in the returned contact as g1 + \param g2 [OUT] Pointer to the convex which should be used in the returned contact as g2 +*/ +inline bool CheckSATConvexFaces(dxConvex& cvx1, + dxConvex& cvx2, + ConvexConvexSATOutput& ccso) +{ + dReal min,max,min1,max1,min2,max2,depth; + dVector4 plane; + for(unsigned int i=0;i<cvx1.planecount;++i) + { + // -- Apply Transforms -- + // Rotate + dMultiply0_331(plane,cvx1.final_posr->R,cvx1.planes+(i*4)); + dNormalize3(plane); + // Translate + plane[3]= + (cvx1.planes[(i*4)+3])+ + ((plane[0] * cvx1.final_posr->pos[0]) + + (plane[1] * cvx1.final_posr->pos[1]) + + (plane[2] * cvx1.final_posr->pos[2])); + ComputeInterval(cvx1,plane,min1,max1); + ComputeInterval(cvx2,plane,min2,max2); + if(max2<min1 || max1<min2) return false; + min = dMAX(min1, min2); + max = dMIN(max1, max2); + depth = max-min; + /* + Take only into account the faces that penetrate cvx1 to determine + minimum depth + ((max2*min2)<=0) = different sign, or one is zero and thus + cvx2 barelly touches cvx1 + */ + if (((max2*min2)<=0) && (dFabs(depth)<dFabs(ccso.min_depth))) + { + // Flip plane because the contact normal must point INTO g1, + // plus the integrator seems to like positive depths better than negative ones + ccso.min_depth=-depth; + ccso.depth_type = 1; // 1 = face-something + } + } + return true; +} +/*! \brief Does an axis separation test using cvx1 and cvx2 edges, returns true for a collision false for no collision + \param cvx1 [IN] First Convex object + \param cvx2 [IN] Second Convex object + \param min_depth [IN/OUT] Used to input as well as output the minimum depth so far, must be set to a huge value such as dInfinity for initialization. + \param g1 [OUT] Pointer to the convex which should be used in the returned contact as g1 + \param g2 [OUT] Pointer to the convex which should be used in the returned contact as g2 +*/ +inline bool CheckSATConvexEdges(dxConvex& cvx1, + dxConvex& cvx2, + ConvexConvexSATOutput& ccso) +{ + // Test cross products of pairs of edges + dReal depth,min,max,min1,max1,min2,max2; + dVector4 plane; + dVector3 e1,e2,e1a,e1b,e2a,e2b; + dVector3 dist; + dVector3Copy(ccso.dist,dist); + unsigned int s1 = cvx1.SupportIndex(dist); + // invert direction + dVector3Inv(dist); + unsigned int s2 = cvx2.SupportIndex(dist); + for(unsigned int i = 0;i<cvx1.edgecount;++i) + { + // Skip edge if it doesn't contain the extremal vertex + if((cvx1.edges[i].first!=s1)&&(cvx1.edges[i].second!=s1)) continue; + // we only need to apply rotation here + dMultiply0_331(e1a,cvx1.final_posr->R,cvx1.points+(cvx1.edges[i].first*3)); + dMultiply0_331(e1b,cvx1.final_posr->R,cvx1.points+(cvx1.edges[i].second*3)); + e1[0]=e1b[0]-e1a[0]; + e1[1]=e1b[1]-e1a[1]; + e1[2]=e1b[2]-e1a[2]; + for(unsigned int j = 0;j<cvx2.edgecount;++j) + { + // Skip edge if it doesn't contain the extremal vertex + if((cvx2.edges[j].first!=s2)&&(cvx2.edges[j].second!=s2)) continue; + // we only need to apply rotation here + dMultiply0_331 (e2a,cvx2.final_posr->R,cvx2.points+(cvx2.edges[j].first*3)); + dMultiply0_331 (e2b,cvx2.final_posr->R,cvx2.points+(cvx2.edges[j].second*3)); + e2[0]=e2b[0]-e2a[0]; + e2[1]=e2b[1]-e2a[1]; + e2[2]=e2b[2]-e2a[2]; + dCalcVectorCross3(plane,e1,e2); + if(dCalcVectorDot3(plane,plane)<dEpsilon) /* edges are parallel */ continue; + dNormalize3(plane); + plane[3]=0; + ComputeInterval(cvx1,plane,min1,max1); + ComputeInterval(cvx2,plane,min2,max2); + if(max2 < min1 || max1 < min2) return false; + min = dMAX(min1, min2); + max = dMIN(max1, max2); + depth = max-min; + if (((dFabs(depth)+dEpsilon)<dFabs(ccso.min_depth))) + { + ccso.min_depth=depth; + ccso.depth_type = 2; // 2 means edge-edge + // use cached values, add position + dVector3Copy(e1a,ccso.e1a); + dVector3Copy(e1b,ccso.e1b); + ccso.e1a[0]+=cvx1.final_posr->pos[0]; + ccso.e1a[1]+=cvx1.final_posr->pos[1]; + ccso.e1a[2]+=cvx1.final_posr->pos[2]; + ccso.e1b[0]+=cvx1.final_posr->pos[0]; + ccso.e1b[1]+=cvx1.final_posr->pos[1]; + ccso.e1b[2]+=cvx1.final_posr->pos[2]; + dVector3Copy(e2a,ccso.e2a); + dVector3Copy(e2b,ccso.e2b); + ccso.e2a[0]+=cvx2.final_posr->pos[0]; + ccso.e2a[1]+=cvx2.final_posr->pos[1]; + ccso.e2a[2]+=cvx2.final_posr->pos[2]; + ccso.e2b[0]+=cvx2.final_posr->pos[0]; + ccso.e2b[1]+=cvx2.final_posr->pos[1]; + ccso.e2b[2]+=cvx2.final_posr->pos[2]; + } + } + } + return true; +} + +#if 0 +/*! \brief Returns the index of the plane/side of the incident convex (ccso.g2) + * which is closer to the reference convex (ccso.g1) side + * + * This function just looks for the incident face that is facing the reference face + * and is the closest to being parallel to it, which sometimes is. + */ +inline unsigned int GetIncidentSide(ConvexConvexSATOutput& ccso) +{ + dVector3 nis; // (N)ormal in (I)ncident convex (S)pace + dReal SavedDot; + dReal Dot; + unsigned int incident_side=0; + // Rotate the plane normal into incident convex space + // (things like this should be done all over this file, + // will look into that) + dMultiply1_331(nis,ccso.g2->final_posr->R,ccso.plane); + SavedDot = dCalcVectorDot3(nis,ccso.g2->planes); + for(unsigned int i=1;i<ccso.g2->planecount;++i) + { + Dot = dCalcVectorDot3(nis,ccso.g2->planes+(i*4)); + if(Dot>SavedDot) + { + SavedDot=Dot; + incident_side=i; + } + } + return incident_side; +} +#endif + +inline unsigned int GetSupportSide(dVector3& dir,dxConvex& cvx) +{ + dVector3 dics,tmp; // Direction in convex space + dReal SavedDot; + dReal Dot; + unsigned int side=0; + dVector3Copy(dir,tmp); + dNormalize3(tmp); + dMultiply1_331(dics,cvx.final_posr->R,tmp); + SavedDot = dCalcVectorDot3(dics,cvx.planes); + for(unsigned int i=1;i<cvx.planecount;++i) + { + Dot = dCalcVectorDot3(dics,cvx.planes+(i*4)); + if(Dot>SavedDot) + { + SavedDot=Dot; + side=i; + } + } + return side; +} + +/*! \brief Does an axis separation test between the 2 convex shapes +using faces and edges */ +int TestConvexIntersection(dxConvex& cvx1,dxConvex& cvx2, int flags, + dContactGeom *contact, int skip) +{ + ConvexConvexSATOutput ccso; +#ifndef dNDEBUG + memset(&ccso, 0, sizeof(ccso)); // get rid of 'uninitialized values' warning +#endif + ccso.min_depth=dInfinity; // Min not min at all + ccso.depth_type=0; // no type + // precompute distance vector + dSubtractVectors3(ccso.dist, cvx2.final_posr->pos, cvx1.final_posr->pos); + int maxc = flags & NUMC_MASK; + dIASSERT(maxc != 0); + dVector3 i1,i2,r1,r2; // edges of incident and reference faces respectively + int contacts=0; + if(!CheckSATConvexFaces(cvx1,cvx2,ccso)) + { + return 0; + } + else + if(!CheckSATConvexFaces(cvx2,cvx1,ccso)) + { + return 0; + } + else if(!CheckSATConvexEdges(cvx1,cvx2,ccso)) + { + return 0; + } + // If we get here, there was a collision + if(ccso.depth_type==1) // face-face + { + // cvx1 MUST always be in contact->g1 and cvx2 in contact->g2 + // This was learned the hard way :( + unsigned int incident_side; + const unsigned int* pIncidentPoly; + const unsigned int* pIncidentPoints; + unsigned int reference_side; + const unsigned int* pReferencePoly; + const unsigned int* pReferencePoints; + dVector4 plane,rplane,iplane; + dVector3 tmp; + dVector3 dist,p; + dReal t,d,d1,d2; + bool outside,out; + dVector3Copy(ccso.dist,dist); + reference_side = GetSupportSide(dist,cvx1); + dNegateVector3(dist); + incident_side = GetSupportSide(dist,cvx2); + + pReferencePoly = cvx1.polygons; + pIncidentPoly = cvx2.polygons; + // Get Reference plane (We may not have to apply transforms Optimization Oportunity) + // Rotate + dMultiply0_331(rplane,cvx1.final_posr->R,cvx1.planes+(reference_side*4)); + dNormalize3(rplane); + // Translate + rplane[3]= + (cvx1.planes[(reference_side*4)+3])+ + ((rplane[0] * cvx1.final_posr->pos[0]) + + (rplane[1] * cvx1.final_posr->pos[1]) + + (rplane[2] * cvx1.final_posr->pos[2])); + // flip + rplane[0]=-rplane[0]; + rplane[1]=-rplane[1]; + rplane[2]=-rplane[2]; + rplane[3]=-rplane[3]; + for(unsigned int i=0;i<incident_side;++i) + { + pIncidentPoly+=pIncidentPoly[0]+1; + } + pIncidentPoints = pIncidentPoly+1; + // Get the first point of the incident face + dMultiply0_331(i2,cvx2.final_posr->R,&cvx2.points[(pIncidentPoints[0]*3)]); + dVector3Add(i2,cvx2.final_posr->pos,i2); + // Get the same point in the reference convex space + dVector3Copy(i2,r2); + dVector3Subtract(r2,cvx1.final_posr->pos,r2); + dVector3Copy(r2,tmp); + dMultiply1_331(r2,cvx1.final_posr->R,tmp); + for(unsigned int i=0;i<pIncidentPoly[0];++i) + { + // Move i2 to i1, r2 to r1 + dVector3Copy(i2,i1); + dVector3Copy(r2,r1); + dMultiply0_331(i2,cvx2.final_posr->R,&cvx2.points[(pIncidentPoints[(i+1)%pIncidentPoly[0]]*3)]); + dVector3Add(i2,cvx2.final_posr->pos,i2); + // Get the same point in the reference convex space + dVector3Copy(i2,r2); + dVector3Subtract(r2,cvx1.final_posr->pos,r2); + dVector3Copy(r2,tmp); + dMultiply1_331(r2,cvx1.final_posr->R,tmp); + outside=false; + for(unsigned int j=0;j<cvx1.planecount;++j) + { + plane[0]=cvx1.planes[(j*4)+0]; + plane[1]=cvx1.planes[(j*4)+1]; + plane[2]=cvx1.planes[(j*4)+2]; + plane[3]=cvx1.planes[(j*4)+3]; + // Get the distance from the points to the plane + d1 = r1[0]*plane[0]+ + r1[1]*plane[1]+ + r1[2]*plane[2]- + plane[3]; + d2 = r2[0]*plane[0]+ + r2[1]*plane[1]+ + r2[2]*plane[2]- + plane[3]; + if(d1*d2<0) + { + out = false; + + // Edge intersects plane + if (!IntersectSegmentPlane(r1,r2,plane,t,p)) + { + out = true; + } + + if (!out) + { + // Check the resulting point again to make sure it is inside the reference convex + for (unsigned int k = 0; k < cvx1.planecount; ++k) + { + d = p[0]*cvx1.planes[(k*4)+0]+ + p[1]*cvx1.planes[(k*4)+1]+ + p[2]*cvx1.planes[(k*4)+2]- + cvx1.planes[(k*4)+3]; + if(d>0) + { + out = true; + break; + } + } + } + + if(!out) + { +#if 0 + // Use t to move p into global space + p[0] = i1[0]+((i2[0]-i1[0])*t); + p[1] = i1[1]+((i2[1]-i1[1])*t); + p[2] = i1[2]+((i2[2]-i1[2])*t); +#else + // Apply reference convex transformations to p + // The commented out piece of code is likelly to + // produce less operations than this one, but + // this way we know we are getting the right data + dMultiply0_331(tmp,cvx1.final_posr->R,p); + dVector3Add(tmp,cvx1.final_posr->pos,p); +#endif + // get p's distance to reference plane + d = p[0]*rplane[0]+ + p[1]*rplane[1]+ + p[2]*rplane[2]- + rplane[3]; + if(d>0) + { + dContactGeom *target = SAFECONTACT(flags, contact, contacts, skip); + dVector3Copy(p, target->pos); + dVector3Copy(rplane, target->normal); + target->g1 = &cvx1; + target->g2 = &cvx2; + target->depth = d; + ++contacts; + if (contacts==maxc) return contacts; + } + } + } + if(d1>0) + { + outside=true; + } + } + if(outside) continue; + d = i1[0]*rplane[0]+ + i1[1]*rplane[1]+ + i1[2]*rplane[2]- + rplane[3]; + if(d>0) + { + dContactGeom *target = SAFECONTACT(flags, contact, contacts, skip); + dVector3Copy(i1, target->pos); + dVector3Copy(rplane, target->normal); + target->g1 = &cvx1; + target->g2 = &cvx2; + target->depth = d; + ++contacts; + if (contacts==maxc) return contacts; + } + } + // IF we get here, we got the easiest contacts to calculate, + // but there is still space in the contacts array for more. + // So, project the Reference's face points onto the Incident face + // plane and test them for inclusion in the reference plane as well. + // We already have computed intersections so, skip those. + + /* Get Incident plane, we need it for projection */ + /* Rotate */ + dMultiply0_331(iplane,cvx2.final_posr->R,cvx2.planes+(incident_side*4)); + dNormalize3(iplane); + /* Translate */ + iplane[3]= + (cvx2.planes[(incident_side*4)+3]) + + ((iplane[0] * cvx2.final_posr->pos[0]) + + (iplane[1] * cvx2.final_posr->pos[1]) + + (iplane[2] * cvx2.final_posr->pos[2])); + // get reference face + for(unsigned int i=0;i<reference_side;++i) + { + pReferencePoly+=pReferencePoly[0]+1; + } + pReferencePoints = pReferencePoly+1; + for(unsigned int i=0;i<pReferencePoly[0];++i) + { + dMultiply0_331(i1,cvx1.final_posr->R,&cvx1.points[(pReferencePoints[i]*3)]); + dVector3Add(cvx1.final_posr->pos,i1,i1); + // Project onto Incident face plane + t = -(i1[0]*iplane[0]+ + i1[1]*iplane[1]+ + i1[2]*iplane[2]- + iplane[3]); + i1[0]+=iplane[0]*t; + i1[1]+=iplane[1]*t; + i1[2]+=iplane[2]*t; + // Get the same point in the incident convex space + dVector3Copy(i1,r1); + dVector3Subtract(r1,cvx2.final_posr->pos,r1); + dVector3Copy(r1,tmp); + dMultiply1_331(r1,cvx2.final_posr->R,tmp); + // Check if it is outside the incident convex + out = false; + for(unsigned int j=0;j<cvx2.planecount;++j) + { + d = r1[0]*cvx2.planes[(j*4)+0]+ + r1[1]*cvx2.planes[(j*4)+1]+ + r1[2]*cvx2.planes[(j*4)+2]- + cvx2.planes[(j*4)+3]; + if(d>=0){out = true;break;}; + } + if(!out) + { + // check that the point is not a duplicate + outside = false; + for(int j=0;j<contacts;++j) + { + dContactGeom *cur_contact = SAFECONTACT(flags, contact, j, skip); + if((cur_contact->pos[0] == i1[0]) && + (cur_contact->pos[1] == i1[1]) && + (cur_contact->pos[2] == i1[2])) + { + outside=true; + } + } + if(!outside) + { + d = i1[0]*rplane[0]+ + i1[1]*rplane[1]+ + i1[2]*rplane[2]- + rplane[3]; + if(d>0) + { + dContactGeom *target = SAFECONTACT(flags, contact, contacts, skip); + dVector3Copy(i1, target->pos); + dVector3Copy(rplane, target->normal); + target->g1 = &cvx1; + target->g2 = &cvx2; + target->depth = d; + ++contacts; + if (contacts==maxc) return contacts; + } + } + } + } + } + else if (ccso.depth_type == 2) // edge-edge + { + dVector3 c1, c2; + ClosestPointBetweenSegments(ccso.e1a, ccso.e1b, ccso.e2a, ccso.e2b, c1, c2); + + dContactGeom *target = SAFECONTACT(flags, contact, contacts, skip); + dSubtractVectors3(target->normal, c2, c1); + dReal depth_square = dCalcVectorLengthSquare3(target->normal); + + if (dxSafeNormalize3(target->normal)) + { + target->depth = dSqrt(depth_square); + } + else + { + // If edges coincide return direction from one center to the other as the contact normal + dVector3Copy(ccso.dist, target->normal); + + if (!dxSafeNormalize3(target->normal)) + { + // If the both centers coincide as well return an arbitrary vector. The depth is going to be zero anyway. + dAssignVector3(target->normal, 1, 0, 0); + } + + target->depth = 0; // Since the edges coincide, return a contact of zero depth + } + + target->g1 = &cvx1; + target->g2 = &cvx2; + dVector3Copy(c1, target->pos); + contacts++; + } + return contacts; +} + +int dCollideConvexConvex (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dConvexClass); + dIASSERT (o2->type == dConvexClass); + dIASSERT ((flags & NUMC_MASK) >= 1); + dxConvex *Convex1 = (dxConvex*) o1; + dxConvex *Convex2 = (dxConvex*) o2; + return TestConvexIntersection(*Convex1,*Convex2,flags, + contact,skip); +} + +#if 0 +int dCollideRayConvex (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT( o1->type == dRayClass ); + dIASSERT( o2->type == dConvexClass ); + dIASSERT ((flags & NUMC_MASK) >= 1); + dxRay* ray = (dxRay*) o1; + dxConvex* convex = (dxConvex*) o2; + dVector3 origin,destination,contactpoint,out; + dReal depth; + dVector4 plane; + unsigned int *pPoly=convex->polygons; + // Calculate ray origin and destination + destination[0]=0; + destination[1]=0; + destination[2]= ray->length; + // -- Rotate -- + dMultiply0_331(destination,ray->final_posr->R,destination); + origin[0]=ray->final_posr->pos[0]; + origin[1]=ray->final_posr->pos[1]; + origin[2]=ray->final_posr->pos[2]; + destination[0]+=origin[0]; + destination[1]+=origin[1]; + destination[2]+=origin[2]; + for(int i=0;i<convex->planecount;++i) + { + // Rotate + dMultiply0_331(plane,convex->final_posr->R,convex->planes+(i*4)); + // Translate + plane[3]= + (convex->planes[(i*4)+3])+ + ((plane[0] * convex->final_posr->pos[0]) + + (plane[1] * convex->final_posr->pos[1]) + + (plane[2] * convex->final_posr->pos[2])); + if(IntersectSegmentPlane(origin, + destination, + plane, + depth, + contactpoint)) + { + if(IsPointInPolygon(contactpoint,pPoly,plane,convex,out)) + { + contact->pos[0]=contactpoint[0]; + contact->pos[1]=contactpoint[1]; + contact->pos[2]=contactpoint[2]; + contact->normal[0]=plane[0]; + contact->normal[1]=plane[1]; + contact->normal[2]=plane[2]; + contact->depth=depth; + contact->g1 = ray; + contact->g2 = convex; + contact->side1 = -1; + contact->side2 = -1; // TODO: set plane index? + return 1; + } + } + pPoly+=pPoly[0]+1; + } + return 0; +} +#else +// Ray - Convex collider by David Walters, June 2006 +int dCollideRayConvex(dxGeom *o1, dxGeom *o2, + int flags, dContactGeom *contact, int skip) +{ + dIASSERT(skip >= (int)sizeof(dContactGeom)); + dIASSERT(o1->type == dRayClass); + dIASSERT(o2->type == dConvexClass); + dIASSERT((flags & NUMC_MASK) >= 1); + + dxRay* ray = (dxRay*)o1; + dxConvex* convex = (dxConvex*)o2; + + contact->g1 = ray; + contact->g2 = convex; + contact->side1 = -1; + contact->side2 = -1; // TODO: set plane index? + + dReal alpha, beta, nsign; + int flag = 0; + + // + // Compute some useful info + // + + dVector3 ray_pos = { + ray->final_posr->pos[0] - convex->final_posr->pos[0], + ray->final_posr->pos[1] - convex->final_posr->pos[1], + ray->final_posr->pos[2] - convex->final_posr->pos[2] + }; + + dVector3 ray_dir = { + ray->final_posr->R[0 * 4 + 2], + ray->final_posr->R[1 * 4 + 2], + ray->final_posr->R[2 * 4 + 2] + }; + + dMultiply1_331(ray_pos, convex->final_posr->R, ray_pos); + dMultiply1_331(ray_dir, convex->final_posr->R, ray_dir); + + for (unsigned int i = 0; i < convex->planecount; ++i) + { + // Alias this plane. + const dReal* plane = convex->planes + (i * 4); + + // If alpha >= 0 then start point is outside of plane. + alpha = dCalcVectorDot3(plane, ray_pos) - plane[3]; + + // If any alpha is positive, then + // the ray start is _outside_ of the hull + if (alpha >= 0) + { + flag = 1; + break; + } + } + + // If the ray starts inside the convex hull, then everything is flipped. + nsign = (flag) ? REAL(1.0) : REAL(-1.0); + + + // + // Find closest contact point + // + + // Assume no contacts. + contact->depth = dInfinity; + + for (unsigned int i = 0; i < convex->planecount; ++i) + { + // Alias this plane. + const dReal* plane = convex->planes + (i * 4); + + // If alpha >= 0 then point is outside of plane. + alpha = nsign * (dCalcVectorDot3(plane, ray_pos) - plane[3]); + + // Compute [ plane-normal DOT ray-normal ], (/flip) + beta = dCalcVectorDot3(plane, ray_dir) * nsign; + + // Ray is pointing at the plane? ( beta < 0 ) + // Ray start to plane is within maximum ray length? + // Ray start to plane is closer than the current best distance? + if (beta < -dEpsilon && + alpha >= 0 && alpha <= ray->length && + alpha < contact->depth) + { + // Compute contact point on convex hull surface. + contact->pos[0] = ray_pos[0] + alpha * ray_dir[0]; + contact->pos[1] = ray_pos[1] + alpha * ray_dir[1]; + contact->pos[2] = ray_pos[2] + alpha * ray_dir[2]; + + flag = 0; + + // For all _other_ planes. + for (unsigned int j = 0; j < convex->planecount; ++j) + { + if (i == j) + continue; // Skip self. + + // Alias this plane. + const dReal* planej = convex->planes + (j * 4); + + // If beta >= 0 then start is outside of plane. + beta = dCalcVectorDot3(planej, contact->pos) - planej[3]; + + // If any beta is positive, then the contact point + // is not on the surface of the convex hull - it's just + // intersecting some part of its infinite extent. + if (beta > dEpsilon) + { + flag = 1; + break; + } + } + + // Contact point isn't outside hull's surface? then it's a good contact! + if (flag == 0) + { + // Store the contact normal, possibly flipped. + contact->normal[0] = nsign * plane[0]; + contact->normal[1] = nsign * plane[1]; + contact->normal[2] = nsign * plane[2]; + + // Store depth + contact->depth = alpha; + + if ((flags & CONTACTS_UNIMPORTANT) && contact->depth <= ray->length) + { + // Break on any contact if contacts are not important + break; + } + } + } + } + // Contact? + if (contact->depth <= ray->length) + { + // Adjust contact position and normal back to global space + dMultiply0_331(contact->pos, convex->final_posr->R, contact->pos); + dMultiply0_331(contact->normal, convex->final_posr->R, contact->normal); + contact->pos[0] += convex->final_posr->pos[0]; + contact->pos[1] += convex->final_posr->pos[1]; + contact->pos[2] += convex->final_posr->pos[2]; + return true; + } + return false; +} + +#endif +//<-- Convex Collision diff --git a/libs/ode-0.16.1/ode/src/coop_matrix_types.h b/libs/ode-0.16.1/ode/src/coop_matrix_types.h new file mode 100644 index 0000000..d94e04b --- /dev/null +++ b/libs/ode-0.16.1/ode/src/coop_matrix_types.h @@ -0,0 +1,158 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// Cooperative matrix algorithm types +// Copyright (C) 2017-2019 Oleh Derevenko (odar@eleks.com - change all "a" to "e") + + +#ifndef _ODE_COOP_MATRIX_TYPES_H_ +#define _ODE_COOP_MATRIX_TYPES_H_ + + + +#include "threadingutils.h" +#include "common.h" +#include "error.h" + + +#ifndef dCOOPERATIVE_ENABLED + +#if dATOMICS_ENABLED && !dTHREADING_INTF_DISABLED + +#define dCOOPERATIVE_ENABLED 1 + + +#endif // #if dATOMICS_ENABLED && !dTHREADING_INTF_DISABLED + + +#endif // #ifndef dCOOPERATIVE_ENABLED + + +enum +{ + COOP_THREAD_DATA_ALIGNMENT_SIZE = 64, // Typical size of a cache line +}; + + +typedef uintptr cellindexint; + + +enum CellContextInstance +{ + CCI__MIN, + + CCI_FIRST = CCI__MIN, + CCI_SECOND, + + CCI__MAX, + CCI__LOG2_OF_MAX = 1, + + CCI__DEFAULT = CCI__MIN, +}; +dSASSERT(1 << CCI__LOG2_OF_MAX >= CCI__MAX); + +static inline +CellContextInstance buildNextContextInstance(CellContextInstance instance) +{ + dIASSERT(dIN_RANGE(instance, CCI__MIN, CCI__MAX)); + dSASSERT(CCI__MAX == 2); + + return (CellContextInstance)(CCI_FIRST + CCI_SECOND - instance); +} + + +enum +{ + CELLDESC_CCI_BITMASK = (1 << CCI__LOG2_OF_MAX) - 1, + CELLDESC_LOCK_BIT = 1 << CCI__LOG2_OF_MAX, + CELLDESC__HELPER_BITS = CELLDESC_CCI_BITMASK | CELLDESC_LOCK_BIT, + CELLDESC__COLINDEX_BASE = CELLDESC__HELPER_BITS + 1, +}; + +#define MAKE_CELLDESCRIPTOR(columnIndex, contextInstance, locked) ((cellindexint)((cellindexint)(columnIndex) * CELLDESC__COLINDEX_BASE + (contextInstance) + ((locked) ? CELLDESC_LOCK_BIT : 0))) +#define MARK_CELLDESCRIPTOR_LOCKED(descriptor) ((cellindexint)((descriptor) | CELLDESC_LOCK_BIT)) +#define GET_CELLDESCRIPTOR_COLUMNINDEX(descriptor) ((unsigned int)((cellindexint)(descriptor) / CELLDESC__COLINDEX_BASE)) +#define GET_CELLDESCRIPTOR_CONTEXTINSTANCE(descriptor) ((CellContextInstance)((descriptor) & CELLDESC_CCI_BITMASK)) +#define GET_CELLDESCRIPTOR_ISLOCKED(descriptor) (((descriptor) & CELLDESC_LOCK_BIT) != 0) + +#define INVALID_CELLDESCRIPTOR MAKE_CELLDESCRIPTOR(GET_CELLDESCRIPTOR_COLUMNINDEX(-1), CCI__MAX - 1, true) + + +enum BlockProcessingState +{ + BPS_COMPETING_FOR_A_BLOCK = -1, + BPS_NO_BLOCKS_PROCESSED, + BPS_SOME_BLOCKS_PROCESSED, +}; + + +class CooperativeAtomics +{ +public: + static atomicord32 AtomicDecrementUint32(volatile atomicord32 *paoDestination) + { +#if dCOOPERATIVE_ENABLED + return ::AtomicDecrement(paoDestination); +#else + dIASSERT(false); return 0; // The function is not supposed to be called in this case +#endif // #if dCOOPERATIVE_ENABLED + } + + static bool AtomicCompareExchangeUint32(volatile atomicord32 *paoDestination, atomicord32 aoComparand, atomicord32 aoExchange) + { +#if dCOOPERATIVE_ENABLED + return ::AtomicCompareExchange(paoDestination, aoComparand, aoExchange); +#else + dIASSERT(false); return false; // The function is not supposed to be called in this case +#endif // #if dCOOPERATIVE_ENABLED + } + + static bool AtomicCompareExchangeCellindexint(volatile cellindexint *destination, cellindexint comparand, cellindexint exchange) + { +#if dCOOPERATIVE_ENABLED + return ::AtomicCompareExchangePointer((volatile atomicptr *)destination, (atomicptr)comparand, (atomicptr)exchange); +#else + dIASSERT(false); return false; // The function is not supposed to be called in this case +#endif // #if dCOOPERATIVE_ENABLED + } + + static void AtomicStoreCellindexint(volatile cellindexint *destination, cellindexint value) + { +#if dCOOPERATIVE_ENABLED + ::AtomicStorePointer((volatile atomicptr *)destination, (atomicptr)value); +#else + dIASSERT(false); // The function is not supposed to be called in this case +#endif // #if dCOOPERATIVE_ENABLED + } + + static void AtomicReadReorderBarrier() + { +#if dCOOPERATIVE_ENABLED + ::AtomicReadReorderBarrier(); +#else + dIASSERT(false); // The function is not supposed to be called in this case +#endif // #if dCOOPERATIVE_ENABLED + } +}; + + +#endif // #ifndef _ODE_COOP_MATRIX_TYPES_H_ diff --git a/libs/ode-0.16.1/ode/src/cylinder.cpp b/libs/ode-0.16.1/ode/src/cylinder.cpp new file mode 100644 index 0000000..cf5cc64 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/cylinder.cpp @@ -0,0 +1,108 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +standard ODE geometry primitives: public API and pairwise collision functions. + +the rule is that only the low level primitive collision functions should set +dContactGeom::g1 and dContactGeom::g2. + +*/ + +#include <ode/common.h> +#include <ode/collision.h> +#include <ode/rotation.h> +#include "config.h" +#include "matrix.h" +#include "odemath.h" +#include "collision_kernel.h" +#include "collision_std.h" +#include "collision_util.h" + +#ifdef _MSC_VER +#pragma warning(disable:4291) // for VC++, no complaints about "no matching operator delete found" +#endif + + +#define dMAX(A,B) ((A)>(B) ? (A) : (B)) + + +// flat cylinder public API + +dxCylinder::dxCylinder (dSpaceID space, dReal _radius, dReal _length) : +dxGeom (space,1) +{ + dAASSERT (_radius >= 0 && _length >= 0); + type = dCylinderClass; + radius = _radius; + lz = _length; + updateZeroSizedFlag(!_radius || !_length); +} + + +void dxCylinder::computeAABB() +{ + const dMatrix3& R = final_posr->R; + const dVector3& pos = final_posr->pos; + + dReal dOneMinusR2Square = (dReal)(REAL(1.0) - R[2]*R[2]); + dReal xrange = dFabs(R[2]*lz*REAL(0.5)) + radius * dSqrt(dMAX(REAL(0.0), dOneMinusR2Square)); + dReal dOneMinusR6Square = (dReal)(REAL(1.0) - R[6]*R[6]); + dReal yrange = dFabs(R[6]*lz*REAL(0.5)) + radius * dSqrt(dMAX(REAL(0.0), dOneMinusR6Square)); + dReal dOneMinusR10Square = (dReal)(REAL(1.0) - R[10]*R[10]); + dReal zrange = dFabs(R[10]*lz*REAL(0.5)) + radius * dSqrt(dMAX(REAL(0.0), dOneMinusR10Square)); + + aabb[0] = pos[0] - xrange; + aabb[1] = pos[0] + xrange; + aabb[2] = pos[1] - yrange; + aabb[3] = pos[1] + yrange; + aabb[4] = pos[2] - zrange; + aabb[5] = pos[2] + zrange; +} + + +dGeomID dCreateCylinder (dSpaceID space, dReal radius, dReal length) +{ + return new dxCylinder (space,radius,length); +} + +void dGeomCylinderSetParams (dGeomID cylinder, dReal radius, dReal length) +{ + dUASSERT (cylinder && cylinder->type == dCylinderClass,"argument not a ccylinder"); + dAASSERT (radius >= 0 && length >= 0); + dxCylinder *c = (dxCylinder*) cylinder; + c->radius = radius; + c->lz = length; + c->updateZeroSizedFlag(!radius || !length); + dGeomMoved (cylinder); +} + +void dGeomCylinderGetParams (dGeomID cylinder, dReal *radius, dReal *length) +{ + dUASSERT (cylinder && cylinder->type == dCylinderClass,"argument not a ccylinder"); + dxCylinder *c = (dxCylinder*) cylinder; + *radius = c->radius; + *length = c->lz; +} + + diff --git a/libs/ode-0.16.1/ode/src/default_threading.cpp b/libs/ode-0.16.1/ode/src/default_threading.cpp new file mode 100644 index 0000000..7f255f6 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/default_threading.cpp @@ -0,0 +1,77 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * Threading base wrapper class header file. * + * Copyright (C) 2011-2019 Oleh Derevenko. All rights reserved. * + * e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * The default threading instance holder class implementation + * Copyright (c) 2017-2019 Oleh Derevenko, odar@eleks.com (change all "a" to "e") + */ + + +#include <ode/common.h> +#include <ode/threading_impl.h> +#include "config.h" +#include "default_threading.h" +#include "error.h" + + +/*static */dThreadingImplementationID DefaultThreadingHolder::m_defaultThreadingImpl = NULL; +/*static */const dThreadingFunctionsInfo *DefaultThreadingHolder::m_defaultThreadingFunctions = NULL; + + +/*static */ +bool DefaultThreadingHolder::initializeDefaultThreading() +{ + dIASSERT(m_defaultThreadingImpl == NULL); + + bool initResult = false; + + dThreadingImplementationID threadingImpl = dThreadingAllocateSelfThreadedImplementation(); + + if (threadingImpl != NULL) + { + m_defaultThreadingFunctions = dThreadingImplementationGetFunctions(threadingImpl); + m_defaultThreadingImpl = threadingImpl; + + initResult = true; + } + + return initResult; +} + +/*static */ +void DefaultThreadingHolder::finalizeDefaultThreading() +{ + dThreadingImplementationID threadingImpl = m_defaultThreadingImpl; + + if (threadingImpl != NULL) + { + dThreadingFreeImplementation(threadingImpl); + + m_defaultThreadingFunctions = NULL; + m_defaultThreadingImpl = NULL; + } +} + diff --git a/libs/ode-0.16.1/ode/src/default_threading.h b/libs/ode-0.16.1/ode/src/default_threading.h new file mode 100644 index 0000000..372a777 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/default_threading.h @@ -0,0 +1,55 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * Threading base wrapper class header file. * + * Copyright (C) 2011-2019 Oleh Derevenko. All rights reserved. * + * e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * A default threading instance holder class definition + * Copyright (c) 2017-2019 Oleh Derevenko, odar@eleks.com (change all "a" to "e") + */ + + +#ifndef _ODE__PRIVATE_DEFAULT_THREADING_H_ +#define _ODE__PRIVATE_DEFAULT_THREADING_H_ + + +#include <ode/threading.h> + + +class DefaultThreadingHolder +{ +public: + static bool initializeDefaultThreading(); + static void finalizeDefaultThreading(); + + static dThreadingImplementationID getDefaultThreadingImpl() { return m_defaultThreadingImpl; } + static const dThreadingFunctionsInfo *getDefaultThreadingFunctions() { return m_defaultThreadingFunctions; } + +private: + static dThreadingImplementationID m_defaultThreadingImpl; + static const dThreadingFunctionsInfo *m_defaultThreadingFunctions; +}; + + +#endif // #ifndef _ODE__PRIVATE_DEFAULT_THREADING_H_ diff --git a/libs/ode-0.16.1/ode/src/error.cpp b/libs/ode-0.16.1/ode/src/error.cpp new file mode 100644 index 0000000..0b1a979 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/error.cpp @@ -0,0 +1,179 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <ode/odeconfig.h> +#include <ode/error.h> +#include "config.h" + + +static dMessageFunction *error_function = 0; +static dMessageFunction *debug_function = 0; +static dMessageFunction *message_function = 0; + + +extern "C" void dSetErrorHandler (dMessageFunction *fn) +{ + error_function = fn; +} + + +extern "C" void dSetDebugHandler (dMessageFunction *fn) +{ + debug_function = fn; +} + + +extern "C" void dSetMessageHandler (dMessageFunction *fn) +{ + message_function = fn; +} + + +extern "C" dMessageFunction *dGetErrorHandler() +{ + return error_function; +} + + +extern "C" dMessageFunction *dGetDebugHandler() +{ + return debug_function; +} + + +extern "C" dMessageFunction *dGetMessageHandler() +{ + return message_function; +} + + +static void printMessage (int num, const char *msg1, const char *msg2, + va_list ap) +{ + fflush (stderr); + fflush (stdout); + if (num) fprintf (stderr,"\n%s %d: ",msg1,num); + else fprintf (stderr,"\n%s: ",msg1); + vfprintf (stderr,msg2,ap); + fprintf (stderr,"\n"); + fflush (stderr); +} + +//**************************************************************************** +// unix + +#ifndef WIN32 + +extern "C" void dError (int num, const char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + if (error_function) error_function (num,msg,ap); + else printMessage (num,"ODE Error",msg,ap); + va_end (ap); + exit (1); +} + + +extern "C" void dDebug (int num, const char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + if (debug_function) debug_function (num,msg,ap); + else printMessage (num,"ODE INTERNAL ERROR",msg,ap); + va_end (ap); + // *((char *)0) = 0; ... commit SEGVicide + abort(); +} + + +extern "C" void dMessage (int num, const char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + if (message_function) message_function (num,msg,ap); + else printMessage (num,"ODE Message",msg,ap); + va_end (ap); +} + +#endif + +//**************************************************************************** +// windows + +#ifdef WIN32 + +// isn't cygwin annoying! +#ifdef CYGWIN +#define _snprintf snprintf +#define _vsnprintf vsnprintf +#endif + + +#include "windows.h" + + +extern "C" void dError (int num, const char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + if (error_function) error_function (num,msg,ap); + else { + char s[1000],title[100]; + _snprintf (title,sizeof(title),"ODE Error %d",num); + _vsnprintf (s,sizeof(s),msg,ap); + s[sizeof(s)-1] = 0; + MessageBox(0,s,title,MB_OK | MB_ICONWARNING); + } + va_end (ap); + exit (1); +} + + +extern "C" void dDebug (int num, const char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + if (debug_function) debug_function (num,msg,ap); + else { + char s[1000],title[100]; + _snprintf (title,sizeof(title),"ODE INTERNAL ERROR %d",num); + _vsnprintf (s,sizeof(s),msg,ap); + s[sizeof(s)-1] = 0; + MessageBox(0,s,title,MB_OK | MB_ICONSTOP); + } + va_end (ap); + abort(); +} + + +extern "C" void dMessage (int num, const char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + if (message_function) message_function (num,msg,ap); + else printMessage (num,"ODE Message",msg,ap); + va_end (ap); +} + + +#endif diff --git a/libs/ode-0.16.1/ode/src/error.h b/libs/ode-0.16.1/ode/src/error.h new file mode 100644 index 0000000..4f561f8 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/error.h @@ -0,0 +1,101 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* Library private error handling functions and macros */ + +#ifndef _ODE__PRIVATE_ERROR_H_ +#define _ODE__PRIVATE_ERROR_H_ + +#include <ode/error.h> +#include <ode/common.h> + + + +/* debugging: + * IASSERT is an internal assertion, i.e. a consistency check. if it fails + * we want to know where. + * UASSERT is a user assertion, i.e. if it fails a nice error message + * should be printed for the user. + * AASSERT is an arguments assertion, i.e. if it fails "bad argument(s)" + * is printed. + * DEBUGMSG just prints out a message + */ + +# if defined(__STDC__) && __STDC_VERSION__ >= 199901L +# define __FUNCTION__ __func__ +# endif +#ifndef dNODEBUG +# ifdef __GNUC__ +# define dIASSERT(a) { if (!(a)) { dDebug (d_ERR_IASSERT, \ + "assertion \"" #a "\" failed in %s() [%s:%u]",__FUNCTION__,__FILE__,__LINE__); } } +# define dUASSERT(a,msg) { if (!(a)) { dDebug (d_ERR_UASSERT, \ + msg " in %s()", __FUNCTION__); } } +# define dDEBUGMSG(msg) { dMessage (d_ERR_UASSERT, \ + msg " in %s() [%s:%u]", __FUNCTION__,__FILE__,__LINE__); } +# else // not __GNUC__ +# define dIASSERT(a) { if (!(a)) { dDebug (d_ERR_IASSERT, \ + "assertion \"" #a "\" failed in %s:%u",__FILE__,__LINE__); } } +# define dUASSERT(a,msg) { if (!(a)) { dDebug (d_ERR_UASSERT, \ + msg " (%s:%u)", __FILE__,__LINE__); } } +# define dDEBUGMSG(msg) { dMessage (d_ERR_UASSERT, \ + msg " (%s:%u)", __FILE__,__LINE__); } +# endif +# define dIVERIFY(a) dIASSERT(a) +# define dUVERIFY(a, msg) dUASSERT(a, msg) +#else +# define dIASSERT(a) ((void)0) +# define dUASSERT(a,msg) ((void)0) +# define dDEBUGMSG(msg) ((void)0) +# define dIVERIFY(a) ((void)(a)) +# define dUVERIFY(a, msg) ((void)(a)) +#endif + +#ifdef __GNUC__ +#define dUNUSED(Name) Name __attribute__((unused)) +#else // not __GNUC__ +#define dUNUSED(Name) Name +#endif + +#if __cplusplus >= 201103L +#define dSASSERT(e) static_assert(e, #e) +#define dSMSGASSERT(e, message) static_assert(e, message) +#else +#define d_SASSERT_INNER_TOKENPASTE(x, y) x ## y +#define d_SASSERT_TOKENPASTE(x, y) d_SASSERT_INNER_TOKENPASTE(x, y) +#define dSASSERT(e) typedef char dUNUSED(d_SASSERT_TOKENPASTE(d_StaticAssertionFailed_, __LINE__)[(e)?1:-1]) +#define dSMSGASSERT(e, message) dSASSERT(e) +#endif + +# ifdef __GNUC__ +# define dICHECK(a) { if (!(a)) { dDebug (d_ERR_IASSERT, \ + "assertion \"" #a "\" failed in %s() [%s:%u]",__FUNCTION__,__FILE__,__LINE__); *(int *)0 = 0; } } +# else // not __GNUC__ +# define dICHECK(a) { if (!(a)) { dDebug (d_ERR_IASSERT, \ + "assertion \"" #a "\" failed in %s:%u",__FILE__,__LINE__); *(int *)0 = 0; } } +# endif + +// Argument assert is a special case of user assert +#define dAASSERT(a) dUASSERT(a, "Bad argument(s)") +#define dAVERIFY(a) dUVERIFY(a, "Bad argument(s)") + + +#endif diff --git a/libs/ode-0.16.1/ode/src/export-dif.cpp b/libs/ode-0.16.1/ode/src/export-dif.cpp new file mode 100644 index 0000000..450021a --- /dev/null +++ b/libs/ode-0.16.1/ode/src/export-dif.cpp @@ -0,0 +1,620 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * Export a DIF (Dynamics Interchange Format) file. + */ + + +// @@@ TODO: +// * export all spaces, and geoms in spaces, not just ones attached to bodies +// (separate export function?) +// * say the space each geom is in, so reader can construct space heirarchy +// * limot --> separate out into limits and motors? +// * make sure ODE-specific parameters divided out + + +#include <ode/ode.h> +#include "config.h" +#include "objects.h" +#include "joints/joints.h" +#include "collision_kernel.h" + +//*************************************************************************** +// utility + +struct PrintingContext { + FILE *file; // file to write to + int precision; // digits of precision to print + int indent; // number of levels of indent + + void printIndent(); + void printReal (dReal x); + void print (const char *name, int x); + void print (const char *name, unsigned x); + void print (const char *name, dReal x); + void print (const char *name, const dReal *x, int n=3); + void print (const char *name, const char *x=0); + void printNonzero (const char *name, dReal x); + void printNonzero (const char *name, const dReal x[3]); +}; + + +void PrintingContext::printIndent() +{ + for (int i=0; i<indent; i++) fputc ('\t',file); +} + + +void PrintingContext::print (const char *name, int x) +{ + printIndent(); + fprintf (file,"%s = %d,\n",name,x); +} + +void PrintingContext::print (const char *name, unsigned x) +{ + printIndent(); + fprintf (file,"%s = %u,\n",name,x); +} + +void PrintingContext::printReal (dReal x) +{ + if (x==dInfinity) { + fprintf (file,"inf"); + } + else if (x==-dInfinity) { + fprintf (file,"-inf"); + } + else { + fprintf (file,"%.*g",precision,x); + } +} + + +void PrintingContext::print (const char *name, dReal x) +{ + printIndent(); + fprintf (file,"%s = ",name); + printReal (x); + fprintf (file,",\n"); +} + + +void PrintingContext::print (const char *name, const dReal *x, int n) +{ + printIndent(); + fprintf (file,"%s = {",name); + for (int i=0; i<n; i++) { + printReal (x[i]); + if (i < n-1) fputc (',',file); + } + fprintf (file,"},\n"); +} + + +void PrintingContext::print (const char *name, const char *x) +{ + printIndent(); + if (x) { + fprintf (file,"%s = \"%s\",\n",name,x); + } + else { + fprintf (file,"%s\n",name); + } +} + + +void PrintingContext::printNonzero (const char *name, dReal x) +{ + if (x != 0) print (name,x); +} + + +void PrintingContext::printNonzero (const char *name, const dReal x[3]) +{ + if (x[0] != 0 && x[1] != 0 && x[2] != 0) print (name,x); +} + +//*************************************************************************** +// joints + + +static void printLimot (PrintingContext &c, dxJointLimitMotor &limot, int num) +{ + if (num >= 0) { + c.printIndent(); + fprintf (c.file,"limit%d = {\n",num); + } + else { + c.print ("limit = {"); + } + c.indent++; + c.print ("low_stop",limot.lostop); + c.print ("high_stop",limot.histop); + c.printNonzero ("bounce",limot.bounce); + c.print ("ODE = {"); + c.indent++; + c.printNonzero ("stop_erp",limot.stop_erp); + c.printNonzero ("stop_cfm",limot.stop_cfm); + c.indent--; + c.print ("},"); + c.indent--; + c.print ("},"); + + if (num >= 0) { + c.printIndent(); + fprintf (c.file,"motor%d = {\n",num); + } + else { + c.print ("motor = {"); + } + c.indent++; + c.printNonzero ("vel",limot.vel); + c.printNonzero ("fmax",limot.fmax); + c.print ("ODE = {"); + c.indent++; + c.printNonzero ("fudge_factor",limot.fudge_factor); + c.printNonzero ("normal_cfm",limot.normal_cfm); + c.indent--; + c.print ("},"); + c.indent--; + c.print ("},"); +} + + +static const char *getJointName (dxJoint *j) +{ + switch (j->type()) { + case dJointTypeBall: return "ball"; + case dJointTypeHinge: return "hinge"; + case dJointTypeSlider: return "slider"; + case dJointTypeContact: return "contact"; + case dJointTypeUniversal: return "universal"; + case dJointTypeHinge2: return "ODE_hinge2"; + case dJointTypeFixed: return "fixed"; + case dJointTypeNull: return "null"; + case dJointTypeAMotor: return "ODE_angular_motor"; + case dJointTypeLMotor: return "ODE_linear_motor"; + case dJointTypePR: return "PR"; + case dJointTypePU: return "PU"; + case dJointTypePiston: return "piston"; + default: return "unknown"; + } +} + + +static void printBall (PrintingContext &c, dxJoint *j) +{ + dxJointBall *b = (dxJointBall*) j; + c.print ("anchor1",b->anchor1); + c.print ("anchor2",b->anchor2); +} + + +static void printHinge (PrintingContext &c, dxJoint *j) +{ + dxJointHinge *h = (dxJointHinge*) j; + c.print ("anchor1",h->anchor1); + c.print ("anchor2",h->anchor2); + c.print ("axis1",h->axis1); + c.print ("axis2",h->axis2); + c.print ("qrel",h->qrel,4); + printLimot (c,h->limot,-1); +} + + +static void printSlider (PrintingContext &c, dxJoint *j) +{ + dxJointSlider *s = (dxJointSlider*) j; + c.print ("axis1",s->axis1); + c.print ("qrel",s->qrel,4); + c.print ("offset",s->offset); + printLimot (c,s->limot,-1); +} + + +static void printContact (PrintingContext &c, dxJoint *j) +{ + dxJointContact *ct = (dxJointContact*) j; + int mode = ct->contact.surface.mode; + c.print ("pos",ct->contact.geom.pos); + c.print ("normal",ct->contact.geom.normal); + c.print ("depth",ct->contact.geom.depth); + //@@@ may want to write the geoms g1 and g2 that are involved, for debugging. + // to do this we must have written out all geoms in all spaces, not just + // geoms that are attached to bodies. + c.print ("mu",ct->contact.surface.mu); + if (mode & dContactMu2) c.print ("mu2",ct->contact.surface.mu2); + if (mode & dContactBounce) c.print ("bounce",ct->contact.surface.bounce); + if (mode & dContactBounce) c.print ("bounce_vel",ct->contact.surface.bounce_vel); + if (mode & dContactSoftERP) c.print ("soft_ERP",ct->contact.surface.soft_erp); + if (mode & dContactSoftCFM) c.print ("soft_CFM",ct->contact.surface.soft_cfm); + if (mode & dContactMotion1) c.print ("motion1",ct->contact.surface.motion1); + if (mode & dContactMotion2) c.print ("motion2",ct->contact.surface.motion2); + if (mode & dContactSlip1) c.print ("slip1",ct->contact.surface.slip1); + if (mode & dContactSlip2) c.print ("slip2",ct->contact.surface.slip2); + int fa = 0; // friction approximation code + if (mode & dContactApprox1_1) fa |= 1; + if (mode & dContactApprox1_2) fa |= 2; + if (fa) c.print ("friction_approximation",fa); + if (mode & dContactFDir1) c.print ("fdir1",ct->contact.fdir1); +} + + +static void printUniversal (PrintingContext &c, dxJoint *j) +{ + dxJointUniversal *u = (dxJointUniversal*) j; + c.print ("anchor1",u->anchor1); + c.print ("anchor2",u->anchor2); + c.print ("axis1",u->axis1); + c.print ("axis2",u->axis2); + c.print ("qrel1",u->qrel1,4); + c.print ("qrel2",u->qrel2,4); + printLimot (c,u->limot1,1); + printLimot (c,u->limot2,2); +} + + +static void printHinge2 (PrintingContext &c, dxJoint *j) +{ + dxJointHinge2 *h = (dxJointHinge2*) j; + c.print ("anchor1",h->anchor1); + c.print ("anchor2",h->anchor2); + c.print ("axis1",h->axis1); + c.print ("axis2",h->axis2); + c.print ("v1",h->v1); //@@@ much better to write out 'qrel' here, if it's available + c.print ("v2",h->v2); + c.print ("susp_erp",h->susp_erp); + c.print ("susp_cfm",h->susp_cfm); + printLimot (c,h->limot1,1); + printLimot (c,h->limot2,2); +} + +static void printPR (PrintingContext &c, dxJoint *j) +{ + dxJointPR *pr = (dxJointPR*) j; + c.print ("anchor2",pr->anchor2); + c.print ("axisR1",pr->axisR1); + c.print ("axisR2",pr->axisR2); + c.print ("axisP1",pr->axisP1); + c.print ("qrel",pr->qrel,4); + c.print ("offset",pr->offset); + printLimot (c,pr->limotP,1); + printLimot (c,pr->limotR,2); +} + +static void printPU (PrintingContext &c, dxJoint *j) +{ + dxJointPU *pu = (dxJointPU*) j; + c.print ("anchor1",pu->anchor1); + c.print ("anchor2",pu->anchor2); + c.print ("axis1",pu->axis1); + c.print ("axis2",pu->axis2); + c.print ("axisP",pu->axisP1); + c.print ("qrel1",pu->qrel1,4); + c.print ("qrel2",pu->qrel2,4); + printLimot (c,pu->limot1,1); + printLimot (c,pu->limot2,2); + printLimot (c,pu->limotP,3); +} + +static void printPiston (PrintingContext &c, dxJoint *j) +{ + dxJointPiston *rap = (dxJointPiston*) j; + c.print ("anchor1",rap->anchor1); + c.print ("anchor2",rap->anchor2); + c.print ("axis1",rap->axis1); + c.print ("axis2",rap->axis2); + c.print ("qrel",rap->qrel,4); + printLimot (c,rap->limotP,1); + printLimot (c, rap->limotR, 2); +} + +static void printFixed (PrintingContext &c, dxJoint *j) +{ + dxJointFixed *f = (dxJointFixed*) j; + c.print ("qrel",f->qrel); + c.print ("offset",f->offset); +} + +static void printLMotor (PrintingContext &c, dxJoint *j) +{ + dxJointLMotor *a = (dxJointLMotor*) j; + c.print("num", a->num); + c.printIndent(); + fprintf (c.file,"rel = {%d,%d,%d},\n",a->rel[0],a->rel[1],a->rel[2]); + c.print ("axis1",a->axis[0]); + c.print ("axis2",a->axis[1]); + c.print ("axis3",a->axis[2]); + for (int i=0; i<3; i++) printLimot (c,a->limot[i],i+1); +} + +struct dxAMotorJointPrinter +{ + static void print(PrintingContext &c, dxJointAMotor *a) + { + c.print ("num",a->m_num); + c.print ("mode",a->m_mode); + c.printIndent(); + fprintf (c.file,"rel = {%d,%d,%d},\n",a->m_rel[0],a->m_rel[1],a->m_rel[2]); + c.print ("axis1",a->m_axis[0]); + c.print ("axis2",a->m_axis[1]); + c.print ("axis3",a->m_axis[2]); + for (int i=0; i<3; i++) printLimot (c,a->m_limot[i],i+1); + c.print ("angle1",a->m_angle[0]); + c.print ("angle2",a->m_angle[1]); + c.print ("angle3",a->m_angle[2]); + } +}; + +static void printAMotor (PrintingContext &c, dxJoint *j) +{ + dxJointAMotor *a = (dxJointAMotor*) j; + dxAMotorJointPrinter::print(c, a); +} + +//*************************************************************************** +// geometry + +static void printGeom (PrintingContext &c, dxGeom *g); + +static void printSphere (PrintingContext &c, dxGeom *g) +{ + c.print ("type","sphere"); + c.print ("radius",dGeomSphereGetRadius (g)); +} + + +static void printBox (PrintingContext &c, dxGeom *g) +{ + dVector3 sides; + dGeomBoxGetLengths (g,sides); + c.print ("type","box"); + c.print ("sides",sides); +} + + +static void printCapsule (PrintingContext &c, dxGeom *g) +{ + dReal radius,length; + dGeomCapsuleGetParams (g,&radius,&length); + c.print ("type","capsule"); + c.print ("radius",radius); + c.print ("length",length); +} + + +static void printCylinder (PrintingContext &c, dxGeom *g) +{ + dReal radius,length; + dGeomCylinderGetParams (g,&radius,&length); + c.print ("type","cylinder"); + c.print ("radius",radius); + c.print ("length",length); +} + + +static void printPlane (PrintingContext &c, dxGeom *g) +{ + dVector4 e; + dGeomPlaneGetParams (g,e); + c.print ("type","plane"); + c.print ("normal",e); + c.print ("d",e[3]); +} + + +static void printRay (PrintingContext &c, dxGeom *g) +{ + dReal length = dGeomRayGetLength (g); + c.print ("type","ray"); + c.print ("length",length); +} + + +static void printConvex (PrintingContext &c, dxGeom * /*g*/) +{ + c.print ("type","convex"); + ///@todo Print information about convex hull +} + + + +static void printTriMesh (PrintingContext &c, dxGeom * /*g*/) +{ + c.print ("type","trimesh"); + //@@@ i don't think that the trimesh accessor functions are really + // sufficient to read out all the triangle data, and anyway we + // should have a method of not duplicating trimesh data that is + // shared. +} + + +static void printHeightfieldClass (PrintingContext &c, dxGeom * /*g*/) +{ + c.print ("type","heightfield"); + ///@todo Print information about heightfield +} + + +static void printGeom (PrintingContext &c, dxGeom *g) +{ + unsigned long category = dGeomGetCategoryBits (g); + if (category != (unsigned long)(~0)) { + c.printIndent(); + fprintf (c.file,"category_bits = %lu\n",category); + } + unsigned long collide = dGeomGetCollideBits (g); + if (collide != (unsigned long)(~0)) { + c.printIndent(); + fprintf (c.file,"collide_bits = %lu\n",collide); + } + if (!dGeomIsEnabled (g)) { + c.print ("disabled",1); + } + switch (g->type) { + case dSphereClass: printSphere (c,g); break; + case dBoxClass: printBox (c,g); break; + case dCapsuleClass: printCapsule (c,g); break; + case dCylinderClass: printCylinder (c,g); break; + case dPlaneClass: printPlane (c,g); break; + case dRayClass: printRay (c,g); break; + case dConvexClass: printConvex (c,g); break; + case dTriMeshClass: printTriMesh (c,g); break; + case dHeightfieldClass: printHeightfieldClass (c,g); break; + } +} + +//*************************************************************************** +// world + +void dWorldExportDIF (dWorldID w, FILE *file, const char *prefix) +{ + PrintingContext c; + c.file = file; +#if defined(dSINGLE) + c.precision = 7; +#else + c.precision = 15; +#endif + c.indent = 1; + + fprintf (file,"-- Dynamics Interchange Format v0.1\n\n%sworld = dynamics.world {\n",prefix); + c.print ("gravity",w->gravity); + c.print ("ODE = {"); + c.indent++; + c.print ("ERP",w->global_erp); + c.print ("CFM",w->global_cfm); + c.print ("auto_disable = {"); + c.indent++; + c.print ("linear_threshold",w->adis.linear_average_threshold); + c.print ("angular_threshold",w->adis.angular_average_threshold); + c.print ("average_samples",(int)w->adis.average_samples); + c.print ("idle_time",w->adis.idle_time); + c.print ("idle_steps",w->adis.idle_steps); + fprintf (file,"\t\t},\n\t},\n}\n"); + c.indent -= 3; + + // bodies + int num = 0; + fprintf (file,"%sbody = {}\n",prefix); + for (dxBody *b=w->firstbody; b; b=(dxBody*)b->next) { + b->tag = num; + fprintf (file,"%sbody[%d] = dynamics.body {\n\tworld = %sworld,\n",prefix,num,prefix); + c.indent++; + c.print ("pos",b->posr.pos); + c.print ("q",b->q,4); + c.print ("lvel",b->lvel); + c.print ("avel",b->avel); + c.print ("mass",b->mass.mass); + fprintf (file,"\tI = {{"); + for (int i=0; i<3; i++) { + for (int j=0; j<3; j++) { + c.printReal (b->mass.I[i*4+j]); + if (j < 2) fputc (',',file); + } + if (i < 2) fprintf (file,"},{"); + } + fprintf (file,"}},\n"); + c.printNonzero ("com",b->mass.c); + c.print ("ODE = {"); + c.indent++; + if (b->flags & dxBodyFlagFiniteRotation) c.print ("finite_rotation",1); + if (b->flags & dxBodyDisabled) c.print ("disabled",1); + if (b->flags & dxBodyNoGravity) c.print ("no_gravity",1); + if (b->flags & dxBodyAutoDisable) { + c.print ("auto_disable = {"); + c.indent++; + c.print ("linear_threshold",b->adis.linear_average_threshold); + c.print ("angular_threshold",b->adis.angular_average_threshold); + c.print ("average_samples",(int)b->adis.average_samples); + c.print ("idle_time",b->adis.idle_time); + c.print ("idle_steps",b->adis.idle_steps); + c.print ("time_left",b->adis_timeleft); + c.print ("steps_left",b->adis_stepsleft); + c.indent--; + c.print ("},"); + } + c.printNonzero ("facc",b->facc); + c.printNonzero ("tacc",b->tacc); + if (b->flags & dxBodyFlagFiniteRotationAxis) { + c.print ("finite_rotation_axis",b->finite_rot_axis); + } + c.indent--; + c.print ("},"); + if (b->geom) { + c.print ("geometry = {"); + c.indent++; + for (dxGeom *g=b->geom; g; g=g->body_next) { + c.print ("{"); + c.indent++; + printGeom (c,g); + c.indent--; + c.print ("},"); + } + c.indent--; + c.print ("},"); + } + c.indent--; + c.print ("}"); + num++; + } + + // joints + num = 0; + fprintf (file,"%sjoint = {}\n",prefix); + for (dxJoint *j=w->firstjoint; j; j=(dxJoint*)j->next) { + c.indent++; + const char *name = getJointName (j); + fprintf (file, + "%sjoint[%d] = dynamics.%s_joint {\n" + "\tworld = %sworld,\n" + "\tbody = {" + ,prefix,num,name,prefix); + + if ( j->node[0].body ) + fprintf (file,"%sbody[%d]",prefix,j->node[0].body->tag); + if ( j->node[1].body ) + fprintf (file,",%sbody[%d]",prefix,j->node[1].body->tag); + fprintf (file,"}\n"); + + switch (j->type()) { + case dJointTypeBall: printBall (c,j); break; + case dJointTypeHinge: printHinge (c,j); break; + case dJointTypeSlider: printSlider (c,j); break; + case dJointTypeContact: printContact (c,j); break; + case dJointTypeUniversal: printUniversal (c,j); break; + case dJointTypeHinge2: printHinge2 (c,j); break; + case dJointTypeFixed: printFixed (c,j); break; + case dJointTypeAMotor: printAMotor (c,j); break; + case dJointTypeLMotor: printLMotor (c,j); break; + case dJointTypePR: printPR (c,j); break; + case dJointTypePU: printPU (c,j); break; + case dJointTypePiston: printPiston (c,j); break; + default: c.print("unknown joint"); + } + c.indent--; + c.print ("}"); + num++; + } +} diff --git a/libs/ode-0.16.1/ode/src/fastdot.cpp b/libs/ode-0.16.1/ode/src/fastdot.cpp new file mode 100644 index 0000000..5594bc5 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/fastdot.cpp @@ -0,0 +1,46 @@ +/*************************************************************************
+ * *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
+ * All rights reserved. Email: russ@q12.org Web: www.q12.org *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of EITHER: *
+ * (1) The GNU Lesser General Public License as published by the Free *
+ * Software Foundation; either version 2.1 of the License, or (at *
+ * your option) any later version. The text of the GNU Lesser *
+ * General Public License is included with this library in the *
+ * file LICENSE.TXT. *
+ * (2) The BSD-style license that is included with this library in *
+ * the file LICENSE-BSD.TXT. *
+ * *
+ * This library 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 files *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
+ * *
+ *************************************************************************/
+
+/* generated code, do not edit. */
+
+#include <ode/common.h>
+#include "config.h"
+#include "matrix.h"
+
+#include "fastdot_impl.h"
+
+
+/*extern */
+dReal dxDot (const dReal *a, const dReal *b, unsigned n)
+{
+ return calculateLargeVectorDot<1>(a, b, n);
+}
+
+
+#undef dDot
+
+/*extern */
+dReal dDot (const dReal *a, const dReal *b, int n)
+{
+ return dxDot (a, b, n);
+}
+
diff --git a/libs/ode-0.16.1/ode/src/fastdot_impl.h b/libs/ode-0.16.1/ode/src/fastdot_impl.h new file mode 100644 index 0000000..f32e717 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/fastdot_impl.h @@ -0,0 +1,51 @@ + + +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_FASTDOT_IMPL_H_ +#define _ODE_FASTDOT_IMPL_H_ + + +template<unsigned b_stride> +dReal calculateLargeVectorDot (const dReal *a, const dReal *b, unsigned n) +{ + dReal sum = 0; + const dReal *a_end = a + (n & (int)(~3)); + for (; a != a_end; b += 4 * b_stride, a += 4) { + dReal p0 = a[0], p1 = a[1], p2 = a[2], p3 = a[3]; + dReal q0 = b[0 * b_stride], q1 = b[1 * b_stride], q2 = b[2 * b_stride], q3 = b[3 * b_stride]; + dReal m0 = p0 * q0; + dReal m1 = p1 * q1; + dReal m2 = p2 * q2; + dReal m3 = p3 * q3; + sum += m0 + m1 + m2 + m3; + } + a_end += (n & 3); + for (; a != a_end; b += b_stride, ++a) { + sum += (*a) * (*b); + } + return sum; +} + + +#endif diff --git a/libs/ode-0.16.1/ode/src/fastldltfactor.cpp b/libs/ode-0.16.1/ode/src/fastldltfactor.cpp new file mode 100644 index 0000000..9c1b921 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/fastldltfactor.cpp @@ -0,0 +1,462 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * LDLT factorization related code of ThreadedEquationSolverLDLT + * Copyright (c) 2017-2019 Oleh Derevenko, odar@eleks.com (change all "a" to "e") + */ + + +#include <ode/common.h> +#include <ode/matrix.h> +#include <ode/matrix_coop.h> +#include "config.h" +#include "threaded_solver_ldlt.h" +#include "threading_base.h" +#include "resource_control.h" +#include "error.h" + +#include "fastldltfactor_impl.h" + + +/*static */ +void ThreadedEquationSolverLDLT::estimateCooperativeFactoringLDLTResourceRequirements( + dxResourceRequirementDescriptor *summaryRequirementsDescriptor, + unsigned allowedThreadCount, unsigned rowCount) +{ + dxThreadingBase *threading = summaryRequirementsDescriptor->getrelatedThreading(); + unsigned limitedThreadCount = restrictFactoringLDLTAllowedThreadCount(threading, allowedThreadCount, rowCount); + + if (limitedThreadCount > 1) + { + doEstimateCooperativeFactoringLDLTResourceRequirementsValidated(summaryRequirementsDescriptor, allowedThreadCount, rowCount); + } +} + +/*static */ +void ThreadedEquationSolverLDLT::cooperativelyFactorLDLT( + dxRequiredResourceContainer *resourceContainer, unsigned allowedThreadCount, + dReal *A, dReal *d, unsigned rowCount, unsigned rowSkip) +{ + dAASSERT(rowCount != 0); + + dxThreadingBase *threading = resourceContainer->getThreadingInstance(); + unsigned limitedThreadCount = restrictFactoringLDLTAllowedThreadCount(threading, allowedThreadCount, rowCount); + + if (limitedThreadCount <= 1) + { + factorMatrixAsLDLT<FLDLT_D_STRIDE>(A, d, rowCount, rowSkip); + } + else + { + doCooperativelyFactorLDLTValidated(resourceContainer, limitedThreadCount, A, d, rowCount, rowSkip); + } +} + + +/*static */ +unsigned ThreadedEquationSolverLDLT::restrictFactoringLDLTAllowedThreadCount( + dxThreadingBase *threading, unsigned allowedThreadCount, unsigned rowCount) +{ + unsigned limitedThreadCount = 1; + +#if dCOOPERATIVE_ENABLED + const unsigned int solvingBlockStep = FSL1S_BLOCK_SIZE; // Required by the implementation + unsigned solvingMaximalBlockCount = deriveSolvingL1StripeBlockCount(rowCount, solvingBlockStep); + dIASSERT(deriveSolvingL1StripeThreadCount(FLDLT_COOPERATIVE_BLOCK_COUNT_MINIMUM - 1, 2) > 1); + + if (solvingMaximalBlockCount >= FLDLT_COOPERATIVE_BLOCK_COUNT_MINIMUM) + { + limitedThreadCount = threading->calculateThreadingLimitedThreadCount(allowedThreadCount, false); + } +#endif // #if dCOOPERATIVE_ENABLED + + return limitedThreadCount; +} + +/*static */ +void ThreadedEquationSolverLDLT::doEstimateCooperativeFactoringLDLTResourceRequirementsValidated( + dxResourceRequirementDescriptor *summaryRequirementsDescriptor, + unsigned allowedThreadCount, unsigned rowCount) +{ + const unsigned int solvingBlockStep = FSL1S_BLOCK_SIZE; // Required by the implementation + unsigned solvingTotalBlockCount = deriveSolvingL1StripeBlockCount(rowCount, solvingBlockStep); + dIASSERT(solvingTotalBlockCount >= 1); + + unsigned solvingLastBlockIndex = solvingTotalBlockCount - 1; + + const unsigned factorizingBlockARows = FFL1S_REGULAR_A_ROWS; + unsigned factorizingMaximalBlockCount = deriveScalingAndFactorizingL1StripeBlockCountFromSolvingBlockIndex(solvingLastBlockIndex, solvingBlockStep, factorizingBlockARows); + + unsigned blockSolvingMaximumThreads = deriveSolvingL1StripeThreadCount(solvingLastBlockIndex, allowedThreadCount); + unsigned blockFactorizingMaximumThreads = deriveScalingAndFactorizingL1StripeThreadCount(factorizingMaximalBlockCount, allowedThreadCount); + unsigned simultaneousCallCount = 1 // Final synchronization point + + 2 // intermediate synchronization points + + dMACRO_MAX(blockSolvingMaximumThreads, blockFactorizingMaximumThreads); + + FactorizationSolvingL1StripeMemoryEstimates solvingMemoryEstimates; + FactorizationScalingAndFactorizingL1StripeMemoryEstimates scalingAndFactorizingEstimates; + sizeint solvingMemoryRequired = estimateCooperativelySolvingL1Stripe_XMemoryRequirement(solvingTotalBlockCount, solvingMemoryEstimates); + sizeint factorizingMemoryRequired = estimateCooperativelyScalingAndFactorizingL1Stripe_XMemoryRequirement(blockFactorizingMaximumThreads, scalingAndFactorizingEstimates); + sizeint totalSizeRequired = solvingMemoryRequired + factorizingMemoryRequired; + const unsigned memoryAlignmentRequired = ALLOCATION_DEFAULT_ALIGNMENT; + + unsigned featureRequirement = dxResourceRequirementDescriptor::STOCK_CALLWAIT_REQUIRED; + summaryRequirementsDescriptor->mergeAnotherDescriptorIn(totalSizeRequired, memoryAlignmentRequired, simultaneousCallCount, featureRequirement); +} + +/*static */ +void ThreadedEquationSolverLDLT::doCooperativelyFactorLDLTValidated( + dxRequiredResourceContainer *resourceContainer, unsigned allowedThreadCount, + dReal *A, dReal *d, unsigned rowCount, unsigned rowSkip) +{ + dIASSERT(allowedThreadCount > 1); + + const unsigned int solvingBlockStep = FSL1S_BLOCK_SIZE; // Required by the implementation + unsigned solvingTotalBlockCount = deriveSolvingL1StripeBlockCount(rowCount, solvingBlockStep); + dIASSERT(solvingTotalBlockCount >= 1); + + unsigned solvingLastBlockIndex = solvingTotalBlockCount - 1; + + const unsigned factorizingBlockARows = FFL1S_REGULAR_A_ROWS; + unsigned factorizingMaximalBlockCount = deriveScalingAndFactorizingL1StripeBlockCountFromSolvingBlockIndex(solvingLastBlockIndex, solvingBlockStep, factorizingBlockARows); + + unsigned blockFactorizingMaximumThreads = deriveScalingAndFactorizingL1StripeThreadCount(factorizingMaximalBlockCount, allowedThreadCount); + + dCallWaitID completionWait = resourceContainer->getStockCallWait(); + dAASSERT(completionWait != NULL); + + FactorizationSolvingL1StripeMemoryEstimates solvingMemoryEstimates; + FactorizationScalingAndFactorizingL1StripeMemoryEstimates scalingAndFactorizingEstimates; + sizeint solvingMemoryRequired = estimateCooperativelySolvingL1Stripe_XMemoryRequirement(solvingTotalBlockCount, solvingMemoryEstimates); + sizeint factorizingMemoryRequired = estimateCooperativelyScalingAndFactorizingL1Stripe_XMemoryRequirement(blockFactorizingMaximumThreads, scalingAndFactorizingEstimates); + sizeint totalSizeRequired = solvingMemoryRequired + factorizingMemoryRequired; + dIASSERT(totalSizeRequired <= resourceContainer->getMemoryBufferSize()); + + void *bufferAllocated = resourceContainer->getMemoryBufferPointer(); + dIASSERT(bufferAllocated != NULL); + dIASSERT(dALIGN_PTR(bufferAllocated, ALLOCATION_DEFAULT_ALIGNMENT) == bufferAllocated); + + atomicord32 solvingBlockCompletionProgress; + cellindexint *solvingBlockProgressDescriptors; + FactorizationSolveL1StripeCellContext *solvingCellContexts; + + FactorizationFactorizeL1StripeContext *factorizingFactorizationContext; + + void *bufferCurrentLocation = bufferAllocated; + bufferCurrentLocation = markCooperativelySolvingL1Stripe_XMemoryStructuresOut(bufferCurrentLocation, solvingMemoryEstimates, solvingBlockProgressDescriptors, solvingCellContexts); + bufferCurrentLocation = markCooperativelyScalingAndFactorizingL1Stripe_XMemoryStructuresOut(bufferCurrentLocation, scalingAndFactorizingEstimates, factorizingFactorizationContext); + dIVERIFY(bufferCurrentLocation <= (uint8 *)bufferAllocated + totalSizeRequired); + + dCallReleaseeID calculationFinishReleasee; + dxThreadingBase *threading = resourceContainer->getThreadingInstance(); + threading->PostThreadedCall(NULL, &calculationFinishReleasee, 1, NULL, completionWait, &factotLDLT_completion_callback, NULL, 0, "FactorLDLT Completion"); + + FactorLDLTWorkerContext workerContext(threading, allowedThreadCount, A, d, solvingTotalBlockCount, rowCount, rowSkip, + solvingBlockCompletionProgress, solvingBlockProgressDescriptors, solvingCellContexts, + factorizingFactorizationContext, + calculationFinishReleasee); // The variable must exist in the outer scope + + dIASSERT(solvingTotalBlockCount >= FLDLT_COOPERATIVE_BLOCK_COUNT_MINIMUM); + dSASSERT(FLDLT_COOPERATIVE_BLOCK_COUNT_MINIMUM > 2); + + scaleAndFactorizeL1FirstRowStripe_2<FLDLT_D_STRIDE>(workerContext.m_ARow, workerContext.m_d, workerContext.m_rowSkip); + workerContext.incrementForNextBlock(); + + const unsigned blockIndex = 1; + dIASSERT(blockIndex == workerContext.m_solvingBlockIndex); + + initializeCooperativelySolvingL1Stripe_XMemoryStructures(blockIndex, solvingBlockCompletionProgress, solvingBlockProgressDescriptors, solvingCellContexts); + unsigned secondBlockSolvingThreadCount = deriveSolvingL1StripeThreadCount(blockIndex, allowedThreadCount); + + dCallReleaseeID secondBlockSolvingSyncReleasee; + threading->PostThreadedCall(NULL, &secondBlockSolvingSyncReleasee, secondBlockSolvingThreadCount, NULL, NULL, &factotLDLT_solvingCompleteSync_callback, &workerContext, 0, "FactorLDLT Solving Complete Sync"); + + if (secondBlockSolvingThreadCount > 1) + { + threading->PostThreadedCallsGroup(NULL, secondBlockSolvingThreadCount - 1, secondBlockSolvingSyncReleasee, &factotLDLT_solvingComplete_callback, &workerContext, "FactorLDLT Solving Complete"); + } + + factotLDLT_solvingComplete(workerContext, secondBlockSolvingThreadCount - 1); + threading->AlterThreadedCallDependenciesCount(secondBlockSolvingSyncReleasee, -1); + + threading->WaitThreadedCallExclusively(NULL, completionWait, NULL, "FactorLDLT End Wait"); +} + + +/*static */ +int ThreadedEquationSolverLDLT::factotLDLT_solvingComplete_callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID dUNUSED(callThisReleasee)) +{ + FactorLDLTWorkerContext *ptrContext = (FactorLDLTWorkerContext *)callContext; + + factotLDLT_solvingComplete(*ptrContext, dCAST_TO_SMALLER(unsigned, callInstanceIndex)); + + return 1; +} + +/*static */ +void ThreadedEquationSolverLDLT::factotLDLT_solvingComplete(FactorLDLTWorkerContext &ref_context, unsigned ownThreadIndex) +{ + participateSolvingL1Stripe_X<FSL1S_BLOCK_SIZE, FSL1S_REGULAR_B_ROWS>(ref_context.m_A, ref_context.m_ARow, ref_context.m_solvingBlockIndex, ref_context.m_rowSkip, + ref_context.m_refSolvingBlockCompletionProgress, ref_context.m_solvingBlockProgressDescriptors, ref_context.m_solvingCellContexts, ownThreadIndex); +} + + +/*static */ +int ThreadedEquationSolverLDLT::factotLDLT_solvingCompleteSync_callback(void *callContext, dcallindex_t dUNUSED(callInstanceIndex), dCallReleaseeID dUNUSED(callThisReleasee)) +{ + FactorLDLTWorkerContext *ptrContext = (FactorLDLTWorkerContext *)callContext; + + factotLDLT_solvingCompleteSync(*ptrContext); + + return 1; +} + +/*static */ +void ThreadedEquationSolverLDLT::factotLDLT_solvingCompleteSync(FactorLDLTWorkerContext &ref_workerContext) +{ + unsigned solvingBlockIndex = ref_workerContext.m_solvingBlockIndex; + FactorizationFactorizeL1StripeContext *factorizingFactorizationContext = ref_workerContext.m_factorizingFactorizationContext; + + const unsigned int solvingBlockStep = FSL1S_BLOCK_SIZE; + const unsigned factorizingBlockARows = FFL1S_REGULAR_A_ROWS; + unsigned factorizingBlockCount = deriveScalingAndFactorizingL1StripeBlockCountFromSolvingBlockIndex(solvingBlockIndex, solvingBlockStep, factorizingBlockARows); + unsigned blockFactorizingThreadCount = deriveScalingAndFactorizingL1StripeThreadCount(factorizingBlockCount, ref_workerContext.m_allowedThreadCount); + initializeCooperativelyScalingAndFactorizingL1Stripe_XMemoryStructures(factorizingFactorizationContext, blockFactorizingThreadCount); + + dCallReleaseeID blockFactorizingSyncReleasee; + + dxThreadingBase *threading = ref_workerContext.m_threading; + if (solvingBlockIndex != ref_workerContext.m_totalBlockCount - 1) + { + threading->PostThreadedCall(NULL, &blockFactorizingSyncReleasee, blockFactorizingThreadCount, NULL, NULL, &factotLDLT_scalingAndFactorizingCompleteSync_callback, &ref_workerContext, 0, "FactorLDLT S'n'F Sync"); + } + else + { + blockFactorizingSyncReleasee = ref_workerContext.m_calculationFinishReleasee; + + if (blockFactorizingThreadCount > 1) + { + threading->AlterThreadedCallDependenciesCount(blockFactorizingSyncReleasee, blockFactorizingThreadCount - 1); + } + } + + if (blockFactorizingThreadCount > 1) + { + threading->PostThreadedCallsGroup(NULL, blockFactorizingThreadCount - 1, blockFactorizingSyncReleasee, &factotLDLT_scalingAndFactorizingComplete_callback, &ref_workerContext, "FactorLDLT S'n'F Complete"); + } + + factotLDLT_scalingAndFactorizingComplete(ref_workerContext, blockFactorizingThreadCount - 1); + threading->AlterThreadedCallDependenciesCount(blockFactorizingSyncReleasee, -1); +} + + +/*static */ +int ThreadedEquationSolverLDLT::factotLDLT_scalingAndFactorizingComplete_callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID dUNUSED(callThisReleasee)) +{ + FactorLDLTWorkerContext *ptrContext = (FactorLDLTWorkerContext *)callContext; + + factotLDLT_scalingAndFactorizingComplete(*ptrContext, dCAST_TO_SMALLER(unsigned, callInstanceIndex)); + + return 1; +} + +/*static */ +void ThreadedEquationSolverLDLT::factotLDLT_scalingAndFactorizingComplete(FactorLDLTWorkerContext &ref_workerContext, unsigned ownThreadIndex) +{ + unsigned factorizationRow = ref_workerContext.m_solvingBlockIndex * FSL1S_BLOCK_SIZE; + participateScalingAndFactorizingL1Stripe_X<FFL1S_REGULAR_A_ROWS, FLDLT_D_STRIDE>(ref_workerContext.m_ARow, ref_workerContext.m_d, factorizationRow, + ref_workerContext.m_rowSkip, ref_workerContext.m_factorizingFactorizationContext, ownThreadIndex); +} + + +/*static */ +int ThreadedEquationSolverLDLT::factotLDLT_scalingAndFactorizingCompleteSync_callback(void *callContext, dcallindex_t dUNUSED(callInstanceIndex), dCallReleaseeID dUNUSED(callThisReleasee)) +{ + FactorLDLTWorkerContext *ptrContext = (FactorLDLTWorkerContext *)callContext; + + factotLDLT_scalingAndFactorizingCompleteSync(*ptrContext); + + return 1; +} + +/*static */ +void ThreadedEquationSolverLDLT::factotLDLT_scalingAndFactorizingCompleteSync(FactorLDLTWorkerContext &ref_workerContext) +{ + ref_workerContext.incrementForNextBlock(); + + unsigned blockIndex = ref_workerContext.m_solvingBlockIndex; + dIASSERT(blockIndex < ref_workerContext.m_totalBlockCount); + + atomicord32 &refSolvingBlockCompletionProgress = ref_workerContext.m_refSolvingBlockCompletionProgress; + cellindexint *solvingBlockProgressDescriptors = ref_workerContext.m_solvingBlockProgressDescriptors; + FactorizationSolveL1StripeCellContext *solvingCellContexts = ref_workerContext.m_solvingCellContexts; + + initializeCooperativelySolvingL1Stripe_XMemoryStructures(blockIndex, refSolvingBlockCompletionProgress, solvingBlockProgressDescriptors, solvingCellContexts); + unsigned blockSolvingThreadCount = deriveSolvingL1StripeThreadCount(blockIndex, ref_workerContext.m_allowedThreadCount); + + dCallReleaseeID blockSolvingSyncReleasee; + + dxThreadingBase *threading = ref_workerContext.m_threading; + if (blockIndex != ref_workerContext.m_totalBlockCount - 1 || ref_workerContext.m_rowCount % FSL1S_REGULAR_B_ROWS == 0) + { + threading->PostThreadedCall(NULL, &blockSolvingSyncReleasee, blockSolvingThreadCount, NULL, NULL, &factotLDLT_solvingCompleteSync_callback, &ref_workerContext, 0, "FactorLDLT Solving Complete Sync"); + + if (blockSolvingThreadCount > 1) + { + threading->PostThreadedCallsGroup(NULL, blockSolvingThreadCount - 1, blockSolvingSyncReleasee, &factotLDLT_solvingComplete_callback, &ref_workerContext, "FactorLDLT Solving Complete"); + } + + factotLDLT_solvingComplete(ref_workerContext, blockSolvingThreadCount - 1); + } + else + { + dSASSERT(FSL1S_REGULAR_B_ROWS == 2); + dSASSERT(FSL1S_FINAL_B_ROWS == 1); + + threading->PostThreadedCall(NULL, &blockSolvingSyncReleasee, blockSolvingThreadCount, NULL, NULL, &factotLDLT_solvingFinalSync_callback, &ref_workerContext, 0, "FactorLDLT Solving Final Sync"); + + if (blockSolvingThreadCount > 1) + { + threading->PostThreadedCallsGroup(NULL, blockSolvingThreadCount - 1, blockSolvingSyncReleasee, &factotLDLT_solvingFinal_callback, &ref_workerContext, "FactorLDLT Solving Final"); + } + + factotLDLT_solvingFinal(ref_workerContext, blockSolvingThreadCount - 1); + } + + threading->AlterThreadedCallDependenciesCount(blockSolvingSyncReleasee, -1); +} + + +/*static */ +int ThreadedEquationSolverLDLT::factotLDLT_solvingFinal_callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID dUNUSED(callThisReleasee)) +{ + FactorLDLTWorkerContext *ptrContext = (FactorLDLTWorkerContext *)callContext; + + factotLDLT_solvingFinal(*ptrContext, dCAST_TO_SMALLER(unsigned, callInstanceIndex)); + + return 1; +} + +/*static */ +void ThreadedEquationSolverLDLT::factotLDLT_solvingFinal(FactorLDLTWorkerContext &ref_context, unsigned ownThreadIndex) +{ + participateSolvingL1Stripe_X<FSL1S_BLOCK_SIZE, FSL1S_FINAL_B_ROWS>(ref_context.m_A, ref_context.m_ARow, ref_context.m_solvingBlockIndex, ref_context.m_rowSkip, + ref_context.m_refSolvingBlockCompletionProgress, ref_context.m_solvingBlockProgressDescriptors, ref_context.m_solvingCellContexts, ownThreadIndex); +} + + +/*static */ +int ThreadedEquationSolverLDLT::factotLDLT_solvingFinalSync_callback(void *callContext, dcallindex_t dUNUSED(callInstanceIndex), dCallReleaseeID dUNUSED(callThisReleasee)) +{ + FactorLDLTWorkerContext *ptrContext = (FactorLDLTWorkerContext *)callContext; + + factotLDLT_solvingFinalSync(*ptrContext); + + return 1; +} + +/*static */ +void ThreadedEquationSolverLDLT::factotLDLT_solvingFinalSync(FactorLDLTWorkerContext &ref_workerContext) +{ + unsigned solvingBlockIndex = ref_workerContext.m_solvingBlockIndex; + FactorizationFactorizeL1StripeContext *factorizingFactorizationContext = ref_workerContext.m_factorizingFactorizationContext; + + const unsigned int solvingBlockStep = FSL1S_BLOCK_SIZE; + const unsigned factorizingBlockARows = FFL1S_FINAL_A_ROWS; + unsigned factorizingBlockCount = deriveScalingAndFactorizingL1StripeBlockCountFromSolvingBlockIndex(solvingBlockIndex, solvingBlockStep, factorizingBlockARows); + unsigned blockFactorizingThreadCount = deriveScalingAndFactorizingL1StripeThreadCount(factorizingBlockCount, ref_workerContext.m_allowedThreadCount); + initializeCooperativelyScalingAndFactorizingL1Stripe_XMemoryStructures(factorizingFactorizationContext, blockFactorizingThreadCount); + + dCallReleaseeID blockFactorizingSyncReleasee = ref_workerContext.m_calculationFinishReleasee; + dIASSERT(solvingBlockIndex == ref_workerContext.m_totalBlockCount - 1); + + dxThreadingBase *threading = ref_workerContext.m_threading; + + if (blockFactorizingThreadCount > 1) + { + threading->AlterThreadedCallDependenciesCount(blockFactorizingSyncReleasee, blockFactorizingThreadCount - 1); + threading->PostThreadedCallsGroup(NULL, blockFactorizingThreadCount - 1, blockFactorizingSyncReleasee, &factotLDLT_scalingAndFactorizingFinal_callback, &ref_workerContext, "FactorLDLT S'n'F Final"); + } + + factotLDLT_scalingAndFactorizingFinal(ref_workerContext, blockFactorizingThreadCount - 1); + threading->AlterThreadedCallDependenciesCount(blockFactorizingSyncReleasee, -1); +} + + +/*static */ +int ThreadedEquationSolverLDLT::factotLDLT_scalingAndFactorizingFinal_callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID dUNUSED(callThisReleasee)) +{ + FactorLDLTWorkerContext *ptrContext = (FactorLDLTWorkerContext *)callContext; + + factotLDLT_scalingAndFactorizingFinal(*ptrContext, dCAST_TO_SMALLER(unsigned, callInstanceIndex)); + + return 1; +} + +/*static */ +void ThreadedEquationSolverLDLT::factotLDLT_scalingAndFactorizingFinal(FactorLDLTWorkerContext &ref_workerContext, unsigned ownThreadIndex) +{ + unsigned factorizationRow = ref_workerContext.m_solvingBlockIndex * FSL1S_BLOCK_SIZE; + participateScalingAndFactorizingL1Stripe_X<FFL1S_FINAL_A_ROWS, FLDLT_D_STRIDE>(ref_workerContext.m_ARow, ref_workerContext.m_d, factorizationRow, + ref_workerContext.m_rowSkip, ref_workerContext.m_factorizingFactorizationContext, ownThreadIndex); +} + + +/*static */ +int ThreadedEquationSolverLDLT::factotLDLT_completion_callback(void *dUNUSED(callContext), dcallindex_t dUNUSED(callInstanceIndex), dCallReleaseeID dUNUSED(callThisReleasee)) +{ + // Do nothing + return 1; +} + + +////////////////////////////////////////////////////////////////////////// +// Public interface functions + + +/*extern ODE_API */ +void dFactorLDLT(dReal *A, dReal *d, int n, int nskip1) +{ + factorMatrixAsLDLT<1>(A, d, n, nskip1); +} + + +/*extern ODE_API */ +void dEstimateCooperativelyFactorLDLTResourceRequirements(dResourceRequirementsID requirements, + unsigned maximalAllowedThreadCount, unsigned maximalRowCount) +{ + dAASSERT(requirements != NULL); + + dxResourceRequirementDescriptor *requirementsDescriptor = (dxResourceRequirementDescriptor *)requirements; + ThreadedEquationSolverLDLT::estimateCooperativeFactoringLDLTResourceRequirements(requirementsDescriptor, maximalAllowedThreadCount, maximalRowCount); +} + +/*extern ODE_API */ +void dCooperativelyFactorLDLT(dResourceContainerID resources, unsigned allowedThreadCount, + dReal *A, dReal *d, unsigned rowCount, unsigned rowSkip) +{ + dAASSERT(resources != NULL); + + dxRequiredResourceContainer *resourceContainer = (dxRequiredResourceContainer *)resources; + ThreadedEquationSolverLDLT::cooperativelyFactorLDLT(resourceContainer, allowedThreadCount, A, d, rowCount, rowSkip); +} diff --git a/libs/ode-0.16.1/ode/src/fastldltfactor_impl.h b/libs/ode-0.16.1/ode/src/fastldltfactor_impl.h new file mode 100644 index 0000000..8f633d3 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/fastldltfactor_impl.h @@ -0,0 +1,1530 @@ + + +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * Code style improvements and optimizations by Oleh Derevenko ????-2019 + * LDLT cooperative factorization code of ThreadedEquationSolverLDLT copyright (c) 2017-2019 Oleh Derevenko, odar@eleks.com (change all "a" to "e") + */ + +#ifndef _ODE_FASTLDLT_IMPL_H_ +#define _ODE_FASTLDLT_IMPL_H_ + + +#include "error.h" +#include "common.h" + + +static void solveL1Stripe_2 (const dReal *L, dReal *B, unsigned rowCount, unsigned rowSkip); +template<unsigned int d_stride> +void scaleAndFactorizeL1Stripe_2(dReal *ARow, dReal *d, unsigned rowIndex, unsigned rowSkip); +template<unsigned int d_stride> +inline void scaleAndFactorizeL1FirstRowStripe_2(dReal *ARow, dReal *d, unsigned rowSkip); + +static void solveStripeL1_1 (const dReal *L, dReal *B, unsigned rowCount, unsigned rowSkip); +template<unsigned int d_stride> +void scaleAndFactorizeL1Stripe_1(dReal *ARow, dReal *d, unsigned rowIndex); +template<unsigned int d_stride> +inline void scaleAndFactorizeL1FirstRowStripe_1(dReal *ARow, dReal *d); + + +template<unsigned int d_stride> +void factorMatrixAsLDLT(dReal *A, dReal *d, unsigned rowCount, unsigned rowSkip) +{ + if (rowCount < 1) return; + + dReal *ARow = A; + unsigned blockStartRow = 0; + + const unsigned blockStep = 2; + const unsigned lastRowIndex = rowCount >= blockStep ? rowCount - blockStep + 1 : 0; + + /* compute blocks of 2 rows */ + bool subsequentPass = false; + for (; blockStartRow < lastRowIndex; subsequentPass = true, ARow += blockStep * rowSkip, blockStartRow += blockStep) + { + if (subsequentPass) + { + /* solve L*(D*l)=a, l is scaled elements in 2 x i block at A(i,0) */ + solveL1Stripe_2(A, ARow, blockStartRow, rowSkip); + scaleAndFactorizeL1Stripe_2<d_stride>(ARow, d, blockStartRow, rowSkip); + } + else + { + scaleAndFactorizeL1FirstRowStripe_2<d_stride>(ARow, d, rowSkip); + } + dSASSERT(blockStep == 2); + /* done factorizing 2 x 2 block */ + } + + /* compute the (less than 2) rows at the bottom */ + if (!subsequentPass || blockStartRow == lastRowIndex) + { + dSASSERT(blockStep == 2); // for the blockStartRow == lastRowIndex comparison above + + if (subsequentPass) + { + solveStripeL1_1(A, ARow, blockStartRow, rowSkip); + scaleAndFactorizeL1Stripe_1<d_stride>(ARow, d, blockStartRow); + } + else + { + scaleAndFactorizeL1FirstRowStripe_1<d_stride>(ARow, d); + } + dSASSERT(blockStep == 2); + /* done factorizing 1 x 1 block */ + } +} + +/* solve L*X=B, with B containing 2 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 rowSkip. + * B is an n*2 matrix that contains the right hand sides. + * B is stored by columns and its leading dimension is also rowSkip. + * B is overwritten with X. + * this processes blocks of 2*2. + * if this is in the factorizer source file, n must be a multiple of 2. + */ +static +void solveL1Stripe_2(const dReal *L, dReal *B, unsigned rowCount, unsigned rowSkip) +{ + dIASSERT(rowCount != 0); + dIASSERT(rowCount % 2 == 0); + + /* compute all 2 x 2 blocks of X */ + unsigned blockStartRow = 0; + for (bool exitLoop = false, subsequentPass = false; !exitLoop; subsequentPass = true, exitLoop = (blockStartRow += 2) == rowCount) + { + const dReal *ptrLElement; + dReal *ptrBElement; + + /* declare variables - Z matrix */ + dReal Z11, Z12, Z21, Z22; + + /* compute all 2 x 2 block of X, from rows i..i+2-1 */ + if (subsequentPass) + { + ptrLElement = L + blockStartRow * rowSkip; + ptrBElement = B; + + /* set Z matrix to 0 */ + Z11 = 0; Z12 = 0; Z21 = 0; Z22 = 0; + + /* the inner loop that computes outer products and adds them to Z */ + // The iteration starts with even number and decreases it by 2. So, it must end in zero + for (unsigned columnCounter = blockStartRow; ;) + { + /* declare p and q vectors, etc */ + dReal p1, q1, p2, q2; + + /* compute outer product and add it to the Z matrix */ + p1 = ptrLElement[0]; + q1 = ptrBElement[0]; + Z11 += p1 * q1; + q2 = ptrBElement[rowSkip]; + Z12 += p1 * q2; + p2 = ptrLElement[rowSkip]; + Z21 += p2 * q1; + Z22 += p2 * q2; + + /* compute outer product and add it to the Z matrix */ + p1 = ptrLElement[1]; + q1 = ptrBElement[1]; + Z11 += p1 * q1; + q2 = ptrBElement[1 + rowSkip]; + Z12 += p1 * q2; + p2 = ptrLElement[1 + rowSkip]; + Z21 += p2 * q1; + Z22 += p2 * q2; + + if (columnCounter > 6) + { + columnCounter -= 6; + + /* advance pointers */ + ptrLElement += 6; + ptrBElement += 6; + + /* compute outer product and add it to the Z matrix */ + p1 = ptrLElement[-4]; + q1 = ptrBElement[-4]; + Z11 += p1 * q1; + q2 = ptrBElement[-4 + rowSkip]; + Z12 += p1 * q2; + p2 = ptrLElement[-4 + rowSkip]; + Z21 += p2 * q1; + Z22 += p2 * q2; + + /* compute outer product and add it to the Z matrix */ + p1 = ptrLElement[-3]; + q1 = ptrBElement[-3]; + Z11 += p1 * q1; + q2 = ptrBElement[-3 + rowSkip]; + Z12 += p1 * q2; + p2 = ptrLElement[-3 + rowSkip]; + Z21 += p2 * q1; + Z22 += p2 * q2; + + /* compute outer product and add it to the Z matrix */ + p1 = ptrLElement[-2]; + q1 = ptrBElement[-2]; + Z11 += p1 * q1; + q2 = ptrBElement[-2 + rowSkip]; + Z12 += p1 * q2; + p2 = ptrLElement[-2 + rowSkip]; + Z21 += p2 * q1; + Z22 += p2 * q2; + + /* compute outer product and add it to the Z matrix */ + p1 = ptrLElement[-1]; + q1 = ptrBElement[-1]; + Z11 += p1 * q1; + q2 = ptrBElement[-1 + rowSkip]; + Z12 += p1 * q2; + p2 = ptrLElement[-1 + rowSkip]; + Z21 += p2 * q1; + Z22 += p2 * q2; + } + else + { + /* advance pointers */ + ptrLElement += 2; + ptrBElement += 2; + + if ((columnCounter -= 2) == 0) + { + break; + } + } + /* end of inner loop */ + } + } + else + { + ptrLElement = L/* + blockStartRow * rowSkip*/; dIASSERT(blockStartRow == 0); + ptrBElement = B; + + /* set Z matrix to 0 */ + Z11 = 0; Z12 = 0; Z21 = 0; Z22 = 0; + } + + /* finish computing the X(i) block */ + + dReal Y11 = ptrBElement[0] - Z11; + dReal Y12 = ptrBElement[rowSkip] - Z12; + + dReal p2 = ptrLElement[rowSkip]; + + ptrBElement[0] = Y11; + ptrBElement[rowSkip] = Y12; + + dReal Y21 = ptrBElement[1] - Z21 - p2 * Y11; + dReal Y22 = ptrBElement[1 + rowSkip] - Z22 - p2 * Y12; + + ptrBElement[1] = Y21; + ptrBElement[1 + rowSkip] = Y22; + /* end of outer loop */ + } +} + +template<unsigned int d_stride> +void scaleAndFactorizeL1Stripe_2(dReal *ARow, dReal *d, unsigned factorizationRow, unsigned rowSkip) +{ + dIASSERT(factorizationRow != 0); + dIASSERT(factorizationRow % 2 == 0); + + dReal *ptrAElement = ARow; + dReal *ptrDElement = d; + + /* 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. */ + dReal Z11 = 0, Z21 = 0, Z22 = 0; + + for (unsigned columnCounter = factorizationRow; ; ) + { + dReal p1, q1, p2, q2, dd; + + p1 = ptrAElement[0]; + p2 = ptrAElement[rowSkip]; + dd = ptrDElement[0 * d_stride]; + q1 = p1 * dd; + q2 = p2 * dd; + ptrAElement[0] = q1; + ptrAElement[rowSkip] = q2; + Z11 += p1 * q1; + Z21 += p2 * q1; + Z22 += p2 * q2; + + p1 = ptrAElement[1]; + p2 = ptrAElement[1 + rowSkip]; + dd = ptrDElement[1 * d_stride]; + q1 = p1 * dd; + q2 = p2 * dd; + ptrAElement[1] = q1; + ptrAElement[1 + rowSkip] = q2; + Z11 += p1 * q1; + Z21 += p2 * q1; + Z22 += p2 * q2; + + if (columnCounter > 6) + { + columnCounter -= 6; + + ptrAElement += 6; + ptrDElement += 6 * d_stride; + + p1 = ptrAElement[-4]; + p2 = ptrAElement[-4 + rowSkip]; + dd = ptrDElement[-4 * (int)d_stride]; + q1 = p1 * dd; + q2 = p2 * dd; + ptrAElement[-4] = q1; + ptrAElement[-4 + rowSkip] = q2; + Z11 += p1 * q1; + Z21 += p2 * q1; + Z22 += p2 * q2; + + p1 = ptrAElement[-3]; + p2 = ptrAElement[-3 + rowSkip]; + dd = ptrDElement[-3 * (int)d_stride]; + q1 = p1 * dd; + q2 = p2 * dd; + ptrAElement[-3] = q1; + ptrAElement[-3 + rowSkip] = q2; + Z11 += p1 * q1; + Z21 += p2 * q1; + Z22 += p2 * q2; + + p1 = ptrAElement[-2]; + p2 = ptrAElement[-2 + rowSkip]; + dd = ptrDElement[-2 * (int)d_stride]; + q1 = p1 * dd; + q2 = p2 * dd; + ptrAElement[-2] = q1; + ptrAElement[-2 + rowSkip] = q2; + Z11 += p1 * q1; + Z21 += p2 * q1; + Z22 += p2 * q2; + + p1 = ptrAElement[-1]; + p2 = ptrAElement[-1 + rowSkip]; + dd = ptrDElement[-1 * (int)d_stride]; + q1 = p1 * dd; + q2 = p2 * dd; + ptrAElement[-1] = q1; + ptrAElement[-1 + rowSkip] = q2; + Z11 += p1 * q1; + Z21 += p2 * q1; + Z22 += p2 * q2; + } + else + { + ptrAElement += 2; + ptrDElement += 2 * d_stride; + + if ((columnCounter -= 2) == 0) + { + break; + } + } + } + + /* solve for diagonal 2 x 2 block at A(i,i) */ + dReal Y11 = ptrAElement[0] - Z11; + dReal Y21 = ptrAElement[rowSkip] - Z21; + dReal Y22 = ptrAElement[1 + rowSkip] - Z22; + + /* factorize 2 x 2 block Y, ptrDElement */ + /* factorize row 1 */ + dReal dd = dRecip(Y11); + + ptrDElement[0 * d_stride] = dd; + dIASSERT(ptrDElement == d + (sizeint)factorizationRow * d_stride); + + /* factorize row 2 */ + dReal q2 = Y21 * dd; + ptrAElement[rowSkip] = q2; + + dReal sum = Y21 * q2; + ptrDElement[1 * d_stride] = dRecip(Y22 - sum); +} + +template<unsigned int d_stride> +void scaleAndFactorizeL1FirstRowStripe_2(dReal *ARow, dReal *d, unsigned rowSkip) +{ + dReal *ptrAElement = ARow; + dReal *ptrDElement = d; + + /* solve for diagonal 2 x 2 block at A(0,0) */ + dReal Y11 = ptrAElement[0]/* - Z11*/; + dReal Y21 = ptrAElement[rowSkip]/* - Z21*/; + dReal Y22 = ptrAElement[1 + rowSkip]/* - Z22*/; + + /* factorize 2 x 2 block Y, ptrDElement */ + /* factorize row 1 */ + dReal dd = dRecip(Y11); + + ptrDElement[0 * d_stride] = dd; + dIASSERT(ptrDElement == d/* + (sizeint)factorizationRow * d_stride*/); + + /* factorize row 2 */ + dReal q2 = Y21 * dd; + ptrAElement[rowSkip] = q2; + + dReal sum = Y21 * q2; + ptrDElement[1 * d_stride] = dRecip(Y22 - sum); +} + + +/* 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. + * B is an n*1 matrix that contains the right hand sides. + * B is stored by columns and its leading dimension is also lskip. + * B is overwritten with X. + * this processes blocks of 2*2. + * if this is in the factorizer source file, n must be a multiple of 2. + */ +static +void solveStripeL1_1(const dReal *L, dReal *B, unsigned rowCount, unsigned rowSkip) +{ + dIASSERT(rowCount != 0); + dIASSERT(rowCount % 2 == 0); + + /* compute all 2 x 1 blocks of X */ + unsigned blockStartRow = 0; + for (bool exitLoop = false, subsequentPass = false; !exitLoop; subsequentPass = true, exitLoop = (blockStartRow += 2) == rowCount) + { + const dReal *ptrLElement; + dReal *ptrBElement; + + /* declare variables - Z matrix */ + dReal Z11, Z21; + + if (subsequentPass) + { + ptrLElement = L + (sizeint)blockStartRow * rowSkip; + ptrBElement = B; + + /* set the Z matrix to 0 */ + Z11 = 0; Z21 = 0; + + /* compute all 2 x 1 block of X, from rows i..i+2-1 */ + + /* the inner loop that computes outer products and adds them to Z */ + // The iteration starts with even number and decreases it by 2. So, it must end in zero + for (unsigned columnCounter = blockStartRow; ; ) + { + /* declare p and q vectors, etc */ + dReal p1, q1, p2; + + /* compute outer product and add it to the Z matrix */ + p1 = ptrLElement[0]; + q1 = ptrBElement[0]; + Z11 += p1 * q1; + p2 = ptrLElement[rowSkip]; + Z21 += p2 * q1; + + /* compute outer product and add it to the Z matrix */ + p1 = ptrLElement[1]; + q1 = ptrBElement[1]; + Z11 += p1 * q1; + p2 = ptrLElement[1 + rowSkip]; + Z21 += p2 * q1; + + if (columnCounter > 6) + { + columnCounter -= 6; + + /* advance pointers */ + ptrLElement += 6; + ptrBElement += 6; + + /* compute outer product and add it to the Z matrix */ + p1 = ptrLElement[-4]; + q1 = ptrBElement[-4]; + Z11 += p1 * q1; + p2 = ptrLElement[-4 + rowSkip]; + Z21 += p2 * q1; + + /* compute outer product and add it to the Z matrix */ + p1 = ptrLElement[-3]; + q1 = ptrBElement[-3]; + Z11 += p1 * q1; + p2 = ptrLElement[-3 + rowSkip]; + Z21 += p2 * q1; + + /* compute outer product and add it to the Z matrix */ + p1 = ptrLElement[-2]; + q1 = ptrBElement[-2]; + Z11 += p1 * q1; + p2 = ptrLElement[-2 + rowSkip]; + Z21 += p2 * q1; + + /* compute outer product and add it to the Z matrix */ + p1 = ptrLElement[-1]; + q1 = ptrBElement[-1]; + Z11 += p1 * q1; + p2 = ptrLElement[-1 + rowSkip]; + Z21 += p2 * q1; + } + else + { + /* advance pointers */ + ptrLElement += 2; + ptrBElement += 2; + + if ((columnCounter -= 2) == 0) + { + break; + } + } + /* end of inner loop */ + } + } + else + { + ptrLElement = L/* + (sizeint)blockStartRow * rowSkip*/; dIASSERT(blockStartRow == 0); + ptrBElement = B; + + /* set the Z matrix to 0 */ + Z11 = 0; Z21 = 0; + } + + /* finish computing the X(i) block */ + dReal p2 = ptrLElement[rowSkip]; + + dReal Y11 = ptrBElement[0] - Z11; + dReal Y21 = ptrBElement[1] - Z21 - p2 * Y11; + + ptrBElement[0] = Y11; + ptrBElement[1] = Y21; + /* end of outer loop */ + } +} + +template<unsigned int d_stride> +void scaleAndFactorizeL1Stripe_1(dReal *ARow, dReal *d, unsigned factorizationRow) +{ + dReal *ptrAElement = ARow; + dReal *ptrDElement = d; + + /* 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. */ + dReal Z11 = 0, Z22 = 0; + + for (unsigned columnCounter = factorizationRow; ; ) + { + dReal p1, p2, q1, q2, dd1, dd2; + + p1 = ptrAElement[0]; + p2 = ptrAElement[1]; + dd1 = ptrDElement[0 * d_stride]; + dd2 = ptrDElement[1 * d_stride]; + q1 = p1 * dd1; + q2 = p2 * dd2; + ptrAElement[0] = q1; + ptrAElement[1] = q2; + Z11 += p1 * q1; + Z22 += p2 * q2; + + if (columnCounter > 6) + { + columnCounter -= 6; + + ptrAElement += 6; + ptrDElement += 6 * d_stride; + + p1 = ptrAElement[-4]; + p2 = ptrAElement[-3]; + dd1 = ptrDElement[-4 * (int)d_stride]; + dd2 = ptrDElement[-3 * (int)d_stride]; + q1 = p1 * dd1; + q2 = p2 * dd2; + ptrAElement[-4] = q1; + ptrAElement[-3] = q2; + Z11 += p1 * q1; + Z22 += p2 * q2; + + p1 = ptrAElement[-2]; + p2 = ptrAElement[-1]; + dd1 = ptrDElement[-2 * (int)d_stride]; + dd2 = ptrDElement[-1 * (int)d_stride]; + q1 = p1 * dd1; + q2 = p2 * dd2; + ptrAElement[-2] = q1; + ptrAElement[-1] = q2; + Z11 += p1 * q1; + Z22 += p2 * q2; + } + else + { + ptrAElement += 2; + ptrDElement += 2 * d_stride; + + if ((columnCounter -= 2) == 0) + { + break; + } + } + } + + dReal Y11 = ptrAElement[0] - (Z11 + Z22); + + /* solve for diagonal 1 x 1 block at A(i,i) */ + dIASSERT(ptrDElement == d + (sizeint)factorizationRow * d_stride); + /* factorize 1 x 1 block Y, ptrDElement */ + /* factorize row 1 */ + ptrDElement[0 * d_stride] = dRecip(Y11); +} + +template<unsigned int d_stride> +void scaleAndFactorizeL1FirstRowStripe_1(dReal *ARow, dReal *d) +{ + dReal *ptrAElement = ARow; + dReal *ptrDElement = d; + + dReal Y11 = ptrAElement[0]; + + /* solve for diagonal 1 x 1 block at A(0,0) */ + /* factorize 1 x 1 block Y, ptrDElement */ + /* factorize row 1 */ + ptrDElement[0 * d_stride] = dRecip(Y11); +} + + + + +template<unsigned int block_step, unsigned int b_rows> +/*static */ +void ThreadedEquationSolverLDLT::participateSolvingL1Stripe_X(const dReal *L, dReal *B, unsigned blockCount, unsigned rowSkip, + volatile atomicord32 &refBlockCompletionProgress/*=0*/, volatile cellindexint *blockProgressDescriptors/*=[blockCount]*/, + FactorizationSolveL1StripeCellContext *cellContexts/*=[CCI__MAX x blockCount] + [blockCount]*/, unsigned ownThreadIndex) +{ + const unsigned lookaheadRange = 64; + BlockProcessingState blockProcessingState = BPS_NO_BLOCKS_PROCESSED; + + unsigned completedBlocks = refBlockCompletionProgress; + unsigned currentBlock = completedBlocks; + dIASSERT(completedBlocks <= blockCount); + + for (bool exitLoop = completedBlocks == blockCount; !exitLoop; exitLoop = false) + { + bool goForLockedBlockPrimaryCalculation = false, goForLockedBlockDuplicateCalculation = false; + bool goAssigningTheResult = false, stayWithinTheBlock = false; + + dReal Z[block_step][b_rows]; + dReal Y[block_step][b_rows]; + + dReal *ptrBElement; + + CellContextInstance previousContextInstance; + unsigned completedColumnBlock; + + for (cellindexint testDescriptor = blockProgressDescriptors[currentBlock]; ; ) + { + if (testDescriptor == INVALID_CELLDESCRIPTOR) + { + // Invalid descriptor is the indication that the row has been fully calculated + // Test if this was the last row and break out if so. + if (currentBlock + 1 == blockCount) + { + exitLoop = true; + break; + } + + // Treat detected row advancement as a row processed + // blockProcessingState = BPS_SOME_BLOCKS_PROCESSED; <-- performs better without it + break; + } + + CooperativeAtomics::AtomicReadReorderBarrier(); + // It is necessary to read up to date completedBblocks value after the descriptor retrieval + // as otherwise the logic below breaks + completedBlocks = refBlockCompletionProgress; + + if (!GET_CELLDESCRIPTOR_ISLOCKED(testDescriptor)) + { + completedColumnBlock = GET_CELLDESCRIPTOR_COLUMNINDEX(testDescriptor); + dIASSERT(completedColumnBlock < currentBlock || (completedColumnBlock == currentBlock && currentBlock == 0)); // Otherwise, why would the calculation have had stopped if the final column is reachable??? + dIASSERT(completedColumnBlock <= completedBlocks); // Since the descriptor is not locked + + if (completedColumnBlock == completedBlocks && currentBlock != completedBlocks) + { + dIASSERT(completedBlocks < currentBlock); + break; + } + + if (CooperativeAtomics::AtomicCompareExchangeCellindexint(&blockProgressDescriptors[currentBlock], testDescriptor, MARK_CELLDESCRIPTOR_LOCKED(testDescriptor))) + { + if (completedColumnBlock != 0) + { + CellContextInstance contextInstance = GET_CELLDESCRIPTOR_CONTEXTINSTANCE(testDescriptor); + previousContextInstance = contextInstance; + + const FactorizationSolveL1StripeCellContext &sourceContext = buildBlockContextRef(cellContexts, currentBlock, contextInstance); + sourceContext.loadPrecalculatedZs(Z); + } + else + { + previousContextInstance = CCI__MIN; + FactorizationSolveL1StripeCellContext::initializePrecalculatedZs(Z); + } + + goForLockedBlockPrimaryCalculation = true; + break; + } + + if (blockProcessingState != BPS_COMPETING_FOR_A_BLOCK) + { + break; + } + + testDescriptor = blockProgressDescriptors[currentBlock]; + } + else + { + if (blockProcessingState != BPS_COMPETING_FOR_A_BLOCK) + { + break; + } + + cellindexint verificativeDescriptor; + bool verificationFailure = false; + + completedColumnBlock = GET_CELLDESCRIPTOR_COLUMNINDEX(testDescriptor); + dIASSERT(completedColumnBlock != currentBlock || currentBlock == 0); // There is no reason for computations to stop at the very end other than being the initial value at the very first block + + if (completedColumnBlock != 0) + { + CellContextInstance contextInstance = GET_CELLDESCRIPTOR_CONTEXTINSTANCE(testDescriptor); + const FactorizationSolveL1StripeCellContext &sourceContext = buildBlockContextRef(cellContexts, currentBlock, contextInstance); + sourceContext.loadPrecalculatedZs(Z); + } + else + { + FactorizationSolveL1StripeCellContext::initializePrecalculatedZs(Z); + } + + if (completedColumnBlock != 0 && completedColumnBlock <= currentBlock) + { + // Make sure the descriptor is re-read after the precalculates + CooperativeAtomics::AtomicReadReorderBarrier(); + } + + if (completedColumnBlock <= currentBlock) + { + verificativeDescriptor = blockProgressDescriptors[currentBlock]; + verificationFailure = verificativeDescriptor != testDescriptor; + } + + if (!verificationFailure) + { + dIASSERT(completedColumnBlock <= currentBlock + 1); + + goForLockedBlockDuplicateCalculation = true; + break; + } + + testDescriptor = verificativeDescriptor; + } + } + + if (exitLoop) + { + break; + } + + if (goForLockedBlockPrimaryCalculation) + { + blockProcessingState = BPS_SOME_BLOCKS_PROCESSED; + + // Declare and assign the variables at the top to not interfere with any branching -- the compiler is going to eliminate them anyway. + bool handleComputationTakenOver = false, rowEndReached = false; + + const dReal *ptrLElement; + unsigned finalColumnBlock; + + if (currentBlock != 0) + { + /* compute all 2 x 2 block of X, from rows i..i+2-1 */ + ptrLElement = L + (currentBlock * rowSkip + completedColumnBlock) * block_step; + ptrBElement = B + completedColumnBlock * block_step; + + /* the inner loop that computes outer products and adds them to Z */ + finalColumnBlock = dMACRO_MIN(currentBlock, completedBlocks); + dIASSERT(completedColumnBlock != finalColumnBlock/* || currentBlock == 0*/); + + // The iteration starts with even number and decreases it by 2. So, it must end in zero + for (unsigned columnCounter = finalColumnBlock - completedColumnBlock; ; ) + { + /* declare p and q vectors, etc */ + dReal p[block_step], q[b_rows]; + + /* compute outer product and add it to the Z matrix */ + p[0] = ptrLElement[0]; + q[0] = ptrBElement[0]; + Z[0][0] += p[0] * q[0]; + if (b_rows >= 2) + { + q[1] = ptrBElement[rowSkip]; + Z[0][1] += p[0] * q[1]; + } + p[1] = ptrLElement[rowSkip]; + Z[1][0] += p[1] * q[0]; + if (b_rows >= 2) + { + Z[1][1] += p[1] * q[1]; + } + + /* compute outer product and add it to the Z matrix */ + p[0] = ptrLElement[1]; + q[0] = ptrBElement[1]; + Z[0][0] += p[0] * q[0]; + if (b_rows >= 2) + { + q[1] = ptrBElement[1 + rowSkip]; + Z[0][1] += p[0] * q[1]; + } + p[1] = ptrLElement[1 + rowSkip]; + Z[1][0] += p[1] * q[0]; + if (b_rows >= 2) + { + Z[1][1] += p[1] * q[1]; + } + + dSASSERT(block_step == 2); + dSASSERT(b_rows >= 1 && b_rows <= 2); + + if (columnCounter > 2) + { + /* compute outer product and add it to the Z matrix */ + p[0] = ptrLElement[2]; + q[0] = ptrBElement[2]; + Z[0][0] += p[0] * q[0]; + if (b_rows >= 2) + { + q[1] = ptrBElement[2 + rowSkip]; + Z[0][1] += p[0] * q[1]; + } + p[1] = ptrLElement[2 + rowSkip]; + Z[1][0] += p[1] * q[0]; + if (b_rows >= 2) + { + Z[1][1] += p[1] * q[1]; + } + + /* compute outer product and add it to the Z matrix */ + p[0] = ptrLElement[3]; + q[0] = ptrBElement[3]; + Z[0][0] += p[0] * q[0]; + if (b_rows >= 2) + { + q[1] = ptrBElement[3 + rowSkip]; + Z[0][1] += p[0] * q[1]; + } + p[1] = ptrLElement[3 + rowSkip]; + Z[1][0] += p[1] * q[0]; + if (b_rows >= 2) + { + Z[1][1] += p[1] * q[1]; + } + + dSASSERT(block_step == 2); + dSASSERT(b_rows >= 1 && b_rows <= 2); + + /* advance pointers */ + ptrLElement += 2 * block_step; + ptrBElement += 2 * block_step; + columnCounter -= 2; + } + else + { + /* advance pointers */ + ptrLElement += block_step; + ptrBElement += block_step; + /* end of inner loop */ + + if (--columnCounter == 0) + { + if (finalColumnBlock == currentBlock) + { + rowEndReached = true; + break; + } + + // Take a look if any more rows have been completed... + completedBlocks = refBlockCompletionProgress; + dIASSERT(completedBlocks >= finalColumnBlock); + + if (completedBlocks == finalColumnBlock) + { + break; + } + + // ...continue if so. + unsigned columnCompletedSoFar = finalColumnBlock; + finalColumnBlock = dMACRO_MIN(currentBlock, completedBlocks); + columnCounter = finalColumnBlock - columnCompletedSoFar; + } + } + } + } + else + { + ptrLElement = L/* + (currentBlock * rowSkip + completedColumnBlock) * block_step*/; + ptrBElement = B/* + completedColumnBlock * block_step*/; + + rowEndReached = true; + } + + if (rowEndReached) + { + // Check whether there is still a need to proceed or if the computation has been taken over by another thread + cellindexint oldDescriptor = MAKE_CELLDESCRIPTOR(completedColumnBlock, previousContextInstance, true); + + if (blockProgressDescriptors[currentBlock] == oldDescriptor) + { + /* finish computing the X(i) block */ + Y[0][0] = ptrBElement[0] - Z[0][0]; + if (b_rows >= 2) + { + Y[0][1] = ptrBElement[rowSkip] - Z[0][1]; + } + + dReal p2 = ptrLElement[rowSkip]; + + Y[1][0] = ptrBElement[1] - Z[1][0] - p2 * Y[0][0]; + if (b_rows >= 2) + { + Y[1][1] = ptrBElement[1 + rowSkip] - Z[1][1] - p2 * Y[0][1]; + } + + dSASSERT(block_step == 2); + dSASSERT(b_rows >= 1 && b_rows <= 2); + + // Use atomic memory barrier to make sure memory reads of ptrBElement[] and blockProgressDescriptors[] are not swapped + CooperativeAtomics::AtomicReadReorderBarrier(); + + // The descriptor has not been altered yet - this means the ptrBElement[] values used above were not modified yet + // and the computation result is valid. + if (blockProgressDescriptors[currentBlock] == oldDescriptor) + { + // Assign the results to the result context (possibly in parallel with other threads + // that could and ought to be assigning exactly the same values) + FactorizationSolveL1StripeCellContext &resultContext = buildResultContextRef(cellContexts, currentBlock, blockCount); + resultContext.storePrecalculatedZs(Y); + + // Assign the result assignment progress descriptor + cellindexint newDescriptor = MAKE_CELLDESCRIPTOR(currentBlock + 1, CCI__MIN, true); + CooperativeAtomics::AtomicCompareExchangeCellindexint(&blockProgressDescriptors[currentBlock], oldDescriptor, newDescriptor); // the result is to be ignored + + // Whether succeeded or not, the result is valid, so go on trying to assign it to the matrix + goAssigningTheResult = true; + } + else + { + // Otherwise, go on competing for copying the results + handleComputationTakenOver = true; + } + } + else + { + handleComputationTakenOver = true; + } + } + else + { + // If the final column has not been reached yet, store current values to the context. + // Select the other context instance as the previous one might be read by other threads. + CellContextInstance nextContextInstance = buildNextContextInstance(previousContextInstance); + FactorizationSolveL1StripeCellContext &destinationContext = buildBlockContextRef(cellContexts, currentBlock, nextContextInstance); + destinationContext.storePrecalculatedZs(Z); + + // Unlock the row until more columns can be used + cellindexint oldDescriptor = MAKE_CELLDESCRIPTOR(completedColumnBlock, previousContextInstance, true); + cellindexint newDescriptor = MAKE_CELLDESCRIPTOR(finalColumnBlock, nextContextInstance, false); + // The descriptor might have been updated by a competing thread + if (!CooperativeAtomics::AtomicCompareExchangeCellindexint(&blockProgressDescriptors[currentBlock], oldDescriptor, newDescriptor)) + { + // Adjust the ptrBElement to point to the result area... + ptrBElement = B + currentBlock * block_step; + // ...and go on handling the case + handleComputationTakenOver = true; + } + } + + if (handleComputationTakenOver) + { + cellindexint existingDescriptor = blockProgressDescriptors[currentBlock]; + // This can only happen if the row was (has become) the uppermost not fully completed one + // and the competing thread is at final stage of calculation (i.e., it has reached the currentBlock column). + if (existingDescriptor != INVALID_CELLDESCRIPTOR) + { + // If not fully completed this must be the final stage of the result assignment into the matrix + dIASSERT(existingDescriptor == MAKE_CELLDESCRIPTOR(currentBlock + 1, CCI__MIN, true)); + + // Go on competing copying the result as anyway the block is the topmost not completed one + // and since there was competition for it, there is no other work that can be done right now. + const FactorizationSolveL1StripeCellContext &resultContext = buildResultContextRef(cellContexts, currentBlock, blockCount); + resultContext.loadPrecalculatedZs(Y); + + goAssigningTheResult = true; + } + else + { + // everything is over -- just go handling next blocks + } + } + } + else if (goForLockedBlockDuplicateCalculation) + { + blockProcessingState = BPS_SOME_BLOCKS_PROCESSED; + + bool skipToHandlingSubsequentRows = false, skiptoCopyingResult = false; + + /* declare variables */ + const dReal *ptrLElement; + + if (completedColumnBlock < currentBlock) + { + /* compute all 2 x 2 block of X, from rows i..i+2-1 */ + ptrLElement = L + (currentBlock * rowSkip + completedColumnBlock) * block_step; + ptrBElement = B + completedColumnBlock * block_step; + + /* the inner loop that computes outer products and adds them to Z */ + // The iteration starts with even number and decreases it by 2. So, it must end in zero + const unsigned finalColumnBlock = currentBlock; + dIASSERT(currentBlock == completedBlocks); // Why would we be competing for a row otherwise? + + unsigned lastCompletedColumn = completedColumnBlock; + unsigned columnCounter = finalColumnBlock - completedColumnBlock; + for (bool exitInnerLoop = false; !exitInnerLoop; exitInnerLoop = --columnCounter == 0) + { + /* declare p and q vectors, etc */ + dReal p[block_step], q[b_rows]; + + /* compute outer product and add it to the Z matrix */ + p[0] = ptrLElement[0]; + q[0] = ptrBElement[0]; + Z[0][0] += p[0] * q[0]; + if (b_rows >= 2) + { + q[1] = ptrBElement[rowSkip]; + Z[0][1] += p[0] * q[1]; + } + p[1] = ptrLElement[rowSkip]; + Z[1][0] += p[1] * q[0]; + if (b_rows >= 2) + { + Z[1][1] += p[1] * q[1]; + } + + /* compute outer product and add it to the Z matrix */ + p[0] = ptrLElement[1]; + q[0] = ptrBElement[1]; + Z[0][0] += p[0] * q[0]; + if (b_rows >= 2) + { + q[1] = ptrBElement[1 + rowSkip]; + Z[0][1] += p[0] * q[1]; + } + p[1] = ptrLElement[1 + rowSkip]; + Z[1][0] += p[1] * q[0]; + if (b_rows >= 2) + { + Z[1][1] += p[1] * q[1]; + } + + dSASSERT(block_step == 2); + dSASSERT(b_rows >= 1 && b_rows <= 2); + + // Check if the primary solver thread has not made any progress + cellindexint descriptorVerification = blockProgressDescriptors[currentBlock]; + unsigned newCompletedColumn = GET_CELLDESCRIPTOR_COLUMNINDEX(descriptorVerification); + + if (newCompletedColumn != lastCompletedColumn) + { + // Check, this is the first change the current thread detects. + // There is absolutely no reason in code for the computation to stop/resume twice + // while the current thread is competing. + dIASSERT(lastCompletedColumn == completedColumnBlock); + + if (descriptorVerification == INVALID_CELLDESCRIPTOR) + { + skipToHandlingSubsequentRows = true; + break; + } + + if (newCompletedColumn == currentBlock + 1) + { + skiptoCopyingResult = true; + break; + } + + // Check if the current thread is behind + if (newCompletedColumn > finalColumnBlock - columnCounter) + { + // If so, go starting over one more time + blockProcessingState = BPS_COMPETING_FOR_A_BLOCK; + stayWithinTheBlock = true; + skipToHandlingSubsequentRows = true; + break; + } + + // If current thread is ahead, just save new completed column for further comparisons and go on calculating + lastCompletedColumn = newCompletedColumn; + } + + /* advance pointers */ + ptrLElement += block_step; + ptrBElement += block_step; + /* end of inner loop */ + } + } + else if (completedColumnBlock > currentBlock) + { + dIASSERT(completedColumnBlock == currentBlock + 1); + + skiptoCopyingResult = true; + } + else + { + dIASSERT(currentBlock == 0); // Execution can get here within the very first block only + + /* assign the pointers appropriately and go on computing the results */ + ptrLElement = L/* + (currentBlock * rowSkip + completedColumnBlock) * block_step*/; + ptrBElement = B/* + completedColumnBlock * block_step*/; + } + + if (!skipToHandlingSubsequentRows) + { + if (!skiptoCopyingResult) + { + /* finish computing the X(i) block */ + Y[0][0] = ptrBElement[0] - Z[0][0]; + if (b_rows >= 2) + { + Y[0][1] = ptrBElement[rowSkip] - Z[0][1]; + } + + dReal p2 = ptrLElement[rowSkip]; + + Y[1][0] = ptrBElement[1] - Z[1][0] - p2 * Y[0][0]; + if (b_rows >= 2) + { + Y[1][1] = ptrBElement[1 + rowSkip] - Z[1][1] - p2 * Y[0][1]; + } + + dSASSERT(block_step == 2); + dSASSERT(b_rows >= 1 && b_rows <= 2); + + // Use atomic memory barrier to make sure memory reads of ptrBElement[] and blockProgressDescriptors[] are not swapped + CooperativeAtomics::AtomicReadReorderBarrier(); + + cellindexint existingDescriptor = blockProgressDescriptors[currentBlock]; + + if (existingDescriptor == INVALID_CELLDESCRIPTOR) + { + // Everything is over -- proceed to subsequent rows + skipToHandlingSubsequentRows = true; + } + else if (existingDescriptor == MAKE_CELLDESCRIPTOR(currentBlock + 1, CCI__MIN, true)) + { + // The values computed above may not be valid. Copy the values already in the result context. + skiptoCopyingResult = true; + } + else + { + // The descriptor has not been altered yet - this means the ptrBElement[] values used above were not modified yet + // and the computation result is valid. + cellindexint newDescriptor = MAKE_CELLDESCRIPTOR(currentBlock + 1, CCI__MIN, true); // put the computation at the top so that the evaluation result from the expression above is reused + + // Assign the results to the result context (possibly in parallel with other threads + // that could and ought to be assigning exactly the same values) + FactorizationSolveL1StripeCellContext &resultContext = buildResultContextRef(cellContexts, currentBlock, blockCount); + resultContext.storePrecalculatedZs(Y); + + // Assign the result assignment progress descriptor + CooperativeAtomics::AtomicCompareExchangeCellindexint(&blockProgressDescriptors[currentBlock], existingDescriptor, newDescriptor); // the result is to be ignored + + // Whether succeeded or not, the result is valid, so go on trying to assign it to the matrix + } + } + + if (!skipToHandlingSubsequentRows) + { + if (skiptoCopyingResult) + { + // Extract the result values stored in the result context + const FactorizationSolveL1StripeCellContext &resultContext = buildResultContextRef(cellContexts, currentBlock, blockCount); + resultContext.loadPrecalculatedZs(Y); + + ptrBElement = B + currentBlock * block_step; + } + + goAssigningTheResult = true; + } + } + } + + if (goAssigningTheResult) + { + cellindexint existingDescriptor = blockProgressDescriptors[currentBlock]; + // Check if the assignment has not been completed yet + if (existingDescriptor != INVALID_CELLDESCRIPTOR) + { + // Assign the computation results to their places in the matrix + ptrBElement[0] = Y[0][0]; + ptrBElement[1] = Y[1][0]; + if (b_rows >= 2) + { + ptrBElement[rowSkip] = Y[0][1]; + ptrBElement[1 + rowSkip] = Y[1][1]; + } + + dSASSERT(block_step == 2); + dSASSERT(b_rows >= 1 && b_rows <= 2); + + ThrsafeIncrementIntUpToLimit(&refBlockCompletionProgress, currentBlock + 1); + dIASSERT(refBlockCompletionProgress >= currentBlock + 1); + + // And assign the completed status no matter what + CooperativeAtomics::AtomicStoreCellindexint(&blockProgressDescriptors[currentBlock], INVALID_CELLDESCRIPTOR); + } + else + { + // everything is over -- just go handling next blocks + } + } + + if (!stayWithinTheBlock) + { + completedBlocks = refBlockCompletionProgress; + + if (completedBlocks == blockCount) + { + break; + } + + currentBlock += 1; + + bool lookaheadBoundaryReached = false; + + if (currentBlock == blockCount || completedBlocks == 0) + { + lookaheadBoundaryReached = true; + } + else if (currentBlock >= completedBlocks + lookaheadRange) + { + lookaheadBoundaryReached = blockProcessingState > BPS_NO_BLOCKS_PROCESSED; + } + else if (currentBlock < completedBlocks) + { + // Treat detected row advancement as a row processed + // blockProcessingState = BPS_SOME_BLOCKS_PROCESSED; <-- performs better without it + + currentBlock = completedBlocks; + } + + if (lookaheadBoundaryReached) + { + dIASSERT(blockProcessingState != BPS_COMPETING_FOR_A_BLOCK); // Why did not we compete??? + + // If no row has been processed in the previous pass, compete for the next row to avoid cycling uselessly + if (blockProcessingState <= BPS_NO_BLOCKS_PROCESSED) + { + // Abandon job if too few blocks remain + if (blockCount - completedBlocks <= ownThreadIndex) + { + break; + } + + blockProcessingState = BPS_COMPETING_FOR_A_BLOCK; + } + else + { + // If there was some progress, just continue to the next pass + blockProcessingState = BPS_NO_BLOCKS_PROCESSED; + } + + currentBlock = completedBlocks; + } + } + } +} + + +template<unsigned int a_rows, unsigned int d_stride> +/*static */ +void ThreadedEquationSolverLDLT::participateScalingAndFactorizingL1Stripe_X(dReal *ARow, dReal *d, unsigned factorizationRow, unsigned rowSkip, + FactorizationFactorizeL1StripeContext *factorizationContext, unsigned ownThreadIndex) +{ + dIASSERT(factorizationRow != 0); + dIASSERT(factorizationRow % 2 == 0); + + /* 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. */ + dReal sameZ[a_rows] = { REAL(0.0), }, mixedZ[dMACRO_MAX(a_rows - 1, 1)] = { REAL(0.0), }; + bool doneAnything = false; + + const unsigned blockSize = deriveScalingAndFactorizingL1StripeBlockSize(a_rows); + + const unsigned blockCount = deriveScalingAndFactorizingL1StripeBlockCountFromFactorizationRow(factorizationRow, blockSize); + dIASSERT(blockCount != 0); + + unsigned blockIndex; + while ((blockIndex = ThrsafeIncrementIntUpToLimit(&factorizationContext->m_nextColumnIndex, blockCount)) != blockCount) + { + doneAnything = true; + unsigned blockStartRow = blockIndex * blockSize; + + dReal *ptrAElement = ARow + blockStartRow; + dReal *ptrDElement = d + blockStartRow * d_stride; + for (unsigned columnCounter = blockIndex != blockCount - 1 ? blockSize : factorizationRow - blockStartRow; ; ) + { + dReal p1, q1, p2, q2, dd; + + p1 = ptrAElement[0]; + if (a_rows >= 2) + { + p2 = ptrAElement[rowSkip]; + } + dd = ptrDElement[0 * d_stride]; + q1 = p1 * dd; + if (a_rows >= 2) + { + q2 = p2 * dd; + } + ptrAElement[0] = q1; + if (a_rows >= 2) + { + ptrAElement[rowSkip] = q2; + } + sameZ[0] += p1 * q1; + if (a_rows >= 2) + { + sameZ[1] += p2 * q2; + mixedZ[0] += p2 * q1; + } + + p1 = ptrAElement[1]; + if (a_rows >= 2) + { + p2 = ptrAElement[1 + rowSkip]; + } + dd = ptrDElement[1 * d_stride]; + q1 = p1 * dd; + if (a_rows >= 2) + { + q2 = p2 * dd; + } + ptrAElement[1] = q1; + if (a_rows >= 2) + { + ptrAElement[1 + rowSkip] = q2; + } + sameZ[0] += p1 * q1; + if (a_rows >= 2) + { + sameZ[1] += p2 * q2; + mixedZ[0] += p2 * q1; + } + + if (columnCounter > 6) + { + columnCounter -= 6; + + ptrAElement += 6; + ptrDElement += 6 * d_stride; + + p1 = ptrAElement[-4]; + if (a_rows >= 2) + { + p2 = ptrAElement[-4 + rowSkip]; + } + dd = ptrDElement[-4 * (int)d_stride]; + q1 = p1 * dd; + if (a_rows >= 2) + { + q2 = p2 * dd; + } + ptrAElement[-4] = q1; + if (a_rows >= 2) + { + ptrAElement[-4 + rowSkip] = q2; + } + sameZ[0] += p1 * q1; + if (a_rows >= 2) + { + sameZ[1] += p2 * q2; + mixedZ[0] += p2 * q1; + } + + p1 = ptrAElement[-3]; + if (a_rows >= 2) + { + p2 = ptrAElement[-3 + rowSkip]; + } + dd = ptrDElement[-3 * (int)d_stride]; + q1 = p1 * dd; + if (a_rows >= 2) + { + q2 = p2 * dd; + } + ptrAElement[-3] = q1; + if (a_rows >= 2) + { + ptrAElement[-3 + rowSkip] = q2; + } + sameZ[0] += p1 * q1; + if (a_rows >= 2) + { + sameZ[1] += p2 * q2; + mixedZ[0] += p2 * q1; + } + + p1 = ptrAElement[-2]; + if (a_rows >= 2) + { + p2 = ptrAElement[-2 + rowSkip]; + } + dd = ptrDElement[-2 * (int)d_stride]; + q1 = p1 * dd; + if (a_rows >= 2) + { + q2 = p2 * dd; + } + ptrAElement[-2] = q1; + if (a_rows >= 2) + { + ptrAElement[-2 + rowSkip] = q2; + } + sameZ[0] += p1 * q1; + if (a_rows >= 2) + { + sameZ[1] += p2 * q2; + mixedZ[0] += p2 * q1; + } + + p1 = ptrAElement[-1]; + if (a_rows >= 2) + { + p2 = ptrAElement[-1 + rowSkip]; + } + dd = ptrDElement[-1 * (int)d_stride]; + q1 = p1 * dd; + if (a_rows >= 2) + { + q2 = p2 * dd; + } + ptrAElement[-1] = q1; + if (a_rows >= 2) + { + ptrAElement[-1 + rowSkip] = q2; + } + sameZ[0] += p1 * q1; + if (a_rows >= 2) + { + sameZ[1] += p2 * q2; + mixedZ[0] += p2 * q1; + } + } + else + { + ptrAElement += 2; + ptrDElement += 2 * d_stride; + + if ((columnCounter -= 2) == 0) + { + break; + } + } + } + } + + if (doneAnything) + { + unsigned partialSumThreadIndex; + for (bool exitLoop = false; !exitLoop; exitLoop = CooperativeAtomics::AtomicCompareExchangeUint32(&factorizationContext->m_sumThreadIndex, partialSumThreadIndex, ownThreadIndex + 1)) + { + partialSumThreadIndex = factorizationContext->m_sumThreadIndex; + + if (partialSumThreadIndex != 0) + { + const FactorizationFactorizeL1StripeThreadContext &partialSumContext = factorizationContext->m_threadContexts[partialSumThreadIndex - 1]; + factorizationContext->m_threadContexts[ownThreadIndex].assignDataSum<a_rows>(sameZ, mixedZ, partialSumContext); + } + else + { + factorizationContext->m_threadContexts[ownThreadIndex].assignDataAlone<a_rows>(sameZ, mixedZ); + } + } + } + + unsigned threadExitIndex = CooperativeAtomics::AtomicDecrementUint32(&factorizationContext->m_threadsRunning); + dIASSERT(threadExitIndex + 1U != 0); + + if (threadExitIndex == 0) + { + // Let the last thread retrieve the sum and perform final computations + unsigned sumThreadIndex = factorizationContext->m_sumThreadIndex; + dIASSERT(sumThreadIndex != 0); // The rowIndex was asserted to be not zero, so at least one thread must have done something + + const FactorizationFactorizeL1StripeThreadContext &sumContext = factorizationContext->m_threadContexts[sumThreadIndex - 1]; + sumContext.retrieveData<a_rows>(sameZ, mixedZ); + + dReal *ptrAElement = ARow + factorizationRow; + dReal *ptrDElement = d + factorizationRow * d_stride; + + /* solve for diagonal 2 x 2 block at A(i,i) */ + dReal Y11, Y21, Y22; + + Y11 = ptrAElement[0] - sameZ[0]; + if (a_rows >= 2) + { + Y21 = ptrAElement[rowSkip] - mixedZ[0]; + Y22 = ptrAElement[1 + rowSkip] - sameZ[1]; + } + + /* factorize 2 x 2 block Y, ptrDElement */ + /* factorize row 1 */ + dReal dd = dRecip(Y11); + + ptrDElement[0 * d_stride] = dd; + dIASSERT(ptrDElement == d + (sizeint)factorizationRow * d_stride); + + if (a_rows >= 2) + { + /* factorize row 2 */ + dReal q2 = Y21 * dd; + ptrAElement[rowSkip] = q2; + + dReal sum = Y21 * q2; + ptrDElement[1 * d_stride] = dRecip(Y22 - sum); + } + } +} + + +#endif // #ifndef _ODE_FASTLDLT_IMPL_H_ diff --git a/libs/ode-0.16.1/ode/src/fastldltsolve.cpp b/libs/ode-0.16.1/ode/src/fastldltsolve.cpp new file mode 100644 index 0000000..ca1ff4d --- /dev/null +++ b/libs/ode-0.16.1/ode/src/fastldltsolve.cpp @@ -0,0 +1,222 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * LDLT solving related code of ThreadedEquationSolverLDLT + * Copyright (c) 2017-2019 Oleh Derevenko, odar@eleks.com (change all "a" to "e") + */ + +#include <ode/common.h> +#include <ode/matrix.h> +#include <ode/matrix_coop.h> +#include "config.h" +#include "threaded_solver_ldlt.h" +#include "threading_base.h" +#include "resource_control.h" + +#include "fastldltsolve_impl.h" + + +/*static */ +void ThreadedEquationSolverLDLT::estimateCooperativeSolvingLDLTResourceRequirements( + dxResourceRequirementDescriptor *summaryRequirementsDescriptor, + unsigned allowedThreadCount, unsigned rowCount) +{ + unsigned stageBlockCountSifficiencyMask; + dxThreadingBase *threading = summaryRequirementsDescriptor->getrelatedThreading(); + unsigned limitedThreadCount = restrictSolvingLDLTAllowedThreadCount(threading, allowedThreadCount, rowCount, stageBlockCountSifficiencyMask); + + if (limitedThreadCount > 1) + { + if ((stageBlockCountSifficiencyMask & (1U << SLDLTS_SOLVING_STRAIGHT)) != 0) + { + doEstimateCooperativeSolvingL1StraightResourceRequirementsValidated(summaryRequirementsDescriptor, allowedThreadCount, rowCount); + } + + if ((stageBlockCountSifficiencyMask & (1U << SLDLTS_SCALING_VECTOR)) != 0) + { + doEstimateCooperativeScalingVectorResourceRequirementsValidated(summaryRequirementsDescriptor, allowedThreadCount, rowCount); + } + + if ((stageBlockCountSifficiencyMask & (1U << SLDLTS_SOLVING_TRANSPOSED)) == 0) + { + doEstimateCooperativeSolvingL1TransposedResourceRequirementsValidated(summaryRequirementsDescriptor, allowedThreadCount, rowCount); + } + } +} + +/*static */ +void ThreadedEquationSolverLDLT::cooperativelySolveLDLT( + dxRequiredResourceContainer *resourceContainer, unsigned allowedThreadCount, + const dReal *L, const dReal *d, dReal *b, unsigned rowCount, unsigned rowSkip) +{ + dAASSERT(rowCount != 0); + + unsigned stageBlockCountSifficiencyMask; + + dxThreadingBase *threading = resourceContainer->getThreadingInstance(); + unsigned limitedThreadCount = restrictSolvingLDLTAllowedThreadCount(threading, allowedThreadCount, rowCount, stageBlockCountSifficiencyMask); + + if (limitedThreadCount <= 1) + { + solveEquationSystemWithLDLT<SLDLT_D_STRIDE, SLDLT_B_STRIDE>(L, d, b, rowCount, rowSkip); + } + else + { + doCooperativelySolveLDLTValidated(resourceContainer, limitedThreadCount, stageBlockCountSifficiencyMask, L, d, b, rowCount, rowSkip); + } +} + +/*static */ +unsigned ThreadedEquationSolverLDLT::restrictSolvingLDLTAllowedThreadCount( + dxThreadingBase *threading, unsigned allowedThreadCount, unsigned rowCount, unsigned &out_stageBlockCountSifficiencyMask) +{ + unsigned limitedThreadCount = 1; + unsigned stageBlockCountSifficiencyMask = 0; + +#if dCOOPERATIVE_ENABLED + { + const unsigned int blockStep = SL1S_BLOCK_SIZE; // Required by the implementation + unsigned solvingStraightBlockCount = deriveSolvingL1StraightBlockCount(rowCount, blockStep); + dIASSERT(deriveSolvingL1StraightThreadCount(SL1S_COOPERATIVE_BLOCK_COUNT_MINIMUM, 2) > 1); + + if (solvingStraightBlockCount >= SL1S_COOPERATIVE_BLOCK_COUNT_MINIMUM) + { + stageBlockCountSifficiencyMask |= 1U << SLDLTS_SOLVING_STRAIGHT; + } + } + + { + const unsigned int blockStep = SV_BLOCK_SIZE; // Required by the implementation + unsigned scalingBlockCount = deriveScalingVectorBlockCount(rowCount, blockStep); + dIASSERT(deriveScalingVectorThreadCount(SV_COOPERATIVE_BLOCK_COUNT_MINIMUM - 1, 2) > 1); + + if (scalingBlockCount >= SV_COOPERATIVE_BLOCK_COUNT_MINIMUM) + { + stageBlockCountSifficiencyMask |= 1U << SLDLTS_SCALING_VECTOR; + } + } + + { + const unsigned int blockStep = SL1T_BLOCK_SIZE; // Required by the implementation + unsigned solvingTransposedBlockCount = deriveSolvingL1TransposedBlockCount(rowCount, blockStep); + dIASSERT(deriveSolvingL1TransposedThreadCount(SL1T_COOPERATIVE_BLOCK_COUNT_MINIMUM, 2) > 1); + + if (solvingTransposedBlockCount >= SL1T_COOPERATIVE_BLOCK_COUNT_MINIMUM) + { + stageBlockCountSifficiencyMask |= 1U << SLDLTS_SOLVING_TRANSPOSED; + } + } + + if (stageBlockCountSifficiencyMask != 0) + { + limitedThreadCount = threading->calculateThreadingLimitedThreadCount(allowedThreadCount, true); + } +#endif // #if dCOOPERATIVE_ENABLED + + out_stageBlockCountSifficiencyMask = stageBlockCountSifficiencyMask; + return limitedThreadCount; +} + + +/*static */ +void ThreadedEquationSolverLDLT::doCooperativelySolveLDLTValidated( + dxRequiredResourceContainer *resourceContainer, unsigned allowedThreadCount, unsigned stageBlockCountSifficiencyMask, + const dReal *L, const dReal *d, dReal *b, unsigned rowCount, unsigned rowSkip) +{ + dIASSERT(allowedThreadCount > 1); + + if ((stageBlockCountSifficiencyMask & (1U << SLDLTS_SOLVING_STRAIGHT)) == 0) + { + solveL1Straight<SLDLT_B_STRIDE>(L, b, rowCount, rowSkip); + } + else + { + dSASSERT(SLDLT_B_STRIDE + 0 == SL1S_B_STRIDE); + + doCooperativelySolveL1StraightValidated(resourceContainer, allowedThreadCount, L, b, rowCount, rowSkip); + } + + if ((stageBlockCountSifficiencyMask & (1U << SLDLTS_SCALING_VECTOR)) == 0) + { + scaleLargeVector<SLDLT_B_STRIDE, SLDLT_D_STRIDE>(b, d, rowCount); + } + else + { + dSASSERT(SLDLT_B_STRIDE + 0 == SV_A_STRIDE); + dSASSERT(SLDLT_D_STRIDE + 0 == SV_D_STRIDE); + + doCooperativelyScaleVectorValidated(resourceContainer, allowedThreadCount, b, d, rowCount); + } + + if ((stageBlockCountSifficiencyMask & (1U << SLDLTS_SOLVING_TRANSPOSED)) == 0) + { + solveL1Transposed<SLDLT_B_STRIDE>(L, b, rowCount, rowSkip); + } + else + { + dSASSERT(SLDLT_B_STRIDE + 0 == SL1T_B_STRIDE); + + doCooperativelySolveL1TransposedValidated(resourceContainer, allowedThreadCount, L, b, rowCount, rowSkip); + } +} + + +////////////////////////////////////////////////////////////////////////// +// Public interface functions + +/*extern ODE_API */ +void dSolveLDLT(const dReal *L, const dReal *d, dReal *b, int n, int nskip) +{ + dAASSERT(n != 0); + + if (n != 0) + { + dAASSERT(L != NULL); + dAASSERT(d != NULL); + dAASSERT(b != NULL); + + solveEquationSystemWithLDLT<1, 1>(L, d, b, n, nskip); + } +} + + +/*extern ODE_API */ +void dEstimateCooperativelySolveLDLTResourceRequirements(dResourceRequirementsID requirements, + unsigned maximalAllowedThreadCount, unsigned maximalRowCount) +{ + dAASSERT(requirements != NULL); + + dxResourceRequirementDescriptor *requirementsDescriptor = (dxResourceRequirementDescriptor *)requirements; + ThreadedEquationSolverLDLT::estimateCooperativeSolvingLDLTResourceRequirements(requirementsDescriptor, maximalAllowedThreadCount, maximalRowCount); +} + +/*extern ODE_API */ +void dCooperativelySolveLDLT(dResourceContainerID resources, unsigned allowedThreadCount, + const dReal *L, const dReal *d, dReal *b, unsigned rowCount, unsigned rowSkip) +{ + dAASSERT(resources != NULL); + + dxRequiredResourceContainer *resourceContainer = (dxRequiredResourceContainer *)resources; + ThreadedEquationSolverLDLT::cooperativelySolveLDLT(resourceContainer, allowedThreadCount, L, d, b, rowCount, rowSkip); +} + diff --git a/libs/ode-0.16.1/ode/src/fastldltsolve_impl.h b/libs/ode-0.16.1/ode/src/fastldltsolve_impl.h new file mode 100644 index 0000000..ad6f393 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/fastldltsolve_impl.h @@ -0,0 +1,49 @@ +
+
+/*************************************************************************
+ * *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
+ * All rights reserved. Email: russ@q12.org Web: www.q12.org *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of EITHER: *
+ * (1) The GNU Lesser General Public License as published by the Free *
+ * Software Foundation; either version 2.1 of the License, or (at *
+ * your option) any later version. The text of the GNU Lesser *
+ * General Public License is included with this library in the *
+ * file LICENSE.TXT. *
+ * (2) The BSD-style license that is included with this library in *
+ * the file LICENSE-BSD.TXT. *
+ * *
+ * This library 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 files *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
+ * *
+ *************************************************************************/
+
+#ifndef _ODE_MATRIX_IMPL_H_
+#define _ODE_MATRIX_IMPL_H_
+
+
+#include "fastlsolve_impl.h"
+#include "fastltsolve_impl.h"
+#include "fastvecscale_impl.h"
+
+
+template<unsigned int d_stride, unsigned int b_stride>
+void solveEquationSystemWithLDLT(const dReal *L, const dReal *d, dReal *b, unsigned rowCount, unsigned rowSkip)
+{
+ dAASSERT(L != NULL);
+ dAASSERT(d != NULL);
+ dAASSERT(b != NULL);
+ dAASSERT(rowCount > 0);
+ dAASSERT(rowSkip >= rowCount);
+
+ solveL1Straight<b_stride>(L, b, rowCount, rowSkip);
+ scaleLargeVector<b_stride, d_stride>(b, d, rowCount);
+ solveL1Transposed<b_stride>(L, b, rowCount, rowSkip);
+}
+
+
+#endif
diff --git a/libs/ode-0.16.1/ode/src/fastlsolve.cpp b/libs/ode-0.16.1/ode/src/fastlsolve.cpp new file mode 100644 index 0000000..6f7e6a4 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/fastlsolve.cpp @@ -0,0 +1,230 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * L1Straight Equation Solving Routines + * Copyright (c) 2017-2019 Oleh Derevenko, odar@eleks.com (change all "a" to "e") + */ + +#include <ode/common.h> +#include <ode/matrix.h> +#include <ode/matrix_coop.h> +#include "config.h" +#include "threaded_solver_ldlt.h" +#include "threading_base.h" +#include "resource_control.h" +#include "error.h" + +#include "fastlsolve_impl.h" + + +/*static */ +void ThreadedEquationSolverLDLT::estimateCooperativeSolvingL1StraightResourceRequirements( + dxResourceRequirementDescriptor *summaryRequirementsDescriptor, + unsigned allowedThreadCount, unsigned rowCount) +{ + dxThreadingBase *threading = summaryRequirementsDescriptor->getrelatedThreading(); + unsigned limitedThreadCount = restrictSolvingL1StraightAllowedThreadCount(threading, allowedThreadCount, rowCount); + + if (limitedThreadCount > 1) + { + doEstimateCooperativeSolvingL1StraightResourceRequirementsValidated(summaryRequirementsDescriptor, allowedThreadCount, rowCount); + } +} + +/*static */ +void ThreadedEquationSolverLDLT::cooperativelySolveL1Straight( + dxRequiredResourceContainer *resourceContainer, unsigned allowedThreadCount, + const dReal *L, dReal *b, unsigned rowCount, unsigned rowSkip) +{ + dAASSERT(rowCount != 0); + + dxThreadingBase *threading = resourceContainer->getThreadingInstance(); + unsigned limitedThreadCount = restrictSolvingL1StraightAllowedThreadCount(threading, allowedThreadCount, rowCount); + + if (limitedThreadCount <= 1) + { + solveL1Straight<SL1S_B_STRIDE>(L, b, rowCount, rowSkip); + } + else + { + doCooperativelySolveL1StraightValidated(resourceContainer, limitedThreadCount, L, b, rowCount, rowSkip); + } +} + + +/*static */ +unsigned ThreadedEquationSolverLDLT::restrictSolvingL1StraightAllowedThreadCount( + dxThreadingBase *threading, unsigned allowedThreadCount, unsigned rowCount) +{ + unsigned limitedThreadCount = 1; + +#if dCOOPERATIVE_ENABLED + const unsigned int blockStep = SL1S_BLOCK_SIZE; // Required by the implementation + unsigned solvingBlockCount = deriveSolvingL1StraightBlockCount(rowCount, blockStep); + dIASSERT(deriveSolvingL1StraightThreadCount(SL1S_COOPERATIVE_BLOCK_COUNT_MINIMUM, 2) > 1); + + if (solvingBlockCount >= SL1S_COOPERATIVE_BLOCK_COUNT_MINIMUM) + { + limitedThreadCount = threading->calculateThreadingLimitedThreadCount(allowedThreadCount, true); + } +#endif // #if dCOOPERATIVE_ENABLED + + return limitedThreadCount; +} + +/*static */ +void ThreadedEquationSolverLDLT::doEstimateCooperativeSolvingL1StraightResourceRequirementsValidated( + dxResourceRequirementDescriptor *summaryRequirementsDescriptor, + unsigned allowedThreadCount, unsigned rowCount) +{ + const unsigned int blockStep = SL1S_BLOCK_SIZE; // Required by the implementation + unsigned blockCount = deriveSolvingL1StraightBlockCount(rowCount, blockStep); + dIASSERT(blockCount >= 1); + + unsigned threadCountToUse = deriveSolvingL1StraightThreadCount(blockCount, allowedThreadCount); + dIASSERT(threadCountToUse > 1); + + unsigned simultaneousCallCount = 1 + (threadCountToUse - 1); + + SolvingL1StraightMemoryEstimates solvingMemoryEstimates; + sizeint solvingMemoryRequired = estimateCooperativelySolvingL1StraightMemoryRequirement<blockStep>(rowCount, solvingMemoryEstimates); + const unsigned solvingAlignmentRequired = ALLOCATION_DEFAULT_ALIGNMENT; + + unsigned featureRequirement = dxResourceRequirementDescriptor::STOCK_CALLWAIT_REQUIRED; + summaryRequirementsDescriptor->mergeAnotherDescriptorIn(solvingMemoryRequired, solvingAlignmentRequired, simultaneousCallCount, featureRequirement); +} + +/*static */ +void ThreadedEquationSolverLDLT::doCooperativelySolveL1StraightValidated( + dxRequiredResourceContainer *resourceContainer, unsigned allowedThreadCount, + const dReal *L, dReal *b, unsigned rowCount, unsigned rowSkip) +{ + dIASSERT(allowedThreadCount > 1); + + const unsigned int blockStep = SL1S_BLOCK_SIZE; // Required by the implementation + unsigned blockCount = deriveSolvingL1StraightBlockCount(rowCount, blockStep); + dIASSERT(blockCount >= 1); + + unsigned threadCountToUse = deriveSolvingL1StraightThreadCount(blockCount, allowedThreadCount); + dIASSERT(threadCountToUse > 1); + + dCallWaitID completionWait = resourceContainer->getStockCallWait(); + dAASSERT(completionWait != NULL); + + atomicord32 blockCompletionProgress; + cellindexint *blockProgressDescriptors; + SolveL1StraightCellContext *cellContexts; + + SolvingL1StraightMemoryEstimates solvingMemoryEstimates; + sizeint solvingMemoryRequired = estimateCooperativelySolvingL1StraightMemoryRequirement<blockStep>(rowCount, solvingMemoryEstimates); + dIASSERT(solvingMemoryRequired <= resourceContainer->getMemoryBufferSize()); + + void *bufferAllocated = resourceContainer->getMemoryBufferPointer(); + dIASSERT(bufferAllocated != NULL); + dIASSERT(dALIGN_PTR(bufferAllocated, ALLOCATION_DEFAULT_ALIGNMENT) == bufferAllocated); + + void *bufferCurrentLocation = bufferAllocated; + bufferCurrentLocation = markCooperativelySolvingL1StraightMemoryStructuresOut(bufferCurrentLocation, solvingMemoryEstimates, blockProgressDescriptors, cellContexts); + dIVERIFY(bufferCurrentLocation <= (uint8 *)bufferAllocated + solvingMemoryRequired); + + initializeCooperativelySolveL1StraightMemoryStructures<blockStep>(rowCount, blockCompletionProgress, blockProgressDescriptors, cellContexts); + + dCallReleaseeID calculationFinishReleasee; + SolveL1StraightWorkerContext workerContext; // The variable must exist in the outer scope + + workerContext.init(L, b, rowCount, rowSkip, blockCompletionProgress, blockProgressDescriptors, cellContexts); + + dxThreadingBase *threading = resourceContainer->getThreadingInstance(); + threading->PostThreadedCall(NULL, &calculationFinishReleasee, threadCountToUse - 1, NULL, completionWait, &solveL1Straight_completion_callback, NULL, 0, "SolveL1Straight Completion"); + threading->PostThreadedCallsGroup(NULL, threadCountToUse - 1, calculationFinishReleasee, &solveL1Straight_worker_callback, &workerContext, "SolveL1Straight Work"); + + participateSolvingL1Straight<blockStep, SL1S_B_STRIDE>(L, b, rowCount, rowSkip, blockCompletionProgress, blockProgressDescriptors, cellContexts, threadCountToUse - 1); + + threading->WaitThreadedCallExclusively(NULL, completionWait, NULL, "SolveL1Straight End Wait"); +} + +/*static */ +int ThreadedEquationSolverLDLT::solveL1Straight_worker_callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID dUNUSED(callThisReleasee)) +{ + SolveL1StraightWorkerContext *ptrContext = (SolveL1StraightWorkerContext *)callContext; + + solveL1Straight_worker(*ptrContext, dCAST_TO_SMALLER(unsigned, callInstanceIndex)); + + return 1; +} + +/*static */ +void ThreadedEquationSolverLDLT::solveL1Straight_worker(SolveL1StraightWorkerContext &ref_context, unsigned ownThreadIndex) +{ + const unsigned blockStep = SL1S_BLOCK_SIZE; + + participateSolvingL1Straight<blockStep, SL1S_B_STRIDE>(ref_context.m_L, ref_context.m_b, ref_context.m_rowCount, ref_context.m_rowSkip, + *ref_context.m_ptrBlockCompletionProgress, ref_context.m_blockProgressDescriptors, ref_context.m_cellContexts, ownThreadIndex); +} + +/*static */ +int ThreadedEquationSolverLDLT::solveL1Straight_completion_callback(void *dUNUSED(callContext), dcallindex_t dUNUSED(callInstanceIndex), dCallReleaseeID dUNUSED(callThisReleasee)) +{ + return 1; +} + + + +////////////////////////////////////////////////////////////////////////// +// Public interface functions + +/*extern ODE_API */ +void dSolveL1(const dReal *L, dReal *B, int n, int lskip1) +{ + dAASSERT(n != 0); + + if (n != 0) + { + dAASSERT(L != NULL); + dAASSERT(B != NULL); + + solveL1Straight<1>(L, B, n, lskip1); + } +} + + +/*extern ODE_API */ +void dEstimateCooperativelySolveL1StraightResourceRequirements(dResourceRequirementsID requirements, + unsigned maximalAllowedThreadCount, unsigned maximalRowCount) +{ + dAASSERT(requirements != NULL); + + dxResourceRequirementDescriptor *requirementsDescriptor = (dxResourceRequirementDescriptor *)requirements; + ThreadedEquationSolverLDLT::estimateCooperativeSolvingL1StraightResourceRequirements(requirementsDescriptor, maximalAllowedThreadCount, maximalRowCount); +} + +/*extern ODE_API */ +void dCooperativelySolveL1Straight(dResourceContainerID resources, unsigned allowedThreadCount, + const dReal *L, dReal *b, unsigned rowCount, unsigned rowSkip) +{ + dAASSERT(resources != NULL); + + dxRequiredResourceContainer *resourceContainer = (dxRequiredResourceContainer *)resources; + ThreadedEquationSolverLDLT::cooperativelySolveL1Straight(resourceContainer, allowedThreadCount, L, b, rowCount, rowSkip); +} + diff --git a/libs/ode-0.16.1/ode/src/fastlsolve_impl.h b/libs/ode-0.16.1/ode/src/fastlsolve_impl.h new file mode 100644 index 0000000..f14ada7 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/fastlsolve_impl.h @@ -0,0 +1,1610 @@ + + +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * Code style improvements and optimizations by Oleh Derevenko ????-2019 + * L1Straight cooperative solving code of ThreadedEquationSolverLDLT copyright (c) 2017-2019 Oleh Derevenko, odar@eleks.com (change all "a" to "e") + */ + +#ifndef _ODE_FASTLSOLVE_IMPL_H_ +#define _ODE_FASTLSOLVE_IMPL_H_ + + +/* 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. + * B is an n*1 matrix that contains the right hand sides. + * B is stored by columns and its leading dimension is also lskip. + * B is overwritten with X. + * this processes blocks of 4*4. + * if this is in the factorizer source file, n must be a multiple of 4. + */ + +template<unsigned int b_stride> +void solveL1Straight (const dReal *L, dReal *B, unsigned rowCount, unsigned rowSkip) +{ + dIASSERT(rowCount != 0); + + /* compute all 4 x 1 blocks of X */ + unsigned blockStartRow = 0; + bool subsequentPass = false; + bool goForLoopX4 = rowCount >= 4; + const unsigned loopX4LastRow = goForLoopX4 ? rowCount - 4 : 0; + for (; goForLoopX4; subsequentPass = true, goForLoopX4 = (blockStartRow += 4) <= loopX4LastRow) + { + /* declare variables - Z matrix, p and q vectors, etc */ + const dReal *ptrLElement; + dReal *ptrBElement; + + dReal Z11, Z21, Z31, Z41; + + /* compute all 4 x 1 block of X, from rows i..i+4-1 */ + if (subsequentPass) + { + ptrLElement = L + (1 + blockStartRow) * rowSkip; + ptrBElement = B; + /* set the Z matrix to 0 */ + Z11 = 0; Z21 = 0; Z31 = 0; Z41 = 0; + + /* the inner loop that computes outer products and adds them to Z */ + for (unsigned columnCounter = blockStartRow; ; ) + { + dReal q1, p1, p2, p3, p4; + + /* load p and q values */ + q1 = ptrBElement[0 * b_stride]; + p1 = (ptrLElement - rowSkip)[0]; + p2 = ptrLElement[0]; + ptrLElement += rowSkip; + p3 = ptrLElement[0]; + p4 = ptrLElement[0 + rowSkip]; + + /* 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 */ + q1 = ptrBElement[1 * b_stride]; + p3 = ptrLElement[1]; + p4 = ptrLElement[1 + rowSkip]; + ptrLElement -= rowSkip; + p1 = (ptrLElement - rowSkip)[1]; + p2 = ptrLElement[1]; + + /* 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 */ + q1 = ptrBElement[2 * b_stride]; + p1 = (ptrLElement - rowSkip)[2]; + p2 = ptrLElement[2]; + ptrLElement += rowSkip; + p3 = ptrLElement[2]; + p4 = ptrLElement[2 + rowSkip]; + + /* 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 */ + q1 = ptrBElement[3 * b_stride]; + p3 = ptrLElement[3]; + p4 = ptrLElement[3 + rowSkip]; + ptrLElement -= rowSkip; + p1 = (ptrLElement - rowSkip)[3]; + p2 = ptrLElement[3]; + + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + Z21 += p2 * q1; + Z31 += p3 * q1; + Z41 += p4 * q1; + + if (columnCounter > 12) + { + columnCounter -= 12; + + /* advance pointers */ + ptrLElement += 12; + ptrBElement += 12 * b_stride; + + /* load p and q values */ + q1 = ptrBElement[-8 * (int)b_stride]; + p1 = (ptrLElement - rowSkip)[-8]; + p2 = ptrLElement[-8]; + ptrLElement += rowSkip; + p3 = ptrLElement[-8]; + p4 = ptrLElement[-8 + rowSkip]; + + /* 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 */ + q1 = ptrBElement[-7 * (int)b_stride]; + p3 = ptrLElement[-7]; + p4 = ptrLElement[-7 + rowSkip]; + ptrLElement -= rowSkip; + p1 = (ptrLElement - rowSkip)[-7]; + p2 = ptrLElement[-7]; + + /* 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 */ + q1 = ptrBElement[-6 * (int)b_stride]; + p1 = (ptrLElement - rowSkip)[-6]; + p2 = ptrLElement[-6]; + ptrLElement += rowSkip; + p3 = ptrLElement[-6]; + p4 = ptrLElement[-6 + rowSkip]; + + /* 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 */ + q1 = ptrBElement[-5 * (int)b_stride]; + p3 = ptrLElement[-5]; + p4 = ptrLElement[-5 + rowSkip]; + ptrLElement -= rowSkip; + p1 = (ptrLElement - rowSkip)[-5]; + p2 = ptrLElement[-5]; + + /* 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 */ + q1 = ptrBElement[-4 * (int)b_stride]; + p1 = (ptrLElement - rowSkip)[-4]; + p2 = ptrLElement[-4]; + ptrLElement += rowSkip; + p3 = ptrLElement[-4]; + p4 = ptrLElement[-4 + rowSkip]; + + /* 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 */ + q1 = ptrBElement[-3 * (int)b_stride]; + p3 = ptrLElement[-3]; + p4 = ptrLElement[-3 + rowSkip]; + ptrLElement -= rowSkip; + p1 = (ptrLElement - rowSkip)[-3]; + p2 = ptrLElement[-3]; + + /* 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 */ + q1 = ptrBElement[-2 * (int)b_stride]; + p1 = (ptrLElement - rowSkip)[-2]; + p2 = ptrLElement[-2]; + ptrLElement += rowSkip; + p3 = ptrLElement[-2]; + p4 = ptrLElement[-2 + rowSkip]; + + /* 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 */ + q1 = ptrBElement[-1 * (int)b_stride]; + p3 = ptrLElement[-1]; + p4 = ptrLElement[-1 + rowSkip]; + ptrLElement -= rowSkip; + p1 = (ptrLElement - rowSkip)[-1]; + p2 = ptrLElement[-1]; + + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + Z21 += p2 * q1; + Z31 += p3 * q1; + Z41 += p4 * q1; + } + else + { + /* advance pointers */ + ptrLElement += 4; + ptrBElement += 4 * b_stride; + + if ((columnCounter -= 4) == 0) + { + break; + } + } + /* end of inner loop */ + } + } + else + { + ptrLElement = L + rowSkip/* + blockStartRow * rowSkip*/; dIASSERT(blockStartRow == 0); + ptrBElement = B; + /* set the Z matrix to 0 */ + Z11 = 0; Z21 = 0; Z31 = 0; Z41 = 0; + } + + /* finish computing the X(i) block */ + dReal Y11, Y21, Y31, Y41; + { + Y11 = ptrBElement[0 * b_stride] - Z11; + ptrBElement[0 * b_stride] = Y11; + } + { + dReal p2 = ptrLElement[0]; + Y21 = ptrBElement[1 * b_stride] - Z21 - p2 * Y11; + ptrBElement[1 * b_stride] = Y21; + } + ptrLElement += rowSkip; + { + dReal p3 = ptrLElement[0]; + dReal p3_1 = ptrLElement[1]; + Y31 = ptrBElement[2 * b_stride] - Z31 - p3 * Y11 - p3_1 * Y21; + ptrBElement[2 * b_stride] = Y31; + } + { + dReal p4 = ptrLElement[rowSkip]; + dReal p4_1 = ptrLElement[1 + rowSkip]; + dReal p4_2 = ptrLElement[2 + rowSkip]; + Y41 = ptrBElement[3 * b_stride] - Z41 - p4 * Y11 - p4_1 * Y21 - p4_2 * Y31; + ptrBElement[3 * b_stride] = Y41; + } + /* end of outer loop */ + } + + /* compute rows at end that are not a multiple of block size */ + for (; !subsequentPass || blockStartRow < rowCount; subsequentPass = true, ++blockStartRow) + { + /* compute all 1 x 1 block of X, from rows i..i+1-1 */ + dReal *ptrBElement; + + dReal Z11, Z12; + + if (subsequentPass) + { + ptrBElement = B; + /* set the Z matrix to 0 */ + Z11 = 0; Z12 = 0; + + const dReal *ptrLElement = L + blockStartRow * rowSkip; + + /* the inner loop that computes outer products and adds them to Z */ + unsigned columnCounter = blockStartRow; + for (bool exitLoop = columnCounter < 4; !exitLoop; exitLoop = false) + { + dReal p1, p2, q1, q2; + + /* load p and q values */ + p1 = ptrLElement[0]; + p2 = ptrLElement[1]; + q1 = ptrBElement[0 * b_stride]; + q2 = ptrBElement[1 * b_stride]; + + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + Z12 += p2 * q2; + + /* load p and q values */ + p1 = ptrLElement[2]; + p2 = ptrLElement[3]; + q1 = ptrBElement[2 * b_stride]; + q2 = ptrBElement[3 * b_stride]; + + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + Z12 += p2 * q2; + + if (columnCounter >= (12 + 4)) + { + columnCounter -= 12; + + /* advance pointers */ + ptrLElement += 12; + ptrBElement += 12 * b_stride; + + /* load p and q values */ + p1 = ptrLElement[-8]; + p2 = ptrLElement[-7]; + q1 = ptrBElement[-8 * (int)b_stride]; + q2 = ptrBElement[-7 * (int)b_stride]; + + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + Z12 += p2 * q2; + + /* load p and q values */ + p1 = ptrLElement[-6]; + p2 = ptrLElement[-5]; + q1 = ptrBElement[-6 * (int)b_stride]; + q2 = ptrBElement[-5 * (int)b_stride]; + + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + Z12 += p2 * q2; + + /* load p and q values */ + p1 = ptrLElement[-4]; + p2 = ptrLElement[-3]; + q1 = ptrBElement[-4 * (int)b_stride]; + q2 = ptrBElement[-3 * (int)b_stride]; + + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + Z12 += p2 * q2; + + /* load p and q values */ + p1 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + q1 = ptrBElement[-2 * (int)b_stride]; + q2 = ptrBElement[-1 * (int)b_stride]; + + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + Z12 += p2 * q2; + } + else + { + /* advance pointers */ + ptrLElement += 4; + ptrBElement += 4 * b_stride; + + if ((columnCounter -= 4) < 4) + { + break; + } + } + /* end of inner loop */ + } + + /* compute left-over iterations */ + if ((columnCounter & 2) != 0) + { + dReal p1, p2, q1, q2; + + /* load p and q values */ + p1 = ptrLElement[0]; + p2 = ptrLElement[1]; + q1 = ptrBElement[0 * b_stride]; + q2 = ptrBElement[1 * b_stride]; + + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + Z12 += p2 * q2; + + /* advance pointers */ + ptrLElement += 2; + ptrBElement += 2 * b_stride; + } + + if ((columnCounter & 1) != 0) + { + dReal p1, q1; + + /* load p and q values */ + p1 = ptrLElement[0]; + q1 = ptrBElement[0 * b_stride]; + + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + + /* advance pointers */ + // ptrLElement += 1; -- not needed any more + ptrBElement += 1 * b_stride; + } + + /* finish computing the X(i) block */ + dReal Y11 = ptrBElement[0 * b_stride] - (Z11 + Z12); + ptrBElement[0 * b_stride] = Y11; + } + } +} + + +template<unsigned int block_step> +/*static */ +sizeint ThreadedEquationSolverLDLT::estimateCooperativelySolvingL1StraightMemoryRequirement(unsigned rowCount, SolvingL1StraightMemoryEstimates &ref_solvingMemoryEstimates) +{ + unsigned blockCount = deriveSolvingL1StraightBlockCount(rowCount, block_step); + sizeint descriptorSizeRequired = dEFFICIENT_SIZE(sizeof(cellindexint) * blockCount); + sizeint contextSizeRequired = dEFFICIENT_SIZE(sizeof(SolveL1StraightCellContext) * (CCI__MAX + 1) * blockCount); + ref_solvingMemoryEstimates.assignData(descriptorSizeRequired, contextSizeRequired); + + sizeint totalSizeRequired = descriptorSizeRequired + contextSizeRequired; + return totalSizeRequired; +} + +template<unsigned int block_step> +/*static */ +void ThreadedEquationSolverLDLT::initializeCooperativelySolveL1StraightMemoryStructures(unsigned rowCount, + atomicord32 &out_blockCompletionProgress, cellindexint *blockProgressDescriptors, SolveL1StraightCellContext *dUNUSED(cellContexts)) +{ + unsigned blockCount = deriveSolvingL1StraightBlockCount(rowCount, block_step); + + out_blockCompletionProgress = 0; + memset(blockProgressDescriptors, 0, blockCount * sizeof(*blockProgressDescriptors)); +} + +template<unsigned int block_step, unsigned int b_stride> +void ThreadedEquationSolverLDLT::participateSolvingL1Straight(const dReal *L, dReal *B, unsigned rowCount, unsigned rowSkip, + volatile atomicord32 &refBlockCompletionProgress/*=0*/, volatile cellindexint *blockProgressDescriptors/*=[blockCount]*/, + SolveL1StraightCellContext *cellContexts/*=[CCI__MAX x blockCount] + [blockCount]*/, unsigned ownThreadIndex) +{ + const unsigned lookaheadRange = 32; + const unsigned blockCount = deriveSolvingL1StraightBlockCount(rowCount, block_step), lastBlock = blockCount - 1; + /* compute rows at end that are not a multiple of block size */ + const unsigned loopX1RowCount = rowCount % block_step; + + BlockProcessingState blockProcessingState = BPS_NO_BLOCKS_PROCESSED; + + unsigned completedBlocks = refBlockCompletionProgress; + unsigned currentBlock = completedBlocks; + dIASSERT(completedBlocks <= blockCount); + + for (bool exitLoop = completedBlocks == blockCount; !exitLoop; exitLoop = false) + { + bool goForLockedBlockPrimaryCalculation = false, goForLockedBlockDuplicateCalculation = false; + bool goAssigningTheResult = false, stayWithinTheBlock = false; + + dReal Z[block_step]; + dReal Y[block_step]; + + dReal *ptrBElement; + + CellContextInstance previousContextInstance; + unsigned completedColumnBlock; + bool partialBlock; + + for (cellindexint testDescriptor = blockProgressDescriptors[currentBlock]; ; ) + { + if (testDescriptor == INVALID_CELLDESCRIPTOR) + { + // Invalid descriptor is the indication that the row has been fully calculated + // Test if this was the last row and break out if so. + if (currentBlock + 1 == blockCount) + { + exitLoop = true; + break; + } + + // Treat detected row advancement as a row processed + // blockProcessingState = BPS_SOME_BLOCKS_PROCESSED; <-- performs better without it + break; + } + + CooperativeAtomics::AtomicReadReorderBarrier(); + // It is necessary to read up to date completedBblocks value after the descriptor retrieval + // as otherwise the logic below breaks + completedBlocks = refBlockCompletionProgress; + + if (!GET_CELLDESCRIPTOR_ISLOCKED(testDescriptor)) + { + completedColumnBlock = GET_CELLDESCRIPTOR_COLUMNINDEX(testDescriptor); + dIASSERT(completedColumnBlock < currentBlock || (completedColumnBlock == currentBlock && currentBlock == 0)); // Otherwise, why would the calculation have had stopped if the final column is reachable??? + dIASSERT(completedColumnBlock <= completedBlocks); // Since the descriptor is not locked + + if (completedColumnBlock == completedBlocks && currentBlock != completedBlocks) + { + dIASSERT(completedBlocks < currentBlock); + break; + } + + if (CooperativeAtomics::AtomicCompareExchangeCellindexint(&blockProgressDescriptors[currentBlock], testDescriptor, MARK_CELLDESCRIPTOR_LOCKED(testDescriptor))) + { + if (completedColumnBlock != 0) + { + CellContextInstance contextInstance = GET_CELLDESCRIPTOR_CONTEXTINSTANCE(testDescriptor); + previousContextInstance = contextInstance; + + const SolveL1StraightCellContext &sourceContext = buildBlockContextRef(cellContexts, currentBlock, contextInstance); + sourceContext.loadPrecalculatedZs(Z); + } + else + { + previousContextInstance = CCI__MIN; + SolveL1StraightCellContext::initializePrecalculatedZs(Z); + } + + goForLockedBlockPrimaryCalculation = true; + break; + } + + if (blockProcessingState != BPS_COMPETING_FOR_A_BLOCK) + { + break; + } + + testDescriptor = blockProgressDescriptors[currentBlock]; + } + else + { + if (blockProcessingState != BPS_COMPETING_FOR_A_BLOCK) + { + break; + } + + cellindexint verificativeDescriptor; + bool verificationFailure = false; + + completedColumnBlock = GET_CELLDESCRIPTOR_COLUMNINDEX(testDescriptor); + dIASSERT(completedColumnBlock != currentBlock || currentBlock == 0); // There is no reason for computations to stop at the very end other than being the initial value at the very first block + + if (completedColumnBlock != 0) + { + CellContextInstance contextInstance = GET_CELLDESCRIPTOR_CONTEXTINSTANCE(testDescriptor); + const SolveL1StraightCellContext &sourceContext = buildBlockContextRef(cellContexts, currentBlock, contextInstance); + sourceContext.loadPrecalculatedZs(Z); + } + else + { + SolveL1StraightCellContext::initializePrecalculatedZs(Z); + } + + if (completedColumnBlock != 0 && completedColumnBlock <= currentBlock) + { + // Make sure the descriptor is re-read after the precalculates + CooperativeAtomics::AtomicReadReorderBarrier(); + } + + if (completedColumnBlock <= currentBlock) + { + verificativeDescriptor = blockProgressDescriptors[currentBlock]; + verificationFailure = verificativeDescriptor != testDescriptor; + } + + if (!verificationFailure) + { + dIASSERT(completedColumnBlock <= currentBlock + 1); + + goForLockedBlockDuplicateCalculation = true; + break; + } + + testDescriptor = verificativeDescriptor; + } + } + + if (exitLoop) + { + break; + } + + if (goForLockedBlockPrimaryCalculation) + { + blockProcessingState = BPS_SOME_BLOCKS_PROCESSED; + + // Declare and assign the variables at the top to not interfere with any branching -- the compiler is going to eliminate them anyway. + bool handleComputationTakenOver = false, rowEndReached = false; + + const dReal *ptrLElement; + unsigned finalColumnBlock; + + /* check if this is not the partial block of fewer rows */ + if (currentBlock != lastBlock || loopX1RowCount == 0) + { + partialBlock = false; + + if (currentBlock != 0) + { + ptrLElement = L + (sizeint)(1 + currentBlock * block_step) * rowSkip + completedColumnBlock * block_step; + ptrBElement = B + (sizeint)(completedColumnBlock * block_step) * b_stride; + + /* the inner loop that computes outer products and adds them to Z */ + finalColumnBlock = dMACRO_MIN(currentBlock, completedBlocks); + dIASSERT(completedColumnBlock != finalColumnBlock/* || currentBlock == 0*/); + + for (unsigned columnCounter = finalColumnBlock - completedColumnBlock; ; ) + { + dReal q1, p1, p2, p3, p4; + + /* load p and q values */ + q1 = ptrBElement[0 * b_stride]; + p1 = (ptrLElement - rowSkip)[0]; + p2 = ptrLElement[0]; + ptrLElement += rowSkip; + p3 = ptrLElement[0]; + p4 = ptrLElement[0 + rowSkip]; + + /* compute outer product and add it to the Z matrix */ + Z[0] += p1 * q1; + Z[1] += p2 * q1; + Z[2] += p3 * q1; + Z[3] += p4 * q1; + + /* load p and q values */ + q1 = ptrBElement[1 * b_stride]; + p3 = ptrLElement[1]; + p4 = ptrLElement[1 + rowSkip]; + ptrLElement -= rowSkip; + p1 = (ptrLElement - rowSkip)[1]; + p2 = ptrLElement[1]; + + /* compute outer product and add it to the Z matrix */ + Z[0] += p1 * q1; + Z[1] += p2 * q1; + Z[2] += p3 * q1; + Z[3] += p4 * q1; + + /* load p and q values */ + q1 = ptrBElement[2 * b_stride]; + p1 = (ptrLElement - rowSkip)[2]; + p2 = ptrLElement[2]; + ptrLElement += rowSkip; + p3 = ptrLElement[2]; + p4 = ptrLElement[2 + rowSkip]; + + /* compute outer product and add it to the Z matrix */ + Z[0] += p1 * q1; + Z[1] += p2 * q1; + Z[2] += p3 * q1; + Z[3] += p4 * q1; + + /* load p and q values */ + q1 = ptrBElement[3 * b_stride]; + p3 = ptrLElement[3]; + p4 = ptrLElement[3 + rowSkip]; + ptrLElement -= rowSkip; + p1 = (ptrLElement - rowSkip)[3]; + p2 = ptrLElement[3]; + + /* compute outer product and add it to the Z matrix */ + Z[0] += p1 * q1; + Z[1] += p2 * q1; + Z[2] += p3 * q1; + Z[3] += p4 * q1; + dSASSERT(block_step == 4); + + if (columnCounter > 3) + { + columnCounter -= 3; + + ptrLElement += 3 * block_step; + ptrBElement += 3 * block_step * b_stride; + + /* load p and q values */ + q1 = ptrBElement[-8 * (int)b_stride]; + p1 = (ptrLElement - rowSkip)[-8]; + p2 = ptrLElement[-8]; + ptrLElement += rowSkip; + p3 = ptrLElement[-8]; + p4 = ptrLElement[-8 + rowSkip]; + + /* compute outer product and add it to the Z matrix */ + Z[0] += p1 * q1; + Z[1] += p2 * q1; + Z[2] += p3 * q1; + Z[3] += p4 * q1; + + /* load p and q values */ + q1 = ptrBElement[-7 * (int)b_stride]; + p3 = ptrLElement[-7]; + p4 = ptrLElement[-7 + rowSkip]; + ptrLElement -= rowSkip; + p1 = (ptrLElement - rowSkip)[-7]; + p2 = ptrLElement[-7]; + + /* compute outer product and add it to the Z matrix */ + Z[0] += p1 * q1; + Z[1] += p2 * q1; + Z[2] += p3 * q1; + Z[3] += p4 * q1; + + /* load p and q values */ + q1 = ptrBElement[-6 * (int)b_stride]; + p1 = (ptrLElement - rowSkip)[-6]; + p2 = ptrLElement[-6]; + ptrLElement += rowSkip; + p3 = ptrLElement[-6]; + p4 = ptrLElement[-6 + rowSkip]; + + /* compute outer product and add it to the Z matrix */ + Z[0] += p1 * q1; + Z[1] += p2 * q1; + Z[2] += p3 * q1; + Z[3] += p4 * q1; + + /* load p and q values */ + q1 = ptrBElement[-5 * (int)b_stride]; + p3 = ptrLElement[-5]; + p4 = ptrLElement[-5 + rowSkip]; + ptrLElement -= rowSkip; + p1 = (ptrLElement - rowSkip)[-5]; + p2 = ptrLElement[-5]; + + /* compute outer product and add it to the Z matrix */ + Z[0] += p1 * q1; + Z[1] += p2 * q1; + Z[2] += p3 * q1; + Z[3] += p4 * q1; + + /* load p and q values */ + q1 = ptrBElement[-4 * (int)b_stride]; + p1 = (ptrLElement - rowSkip)[-4]; + p2 = ptrLElement[-4]; + ptrLElement += rowSkip; + p3 = ptrLElement[-4]; + p4 = ptrLElement[-4 + rowSkip]; + + /* compute outer product and add it to the Z matrix */ + Z[0] += p1 * q1; + Z[1] += p2 * q1; + Z[2] += p3 * q1; + Z[3] += p4 * q1; + + /* load p and q values */ + q1 = ptrBElement[-3 * (int)b_stride]; + p3 = ptrLElement[-3]; + p4 = ptrLElement[-3 + rowSkip]; + ptrLElement -= rowSkip; + p1 = (ptrLElement - rowSkip)[-3]; + p2 = ptrLElement[-3]; + + /* compute outer product and add it to the Z matrix */ + Z[0] += p1 * q1; + Z[1] += p2 * q1; + Z[2] += p3 * q1; + Z[3] += p4 * q1; + + /* load p and q values */ + q1 = ptrBElement[-2 * (int)b_stride]; + p1 = (ptrLElement - rowSkip)[-2]; + p2 = ptrLElement[-2]; + ptrLElement += rowSkip; + p3 = ptrLElement[-2]; + p4 = ptrLElement[-2 + rowSkip]; + + /* compute outer product and add it to the Z matrix */ + Z[0] += p1 * q1; + Z[1] += p2 * q1; + Z[2] += p3 * q1; + Z[3] += p4 * q1; + + /* load p and q values */ + q1 = ptrBElement[-1 * (int)b_stride]; + p3 = ptrLElement[-1]; + p4 = ptrLElement[-1 + rowSkip]; + ptrLElement -= rowSkip; + p1 = (ptrLElement - rowSkip)[-1]; + p2 = ptrLElement[-1]; + + /* compute outer product and add it to the Z matrix */ + Z[0] += p1 * q1; + Z[1] += p2 * q1; + Z[2] += p3 * q1; + Z[3] += p4 * q1; + dSASSERT(block_step == 4); + } + else + { + ptrLElement += block_step; + ptrBElement += block_step * b_stride; + + if (--columnCounter == 0) + { + if (finalColumnBlock == currentBlock) + { + rowEndReached = true; + break; + } + + // Take a look if any more columns have been completed... + completedBlocks = refBlockCompletionProgress; + dIASSERT(completedBlocks >= finalColumnBlock); + + if (completedBlocks == finalColumnBlock) + { + break; + } + + // ...continue if so. + unsigned columnCompletedSoFar = finalColumnBlock; + finalColumnBlock = dMACRO_MIN(currentBlock, completedBlocks); + columnCounter = finalColumnBlock - columnCompletedSoFar; + } + } + /* end of inner loop */ + } + } + else + { + ptrLElement = L + (sizeint)(1/* + currentBlock * block_step*/) * rowSkip/* + completedColumnBlock * block_step*/; + ptrBElement = B/* + (sizeint)(completedColumnBlock * block_step) * b_stride*/; + dIASSERT(completedColumnBlock == 0); + + rowEndReached = true; + } + } + else + { + partialBlock = true; + + if (currentBlock != 0) + { + dReal tempZ[dMACRO_MAX(block_step - 1U, 1U)] = { REAL(0.0), }; + + ptrLElement = L + (sizeint)(/*1 + */currentBlock * block_step) * rowSkip + completedColumnBlock * block_step; + ptrBElement = B + (sizeint)(completedColumnBlock * block_step) * b_stride; + + /* the inner loop that computes outer products and adds them to Z */ + finalColumnBlock = dMACRO_MIN(currentBlock, completedBlocks); + dIASSERT(completedColumnBlock != finalColumnBlock/* || currentBlock == 0*/); + + for (unsigned partialRow = 0, columnCompletedSoFar = completedColumnBlock; ; ) + { + dReal Z1 = 0, Z2 = 0, Z3 = 0, Z4 = 0; + + for (unsigned columnCounter = finalColumnBlock - columnCompletedSoFar; ; ) + { + dReal q1, q2, q3, q4, p1, p2, p3, p4; + + /* load p and q values */ + q1 = ptrBElement[0 * b_stride]; + q2 = ptrBElement[1 * b_stride]; + q3 = ptrBElement[2 * b_stride]; + q4 = ptrBElement[3 * b_stride]; + p1 = ptrLElement[0]; + p2 = ptrLElement[1]; + p3 = ptrLElement[2]; + p4 = ptrLElement[3]; + + /* compute outer product and add it to the Z matrix */ + Z1 += p1 * q1; + Z2 += p2 * q2; + Z3 += p3 * q3; + Z4 += p4 * q4; + dSASSERT(block_step == 4); + + if (columnCounter > 3) + { + columnCounter -= 3; + + ptrLElement += 3 * block_step; + ptrBElement += 3 * block_step * b_stride; + + /* load p and q values */ + q1 = ptrBElement[-8 * (int)b_stride]; + q2 = ptrBElement[-7 * (int)b_stride]; + q3 = ptrBElement[-6 * (int)b_stride]; + q4 = ptrBElement[-5 * (int)b_stride]; + p1 = ptrLElement[-8]; + p2 = ptrLElement[-7]; + p3 = ptrLElement[-6]; + p4 = ptrLElement[-5]; + + /* compute outer product and add it to the Z matrix */ + Z1 += p1 * q1; + Z2 += p2 * q2; + Z3 += p3 * q3; + Z4 += p4 * q4; + + /* load p and q values */ + q1 = ptrBElement[-4 * (int)b_stride]; + q2 = ptrBElement[-3 * (int)b_stride]; + q3 = ptrBElement[-2 * (int)b_stride]; + q4 = ptrBElement[-1 * (int)b_stride]; + p1 = ptrLElement[-4]; + p2 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p4 = ptrLElement[-1]; + + /* compute outer product and add it to the Z matrix */ + Z1 += p1 * q1; + Z2 += p2 * q2; + Z3 += p3 * q3; + Z4 += p4 * q4; + dSASSERT(block_step == 4); + } + else + { + ptrLElement += block_step; + ptrBElement += block_step * b_stride; + + if (--columnCounter == 0) + { + break; + } + } + /* end of inner loop */ + } + + tempZ[partialRow] += Z1 + Z2 + Z3 + Z4; + + if (++partialRow == loopX1RowCount) + { + // Here switch is used to avoid accessing Z by parametrized index. + // So far all the accesses were performed by explicit constants + // what lets the compiler treat Z elements as individual variables + // rather than array elements. + Z[0] += tempZ[0]; + + if (loopX1RowCount >= 2) + { + Z[1] += tempZ[1]; + + if (loopX1RowCount > 2) + { + Z[2] += tempZ[2]; + } + } + dSASSERT(block_step == 4); + + if (finalColumnBlock == currentBlock) + { + if (loopX1RowCount > 2) + { + // Correct the LElement so that it points to the second row + // + // Note, that ff there is just one partial row, it does not matter that + // the LElement will remain pointing at the first row, + // since the former is not going to be used in that case. + ptrLElement -= /*(sizeint)*/rowSkip/* * (loopX1RowCount - 2)*/; dIASSERT(loopX1RowCount == 3); + } + dSASSERT(block_step == 4); + + rowEndReached = true; + break; + } + + // Take a look if any more columns have been completed... + completedBlocks = refBlockCompletionProgress; + dIASSERT(completedBlocks >= finalColumnBlock); + + if (completedBlocks == finalColumnBlock) + { + break; + } + + std::fill(tempZ, tempZ + loopX1RowCount, REAL(0.0)); + partialRow = 0; + + // Correct the LElement pointer to continue at the first partial row + ptrLElement -= (sizeint)rowSkip * (loopX1RowCount - 1); + + // ...continue if so. + columnCompletedSoFar = finalColumnBlock; + finalColumnBlock = dMACRO_MIN(currentBlock, completedBlocks); + } + else + { + ptrLElement += rowSkip - (finalColumnBlock - columnCompletedSoFar) * block_step; + ptrBElement -= (sizeint)((finalColumnBlock - columnCompletedSoFar) * block_step) * b_stride; + } + /* end of loop by individual rows */ + } + } + else + { + ptrLElement = L + (sizeint)(1/* + currentBlock * block_step*/) * rowSkip/* + completedColumnBlock * block_step*/; + ptrBElement = B/* + (sizeint)(completedColumnBlock * block_step) * b_stride*/; + dIASSERT(completedColumnBlock == 0); + + rowEndReached = true; + } + } + + if (rowEndReached) + { + // Check whether there is still a need to proceed or if the computation has been taken over by another thread + cellindexint oldDescriptor = MAKE_CELLDESCRIPTOR(completedColumnBlock, previousContextInstance, true); + + if (blockProgressDescriptors[currentBlock] == oldDescriptor) + { + /* finish computing the X(i) block */ + if (!partialBlock) + { + Y[0] = ptrBElement[0 * b_stride] - Z[0]; + + dReal p2 = ptrLElement[0]; + Y[1] = ptrBElement[1 * b_stride] - Z[1] - p2 * Y[0]; + + ptrLElement += rowSkip; + + dReal p3 = ptrLElement[0]; + dReal p3_1 = ptrLElement[1]; + Y[2] = ptrBElement[2 * b_stride] - Z[2] - p3 * Y[0] - p3_1 * Y[1]; + + dReal p4 = ptrLElement[rowSkip]; + dReal p4_1 = ptrLElement[1 + rowSkip]; + dReal p4_2 = ptrLElement[2 + rowSkip]; + Y[3] = ptrBElement[3 * b_stride] - Z[3] - p4 * Y[0] - p4_1 * Y[1] - p4_2 * Y[2]; + dSASSERT(block_step == 4); + } + else + { + Y[0] = ptrBElement[0 * b_stride] - Z[0]; + + if (loopX1RowCount >= 2) + { + dReal p2 = ptrLElement[0]; + Y[1] = ptrBElement[1 * b_stride] - Z[1] - p2 * Y[0]; + + if (loopX1RowCount > 2) + { + dReal p3 = ptrLElement[0 + rowSkip]; + dReal p3_1 = ptrLElement[1 + rowSkip]; + Y[2] = ptrBElement[2 * b_stride] - Z[2] - p3 * Y[0] - p3_1 * Y[1]; + } + } + dSASSERT(block_step == 4); + } + + // Use atomic memory barrier to make sure memory reads of ptrBElement[] and blockProgressDescriptors[] are not swapped + CooperativeAtomics::AtomicReadReorderBarrier(); + + // The descriptor has not been altered yet - this means the ptrBElement[] values used above were not modified yet + // and the computation result is valid. + if (blockProgressDescriptors[currentBlock] == oldDescriptor) + { + // Assign the results to the result context (possibly in parallel with other threads + // that could and ought to be assigning exactly the same values) + SolveL1StraightCellContext &resultContext = buildResultContextRef(cellContexts, currentBlock, blockCount); + resultContext.storePrecalculatedZs(Y); + + // Assign the result assignment progress descriptor + cellindexint newDescriptor = MAKE_CELLDESCRIPTOR(currentBlock + 1, CCI__MIN, true); + CooperativeAtomics::AtomicCompareExchangeCellindexint(&blockProgressDescriptors[currentBlock], oldDescriptor, newDescriptor); // the result is to be ignored + + // Whether succeeded or not, the result is valid, so go on trying to assign it to the matrix + goAssigningTheResult = true; + } + else + { + // Otherwise, go on competing for copying the results + handleComputationTakenOver = true; + } + } + else + { + handleComputationTakenOver = true; + } + } + else + { + // If the final column has not been reached yet, store current values to the context. + // Select the other context instance as the previous one might be read by other threads. + CellContextInstance nextContextInstance = buildNextContextInstance(previousContextInstance); + SolveL1StraightCellContext &destinationContext = buildBlockContextRef(cellContexts, currentBlock, nextContextInstance); + destinationContext.storePrecalculatedZs(Z); + + // Unlock the row until more columns can be used + cellindexint oldDescriptor = MAKE_CELLDESCRIPTOR(completedColumnBlock, previousContextInstance, true); + cellindexint newDescriptor = MAKE_CELLDESCRIPTOR(finalColumnBlock, nextContextInstance, false); + // The descriptor might have been updated by a competing thread + if (!CooperativeAtomics::AtomicCompareExchangeCellindexint(&blockProgressDescriptors[currentBlock], oldDescriptor, newDescriptor)) + { + // Adjust the ptrBElement to point to the result area... + ptrBElement = B + (sizeint)(currentBlock * block_step) * b_stride; + // ...and go on handling the case + handleComputationTakenOver = true; + } + } + + if (handleComputationTakenOver) + { + cellindexint existingDescriptor = blockProgressDescriptors[currentBlock]; + // This can only happen if the row was (has become) the uppermost not fully completed one + // and the competing thread is at final stage of calculation (i.e., it has reached the currentBlock column). + if (existingDescriptor != INVALID_CELLDESCRIPTOR) + { + // If not fully completed this must be the final stage of the result assignment into the matrix + dIASSERT(existingDescriptor == MAKE_CELLDESCRIPTOR(currentBlock + 1, CCI__MIN, true)); + + // Go on competing copying the result as anyway the block is the topmost not completed one + // and since there was competition for it, there is no other work that can be done right now. + const SolveL1StraightCellContext &resultContext = buildResultContextRef(cellContexts, currentBlock, blockCount); + resultContext.loadPrecalculatedZs(Y); + + goAssigningTheResult = true; + } + else + { + // everything is over -- just go handling next blocks + } + } + } + else if (goForLockedBlockDuplicateCalculation) + { + blockProcessingState = BPS_SOME_BLOCKS_PROCESSED; + + bool skipToHandlingSubsequentRows = false, skiptoCopyingResult = false; + + /* declare variables */ + const dReal *ptrLElement; + + if (completedColumnBlock < currentBlock) + { + /* check if this is not the partial block of fewer rows */ + if (currentBlock != lastBlock || loopX1RowCount == 0) + { + partialBlock = false; + + ptrLElement = L + (sizeint)(1 + currentBlock * block_step) * rowSkip + completedColumnBlock * block_step; + ptrBElement = B + (sizeint)(completedColumnBlock * block_step) * b_stride; + + /* the inner loop that computes outer products and adds them to Z */ + unsigned finalColumnBlock = currentBlock; + dIASSERT(currentBlock == completedBlocks); // Why would we be competing for a row otherwise? + + unsigned lastCompletedColumn = completedColumnBlock; + unsigned columnCounter = finalColumnBlock - completedColumnBlock; + for (bool exitInnerLoop = false; !exitInnerLoop; exitInnerLoop = --columnCounter == 0) + { + dReal q1, p1, p2, p3, p4; + + /* load p and q values */ + q1 = ptrBElement[0 * b_stride]; + p1 = (ptrLElement - rowSkip)[0]; + p2 = ptrLElement[0]; + ptrLElement += rowSkip; + p3 = ptrLElement[0]; + p4 = ptrLElement[0 + rowSkip]; + + /* compute outer product and add it to the Z matrix */ + Z[0] += p1 * q1; + Z[1] += p2 * q1; + Z[2] += p3 * q1; + Z[3] += p4 * q1; + + /* load p and q values */ + q1 = ptrBElement[1 * b_stride]; + p3 = ptrLElement[1]; + p4 = ptrLElement[1 + rowSkip]; + ptrLElement -= rowSkip; + p1 = (ptrLElement - rowSkip)[1]; + p2 = ptrLElement[1]; + + /* compute outer product and add it to the Z matrix */ + Z[0] += p1 * q1; + Z[1] += p2 * q1; + Z[2] += p3 * q1; + Z[3] += p4 * q1; + + /* load p and q values */ + q1 = ptrBElement[2 * b_stride]; + p1 = (ptrLElement - rowSkip)[2]; + p2 = ptrLElement[2]; + ptrLElement += rowSkip; + p3 = ptrLElement[2]; + p4 = ptrLElement[2 + rowSkip]; + + /* compute outer product and add it to the Z matrix */ + Z[0] += p1 * q1; + Z[1] += p2 * q1; + Z[2] += p3 * q1; + Z[3] += p4 * q1; + + /* load p and q values */ + q1 = ptrBElement[3 * b_stride]; + p3 = ptrLElement[3]; + p4 = ptrLElement[3 + rowSkip]; + ptrLElement -= rowSkip; + p1 = (ptrLElement - rowSkip)[3]; + p2 = ptrLElement[3]; + + /* compute outer product and add it to the Z matrix */ + Z[0] += p1 * q1; + Z[1] += p2 * q1; + Z[2] += p3 * q1; + Z[3] += p4 * q1; + dSASSERT(block_step == 4); + + // Check if the primary solver thread has not made any progress + cellindexint descriptorVerification = blockProgressDescriptors[currentBlock]; + unsigned newCompletedColumn = GET_CELLDESCRIPTOR_COLUMNINDEX(descriptorVerification); + + if (newCompletedColumn != lastCompletedColumn) + { + // Check, this is the first change the current thread detects. + // There is absolutely no reason in code for the computation to stop/resume twice + // while the current thread is competing. + dIASSERT(lastCompletedColumn == completedColumnBlock); + + if (descriptorVerification == INVALID_CELLDESCRIPTOR) + { + skipToHandlingSubsequentRows = true; + break; + } + + if (newCompletedColumn == currentBlock + 1) + { + skiptoCopyingResult = true; + break; + } + + // Check if the current thread is behind + if (newCompletedColumn > finalColumnBlock - columnCounter) + { + // If so, go starting over one more time + blockProcessingState = BPS_COMPETING_FOR_A_BLOCK; + stayWithinTheBlock = true; + skipToHandlingSubsequentRows = true; + break; + } + + // If current thread is ahead, just save new completed column for further comparisons and go on calculating + lastCompletedColumn = newCompletedColumn; + } + + /* advance pointers */ + ptrLElement += block_step; + ptrBElement += block_step * b_stride; + /* end of inner loop */ + } + } + else + { + partialBlock = true; + + dReal tempZ[dMACRO_MAX(block_step - 1U, 1U)] = { REAL(0.0), }; + + ptrLElement = L + (sizeint)(/*1 + */currentBlock * block_step) * rowSkip + completedColumnBlock * block_step; + ptrBElement = B + (sizeint)(completedColumnBlock * block_step) * b_stride; + + /* the inner loop that computes outer products and adds them to Z */ + unsigned finalColumnBlock = currentBlock; + dIASSERT(currentBlock == completedBlocks); // Why would we be competing for a row otherwise? + + unsigned lastCompletedColumn = completedColumnBlock; + for (unsigned columnCounter = finalColumnBlock - completedColumnBlock; ; ) + { + dReal q1, q2, q3, q4; + + /* load q values */ + q1 = ptrBElement[0 * b_stride]; + q2 = ptrBElement[1 * b_stride]; + q3 = ptrBElement[2 * b_stride]; + q4 = ptrBElement[3 * b_stride]; + + for (unsigned partialRow = 0; ; ) + { + dReal p1, p2, p3, p4; + + /* load p values */ + p1 = ptrLElement[0]; + p2 = ptrLElement[1]; + p3 = ptrLElement[2]; + p4 = ptrLElement[3]; + + /* compute outer product and add it to the Z matrix */ + tempZ[partialRow] += p1 * q1 + p2 * q2 + p3 * q3 + p4 * q4; + dSASSERT(block_step == 4); + + if (++partialRow == loopX1RowCount) + { + break; + } + + ptrLElement += rowSkip; + } + + // Check if the primary solver thread has not made any progress + cellindexint descriptorVerification = blockProgressDescriptors[currentBlock]; + unsigned newCompletedColumn = GET_CELLDESCRIPTOR_COLUMNINDEX(descriptorVerification); + + if (newCompletedColumn != lastCompletedColumn) + { + // Check, this is the first change the current thread detects. + // There is absolutely no reason in code for the computation to stop/resume twice + // while the current thread is competing. + dIASSERT(lastCompletedColumn == completedColumnBlock); + + if (descriptorVerification == INVALID_CELLDESCRIPTOR) + { + skipToHandlingSubsequentRows = true; + break; + } + + if (newCompletedColumn == currentBlock + 1) + { + skiptoCopyingResult = true; + break; + } + + // Check if the current thread is behind + if (newCompletedColumn > finalColumnBlock - columnCounter) + { + // If so, go starting over one more time + blockProcessingState = BPS_COMPETING_FOR_A_BLOCK; + stayWithinTheBlock = true; + skipToHandlingSubsequentRows = true; + break; + } + + // If current thread is ahead, just save new completed column for further comparisons and go on calculating + lastCompletedColumn = newCompletedColumn; + } + + ptrLElement += block_step; + ptrBElement += block_step * b_stride; + + if (--columnCounter == 0) + { + // Here switch is used to avoid accessing Z by parametrized index. + // So far all the accesses were performed by explicit constants + // what lets the compiler treat Z elements as individual variables + // rather than array elements. + Z[0] += tempZ[0]; + + if (loopX1RowCount >= 2) + { + Z[1] += tempZ[1]; + + if (loopX1RowCount > 2) + { + Z[2] += tempZ[2]; + + // Correct the LElement so that it points to the second row + // + // Note, that if there is just one partial row, it does not matter that + // the LElement will remain pointing at the first row, + // since the former is not going to be used in that case. + ptrLElement -= /*(sizeint)*/rowSkip/* * (loopX1RowCount - 2)*/; dIASSERT(loopX1RowCount == 3); + } + } + dSASSERT(block_step == 4); + + break; + } + + /* advance pointers */ + ptrLElement -= (sizeint)rowSkip * (loopX1RowCount - 1); + /* end of inner loop */ + } + } + } + else if (completedColumnBlock > currentBlock) + { + dIASSERT(completedColumnBlock == currentBlock + 1); + + partialBlock = currentBlock == lastBlock && loopX1RowCount != 0; + + skiptoCopyingResult = true; + } + else + { + dIASSERT(currentBlock == 0); // Execution can get here within the very first block only + + partialBlock = rowCount < block_step; + + /* assign the pointers appropriately and go on computing the results */ + ptrLElement = L + (sizeint)(1/* + currentBlock * block_step*/) * rowSkip/* + completedColumnBlock * block_step*/; + ptrBElement = B/* + (sizeint)(completedColumnBlock * block_step) * b_stride*/; + } + + if (!skipToHandlingSubsequentRows) + { + if (!skiptoCopyingResult) + { + if (!partialBlock) + { + Y[0] = ptrBElement[0 * b_stride] - Z[0]; + + dReal p2 = ptrLElement[0]; + Y[1] = ptrBElement[1 * b_stride] - Z[1] - p2 * Y[0]; + + ptrLElement += rowSkip; + + dReal p3 = ptrLElement[0]; + dReal p3_1 = ptrLElement[1]; + Y[2] = ptrBElement[2 * b_stride] - Z[2] - p3 * Y[0] - p3_1 * Y[1]; + + dReal p4 = ptrLElement[rowSkip]; + dReal p4_1 = ptrLElement[1 + rowSkip]; + dReal p4_2 = ptrLElement[2 + rowSkip]; + Y[3] = ptrBElement[3 * b_stride] - Z[3] - p4 * Y[0] - p4_1 * Y[1] - p4_2 * Y[2]; + dSASSERT(block_step == 4); + } + else + { + Y[0] = ptrBElement[0 * b_stride] - Z[0]; + + if (loopX1RowCount >= 2) + { + dReal p2 = ptrLElement[0]; + Y[1] = ptrBElement[1 * b_stride] - Z[1] - p2 * Y[0]; + + if (loopX1RowCount > 2) + { + dReal p3 = ptrLElement[0 + rowSkip]; + dReal p3_1 = ptrLElement[1 + rowSkip]; + Y[2] = ptrBElement[2 * b_stride] - Z[2] - p3 * Y[0] - p3_1 * Y[1]; + } + } + dSASSERT(block_step == 4); + } + + CooperativeAtomics::AtomicReadReorderBarrier(); + + // Use atomic load to make sure memory reads of ptrBElement[] and blockProgressDescriptors[] are not swapped + cellindexint existingDescriptor = blockProgressDescriptors[currentBlock]; + + if (existingDescriptor == INVALID_CELLDESCRIPTOR) + { + // Everything is over -- proceed to subsequent rows + skipToHandlingSubsequentRows = true; + } + else if (existingDescriptor == MAKE_CELLDESCRIPTOR(currentBlock + 1, CCI__MIN, true)) + { + // The values computed above may not be valid. Copy the values already in the result context. + skiptoCopyingResult = true; + } + else + { + // The descriptor has not been altered yet - this means the ptrBElement[] values used above were not modified yet + // and the computation result is valid. + cellindexint newDescriptor = MAKE_CELLDESCRIPTOR(currentBlock + 1, CCI__MIN, true); // put the computation at the top so that the evaluation result from the expression above is reused + + // Assign the results to the result context (possibly in parallel with other threads + // that could and ought to be assigning exactly the same values) + SolveL1StraightCellContext &resultContext = buildResultContextRef(cellContexts, currentBlock, blockCount); + resultContext.storePrecalculatedZs(Y); + + // Assign the result assignment progress descriptor + CooperativeAtomics::AtomicCompareExchangeCellindexint(&blockProgressDescriptors[currentBlock], existingDescriptor, newDescriptor); // the result is to be ignored + + // Whether succeeded or not, the result is valid, so go on trying to assign it to the matrix + } + } + + if (!skipToHandlingSubsequentRows) + { + if (skiptoCopyingResult) + { + // Extract the result values stored in the result context + const SolveL1StraightCellContext &resultContext = buildResultContextRef(cellContexts, currentBlock, blockCount); + resultContext.loadPrecalculatedZs(Y); + + ptrBElement = B + (sizeint)(currentBlock * block_step) * b_stride; + } + + goAssigningTheResult = true; + } + } + } + + if (goAssigningTheResult) + { + cellindexint existingDescriptor = blockProgressDescriptors[currentBlock]; + // Check if the assignment has not been completed yet + if (existingDescriptor != INVALID_CELLDESCRIPTOR) + { + // Assign the computation results to the B vector + if (!partialBlock) + { + ptrBElement[0 * b_stride] = Y[0]; + ptrBElement[1 * b_stride] = Y[1]; + ptrBElement[2 * b_stride] = Y[2]; + ptrBElement[3 * b_stride] = Y[3]; + dSASSERT(block_step == 4); + } + else + { + ptrBElement[0 * b_stride] = Y[0]; + + if (loopX1RowCount >= 2) + { + ptrBElement[1 * b_stride] = Y[1]; + + if (loopX1RowCount > 2) + { + ptrBElement[2 * b_stride] = Y[2]; + } + } + dSASSERT(block_step == 4); + } + + ThrsafeIncrementIntUpToLimit(&refBlockCompletionProgress, currentBlock + 1); + dIASSERT(refBlockCompletionProgress >= currentBlock + 1); + + // And assign the completed status no matter what + CooperativeAtomics::AtomicStoreCellindexint(&blockProgressDescriptors[currentBlock], INVALID_CELLDESCRIPTOR); + } + else + { + // everything is over -- just go handling next blocks + } + } + + if (!stayWithinTheBlock) + { + completedBlocks = refBlockCompletionProgress; + + if (completedBlocks == blockCount) + { + break; + } + + currentBlock += 1; + + bool lookaheadBoundaryReached = false; + + if (currentBlock == blockCount || completedBlocks == 0) + { + lookaheadBoundaryReached = true; + } + else if (currentBlock >= completedBlocks + lookaheadRange) + { + lookaheadBoundaryReached = blockProcessingState > BPS_NO_BLOCKS_PROCESSED; + } + else if (currentBlock < completedBlocks) + { + // Treat detected row advancement as a row processed + // blockProcessingState = BPS_SOME_BLOCKS_PROCESSED; <-- performs better without it + + currentBlock = completedBlocks; + } + + if (lookaheadBoundaryReached) + { + dIASSERT(blockProcessingState != BPS_COMPETING_FOR_A_BLOCK); // Why did not we compete??? + + // If no row has been processed in the previous pass, compete for the next row to avoid cycling uselessly + if (blockProcessingState <= BPS_NO_BLOCKS_PROCESSED) + { + // Abandon job if too few blocks remain + if (blockCount - completedBlocks <= ownThreadIndex) + { + break; + } + + blockProcessingState = BPS_COMPETING_FOR_A_BLOCK; + } + else + { + // If there was some progress, just continue to the next pass + blockProcessingState = BPS_NO_BLOCKS_PROCESSED; + } + + currentBlock = completedBlocks; + } + } + } +} + + +#endif diff --git a/libs/ode-0.16.1/ode/src/fastltsolve.cpp b/libs/ode-0.16.1/ode/src/fastltsolve.cpp new file mode 100644 index 0000000..e9c7ec5 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/fastltsolve.cpp @@ -0,0 +1,229 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * L1Transposed Equation Solving Routines + * Copyright (c) 2017-2019 Oleh Derevenko, odar@eleks.com (change all "a" to "e") + */ + +#include <ode/common.h> +#include <ode/matrix.h> +#include <ode/matrix_coop.h> +#include "config.h" +#include "threaded_solver_ldlt.h" +#include "threading_base.h" +#include "resource_control.h" +#include "error.h" + +#include "fastltsolve_impl.h" + + +/*static */ +void ThreadedEquationSolverLDLT::estimateCooperativeSolvingL1TransposedResourceRequirements( + dxResourceRequirementDescriptor *summaryRequirementsDescriptor, + unsigned allowedThreadCount, unsigned rowCount) +{ + dxThreadingBase *threading = summaryRequirementsDescriptor->getrelatedThreading(); + unsigned limitedThreadCount = restrictSolvingL1TransposedAllowedThreadCount(threading, allowedThreadCount, rowCount); + + if (limitedThreadCount > 1) + { + doEstimateCooperativeSolvingL1TransposedResourceRequirementsValidated(summaryRequirementsDescriptor, allowedThreadCount, rowCount); + } +} + +/*static */ +void ThreadedEquationSolverLDLT::cooperativelySolveL1Transposed( + dxRequiredResourceContainer *resourceContainer, unsigned allowedThreadCount, + const dReal *L, dReal *b, unsigned rowCount, unsigned rowSkip) +{ + dIASSERT(rowCount != 0); + + dxThreadingBase *threading = resourceContainer->getThreadingInstance(); + unsigned limitedThreadCount = restrictSolvingL1TransposedAllowedThreadCount(threading, allowedThreadCount, rowCount); + + if (limitedThreadCount <= 1) + { + solveL1Transposed<SL1T_B_STRIDE>(L, b, rowCount, rowSkip); + } + else + { + doCooperativelySolveL1TransposedValidated(resourceContainer, limitedThreadCount, L, b, rowCount, rowSkip); + } +} + + +/*static */ +unsigned ThreadedEquationSolverLDLT::restrictSolvingL1TransposedAllowedThreadCount( + dxThreadingBase *threading, unsigned allowedThreadCount, unsigned rowCount) +{ + unsigned limitedThreadCount = 1; + +#if dCOOPERATIVE_ENABLED + const unsigned int blockStep = SL1T_BLOCK_SIZE; // Required by the implementation + unsigned solvingBlockCount = deriveSolvingL1TransposedBlockCount(rowCount, blockStep); + dIASSERT(deriveSolvingL1TransposedThreadCount(SL1T_COOPERATIVE_BLOCK_COUNT_MINIMUM, 2) > 1); + + if (solvingBlockCount >= SL1T_COOPERATIVE_BLOCK_COUNT_MINIMUM) + { + limitedThreadCount = threading->calculateThreadingLimitedThreadCount(allowedThreadCount, true); + } +#endif // #if dCOOPERATIVE_ENABLED + + return limitedThreadCount; +} + +/*static */ +void ThreadedEquationSolverLDLT::doEstimateCooperativeSolvingL1TransposedResourceRequirementsValidated( + dxResourceRequirementDescriptor *summaryRequirementsDescriptor, + unsigned allowedThreadCount, unsigned rowCount) +{ + const unsigned int blockStep = SL1T_BLOCK_SIZE; // Required by the implementation + unsigned blockCount = deriveSolvingL1TransposedBlockCount(rowCount, blockStep); + dIASSERT(blockCount >= 1); + + unsigned threadCountToUse = deriveSolvingL1TransposedThreadCount(blockCount, allowedThreadCount); + dIASSERT(threadCountToUse > 1); + + unsigned simultaneousCallCount = 1 + (threadCountToUse - 1); + + SolvingL1TransposedMemoryEstimates solvingMemoryEstimates; + sizeint solvingMemoryRequired = estimateCooperativelySolvingL1TransposedMemoryRequirement<blockStep>(rowCount, solvingMemoryEstimates); + const unsigned solvingAlignmentRequired = ALLOCATION_DEFAULT_ALIGNMENT; + + unsigned featureRequirement = dxResourceRequirementDescriptor::STOCK_CALLWAIT_REQUIRED; + summaryRequirementsDescriptor->mergeAnotherDescriptorIn(solvingMemoryRequired, solvingAlignmentRequired, simultaneousCallCount, featureRequirement); +} + +/*static */ +void ThreadedEquationSolverLDLT::doCooperativelySolveL1TransposedValidated( + dxRequiredResourceContainer *resourceContainer, unsigned allowedThreadCount, + const dReal *L, dReal *b, unsigned rowCount, unsigned rowSkip) +{ + dIASSERT(allowedThreadCount > 1); + + const unsigned int blockStep = SL1T_BLOCK_SIZE; // Required by the implementation + unsigned blockCount = deriveSolvingL1TransposedBlockCount(rowCount, blockStep); + dIASSERT(blockCount >= 1); + + unsigned threadCountToUse = deriveSolvingL1TransposedThreadCount(blockCount, allowedThreadCount); + dIASSERT(threadCountToUse > 1); + + dCallWaitID completionWait = resourceContainer->getStockCallWait(); + dAASSERT(completionWait != NULL); + + atomicord32 blockCompletionProgress; + cellindexint *blockProgressDescriptors; + SolveL1TransposedCellContext *cellContexts; + + SolvingL1TransposedMemoryEstimates solvingMemoryEstimates; + sizeint solvingMemoryRequired = estimateCooperativelySolvingL1TransposedMemoryRequirement<blockStep>(rowCount, solvingMemoryEstimates); + dIASSERT(solvingMemoryRequired <= resourceContainer->getMemoryBufferSize()); + + void *bufferAllocated = resourceContainer->getMemoryBufferPointer(); + dIASSERT(bufferAllocated != NULL); + dIASSERT(dALIGN_PTR(bufferAllocated, ALLOCATION_DEFAULT_ALIGNMENT) == bufferAllocated); + + void *bufferCurrentLocation = bufferAllocated; + bufferCurrentLocation = markCooperativelySolvingL1TransposedMemoryStructuresOut(bufferCurrentLocation, solvingMemoryEstimates, blockProgressDescriptors, cellContexts); + dIVERIFY(bufferCurrentLocation <= (uint8 *)bufferAllocated + solvingMemoryRequired); + + initializeCooperativelySolveL1TransposedMemoryStructures<blockStep>(rowCount, blockCompletionProgress, blockProgressDescriptors, cellContexts); + + dCallReleaseeID calculationFinishReleasee; + SolveL1TransposedWorkerContext workerContext; // The variable must exist in the outer scope + + workerContext.init(L, b, rowCount, rowSkip, blockCompletionProgress, blockProgressDescriptors, cellContexts); + + dxThreadingBase *threading = resourceContainer->getThreadingInstance(); + threading->PostThreadedCall(NULL, &calculationFinishReleasee, threadCountToUse - 1, NULL, completionWait, &solveL1Transposed_completion_callback, NULL, 0, "SolveL1Transposed Completion"); + threading->PostThreadedCallsGroup(NULL, threadCountToUse - 1, calculationFinishReleasee, &solveL1Transposed_worker_callback, &workerContext, "SolveL1Transposed Work"); + + participateSolvingL1Transposed<blockStep, SL1T_B_STRIDE>(L, b, rowCount, rowSkip, blockCompletionProgress, blockProgressDescriptors, cellContexts, threadCountToUse - 1); + + threading->WaitThreadedCallExclusively(NULL, completionWait, NULL, "SolveL1Transposed End Wait"); +} + +/*static */ +int ThreadedEquationSolverLDLT::solveL1Transposed_worker_callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID dUNUSED(callThisReleasee)) +{ + SolveL1TransposedWorkerContext *ptrContext = (SolveL1TransposedWorkerContext *)callContext; + + solveL1Transposed_worker(*ptrContext, dCAST_TO_SMALLER(unsigned, callInstanceIndex)); + + return 1; +} + +/*static */ +void ThreadedEquationSolverLDLT::solveL1Transposed_worker(SolveL1TransposedWorkerContext &ref_context, unsigned ownThreadIndex) +{ + const unsigned blockStep = SL1T_BLOCK_SIZE; + participateSolvingL1Transposed<blockStep, SL1T_B_STRIDE>(ref_context.m_L, ref_context.m_b, ref_context.m_rowCount, ref_context.m_rowSkip, + *ref_context.m_ptrBlockCompletionProgress, ref_context.m_blockProgressDescriptors, ref_context.m_cellContexts, ownThreadIndex); +} + +/*static */ +int ThreadedEquationSolverLDLT::solveL1Transposed_completion_callback(void *dUNUSED(callContext), dcallindex_t dUNUSED(callInstanceIndex), dCallReleaseeID dUNUSED(callThisReleasee)) +{ + return 1; +} + + + +////////////////////////////////////////////////////////////////////////// +// Public interface functions + +/*extern ODE_API */ +void dSolveL1T(const dReal *L, dReal *B, int rowCount, int rowSkip) +{ + dAASSERT(rowCount != 0); + + if (rowCount != 0) + { + dAASSERT(L != NULL); + dAASSERT(B != NULL); + + solveL1Transposed<1>(L, B, rowCount, rowSkip); + } +} + + +/*extern ODE_API */ +void dEstimateCooperativelySolveL1TransposedResourceRequirements(dResourceRequirementsID requirements, + unsigned maximalAllowedThreadCount, unsigned maximalRowCount) +{ + dAASSERT(requirements != NULL); + + dxResourceRequirementDescriptor *requirementsDescriptor = (dxResourceRequirementDescriptor *)requirements; + ThreadedEquationSolverLDLT::estimateCooperativeSolvingL1TransposedResourceRequirements(requirementsDescriptor, maximalAllowedThreadCount, maximalRowCount); +} + +/*extern ODE_API */ +void dCooperativelySolveL1Transposed(dResourceContainerID resources, unsigned allowedThreadCount, + const dReal *L, dReal *b, unsigned rowCount, unsigned rowSkip) +{ + dAASSERT(resources != NULL); + + dxRequiredResourceContainer *resourceContainer = (dxRequiredResourceContainer *)resources; + ThreadedEquationSolverLDLT::cooperativelySolveL1Transposed(resourceContainer, allowedThreadCount, L, b, rowCount, rowSkip); +} + diff --git a/libs/ode-0.16.1/ode/src/fastltsolve_impl.h b/libs/ode-0.16.1/ode/src/fastltsolve_impl.h new file mode 100644 index 0000000..ca30d9c --- /dev/null +++ b/libs/ode-0.16.1/ode/src/fastltsolve_impl.h @@ -0,0 +1,1440 @@ + + +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * Code style improvements and optimizations by Oleh Derevenko ????-2019 + * L1Transposed cooperative solving code of ThreadedEquationSolverLDLT copyright (c) 2017-2019 Oleh Derevenko, odar@eleks.com (change all "a" to "e") + */ + + +#ifndef _ODE_FASTLTSOLVE_IMPL_H_ +#define _ODE_FASTLTSOLVE_IMPL_H_ + + +/* solve L^T * x=b, with b containing 1 right hand side. + * L is an n*n lower triangular matrix with ones on the diagonal. + * L is stored by rows and its leading dimension is rowSkip. + * b is an n*1 matrix that contains the right hand side. + * b is overwritten with x. + * this processes blocks of 4. + */ + +template<unsigned int b_stride> +void solveL1Transposed(const dReal *L, dReal *B, unsigned rowCount, unsigned rowSkip) +{ + dIASSERT(rowCount != 0); + + /* special handling for L and B because we're solving L1 *transpose* */ + const dReal *lastLElement = L + (sizeint)(rowCount - 1) * (rowSkip + 1); + dReal *lastBElement = B + (sizeint)(rowCount - 1) * b_stride; + + /* compute rows at end that are not a multiple of block size */ + const unsigned loopX1RowCount = rowCount % 4; + + unsigned blockStartRow = loopX1RowCount; + bool subsequentPass = false; + + /* compute rightmost bottom X(i) block */ + if (loopX1RowCount != 0) + { + subsequentPass = true; + + const dReal *ptrLElement = lastLElement; + dReal *ptrBElement = lastBElement; + + dReal Y11 = ptrBElement[0 * b_stride]/* - Z11*/; + // ptrBElement[0 * b_stride] = Y11; -- unchanged + + if (loopX1RowCount >= 2) + { + dReal p2 = ptrLElement[-1]; + dReal Y21 = ptrBElement[-1 * (int)b_stride]/* - Z21 */- p2 * Y11; + ptrBElement[-1 * (int)b_stride] = Y21; + + if (loopX1RowCount > 2) + { + dReal p3 = ptrLElement[-2]; + dReal p3_1 = (ptrLElement - rowSkip)[-2]; + dReal Y31 = ptrBElement[-2 * (int)b_stride]/* - Z31 */- p3 * Y11 - p3_1 * Y21; + ptrBElement[-2 * (int)b_stride] = Y31; + } + } + } + + /* compute all 4 x 1 blocks of X */ + for (; !subsequentPass || blockStartRow < rowCount; subsequentPass = true, blockStartRow += 4) + { + /* compute all 4 x 1 block of X, from rows i..i+4-1 */ + + /* declare variables - Z matrix, p and q vectors, etc */ + const dReal *ptrLElement; + dReal *ptrBElement; + + dReal Z41, Z31, Z21, Z11; + + if (subsequentPass) + { + ptrLElement = lastLElement - blockStartRow; + ptrBElement = lastBElement; + + /* set the Z matrix to 0 */ + Z41 = 0; Z31 = 0; Z21 = 0; Z11 = 0; + + unsigned rowCounter = blockStartRow; + + if (rowCounter % 2 != 0) + { + dReal q1, p4, p3, p2, p1; + + /* load p and q values */ + q1 = ptrBElement[0 * (int)b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z41 += p4 * q1; + Z31 += p3 * q1; + Z21 += p2 * q1; + Z11 += p1 * q1; + + ptrBElement -= 1 * b_stride; + rowCounter -= 1; + } + + if (rowCounter % 4 != 0) + { + dReal q1, p4, p3, p2, p1; + + /* load p and q values */ + q1 = ptrBElement[0 * (int)b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z41 += p4 * q1; + Z31 += p3 * q1; + Z21 += p2 * q1; + Z11 += p1 * q1; + + /* load p and q values */ + q1 = ptrBElement[-1 * (int)b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z41 += p4 * q1; + Z31 += p3 * q1; + Z21 += p2 * q1; + Z11 += p1 * q1; + + ptrBElement -= 2 * b_stride; + rowCounter -= 2; + } + + /* the inner loop that computes outer products and adds them to Z */ + for (bool exitLoop = rowCounter == 0; !exitLoop; exitLoop = false) + { + dReal q1, p4, p3, p2, p1; + + /* load p and q values */ + q1 = ptrBElement[0 * (int)b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z41 += p4 * q1; + Z31 += p3 * q1; + Z21 += p2 * q1; + Z11 += p1 * q1; + + /* load p and q values */ + q1 = ptrBElement[-1 * (int)b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z41 += p4 * q1; + Z31 += p3 * q1; + Z21 += p2 * q1; + Z11 += p1 * q1; + + /* load p and q values */ + q1 = ptrBElement[-2 * (int)b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z41 += p4 * q1; + Z31 += p3 * q1; + Z21 += p2 * q1; + Z11 += p1 * q1; + + /* load p and q values */ + q1 = ptrBElement[-3 * (int)b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z41 += p4 * q1; + Z31 += p3 * q1; + Z21 += p2 * q1; + Z11 += p1 * q1; + + if (rowCounter > 12) + { + rowCounter -= 12; + + ptrBElement -= 12 * b_stride; + + /* load p and q values */ + q1 = ptrBElement[8 * b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z41 += p4 * q1; + Z31 += p3 * q1; + Z21 += p2 * q1; + Z11 += p1 * q1; + + /* load p and q values */ + q1 = ptrBElement[7 * b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z41 += p4 * q1; + Z31 += p3 * q1; + Z21 += p2 * q1; + Z11 += p1 * q1; + + /* load p and q values */ + q1 = ptrBElement[6 * b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z41 += p4 * q1; + Z31 += p3 * q1; + Z21 += p2 * q1; + Z11 += p1 * q1; + + /* load p and q values */ + q1 = ptrBElement[5 * b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z41 += p4 * q1; + Z31 += p3 * q1; + Z21 += p2 * q1; + Z11 += p1 * q1; + + /* load p and q values */ + q1 = ptrBElement[4 * b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z41 += p4 * q1; + Z31 += p3 * q1; + Z21 += p2 * q1; + Z11 += p1 * q1; + + /* load p and q values */ + q1 = ptrBElement[3 * b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z41 += p4 * q1; + Z31 += p3 * q1; + Z21 += p2 * q1; + Z11 += p1 * q1; + + /* load p and q values */ + q1 = ptrBElement[2 * b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z41 += p4 * q1; + Z31 += p3 * q1; + Z21 += p2 * q1; + Z11 += p1 * q1; + + /* load p and q values */ + q1 = ptrBElement[1 * b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z41 += p4 * q1; + Z31 += p3 * q1; + Z21 += p2 * q1; + Z11 += p1 * q1; + } + else + { + ptrBElement -= 4 * b_stride; + + if ((rowCounter -= 4) == 0) + { + break; + } + } + /* end of inner loop */ + } + } + else + { + ptrLElement = lastLElement/* - blockStartRow*/; dIASSERT(blockStartRow == 0); + ptrBElement = lastBElement; + + /* set the Z matrix to 0 */ + Z41 = 0; Z31 = 0; Z21 = 0; Z11 = 0; + } + + /* finish computing the X(i) block */ + dReal Y11, Y21, Y31, Y41; + { + Y11 = ptrBElement[0 * b_stride] - Z11; + ptrBElement[0 * b_stride] = Y11; + } + { + dReal p2 = ptrLElement[-1]; + Y21 = ptrBElement[-1 * (int)b_stride] - Z21 - p2 * Y11; + ptrBElement[-1 * (int)b_stride] = Y21; + } + { + dReal p3 = ptrLElement[-2]; + dReal p3_1 = (ptrLElement - rowSkip)[-2]; + Y31 = ptrBElement[-2 * (int)b_stride] - Z31 - p3 * Y11 - p3_1 * Y21; + ptrBElement[-2 * (int)b_stride] = Y31; + } + { + dReal p4 = ptrLElement[-3]; + dReal p4_1 = (ptrLElement - rowSkip)[-3]; + dReal p4_2 = (ptrLElement - rowSkip * 2)[-3]; + Y41 = ptrBElement[-3 * (int)b_stride] - Z41 - p4 * Y11 - p4_1 * Y21 - p4_2 * Y31; + ptrBElement[-3 * (int)b_stride] = Y41; + } + /* end of outer loop */ + } +} + + + +template<unsigned int block_step> +/*static */ +sizeint ThreadedEquationSolverLDLT::estimateCooperativelySolvingL1TransposedMemoryRequirement(unsigned rowCount, SolvingL1TransposedMemoryEstimates &ref_solvingMemoryEstimates) +{ + unsigned blockCount = deriveSolvingL1TransposedBlockCount(rowCount, block_step); + sizeint descriptorSizeRequired = dEFFICIENT_SIZE(sizeof(cellindexint) * blockCount); + sizeint contextSizeRequired = dEFFICIENT_SIZE(sizeof(SolveL1TransposedCellContext) * (CCI__MAX + 1) * blockCount); + ref_solvingMemoryEstimates.assignData(descriptorSizeRequired, contextSizeRequired); + + sizeint totalSizeRequired = descriptorSizeRequired + contextSizeRequired; + return totalSizeRequired; +} + +template<unsigned int block_step> +/*static */ +void ThreadedEquationSolverLDLT::initializeCooperativelySolveL1TransposedMemoryStructures(unsigned rowCount, + atomicord32 &out_blockCompletionProgress, cellindexint *blockProgressDescriptors, SolveL1TransposedCellContext *dUNUSED(cellContexts)) +{ + unsigned blockCount = deriveSolvingL1TransposedBlockCount(rowCount, block_step); + + out_blockCompletionProgress = 0; + memset(blockProgressDescriptors, 0, blockCount * sizeof(*blockProgressDescriptors)); +} + +template<unsigned int block_step, unsigned int b_stride> +/*static */ +void ThreadedEquationSolverLDLT::participateSolvingL1Transposed(const dReal *L, dReal *B, unsigned rowCount, unsigned rowSkip, + volatile atomicord32 &refBlockCompletionProgress/*=0*/, volatile cellindexint *blockProgressDescriptors/*=[blockCount]*/, + SolveL1TransposedCellContext *cellContexts/*=[CCI__MAX x blockCount] + [blockCount]*/, unsigned ownThreadIndex) +{ + const unsigned lookaheadRange = 32; + const unsigned blockCount = deriveSolvingL1TransposedBlockCount(rowCount, block_step); + /* compute rows at end that are not a multiple of block size */ + const unsigned loopX1RowCount = rowCount % block_step; + + /* special handling for L and B because we're solving L1 *transpose* */ + const dReal *lastLElement = L + (rowCount - 1) * ((sizeint)rowSkip + 1); + dReal *lastBElement = B + (rowCount - 1) * (sizeint)b_stride; + + /* elements adjusted as if the last block was full block_step elements */ + unsigned x1AdjustmentElements = (block_step - loopX1RowCount) % block_step; + const dReal *columnAdjustedLastLElement = lastLElement + x1AdjustmentElements; + const dReal *fullyAdjustedLastLElement = columnAdjustedLastLElement + (sizeint)rowSkip * x1AdjustmentElements; + dReal *adjustedLastBElement = lastBElement + b_stride * x1AdjustmentElements; + + BlockProcessingState blockProcessingState = BPS_NO_BLOCKS_PROCESSED; + + unsigned completedBlocks = refBlockCompletionProgress; + unsigned currentBlock = completedBlocks; + dIASSERT(completedBlocks <= blockCount); + + for (bool exitLoop = completedBlocks == blockCount; !exitLoop; exitLoop = false) + { + bool goForLockedBlockPrimaryCalculation = false, goForLockedBlockDuplicateCalculation = false; + bool goAssigningTheResult = false, stayWithinTheBlock = false; + + dReal Z[block_step]; + dReal Y[block_step]; + + dReal *ptrBElement; + + CellContextInstance previousContextInstance; + unsigned completedRowBlock; + bool partialBlock; + + for (cellindexint testDescriptor = blockProgressDescriptors[currentBlock]; ; ) + { + if (testDescriptor == INVALID_CELLDESCRIPTOR) + { + // Invalid descriptor is the indication that the row has been fully calculated + // Test if this was the last row and break out if so. + if (currentBlock + 1 == blockCount) + { + exitLoop = true; + break; + } + + // Treat detected row advancement as a row processed + // blockProcessingState = BPS_SOME_BLOCKS_PROCESSED; <-- performs better without it + break; + } + + CooperativeAtomics::AtomicReadReorderBarrier(); + // It is necessary to read up to date completedBblocks value after the descriptor retrieval + // as otherwise the logic below breaks + completedBlocks = refBlockCompletionProgress; + + if (!GET_CELLDESCRIPTOR_ISLOCKED(testDescriptor)) + { + completedRowBlock = GET_CELLDESCRIPTOR_COLUMNINDEX(testDescriptor); + dIASSERT(completedRowBlock < currentBlock || (completedRowBlock == currentBlock && currentBlock == 0)); // Otherwise, why would the calculation have had stopped if the final column is reachable??? + dIASSERT(completedRowBlock <= completedBlocks); // Since the descriptor is not locked + + if (completedRowBlock == completedBlocks && currentBlock != completedBlocks) + { + dIASSERT(completedBlocks < currentBlock); + break; + } + + if (CooperativeAtomics::AtomicCompareExchangeCellindexint(&blockProgressDescriptors[currentBlock], testDescriptor, MARK_CELLDESCRIPTOR_LOCKED(testDescriptor))) + { + if (completedRowBlock != 0) + { + CellContextInstance contextInstance = GET_CELLDESCRIPTOR_CONTEXTINSTANCE(testDescriptor); + previousContextInstance = contextInstance; + + const SolveL1TransposedCellContext &sourceContext = buildBlockContextRef(cellContexts, currentBlock, contextInstance); + sourceContext.loadPrecalculatedZs(Z); + } + else + { + previousContextInstance = CCI__MIN; + SolveL1TransposedCellContext::initializePrecalculatedZs(Z); + } + + goForLockedBlockPrimaryCalculation = true; + break; + } + + if (blockProcessingState != BPS_COMPETING_FOR_A_BLOCK) + { + break; + } + + testDescriptor = blockProgressDescriptors[currentBlock]; + } + else + { + if (blockProcessingState != BPS_COMPETING_FOR_A_BLOCK) + { + break; + } + + cellindexint verificativeDescriptor; + bool verificationFailure = false; + + completedRowBlock = GET_CELLDESCRIPTOR_COLUMNINDEX(testDescriptor); + dIASSERT(completedRowBlock != currentBlock || currentBlock == 0); // There is no reason for computations to stop at the very end other than being the initial value at the very first block + + if (completedRowBlock != 0) + { + CellContextInstance contextInstance = GET_CELLDESCRIPTOR_CONTEXTINSTANCE(testDescriptor); + const SolveL1TransposedCellContext &sourceContext = buildBlockContextRef(cellContexts, currentBlock, contextInstance); + sourceContext.loadPrecalculatedZs(Z); + } + else + { + SolveL1TransposedCellContext::initializePrecalculatedZs(Z); + } + + if (completedRowBlock != 0 && completedRowBlock <= currentBlock) + { + // Make sure the descriptor is re-read after the precalculates + CooperativeAtomics::AtomicReadReorderBarrier(); + } + + if (completedRowBlock <= currentBlock) + { + verificativeDescriptor = blockProgressDescriptors[currentBlock]; + verificationFailure = verificativeDescriptor != testDescriptor; + } + + if (!verificationFailure) + { + dIASSERT(completedRowBlock <= currentBlock + 1); + + goForLockedBlockDuplicateCalculation = true; + break; + } + + testDescriptor = verificativeDescriptor; + } + } + + if (exitLoop) + { + break; + } + + if (goForLockedBlockPrimaryCalculation) + { + blockProcessingState = BPS_SOME_BLOCKS_PROCESSED; + + // Declare and assign the variables at the top to not interfere with any branching -- the compiler is going to eliminate them anyway. + bool handleComputationTakenOver = false, columnEndReached = false; + + const dReal *ptrLElement; + unsigned finalRowBlock; + + /* check if this is not the partial block of fewer rows */ + if (currentBlock != 0 || loopX1RowCount == 0) + { + partialBlock = false; + + ptrLElement = completedRowBlock != 0 + ? fullyAdjustedLastLElement - currentBlock * block_step - (sizeint)(completedRowBlock * block_step) * rowSkip + : columnAdjustedLastLElement - currentBlock * block_step; + ptrBElement = completedRowBlock != 0 + ? adjustedLastBElement - (sizeint)(completedRowBlock * block_step) * b_stride + : lastBElement; + + finalRowBlock = dMACRO_MIN(currentBlock, completedBlocks); + dIASSERT(finalRowBlock != completedRowBlock || finalRowBlock == 0); + + unsigned rowCounter = finalRowBlock - completedRowBlock; + bool exitLoop = rowCounter == 0; + + if (exitLoop) + { + columnEndReached = true; + } + else if (completedRowBlock == 0 && currentBlock != 0 && loopX1RowCount != 0) + { + if ((loopX1RowCount & 1) != 0) + { + dReal q1, p4, p3, p2, p1; + + /* load p and q values */ + q1 = ptrBElement[0 * (int)b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z[3] += p4 * q1; + Z[2] += p3 * q1; + Z[1] += p2 * q1; + Z[0] += p1 * q1; + + ptrBElement -= 1 * b_stride; + } + + if ((loopX1RowCount & 2) != 0) + { + dReal q1, p4, p3, p2, p1; + + /* load p and q values */ + q1 = ptrBElement[0 * (int)b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z[3] += p4 * q1; + Z[2] += p3 * q1; + Z[1] += p2 * q1; + Z[0] += p1 * q1; + + /* load p and q values */ + q1 = ptrBElement[-1 * (int)b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z[3] += p4 * q1; + Z[2] += p3 * q1; + Z[1] += p2 * q1; + Z[0] += p1 * q1; + + ptrBElement -= 2 * b_stride; + } + dSASSERT(block_step == 4); + + if (--rowCounter == 0) + { + do + { + if (finalRowBlock == currentBlock) + { + columnEndReached = true; + exitLoop = true; + break; + } + + // Take a look if any more columns have been completed... + completedBlocks = refBlockCompletionProgress; + dIASSERT(completedBlocks >= finalRowBlock); + + if (completedBlocks == finalRowBlock) + { + exitLoop = true; + break; + } + + // ...continue if so. + unsigned rowCompletedSoFar = finalRowBlock; + finalRowBlock = dMACRO_MIN(currentBlock, completedBlocks); + rowCounter = finalRowBlock - rowCompletedSoFar; + } + while (false); + } + } + + for (; !exitLoop; exitLoop = false) + { + dReal q1, p4, p3, p2, p1; + + /* load p and q values */ + q1 = ptrBElement[0 * (int)b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z[3] += p4 * q1; + Z[2] += p3 * q1; + Z[1] += p2 * q1; + Z[0] += p1 * q1; + + /* load p and q values */ + q1 = ptrBElement[-1 * (int)b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z[3] += p4 * q1; + Z[2] += p3 * q1; + Z[1] += p2 * q1; + Z[0] += p1 * q1; + + /* load p and q values */ + q1 = ptrBElement[-2 * (int)b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z[3] += p4 * q1; + Z[2] += p3 * q1; + Z[1] += p2 * q1; + Z[0] += p1 * q1; + + /* load p and q values */ + q1 = ptrBElement[-3 * (int)b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z[3] += p4 * q1; + Z[2] += p3 * q1; + Z[1] += p2 * q1; + Z[0] += p1 * q1; + dSASSERT(block_step == 4); + + if (rowCounter > 3) + { + rowCounter -= 3; + + ptrBElement -= 3 * block_step * b_stride; + + /* load p and q values */ + q1 = ptrBElement[8 * b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z[3] += p4 * q1; + Z[2] += p3 * q1; + Z[1] += p2 * q1; + Z[0] += p1 * q1; + + /* load p and q values */ + q1 = ptrBElement[7 * b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z[3] += p4 * q1; + Z[2] += p3 * q1; + Z[1] += p2 * q1; + Z[0] += p1 * q1; + + /* load p and q values */ + q1 = ptrBElement[6 * b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z[3] += p4 * q1; + Z[2] += p3 * q1; + Z[1] += p2 * q1; + Z[0] += p1 * q1; + + /* load p and q values */ + q1 = ptrBElement[5 * b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z[3] += p4 * q1; + Z[2] += p3 * q1; + Z[1] += p2 * q1; + Z[0] += p1 * q1; + + /* load p and q values */ + q1 = ptrBElement[4 * b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z[3] += p4 * q1; + Z[2] += p3 * q1; + Z[1] += p2 * q1; + Z[0] += p1 * q1; + + /* load p and q values */ + q1 = ptrBElement[3 * b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z[3] += p4 * q1; + Z[2] += p3 * q1; + Z[1] += p2 * q1; + Z[0] += p1 * q1; + + /* load p and q values */ + q1 = ptrBElement[2 * b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z[3] += p4 * q1; + Z[2] += p3 * q1; + Z[1] += p2 * q1; + Z[0] += p1 * q1; + + /* load p and q values */ + q1 = ptrBElement[1 * b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z[3] += p4 * q1; + Z[2] += p3 * q1; + Z[1] += p2 * q1; + Z[0] += p1 * q1; + dSASSERT(block_step == 4); + } + else + { + ptrBElement -= block_step * b_stride; + + if (--rowCounter == 0) + { + if (finalRowBlock == currentBlock) + { + columnEndReached = true; + break; + } + + // Take a look if any more columns have been completed... + completedBlocks = refBlockCompletionProgress; + dIASSERT(completedBlocks >= finalRowBlock); + + if (completedBlocks == finalRowBlock) + { + break; + } + + // ...continue if so. + unsigned rowCompletedSoFar = finalRowBlock; + finalRowBlock = dMACRO_MIN(currentBlock, completedBlocks); + rowCounter = finalRowBlock - rowCompletedSoFar; + } + } + /* end of inner loop */ + } + } + else /* compute rightmost bottom X(i) block */ + { + partialBlock = true; + + ptrLElement = lastLElement; + ptrBElement = lastBElement; + dIASSERT(completedRowBlock == 0); + + columnEndReached = true; + } + + if (columnEndReached) + { + // Check whether there is still a need to proceed or if the computation has been taken over by another thread + cellindexint oldDescriptor = MAKE_CELLDESCRIPTOR(completedRowBlock, previousContextInstance, true); + + if (blockProgressDescriptors[currentBlock] == oldDescriptor) + { + if (partialBlock) + { + Y[0] = ptrBElement[0 * b_stride]/* - Z[0]*/; + + if (loopX1RowCount >= 2) + { + dReal p2 = ptrLElement[-1]; + Y[1] = ptrBElement[-1 * (int)b_stride]/* - Z[1] */- p2 * Y[0]; + + if (loopX1RowCount > 2) + { + dReal p3 = ptrLElement[-2]; + dReal p3_1 = (ptrLElement - rowSkip)[-2]; + Y[2] = ptrBElement[-2 * (int)b_stride]/* - Z[2] */- p3 * Y[0] - p3_1 * Y[1]; + } + } + + dSASSERT(block_step == 4); + } + else + { + Y[0] = ptrBElement[0 * b_stride] - Z[0]; + + dReal p2 = ptrLElement[-1]; + Y[1] = ptrBElement[-1 * (int)b_stride] - Z[1] - p2 * Y[0]; + + dReal p3 = ptrLElement[-2]; + dReal p3_1 = (ptrLElement - rowSkip)[-2]; + Y[2] = ptrBElement[-2 * (int)b_stride] - Z[2] - p3 * Y[0] - p3_1 * Y[1]; + + dReal p4 = ptrLElement[-3]; + dReal p4_1 = (ptrLElement - rowSkip)[-3]; + dReal p4_2 = (ptrLElement - rowSkip * 2)[-3]; + Y[3] = ptrBElement[-3 * (int)b_stride] - Z[3] - p4 * Y[0] - p4_1 * Y[1] - p4_2 * Y[2]; + + dSASSERT(block_step == 4); + } + + // Use atomic memory barrier to make sure memory reads of ptrBElement[] and blockProgressDescriptors[] are not swapped + CooperativeAtomics::AtomicReadReorderBarrier(); + + // The descriptor has not been altered yet - this means the ptrBElement[] values used above were not modified yet + // and the computation result is valid. + if (blockProgressDescriptors[currentBlock] == oldDescriptor) + { + // Assign the results to the result context (possibly in parallel with other threads + // that could and ought to be assigning exactly the same values) + SolveL1TransposedCellContext &resultContext = buildResultContextRef(cellContexts, currentBlock, blockCount); + resultContext.storePrecalculatedZs(Y); + + // Assign the result assignment progress descriptor + cellindexint newDescriptor = MAKE_CELLDESCRIPTOR(currentBlock + 1, CCI__MIN, true); + CooperativeAtomics::AtomicCompareExchangeCellindexint(&blockProgressDescriptors[currentBlock], oldDescriptor, newDescriptor); // the result is to be ignored + + // Whether succeeded or not, the result is valid, so go on trying to assign it to the matrix + goAssigningTheResult = true; + } + else + { + // Otherwise, go on competing for copying the results + handleComputationTakenOver = true; + } + } + else + { + handleComputationTakenOver = true; + } + } + else + { + // If the final column has not been reached yet, store current values to the context. + // Select the other context instance as the previous one might be read by other threads. + CellContextInstance nextContextInstance = buildNextContextInstance(previousContextInstance); + SolveL1TransposedCellContext &destinationContext = buildBlockContextRef(cellContexts, currentBlock, nextContextInstance); + destinationContext.storePrecalculatedZs(Z); + + // Unlock the row until more columns can be used + cellindexint oldDescriptor = MAKE_CELLDESCRIPTOR(completedRowBlock, previousContextInstance, true); + cellindexint newDescriptor = MAKE_CELLDESCRIPTOR(finalRowBlock, nextContextInstance, false); + // The descriptor might have been updated by a competing thread + if (!CooperativeAtomics::AtomicCompareExchangeCellindexint(&blockProgressDescriptors[currentBlock], oldDescriptor, newDescriptor)) + { + // Adjust the ptrBElement to point to the result area... + ptrBElement = adjustedLastBElement - (sizeint)(currentBlock * block_step) * b_stride; + dIASSERT(currentBlock != 0 || adjustedLastBElement == lastBElement); + // ...and go on handling the case + handleComputationTakenOver = true; + } + } + + if (handleComputationTakenOver) + { + cellindexint existingDescriptor = blockProgressDescriptors[currentBlock]; + // This can only happen if the row was (has become) the uppermost not fully completed one + // and the competing thread is at final stage of calculation (i.e., it has reached the currentBlock column). + if (existingDescriptor != INVALID_CELLDESCRIPTOR) + { + // If not fully completed this must be the final stage of the result assignment into the matrix + dIASSERT(existingDescriptor == MAKE_CELLDESCRIPTOR(currentBlock + 1, CCI__MIN, true)); + + // Go on competing copying the result as anyway the block is the topmost not completed one + // and since there was competition for it, there is no other work that can be done right now. + const SolveL1TransposedCellContext &resultContext = buildResultContextRef(cellContexts, currentBlock, blockCount); + resultContext.loadPrecalculatedZs(Y); + + goAssigningTheResult = true; + } + else + { + // everything is over -- just go handling next blocks + } + } + } + else if (goForLockedBlockDuplicateCalculation) + { + blockProcessingState = BPS_SOME_BLOCKS_PROCESSED; + + bool skipToHandlingSubsequentRows = false, skiptoCopyingResult = false; + + /* declare variables */ + const dReal *ptrLElement; + + if (completedRowBlock < currentBlock) + { + partialBlock = false; + + ptrLElement = completedRowBlock != 0 + ? fullyAdjustedLastLElement - currentBlock * block_step - (sizeint)(completedRowBlock * block_step) * rowSkip + : columnAdjustedLastLElement - currentBlock * block_step; + ptrBElement = completedRowBlock != 0 + ? adjustedLastBElement - (sizeint)(completedRowBlock * block_step) * b_stride + : lastBElement; + + unsigned finalRowBlock = currentBlock/*std::min(currentBlock, completedBlocks)*/; + dIASSERT(currentBlock == completedBlocks); // Why would we be competing for a row otherwise? + + bool exitInnerLoop = false; + unsigned lastCompletedRow = completedRowBlock; + unsigned rowCounter = finalRowBlock - completedRowBlock; + + if (completedRowBlock == 0/* && currentBlock != 0 */&& loopX1RowCount != 0) + { + if ((loopX1RowCount & 1) != 0) + { + dReal q1, p4, p3, p2, p1; + + /* load p and q values */ + q1 = ptrBElement[0 * (int)b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z[3] += p4 * q1; + Z[2] += p3 * q1; + Z[1] += p2 * q1; + Z[0] += p1 * q1; + + ptrBElement -= 1 * b_stride; + } + + if ((loopX1RowCount & 2) != 0) + { + dReal q1, p4, p3, p2, p1; + + /* load p and q values */ + q1 = ptrBElement[0 * (int)b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z[3] += p4 * q1; + Z[2] += p3 * q1; + Z[1] += p2 * q1; + Z[0] += p1 * q1; + + /* load p and q values */ + q1 = ptrBElement[-1 * (int)b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z[3] += p4 * q1; + Z[2] += p3 * q1; + Z[1] += p2 * q1; + Z[0] += p1 * q1; + + ptrBElement -= 2 * b_stride; + } + dSASSERT(block_step == 4); + + if (--rowCounter == 0) + { + exitInnerLoop = true; + } + } + + for (; !exitInnerLoop; exitInnerLoop = --rowCounter == 0) + { + dReal q1, p4, p3, p2, p1; + + /* load p and q values */ + q1 = ptrBElement[0 * (int)b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z[3] += p4 * q1; + Z[2] += p3 * q1; + Z[1] += p2 * q1; + Z[0] += p1 * q1; + + /* load p and q values */ + q1 = ptrBElement[-1 * (int)b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z[3] += p4 * q1; + Z[2] += p3 * q1; + Z[1] += p2 * q1; + Z[0] += p1 * q1; + + /* load p and q values */ + q1 = ptrBElement[-2 * (int)b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z[3] += p4 * q1; + Z[2] += p3 * q1; + Z[1] += p2 * q1; + Z[0] += p1 * q1; + + /* load p and q values */ + q1 = ptrBElement[-3 * (int)b_stride]; + p4 = ptrLElement[-3]; + p3 = ptrLElement[-2]; + p2 = ptrLElement[-1]; + p1 = ptrLElement[0]; + ptrLElement -= rowSkip; + + /* compute outer product and add it to the Z matrix */ + Z[3] += p4 * q1; + Z[2] += p3 * q1; + Z[1] += p2 * q1; + Z[0] += p1 * q1; + dSASSERT(block_step == 4); + + // Check if the primary solver thread has not made any progress + cellindexint descriptorVerification = blockProgressDescriptors[currentBlock]; + unsigned newCompletedRow = GET_CELLDESCRIPTOR_COLUMNINDEX(descriptorVerification); + + if (newCompletedRow != lastCompletedRow) + { + // Check, this is the first change the current thread detects. + // There is absolutely no reason in code for the computation to stop/resume twice + // while the current thread is competing. + dIASSERT(lastCompletedRow == completedRowBlock); + + if (descriptorVerification == INVALID_CELLDESCRIPTOR) + { + skipToHandlingSubsequentRows = true; + break; + } + + if (newCompletedRow == currentBlock + 1) + { + skiptoCopyingResult = true; + break; + } + + // Check if the current thread is behind + if (newCompletedRow > finalRowBlock - rowCounter) + { + // If so, go starting over one more time + blockProcessingState = BPS_COMPETING_FOR_A_BLOCK; + stayWithinTheBlock = true; + skipToHandlingSubsequentRows = true; + break; + } + + // If current thread is ahead, just save new completed column for further comparisons and go on calculating + lastCompletedRow = newCompletedRow; + } + + /* advance pointers */ + ptrBElement -= block_step * b_stride; + /* end of inner loop */ + } + } + else if (completedRowBlock > currentBlock) + { + dIASSERT(completedRowBlock == currentBlock + 1); + + partialBlock = currentBlock == 0 && loopX1RowCount != 0; + + skiptoCopyingResult = true; + } + else + { + dIASSERT(currentBlock == 0); // Execution can get here within the very first block only + + partialBlock = /*currentBlock == 0 && */loopX1RowCount != 0; + + /* just assign the pointers appropriately and go on computing the results */ + ptrLElement = lastLElement; + ptrBElement = lastBElement; + } + + if (!skipToHandlingSubsequentRows) + { + if (!skiptoCopyingResult) + { + if (partialBlock) + { + Y[0] = ptrBElement[0 * b_stride]/* - Z[0]*/; + + if (loopX1RowCount >= 2) + { + dReal p2 = ptrLElement[-1]; + Y[1] = ptrBElement[-1 * (int)b_stride]/* - Z[1] */- p2 * Y[0]; + + if (loopX1RowCount > 2) + { + dReal p3 = ptrLElement[-2]; + dReal p3_1 = (ptrLElement - rowSkip)[-2]; + Y[2] = ptrBElement[-2 * (int)b_stride]/* - Z[2] */- p3 * Y[0] - p3_1 * Y[1]; + } + } + + dSASSERT(block_step == 4); + } + else + { + Y[0] = ptrBElement[0 * b_stride] - Z[0]; + + dReal p2 = ptrLElement[-1]; + Y[1] = ptrBElement[-1 * (int)b_stride] - Z[1] - p2 * Y[0]; + + dReal p3 = ptrLElement[-2]; + dReal p3_1 = (ptrLElement - rowSkip)[-2]; + Y[2] = ptrBElement[-2 * (int)b_stride] - Z[2] - p3 * Y[0] - p3_1 * Y[1]; + + dReal p4 = ptrLElement[-3]; + dReal p4_1 = (ptrLElement - rowSkip)[-3]; + dReal p4_2 = (ptrLElement - rowSkip * 2)[-3]; + Y[3] = ptrBElement[-3 * (int)b_stride] - Z[3] - p4 * Y[0] - p4_1 * Y[1] - p4_2 * Y[2]; + + dSASSERT(block_step == 4); + } + + // Use atomic memory barrier to make sure memory reads of ptrBElement[] and blockProgressDescriptors[] are not swapped + CooperativeAtomics::AtomicReadReorderBarrier(); + + cellindexint existingDescriptor = blockProgressDescriptors[currentBlock]; + + if (existingDescriptor == INVALID_CELLDESCRIPTOR) + { + // Everything is over -- proceed to subsequent rows + skipToHandlingSubsequentRows = true; + } + else if (existingDescriptor == MAKE_CELLDESCRIPTOR(currentBlock + 1, CCI__MIN, true)) + { + // The values computed above may not be valid. Copy the values already in the result context. + skiptoCopyingResult = true; + } + else + { + // The descriptor has not been altered yet - this means the ptrBElement[] values used above were not modified yet + // and the computation result is valid. + cellindexint newDescriptor = MAKE_CELLDESCRIPTOR(currentBlock + 1, CCI__MIN, true); // put the computation at the top so that the evaluation result from the expression above is reused + + // Assign the results to the result context (possibly in parallel with other threads + // that could and ought to be assigning exactly the same values) + SolveL1TransposedCellContext &resultContext = buildResultContextRef(cellContexts, currentBlock, blockCount); + resultContext.storePrecalculatedZs(Y); + + // Assign the result assignment progress descriptor + CooperativeAtomics::AtomicCompareExchangeCellindexint(&blockProgressDescriptors[currentBlock], existingDescriptor, newDescriptor); // the result is to be ignored + + // Whether succeeded or not, the result is valid, so go on trying to assign it to the matrix + } + } + + if (!skipToHandlingSubsequentRows) + { + if (skiptoCopyingResult) + { + // Extract the result values stored in the result context + const SolveL1TransposedCellContext &resultContext = buildResultContextRef(cellContexts, currentBlock, blockCount); + resultContext.loadPrecalculatedZs(Y); + + ptrBElement = currentBlock != 0 ? adjustedLastBElement - (sizeint)(currentBlock * block_step) * b_stride : lastBElement; + } + + goAssigningTheResult = true; + } + } + } + + if (goAssigningTheResult) + { + cellindexint existingDescriptor = blockProgressDescriptors[currentBlock]; + // Check if the assignment has not been completed yet + if (existingDescriptor != INVALID_CELLDESCRIPTOR) + { + // Assign the computation results to B vector + if (partialBlock) + { + // ptrBElement[0 * b_stride] = Y[0]; -- unchanged + + if (loopX1RowCount >= 2) + { + ptrBElement[-1 * (int)b_stride] = Y[1]; + + if (loopX1RowCount > 2) + { + ptrBElement[-2 * (int)b_stride] = Y[2]; + } + } + dSASSERT(block_step == 4); + } + else + { + ptrBElement[0 * b_stride] = Y[0]; + ptrBElement[-1 * (int)b_stride] = Y[1]; + ptrBElement[-2 * (int)b_stride] = Y[2]; + ptrBElement[-3 * (int)b_stride] = Y[3]; + dSASSERT(block_step == 4); + } + + ThrsafeIncrementIntUpToLimit(&refBlockCompletionProgress, currentBlock + 1); + dIASSERT(refBlockCompletionProgress >= currentBlock + 1); + + // And assign the completed status no matter what + CooperativeAtomics::AtomicStoreCellindexint(&blockProgressDescriptors[currentBlock], INVALID_CELLDESCRIPTOR); + } + else + { + // everything is over -- just go handling next blocks + } + } + + if (!stayWithinTheBlock) + { + completedBlocks = refBlockCompletionProgress; + + if (completedBlocks == blockCount) + { + break; + } + + currentBlock += 1; + + bool lookaheadBoundaryReached = false; + + if (currentBlock == blockCount || completedBlocks == 0) + { + lookaheadBoundaryReached = true; + } + else if (currentBlock >= completedBlocks + lookaheadRange) + { + lookaheadBoundaryReached = blockProcessingState > BPS_NO_BLOCKS_PROCESSED; + } + else if (currentBlock < completedBlocks) + { + // Treat detected row advancement as a row processed + // blockProcessingState = BPS_SOME_BLOCKS_PROCESSED; <-- performs better without it + + currentBlock = completedBlocks; + } + + if (lookaheadBoundaryReached) + { + dIASSERT(blockProcessingState != BPS_COMPETING_FOR_A_BLOCK); // Why did not we compete??? + + // If no row has been processed in the previous pass, compete for the next row to avoid cycling uselessly + if (blockProcessingState <= BPS_NO_BLOCKS_PROCESSED) + { + // Abandon job if too few blocks remain + if (blockCount - completedBlocks <= ownThreadIndex) + { + break; + } + + blockProcessingState = BPS_COMPETING_FOR_A_BLOCK; + } + else + { + // If there was some progress, just continue to the next pass + blockProcessingState = BPS_NO_BLOCKS_PROCESSED; + } + + currentBlock = completedBlocks; + } + } + } +} + + +#endif diff --git a/libs/ode-0.16.1/ode/src/fastvecscale.cpp b/libs/ode-0.16.1/ode/src/fastvecscale.cpp new file mode 100644 index 0000000..9927d89 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/fastvecscale.cpp @@ -0,0 +1,204 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * Vector scaling related code of ThreadedEquationSolverLDLT + * Copyright (c) 2017-2019 Oleh Derevenko, odar@eleks.com (change all "a" to "e") + */ + + +#include <ode/common.h> +#include <ode/matrix.h> +#include <ode/matrix_coop.h> +#include "config.h" +#include "threaded_solver_ldlt.h" +#include "threading_base.h" +#include "resource_control.h" +#include "error.h" + +#include "fastvecscale_impl.h" + + +/*static */ +void ThreadedEquationSolverLDLT::estimateCooperativeScalingVectorResourceRequirements( + dxResourceRequirementDescriptor *summaryRequirementsDescriptor, + unsigned allowedThreadCount, unsigned elementCount) +{ + dxThreadingBase *threading = summaryRequirementsDescriptor->getrelatedThreading(); + unsigned limitedThreadCount = restrictScalingVectorAllowedThreadCount(threading, allowedThreadCount, elementCount); + + if (limitedThreadCount > 1) + { + doEstimateCooperativeScalingVectorResourceRequirementsValidated(summaryRequirementsDescriptor, allowedThreadCount, elementCount); + } +} + +/*static */ +void ThreadedEquationSolverLDLT::cooperativelyScaleVector(dxRequiredResourceContainer *resourceContainer, unsigned allowedThreadCount, + dReal *vectorData, const dReal *scaleData, unsigned elementCount) +{ + dAASSERT(elementCount != 0); + + dxThreadingBase *threading = resourceContainer->getThreadingInstance(); + unsigned limitedThreadCount = restrictScalingVectorAllowedThreadCount(threading, allowedThreadCount, elementCount); + + if (limitedThreadCount <= 1) + { + scaleLargeVector<SV_A_STRIDE, SV_D_STRIDE>(vectorData, scaleData, elementCount); + } + else + { + doCooperativelyScaleVectorValidated(resourceContainer, limitedThreadCount, vectorData, scaleData, elementCount); + } +} + +/*static */ +unsigned ThreadedEquationSolverLDLT::restrictScalingVectorAllowedThreadCount( + dxThreadingBase *threading, unsigned allowedThreadCount, unsigned elementCount) +{ + unsigned limitedThreadCount = 1; + +#if dCOOPERATIVE_ENABLED + const unsigned int blockStep = SV_BLOCK_SIZE; // Required by the implementation + unsigned scalingBlockCount = deriveScalingVectorBlockCount(elementCount, blockStep); + dIASSERT(deriveScalingVectorThreadCount(SV_COOPERATIVE_BLOCK_COUNT_MINIMUM - 1, 2) > 1); + + if (scalingBlockCount >= SV_COOPERATIVE_BLOCK_COUNT_MINIMUM) + { + limitedThreadCount = threading->calculateThreadingLimitedThreadCount(allowedThreadCount, true); + } +#endif // #if dCOOPERATIVE_ENABLED + + return limitedThreadCount; +} + +/*static */ +void ThreadedEquationSolverLDLT::doEstimateCooperativeScalingVectorResourceRequirementsValidated( + dxResourceRequirementDescriptor *summaryRequirementsDescriptor, + unsigned allowedThreadCount, unsigned elementCount) +{ + unsigned simultaneousCallCount = 1 + (allowedThreadCount - 1); + + sizeint scalingMemoryRequired = 0; + const unsigned scalingAlignmentRequired = 0; + + unsigned featureRequirement = dxResourceRequirementDescriptor::STOCK_CALLWAIT_REQUIRED; + summaryRequirementsDescriptor->mergeAnotherDescriptorIn(scalingMemoryRequired, scalingAlignmentRequired, simultaneousCallCount, featureRequirement); +} + +/*static */ +void ThreadedEquationSolverLDLT::doCooperativelyScaleVectorValidated( + dxRequiredResourceContainer *resourceContainer, unsigned allowedThreadCount, + dReal *vectorData, const dReal *scaleData, unsigned elementCount) +{ + dIASSERT(allowedThreadCount > 1); + + const unsigned int blockStep = SV_BLOCK_SIZE; // Required by the implementation + unsigned scalingBlockCount = deriveScalingVectorBlockCount(elementCount, blockStep); + dIASSERT(scalingBlockCount > 0U); + + unsigned threadCountToUse = deriveScalingVectorThreadCount(scalingBlockCount - 1, allowedThreadCount); + dIASSERT(threadCountToUse > 1); + + dCallWaitID completionWait = resourceContainer->getStockCallWait(); + dAASSERT(completionWait != NULL); + + atomicord32 blockCompletionProgress; + + initializeCooperativelyScaleVectorMemoryStructures(blockCompletionProgress); + + dCallReleaseeID calculationFinishReleasee; + ScaleVectorWorkerContext workerContext; // The variable must exist in the outer scope + + workerContext.init(vectorData, scaleData, elementCount, blockCompletionProgress); + + dxThreadingBase *threading = resourceContainer->getThreadingInstance(); + threading->PostThreadedCall(NULL, &calculationFinishReleasee, threadCountToUse - 1, NULL, completionWait, &scaleVector_completion_callback, NULL, 0, "ScaleVector Completion"); + threading->PostThreadedCallsGroup(NULL, threadCountToUse - 1, calculationFinishReleasee, &scaleVector_worker_callback, &workerContext, "ScaleVector Work"); + + participateScalingVector<blockStep, SV_A_STRIDE, SV_D_STRIDE>(vectorData, scaleData, elementCount, blockCompletionProgress); + + threading->WaitThreadedCallExclusively(NULL, completionWait, NULL, "ScaleVector End Wait"); +} + + +/*static */ +int ThreadedEquationSolverLDLT::scaleVector_worker_callback(void *callContext, dcallindex_t dUNUSED(callInstanceIndex), dCallReleaseeID dUNUSED(callThisReleasee)) +{ + ScaleVectorWorkerContext *ptrContext = (ScaleVectorWorkerContext *)callContext; + + scaleVector_worker(*ptrContext); + + return 1; +} + +/*static */ +void ThreadedEquationSolverLDLT::scaleVector_worker(ScaleVectorWorkerContext &ref_context) +{ + const unsigned blockStep = SV_BLOCK_SIZE; + + participateScalingVector<blockStep, SV_A_STRIDE, SV_D_STRIDE>(ref_context.m_vectorData, ref_context.m_scaleData, ref_context.m_elementCount, *ref_context.m_ptrBlockCompletionProgress); +} + +/*static */ +int ThreadedEquationSolverLDLT::scaleVector_completion_callback(void *dUNUSED(callContext), dcallindex_t dUNUSED(callInstanceIndex), dCallReleaseeID dUNUSED(callThisReleasee)) +{ + return 1; +} + + +////////////////////////////////////////////////////////////////////////// +// Public interface functions + +/*extern ODE_API */ +void dScaleVector(dReal *a, const dReal *d, int n) +{ + scaleLargeVector<1, 1>(a, d, n); +} + +/*extern ODE_API_DEPRECATED ODE_API */ +void dVectorScale(dReal *a, const dReal *d, int n) +{ + scaleLargeVector<1, 1>(a, d, n); +} + + +/*extern ODE_API */ +void dEstimateCooperativelyScaleVectorResourceRequirements(dResourceRequirementsID requirements, + unsigned maximalAllowedThreadCount, unsigned maximalElementCount) +{ + dAASSERT(requirements != NULL); + + dxResourceRequirementDescriptor *requirementsDescriptor = (dxResourceRequirementDescriptor *)requirements; + ThreadedEquationSolverLDLT::estimateCooperativeScalingVectorResourceRequirements(requirementsDescriptor, maximalAllowedThreadCount, maximalElementCount); +} + +/*extern ODE_API */ +void dCooperativelyScaleVector(dResourceContainerID resources, unsigned allowedThreadCount, + dReal *dataVector, const dReal *scaleVector, unsigned elementCount) +{ + dAASSERT(resources != NULL); + + dxRequiredResourceContainer *resourceContainer = (dxRequiredResourceContainer *)resources; + ThreadedEquationSolverLDLT::cooperativelyScaleVector(resourceContainer, allowedThreadCount, dataVector, scaleVector, elementCount); +} + diff --git a/libs/ode-0.16.1/ode/src/fastvecscale_impl.h b/libs/ode-0.16.1/ode/src/fastvecscale_impl.h new file mode 100644 index 0000000..c483fdd --- /dev/null +++ b/libs/ode-0.16.1/ode/src/fastvecscale_impl.h @@ -0,0 +1,171 @@ +/*************************************************************************
+ * *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
+ * All rights reserved. Email: russ@q12.org Web: www.q12.org *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of EITHER: *
+ * (1) The GNU Lesser General Public License as published by the Free *
+ * Software Foundation; either version 2.1 of the License, or (at *
+ * your option) any later version. The text of the GNU Lesser *
+ * General Public License is included with this library in the *
+ * file LICENSE.TXT. *
+ * (2) The BSD-style license that is included with this library in *
+ * the file LICENSE-BSD.TXT. *
+ * *
+ * This library 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 files *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
+ * *
+ *************************************************************************/
+
+/*
+ * Vector scaling function implementation
+ * Improvements and cooperative implementation copyright (c) 2017-2019 Oleh Derevenko, odar@eleks.com (change all "a" to "e")
+ */
+
+#ifndef _ODE_FASTVECSCALE_IMPL_H_
+#define _ODE_FASTVECSCALE_IMPL_H_
+
+
+
+template<unsigned int a_stride, unsigned int d_stride>
+void scaleLargeVector(dReal *aStart, const dReal *dStart, unsigned elementCount)
+{
+ dAASSERT (aStart && dStart && elementCount >= 0);
+
+ const unsigned step = 4;
+
+ dReal *ptrA = aStart;
+ const dReal *ptrD = dStart;
+ const dReal *const dStepsEnd = dStart + (sizeint)(elementCount & ~(step - 1)) * d_stride;
+ for (; ptrD != dStepsEnd; ptrA += step * a_stride, ptrD += step * d_stride)
+ {
+ dReal a0 = ptrA[0], a1 = ptrA[1 * a_stride], a2 = ptrA[2 * a_stride], a3 = ptrA[3 * a_stride];
+ dReal d0 = ptrD[0], d1 = ptrD[1 * d_stride], d2 = ptrD[2 * d_stride], d3 = ptrD[3 * d_stride];
+ a0 *= d0;
+ a1 *= d1;
+ a2 *= d2;
+ a3 *= d3;
+ ptrA[0] = a0; ptrA[1 * a_stride] = a1; ptrA[2 * a_stride] = a2; ptrA[3 * a_stride] = a3;
+ dSASSERT(step == 4);
+ }
+
+ switch (elementCount & (step - 1))
+ {
+ case 3:
+ {
+ dReal a2 = ptrA[2 * a_stride];
+ dReal d2 = ptrD[2 * d_stride];
+ ptrA[2 * a_stride] = a2 * d2;
+ // break; -- proceed to case 2
+ }
+
+ case 2:
+ {
+ dReal a1 = ptrA[1 * a_stride];
+ dReal d1 = ptrD[1 * d_stride];
+ ptrA[1 * a_stride] = a1 * d1;
+ // break; -- proceed to case 1
+ }
+
+ case 1:
+ {
+ dReal a0 = ptrA[0];
+ dReal d0 = ptrD[0];
+ ptrA[0] = a0 * d0;
+ break;
+ }
+ }
+ dSASSERT(step == 4);
+}
+
+
+template<unsigned int block_step, unsigned int a_stride, unsigned int d_stride>
+/*static */
+void ThreadedEquationSolverLDLT::participateScalingVector(dReal *ptrAStart, const dReal *ptrDStart, const unsigned elementCount,
+ volatile atomicord32 &refBlockCompletionProgress/*=0*/)
+{
+ dAASSERT (ptrAStart != NULL);
+ dAASSERT(ptrDStart != NULL);
+ dAASSERT(elementCount >= 0);
+
+ const unsigned wrapSize = 4;
+ dSASSERT(block_step % wrapSize == 0);
+
+ const unsigned completeBlockCount = elementCount / block_step;
+ const unsigned trailingBlockElements = elementCount % block_step;
+
+ unsigned blockIndex;
+ while ((blockIndex = ThrsafeIncrementIntUpToLimit(&refBlockCompletionProgress, completeBlockCount)) != completeBlockCount)
+ {
+ dReal *ptrAElement = ptrAStart + (sizeint)(blockIndex * block_step) * a_stride;
+ const dReal *ptrDElement = ptrDStart + (sizeint)(blockIndex * block_step) * d_stride;
+ const dReal *const ptrDBlockEnd = ptrDElement + block_step * d_stride;
+ dSASSERT((sizeint)block_step * a_stride < UINT_MAX);
+ dSASSERT((sizeint)block_step * d_stride < UINT_MAX);
+
+ for (; ptrDElement != ptrDBlockEnd; ptrAElement += wrapSize * a_stride, ptrDElement += wrapSize * d_stride)
+ {
+ dReal a0 = ptrAElement[0], a1 = ptrAElement[1 * a_stride], a2 = ptrAElement[2 * a_stride], a3 = ptrAElement[3 * a_stride];
+ dReal d0 = ptrDElement[0], d1 = ptrDElement[1 * d_stride], d2 = ptrDElement[2 * d_stride], d3 = ptrDElement[3 * d_stride];
+ a0 *= d0;
+ a1 *= d1;
+ a2 *= d2;
+ a3 *= d3;
+ ptrAElement[0] = a0; ptrAElement[1 * a_stride] = a1; ptrAElement[2 * a_stride] = a2; ptrAElement[3 * a_stride] = a3;
+ dSASSERT(wrapSize == 4);
+ }
+ }
+
+ if (trailingBlockElements != 0 && (blockIndex = ThrsafeIncrementIntUpToLimit(&refBlockCompletionProgress, completeBlockCount + 1)) != completeBlockCount + 1)
+ {
+ dReal *ptrAElement = ptrAStart + (sizeint)(completeBlockCount * block_step) * a_stride;
+ const dReal *ptrDElement = ptrDStart + (sizeint)(completeBlockCount * block_step) * d_stride;
+ const dReal *const ptrDBlockEnd = ptrDElement + (trailingBlockElements & ~(wrapSize - 1)) * d_stride;
+
+ for (; ptrDElement != ptrDBlockEnd; ptrAElement += wrapSize * a_stride, ptrDElement += wrapSize * d_stride)
+ {
+ dReal a0 = ptrAElement[0], a1 = ptrAElement[1 * a_stride], a2 = ptrAElement[2 * a_stride], a3 = ptrAElement[3 * a_stride];
+ dReal d0 = ptrDElement[0], d1 = ptrDElement[1 * d_stride], d2 = ptrDElement[2 * d_stride], d3 = ptrDElement[3 * d_stride];
+ a0 *= d0;
+ a1 *= d1;
+ a2 *= d2;
+ a3 *= d3;
+ ptrAElement[0] = a0; ptrAElement[1 * a_stride] = a1; ptrAElement[2 * a_stride] = a2; ptrAElement[3 * a_stride] = a3;
+ dSASSERT(wrapSize == 4);
+ }
+
+ switch (trailingBlockElements & (wrapSize - 1))
+ {
+ case 3:
+ {
+ dReal a2 = ptrAElement[2 * a_stride];
+ dReal d2 = ptrDElement[2 * d_stride];
+ ptrAElement[2 * a_stride] = a2 * d2;
+ // break; -- proceed to case 2
+ }
+
+ case 2:
+ {
+ dReal a1 = ptrAElement[1 * a_stride];
+ dReal d1 = ptrDElement[1 * d_stride];
+ ptrAElement[1 * a_stride] = a1 * d1;
+ // break; -- proceed to case 1
+ }
+
+ case 1:
+ {
+ dReal a0 = ptrAElement[0];
+ dReal d0 = ptrDElement[0];
+ ptrAElement[0] = a0 * d0;
+ break;
+ }
+ }
+ dSASSERT(wrapSize == 4);
+ }
+}
+
+
+#endif
diff --git a/libs/ode-0.16.1/ode/src/gimpact_contact_export_helper.cpp b/libs/ode-0.16.1/ode/src/gimpact_contact_export_helper.cpp new file mode 100644 index 0000000..0e107b0 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/gimpact_contact_export_helper.cpp @@ -0,0 +1,95 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <ode/collision.h> +#include "config.h" + + +#if dTRIMESH_ENABLED && dTRIMESH_GIMPACT + +#include "gimpact_contact_export_helper.h" +#include "error.h" + + +/*static */ +dReal dxGImpactContactsExportHelper::FindContactsMarginalDepth(dReal *pdepths, unsigned contactcount, unsigned maxcontacts, dReal mindepth, dReal maxdepth) +{ + dReal result; + + while (true) + { + dReal firstdepth = REAL(0.5) * (mindepth + maxdepth); + dReal lowdepth = maxdepth, highdepth = mindepth; + + unsigned marginindex = 0; + unsigned highindex = marginindex; + dIASSERT(contactcount != 0); + + for (unsigned i = 0; i < contactcount; i++) + { + dReal depth = pdepths[i]; + + if (depth < firstdepth) + { + dReal temp = pdepths[marginindex]; pdepths[highindex++] = temp; pdepths[marginindex++] = depth; + if (highdepth < depth) { highdepth = depth; } + } + else if (depth > firstdepth) + { + pdepths[highindex++] = depth; + if (depth < lowdepth) { lowdepth = depth; } + } + } + + unsigned countabove = highindex - marginindex; + if (maxcontacts < countabove) + { + contactcount = countabove; + pdepths += marginindex; + mindepth = lowdepth; + } + else if (maxcontacts == countabove) + { + result = dNextAfter(firstdepth, dInfinity); + break; + } + else + { + unsigned countbelow = marginindex; + if (maxcontacts <= contactcount - countbelow) + { + result = firstdepth; + break; + } + + maxcontacts -= contactcount - countbelow; + contactcount = countbelow; + maxdepth = highdepth; + } + } + + return result; +} + + +#endif // #if dTRIMESH_ENABLED && dTRIMESH_GIMPACT + diff --git a/libs/ode-0.16.1/ode/src/gimpact_contact_export_helper.h b/libs/ode-0.16.1/ode/src/gimpact_contact_export_helper.h new file mode 100644 index 0000000..149ac91 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/gimpact_contact_export_helper.h @@ -0,0 +1,177 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + + +#ifndef _ODE_GIMPACT_CONTACT_EXPORT_HELPER_H_ +#define _ODE_GIMPACT_CONTACT_EXPORT_HELPER_H_ + + +#include "collision_kernel.h" +#include "collision_util.h" +#include "util.h" + + +#ifndef ALLOCA +#define ALLOCA(x) dALLOCA16(x) +#endif + + +struct dxGImpactContactsExportHelper +{ +public: + template<class dxGImpactContactAccessor> + static unsigned ExportMaxDepthGImpactContacts(dxGImpactContactAccessor &srccontacts, unsigned contactcount, + int Flags, dContactGeom* Contacts, int Stride) + { + unsigned result; + + unsigned maxcontacts = (unsigned)(Flags & NUMC_MASK); + if (contactcount > maxcontacts) + { + ExportExcesssiveContacts(srccontacts, contactcount, Flags, Contacts, Stride); + result = maxcontacts; + } + else + { + ExportFitContacts(srccontacts, contactcount, Flags, Contacts, Stride); + result = contactcount; + } + + return result; + } + +private: + template<class dxGImpactContactAccessor> + static void ExportExcesssiveContacts(dxGImpactContactAccessor &srccontacts, unsigned contactcount, + int Flags, dContactGeom* Contacts, int Stride); + template<class dxGImpactContactAccessor> + static void ExportFitContacts(dxGImpactContactAccessor &srccontacts, unsigned contactcount, + int Flags, dContactGeom* Contacts, int Stride); + template<class dxGImpactContactAccessor> + static dReal FindContactsMarginalDepth(dxGImpactContactAccessor &srccontacts, unsigned contactcount, unsigned maxcontacts); + static dReal FindContactsMarginalDepth(dReal *pdepths, unsigned contactcount, unsigned maxcontacts, dReal mindepth, dReal maxdepth); +}; + + +template<class dxGImpactContactAccessor> +/*static */ +void dxGImpactContactsExportHelper::ExportExcesssiveContacts(dxGImpactContactAccessor &srccontacts, unsigned contactcount, + int Flags, dContactGeom* Contacts, int Stride) +{ + unsigned maxcontacts = (unsigned)(Flags & NUMC_MASK); + dReal marginaldepth = FindContactsMarginalDepth(srccontacts, contactcount, maxcontacts); + + unsigned contactshead = 0, contacttail = maxcontacts; + for (unsigned i = 0; i < contactcount; i++) + { + dReal depth = srccontacts.RetrieveDepthByIndex(i); + + if (depth > marginaldepth) + { + dContactGeom *pcontact = SAFECONTACT(Flags, Contacts, contactshead, Stride); + srccontacts.ExportContactGeomByIndex(pcontact, i); + + if (++contactshead == maxcontacts) + { + break; + } + } + else if (depth == marginaldepth && contactshead < contacttail) + { + --contacttail; + + dContactGeom *pcontact = SAFECONTACT(Flags, Contacts, contacttail, Stride); + srccontacts.ExportContactGeomByIndex(pcontact, i); + } + } +} + +template<class dxGImpactContactAccessor> +/*static */ +void dxGImpactContactsExportHelper::ExportFitContacts(dxGImpactContactAccessor &srccontacts, unsigned contactcount, + int Flags, dContactGeom* Contacts, int Stride) +{ + for (unsigned i = 0; i < contactcount; i++) + { + dContactGeom *pcontact = SAFECONTACT(Flags, Contacts, i, Stride); + + srccontacts.ExportContactGeomByIndex(pcontact, i); + } +} + +template<class dxGImpactContactAccessor> +/*static */ +dReal dxGImpactContactsExportHelper::FindContactsMarginalDepth(dxGImpactContactAccessor &srccontacts, unsigned contactcount, unsigned maxcontacts) +{ + dReal result; + + dReal *pdepths = (dReal *)ALLOCA(contactcount * sizeof(dReal)); + unsigned marginindex = 0; + unsigned highindex = marginindex; + + dReal firstdepth = srccontacts.RetrieveDepthByIndex(0); + dReal mindepth = firstdepth, maxdepth = firstdepth; + dIASSERT(contactcount > 1); + + for (unsigned i = 1; i < contactcount; i++) + { + dReal depth = srccontacts.RetrieveDepthByIndex(i); + + if (depth < firstdepth) + { + dReal temp = pdepths[marginindex]; pdepths[highindex++] = temp; pdepths[marginindex++] = depth; + if (depth < mindepth) { mindepth = depth; } + } + else if (depth > firstdepth) + { + pdepths[highindex++] = depth; + if (maxdepth < depth) { maxdepth = depth; } + } + } + + unsigned countabove = highindex - marginindex; + if (maxcontacts < countabove) + { + result = FindContactsMarginalDepth(pdepths + marginindex, countabove, maxcontacts, firstdepth, maxdepth); + } + else if (maxcontacts == countabove) + { + result = dNextAfter(firstdepth, dInfinity); + } + else + { + unsigned countbelow = marginindex; + if (maxcontacts <= contactcount - countbelow) + { + result = firstdepth; + } + else + { + result = FindContactsMarginalDepth(pdepths, countbelow, maxcontacts - (contactcount - countbelow), mindepth, firstdepth); + } + } + + return result; +} + + +#endif //_ODE_GIMPACT_CONTACT_EXPORT_HELPER_H_ diff --git a/libs/ode-0.16.1/ode/src/gimpact_gim_contact_accessor.h b/libs/ode-0.16.1/ode/src/gimpact_gim_contact_accessor.h new file mode 100644 index 0000000..2b252b4 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/gimpact_gim_contact_accessor.h @@ -0,0 +1,62 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + + +#ifndef _ODE_GIMPACT_GIM_CONTACT_ACCESSOR_H_ +#define _ODE_GIMPACT_GIM_CONTACT_ACCESSOR_H_ + + +struct dxGIMCContactAccessor +{ + dxGIMCContactAccessor(GIM_CONTACT *ptrimeshcontacts, dGeomID g1, dGeomID g2) : m_ptrimeshcontacts(ptrimeshcontacts), m_g1(g1), m_g2(g2), m_gotside2ovr(false), m_side2ovr() {} + dxGIMCContactAccessor(GIM_CONTACT *ptrimeshcontacts, dGeomID g1, dGeomID g2, int side2ovr) : m_ptrimeshcontacts(ptrimeshcontacts), m_g1(g1), m_g2(g2), m_gotside2ovr(true), m_side2ovr(side2ovr) {} + + dReal RetrieveDepthByIndex(unsigned index) const { return m_ptrimeshcontacts[index].m_depth; } + + void ExportContactGeomByIndex(dContactGeom *pcontact, unsigned index) const + { + const GIM_CONTACT *ptrimeshcontact = m_ptrimeshcontacts + index; + pcontact->pos[0] = ptrimeshcontact->m_point[0]; + pcontact->pos[1] = ptrimeshcontact->m_point[1]; + pcontact->pos[2] = ptrimeshcontact->m_point[2]; + pcontact->pos[3] = REAL(1.0); + + pcontact->normal[0] = ptrimeshcontact->m_normal[0]; + pcontact->normal[1] = ptrimeshcontact->m_normal[1]; + pcontact->normal[2] = ptrimeshcontact->m_normal[2]; + pcontact->normal[3] = 0; + + pcontact->depth = ptrimeshcontact->m_depth; + pcontact->g1 = m_g1; + pcontact->g2 = m_g2; + pcontact->side1 = ptrimeshcontact->m_feature1; + pcontact->side2 = !m_gotside2ovr ? ptrimeshcontact->m_feature2 : m_side2ovr; + } + + const GIM_CONTACT *m_ptrimeshcontacts; + dGeomID m_g1, m_g2; + bool m_gotside2ovr; + int m_side2ovr; +}; + + +#endif //_ODE_GIMPACT_GIM_CONTACT_ACCESSOR_H_ diff --git a/libs/ode-0.16.1/ode/src/gimpact_plane_contact_accessor.h b/libs/ode-0.16.1/ode/src/gimpact_plane_contact_accessor.h new file mode 100644 index 0000000..035dcfd --- /dev/null +++ b/libs/ode-0.16.1/ode/src/gimpact_plane_contact_accessor.h @@ -0,0 +1,62 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + + +#ifndef _ODE_GIMPACT_PLANE_CONTACT_ACCESSOR_H_ +#define _ODE_GIMPACT_PLANE_CONTACT_ACCESSOR_H_ + + +struct dxPlaneContactAccessor +{ + dxPlaneContactAccessor(const vec4f *planecontact_results, const dReal *plane, dGeomID g1, dGeomID g2) : m_planecontact_results(planecontact_results), m_plane(plane), m_g1(g1), m_g2(g2) {} + + dReal RetrieveDepthByIndex(unsigned index) const { return m_planecontact_results[index][3]; } + + void ExportContactGeomByIndex(dContactGeom *pcontact, unsigned index) const + { + const vec4f *planecontact = m_planecontact_results + index; + + pcontact->pos[0] = (*planecontact)[0]; + pcontact->pos[1] = (*planecontact)[1]; + pcontact->pos[2] = (*planecontact)[2]; + pcontact->pos[3] = REAL(1.0); + + const dReal *plane = m_plane; + pcontact->normal[0] = plane[0]; + pcontact->normal[1] = plane[1]; + pcontact->normal[2] = plane[2]; + pcontact->normal[3] = 0; + + pcontact->depth = (*planecontact)[3]; + pcontact->g1 = m_g1; // trimesh geom + pcontact->g2 = m_g2; // plane geom + pcontact->side1 = -1; // note: don't have the triangle index, but OPCODE *does* do this properly + pcontact->side2 = -1; + } + + const vec4f *m_planecontact_results; + const dReal *m_plane; + dGeomID m_g1, m_g2; +}; + + +#endif //_ODE_GIMPACT_PLANE_CONTACT_ACCESSOR_H_ diff --git a/libs/ode-0.16.1/ode/src/heightfield.cpp b/libs/ode-0.16.1/ode/src/heightfield.cpp new file mode 100644 index 0000000..71699db --- /dev/null +++ b/libs/ode-0.16.1/ode/src/heightfield.cpp @@ -0,0 +1,1876 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// dHeightfield Collider +// Paul Cheyrou-Lagreze aka Tuan Kuranes 2006 Speed enhancements http://www.pop-3d.com +// Martijn Buijs 2006 http://home.planet.nl/~buijs512/ +// Based on Terrain & Cone contrib by: +// Benoit CHAPEROT 2003-2004 http://www.jstarlab.com +// Some code inspired by Magic Software + + +#include <ode/common.h> +#include <ode/collision.h> +#include <ode/rotation.h> +#include "config.h" +#include "matrix.h" +#include "odemath.h" +#include "collision_kernel.h" +#include "collision_std.h" +#include "collision_util.h" +#include "heightfield.h" + + + +#if dTRIMESH_ENABLED +#include "collision_trimesh_colliders.h" +#endif // dTRIMESH_ENABLED + +#define dMIN(A,B) ((A)>(B) ? (B) : (A)) +#define dMAX(A,B) ((A)>(B) ? (A) : (B)) + + +// Three-way MIN and MAX +#define dMIN3(A,B,C) ( (A)<(B) ? dMIN((A),(C)) : dMIN((B),(C)) ) +#define dMAX3(A,B,C) ( (A)>(B) ? dMAX((A),(C)) : dMAX((B),(C)) ) + +#define dOPESIGN(a, op1, op2,b) \ + (a)[0] op1 op2 ((b)[0]); \ + (a)[1] op1 op2 ((b)[1]); \ + (a)[2] op1 op2 ((b)[2]); + +#define dGeomRaySetNoNormalize(myRay, MyPoint, MyVector) { \ + \ + dVector3Copy (MyPoint, (myRay).final_posr->pos); \ + (myRay).final_posr->R[2] = (MyVector)[0]; \ + (myRay).final_posr->R[6] = (MyVector)[1]; \ + (myRay).final_posr->R[10] = (MyVector)[2]; \ + dGeomMoved (&myRay); \ + } + +#define dGeomPlaneSetNoNormalize(MyPlane, MyPlaneDef) { \ + \ + (MyPlane)->p[0] = (MyPlaneDef)[0]; \ + (MyPlane)->p[1] = (MyPlaneDef)[1]; \ + (MyPlane)->p[2] = (MyPlaneDef)[2]; \ + (MyPlane)->p[3] = (MyPlaneDef)[3]; \ + dGeomMoved (MyPlane); \ + } +//////// Local Build Option //////////////////////////////////////////////////// + +// Uncomment this #define to use the (0,0) corner of the geom as the origin, +// rather than the center. This was the way the original heightfield worked, +// but as it does not match the way all other geometries work, so for constancy it +// was changed to work like this. + +// #define DHEIGHTFIELD_CORNER_ORIGIN + + +// Uncomment this #define to add heightfield triangles edge colliding +// Code is not guaranteed and I didn't find the need to add that as +// colliding planes triangles and edge triangles seems enough. +// #define _HEIGHTFIELDEDGECOLLIDING + + +//////// dxHeightfieldData ///////////////////////////////////////////////////////////// + +// dxHeightfieldData constructor +dxHeightfieldData::dxHeightfieldData(): + m_fWidth( 0 ), + m_fDepth( 0 ), + m_fSampleWidth( 0 ), + m_fSampleDepth( 0 ), + m_fSampleZXAspect( 0 ), + m_fInvSampleWidth( 0 ), + m_fInvSampleDepth( 0 ), + + m_fHalfWidth( 0 ), + m_fHalfDepth( 0 ), + + m_fMinHeight( 0 ), + m_fMaxHeight( 0 ), + m_fThickness( 0 ), + m_fScale( 0 ), + m_fOffset( 0 ), + + m_nWidthSamples( 0 ), + m_nDepthSamples( 0 ), + m_bCopyHeightData( 0 ), + m_bWrapMode( 0 ), + m_nGetHeightMode( 0 ), + + m_pHeightData( NULL ), + m_pUserData( NULL ), + + m_pGetHeightCallback( NULL ) +{ + memset( m_contacts, 0, sizeof( m_contacts ) ); +} + +// build Heightfield data +void dxHeightfieldData::SetData( int nWidthSamples, int nDepthSamples, + dReal fWidth, dReal fDepth, + dReal fScale, dReal fOffset, dReal fThickness, + int bWrapMode ) +{ + dIASSERT( fWidth > REAL( 0.0 ) ); + dIASSERT( fDepth > REAL( 0.0 ) ); + dIASSERT( nWidthSamples > 0 ); + dIASSERT( nDepthSamples > 0 ); + + // x,z bounds + m_fWidth = fWidth; + m_fDepth = fDepth; + + // cache half x,z bounds + m_fHalfWidth = fWidth / REAL( 2.0 ); + m_fHalfDepth = fDepth / REAL( 2.0 ); + + // scale and offset + m_fScale = fScale; + m_fOffset = fOffset; + + // infinite min height bounds + m_fThickness = fThickness; + + // number of vertices per side + m_nWidthSamples = nWidthSamples; + m_nDepthSamples = nDepthSamples; + + m_fSampleWidth = m_fWidth / ( m_nWidthSamples - REAL( 1.0 ) ); + m_fSampleDepth = m_fDepth / ( m_nDepthSamples - REAL( 1.0 ) ); + + m_fSampleZXAspect = m_fSampleDepth / m_fSampleWidth; + + m_fInvSampleWidth = REAL( 1.0 ) / m_fSampleWidth; + m_fInvSampleDepth = REAL( 1.0 ) / m_fSampleDepth; + + // finite or repeated terrain? + m_bWrapMode = bWrapMode; +} + + +// recomputes heights bounds +void dxHeightfieldData::ComputeHeightBounds() +{ + int i; + dReal h; + unsigned char *data_byte; + short *data_short; + float *data_float; + double *data_double; + + switch ( m_nGetHeightMode ) + { + + // callback + case 0: + // change nothing, keep using default or user specified bounds + return; + + // byte + case 1: + data_byte = (unsigned char*)m_pHeightData; + m_fMinHeight = dInfinity; + m_fMaxHeight = -dInfinity; + + for (i=0; i<m_nWidthSamples*m_nDepthSamples; i++) + { + h = data_byte[i]; + if (h < m_fMinHeight) m_fMinHeight = h; + if (h > m_fMaxHeight) m_fMaxHeight = h; + } + + break; + + // short + case 2: + data_short = (short*)m_pHeightData; + m_fMinHeight = dInfinity; + m_fMaxHeight = -dInfinity; + + for (i=0; i<m_nWidthSamples*m_nDepthSamples; i++) + { + h = data_short[i]; + if (h < m_fMinHeight) m_fMinHeight = h; + if (h > m_fMaxHeight) m_fMaxHeight = h; + } + + break; + + // float + case 3: + data_float = (float*)m_pHeightData; + m_fMinHeight = dInfinity; + m_fMaxHeight = -dInfinity; + + for (i=0; i<m_nWidthSamples*m_nDepthSamples; i++) + { + h = data_float[i]; + if (h < m_fMinHeight) m_fMinHeight = h; + if (h > m_fMaxHeight) m_fMaxHeight = h; + } + + break; + + // double + case 4: + data_double = (double*)m_pHeightData; + m_fMinHeight = dInfinity; + m_fMaxHeight = -dInfinity; + + for (i=0; i<m_nWidthSamples*m_nDepthSamples; i++) + { + h = static_cast< dReal >( data_double[i] ); + if (h < m_fMinHeight) m_fMinHeight = h; + if (h > m_fMaxHeight) m_fMaxHeight = h; + } + + break; + + } + + // scale and offset + m_fMinHeight *= m_fScale; + m_fMaxHeight *= m_fScale; + m_fMinHeight += m_fOffset; + m_fMaxHeight += m_fOffset; + + // add thickness + m_fMinHeight -= m_fThickness; +} + + +// returns whether point is over terrain Cell triangle? +bool dxHeightfieldData::IsOnHeightfield2 ( const HeightFieldVertex * const CellCorner, + const dReal * const pos, const bool isABC) const +{ + // WARNING!!! + // This function must be written in the way to make sure that every point on + // XZ plane falls in one and only one triangle. Keep that in mind if you + // intend to change the code. + // Also remember about computational errors and possible mismatches in + // values if they are calculated differently in different places in the code. + // Currently both the implementation has been optimized and effects of + // computational errors have been eliminated. + + dReal MaxX, MinX; + dReal MaxZ, MinZ; + + if (isABC) + { + // point A + MinX = CellCorner->vertex[0]; + if (pos[0] < MinX) + return false; + + MaxX = (CellCorner->coords[0] + 1) * m_fSampleWidth; + if (pos[0] >= MaxX) + return false; + + MinZ = CellCorner->vertex[2]; + if (pos[2] < MinZ) + return false; + + MaxZ = (CellCorner->coords[1] + 1) * m_fSampleDepth; + if (pos[2] >= MaxZ) + return false; + + return (MaxZ - pos[2]) > (pos[0] - MinX) * m_fSampleZXAspect; + } + else + { + // point D + MaxX = CellCorner->vertex[0]; + if (pos[0] >= MaxX) + return false; + + MinX = (CellCorner->coords[0] - 1) * m_fSampleWidth; + if (pos[0] < MinX) + return false; + + MaxZ = CellCorner->vertex[2]; + if (pos[2] >= MaxZ) + return false; + + MinZ = (CellCorner->coords[1] - 1) * m_fSampleDepth; + if (pos[2] < MinZ) + return false; + + return (MaxZ - pos[2]) <= (pos[0] - MinX) * m_fSampleZXAspect; + } +} + + +// returns height at given sample coordinates +dReal dxHeightfieldData::GetHeight( int x, int z ) +{ + dReal h=0; + unsigned char *data_byte; + short *data_short; + float *data_float; + double *data_double; + + if ( m_bWrapMode == 0 ) + { + // Finite + if ( x < 0 ) x = 0; + if ( z < 0 ) z = 0; + if ( x > m_nWidthSamples - 1 ) x = m_nWidthSamples - 1; + if ( z > m_nDepthSamples - 1 ) z = m_nDepthSamples - 1; + } + else + { + // Infinite + x %= m_nWidthSamples - 1; + z %= m_nDepthSamples - 1; + if ( x < 0 ) x += m_nWidthSamples - 1; + if ( z < 0 ) z += m_nDepthSamples - 1; + } + + switch ( m_nGetHeightMode ) + { + + // callback (dReal) + case 0: + h = (*m_pGetHeightCallback)(m_pUserData, x, z); + break; + + // byte + case 1: + data_byte = (unsigned char*)m_pHeightData; + h = data_byte[x+(z * m_nWidthSamples)]; + break; + + // short + case 2: + data_short = (short*)m_pHeightData; + h = data_short[x+(z * m_nWidthSamples)]; + break; + + // float + case 3: + data_float = (float*)m_pHeightData; + h = data_float[x+(z * m_nWidthSamples)]; + break; + + // double + case 4: + data_double = (double*)m_pHeightData; + h = (dReal)( data_double[x+(z * m_nWidthSamples)] ); + break; + } + + return (h * m_fScale) + m_fOffset; +} + + +// returns height at given coordinates +dReal dxHeightfieldData::GetHeight( dReal x, dReal z ) +{ + dReal dnX = dFloor( x * m_fInvSampleWidth ); + dReal dnZ = dFloor( z * m_fInvSampleDepth ); + + dReal dx = ( x - ( dnX * m_fSampleWidth ) ) * m_fInvSampleWidth; + dReal dz = ( z - ( dnZ * m_fSampleDepth ) ) * m_fInvSampleDepth; + + int nX = int( dnX ); + int nZ = int( dnZ ); + + //dIASSERT( ( dx + dEpsilon >= 0.0f ) && ( dx - dEpsilon <= 1.0f ) ); + //dIASSERT( ( dz + dEpsilon >= 0.0f ) && ( dz - dEpsilon <= 1.0f ) ); + + dReal y, y0; + + if ( dx + dz <= REAL( 1.0 ) ) // Use <= comparison to prefer simpler branch + { + y0 = GetHeight( nX, nZ ); + + y = y0 + ( GetHeight( nX + 1, nZ ) - y0 ) * dx + + ( GetHeight( nX, nZ + 1 ) - y0 ) * dz; + } + else + { + y0 = GetHeight( nX + 1, nZ + 1 ); + + y = y0 + ( GetHeight( nX + 1, nZ ) - y0 ) * ( REAL(1.0) - dz ) + + ( GetHeight( nX, nZ + 1 ) - y0 ) * ( REAL(1.0) - dx ); + } + + return y; +} + + +// dxHeightfieldData destructor +dxHeightfieldData::~dxHeightfieldData() +{ + unsigned char *data_byte; + short *data_short; + float *data_float; + double *data_double; + + if ( m_bCopyHeightData ) + { + switch ( m_nGetHeightMode ) + { + + // callback + case 0: + // do nothing + break; + + // byte + case 1: + dIASSERT( m_pHeightData ); + data_byte = (unsigned char*)m_pHeightData; + delete [] data_byte; + break; + + // short + case 2: + dIASSERT( m_pHeightData ); + data_short = (short*)m_pHeightData; + delete [] data_short; + break; + + // float + case 3: + dIASSERT( m_pHeightData ); + data_float = (float*)m_pHeightData; + delete [] data_float; + break; + + // double + case 4: + dIASSERT( m_pHeightData ); + data_double = (double*)m_pHeightData; + delete [] data_double; + break; + + } + } +} + + +//////// dxHeightfield ///////////////////////////////////////////////////////////////// + + +// dxHeightfield constructor +dxHeightfield::dxHeightfield( dSpaceID space, + dHeightfieldDataID data, + int bPlaceable ) : + dxGeom( space, bPlaceable ), + tempPlaneBuffer(0), + tempPlaneInstances(0), + tempPlaneBufferSize(0), + tempTriangleBuffer(0), + tempTriangleBufferSize(0), + tempHeightBuffer(0), + tempHeightInstances(0), + tempHeightBufferSizeX(0), + tempHeightBufferSizeZ(0) +{ + type = dHeightfieldClass; + this->m_p_data = data; +} + + +// compute axis aligned bounding box +void dxHeightfield::computeAABB() +{ + const dxHeightfieldData *d = m_p_data; + + if ( d->m_bWrapMode == 0 ) + { + // Finite + if ( gflags & GEOM_PLACEABLE ) + { + dReal dx[6], dy[6], dz[6]; + + // Y-axis + if (d->m_fMinHeight != -dInfinity) + { + dy[0] = ( final_posr->R[ 1] * d->m_fMinHeight ); + dy[1] = ( final_posr->R[ 5] * d->m_fMinHeight ); + dy[2] = ( final_posr->R[ 9] * d->m_fMinHeight ); + } + else + { + // Multiplication is performed to obtain infinity of correct sign + dy[0] = ( final_posr->R[ 1] ? final_posr->R[ 1] * -dInfinity : REAL(0.0) ); + dy[1] = ( final_posr->R[ 5] ? final_posr->R[ 5] * -dInfinity : REAL(0.0) ); + dy[2] = ( final_posr->R[ 9] ? final_posr->R[ 9] * -dInfinity : REAL(0.0) ); + } + + if (d->m_fMaxHeight != dInfinity) + { + dy[3] = ( final_posr->R[ 1] * d->m_fMaxHeight ); + dy[4] = ( final_posr->R[ 5] * d->m_fMaxHeight ); + dy[5] = ( final_posr->R[ 9] * d->m_fMaxHeight ); + } + else + { + dy[3] = ( final_posr->R[ 1] ? final_posr->R[ 1] * dInfinity : REAL(0.0) ); + dy[4] = ( final_posr->R[ 5] ? final_posr->R[ 5] * dInfinity : REAL(0.0) ); + dy[5] = ( final_posr->R[ 9] ? final_posr->R[ 9] * dInfinity : REAL(0.0) ); + } + +#ifdef DHEIGHTFIELD_CORNER_ORIGIN + + // X-axis + dx[0] = 0; dx[3] = ( final_posr->R[ 0] * d->m_fWidth ); + dx[1] = 0; dx[4] = ( final_posr->R[ 4] * d->m_fWidth ); + dx[2] = 0; dx[5] = ( final_posr->R[ 8] * d->m_fWidth ); + + // Z-axis + dz[0] = 0; dz[3] = ( final_posr->R[ 2] * d->m_fDepth ); + dz[1] = 0; dz[4] = ( final_posr->R[ 6] * d->m_fDepth ); + dz[2] = 0; dz[5] = ( final_posr->R[10] * d->m_fDepth ); + +#else // DHEIGHTFIELD_CORNER_ORIGIN + + // X-axis + dx[0] = ( final_posr->R[ 0] * -d->m_fHalfWidth ); + dx[1] = ( final_posr->R[ 4] * -d->m_fHalfWidth ); + dx[2] = ( final_posr->R[ 8] * -d->m_fHalfWidth ); + dx[3] = ( final_posr->R[ 0] * d->m_fHalfWidth ); + dx[4] = ( final_posr->R[ 4] * d->m_fHalfWidth ); + dx[5] = ( final_posr->R[ 8] * d->m_fHalfWidth ); + + // Z-axis + dz[0] = ( final_posr->R[ 2] * -d->m_fHalfDepth ); + dz[1] = ( final_posr->R[ 6] * -d->m_fHalfDepth ); + dz[2] = ( final_posr->R[10] * -d->m_fHalfDepth ); + dz[3] = ( final_posr->R[ 2] * d->m_fHalfDepth ); + dz[4] = ( final_posr->R[ 6] * d->m_fHalfDepth ); + dz[5] = ( final_posr->R[10] * d->m_fHalfDepth ); + +#endif // DHEIGHTFIELD_CORNER_ORIGIN + + // X extents + aabb[0] = final_posr->pos[0] + + dMIN3( dMIN( dx[0], dx[3] ), dMIN( dy[0], dy[3] ), dMIN( dz[0], dz[3] ) ); + aabb[1] = final_posr->pos[0] + + dMAX3( dMAX( dx[0], dx[3] ), dMAX( dy[0], dy[3] ), dMAX( dz[0], dz[3] ) ); + + // Y extents + aabb[2] = final_posr->pos[1] + + dMIN3( dMIN( dx[1], dx[4] ), dMIN( dy[1], dy[4] ), dMIN( dz[1], dz[4] ) ); + aabb[3] = final_posr->pos[1] + + dMAX3( dMAX( dx[1], dx[4] ), dMAX( dy[1], dy[4] ), dMAX( dz[1], dz[4] ) ); + + // Z extents + aabb[4] = final_posr->pos[2] + + dMIN3( dMIN( dx[2], dx[5] ), dMIN( dy[2], dy[5] ), dMIN( dz[2], dz[5] ) ); + aabb[5] = final_posr->pos[2] + + dMAX3( dMAX( dx[2], dx[5] ), dMAX( dy[2], dy[5] ), dMAX( dz[2], dz[5] ) ); + } + else + { + +#ifdef DHEIGHTFIELD_CORNER_ORIGIN + + aabb[0] = 0; aabb[1] = d->m_fWidth; + aabb[2] = d->m_fMinHeight; aabb[3] = d->m_fMaxHeight; + aabb[4] = 0; aabb[5] = d->m_fDepth; + +#else // DHEIGHTFIELD_CORNER_ORIGIN + + aabb[0] = -d->m_fHalfWidth; aabb[1] = +d->m_fHalfWidth; + aabb[2] = d->m_fMinHeight; aabb[3] = d->m_fMaxHeight; + aabb[4] = -d->m_fHalfDepth; aabb[5] = +d->m_fHalfDepth; + +#endif // DHEIGHTFIELD_CORNER_ORIGIN + + } + } + else + { + // Infinite + if ( gflags & GEOM_PLACEABLE ) + { + aabb[0] = -dInfinity; aabb[1] = +dInfinity; + aabb[2] = -dInfinity; aabb[3] = +dInfinity; + aabb[4] = -dInfinity; aabb[5] = +dInfinity; + } + else + { + aabb[0] = -dInfinity; aabb[1] = +dInfinity; + aabb[2] = d->m_fMinHeight; aabb[3] = d->m_fMaxHeight; + aabb[4] = -dInfinity; aabb[5] = +dInfinity; + } + } + +} + + +// dxHeightfield destructor +dxHeightfield::~dxHeightfield() +{ + resetTriangleBuffer(); + resetPlaneBuffer(); + resetHeightBuffer(); +} + +void dxHeightfield::allocateTriangleBuffer(sizeint numTri) +{ + sizeint alignedNumTri = AlignBufferSize(numTri, TEMP_TRIANGLE_BUFFER_ELEMENT_COUNT_ALIGNMENT); + tempTriangleBufferSize = alignedNumTri; + tempTriangleBuffer = new HeightFieldTriangle[alignedNumTri]; +} + +void dxHeightfield::resetTriangleBuffer() +{ + delete[] tempTriangleBuffer; +} + +void dxHeightfield::allocatePlaneBuffer(sizeint numTri) +{ + sizeint alignedNumTri = AlignBufferSize(numTri, TEMP_PLANE_BUFFER_ELEMENT_COUNT_ALIGNMENT); + tempPlaneBufferSize = alignedNumTri; + tempPlaneBuffer = new HeightFieldPlane *[alignedNumTri]; + tempPlaneInstances = new HeightFieldPlane[alignedNumTri]; + + HeightFieldPlane *ptrPlaneMatrix = tempPlaneInstances; + for (sizeint indexTri = 0; indexTri != alignedNumTri; indexTri++) + { + tempPlaneBuffer[indexTri] = ptrPlaneMatrix; + ptrPlaneMatrix += 1; + } +} + +void dxHeightfield::resetPlaneBuffer() +{ + delete[] tempPlaneInstances; + delete[] tempPlaneBuffer; +} + +void dxHeightfield::allocateHeightBuffer(sizeint numX, sizeint numZ) +{ + sizeint alignedNumX = AlignBufferSize(numX, TEMP_HEIGHT_BUFFER_ELEMENT_COUNT_ALIGNMENT_X); + sizeint alignedNumZ = AlignBufferSize(numZ, TEMP_HEIGHT_BUFFER_ELEMENT_COUNT_ALIGNMENT_Z); + tempHeightBufferSizeX = alignedNumX; + tempHeightBufferSizeZ = alignedNumZ; + tempHeightBuffer = new HeightFieldVertex *[alignedNumX]; + sizeint numCells = alignedNumX * alignedNumZ; + tempHeightInstances = new HeightFieldVertex [numCells]; + + HeightFieldVertex *ptrHeightMatrix = tempHeightInstances; + for (sizeint indexX = 0; indexX != alignedNumX; indexX++) + { + tempHeightBuffer[indexX] = ptrHeightMatrix; + ptrHeightMatrix += alignedNumZ; + } +} + +void dxHeightfield::resetHeightBuffer() +{ + delete[] tempHeightInstances; + delete[] tempHeightBuffer; +} +//////// Heightfield data interface //////////////////////////////////////////////////// + + +dHeightfieldDataID dGeomHeightfieldDataCreate() +{ + return new dxHeightfieldData(); +} + + +void dGeomHeightfieldDataBuildCallback( dHeightfieldDataID d, + void* pUserData, dHeightfieldGetHeight* pCallback, + dReal width, dReal depth, int widthSamples, int depthSamples, + dReal scale, dReal offset, dReal thickness, int bWrap ) +{ + dUASSERT( d, "argument not Heightfield data" ); + dIASSERT( pCallback ); + dIASSERT( widthSamples >= 2 ); // Ensure we're making something with at least one cell. + dIASSERT( depthSamples >= 2 ); + + // callback + d->m_nGetHeightMode = 0; + d->m_pUserData = pUserData; + d->m_pGetHeightCallback = pCallback; + + // set info + d->SetData( widthSamples, depthSamples, width, depth, scale, offset, thickness, bWrap ); + + // default bounds + d->m_fMinHeight = -dInfinity; + d->m_fMaxHeight = dInfinity; +} + + +void dGeomHeightfieldDataBuildByte( dHeightfieldDataID d, + const unsigned char *pHeightData, int bCopyHeightData, + dReal width, dReal depth, int widthSamples, int depthSamples, + dReal scale, dReal offset, dReal thickness, int bWrap ) +{ + dUASSERT( d, "Argument not Heightfield data" ); + dIASSERT( pHeightData ); + dIASSERT( widthSamples >= 2 ); // Ensure we're making something with at least one cell. + dIASSERT( depthSamples >= 2 ); + + // set info + d->SetData( widthSamples, depthSamples, width, depth, scale, offset, thickness, bWrap ); + d->m_nGetHeightMode = 1; + d->m_bCopyHeightData = bCopyHeightData; + + if ( d->m_bCopyHeightData == 0 ) + { + // Data is referenced only. + d->m_pHeightData = pHeightData; + } + else + { + // We own the height data, allocate storage + d->m_pHeightData = new unsigned char[ d->m_nWidthSamples * d->m_nDepthSamples ]; + dIASSERT( d->m_pHeightData ); + + // Copy data. + memcpy( (void*)d->m_pHeightData, pHeightData, + sizeof( unsigned char ) * d->m_nWidthSamples * d->m_nDepthSamples ); + } + + // Find height bounds + d->ComputeHeightBounds(); +} + + +void dGeomHeightfieldDataBuildShort( dHeightfieldDataID d, + const short* pHeightData, int bCopyHeightData, + dReal width, dReal depth, int widthSamples, int depthSamples, + dReal scale, dReal offset, dReal thickness, int bWrap ) +{ + dUASSERT( d, "Argument not Heightfield data" ); + dIASSERT( pHeightData ); + dIASSERT( widthSamples >= 2 ); // Ensure we're making something with at least one cell. + dIASSERT( depthSamples >= 2 ); + + // set info + d->SetData( widthSamples, depthSamples, width, depth, scale, offset, thickness, bWrap ); + d->m_nGetHeightMode = 2; + d->m_bCopyHeightData = bCopyHeightData; + + if ( d->m_bCopyHeightData == 0 ) + { + // Data is referenced only. + d->m_pHeightData = pHeightData; + } + else + { + // We own the height data, allocate storage + d->m_pHeightData = new short[ d->m_nWidthSamples * d->m_nDepthSamples ]; + dIASSERT( d->m_pHeightData ); + + // Copy data. + memcpy( (void*)d->m_pHeightData, pHeightData, + sizeof( short ) * d->m_nWidthSamples * d->m_nDepthSamples ); + } + + // Find height bounds + d->ComputeHeightBounds(); +} + + +void dGeomHeightfieldDataBuildSingle( dHeightfieldDataID d, + const float *pHeightData, int bCopyHeightData, + dReal width, dReal depth, int widthSamples, int depthSamples, + dReal scale, dReal offset, dReal thickness, int bWrap ) +{ + dUASSERT( d, "Argument not Heightfield data" ); + dIASSERT( pHeightData ); + dIASSERT( widthSamples >= 2 ); // Ensure we're making something with at least one cell. + dIASSERT( depthSamples >= 2 ); + + // set info + d->SetData( widthSamples, depthSamples, width, depth, scale, offset, thickness, bWrap ); + d->m_nGetHeightMode = 3; + d->m_bCopyHeightData = bCopyHeightData; + + if ( d->m_bCopyHeightData == 0 ) + { + // Data is referenced only. + d->m_pHeightData = pHeightData; + } + else + { + // We own the height data, allocate storage + d->m_pHeightData = new float[ d->m_nWidthSamples * d->m_nDepthSamples ]; + dIASSERT( d->m_pHeightData ); + + // Copy data. + memcpy( (void*)d->m_pHeightData, pHeightData, + sizeof( float ) * d->m_nWidthSamples * d->m_nDepthSamples ); + } + + // Find height bounds + d->ComputeHeightBounds(); +} + +void dGeomHeightfieldDataBuildDouble( dHeightfieldDataID d, + const double *pHeightData, int bCopyHeightData, + dReal width, dReal depth, int widthSamples, int depthSamples, + dReal scale, dReal offset, dReal thickness, int bWrap ) +{ + dUASSERT( d, "Argument not Heightfield data" ); + dIASSERT( pHeightData ); + dIASSERT( widthSamples >= 2 ); // Ensure we're making something with at least one cell. + dIASSERT( depthSamples >= 2 ); + + // set info + d->SetData( widthSamples, depthSamples, width, depth, scale, offset, thickness, bWrap ); + d->m_nGetHeightMode = 4; + d->m_bCopyHeightData = bCopyHeightData; + + if ( d->m_bCopyHeightData == 0 ) + { + // Data is referenced only. + d->m_pHeightData = pHeightData; + } + else + { + // We own the height data, allocate storage + d->m_pHeightData = new double[ d->m_nWidthSamples * d->m_nDepthSamples ]; + dIASSERT( d->m_pHeightData ); + + // Copy data. + memcpy( (void*)d->m_pHeightData, pHeightData, + sizeof( double ) * d->m_nWidthSamples * d->m_nDepthSamples ); + } + + // Find height bounds + d->ComputeHeightBounds(); +} + + + + +void dGeomHeightfieldDataSetBounds( dHeightfieldDataID d, dReal minHeight, dReal maxHeight ) +{ + dUASSERT(d, "Argument not Heightfield data"); + d->m_fMinHeight = ( minHeight * d->m_fScale ) + d->m_fOffset - d->m_fThickness; + d->m_fMaxHeight = ( maxHeight * d->m_fScale ) + d->m_fOffset; +} + + +void dGeomHeightfieldDataDestroy( dHeightfieldDataID d ) +{ + dUASSERT(d, "argument not Heightfield data"); + delete d; +} + + +//////// Heightfield geom interface //////////////////////////////////////////////////// + + +dGeomID dCreateHeightfield( dSpaceID space, dHeightfieldDataID data, int bPlaceable ) +{ + return new dxHeightfield( space, data, bPlaceable ); +} + + +void dGeomHeightfieldSetHeightfieldData( dGeomID g, dHeightfieldDataID d ) +{ + dxHeightfield* geom = (dxHeightfield*) g; + geom->m_p_data = d; +} + + +dHeightfieldDataID dGeomHeightfieldGetHeightfieldData( dGeomID g ) +{ + dxHeightfield* geom = (dxHeightfield*) g; + return geom->m_p_data; +} + +//////// dxHeightfield ///////////////////////////////////////////////////////////////// + + +// Typedef for generic 'get point depth' function +typedef dReal dGetDepthFn( dGeomID g, dReal x, dReal y, dReal z ); + + +#define DMESS(A) \ + dMessage(0,"Contact Plane (%d %d %d) %.5e %.5e (%.5e %.5e %.5e)(%.5e %.5e %.5e)).", \ + x,z,(A), \ + pContact->depth, \ + dGeomSphereGetRadius(o2), \ + pContact->pos[0], \ + pContact->pos[1], \ + pContact->pos[2], \ + pContact->normal[0], \ + pContact->normal[1], \ + pContact->normal[2]); + +static inline bool DescendingTriangleSort(const HeightFieldTriangle * const A, const HeightFieldTriangle * const B) +{ + return ((A->maxAAAB - B->maxAAAB) > dEpsilon); +} +static inline bool DescendingPlaneSort(const HeightFieldPlane * const A, const HeightFieldPlane * const B) +{ + return ((A->maxAAAB - B->maxAAAB) > dEpsilon); +} + +void dxHeightfield::sortPlanes(const sizeint numPlanes) +{ + bool has_swapped = true; + do + { + has_swapped = false;//reset flag + for (sizeint i = 0; i < numPlanes - 1; i++) + { + //if they are in the wrong order + if (DescendingPlaneSort(tempPlaneBuffer[i], tempPlaneBuffer[i + 1])) + { + //exchange them + HeightFieldPlane * tempPlane = tempPlaneBuffer[i]; + tempPlaneBuffer[i] = tempPlaneBuffer[i + 1]; + tempPlaneBuffer[i + 1] = tempPlane; + + //we have swapped at least once, list may not be sorted yet + has_swapped = true; + } + } + } //if no swaps were made during this pass, the list has been sorted + while (has_swapped); +} + +static inline dReal DistancePointToLine(const dVector3 &_point, + const dVector3 &_pt0, + const dVector3 &_Edge, + const dReal _Edgelength) +{ + dVector3 v; + dVector3Subtract(_point, _pt0, v); + dVector3 s; + dVector3Copy (_Edge, s); + const dReal dot = dVector3Dot(v, _Edge) / _Edgelength; + dVector3Scale(s, dot); + dVector3Subtract(v, s, v); + return dVector3Length(v); +} + + + + +int dxHeightfield::dCollideHeightfieldZone( const int minX, const int maxX, const int minZ, const int maxZ, + dxGeom* o2, const int numMaxContactsPossible, + int flags, dContactGeom* contact, + int skip ) +{ + dContactGeom *pContact = 0; + int x, z; + // check if not above or inside terrain first + // while filling a heightmap partial temporary buffer + const unsigned int numX = (maxX - minX) + 1; + const unsigned int numZ = (maxZ - minZ) + 1; + const dReal minO2Height = o2->aabb[2]; + const dReal maxO2Height = o2->aabb[3]; + unsigned int x_local, z_local; + dReal maxY = - dInfinity; + dReal minY = dInfinity; + // localize and const for faster access + const dReal cfSampleWidth = m_p_data->m_fSampleWidth; + const dReal cfSampleDepth = m_p_data->m_fSampleDepth; + { + if (tempHeightBufferSizeX < numX || tempHeightBufferSizeZ < numZ) + { + resetHeightBuffer(); + allocateHeightBuffer(numX, numZ); + } + + dReal Xpos, Ypos; + + for ( x = minX, x_local = 0; x_local < numX; x++, x_local++) + { + Xpos = x * cfSampleWidth; // Always calculate pos via multiplication to avoid computational error accumulation during multiple additions + + const dReal c_Xpos = Xpos; + HeightFieldVertex *HeightFieldRow = tempHeightBuffer[x_local]; + for ( z = minZ, z_local = 0; z_local < numZ; z++, z_local++) + { + Ypos = z * cfSampleDepth; // Always calculate pos via multiplication to avoid computational error accumulation during multiple additions + + const dReal h = m_p_data->GetHeight(x, z); + HeightFieldRow[z_local].vertex[0] = c_Xpos; + HeightFieldRow[z_local].vertex[1] = h; + HeightFieldRow[z_local].vertex[2] = Ypos; + HeightFieldRow[z_local].coords[0] = x; + HeightFieldRow[z_local].coords[1] = z; + + maxY = dMAX(maxY, h); + minY = dMIN(minY, h); + } + } + if (minO2Height - maxY > -dEpsilon ) + { + //totally above heightfield + return 0; + } + if (minY - maxO2Height > -dEpsilon ) + { + // totally under heightfield + pContact = CONTACT(contact, 0); + + pContact->pos[0] = o2->final_posr->pos[0]; + pContact->pos[1] = minY; + pContact->pos[2] = o2->final_posr->pos[2]; + + pContact->normal[0] = 0; + pContact->normal[1] = - 1; + pContact->normal[2] = 0; + + pContact->depth = minY - maxO2Height; + + pContact->side1 = -1; + pContact->side2 = -1; + + return 1; + } + } + // get All Planes that could collide against. + dColliderFn *geomRayNCollider=0; + dColliderFn *geomNPlaneCollider=0; + dGetDepthFn *geomNDepthGetter=0; + + // int max_collisionContact = numMaxContactsPossible; -- not used + switch (o2->type) + { + case dRayClass: + geomRayNCollider = NULL; + geomNPlaneCollider = dCollideRayPlane; + geomNDepthGetter = NULL; + //max_collisionContact = 1; + break; + + case dSphereClass: + geomRayNCollider = dCollideRaySphere; + geomNPlaneCollider = dCollideSpherePlane; + geomNDepthGetter = dGeomSpherePointDepth; + //max_collisionContact = 3; + break; + + case dBoxClass: + geomRayNCollider = dCollideRayBox; + geomNPlaneCollider = dCollideBoxPlane; + geomNDepthGetter = dGeomBoxPointDepth; + //max_collisionContact = 8; + break; + + case dCapsuleClass: + geomRayNCollider = dCollideRayCapsule; + geomNPlaneCollider = dCollideCapsulePlane; + geomNDepthGetter = dGeomCapsulePointDepth; + // max_collisionContact = 3; + break; + + case dCylinderClass: + geomRayNCollider = dCollideRayCylinder; + geomNPlaneCollider = dCollideCylinderPlane; + geomNDepthGetter = NULL;// TODO: dGeomCCylinderPointDepth + //max_collisionContact = 3; + break; + + case dConvexClass: + geomRayNCollider = dCollideRayConvex; + geomNPlaneCollider = dCollideConvexPlane; + geomNDepthGetter = NULL;// TODO: dGeomConvexPointDepth; + //max_collisionContact = 3; + break; + +#if dTRIMESH_ENABLED + + case dTriMeshClass: + geomRayNCollider = dCollideRayTrimesh; + geomNPlaneCollider = dCollideTrimeshPlane; + geomNDepthGetter = NULL;// TODO: dGeomTrimeshPointDepth; + //max_collisionContact = 3; + break; + +#endif // dTRIMESH_ENABLED + + default: + dIASSERT(0); // Shouldn't ever get here. + break; + + } + + dxPlane myplane(0,0,0,0,0); + dxPlane* sliding_plane = &myplane; + dReal triplane[4]; + int i; + + // check some trivial case. + // Vector Up plane + if (maxY - minY < dEpsilon) + { + // it's a single plane. + triplane[0] = 0; + triplane[1] = 1; + triplane[2] = 0; + triplane[3] = minY; + dGeomPlaneSetNoNormalize (sliding_plane, triplane); + // find collision and compute contact points + const int numTerrainContacts = geomNPlaneCollider (o2, sliding_plane, flags, contact, skip); + dIASSERT(numTerrainContacts <= numMaxContactsPossible); + for (i = 0; i < numTerrainContacts; i++) + { + pContact = CONTACT(contact, i*skip); + dOPESIGN(pContact->normal, =, -, triplane); + } + return numTerrainContacts; + } + + /* -- This block is invalid as per Martijn Buijs <buijs512@planet.nl> + + The problem seems to be based on the erroneously assumption that if two of + the four vertices of a 'grid' are at the same height, the entire grid can be + represented as a single plane. It works for an axis aligned slope, but fails + on all 4 grids of a 3x3 spike feature. Since the plane normal is constructed + from only 3 vertices (only one of the two triangles) this often results in + discontinuities at the grid edges (causing small jumps when the contact + point moves from one grid to another). + + // unique plane + { + // check for very simple plane heightfield + dReal minXHeightDelta = dInfinity, maxXHeightDelta = - dInfinity; + dReal minZHeightDelta = dInfinity, maxZHeightDelta = - dInfinity; + + + dReal lastXHeight = tempHeightBuffer[0][0].vertex[1]; + for ( x_local = 1; x_local < numX; x_local++) + { + HeightFieldVertex *HeightFieldRow = tempHeightBuffer[x_local]; + + const dReal deltaX = HeightFieldRow[0].vertex[1] - lastXHeight; + + maxXHeightDelta = dMAX (maxXHeightDelta, deltaX); + minXHeightDelta = dMIN (minXHeightDelta, deltaX); + + dReal lastZHeight = HeightFieldRow[0].vertex[1]; + for ( z_local = 1; z_local < numZ; z_local++) + { + const dReal deltaZ = (HeightFieldRow[z_local].vertex[1] - lastZHeight); + + maxZHeightDelta = dMAX (maxZHeightDelta, deltaZ); + minZHeightDelta = dMIN (minZHeightDelta, deltaZ); + + } + } + + if (maxZHeightDelta - minZHeightDelta < dEpsilon && + maxXHeightDelta - minXHeightDelta < dEpsilon ) + { + // it's a single plane. + const dVector3 &A = tempHeightBuffer[0][0].vertex; + const dVector3 &B = tempHeightBuffer[1][0].vertex; + const dVector3 &C = tempHeightBuffer[0][1].vertex; + + // define 2 edges and a point that will define collision plane + { + dVector3 Edge1, Edge2; + dVector3Subtract(C, A, Edge1); + dVector3Subtract(B, A, Edge2); + dVector3Cross(Edge1, Edge2, triplane); + } + + // Define Plane + // Normalize plane normal + const dReal dinvlength = REAL(1.0) / dVector3Length(triplane); + triplane[0] *= dinvlength; + triplane[1] *= dinvlength; + triplane[2] *= dinvlength; + // get distance to origin from plane + triplane[3] = dVector3Dot(triplane, A); + + dGeomPlaneSetNoNormalize (sliding_plane, triplane); + // find collision and compute contact points + const int numTerrainContacts = geomNPlaneCollider (o2, sliding_plane, flags, contact, skip); + dIASSERT(numTerrainContacts <= numMaxContactsPossible); + for (i = 0; i < numTerrainContacts; i++) + { + pContact = CONTACT(contact, i*skip); + dOPESIGN(pContact->normal, =, -, triplane); + } + return numTerrainContacts; + } + } + */ + + int numTerrainContacts = 0; + dContactGeom *PlaneContact = m_p_data->m_contacts; + + const unsigned int numTriMax = (maxX - minX) * (maxZ - minZ) * 2; + if (tempTriangleBufferSize < numTriMax) + { + resetTriangleBuffer(); + allocateTriangleBuffer(numTriMax); + } + + // Sorting triangle/plane resulting from heightfield zone + // Perhaps that would be necessary in case of too much limited + // maximum contact point... + // or in complex mesh case (trimesh and convex) + // need some test or insights on this before enabling this. + const bool isContactNumPointsLimited = + true; + // (numMaxContacts < 8) + // || o2->type == dConvexClass + // || o2->type == dTriMeshClass + // || (numMaxContacts < (int)numTriMax) + + + + // if small heightfield triangle related to O2 colliding + // or no Triangle colliding at all. + bool needFurtherPasses = (o2->type == dTriMeshClass); + //compute Ratio between Triangle size and O2 aabb size + // no FurtherPasses are needed in ray class + if (o2->type != dRayClass && needFurtherPasses == false) + { + const dReal xratio = (o2->aabb[1] - o2->aabb[0]) * m_p_data->m_fInvSampleWidth; + if (xratio > REAL(1.5)) + needFurtherPasses = true; + else + { + const dReal zratio = (o2->aabb[5] - o2->aabb[4]) * m_p_data->m_fInvSampleDepth; + if (zratio > REAL(1.5)) + needFurtherPasses = true; + } + + } + + unsigned int numTri = 0; + HeightFieldVertex *A, *B, *C, *D; + /* (y is up) + A--------B-...x + | /| + | / | + | / | + | / | + | / | + | / | + | / | + |/ | + C--------D + . + . + . + z + */ + // keep only triangle that does intersect geom + + const unsigned int maxX_local = maxX - minX; + const unsigned int maxZ_local = maxZ - minZ; + + for ( x_local = 0; x_local < maxX_local; x_local++) + { + HeightFieldVertex *HeightFieldRow = tempHeightBuffer[x_local]; + HeightFieldVertex *HeightFieldNextRow = tempHeightBuffer[x_local + 1]; + + // First A + C = &HeightFieldRow [0]; + // First B + D = &HeightFieldNextRow[0]; + + for ( z_local = 0; z_local < maxZ_local; z_local++) + { + A = C; + B = D; + + C = &HeightFieldRow [z_local + 1]; + D = &HeightFieldNextRow[z_local + 1]; + + const dReal AHeight = A->vertex[1]; + const dReal BHeight = B->vertex[1]; + const dReal CHeight = C->vertex[1]; + const dReal DHeight = D->vertex[1]; + + const bool isACollide = AHeight > minO2Height; + const bool isBCollide = BHeight > minO2Height; + const bool isCCollide = CHeight > minO2Height; + const bool isDCollide = DHeight > minO2Height; + + A->state = !(isACollide); + B->state = !(isBCollide); + C->state = !(isCCollide); + D->state = !(isDCollide); + + if (isACollide || isBCollide || isCCollide) + { + HeightFieldTriangle * const CurrTriUp = &tempTriangleBuffer[numTri++]; + + CurrTriUp->state = false; + + // changing point order here implies to change it in isOnHeightField + CurrTriUp->vertices[0] = A; + CurrTriUp->vertices[1] = B; + CurrTriUp->vertices[2] = C; + + if (isContactNumPointsLimited) + CurrTriUp->setMinMax(); + CurrTriUp->isUp = true; + } + + if (isBCollide || isCCollide || isDCollide) + { + HeightFieldTriangle * const CurrTriDown = &tempTriangleBuffer[numTri++]; + + CurrTriDown->state = false; + // changing point order here implies to change it in isOnHeightField + + CurrTriDown->vertices[0] = D; + CurrTriDown->vertices[1] = B; + CurrTriDown->vertices[2] = C; + + + if (isContactNumPointsLimited) + CurrTriDown->setMinMax(); + CurrTriDown->isUp = false; + } + + + if (needFurtherPasses && + (isBCollide || isCCollide) + && + (AHeight > CHeight && + AHeight > BHeight && + DHeight > CHeight && + DHeight > BHeight)) + { + // That means Edge BC is concave, therefore + // BC Edge and B and C vertices cannot collide + + B->state = true; + C->state = true; + } + // should find a way to check other edges (AB, BD, CD) too for concavity + } + } + + // at least on triangle should intersect geom + dIASSERT (numTri != 0); + // pass1: VS triangle as Planes + // Group Triangle by same plane definition + // as Terrain often has many triangles using same plane definition + // then collide against that list of triangles. + { + + dVector3 Edge1, Edge2; + //compute all triangles normals. + for (unsigned int k = 0; k < numTri; k++) + { + HeightFieldTriangle * const itTriangle = &tempTriangleBuffer[k]; + + // define 2 edges and a point that will define collision plane + dVector3Subtract(itTriangle->vertices[2]->vertex, itTriangle->vertices[0]->vertex, Edge1); + dVector3Subtract(itTriangle->vertices[1]->vertex, itTriangle->vertices[0]->vertex, Edge2); + + // find a perpendicular vector to the triangle + if (itTriangle->isUp) + dVector3Cross(Edge1, Edge2, triplane); + else + dVector3Cross(Edge2, Edge1, triplane); + + // Define Plane + // Normalize plane normal + const dReal dinvlength = REAL(1.0) / dVector3Length(triplane); + triplane[0] *= dinvlength; + triplane[1] *= dinvlength; + triplane[2] *= dinvlength; + // get distance to origin from plane + triplane[3] = dVector3Dot(triplane, itTriangle->vertices[0]->vertex); + + // saves normal for collision check (planes, triangles, vertices and edges.) + dVector3Copy(triplane, itTriangle->planeDef); + // saves distance for collision check (planes, triangles, vertices and edges.) + itTriangle->planeDef[3] = triplane[3]; + } + + // group by Triangles by Planes sharing shame plane definition + if (tempPlaneBufferSize < numTri) + { + resetPlaneBuffer(); + allocatePlaneBuffer(numTri); + } + + unsigned int numPlanes = 0; + for (unsigned int k = 0; k < numTri; k++) + { + HeightFieldTriangle * const tri_base = &tempTriangleBuffer[k]; + + if (tri_base->state == true) + continue;// already tested or added to plane list. + + HeightFieldPlane * const currPlane = tempPlaneBuffer[numPlanes]; + currPlane->resetTriangleListSize(numTri - k); + currPlane->addTriangle(tri_base); + // saves normal for collision check (planes, triangles, vertices and edges.) + dVector3Copy(tri_base->planeDef, currPlane->planeDef); + // saves distance for collision check (planes, triangles, vertices and edges.) + currPlane->planeDef[3]= tri_base->planeDef[3]; + + const dReal normx = tri_base->planeDef[0]; + const dReal normy = tri_base->planeDef[1]; + const dReal normz = tri_base->planeDef[2]; + const dReal dist = tri_base->planeDef[3]; + + for (unsigned int m = k + 1; m < numTri; m++) + { + + HeightFieldTriangle * const tri_test = &tempTriangleBuffer[m]; + if (tri_test->state == true) + continue;// already tested or added to plane list. + + // normals and distance are the same. + if ( + dFabs(normy - tri_test->planeDef[1]) < dEpsilon && + dFabs(dist - tri_test->planeDef[3]) < dEpsilon && + dFabs(normx - tri_test->planeDef[0]) < dEpsilon && + dFabs(normz - tri_test->planeDef[2]) < dEpsilon + ) + { + currPlane->addTriangle (tri_test); + tri_test->state = true; + } + } + + tri_base->state = true; + if (isContactNumPointsLimited) + currPlane->setMinMax(); + + numPlanes++; + } + + // sort planes + if (isContactNumPointsLimited) + sortPlanes(numPlanes); + +#if !defined(NO_CONTACT_CULLING_BY_ISONHEIGHTFIELD2) + /* + Note by Oleh_Derevenko: + It seems to be incorrect to limit contact count by some particular value + since some of them (and even all of them) may be culled in following condition. + However I do not see an easy way to fix this. + If not that culling the flags modification should be changed here and + additionally repeated after some contacts have been generated (in "if (didCollide)"). + The maximum of contacts in flags would then be set to minimum of contacts + remaining and HEIGHTFIELDMAXCONTACTPERCELL. + */ + int planeTestFlags = (flags & ~NUMC_MASK) | HEIGHTFIELDMAXCONTACTPERCELL; + dIASSERT((HEIGHTFIELDMAXCONTACTPERCELL & ~NUMC_MASK) == 0); +#else // if defined(NO_CONTACT_CULLING_BY_ISONHEIGHTFIELD2) + int numMaxContactsPerPlane = dMIN(numMaxContactsPossible - numTerrainContacts, HEIGHTFIELDMAXCONTACTPERCELL); + int planeTestFlags = (flags & ~NUMC_MASK) | numMaxContactsPerPlane; + dIASSERT((HEIGHTFIELDMAXCONTACTPERCELL & ~NUMC_MASK) == 0); +#endif + + for (unsigned int k = 0; k < numPlanes; k++) + { + HeightFieldPlane * const itPlane = tempPlaneBuffer[k]; + + //set Geom + dGeomPlaneSetNoNormalize (sliding_plane, itPlane->planeDef); + //dGeomPlaneSetParams (sliding_plane, triangle_Plane[0], triangle_Plane[1], triangle_Plane[2], triangle_Plane[3]); + // find collision and compute contact points + bool didCollide = false; + const int numPlaneContacts = geomNPlaneCollider (o2, sliding_plane, planeTestFlags, PlaneContact, sizeof(dContactGeom)); + const sizeint planeTriListSize = itPlane->trianglelistCurrentSize; + for (i = 0; i < numPlaneContacts; i++) + { + dContactGeom *planeCurrContact = PlaneContact + i; + // Check if contact point found in plane is inside Triangle. + const dVector3 &pCPos = planeCurrContact->pos; + for (sizeint b = 0; planeTriListSize > b; b++) + { + if (m_p_data->IsOnHeightfield2 (itPlane->trianglelist[b]->vertices[0], + pCPos, + itPlane->trianglelist[b]->isUp)) + { + pContact = CONTACT(contact, numTerrainContacts*skip); + dVector3Copy(pCPos, pContact->pos); + dOPESIGN(pContact->normal, =, -, itPlane->planeDef); + pContact->depth = planeCurrContact->depth; + pContact->side1 = planeCurrContact->side1; + pContact->side2 = planeCurrContact->side2; + numTerrainContacts++; + if ( numTerrainContacts == numMaxContactsPossible ) + return numTerrainContacts; + + didCollide = true; + break; + } + } + } + if (didCollide) + { +#if defined(NO_CONTACT_CULLING_BY_ISONHEIGHTFIELD2) + /* Note by Oleh_Derevenko: + This code is not used - see another note above + */ + numMaxContactsPerPlane = dMIN(numMaxContactsPossible - numTerrainContacts, HEIGHTFIELDMAXCONTACTPERCELL); + planeTestFlags = (flags & ~NUMC_MASK) | numMaxContactsPerPlane; + dIASSERT((HEIGHTFIELDMAXCONTACTPERCELL & ~NUMC_MASK) == 0); +#endif + for (sizeint b = 0; planeTriListSize > b; b++) + { + // flag Triangles Vertices as collided + // to prevent any collision test of those + for (i = 0; i < 3; i++) + itPlane->trianglelist[b]->vertices[i]->state = true; + } + } + else + { + // flag triangle as not collided so that Vertices or Edge + // of that triangles will be checked. + for (sizeint b = 0; planeTriListSize > b; b++) + { + itPlane->trianglelist[b]->state = false; + } + } + } + } + + + + // pass2: VS triangle vertices + if (needFurtherPasses) + { + dxRay tempRay(0, 1); + dReal depth; + bool vertexCollided; + + // Only one contact is necessary for ray test + int rayTestFlags = (flags & ~NUMC_MASK) | 1; + dIASSERT((1 & ~NUMC_MASK) == 0); + // + // Find Contact Penetration Depth of each vertices + // + for (unsigned int k = 0; k < numTri; k++) + { + const HeightFieldTriangle * const itTriangle = &tempTriangleBuffer[k]; + if (itTriangle->state == true) + continue;// plane triangle did already collide. + + for (sizeint i = 0; i < 3; i++) + { + HeightFieldVertex *vertex = itTriangle->vertices[i]; + if (vertex->state == true) + continue;// vertice did already collide. + + vertexCollided = false; + const dVector3 &triVertex = vertex->vertex; + if ( geomNDepthGetter ) + { + depth = geomNDepthGetter( o2, + triVertex[0], triVertex[1], triVertex[2] ); + if (depth > dEpsilon) + vertexCollided = true; + } + else + { + // We don't have a GetDepth function, so do a ray cast instead. + // NOTE: This isn't ideal, and a GetDepth function should be + // written for all geom classes. + tempRay.length = (minO2Height - triVertex[1]) * REAL(1000.0); + + //dGeomRaySet( &tempRay, pContact->pos[0], pContact->pos[1], pContact->pos[2], + // - itTriangle->Normal[0], - itTriangle->Normal[1], - itTriangle->Normal[2] ); + dGeomRaySetNoNormalize(tempRay, triVertex, itTriangle->planeDef); + + if ( geomRayNCollider( &tempRay, o2, rayTestFlags, PlaneContact, sizeof( dContactGeom ) ) ) + { + depth = PlaneContact[0].depth; + vertexCollided = true; + } + } + if (vertexCollided) + { + pContact = CONTACT(contact, numTerrainContacts*skip); + //create contact using vertices + dVector3Copy (triVertex, pContact->pos); + //create contact using Plane Normal + dOPESIGN(pContact->normal, =, -, itTriangle->planeDef); + + pContact->depth = depth; + pContact->side1 = -1; + pContact->side2 = -1; + + numTerrainContacts++; + if ( numTerrainContacts == numMaxContactsPossible ) + return numTerrainContacts; + + vertex->state = true; + } + } + } + } + +#ifdef _HEIGHTFIELDEDGECOLLIDING + // pass3: VS triangle Edges + if (needFurtherPasses) + { + dVector3 Edge; + dxRay edgeRay(0, 1); + + int numMaxContactsPerTri = dMIN(numMaxContactsPossible - numTerrainContacts, HEIGHTFIELDMAXCONTACTPERCELL); + int triTestFlags = (flags & ~NUMC_MASK) | numMaxContactsPerTri; + dIASSERT((HEIGHTFIELDMAXCONTACTPERCELL & ~NUMC_MASK) == 0); + + for (unsigned int k = 0; k < numTri; k++) + { + const HeightFieldTriangle * const itTriangle = &tempTriangleBuffer[k]; + + if (itTriangle->state == true) + continue;// plane did already collide. + + for (sizeint m = 0; m < 3; m++) + { + const sizeint next = (m + 1) % 3; + HeightFieldVertex *vertex0 = itTriangle->vertices[m]; + HeightFieldVertex *vertex1 = itTriangle->vertices[next]; + + // not concave or under the AABB + // nor triangle already collided against vertices + if (vertex0->state == true && vertex1->state == true) + continue;// plane did already collide. + + dVector3Subtract(vertex1->vertex, vertex0->vertex, Edge); + edgeRay.length = dVector3Length (Edge); + dGeomRaySetNoNormalize(edgeRay, vertex1->vertex, Edge); + int prevTerrainContacts = numTerrainContacts; + pContact = CONTACT(contact, prevTerrainContacts*skip); + const int numCollision = geomRayNCollider(&edgeRay,o2,triTestFlags,pContact,skip); + dIASSERT(numCollision <= numMaxContactsPerTri); + + if (numCollision) + { + numTerrainContacts += numCollision; + + do + { + pContact = CONTACT(contact, prevTerrainContacts*skip); + + //create contact using Plane Normal + dOPESIGN(pContact->normal, =, -, itTriangle->planeDef); + + pContact->depth = DistancePointToLine(pContact->pos, vertex1->vertex, Edge, edgeRay.length); + } + while (++prevTerrainContacts != numTerrainContacts); + + if ( numTerrainContacts == numMaxContactsPossible ) + return numTerrainContacts; + + numMaxContactsPerTri = dMIN(numMaxContactsPossible - numTerrainContacts, HEIGHTFIELDMAXCONTACTPERCELL); + triTestFlags = (flags & ~NUMC_MASK) | numMaxContactsPerTri; + dIASSERT((HEIGHTFIELDMAXCONTACTPERCELL & ~NUMC_MASK) == 0); + } + } + + itTriangle->vertices[0]->state = true; + itTriangle->vertices[1]->state = true; + itTriangle->vertices[2]->state = true; + } + } +#endif // _HEIGHTFIELDEDGECOLLIDING + return numTerrainContacts; +} + +int dCollideHeightfield( dxGeom *o1, dxGeom *o2, int flags, dContactGeom* contact, int skip ) +{ + dIASSERT( skip >= (int)sizeof(dContactGeom) ); + dIASSERT( o1->type == dHeightfieldClass ); + dIASSERT((flags & NUMC_MASK) >= 1); + + int i; + + // if ((flags & NUMC_MASK) == 0) -- An assertion check is made on entry + // { flags = (flags & ~NUMC_MASK) | 1; dIASSERT((1 & ~NUMC_MASK) == 0); } + + int numMaxTerrainContacts = (flags & NUMC_MASK); + + dxHeightfield *terrain = (dxHeightfield*) o1; + + dVector3 posbak; + dMatrix3 Rbak; + dReal aabbbak[6]; + int gflagsbak; + dVector3 pos0,pos1; + dMatrix3 R1; + + int numTerrainContacts = 0; + int numTerrainOrigContacts = 0; + + //@@ Should find a way to set reComputeAABB to false in default case + // aka DHEIGHTFIELD_CORNER_ORIGIN not defined and terrain not PLACEABLE + // so that we can free some memory and speed up things a bit + // while saving some precision loss +#ifndef DHEIGHTFIELD_CORNER_ORIGIN + const bool reComputeAABB = true; +#else + const bool reComputeAABB = ( terrain->gflags & GEOM_PLACEABLE ) ? true : false; +#endif //DHEIGHTFIELD_CORNER_ORIGIN + + // + // Transform O2 into Heightfield Space + // + if (reComputeAABB) + { + // Backup original o2 position, rotation and AABB. + dVector3Copy( o2->final_posr->pos, posbak ); + dMatrix3Copy( o2->final_posr->R, Rbak ); + memcpy( aabbbak, o2->aabb, sizeof( dReal ) * 6 ); + gflagsbak = o2->gflags; + } + + if ( terrain->gflags & GEOM_PLACEABLE ) + { + // Transform o2 into heightfield space. + dSubtractVectors3( pos0, o2->final_posr->pos, terrain->final_posr->pos ); + dMultiply1_331( pos1, terrain->final_posr->R, pos0 ); + dMultiply1_333( R1, terrain->final_posr->R, o2->final_posr->R ); + + // Update o2 with transformed position and rotation. + dVector3Copy( pos1, o2->final_posr->pos ); + dMatrix3Copy( R1, o2->final_posr->R ); + } + +#ifndef DHEIGHTFIELD_CORNER_ORIGIN + o2->final_posr->pos[ 0 ] += terrain->m_p_data->m_fHalfWidth; + o2->final_posr->pos[ 2 ] += terrain->m_p_data->m_fHalfDepth; +#endif // DHEIGHTFIELD_CORNER_ORIGIN + + // Rebuild AABB for O2 + if (reComputeAABB) + o2->computeAABB(); + + // + // Collide + // + + //check if inside boundaries + // using O2 aabb + // aabb[6] is (minx, maxx, miny, maxy, minz, maxz) + const bool wrapped = terrain->m_p_data->m_bWrapMode != 0; + + if ( !wrapped ) + { + if ( o2->aabb[0] > terrain->m_p_data->m_fWidth //MinX + || o2->aabb[4] > terrain->m_p_data->m_fDepth)//MinZ + goto dCollideHeightfieldExit; + + if ( o2->aabb[1] < 0 //MaxX + || o2->aabb[5] < 0)//MaxZ + goto dCollideHeightfieldExit; + } + + { // To narrow scope of following variables + const dReal fInvSampleWidth = terrain->m_p_data->m_fInvSampleWidth; + int nMinX = (int)dFloor(dNextAfter(o2->aabb[0] * fInvSampleWidth, -dInfinity)); + int nMaxX = (int)dCeil(dNextAfter(o2->aabb[1] * fInvSampleWidth, dInfinity)); + const dReal fInvSampleDepth = terrain->m_p_data->m_fInvSampleDepth; + int nMinZ = (int)dFloor(dNextAfter(o2->aabb[4] * fInvSampleDepth, -dInfinity)); + int nMaxZ = (int)dCeil(dNextAfter(o2->aabb[5] * fInvSampleDepth, dInfinity)); + + if ( !wrapped ) + { + nMinX = dMAX( nMinX, 0 ); + nMaxX = dMIN( nMaxX, terrain->m_p_data->m_nWidthSamples - 1 ); + nMinZ = dMAX( nMinZ, 0 ); + nMaxZ = dMIN( nMaxZ, terrain->m_p_data->m_nDepthSamples - 1 ); + + dIASSERT ((nMinX < nMaxX) && (nMinZ < nMaxZ)); + } + + numTerrainOrigContacts = numTerrainContacts; + numTerrainContacts += terrain->dCollideHeightfieldZone( + nMinX,nMaxX,nMinZ,nMaxZ,o2,numMaxTerrainContacts - numTerrainContacts, + flags,CONTACT(contact,numTerrainContacts*skip),skip ); + dIASSERT( numTerrainContacts <= numMaxTerrainContacts ); + } + + dContactGeom *pContact; + for ( i = numTerrainOrigContacts; i != numTerrainContacts; ++i ) + { + pContact = CONTACT(contact,i*skip); + pContact->g1 = o1; + pContact->g2 = o2; + // pContact->side1 = -1; -- Oleh_Derevenko: sides must not be erased here as they are set by respective colliders during ray/plane tests + // pContact->side2 = -1; + } + + + //------------------------------------------------------------------------------ + +dCollideHeightfieldExit: + + if (reComputeAABB) + { + // Restore o2 position, rotation and AABB + dVector3Copy( posbak, o2->final_posr->pos ); + dMatrix3Copy( Rbak, o2->final_posr->R ); + memcpy( o2->aabb, aabbbak, sizeof(dReal)*6 ); + o2->gflags = gflagsbak; + + // + // Transform Contacts to World Space + // + if ( terrain->gflags & GEOM_PLACEABLE ) + { + for ( i = 0; i < numTerrainContacts; ++i ) + { + pContact = CONTACT(contact,i*skip); + dCopyVector3( pos0, pContact->pos ); + +#ifndef DHEIGHTFIELD_CORNER_ORIGIN + pos0[ 0 ] -= terrain->m_p_data->m_fHalfWidth; + pos0[ 2 ] -= terrain->m_p_data->m_fHalfDepth; +#endif // !DHEIGHTFIELD_CORNER_ORIGIN + + dMultiply0_331( pContact->pos, terrain->final_posr->R, pos0 ); + + dAddVectors3( pContact->pos, pContact->pos, terrain->final_posr->pos ); + dCopyVector3( pos0, pContact->normal ); + + dMultiply0_331( pContact->normal, terrain->final_posr->R, pos0 ); + } + } +#ifndef DHEIGHTFIELD_CORNER_ORIGIN + else + { + for ( i = 0; i < numTerrainContacts; ++i ) + { + pContact = CONTACT(contact,i*skip); + pContact->pos[ 0 ] -= terrain->m_p_data->m_fHalfWidth; + pContact->pos[ 2 ] -= terrain->m_p_data->m_fHalfDepth; + } + } +#endif // !DHEIGHTFIELD_CORNER_ORIGIN + } + // Return contact count. + return numTerrainContacts; +} + + + diff --git a/libs/ode-0.16.1/ode/src/heightfield.h b/libs/ode-0.16.1/ode/src/heightfield.h new file mode 100644 index 0000000..9b27f34 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/heightfield.h @@ -0,0 +1,245 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// dHeightfield Collider +// Martijn Buijs 2006 http://home.planet.nl/~buijs512/ +// Based on Terrain & Cone contrib by: +// Benoit CHAPEROT 2003-2004 http://www.jstarlab.com + +#ifndef _DHEIGHTFIELD_H_ +#define _DHEIGHTFIELD_H_ +//------------------------------------------------------------------------------ + +#include <ode/common.h> +#include "collision_kernel.h" + + +#define HEIGHTFIELDMAXCONTACTPERCELL 10 + + +class HeightFieldVertex; +class HeightFieldEdge; +class HeightFieldTriangle; + +// +// dxHeightfieldData +// +// Heightfield Data structure +// +struct dxHeightfieldData +{ + dReal m_fWidth; // World space heightfield dimension on X axis + dReal m_fDepth; // World space heightfield dimension on Z axis + dReal m_fSampleWidth; // Vertex spacing on X axis edge (== m_vWidth / (m_nWidthSamples-1)) + dReal m_fSampleDepth; // Vertex spacing on Z axis edge (== m_vDepth / (m_nDepthSamples-1)) + dReal m_fSampleZXAspect; // Relation of Z axis spacing to X axis spacing (== m_fSampleDepth / m_fSampleWidth) + dReal m_fInvSampleWidth; // Cache of inverse Vertex count on X axis edge (== m_vWidth / (m_nWidthSamples-1)) + dReal m_fInvSampleDepth; // Cache of inverse Vertex count on Z axis edge (== m_vDepth / (m_nDepthSamples-1)) + + dReal m_fHalfWidth; // Cache of half of m_fWidth + dReal m_fHalfDepth; // Cache of half of m_fDepth + + dReal m_fMinHeight; // Min sample height value (scaled and offset) + dReal m_fMaxHeight; // Max sample height value (scaled and offset) + dReal m_fThickness; // Surface thickness (added to bottom AABB) + dReal m_fScale; // Sample value multiplier + dReal m_fOffset; // Vertical sample offset + + int m_nWidthSamples; // Vertex count on X axis edge (number of samples) + int m_nDepthSamples; // Vertex count on Z axis edge (number of samples) + int m_bCopyHeightData; // Do we own the sample data? + int m_bWrapMode; // Heightfield wrapping mode (0=finite, 1=infinite) + int m_nGetHeightMode; // GetHeight mode ( 0=callback, 1=byte, 2=short, 3=float ) + + const void* m_pHeightData; // Sample data array + void* m_pUserData; // Callback user data + + dContactGeom m_contacts[HEIGHTFIELDMAXCONTACTPERCELL]; + + dHeightfieldGetHeight* m_pGetHeightCallback; // Callback pointer. + + dxHeightfieldData(); + ~dxHeightfieldData(); + + void SetData( int nWidthSamples, int nDepthSamples, + dReal fWidth, dReal fDepth, + dReal fScale, dReal fOffset, + dReal fThickness, int bWrapMode ); + + void ComputeHeightBounds(); + + bool IsOnHeightfield2 ( const HeightFieldVertex * const CellCorner, + const dReal * const pos, const bool isABC) const; + + dReal GetHeight(int x, int z); + dReal GetHeight(dReal x, dReal z); + +}; + +typedef int HeightFieldVertexCoords[2]; + +class HeightFieldVertex +{ +public: + HeightFieldVertex(){}; + + dVector3 vertex; + HeightFieldVertexCoords coords; + bool state; +}; + +class HeightFieldEdge +{ +public: + HeightFieldEdge(){}; + + HeightFieldVertex *vertices[2]; +}; + +class HeightFieldTriangle +{ +public: + HeightFieldTriangle(){}; + + inline void setMinMax() + { + maxAAAB = vertices[0]->vertex[1] > vertices[1]->vertex[1] ? vertices[0]->vertex[1] : vertices[1]->vertex[1]; + maxAAAB = vertices[2]->vertex[1] > maxAAAB ? vertices[2]->vertex[1] : maxAAAB; + }; + + HeightFieldVertex *vertices[3]; + dReal planeDef[4]; + dReal maxAAAB; + + bool isUp; + bool state; +}; + +class HeightFieldPlane +{ +public: + HeightFieldPlane(): + trianglelist(0), + trianglelistReservedSize(0), + trianglelistCurrentSize(0) + { + } + + ~HeightFieldPlane() + { + delete [] trianglelist; + } + + inline void setMinMax() + { + const sizeint asize = trianglelistCurrentSize; + if (asize > 0) + { + maxAAAB = trianglelist[0]->maxAAAB; + for (sizeint k = 1; asize > k; k++) + { + if (trianglelist[k]->maxAAAB > maxAAAB) + maxAAAB = trianglelist[k]->maxAAAB; + } + } + }; + + void resetTriangleListSize(const sizeint newSize) + { + if (trianglelistReservedSize < newSize) + { + delete [] trianglelist; + trianglelistReservedSize = newSize; + trianglelist = new HeightFieldTriangle *[newSize]; + } + trianglelistCurrentSize = 0; + } + + void addTriangle(HeightFieldTriangle *tri) + { + dIASSERT(trianglelistCurrentSize < trianglelistReservedSize); + + trianglelist[trianglelistCurrentSize++] = tri; + } + + HeightFieldTriangle **trianglelist; + sizeint trianglelistReservedSize; + sizeint trianglelistCurrentSize; + + dReal maxAAAB; + dReal planeDef[4]; +}; + +// +// dxHeightfield +// +// Heightfield geom structure +// +struct dxHeightfield : public dxGeom +{ + dxHeightfieldData* m_p_data; + + dxHeightfield( dSpaceID space, dHeightfieldDataID data, int bPlaceable ); + ~dxHeightfield(); + + void computeAABB(); + + int dCollideHeightfieldZone( const int minX, const int maxX, const int minZ, const int maxZ, + dxGeom *o2, const int numMaxContacts, + int flags, dContactGeom *contact, int skip ); + + enum + { + TEMP_PLANE_BUFFER_ELEMENT_COUNT_ALIGNMENT = 4, + TEMP_HEIGHT_BUFFER_ELEMENT_COUNT_ALIGNMENT_X = 4, + TEMP_HEIGHT_BUFFER_ELEMENT_COUNT_ALIGNMENT_Z = 4, + TEMP_TRIANGLE_BUFFER_ELEMENT_COUNT_ALIGNMENT = 1 // Triangles are easy to reallocate and hard to predict + }; + + static inline sizeint AlignBufferSize(sizeint value, sizeint alignment) { dIASSERT((alignment & (alignment - 1)) == 0); return (value + (alignment - 1)) & ~(alignment - 1); } + + void allocateTriangleBuffer(sizeint numTri); + void resetTriangleBuffer(); + void allocatePlaneBuffer(sizeint numTri); + void resetPlaneBuffer(); + void allocateHeightBuffer(sizeint numX, sizeint numZ); + void resetHeightBuffer(); + + void sortPlanes(const sizeint numPlanes); + + HeightFieldPlane **tempPlaneBuffer; + HeightFieldPlane *tempPlaneInstances; + sizeint tempPlaneBufferSize; + + HeightFieldTriangle *tempTriangleBuffer; + sizeint tempTriangleBufferSize; + + HeightFieldVertex **tempHeightBuffer; + HeightFieldVertex *tempHeightInstances; + sizeint tempHeightBufferSizeX; + sizeint tempHeightBufferSizeZ; + +}; + + +//------------------------------------------------------------------------------ +#endif //_DHEIGHTFIELD_H_ diff --git a/libs/ode-0.16.1/ode/src/joints/Makefile.am b/libs/ode-0.16.1/ode/src/joints/Makefile.am new file mode 100644 index 0000000..194ef60 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/Makefile.am @@ -0,0 +1,37 @@ +AM_CPPFLAGS = -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/ode/src \ + -D__ODE__ + + +if ENABLE_OU + +AM_CPPFLAGS += -I$(top_srcdir)/ou/include + + +endif + + +noinst_LTLIBRARIES = libjoints.la + +libjoints_la_SOURCES = joints.h \ + joint.h joint.cpp \ + joint_internal.h \ + ball.h ball.cpp \ + dball.h dball.cpp \ + dhinge.h dhinge.cpp \ + transmission.h transmission.cpp \ + hinge.h hinge.cpp \ + slider.h slider.cpp \ + contact.h contact.cpp \ + universal.h universal.cpp \ + hinge2.h hinge2.cpp \ + fixed.h fixed.cpp \ + null.h null.cpp \ + amotor.h amotor.cpp \ + lmotor.h lmotor.cpp \ + plane2d.h plane2d.cpp \ + pu.h pu.cpp \ + pr.h pr.cpp \ + piston.h piston.cpp + diff --git a/libs/ode-0.16.1/ode/src/joints/Makefile.in b/libs/ode-0.16.1/ode/src/joints/Makefile.in new file mode 100644 index 0000000..9e43f9f --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/Makefile.in @@ -0,0 +1,668 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@ENABLE_OU_TRUE@am__append_1 = -I$(top_srcdir)/ou/include +subdir = ode/src/joints +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ode/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libjoints_la_LIBADD = +am_libjoints_la_OBJECTS = joint.lo ball.lo dball.lo dhinge.lo \ + transmission.lo hinge.lo slider.lo contact.lo universal.lo \ + hinge2.lo fixed.lo null.lo amotor.lo lmotor.lo plane2d.lo \ + pu.lo pr.lo piston.lo +libjoints_la_OBJECTS = $(am_libjoints_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libjoints_la_SOURCES) +DIST_SOURCES = $(libjoints_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_CFLAGS = @CCD_CFLAGS@ +CCD_LIBS = @CCD_LIBS@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSTDCXX = @LIBSTDCXX@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ODE_PRECISION = @ODE_PRECISION@ +ODE_VERSION = @ODE_VERSION@ +ODE_VERSION_INFO = @ODE_VERSION_INFO@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include \ + -I$(top_srcdir)/ode/src -D__ODE__ $(am__append_1) +noinst_LTLIBRARIES = libjoints.la +libjoints_la_SOURCES = joints.h \ + joint.h joint.cpp \ + joint_internal.h \ + ball.h ball.cpp \ + dball.h dball.cpp \ + dhinge.h dhinge.cpp \ + transmission.h transmission.cpp \ + hinge.h hinge.cpp \ + slider.h slider.cpp \ + contact.h contact.cpp \ + universal.h universal.cpp \ + hinge2.h hinge2.cpp \ + fixed.h fixed.cpp \ + null.h null.cpp \ + amotor.h amotor.cpp \ + lmotor.h lmotor.cpp \ + plane2d.h plane2d.cpp \ + pu.h pu.cpp \ + pr.h pr.cpp \ + piston.h piston.cpp + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign ode/src/joints/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign ode/src/joints/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libjoints.la: $(libjoints_la_OBJECTS) $(libjoints_la_DEPENDENCIES) $(EXTRA_libjoints_la_DEPENDENCIES) + $(AM_V_CXXLD)$(CXXLINK) $(libjoints_la_OBJECTS) $(libjoints_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amotor.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ball.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/contact.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dball.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dhinge.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fixed.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hinge.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hinge2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/joint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmotor.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/null.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/piston.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plane2d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pu.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slider.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transmission.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/universal.Plo@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/ode/src/joints/amotor.cpp b/libs/ode-0.16.1/ode/src/joints/amotor.cpp new file mode 100644 index 0000000..aa30c76 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/amotor.cpp @@ -0,0 +1,810 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + + +#include <ode/odeconfig.h> +#include "config.h" +#include "common.h" +#include "amotor.h" +#include "joint_internal.h" +#include "odeou.h" + + +/*extern */ +void dJointSetAMotorNumAxes(dJointID j, int num) +{ + dxJointAMotor* joint = (dxJointAMotor*)j; + dAASSERT(joint != NULL); + dAASSERT(dIN_RANGE(num, dSA__MIN, dSA__MAX + 1)); + checktype(joint, AMotor); + + num = dCLAMP(num, dSA__MIN, dSA__MAX); + + joint->setNumAxes(num); +} + +/*extern */ +void dJointSetAMotorAxis(dJointID j, int anum, int rel/*=dJointBodyRelativity*/, + dReal x, dReal y, dReal z) +{ + dxJointAMotor* joint = (dxJointAMotor*)j; + dAASSERT(joint != NULL); + dAASSERT(dIN_RANGE(anum, dSA__MIN, dSA__MAX)); + dAASSERT(dIN_RANGE(rel, dJBR__MIN, dJBR__MAX)); + checktype(joint, AMotor); + + anum = dCLAMP(anum, dSA__MIN, dSA__MAX - 1); + + joint->setAxisValue(anum, (dJointBodyRelativity)rel, x, y, z); +} + +/*extern */ +void dJointSetAMotorAngle(dJointID j, int anum, dReal angle) +{ + dxJointAMotor* joint = (dxJointAMotor*)j; + dAASSERT(joint != NULL); + dAASSERT(dIN_RANGE(anum, dSA__MIN, dSA__MAX)); + checktype(joint, AMotor); + + anum = dCLAMP(anum, dSA__MIN, dSA__MAX - 1); + + joint->setAngleValue(anum, angle); +} + +/*extern */ +void dJointSetAMotorParam(dJointID j, int parameter, dReal value) +{ + dxJointAMotor* joint = (dxJointAMotor*)j; + dAASSERT(joint != NULL); + checktype(joint, AMotor); + + int anum = parameter >> 8; + dAASSERT(dIN_RANGE(anum, dSA__MIN, dSA__MAX)); + + anum = dCLAMP(anum, dSA__MIN, dSA__MAX - 1); + + int limotParam = parameter & 0xff; + joint->setLimotParameter(anum, limotParam, value); +} + +/*extern */ +void dJointSetAMotorMode(dJointID j, int mode) +{ + dxJointAMotor* joint = (dxJointAMotor*)j; + dAASSERT(joint != NULL); + checktype(joint, AMotor); + + joint->setOperationMode(mode); +} + +/*extern */ +int dJointGetAMotorNumAxes(dJointID j) +{ + dxJointAMotor* joint = (dxJointAMotor*)j; + dAASSERT(joint != NULL); + checktype(joint, AMotor); + + return joint->getNumAxes(); +} + +/*extern */ +void dJointGetAMotorAxis(dJointID j, int anum, dVector3 result) +{ + dxJointAMotor* joint = (dxJointAMotor*)j; + dAASSERT(joint != NULL); + dAASSERT(dIN_RANGE(anum, dSA__MIN, dSA__MAX)); + checktype(joint, AMotor); + + anum = dCLAMP(anum, dSA__MIN, dSA__MAX - 1); + + joint->getAxisValue(result, anum); +} + +/*extern */ +int dJointGetAMotorAxisRel(dJointID j, int anum) +{ + dxJointAMotor* joint = (dxJointAMotor*)j; + dAASSERT(joint != NULL); + dAASSERT(dIN_RANGE(anum, dSA__MIN, dSA__MAX)); + checktype(joint, AMotor); + + anum = dCLAMP(anum, dSA__MIN, dSA__MAX - 1); + + int result = joint->getAxisBodyRelativity(anum); + return result; +} + +/*extern */ +dReal dJointGetAMotorAngle(dJointID j, int anum) +{ + dxJointAMotor* joint = (dxJointAMotor*)j; + dAASSERT(joint != NULL); + dAASSERT(dIN_RANGE(anum, dSA__MIN, dSA__MAX)); + checktype(joint, AMotor); + + anum = dCLAMP(anum, dSA__MIN, dSA__MAX - 1); + + dReal result = joint->getAngleValue(anum); + return result; +} + +/*extern */ +dReal dJointGetAMotorAngleRate(dJointID j, int anum) +{ + dxJointAMotor* joint = (dxJointAMotor*)j; + dAASSERT(joint != NULL); + dAASSERT(dIN_RANGE(anum, dSA__MIN, dSA__MAX)); + checktype(joint, AMotor); + + anum = dCLAMP(anum, dSA__MIN, dSA__MAX - 1); + + dReal result = joint->calculateAngleRate(anum); + return result; +} + +/*extern */ +dReal dJointGetAMotorParam(dJointID j, int parameter) +{ + dxJointAMotor* joint = (dxJointAMotor*)j; + dAASSERT(joint != NULL); + checktype(joint, AMotor); + + int anum = parameter >> 8; + dAASSERT(dIN_RANGE(anum, dSA__MIN, dSA__MAX)); + + anum = dCLAMP(anum, dSA__MIN, dSA__MAX - 1); + + int limotParam = parameter & 0xff; + dReal result = joint->getLimotParameter(anum, limotParam); + return result; +} + +/*extern */ +int dJointGetAMotorMode(dJointID j) +{ + dxJointAMotor* joint = (dxJointAMotor*)j; + dAASSERT(joint != NULL); + checktype(joint, AMotor); + + int result = joint->getOperationMode(); + return result; +} + +/*extern */ +void dJointAddAMotorTorques(dJointID j, dReal torque1, dReal torque2, dReal torque3) +{ + dxJointAMotor* joint = (dxJointAMotor*)j; + dAASSERT(joint != NULL); + checktype(joint, AMotor); + + joint->addTorques(torque1, torque2, torque3); +} + + +//**************************************************************************** + +BEGIN_NAMESPACE_OU(); +template<> +const dJointBodyRelativity CEnumUnsortedElementArray<dSpaceAxis, dSA__MAX, dJointBodyRelativity, 0x160703D5>::m_aetElementArray[] = +{ + dJBR_BODY1, // dSA_X, + dJBR_GLOBAL, // dSA_Y, + dJBR_BODY2, // dSA_Z, +}; +END_NAMESPACE_OU(); +static const CEnumUnsortedElementArray<dSpaceAxis, dSA__MAX, dJointBodyRelativity, 0x160703D5> g_abrEulerAxisAllowedBodyRelativities; + +static inline +dSpaceAxis EncodeJointConnectedBodyEulerAxis(dJointConnectedBody cbBodyIndex) +{ + dSASSERT(dJCB__MAX == 2); + + return cbBodyIndex == dJCB_FIRST_BODY ? dSA_X : dSA_Z; +} + +static inline +dSpaceAxis EncodeOtherEulerAxis(dSpaceAxis saOneAxis) +{ + dIASSERT(saOneAxis == EncodeJointConnectedBodyEulerAxis(dJCB_FIRST_BODY) || saOneAxis == EncodeJointConnectedBodyEulerAxis(dJCB_SECOND_BODY)); + dSASSERT(dJCB__MAX == 2); + + return (dSpaceAxis)(dSA_X + dSA_Z - saOneAxis); +} + + +//**************************************************************************** +// angular motor + +dxJointAMotor::dxJointAMotor(dxWorld *w) : + dxJointAMotor_Parent(w), + m_mode(dAMotorUser), + m_num(0) +{ + std::fill(m_rel, m_rel + dARRAY_SIZE(m_rel), dJBR__DEFAULT); + { for (int i = 0; i != dARRAY_SIZE(m_axis); ++i) { dZeroVector3(m_axis[i]); } } + { for (int i = 0; i != dARRAY_SIZE(m_references); ++i) { dZeroVector3(m_references[i]); } } + std::fill(m_angle, m_angle + dARRAY_SIZE(m_angle), REAL(0.0)); + { for (int i = 0; i != dARRAY_SIZE(m_limot); ++i) { m_limot[i].init(w); } } +} + + +/*virtual */ +dxJointAMotor::~dxJointAMotor() +{ + // The virtual destructor +} + + +/*virtual */ +void dxJointAMotor::getSureMaxInfo(SureMaxInfo* info) +{ + info->max_m = m_num; +} + +/*virtual */ +void dxJointAMotor::getInfo1(dxJoint::Info1 *info) +{ + info->m = 0; + info->nub = 0; + + // compute the axes and angles, if in Euler mode + if (m_mode == dAMotorEuler) + { + dVector3 ax[dSA__MAX]; + computeGlobalAxes(ax); + computeEulerAngles(ax); + } + + // see if we're powered or at a joint limit for each axis + const unsigned num = m_num; + for (unsigned i = 0; i != num; ++i) + { + if (m_limot[i].testRotationalLimit(m_angle[i]) + || m_limot[i].fmax > 0) + { + info->m++; + } + } +} + +/*virtual */ +void dxJointAMotor::getInfo2(dReal worldFPS, dReal /*worldERP*/, + int rowskip, dReal *J1, dReal *J2, + int pairskip, dReal *pairRhsCfm, dReal *pairLoHi, + int *findex) +{ + // compute the axes (if not global) + dVector3 ax[dSA__MAX]; + computeGlobalAxes(ax); + + // 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]) : + // + // to get constrain w2-w1 along ...not + // ------ --------------------- ------ + // d(angle[0])/dt = 0 ax[1] x ax[2] ax[0] + // d(angle[1])/dt = 0 ax[1] + // d(angle[2])/dt = 0 ax[0] x ax[1] ax[2] + // + // constraining w2-w1 along an axis 'a' means that a'*(w2-w1)=0. + // to prove the result for angle[0], write the expression for angle[0] from + // GetInfo1 then take the derivative. to prove this for angle[2] it is + // easier to take the Euler rate expression for d(angle[2])/dt with respect + // to the components of w and set that to 0. + + dVector3 *axptr[dSA__MAX]; + for (int j = dSA__MIN; j != dSA__MAX; ++j) { axptr[j] = &ax[j]; } + + dVector3 ax0_cross_ax1; + dVector3 ax1_cross_ax2; + + if (m_mode == dAMotorEuler) + { + dCalcVectorCross3(ax0_cross_ax1, ax[dSA_X], ax[dSA_Y]); + axptr[dSA_Z] = &ax0_cross_ax1; + dCalcVectorCross3(ax1_cross_ax2, ax[dSA_Y], ax[dSA_Z]); + axptr[dSA_X] = &ax1_cross_ax2; + } + + sizeint rowTotalSkip = 0, pairTotalSkip = 0; + + const unsigned num = m_num; + for (unsigned i = 0; i != num; ++i) + { + if (m_limot[i].addLimot(this, worldFPS, J1 + rowTotalSkip, J2 + rowTotalSkip, pairRhsCfm + pairTotalSkip, pairLoHi + pairTotalSkip, *(axptr[i]), 1)) + { + rowTotalSkip += rowskip; + pairTotalSkip += pairskip; + } + } +} + +/*virtual */ +dJointType dxJointAMotor::type() const +{ + return dJointTypeAMotor; +} + +/*virtual */ +sizeint dxJointAMotor::size() const +{ + return sizeof(*this); +} + + +void dxJointAMotor::setOperationMode(int mode) +{ + m_mode = mode; + + if (mode == dAMotorEuler) + { + m_num = dSA__MAX; + setEulerReferenceVectors(); + } +} + + +void dxJointAMotor::setNumAxes(unsigned num) +{ + if (m_mode == dAMotorEuler) + { + m_num = dSA__MAX; + } + else + { + m_num = num; + } +} + + +dJointBodyRelativity dxJointAMotor::getAxisBodyRelativity(unsigned anum) const +{ + dAASSERT(dIN_RANGE(anum, dSA__MIN, dSA__MAX)); + + dJointBodyRelativity rel = m_rel[anum]; + if (dJBREncodeBodyRelativityStatus(rel) && GetIsJointReverse()) + { + rel = dJBRSwapBodyRelativity(rel); // turns 1 into 2, 2 into 1 + } + + return rel; +} + + +void dxJointAMotor::setAxisValue(unsigned anum, dJointBodyRelativity rel, + dReal x, dReal y, dReal z) +{ + dAASSERT(dIN_RANGE(anum, dSA__MIN, dSA__MAX)); + dAASSERT(m_mode != dAMotorEuler || !dJBREncodeBodyRelativityStatus(rel) || rel == g_abrEulerAxisAllowedBodyRelativities.Encode((dSpaceAxis)anum)); + + // x,y,z is always in global coordinates regardless of rel, so we may have + // to convert it to be relative to a body + dVector3 r; + dAssignVector3(r, x, y, z); + + // adjust rel to match the internal body order + if (dJBREncodeBodyRelativityStatus(rel) && GetIsJointReverse()) + { + rel = dJBRSwapBodyRelativity(rel); // turns 1 into 2, 2, into 1 + } + + m_rel[anum] = rel; + + bool assigned = false; + + if (dJBREncodeBodyRelativityStatus(rel)) + { + if (rel == dJBR_BODY1) + { + dMultiply1_331(m_axis[anum], this->node[0].body->posr.R, r); + assigned = true; + } + // rel == 2 + else if (this->node[1].body != NULL) + { + dIASSERT(rel == dJBR_BODY2); + + dMultiply1_331(m_axis[anum], this->node[1].body->posr.R, r); + assigned = true; + } + } + + if (!assigned) + { + dCopyVector3(m_axis[anum], r); + } + + dNormalize3(m_axis[anum]); + + if (m_mode == dAMotorEuler) + { + setEulerReferenceVectors(); + } +} + +void dxJointAMotor::getAxisValue(dVector3 result, unsigned anum) const +{ + dAASSERT(dIN_RANGE(anum, dSA__MIN, dSA__MAX)); + + switch (m_mode) + { + case dAMotorUser: + { + doGetUserAxis(result, anum); + break; + } + + case dAMotorEuler: + { + doGetEulerAxis(result, anum); + break; + } + + default: + { + dIASSERT(false); + break; + } + } +} + + +void dxJointAMotor::doGetUserAxis(dVector3 result, unsigned anum) const +{ + bool retrieved = false; + + if (dJBREncodeBodyRelativityStatus(m_rel[anum])) + { + if (m_rel[anum] == dJBR_BODY1) + { + dMultiply0_331(result, this->node[0].body->posr.R, m_axis[anum]); + retrieved = true; + } + else if (this->node[1].body != NULL) + { + dMultiply0_331(result, this->node[1].body->posr.R, m_axis[anum]); + retrieved = true; + } + } + + if (!retrieved) + { + dCopyVector3(result, m_axis[anum]); + } +} + +void dxJointAMotor::doGetEulerAxis(dVector3 result, unsigned anum) const +{ + // If we're in Euler mode, joint->axis[1] doesn't + // have anything sensible in it. So don't just return + // that, find the actual effective axis. + // Likewise, the actual axis of rotation for the + // the other axes is different from what's stored. + dVector3 axes[dSA__MAX]; + computeGlobalAxes(axes); + + if (anum == dSA_Y) + { + dCopyVector3(result, axes[dSA_Y]); + } + else if (anum < dSA_Y) // Comparing against the same constant lets compiler reuse EFLAGS register for another conditional jump + { + dSASSERT(dSA_X < dSA_Y); // Otherwise the condition above is incorrect + dIASSERT(anum == dSA_X); + + // This won't be unit length in general, + // but it's what's used in getInfo2 + // This may be why things freak out as + // the body-relative axes get close to each other. + dCalcVectorCross3(result, axes[dSA_Y], axes[dSA_Z]); + } + else + { + dSASSERT(dSA_Z > dSA_Y); // Otherwise the condition above is incorrect + dIASSERT(anum == dSA_Z); + + // Same problem as above. + dCalcVectorCross3(result, axes[dSA_X], axes[dSA_Y]); + } +} + + +void dxJointAMotor::setAngleValue(unsigned anum, dReal angle) +{ + dAASSERT(dIN_RANGE(anum, dSA__MIN, dSA__MAX)); + dAASSERT(m_mode == dAMotorUser); // This only works for the dAMotorUser + + if (m_mode == dAMotorUser) + { + m_angle[anum] = angle; + } +} + + +dReal dxJointAMotor::calculateAngleRate(unsigned anum) const +{ + dAASSERT(dIN_RANGE(anum, dSA__MIN, dSA__MAX)); + dAASSERT(this->node[0].body != NULL); // Don't call for angle rate before the joint is set up + + dVector3 axis; + getAxisValue(axis, anum); + + // NOTE! + // For reverse joints, the rate is negated at the function exit to create swapped bodies effect + dReal rate = dDOT(axis, this->node[0].body->avel); + + if (this->node[1].body != NULL) + { + rate -= dDOT(axis, this->node[1].body->avel); + } + + // Negating the rate for reverse joints creates an effect of body swapping + dReal result = !GetIsJointReverse() ? rate : -rate; + return result; +} + + +void dxJointAMotor::addTorques(dReal torque1, dReal torque2, dReal torque3) +{ + unsigned num = getNumAxes(); + dAASSERT(dIN_RANGE(num, dSA__MIN, dSA__MAX + 1)); + + dVector3 sum; + dVector3 torqueVector; + dVector3 axes[dSA__MAX]; + + + if (num != dSA__MIN) + { + computeGlobalAxes(axes); + + if (!GetIsJointReverse()) + { + dAssignVector3(torqueVector, torque1, torque2, torque3); + } + else + { + // Negating torques creates an effect of swapped bodies later + dAssignVector3(torqueVector, -torque1, -torque2, -torque3); + } + } + + switch (num) + { + case dSA_Z + 1: + { + dAddThreeScaledVectors3(sum, axes[dSA_Z], axes[dSA_Y], axes[dSA_X], torqueVector[dSA_Z], torqueVector[dSA_Y], torqueVector[dSA_X]); + break; + } + + case dSA_Y + 1: + { + dAddScaledVectors3(sum, axes[dSA_Y], axes[dSA_X], torqueVector[dSA_Y], torqueVector[dSA_X]); + break; + } + + case dSA_X + 1: + { + dCopyScaledVector3(sum, axes[dSA_X], torqueVector[dSA_X]); + break; + } + + default: + { + dSASSERT(dSA_Z > dSA_Y); // Otherwise the addends order needs to be switched + dSASSERT(dSA_Y > dSA_X); + + // Do nothing + break; + } + } + + if (num != dSA__MIN) + { + dAASSERT(this->node[0].body != NULL); // Don't add torques unless you set the joint up first! + + // NOTE! + // For reverse joints, the torqueVector negated at function entry produces the effect of swapped bodies + dBodyAddTorque(this->node[0].body, sum[dV3E_X], sum[dV3E_Y], sum[dV3E_Z]); + + if (this->node[1].body != NULL) + { + dBodyAddTorque(this->node[1].body, -sum[dV3E_X], -sum[dV3E_Y], -sum[dV3E_Z]); + } + } +} + + +// compute the 3 axes in global coordinates +void dxJointAMotor::computeGlobalAxes(dVector3 ax[dSA__MAX]) const +{ + switch (m_mode) + { + case dAMotorUser: + { + doComputeGlobalUserAxes(ax); + break; + } + + case dAMotorEuler: + { + doComputeGlobalEulerAxes(ax); + break; + } + + default: + { + dIASSERT(false); + break; + } + } +} + +void dxJointAMotor::doComputeGlobalUserAxes(dVector3 ax[dSA__MAX]) const +{ + unsigned num = m_num; + for (unsigned i = 0; i != num; ++i) + { + bool assigned = false; + + if (m_rel[i] == dJBR_BODY1) + { + // relative to b1 + dMultiply0_331(ax[i], this->node[0].body->posr.R, m_axis[i]); + assigned = true; + } + else if (m_rel[i] == dJBR_BODY2) + { + // relative to b2 + if (this->node[1].body != NULL) + { + dMultiply0_331(ax[i], this->node[1].body->posr.R, m_axis[i]); + assigned = true; + } + } + + if (!assigned) + { + // global - just copy it + dCopyVector3(ax[i], m_axis[i]); + } + } +} + +void dxJointAMotor::doComputeGlobalEulerAxes(dVector3 ax[dSA__MAX]) const +{ + // special handling for Euler mode + + dSpaceAxis firstBodyAxis = BuildFirstBodyEulerAxis(); + dMultiply0_331(ax[firstBodyAxis], this->node[0].body->posr.R, m_axis[firstBodyAxis]); + + dSpaceAxis secondBodyAxis = EncodeOtherEulerAxis(firstBodyAxis); + + if (this->node[1].body != NULL) + { + dMultiply0_331(ax[secondBodyAxis], this->node[1].body->posr.R, m_axis[secondBodyAxis]); + } + else + { + dCopyVector3(ax[secondBodyAxis], m_axis[secondBodyAxis]); + } + + dCalcVectorCross3(ax[dSA_Y], ax[dSA_Z], ax[dSA_X]); + dNormalize3(ax[dSA_Y]); +} + + +void dxJointAMotor::computeEulerAngles(dVector3 ax[dSA__MAX]) +{ + // assumptions: + // global axes already calculated --> ax + // axis[0] is relative to body 1 --> global ax[0] + // axis[2] is relative to body 2 --> global ax[2] + // ax[1] = ax[2] x ax[0] + // original ax[0] and ax[2] are perpendicular + // reference1 is perpendicular to ax[0] (in body 1 frame) + // reference2 is perpendicular to ax[2] (in body 2 frame) + // all ax[] and reference vectors are unit length + + // calculate references in global frame + dVector3 refs[dJCB__MAX]; + dMultiply0_331(refs[dJCB_FIRST_BODY], this->node[0].body->posr.R, m_references[dJCB_FIRST_BODY]); + + if (this->node[1].body != NULL) + { + dMultiply0_331(refs[dJCB_SECOND_BODY], this->node[1].body->posr.R, m_references[dJCB_SECOND_BODY]); + } + else + { + dCopyVector3(refs[dJCB_SECOND_BODY], m_references[dJCB_SECOND_BODY]); + } + + + // get q perpendicular to both ax[0] and ref1, get first euler angle + dVector3 q; + dJointConnectedBody firstAxisBody = BuildFirstEulerAxisBody(); + + dCalcVectorCross3(q, ax[dSA_X], refs[firstAxisBody]); + m_angle[dSA_X] = -dAtan2(dCalcVectorDot3(ax[dSA_Z], q), dCalcVectorDot3(ax[dSA_Z], refs[firstAxisBody])); + + // get q perpendicular to both ax[0] and ax[1], get second euler angle + dCalcVectorCross3(q, ax[dSA_X], ax[dSA_Y]); + m_angle[dSA_Y] = -dAtan2(dCalcVectorDot3(ax[dSA_Z], ax[dSA_X]), dCalcVectorDot3(ax[dSA_Z], q)); + + dJointConnectedBody secondAxisBody = EncodeJointOtherConnectedBody(firstAxisBody); + + // get q perpendicular to both ax[1] and ax[2], get third euler angle + dCalcVectorCross3(q, ax[dSA_Y], ax[dSA_Z]); + m_angle[dSA_Z] = -dAtan2(dCalcVectorDot3(refs[secondAxisBody], ax[dSA_Y]), dCalcVectorDot3(refs[secondAxisBody], q)); +} + + +// set the reference vectors as follows: +// * reference1 = current axis[2] relative to body 1 +// * reference2 = current axis[0] relative to body 2 +// this assumes that: +// * axis[0] is relative to body 1 +// * axis[2] is relative to body 2 + +void dxJointAMotor::setEulerReferenceVectors() +{ + if (/*this->node[0].body != NULL && */this->node[1].body != NULL) + { + dIASSERT(this->node[0].body != NULL); + + dVector3 r; // axis[2] and axis[0] in global coordinates + + dSpaceAxis firstBodyAxis = BuildFirstBodyEulerAxis(); + dMultiply0_331(r, this->node[0].body->posr.R, m_axis[firstBodyAxis]); + dMultiply1_331(m_references[dJCB_SECOND_BODY], this->node[1].body->posr.R, r); + + dSpaceAxis secondBodyAxis = EncodeOtherEulerAxis(firstBodyAxis); + dMultiply0_331(r, this->node[1].body->posr.R, m_axis[secondBodyAxis]); + dMultiply1_331(m_references[dJCB_FIRST_BODY], this->node[0].body->posr.R, r); + } + else + { + // We want to handle angular motors attached to passive geoms + // Replace missing node.R with identity + if (this->node[0].body != NULL) + { + dSpaceAxis firstBodyAxis = BuildFirstBodyEulerAxis(); + dMultiply0_331(m_references[dJCB_SECOND_BODY], this->node[0].body->posr.R, m_axis[firstBodyAxis]); + + dSpaceAxis secondBodyAxis = EncodeOtherEulerAxis(firstBodyAxis); + dMultiply1_331(m_references[dJCB_FIRST_BODY], this->node[0].body->posr.R, m_axis[secondBodyAxis]); + } + } +} + +/*inline */ +dSpaceAxis dxJointAMotor::BuildFirstBodyEulerAxis() const +{ + return EncodeJointConnectedBodyEulerAxis(BuildFirstEulerAxisBody()); +} + +/*inline */ +dJointConnectedBody dxJointAMotor::BuildFirstEulerAxisBody() const +{ + return !GetIsJointReverse() ? dJCB_FIRST_BODY : dJCB_SECOND_BODY; +} + diff --git a/libs/ode-0.16.1/ode/src/joints/amotor.h b/libs/ode-0.16.1/ode/src/joints/amotor.h new file mode 100644 index 0000000..2fd421c --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/amotor.h @@ -0,0 +1,105 @@ +/*************************************************************************
+ * *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
+ * All rights reserved. Email: russ@q12.org Web: www.q12.org *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of EITHER: *
+ * (1) The GNU Lesser General Public License as published by the Free *
+ * Software Foundation; either version 2.1 of the License, or (at *
+ * your option) any later version. The text of the GNU Lesser *
+ * General Public License is included with this library in the *
+ * file LICENSE.TXT. *
+ * (2) The BSD-style license that is included with this library in *
+ * the file LICENSE-BSD.TXT. *
+ * *
+ * This library 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 files *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
+ * *
+ *************************************************************************/
+
+#ifndef _ODE_JOINT_AMOTOR_H_
+#define _ODE_JOINT_AMOTOR_H_
+
+#include "joint.h"
+
+
+// angular motor
+
+typedef dxJoint dxJointAMotor_Parent;
+class dxJointAMotor:
+ public dxJointAMotor_Parent
+{
+public:
+ dxJointAMotor(dxWorld *w);
+ virtual ~dxJointAMotor();
+
+public:
+ virtual void getSureMaxInfo(SureMaxInfo* info);
+ virtual void getInfo1(Info1* info);
+ virtual void getInfo2(dReal worldFPS, dReal worldERP,
+ int rowskip, dReal *J1, dReal *J2,
+ int pairskip, dReal *pairRhsCfm, dReal *pairLoHi,
+ int *findex);
+ virtual dJointType type() const;
+ virtual sizeint size() const;
+
+public:
+ void setOperationMode(int mode);
+ int getOperationMode() const { return m_mode; }
+
+ void setNumAxes(unsigned num);
+ int getNumAxes() const { return m_num; }
+
+ dJointBodyRelativity getAxisBodyRelativity(unsigned anum) const;
+
+ void setAxisValue(unsigned anum, dJointBodyRelativity rel, dReal x, dReal y, dReal z);
+ void getAxisValue(dVector3 result, unsigned anum) const;
+
+private:
+ void doGetUserAxis(dVector3 result, unsigned anum) const;
+ void doGetEulerAxis(dVector3 result, unsigned anum) const;
+
+public:
+ void setAngleValue(unsigned anum, dReal angle);
+ dReal getAngleValue(unsigned anum) const { dAASSERT(dIN_RANGE(anum, dSA__MIN, dSA__MAX)); return m_angle[anum]; }
+
+ dReal calculateAngleRate(unsigned anum) const;
+
+ void setLimotParameter(unsigned anum, int limotParam, dReal value) { dAASSERT(dIN_RANGE(anum, dSA__MIN, dSA__MAX)); m_limot[anum].set(limotParam, value); }
+ dReal getLimotParameter(unsigned anum, int limotParam) const { dAASSERT(dIN_RANGE(anum, dSA__MIN, dSA__MAX)); return m_limot[anum].get(limotParam); }
+
+public:
+ void addTorques(dReal torque1, dReal torque2, dReal torque3);
+
+private:
+ void computeGlobalAxes(dVector3 ax[dSA__MAX]) const;
+ void doComputeGlobalUserAxes(dVector3 ax[dSA__MAX]) const;
+ void doComputeGlobalEulerAxes(dVector3 ax[dSA__MAX]) const;
+
+ void computeEulerAngles(dVector3 ax[dSA__MAX]);
+ void setEulerReferenceVectors();
+
+private:
+ inline dSpaceAxis BuildFirstBodyEulerAxis() const;
+ inline dJointConnectedBody BuildFirstEulerAxisBody() const;
+
+private:
+ friend struct dxAMotorJointPrinter;
+
+private:
+ int m_mode; // a dAMotorXXX constant
+ unsigned m_num; // number of axes (0..3)
+ dJointBodyRelativity m_rel[dSA__MAX]; // what the axes are relative to (global,b1,b2)
+ dVector3 m_axis[dSA__MAX]; // three axes
+ // these vectors are used for calculating Euler angles
+ dVector3 m_references[dJCB__MAX]; // original axis[2], relative to body 1; original axis[0], relative to body 2
+ dReal m_angle[dSA__MAX]; // user-supplied angles for axes
+ dxJointLimitMotor m_limot[dJBR__MAX]; // limit+motor info for axes
+};
+
+
+#endif
+
diff --git a/libs/ode-0.16.1/ode/src/joints/ball.cpp b/libs/ode-0.16.1/ode/src/joints/ball.cpp new file mode 100644 index 0000000..c295b85 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/ball.cpp @@ -0,0 +1,186 @@ +/*************************************************************************
+ * *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
+ * All rights reserved. Email: russ@q12.org Web: www.q12.org *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of EITHER: *
+ * (1) The GNU Lesser General Public License as published by the Free *
+ * Software Foundation; either version 2.1 of the License, or (at *
+ * your option) any later version. The text of the GNU Lesser *
+ * General Public License is included with this library in the *
+ * file LICENSE.TXT. *
+ * (2) The BSD-style license that is included with this library in *
+ * the file LICENSE-BSD.TXT. *
+ * *
+ * This library 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 files *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
+ * *
+ *************************************************************************/
+
+
+#include <ode/odeconfig.h>
+#include "config.h"
+#include "ball.h"
+#include "joint_internal.h"
+
+//****************************************************************************
+// ball and socket
+
+dxJointBall::dxJointBall( dxWorld *w ) :
+ dxJoint( w )
+{
+ dSetZero( anchor1, 4 );
+ dSetZero( anchor2, 4 );
+ erp = world->global_erp;
+ cfm = world->global_cfm;
+}
+
+
+void
+dxJointBall::getSureMaxInfo( SureMaxInfo* info )
+{
+ info->max_m = 3;
+}
+
+
+void
+dxJointBall::getInfo1( dxJoint::Info1 *info )
+{
+ info->m = 3;
+ info->nub = 3;
+}
+
+
+void
+dxJointBall::getInfo2( dReal worldFPS, dReal /*worldERP*/,
+ int rowskip, dReal *J1, dReal *J2,
+ int pairskip, dReal *pairRhsCfm, dReal *pairLoHi,
+ int *findex )
+{
+ pairRhsCfm[GI2_CFM] = cfm;
+ pairRhsCfm[pairskip + GI2_CFM] = cfm;
+ pairRhsCfm[2 * pairskip + GI2_CFM] = cfm;
+ setBall( this, worldFPS, this->erp, rowskip, J1, J2, pairskip, pairRhsCfm, anchor1, anchor2 );
+}
+
+
+
+
+
+void dJointSetBallAnchor( dJointID j, dReal x, dReal y, dReal z )
+{
+ dxJointBall* joint = ( dxJointBall* )j;
+ dUASSERT( joint, "bad joint argument" );
+ checktype( joint, Ball );
+ setAnchors( joint, x, y, z, joint->anchor1, joint->anchor2 );
+}
+
+
+void dJointSetBallAnchor2( dJointID j, dReal x, dReal y, dReal z )
+{
+ dxJointBall* joint = ( dxJointBall* )j;
+ dUASSERT( joint, "bad joint argument" );
+ checktype( joint, Ball );
+ joint->anchor2[0] = x;
+ joint->anchor2[1] = y;
+ joint->anchor2[2] = z;
+ joint->anchor2[3] = 0;
+}
+
+void dJointGetBallAnchor( dJointID j, dVector3 result )
+{
+ dxJointBall* joint = ( dxJointBall* )j;
+ dUASSERT( joint, "bad joint argument" );
+ dUASSERT( result, "bad result argument" );
+ checktype( joint, Ball );
+ if ( joint->flags & dJOINT_REVERSE )
+ getAnchor2( joint, result, joint->anchor2 );
+ else
+ getAnchor( joint, result, joint->anchor1 );
+}
+
+
+void dJointGetBallAnchor2( dJointID j, dVector3 result )
+{
+ dxJointBall* joint = ( dxJointBall* )j;
+ dUASSERT( joint, "bad joint argument" );
+ dUASSERT( result, "bad result argument" );
+ checktype( joint, Ball );
+ if ( joint->flags & dJOINT_REVERSE )
+ getAnchor( joint, result, joint->anchor1 );
+ else
+ getAnchor2( joint, result, joint->anchor2 );
+}
+
+
+void dxJointBall::set( int num, dReal value )
+{
+ switch ( num )
+ {
+ case dParamCFM:
+ cfm = value;
+ break;
+ case dParamERP:
+ erp = value;
+ break;
+ }
+}
+
+
+dReal dxJointBall::get( int num )
+{
+ switch ( num )
+ {
+ case dParamCFM:
+ return cfm;
+ case dParamERP:
+ return erp;
+ default:
+ return 0;
+ }
+}
+
+
+void dJointSetBallParam( dJointID j, int parameter, dReal value )
+{
+ dxJointBall* joint = ( dxJointBall* )j;
+ dUASSERT( joint, "bad joint argument" );
+ checktype( joint, Ball );
+ joint->set( parameter, value );
+}
+
+
+dReal dJointGetBallParam( dJointID j, int parameter )
+{
+ dxJointBall* joint = ( dxJointBall* )j;
+ dUASSERT( joint, "bad joint argument" );
+ checktype( joint, Ball );
+ return joint->get( parameter );
+}
+
+
+dJointType
+dxJointBall::type() const
+{
+ return dJointTypeBall;
+}
+
+sizeint
+dxJointBall::size() const
+{
+ return sizeof( *this );
+}
+
+void
+dxJointBall::setRelativeValues()
+{
+ dVector3 anchor;
+ dJointGetBallAnchor(this, anchor);
+ setAnchors( this, anchor[0], anchor[1], anchor[2], anchor1, anchor2 );
+}
+
+
+
diff --git a/libs/ode-0.16.1/ode/src/joints/ball.h b/libs/ode-0.16.1/ode/src/joints/ball.h new file mode 100644 index 0000000..d8d22a5 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/ball.h @@ -0,0 +1,54 @@ +/*************************************************************************
+ * *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
+ * All rights reserved. Email: russ@q12.org Web: www.q12.org *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of EITHER: *
+ * (1) The GNU Lesser General Public License as published by the Free *
+ * Software Foundation; either version 2.1 of the License, or (at *
+ * your option) any later version. The text of the GNU Lesser *
+ * General Public License is included with this library in the *
+ * file LICENSE.TXT. *
+ * (2) The BSD-style license that is included with this library in *
+ * the file LICENSE-BSD.TXT. *
+ * *
+ * This library 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 files *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
+ * *
+ *************************************************************************/
+
+#ifndef _ODE_JOINT_BALL_H_
+#define _ODE_JOINT_BALL_H_
+
+#include "joint.h"
+
+// ball and socket
+
+struct dxJointBall : public dxJoint
+{
+ dVector3 anchor1; // anchor w.r.t first body
+ dVector3 anchor2; // anchor w.r.t second body
+ dReal erp; // error reduction
+ dReal cfm; // constraint force mix in
+ void set( int num, dReal value );
+ dReal get( int num );
+
+ dxJointBall( dxWorld *w );
+ virtual void getSureMaxInfo( SureMaxInfo* info );
+ virtual void getInfo1( Info1* info );
+ virtual void getInfo2( dReal worldFPS, dReal worldERP,
+ int rowskip, dReal *J1, dReal *J2,
+ int pairskip, dReal *pairRhsCfm, dReal *pairLoHi,
+ int *findex );
+ virtual dJointType type() const;
+ virtual sizeint size() const;
+
+ virtual void setRelativeValues();
+};
+
+
+#endif
+
diff --git a/libs/ode-0.16.1/ode/src/joints/contact.cpp b/libs/ode-0.16.1/ode/src/joints/contact.cpp new file mode 100644 index 0000000..5ab3482 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/contact.cpp @@ -0,0 +1,361 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + + +#include <ode/odeconfig.h> +#include "config.h" +#include "contact.h" +#include "joint_internal.h" + + + + //**************************************************************************** + // contact + +dxJointContact::dxJointContact(dxWorld *w) : + dxJoint(w) +{ +} + + +void +dxJointContact::getSureMaxInfo(SureMaxInfo* info) +{ + // ...as the actual m is very likely to hit the maximum + info->max_m = (contact.surface.mode&dContactRolling) ? 6 : 3; +} + + +void +dxJointContact::getInfo1(dxJoint::Info1 *info) +{ + // make sure mu's >= 0, then calculate number of constraint rows and number + // of unbounded rows. + int m = 1, nub = 0; + + // Anisotropic sliding and rolling and spinning friction + if (contact.surface.mode & dContactAxisDep) { + if (contact.surface.mu < 0) { + contact.surface.mu = 0; + } + else if (contact.surface.mu > 0) { + if (contact.surface.mu == dInfinity) { nub++; } + m++; + } + + if (contact.surface.mu2 < 0) { + contact.surface.mu2 = 0; + } + else if (contact.surface.mu2 > 0) { + if (contact.surface.mu2 == dInfinity) { nub++; } + m++; + } + + if ((contact.surface.mode & dContactRolling) != 0) { + if (contact.surface.rho < 0) { + contact.surface.rho = 0; + } + else { + if (contact.surface.rho == dInfinity) { nub++; } + m++; + } + + if (contact.surface.rho2 < 0) { + contact.surface.rho2 = 0; + } + else { + if (contact.surface.rho2 == dInfinity) { nub++; } + m++; + } + + if (contact.surface.rhoN < 0) { + contact.surface.rhoN = 0; + } + else { + if (contact.surface.rhoN == dInfinity) { nub++; } + m++; + } + } + } + else { + if (contact.surface.mu < 0) { + contact.surface.mu = 0; + } + else if (contact.surface.mu > 0) { + if (contact.surface.mu == dInfinity) { nub += 2; } + m += 2; + } + + if ((contact.surface.mode & dContactRolling) != 0) { + if (contact.surface.rho < 0) { + contact.surface.rho = 0; + } + else { + if (contact.surface.rho == dInfinity) { nub += 3; } + m += 3; + } + } + } + + the_m = m; + info->m = m; + info->nub = nub; +} + + +void +dxJointContact::getInfo2(dReal worldFPS, dReal worldERP, + int rowskip, dReal *J1, dReal *J2, + int pairskip, dReal *pairRhsCfm, dReal *pairLoHi, + int *findex) +{ + enum + { + ROW_NORMAL, + + ROW__OPTIONAL_MIN, + }; + + const int surface_mode = contact.surface.mode; + + // set right hand side and cfm value for normal + dReal erp = (surface_mode & dContactSoftERP) != 0 ? contact.surface.soft_erp : worldERP; + dReal k = worldFPS * erp; + + dReal depth = contact.geom.depth - world->contactp.min_depth; + if (depth < 0) depth = 0; + + dReal motionN = (surface_mode & dContactMotionN) != 0 ? contact.surface.motionN : REAL(0.0); + const dReal pushout = k * depth + motionN; + + bool apply_bounce = (surface_mode & dContactBounce) != 0 && contact.surface.bounce_vel >= 0; + dReal outgoing = 0; + + // note: this cap should not limit bounce velocity + const dReal maxvel = world->contactp.max_vel; + dReal c = pushout > maxvel ? maxvel : pushout; + + // c1,c2 = contact points with respect to body PORs + dVector3 c1, c2 = { 0, }; + + // get normal, with sign adjusted for body1/body2 polarity + dVector3 normal; + if ((flags & dJOINT_REVERSE) != 0) { + dCopyNegatedVector3(normal, contact.geom.normal); + } + else { + dCopyVector3(normal, contact.geom.normal); + } + + dxBody *b1 = node[1].body; + if (b1) { + dSubtractVectors3(c2, contact.geom.pos, b1->posr.pos); + // set Jacobian for b1 normal + dCopyNegatedVector3(J2 + ROW_NORMAL * rowskip + GI2__JL_MIN, normal); + dCalcVectorCross3(J2 + ROW_NORMAL * rowskip + GI2__JA_MIN, normal, c2); //== dCalcVectorCross3( J2 + GI2__JA_MIN, c2, normal ); dNegateVector3( J2 + GI2__JA_MIN ); + if (apply_bounce) { + outgoing /*+*/= dCalcVectorDot3(J2 + ROW_NORMAL * rowskip + GI2__JA_MIN, node[1].body->avel) + - dCalcVectorDot3(normal, node[1].body->lvel); + } + } + + dxBody *b0 = node[0].body; + dSubtractVectors3(c1, contact.geom.pos, b0->posr.pos); + // set Jacobian for b0 normal + dCopyVector3(J1 + ROW_NORMAL * rowskip + GI2__JL_MIN, normal); + dCalcVectorCross3(J1 + ROW_NORMAL * rowskip + GI2__JA_MIN, c1, normal); + if (apply_bounce) { + // calculate outgoing velocity (-ve for incoming contact) + outgoing += dCalcVectorDot3(J1 + ROW_NORMAL * rowskip + GI2__JA_MIN, node[0].body->avel) + + dCalcVectorDot3(normal, node[0].body->lvel); + } + + // deal with bounce + if (apply_bounce) { + dReal negated_outgoing = motionN - outgoing; + // only apply bounce if the outgoing velocity is greater than the + // threshold, and if the resulting c[rowNormal] exceeds what we already have. + dIASSERT(contact.surface.bounce_vel >= 0); + if (/*contact.surface.bounce_vel >= 0 &&*/ + negated_outgoing > contact.surface.bounce_vel) { + const dReal newc = contact.surface.bounce * negated_outgoing + motionN; + if (newc > c) { c = newc; } + } + } + + pairRhsCfm[ROW_NORMAL * pairskip + GI2_RHS] = c; + + if ((surface_mode & dContactSoftCFM) != 0) { + pairRhsCfm[ROW_NORMAL * pairskip + GI2_CFM] = contact.surface.soft_cfm; + } + + // set LCP limits for normal + pairLoHi[ROW_NORMAL * pairskip + GI2_LO] = 0; + pairLoHi[ROW_NORMAL * pairskip + GI2_HI] = dInfinity; + + + if (the_m > 1) { // if no friction, there is nothing else to do + // now do jacobian for tangential forces + dVector3 t1, t2; // two vectors tangential to normal + + if ((surface_mode & dContactFDir1) != 0) { // use fdir1 ? + dCopyVector3(t1, contact.fdir1); + dCalcVectorCross3(t2, normal, t1); + } + else { + dPlaneSpace(normal, t1, t2); + } + + int row = ROW__OPTIONAL_MIN; + int currRowSkip = row * rowskip, currPairSkip = row * pairskip; + + // first friction direction + const dReal mu = contact.surface.mu; + + if (mu > 0) { + dCopyVector3(J1 + currRowSkip + GI2__JL_MIN, t1); + dCalcVectorCross3(J1 + currRowSkip + GI2__JA_MIN, c1, t1); + + if (node[1].body) { + dCopyNegatedVector3(J2 + currRowSkip + GI2__JL_MIN, t1); + dCalcVectorCross3(J2 + currRowSkip + GI2__JA_MIN, t1, c2); //== dCalcVectorCross3( J2 + rowskip + GI2__JA_MIN, c2, t1 ); dNegateVector3( J2 + rowskip + GI2__JA_MIN ); + } + + // set right hand side + if ((surface_mode & dContactMotion1) != 0) { + pairRhsCfm[currPairSkip + GI2_RHS] = contact.surface.motion1; + } + // set slip (constraint force mixing) + if ((surface_mode & dContactSlip1) != 0) { + pairRhsCfm[currPairSkip + GI2_CFM] = contact.surface.slip1; + } + + // set LCP bounds and friction index. this depends on the approximation + // mode + pairLoHi[currPairSkip + GI2_LO] = -mu; + pairLoHi[currPairSkip + GI2_HI] = mu; + + if ((surface_mode & dContactApprox1_1) != 0) { + findex[row] = 0; + } + + ++row; + currRowSkip += rowskip; currPairSkip += pairskip; + } + + // second friction direction + const dReal mu2 = (surface_mode & dContactMu2) != 0 ? contact.surface.mu2 : mu; + + if (mu2 > 0) { + dCopyVector3(J1 + currRowSkip + GI2__JL_MIN, t2); + dCalcVectorCross3(J1 + currRowSkip + GI2__JA_MIN, c1, t2); + + if (node[1].body) { + dCopyNegatedVector3(J2 + currRowSkip + GI2__JL_MIN, t2); + dCalcVectorCross3(J2 + currRowSkip + GI2__JA_MIN, t2, c2); //== dCalcVectorCross3( J2 + currRowSkip + GI2__JA_MIN, c2, t2 ); dNegateVector3( J2 + currRowSkip + GI2__JA_MIN ); + } + + // set right hand side + if ((surface_mode & dContactMotion2) != 0) { + pairRhsCfm[currPairSkip + GI2_RHS] = contact.surface.motion2; + } + // set slip (constraint force mixing) + if ((surface_mode & dContactSlip2) != 0) { + pairRhsCfm[currPairSkip + GI2_CFM] = contact.surface.slip2; + } + + // set LCP bounds and friction index. this depends on the approximation + // mode + pairLoHi[currPairSkip + GI2_LO] = -mu2; + pairLoHi[currPairSkip + GI2_HI] = mu2; + + if ((surface_mode & dContactApprox1_2) != 0) { + findex[row] = 0; + } + + ++row; + currRowSkip += rowskip; currPairSkip += pairskip; + } + + // Handle rolling/spinning friction + if ((surface_mode & dContactRolling) != 0) { + + const dReal *const ax[3] = { + t1, // Rolling around t1 creates movement parallel to t2 + t2, + normal // Spinning axis + }; + + const int approx_bits[3] = { dContactApprox1_1, dContactApprox1_2, dContactApprox1_N }; + + // Get the coefficients + dReal rho[3]; + rho[0] = contact.surface.rho; + if ((surface_mode & dContactAxisDep) != 0) { + rho[1] = contact.surface.rho2; + rho[2] = contact.surface.rhoN; + } + else { + rho[1] = rho[0]; + rho[2] = rho[0]; + } + + for (int i = 0; i != 3; ++i) { + if (rho[i] > 0) { + // Set the angular axis + dCopyVector3(J1 + currRowSkip + GI2__JA_MIN, ax[i]); + + if (b1) { + dCopyNegatedVector3(J2 + currRowSkip + GI2__JA_MIN, ax[i]); + } + + // Set the lcp limits + pairLoHi[currPairSkip + GI2_LO] = -rho[i]; + pairLoHi[currPairSkip + GI2_HI] = rho[i]; + + // Should we use proportional force? + if ((surface_mode & approx_bits[i]) != 0) { + // Make limits proportional to normal force + findex[row] = 0; + } + + ++row; + currRowSkip += rowskip; currPairSkip += pairskip; + } + } + } + } +} + +dJointType +dxJointContact::type() const +{ + return dJointTypeContact; +} + + +sizeint +dxJointContact::size() const +{ + return sizeof(*this); +} + diff --git a/libs/ode-0.16.1/ode/src/joints/contact.h b/libs/ode-0.16.1/ode/src/joints/contact.h new file mode 100644 index 0000000..604a4fb --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/contact.h @@ -0,0 +1,48 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_JOINT_CONTACT_H_ +#define _ODE_JOINT_CONTACT_H_ + +#include "joint.h" + +// contact + +struct dxJointContact : public dxJoint +{ + int the_m; // number of rows computed by getInfo1 + dContact contact; + + dxJointContact( dxWorld* w ); + virtual void getSureMaxInfo( SureMaxInfo* info ); + virtual void getInfo1( Info1* info ); + virtual void getInfo2( dReal worldFPS, dReal worldERP, + int rowskip, dReal *J1, dReal *J2, + int pairskip, dReal *pairRhsCfm, dReal *pairLoHi, + int *findex); + virtual dJointType type() const; + virtual sizeint size() const; +}; + + +#endif + diff --git a/libs/ode-0.16.1/ode/src/joints/dball.cpp b/libs/ode-0.16.1/ode/src/joints/dball.cpp new file mode 100644 index 0000000..3754646 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/dball.cpp @@ -0,0 +1,314 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + + +#include <ode/odeconfig.h> +#include "config.h" +#include "dball.h" +#include "joint_internal.h" + +/* + * Double Ball joint: tries to maintain a fixed distance between two anchor + * points. + */ + +dxJointDBall::dxJointDBall(dxWorld *w) : + dxJoint(w) +{ + dSetZero(anchor1, 3); + dSetZero(anchor2, 3); + targetDistance = 0; + erp = world->global_erp; + cfm = world->global_cfm; +} + +void +dxJointDBall::getSureMaxInfo( SureMaxInfo* info ) +{ + info->max_m = 1; +} +void +dxJointDBall::getInfo1( dxJoint::Info1 *info ) +{ + info->m = 1; + info->nub = 1; +} + +void +dxJointDBall::getInfo2( dReal worldFPS, dReal /*worldERP*/, + int rowskip, dReal *J1, dReal *J2, + int pairskip, dReal *pairRhsCfm, dReal *pairLoHi, + int *findex ) +{ + dVector3 globalA1, globalA2; + dBodyGetRelPointPos(node[0].body, anchor1[0], anchor1[1], anchor1[2], globalA1); + + if (node[1].body) { + dBodyGetRelPointPos(node[1].body, anchor2[0], anchor2[1], anchor2[2], globalA2); + } else { + dCopyVector3(globalA2, anchor2); + } + + dVector3 q; + dSubtractVectors3(q, globalA1, globalA2); + +#ifdef dSINGLE + const dReal MIN_LENGTH = REAL(1e-7); +#else + const dReal MIN_LENGTH = REAL(1e-12); +#endif + + if (dCalcVectorLength3(q) < MIN_LENGTH) { + // too small, let's choose an arbitrary direction + // heuristic: difference in velocities at anchors + dVector3 v1, v2; + dBodyGetPointVel(node[0].body, globalA1[0], globalA1[1], globalA1[2], v1); + + if (node[1].body) { + dBodyGetPointVel(node[1].body, globalA2[0], globalA2[1], globalA2[2], v2); + } else { + dZeroVector3(v2); + } + + dSubtractVectors3(q, v1, v2); + + if (dCalcVectorLength3(q) < MIN_LENGTH) { + // this direction is as good as any + dAssignVector3(q, 1, 0, 0); + } + } + dNormalize3(q); + + dCopyVector3(J1 + GI2__JL_MIN, q); + + dVector3 relA1; + dBodyVectorToWorld(node[0].body, + anchor1[0], anchor1[1], anchor1[2], + relA1); + + dMatrix3 a1m; + dZeroMatrix3(a1m); + dSetCrossMatrixMinus(a1m, relA1, 4); + + dMultiply1_331(J1 + GI2__JA_MIN, a1m, q); + + if (node[1].body) { + dCopyNegatedVector3(J2 + GI2__JL_MIN, q); + + dVector3 relA2; + dBodyVectorToWorld(node[1].body, + anchor2[0], anchor2[1], anchor2[2], + relA2); + dMatrix3 a2m; + dZeroMatrix3(a2m); + dSetCrossMatrixPlus(a2m, relA2, 4); + dMultiply1_331(J2 + GI2__JA_MIN, a2m, q); + } + + const dReal k = worldFPS * this->erp; + pairRhsCfm[GI2_RHS] = k * (targetDistance - dCalcPointsDistance3(globalA1, globalA2)); + pairRhsCfm[GI2_CFM] = this->cfm; +} + + +void +dxJointDBall::updateTargetDistance() +{ + dVector3 p1, p2; + + if (node[0].body) + dBodyGetRelPointPos(node[0].body, anchor1[0], anchor1[1], anchor1[2], p1); + else + dCopyVector3(p1, anchor1); + if (node[1].body) + dBodyGetRelPointPos(node[1].body, anchor2[0], anchor2[1], anchor2[2], p2); + else + dCopyVector3(p2, anchor2); + + targetDistance = dCalcPointsDistance3(p1, p2); +} + + +void dJointSetDBallAnchor1( dJointID j, dReal x, dReal y, dReal z ) +{ + dxJointDBall* joint = static_cast<dxJointDBall*>(j); + dUASSERT( joint, "bad joint argument" ); + + if ( joint->flags & dJOINT_REVERSE ) { + if (joint->node[1].body) + dBodyGetPosRelPoint(joint->node[1].body, x, y, z, joint->anchor2); + else { + joint->anchor2[0] = x; + joint->anchor2[1] = y; + joint->anchor2[2] = z; + } + } else { + if (joint->node[0].body) + dBodyGetPosRelPoint(joint->node[0].body, x, y, z, joint->anchor1); + else { + joint->anchor1[0] = x; + joint->anchor1[1] = y; + joint->anchor1[2] = z; + } + } + + joint->updateTargetDistance(); +} + + +void dJointSetDBallAnchor2( dJointID j, dReal x, dReal y, dReal z ) +{ + dxJointDBall* joint = static_cast<dxJointDBall*>(j); + dUASSERT( joint, "bad joint argument" ); + + + if ( joint->flags & dJOINT_REVERSE ) { + if (joint->node[0].body) + dBodyGetPosRelPoint(joint->node[0].body, x, y, z, joint->anchor1); + else { + joint->anchor1[0] = x; + joint->anchor1[1] = y; + joint->anchor1[2] = z; + } + } else { + if (joint->node[1].body) + dBodyGetPosRelPoint(joint->node[1].body, x, y, z, joint->anchor2); + else { + joint->anchor2[0] = x; + joint->anchor2[1] = y; + joint->anchor2[2] = z; + } + } + + joint->updateTargetDistance(); +} + +dReal dJointGetDBallDistance(dJointID j) +{ + dxJointDBall* joint = static_cast<dxJointDBall*>(j); + dUASSERT( joint, "bad joint argument" ); + + return joint->targetDistance; +} + +void dJointSetDBallDistance(dJointID j, dReal dist) +{ + dxJointDBall* joint = static_cast<dxJointDBall*>(j); + dUASSERT( joint, "bad joint argument" ); + dUASSERT( dist>=0, "target distance must be non-negative" ); + + joint->targetDistance = dist; +} + + +void dJointGetDBallAnchor1( dJointID j, dVector3 result ) +{ + dxJointDBall* joint = static_cast<dxJointDBall*>(j); + dUASSERT( joint, "bad joint argument" ); + dUASSERT( result, "bad result argument" ); + + if ( joint->flags & dJOINT_REVERSE ) { + if (joint->node[1].body) + dBodyGetRelPointPos(joint->node[1].body, joint->anchor2[0], joint->anchor2[1], joint->anchor2[2], result); + else + dCopyVector3(result, joint->anchor2); + } else { + if (joint->node[0].body) + dBodyGetRelPointPos(joint->node[0].body, joint->anchor1[0], joint->anchor1[1], joint->anchor1[2], result); + else + dCopyVector3(result, joint->anchor1); + } +} + + +void dJointGetDBallAnchor2( dJointID j, dVector3 result ) +{ + dxJointDBall* joint = static_cast<dxJointDBall*>(j); + dUASSERT( joint, "bad joint argument" ); + dUASSERT( result, "bad result argument" ); + + if ( joint->flags & dJOINT_REVERSE ) { + if (joint->node[0].body) + dBodyGetRelPointPos(joint->node[0].body, joint->anchor1[0], joint->anchor1[1], joint->anchor1[2], result); + else + dCopyVector3(result, joint->anchor1); + } else { + if (joint->node[1].body) + dBodyGetRelPointPos(joint->node[1].body, joint->anchor2[0], joint->anchor2[1], joint->anchor2[2], result); + else + dCopyVector3(result, joint->anchor2); + } +} + + +void dJointSetDBallParam( dJointID j, int parameter, dReal value ) +{ + dxJointDBall* joint = static_cast<dxJointDBall*>(j); + dUASSERT( joint, "bad joint argument" ); + + switch ( parameter ) { + case dParamCFM: + joint->cfm = value; + break; + case dParamERP: + joint->erp = value; + break; + } +} + + +dReal dJointGetDBallParam( dJointID j, int parameter ) +{ + dxJointDBall* joint = static_cast<dxJointDBall*>(j); + dUASSERT( joint, "bad joint argument" ); + + switch ( parameter ) { + case dParamCFM: + return joint->cfm; + case dParamERP: + return joint->erp; + default: + return 0; + } +} + + +dJointType +dxJointDBall::type() const +{ + return dJointTypeDBall; +} + +sizeint +dxJointDBall::size() const +{ + return sizeof( *this ); +} + +void +dxJointDBall::setRelativeValues() +{ + updateTargetDistance(); +} + + + diff --git a/libs/ode-0.16.1/ode/src/joints/dball.h b/libs/ode-0.16.1/ode/src/joints/dball.h new file mode 100644 index 0000000..e52fc6c --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/dball.h @@ -0,0 +1,58 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_JOINT_DBALL_H_ +#define _ODE_JOINT_DBALL_H_ + +#include "joint.h" + +// ball and socket + +struct dxJointDBall : public dxJoint +{ + dVector3 anchor1; // anchor w.r.t first body + dVector3 anchor2; // anchor w.r.t second body + dReal erp; // error reduction + dReal cfm; // constraint force mix in + dReal targetDistance; + + void set( int num, dReal value ); + dReal get( int num ); + + void updateTargetDistance(); + + dxJointDBall( dxWorld *w ); + virtual void getSureMaxInfo( SureMaxInfo* info ); + virtual void getInfo1( Info1* info ); + virtual void getInfo2( dReal worldFPS, dReal worldERP, + int rowskip, dReal *J1, dReal *J2, + int pairskip, dReal *pairRhsCfm, dReal *pairLoHi, + int *findex ); + virtual dJointType type() const; + virtual sizeint size() const; + + virtual void setRelativeValues(); +}; + + +#endif + diff --git a/libs/ode-0.16.1/ode/src/joints/dhinge.cpp b/libs/ode-0.16.1/ode/src/joints/dhinge.cpp new file mode 100644 index 0000000..e300bf5 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/dhinge.cpp @@ -0,0 +1,220 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + + +#include <ode/odeconfig.h> +#include "config.h" +#include "dhinge.h" +#include "joint_internal.h" + +/* + * Double Hinge joint + */ + +dxJointDHinge::dxJointDHinge(dxWorld* w) : + dxJointDBall(w) +{ + dSetZero(axis1, 3); + dSetZero(axis2, 3); +} + + +void +dxJointDHinge::getSureMaxInfo( SureMaxInfo* info ) +{ + info->max_m = 4; +} + + +void +dxJointDHinge::getInfo1( dxJoint::Info1* info ) +{ + info->m = 4; + info->nub = 4; +} + + +void +dxJointDHinge::getInfo2( dReal worldFPS, dReal worldERP, + int rowskip, dReal *J1, dReal *J2, + int pairskip, dReal *pairRhsCfm, dReal *pairLoHi, + int *findex ) +{ + dxJointDBall::getInfo2( worldFPS, worldERP, rowskip, J1, J2, pairskip, pairRhsCfm, pairLoHi, findex ); // sets row0 + + dVector3 globalAxis1; + dBodyVectorToWorld(node[0].body, axis1[0], axis1[1], axis1[2], globalAxis1); + + dxBody *body1 = node[1].body; + + // angular constraints, perpendicular to axis + dVector3 p, q; + dPlaneSpace(globalAxis1, p, q); + + dCopyVector3(J1 + rowskip + GI2__JA_MIN, p); + if ( body1 ) { + dCopyNegatedVector3(J2 + rowskip + GI2__JA_MIN, p); + } + + dCopyVector3(J1 + 2 * rowskip + GI2__JA_MIN, q); + if ( body1 ) { + dCopyNegatedVector3(J2 + 2 * rowskip + GI2__JA_MIN, q); + } + + dVector3 globalAxis2; + if ( body1 ) { + dBodyVectorToWorld(body1, axis2[0], axis2[1], axis2[2], globalAxis2); + } else { + dCopyVector3(globalAxis2, axis2); + } + + // similar to the hinge joint + dVector3 u; + dCalcVectorCross3(u, globalAxis1, globalAxis2); + + const dReal k = worldFPS * this->erp; + pairRhsCfm[pairskip + GI2_RHS] = k * dCalcVectorDot3( u, p ); + pairRhsCfm[2 * pairskip + GI2_RHS] = k * dCalcVectorDot3( u, q ); + + + + + /* + * Constraint along the axis: translation along it should couple angular movement. + * This is just the ball-and-socket derivation, projected onto the hinge axis, + * producing a single constraint at the end. + * + * The choice of "ball" position can be arbitrary; we could place it at the center + * of one of the bodies, canceling out its rotational jacobian; or we could make + * everything symmetrical by just placing at the midpoint between the centers. + * + * I like symmetry, so I'll use the second approach here. I'll call the midpoint h. + * + * Of course, if the second body is NULL, the first body is pretty much locked + * along this axis, and the linear constraint is enough. + */ + + int rowskip_mul_3 = 3 * rowskip; + dCopyVector3(J1 + rowskip_mul_3 + GI2__JL_MIN, globalAxis1); + + if ( body1 ) { + dVector3 h; + dAddScaledVectors3(h, node[0].body->posr.pos, body1->posr.pos, -0.5, 0.5); + + dCalcVectorCross3(J1 + rowskip_mul_3 + GI2__JA_MIN, h, globalAxis1); + + dCopyNegatedVector3(J2 + rowskip_mul_3 + GI2__JL_MIN, globalAxis1); + dCopyVector3(J2 + rowskip_mul_3 + GI2__JA_MIN, J1 + rowskip_mul_3 + GI2__JA_MIN); + } + + // error correction: both anchors should lie on the same plane perpendicular to the axis + dVector3 globalA1, globalA2; + dBodyGetRelPointPos(node[0].body, anchor1[0], anchor1[1], anchor1[2], globalA1); + + if ( body1 ) { + dBodyGetRelPointPos(body1, anchor2[0], anchor2[1], anchor2[2], globalA2); + } else { + dCopyVector3(globalA2, anchor2); + } + + dVector3 d; + dSubtractVectors3(d, globalA1, globalA2); // displacement error + pairRhsCfm[3 * pairskip + GI2_RHS] = -k * dCalcVectorDot3(globalAxis1, d); +} + +void dJointSetDHingeAxis( dJointID j, dReal x, dReal y, dReal z ) +{ + dxJointDHinge* joint = static_cast<dxJointDHinge*>(j); + dUASSERT( joint, "bad joint argument" ); + + dBodyVectorFromWorld(joint->node[0].body, x, y, z, joint->axis1); + if (joint->node[1].body) + dBodyVectorFromWorld(joint->node[1].body, x, y, z, joint->axis2); + else { + joint->axis2[0] = x; + joint->axis2[1] = y; + joint->axis2[2] = z; + } + dNormalize3(joint->axis1); + dNormalize3(joint->axis2); +} + +void dJointGetDHingeAxis( dJointID j, dVector3 result ) +{ + dxJointDHinge* joint = static_cast<dxJointDHinge*>(j); + dUASSERT( joint, "bad joint argument" ); + + dBodyVectorToWorld(joint->node[0].body, joint->axis1[0], joint->axis1[1], joint->axis1[2], result); +} + + +void dJointSetDHingeAnchor1( dJointID j, dReal x, dReal y, dReal z ) +{ + dJointSetDBallAnchor1(j, x, y, z); +} + + +void dJointSetDHingeAnchor2( dJointID j, dReal x, dReal y, dReal z ) +{ + dJointSetDBallAnchor2(j, x, y, z); +} + +dReal dJointGetDHingeDistance(dJointID j) +{ + return dJointGetDBallDistance(j); +} + + +void dJointGetDHingeAnchor1( dJointID j, dVector3 result ) +{ + dJointGetDBallAnchor1(j, result); +} + + +void dJointGetDHingeAnchor2( dJointID j, dVector3 result ) +{ + dJointGetDBallAnchor2(j, result); +} + + +void dJointSetDHingeParam( dJointID j, int parameter, dReal value ) +{ + dJointSetDBallParam(j, parameter, value); +} + + +dReal dJointGetDHingeParam( dJointID j, int parameter ) +{ + return dJointGetDBallParam(j, parameter); +} + +dJointType +dxJointDHinge::type() const +{ + return dJointTypeDHinge; +} + +sizeint +dxJointDHinge::size() const +{ + return sizeof( *this ); +} diff --git a/libs/ode-0.16.1/ode/src/joints/dhinge.h b/libs/ode-0.16.1/ode/src/joints/dhinge.h new file mode 100644 index 0000000..efc5688 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/dhinge.h @@ -0,0 +1,46 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_JOINT_DHINGE_ +#define _ODE_JOINT_DHINGE_ + +#include "dball.h" + +struct dxJointDHinge : public dxJointDBall +{ + dVector3 axis1, axis2; + + dxJointDHinge(dxWorld *w); + + virtual void getSureMaxInfo( SureMaxInfo* info ); + virtual void getInfo1( Info1* info ); + virtual void getInfo2( dReal worldFPS, dReal worldERP, + int rowskip, dReal *J1, dReal *J2, + int pairskip, dReal *pairRhsCfm, dReal *pairLoHi, + int *findex ); + virtual dJointType type() const; + virtual sizeint size() const; + +}; + + +#endif diff --git a/libs/ode-0.16.1/ode/src/joints/fixed.cpp b/libs/ode-0.16.1/ode/src/joints/fixed.cpp new file mode 100644 index 0000000..527bf48 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/fixed.cpp @@ -0,0 +1,216 @@ +/*************************************************************************
+ * *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
+ * All rights reserved. Email: russ@q12.org Web: www.q12.org *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of EITHER: *
+ * (1) The GNU Lesser General Public License as published by the Free *
+ * Software Foundation; either version 2.1 of the License, or (at *
+ * your option) any later version. The text of the GNU Lesser *
+ * General Public License is included with this library in the *
+ * file LICENSE.TXT. *
+ * (2) The BSD-style license that is included with this library in *
+ * the file LICENSE-BSD.TXT. *
+ * *
+ * This library 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 files *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
+ * *
+ *************************************************************************/
+
+
+#include <ode/odeconfig.h>
+#include "config.h"
+#include "fixed.h"
+#include "joint_internal.h"
+
+
+
+//****************************************************************************
+// fixed joint
+
+dxJointFixed::dxJointFixed ( dxWorld *w ) :
+ dxJoint ( w )
+{
+ dSetZero ( offset, 4 );
+ dSetZero ( qrel, 4 );
+ erp = world->global_erp;
+ cfm = world->global_cfm;
+}
+
+
+void
+dxJointFixed::getSureMaxInfo( SureMaxInfo* info )
+{
+ info->max_m = 6;
+}
+
+
+void
+dxJointFixed::getInfo1 ( dxJoint::Info1 *info )
+{
+ info->m = 6;
+ info->nub = 6;
+}
+
+
+void
+dxJointFixed::getInfo2 ( dReal worldFPS, dReal worldERP,
+ int rowskip, dReal *J1, dReal *J2,
+ int pairskip, dReal *pairRhsCfm, dReal *pairLoHi,
+ int *findex )
+{
+ // Three rows for orientation
+ setFixedOrientation ( this, worldFPS, worldERP,
+ rowskip, J1 + dSA__MAX * rowskip, J2 + dSA__MAX * rowskip,
+ pairskip, pairRhsCfm + dSA__MAX * pairskip, qrel );
+
+ // Three rows for position.
+ // set Jacobian
+ J1[GI2_JLX] = 1;
+ J1[rowskip + GI2_JLY] = 1;
+ J1[2 * rowskip + GI2_JLZ] = 1;
+
+ dReal k = worldFPS * this->erp;
+ dxBody *b0 = node[0].body, *b1 = node[1].body;
+
+ dVector3 ofs;
+ dMultiply0_331 ( ofs, b0->posr.R, offset );
+
+ if ( b1 ) {
+ dSetCrossMatrixPlus( J1 + GI2__JA_MIN, ofs, rowskip );
+
+ J2[GI2_JLX] = -1;
+ J2[rowskip + GI2_JLY] = -1;
+ J2[2 * rowskip + GI2_JLZ] = -1;
+ }
+
+ // set right hand side for the first three rows (linear)
+ if ( b1 ) {
+ for ( int j = 0, currPairSkip = 0; j < 3; currPairSkip += pairskip, ++j ) {
+ pairRhsCfm[currPairSkip + GI2_RHS] = k * ( b1->posr.pos[j] - b0->posr.pos[j] + ofs[j] );
+ }
+ } else {
+ for ( int j = 0, currPairSkip = 0; j < 3; currPairSkip += pairskip, ++j ) {
+ pairRhsCfm[currPairSkip + GI2_RHS] = k * ( offset[j] - b0->posr.pos[j] );
+ }
+ }
+
+ dReal cfm = this->cfm;
+ pairRhsCfm[GI2_CFM] = cfm;
+ pairRhsCfm[pairskip + GI2_CFM] = cfm;
+ pairRhsCfm[2 * pairskip + GI2_CFM] = cfm;
+}
+
+
+void dJointSetFixed ( dJointID j )
+{
+ dxJointFixed* joint = ( dxJointFixed* ) j;
+ dUASSERT ( joint, "bad joint argument" );
+ checktype ( joint, Fixed );
+ int i;
+
+ // This code is taken from dJointSetSliderAxis(), we should really put the
+ // common code in its own function.
+ // compute the offset between the bodies
+ if ( joint->node[0].body )
+ {
+ if ( joint->node[1].body )
+ {
+ dReal ofs[4];
+ for ( i = 0; i < 4; i++ )
+ ofs[i] = joint->node[0].body->posr.pos[i] - joint->node[1].body->posr.pos[i];
+ dMultiply1_331 ( joint->offset, joint->node[0].body->posr.R, ofs );
+ }
+ else
+ {
+ joint->offset[0] = joint->node[0].body->posr.pos[0];
+ joint->offset[1] = joint->node[0].body->posr.pos[1];
+ joint->offset[2] = joint->node[0].body->posr.pos[2];
+ }
+ }
+
+ joint->computeInitialRelativeRotation();
+}
+
+void dxJointFixed::set ( int num, dReal value )
+{
+ switch ( num )
+ {
+ case dParamCFM:
+ cfm = value;
+ break;
+ case dParamERP:
+ erp = value;
+ break;
+ }
+}
+
+
+dReal dxJointFixed::get ( int num )
+{
+ switch ( num )
+ {
+ case dParamCFM:
+ return cfm;
+ case dParamERP:
+ return erp;
+ default:
+ return 0;
+ }
+}
+
+
+void dJointSetFixedParam ( dJointID j, int parameter, dReal value )
+{
+ dxJointFixed* joint = ( dxJointFixed* ) j;
+ dUASSERT ( joint, "bad joint argument" );
+ checktype ( joint, Fixed );
+ joint->set ( parameter, value );
+}
+
+
+dReal dJointGetFixedParam ( dJointID j, int parameter )
+{
+ dxJointFixed* joint = ( dxJointFixed* ) j;
+ dUASSERT ( joint, "bad joint argument" );
+ checktype ( joint, Fixed );
+ return joint->get ( parameter );
+}
+
+
+dJointType
+dxJointFixed::type() const
+{
+ return dJointTypeFixed;
+}
+
+
+sizeint
+dxJointFixed::size() const
+{
+ return sizeof ( *this );
+}
+
+void
+dxJointFixed::computeInitialRelativeRotation()
+{
+ if (node[0].body )
+ {
+ if (node[1].body )
+ {
+ dQMultiply1 (qrel, node[0].body->q, node[1].body->q );
+ }
+ else
+ {
+ // set qrel to the transpose of the first body q
+ qrel[0] = node[0].body->q[0];
+ qrel[1] = -node[0].body->q[1];
+ qrel[2] = -node[0].body->q[2];
+ qrel[3] = -node[0].body->q[3];
+ }
+ }
+}
+
diff --git a/libs/ode-0.16.1/ode/src/joints/fixed.h b/libs/ode-0.16.1/ode/src/joints/fixed.h new file mode 100644 index 0000000..c0f6932 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/fixed.h @@ -0,0 +1,54 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_JOINT_FIXED_H_ +#define _ODE_JOINT_FIXED_H_ + +#include "joint.h" + + +// fixed + +struct dxJointFixed : public dxJoint +{ + dQuaternion qrel; // initial relative rotation body1 -> body2 + dVector3 offset; // relative offset between the bodies + dReal erp; // error reduction parameter + dReal cfm; // constraint force mix-in + void set ( int num, dReal value ); + dReal get ( int num ); + + dxJointFixed ( dxWorld *w ); + virtual void getSureMaxInfo( SureMaxInfo* info ); + virtual void getInfo1 ( Info1* info ); + virtual void getInfo2 ( dReal worldFPS, dReal worldERP, + int rowskip, dReal *J1, dReal *J2, + int pairskip, dReal *pairRhsCfm, dReal *pairLoHi, + int *findex ); + virtual dJointType type() const; + virtual sizeint size() const; + + void computeInitialRelativeRotation(); +}; + + +#endif diff --git a/libs/ode-0.16.1/ode/src/joints/hinge.cpp b/libs/ode-0.16.1/ode/src/joints/hinge.cpp new file mode 100644 index 0000000..70dcd78 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/hinge.cpp @@ -0,0 +1,394 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + + +#include <ode/odeconfig.h> +#include "config.h" +#include "hinge.h" +#include "joint_internal.h" + + +//**************************************************************************** +// hinge + +dxJointHinge::dxJointHinge( dxWorld *w ) : + dxJoint( w ) +{ + dSetZero( anchor1, 4 ); + dSetZero( anchor2, 4 ); + dSetZero( axis1, 4 ); + axis1[0] = 1; + dSetZero( axis2, 4 ); + axis2[0] = 1; + dSetZero( qrel, 4 ); + limot.init( world ); +} + + +void +dxJointHinge::getSureMaxInfo( SureMaxInfo* info ) +{ + info->max_m = 6; +} + + +void +dxJointHinge::getInfo1( dxJoint::Info1 *info ) +{ + info->nub = 5; + + // see if joint is powered + if ( limot.fmax > 0 ) + info->m = 6; // powered hinge needs an extra constraint row + else info->m = 5; + + // see if we're at a joint limit. + if (( limot.lostop >= -M_PI || limot.histop <= M_PI ) && + limot.lostop <= limot.histop ) + { + dReal angle = getHingeAngle( node[0].body, + node[1].body, + axis1, qrel ); + if ( limot.testRotationalLimit( angle ) ) + info->m = 6; + } +} + + +void dxJointHinge::getInfo2( dReal worldFPS, dReal worldERP, + int rowskip, dReal *J1, dReal *J2, + int pairskip, dReal *pairRhsCfm, dReal *pairLoHi, + int *findex ) +{ + // set the three ball-and-socket rows + setBall( this, worldFPS, worldERP, rowskip, J1, J2, pairskip, pairRhsCfm, anchor1, anchor2 ); + + // set the two hinge rows. the hinge axis should be the only unconstrained + // rotational axis, the angular velocity of the two bodies perpendicular to + // the hinge axis should be equal. thus the constraint equations are + // p*w1 - p*w2 = 0 + // q*w1 - q*w2 = 0 + // where p and q are unit vectors normal to the hinge axis, and w1 and w2 + // are the angular velocity vectors of the two bodies. + + dVector3 ax1; // length 1 joint axis in global coordinates, from 1st body + dVector3 p, q; // plane space vectors for ax1 + dMultiply0_331( ax1, node[0].body->posr.R, axis1 ); + dPlaneSpace( ax1, p, q ); + + dxBody *body1 = node[1].body; + + int currRowSkip = 3 * rowskip; + dCopyVector3(J1 + currRowSkip + GI2__JA_MIN, p); + if ( body1 ) { + dCopyNegatedVector3(J2 + currRowSkip + GI2__JA_MIN, p); + } + + currRowSkip += rowskip; + dCopyVector3(J1 + currRowSkip + GI2__JA_MIN, q); + if ( body1 ) { + dCopyNegatedVector3(J2 + currRowSkip + GI2__JA_MIN, q); + } + + // 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. + + dVector3 b; + if ( body1 ) { + dVector3 ax2; + dMultiply0_331( ax2, body1->posr.R, axis2 ); + dCalcVectorCross3( b, ax1, ax2 ); + } else { + dCalcVectorCross3( b, ax1, axis2 ); + } + + dReal k = worldFPS * worldERP; + int currPairSkip = 3 * pairskip; + pairRhsCfm[currPairSkip + GI2_RHS] = k * dCalcVectorDot3( b, p ); + currPairSkip += pairskip; + pairRhsCfm[currPairSkip + GI2_RHS] = k * dCalcVectorDot3( b, q ); + + // if the hinge is powered, or has joint limits, add in the stuff + currRowSkip += rowskip; + currPairSkip += pairskip; + limot.addLimot( this, worldFPS, J1 + currRowSkip, J2 + currRowSkip, pairRhsCfm + currPairSkip, pairLoHi + currPairSkip, ax1, 1 ); +} + + + +void dJointSetHingeAnchor( dJointID j, dReal x, dReal y, dReal z ) +{ + dxJointHinge* joint = ( dxJointHinge* )j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Hinge ); + setAnchors( joint, x, y, z, joint->anchor1, joint->anchor2 ); + joint->computeInitialRelativeRotation(); +} + + +void dJointSetHingeAnchorDelta( dJointID j, dReal x, dReal y, dReal z, dReal dx, dReal dy, dReal dz ) +{ + dxJointHinge* joint = ( dxJointHinge* )j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Hinge ); + + if ( joint->node[0].body ) + { + dReal q[4]; + q[0] = x - joint->node[0].body->posr.pos[0]; + q[1] = y - joint->node[0].body->posr.pos[1]; + q[2] = z - joint->node[0].body->posr.pos[2]; + q[3] = 0; + dMultiply1_331( joint->anchor1, joint->node[0].body->posr.R, q ); + + if ( joint->node[1].body ) + { + q[0] = x - joint->node[1].body->posr.pos[0]; + q[1] = y - joint->node[1].body->posr.pos[1]; + q[2] = z - joint->node[1].body->posr.pos[2]; + q[3] = 0; + dMultiply1_331( joint->anchor2, joint->node[1].body->posr.R, q ); + } + else + { + // Move the relative displacement between the passive body and the + // anchor in the same direction as the passive body has just moved + joint->anchor2[0] = x + dx; + joint->anchor2[1] = y + dy; + joint->anchor2[2] = z + dz; + } + } + joint->anchor1[3] = 0; + joint->anchor2[3] = 0; + + joint->computeInitialRelativeRotation(); +} + + + +void dJointSetHingeAxis( dJointID j, dReal x, dReal y, dReal z ) +{ + dxJointHinge* joint = ( dxJointHinge* )j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Hinge ); + setAxes( joint, x, y, z, joint->axis1, joint->axis2 ); + joint->computeInitialRelativeRotation(); +} + + +void dJointSetHingeAxisOffset( dJointID j, dReal x, dReal y, dReal z, dReal dangle ) +{ + dxJointHinge* joint = ( dxJointHinge* )j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Hinge ); + setAxes( joint, x, y, z, joint->axis1, joint->axis2 ); + joint->computeInitialRelativeRotation(); + + if ( joint->flags & dJOINT_REVERSE ) dangle = -dangle; + + dQuaternion qAngle, qOffset; + dQFromAxisAndAngle(qAngle, x, y, z, dangle); + dQMultiply3(qOffset, qAngle, joint->qrel); + joint->qrel[0] = qOffset[0]; + joint->qrel[1] = qOffset[1]; + joint->qrel[2] = qOffset[2]; + joint->qrel[3] = qOffset[3]; +} + + + +void dJointGetHingeAnchor( dJointID j, dVector3 result ) +{ + dxJointHinge* joint = ( dxJointHinge* )j; + dUASSERT( joint, "bad joint argument" ); + dUASSERT( result, "bad result argument" ); + checktype( joint, Hinge ); + if ( joint->flags & dJOINT_REVERSE ) + getAnchor2( joint, result, joint->anchor2 ); + else + getAnchor( joint, result, joint->anchor1 ); +} + + +void dJointGetHingeAnchor2( dJointID j, dVector3 result ) +{ + dxJointHinge* joint = ( dxJointHinge* )j; + dUASSERT( joint, "bad joint argument" ); + dUASSERT( result, "bad result argument" ); + checktype( joint, Hinge ); + if ( joint->flags & dJOINT_REVERSE ) + getAnchor( joint, result, joint->anchor1 ); + else + getAnchor2( joint, result, joint->anchor2 ); +} + + +void dJointGetHingeAxis( dJointID j, dVector3 result ) +{ + dxJointHinge* joint = ( dxJointHinge* )j; + dUASSERT( joint, "bad joint argument" ); + dUASSERT( result, "bad result argument" ); + checktype( joint, Hinge ); + getAxis( joint, result, joint->axis1 ); +} + + +void dJointSetHingeParam( dJointID j, int parameter, dReal value ) +{ + dxJointHinge* joint = ( dxJointHinge* )j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Hinge ); + joint->limot.set( parameter, value ); +} + + +dReal dJointGetHingeParam( dJointID j, int parameter ) +{ + dxJointHinge* joint = ( dxJointHinge* )j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Hinge ); + return joint->limot.get( parameter ); +} + + +dReal dJointGetHingeAngle( dJointID j ) +{ + dxJointHinge* joint = ( dxJointHinge* )j; + dAASSERT( joint ); + checktype( joint, Hinge ); + if ( joint->node[0].body ) + { + dReal ang = getHingeAngle( joint->node[0].body, + joint->node[1].body, + joint->axis1, + joint->qrel ); + if ( joint->flags & dJOINT_REVERSE ) + return -ang; + else + return ang; + } + else return 0; +} + + +dReal dJointGetHingeAngleRate( dJointID j ) +{ + dxJointHinge* joint = ( dxJointHinge* )j; + dAASSERT( joint ); + checktype( joint, Hinge ); + if ( joint->node[0].body ) + { + dVector3 axis; + dMultiply0_331( axis, joint->node[0].body->posr.R, joint->axis1 ); + dReal rate = dCalcVectorDot3( axis, joint->node[0].body->avel ); + if ( joint->node[1].body ) rate -= dCalcVectorDot3( axis, joint->node[1].body->avel ); + if ( joint->flags & dJOINT_REVERSE ) rate = - rate; + return rate; + } + else return 0; +} + + +void dJointAddHingeTorque( dJointID j, dReal torque ) +{ + dxJointHinge* joint = ( dxJointHinge* )j; + dVector3 axis; + dAASSERT( joint ); + checktype( joint, Hinge ); + + if ( joint->flags & dJOINT_REVERSE ) + torque = -torque; + + getAxis( joint, axis, joint->axis1 ); + axis[0] *= torque; + axis[1] *= torque; + axis[2] *= torque; + + if ( joint->node[0].body != 0 ) + dBodyAddTorque( joint->node[0].body, axis[0], axis[1], axis[2] ); + if ( joint->node[1].body != 0 ) + dBodyAddTorque( joint->node[1].body, -axis[0], -axis[1], -axis[2] ); +} + + +dJointType +dxJointHinge::type() const +{ + return dJointTypeHinge; +} + + + +sizeint +dxJointHinge::size() const +{ + return sizeof( *this ); +} + + +void +dxJointHinge::setRelativeValues() +{ + dVector3 vec; + dJointGetHingeAnchor(this, vec); + setAnchors( this, vec[0], vec[1], vec[2], anchor1, anchor2 ); + + dJointGetHingeAxis(this, vec); + setAxes( this, vec[0], vec[1], vec[2], axis1, axis2 ); + computeInitialRelativeRotation(); +} + + +/// Compute initial relative rotation body1 -> body2, or env -> body1 +void +dxJointHinge::computeInitialRelativeRotation() +{ + if ( node[0].body ) + { + if ( node[1].body ) + { + dQMultiply1( qrel, node[0].body->q, node[1].body->q ); + } + else + { + // set qrel to the transpose of the first body q + qrel[0] = node[0].body->q[0]; + qrel[1] = -node[0].body->q[1]; + qrel[2] = -node[0].body->q[2]; + qrel[3] = -node[0].body->q[3]; + } + } +} + diff --git a/libs/ode-0.16.1/ode/src/joints/hinge.h b/libs/ode-0.16.1/ode/src/joints/hinge.h new file mode 100644 index 0000000..0fb4dba --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/hinge.h @@ -0,0 +1,57 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_JOINT_HINGE_H_ +#define _ODE_JOINT_HINGE_H_ + +#include "joint.h" + + +// hinge + +struct dxJointHinge : public dxJoint +{ + dVector3 anchor1; // anchor w.r.t first body + dVector3 anchor2; // anchor w.r.t second body + dVector3 axis1; // axis w.r.t first body + dVector3 axis2; // axis w.r.t second body + dQuaternion qrel; // initial relative rotation body1 -> body2 + dxJointLimitMotor limot; // limit and motor information + + dxJointHinge( dxWorld *w ); + virtual void getSureMaxInfo( SureMaxInfo* info ); + virtual void getInfo1( Info1* info ); + virtual void getInfo2( dReal worldFPS, dReal worldERP, + int rowskip, dReal *J1, dReal *J2, + int pairskip, dReal *pairRhsCfm, dReal *pairLoHi, + int *findex ); + virtual dJointType type() const; + virtual sizeint size() const; + + virtual void setRelativeValues(); + + void computeInitialRelativeRotation(); +}; + + + +#endif diff --git a/libs/ode-0.16.1/ode/src/joints/hinge2.cpp b/libs/ode-0.16.1/ode/src/joints/hinge2.cpp new file mode 100644 index 0000000..89d5e30 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/hinge2.cpp @@ -0,0 +1,546 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + + +#include <ode/odeconfig.h> +#include "config.h" +#include "hinge2.h" +#include "joint_internal.h" + + + + +//**************************************************************************** +// hinge 2. note that this joint must be attached to two bodies for it to work + +dReal +dxJointHinge2::measureAngle1() const +{ + // bring axis 2 into first body's reference frame + dVector3 p, q; + if (node[1].body) + dMultiply0_331( p, node[1].body->posr.R, axis2 ); + else + dCopyVector3(p, axis2); + + if (node[0].body) + dMultiply1_331( q, node[0].body->posr.R, p ); + else + dCopyVector3(q, p); + + dReal x = dCalcVectorDot3( v1, q ); + dReal y = dCalcVectorDot3( v2, q ); + return -dAtan2( y, x ); +} + +dReal +dxJointHinge2::measureAngle2() const +{ + // bring axis 1 into second body's reference frame + dVector3 p, q; + if (node[0].body) + dMultiply0_331( p, node[0].body->posr.R, axis1 ); + else + dCopyVector3(p, axis1); + + if (node[1].body) + dMultiply1_331( q, node[1].body->posr.R, p ); + else + dCopyVector3(q, p); + + dReal x = dCalcVectorDot3( w1, q ); + dReal y = dCalcVectorDot3( w2, q ); + return -dAtan2( y, x ); +} + + +dxJointHinge2::dxJointHinge2( dxWorld *w ) : + dxJoint( w ) +{ + dSetZero( anchor1, 4 ); + dSetZero( anchor2, 4 ); + dSetZero( axis1, 4 ); + axis1[0] = 1; + dSetZero( axis2, 4 ); + axis2[1] = 1; + c0 = 0; + s0 = 0; + + dSetZero( v1, 4 ); + v1[0] = 1; + dSetZero( v2, 4 ); + v2[1] = 1; + + limot1.init( world ); + limot2.init( world ); + + susp_erp = world->global_erp; + susp_cfm = world->global_cfm; + + flags |= dJOINT_TWOBODIES; +} + + +void +dxJointHinge2::getSureMaxInfo( SureMaxInfo* info ) +{ + info->max_m = 6; +} + + +void +dxJointHinge2::getInfo1( dxJoint::Info1 *info ) +{ + info->m = 4; + info->nub = 4; + + // see if we're powered or at a joint limit for axis 1 + limot1.limit = 0; + if (( limot1.lostop >= -M_PI || limot1.histop <= M_PI ) && + limot1.lostop <= limot1.histop ) + { + dReal angle = measureAngle1(); + limot1.testRotationalLimit( angle ); + } + if ( limot1.limit || limot1.fmax > 0 ) info->m++; + + // see if we're powering axis 2 (we currently never limit this axis) + limot2.limit = 0; + if ( limot2.fmax > 0 ) info->m++; +} + + +//////////////////////////////////////////////////////////////////////////////// +/// Function that computes ax1,ax2 = axis 1 and 2 in global coordinates (they are +/// relative to body 1 and 2 initially) and then computes the constrained +/// rotational axis as the cross product of ax1 and ax2. +/// the sin and cos of the angle between axis 1 and 2 is computed, this comes +/// from dot and cross product rules. +/// +/// @param ax1 Will contain the joint axis1 in world frame +/// @param ax2 Will contain the joint axis2 in world frame +/// @param axis Will contain the cross product of ax1 x ax2 +/// @param sin_angle +/// @param cos_angle +//////////////////////////////////////////////////////////////////////////////// +void +dxJointHinge2::getAxisInfo(dVector3 ax1, dVector3 ax2, dVector3 axCross, + dReal &sin_angle, dReal &cos_angle) const +{ + dMultiply0_331 (ax1, node[0].body->posr.R, axis1); + dMultiply0_331 (ax2, node[1].body->posr.R, axis2); + dCalcVectorCross3(axCross,ax1,ax2); + sin_angle = dSqrt (axCross[0]*axCross[0] + axCross[1]*axCross[1] + axCross[2]*axCross[2]); + cos_angle = dCalcVectorDot3 (ax1,ax2); +} + + +void +dxJointHinge2::getInfo2( dReal worldFPS, dReal worldERP, + int rowskip, dReal *J1, dReal *J2, + int pairskip, dReal *pairRhsCfm, dReal *pairLoHi, + int *findex ) +{ + // get information we need to set the hinge row + dReal s, c; + dVector3 q; + + dVector3 ax1, ax2; + getAxisInfo( ax1, ax2, q, s, c ); + dNormalize3( q ); // @@@ quicker: divide q by s ? + + // set the three ball-and-socket rows (aligned to the suspension axis ax1) + setBall2( this, worldFPS, worldERP, rowskip, J1, J2, pairskip, pairRhsCfm, anchor1, anchor2, ax1, susp_erp ); + // set parameter for the suspension + pairRhsCfm[GI2_CFM] = susp_cfm; + + // set the hinge row + int currRowSkip = 3 * rowskip; + dCopyVector3(J1 + currRowSkip + GI2__JA_MIN, q); + if ( node[1].body ) { + dCopyNegatedVector3(J2 + currRowSkip + GI2__JA_MIN, q); + } + + // compute the right hand side for the constrained rotational DOF. + // axis 1 and axis 2 are separated by an angle `theta'. the desired + // separation angle is theta0. sin(theta0) and cos(theta0) are recorded + // in the joint structure. the correcting angular velocity is: + // |angular_velocity| = angle/time = erp*(theta0-theta) / stepsize + // = (erp*fps) * (theta0-theta) + // (theta0-theta) can be computed using the following small-angle-difference + // approximation: + // theta0-theta ~= tan(theta0-theta) + // = sin(theta0-theta)/cos(theta0-theta) + // = (c*s0 - s*c0) / (c*c0 + s*s0) + // = c*s0 - s*c0 assuming c*c0 + s*s0 ~= 1 + // where c = cos(theta), s = sin(theta) + // c0 = cos(theta0), s0 = sin(theta0) + + dReal k = worldFPS * worldERP; + + int currPairSkip = 3 * pairskip; + pairRhsCfm[currPairSkip + GI2_RHS] = k * ( c0 * s - this->s0 * c ); + + currRowSkip += rowskip; currPairSkip += pairskip; + // if the axis1 hinge is powered, or has joint limits, add in more stuff + if (limot1.addLimot( this, worldFPS, J1 + currRowSkip, J2 + currRowSkip, pairRhsCfm + currPairSkip, pairLoHi + currPairSkip, ax1, 1 )) { + currRowSkip += rowskip; currPairSkip += pairskip; + } + + // if the axis2 hinge is powered, add in more stuff + limot2.addLimot( this, worldFPS, J1 + currRowSkip, J2 + currRowSkip, pairRhsCfm + currPairSkip, pairLoHi + currPairSkip, ax2, 1 ); +} + + +// compute vectors v1 and v2 (embedded in body1), used to measure angle +// between body 1 and body 2 + +void +dxJointHinge2::makeV1andV2() +{ + if ( node[0].body ) + { + // get axis 1 and 2 in global coords + dVector3 ax1, ax2, v; + dMultiply0_331( ax1, node[0].body->posr.R, axis1 ); + dMultiply0_331( ax2, node[1].body->posr.R, axis2 ); + + // modify axis 2 so it's perpendicular to axis 1 + dReal k = dCalcVectorDot3( ax1, ax2 ); + dAddVectorScaledVector3(ax2, ax2, ax1, -k); + + if (dxSafeNormalize3( ax2 )) { + // make v1 = modified axis2, v2 = axis1 x (modified axis2) + dCalcVectorCross3( v, ax1, ax2 ); + dMultiply1_331( v1, node[0].body->posr.R, ax2 ); + dMultiply1_331( v2, node[0].body->posr.R, v ); + } + else { + dUASSERT(false, "Hinge2 axes must be chosen to be linearly independent"); + } + } +} + +// same as above, but for the second axis + +void +dxJointHinge2::makeW1andW2() +{ + if ( node[1].body ) + { + // get axis 1 and 2 in global coords + dVector3 ax1, ax2, w; + dMultiply0_331( ax1, node[0].body->posr.R, axis1 ); + dMultiply0_331( ax2, node[1].body->posr.R, axis2 ); + + // modify axis 1 so it's perpendicular to axis 2 + dReal k = dCalcVectorDot3( ax2, ax1 ); + dAddVectorScaledVector3(ax1, ax1, ax2, -k); + + if (dxSafeNormalize3( ax1 )) { + // make w1 = modified axis1, w2 = axis2 x (modified axis1) + dCalcVectorCross3( w, ax2, ax1 ); + dMultiply1_331( w1, node[1].body->posr.R, ax1 ); + dMultiply1_331( w2, node[1].body->posr.R, w ); + } + else { + dUASSERT(false, "Hinge2 axes must be chosen to be linearly independent"); + } + } +} + + +/*ODE_API */ +void dJointSetHinge2Anchor( dJointID j, dReal x, dReal y, dReal z ) +{ + dxJointHinge2* joint = ( dxJointHinge2* )j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Hinge2 ); + + setAnchors( joint, x, y, z, joint->anchor1, joint->anchor2 ); + + joint->makeV1andV2(); + joint->makeW1andW2(); +} + + +/*ODE_API */ +void dJointSetHinge2Axes (dJointID j, const dReal *axis1/*=[dSA__MAX],=NULL*/, const dReal *axis2/*=[dSA__MAX],=NULL*/) +{ + dxJointHinge2* joint = ( dxJointHinge2* )j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Hinge2 ); + + dAASSERT(axis1 != NULL || axis2 != NULL); + dAASSERT(joint->node[0].body != NULL || axis1 == NULL); + dAASSERT(joint->node[1].body != NULL || axis2 == NULL); + + if ( axis1 != NULL ) + { + setAxes(joint, axis1[dSA_X], axis1[dSA_Y], axis1[dSA_Z], joint->axis1, NULL); + } + + if ( axis2 != NULL ) + { + setAxes(joint, axis2[dSA_X], axis2[dSA_Y], axis2[dSA_Z], NULL, joint->axis2); + } + + // compute the sin and cos of the angle between axis 1 and axis 2 + dVector3 ax1, ax2, ax; + joint->getAxisInfo( ax1, ax2, ax, joint->s0, joint->c0 ); + + joint->makeV1andV2(); + joint->makeW1andW2(); +} + + +/*ODE_API_DEPRECATED ODE_API */ +void dJointSetHinge2Axis1( dJointID j, dReal x, dReal y, dReal z ) +{ + dVector3 axis1; + axis1[dSA_X] = x; axis1[dSA_Y] = y; axis1[dSA_Z] = z; + dJointSetHinge2Axes(j, axis1, NULL); +} + +/*ODE_API_DEPRECATED ODE_API */ +void dJointSetHinge2Axis2( dJointID j, dReal x, dReal y, dReal z ) +{ + dVector3 axis2; + axis2[dSA_X] = x; axis2[dSA_Y] = y; axis2[dSA_Z] = z; + dJointSetHinge2Axes(j, NULL, axis2); +} + + +void dJointSetHinge2Param( dJointID j, int parameter, dReal value ) +{ + dxJointHinge2* joint = ( dxJointHinge2* )j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Hinge2 ); + if (( parameter & 0xff00 ) == 0x100 ) + { + joint->limot2.set( parameter & 0xff, value ); + } + else + { + if ( parameter == dParamSuspensionERP ) joint->susp_erp = value; + else if ( parameter == dParamSuspensionCFM ) joint->susp_cfm = value; + else joint->limot1.set( parameter, value ); + } +} + + +void dJointGetHinge2Anchor( dJointID j, dVector3 result ) +{ + dxJointHinge2* joint = ( dxJointHinge2* )j; + dUASSERT( joint, "bad joint argument" ); + dUASSERT( result, "bad result argument" ); + checktype( joint, Hinge2 ); + if ( joint->flags & dJOINT_REVERSE ) + getAnchor2( joint, result, joint->anchor2 ); + else + getAnchor( joint, result, joint->anchor1 ); +} + + +void dJointGetHinge2Anchor2( dJointID j, dVector3 result ) +{ + dxJointHinge2* joint = ( dxJointHinge2* )j; + dUASSERT( joint, "bad joint argument" ); + dUASSERT( result, "bad result argument" ); + checktype( joint, Hinge2 ); + if ( joint->flags & dJOINT_REVERSE ) + getAnchor( joint, result, joint->anchor1 ); + else + getAnchor2( joint, result, joint->anchor2 ); +} + + +void dJointGetHinge2Axis1( dJointID j, dVector3 result ) +{ + dxJointHinge2* joint = ( dxJointHinge2* )j; + dUASSERT( joint, "bad joint argument" ); + dUASSERT( result, "bad result argument" ); + checktype( joint, Hinge2 ); + if ( joint->node[0].body ) + { + dMultiply0_331( result, joint->node[0].body->posr.R, joint->axis1 ); + } + else + { + dZeroVector3(result); + dUASSERT( false, "the joint does not have first body attached" ); + } +} + + +void dJointGetHinge2Axis2( dJointID j, dVector3 result ) +{ + dxJointHinge2* joint = ( dxJointHinge2* )j; + dUASSERT( joint, "bad joint argument" ); + dUASSERT( result, "bad result argument" ); + checktype( joint, Hinge2 ); + if ( joint->node[1].body ) + { + dMultiply0_331( result, joint->node[1].body->posr.R, joint->axis2 ); + } + else + { + dZeroVector3(result); + dUASSERT( false, "the joint does not have second body attached" ); + } +} + + +dReal dJointGetHinge2Param( dJointID j, int parameter ) +{ + dxJointHinge2* joint = ( dxJointHinge2* )j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Hinge2 ); + if (( parameter & 0xff00 ) == 0x100 ) + { + return joint->limot2.get( parameter & 0xff ); + } + else + { + if ( parameter == dParamSuspensionERP ) return joint->susp_erp; + else if ( parameter == dParamSuspensionCFM ) return joint->susp_cfm; + else return joint->limot1.get( parameter ); + } +} + + +dReal dJointGetHinge2Angle1( dJointID j ) +{ + dxJointHinge2* joint = ( dxJointHinge2* )j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Hinge2 ); + return joint->measureAngle1(); +} + + +dReal dJointGetHinge2Angle2( dJointID j ) +{ + dxJointHinge2* joint = ( dxJointHinge2* )j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Hinge2 ); + return joint->measureAngle2(); +} + + + +dReal dJointGetHinge2Angle1Rate( dJointID j ) +{ + dxJointHinge2* joint = ( dxJointHinge2* )j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Hinge2 ); + if ( joint->node[0].body ) + { + dVector3 axis; + dMultiply0_331( axis, joint->node[0].body->posr.R, joint->axis1 ); + dReal rate = dCalcVectorDot3( axis, joint->node[0].body->avel ); + if ( joint->node[1].body ) + rate -= dCalcVectorDot3( axis, joint->node[1].body->avel ); + return rate; + } + else return 0; +} + + +dReal dJointGetHinge2Angle2Rate( dJointID j ) +{ + dxJointHinge2* joint = ( dxJointHinge2* )j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Hinge2 ); + if ( joint->node[0].body && joint->node[1].body ) + { + dVector3 axis; + dMultiply0_331( axis, joint->node[1].body->posr.R, joint->axis2 ); + dReal rate = dCalcVectorDot3( axis, joint->node[0].body->avel ); + if ( joint->node[1].body ) + rate -= dCalcVectorDot3( axis, joint->node[1].body->avel ); + return rate; + } + else return 0; +} + + +void dJointAddHinge2Torques( dJointID j, dReal torque1, dReal torque2 ) +{ + dxJointHinge2* joint = ( dxJointHinge2* )j; + dVector3 axis1, axis2; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Hinge2 ); + + if ( joint->node[0].body && joint->node[1].body ) + { + dMultiply0_331( axis1, joint->node[0].body->posr.R, joint->axis1 ); + dMultiply0_331( axis2, joint->node[1].body->posr.R, joint->axis2 ); + axis1[0] = axis1[0] * torque1 + axis2[0] * torque2; + axis1[1] = axis1[1] * torque1 + axis2[1] * torque2; + axis1[2] = axis1[2] * torque1 + axis2[2] * torque2; + dBodyAddTorque( joint->node[0].body, axis1[0], axis1[1], axis1[2] ); + dBodyAddTorque( joint->node[1].body, -axis1[0], -axis1[1], -axis1[2] ); + } +} + + +dJointType +dxJointHinge2::type() const +{ + return dJointTypeHinge2; +} + + +sizeint +dxJointHinge2::size() const +{ + return sizeof( *this ); +} + + +void +dxJointHinge2::setRelativeValues() +{ + dVector3 anchor; + dJointGetHinge2Anchor(this, anchor); + setAnchors( this, anchor[0], anchor[1], anchor[2], anchor1, anchor2 ); + + dVector3 axis; + + if ( node[0].body ) + { + dJointGetHinge2Axis1(this, axis); + setAxes( this, axis[0],axis[1],axis[2], axis1, NULL ); + } + + if ( node[0].body ) + { + dJointGetHinge2Axis2(this, axis); + setAxes( this, axis[0],axis[1],axis[2], NULL, axis2 ); + } + + dVector3 ax1, ax2; + getAxisInfo( ax1, ax2, axis, s0, c0 ); + + makeV1andV2(); + makeW1andW2(); +} diff --git a/libs/ode-0.16.1/ode/src/joints/hinge2.h b/libs/ode-0.16.1/ode/src/joints/hinge2.h new file mode 100644 index 0000000..06ce240 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/hinge2.h @@ -0,0 +1,71 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_JOINT_HINGE2_H_ +#define _ODE_JOINT_HINGE2_H_ + +#include "joint.h" + + +// hinge 2 + +struct dxJointHinge2 : public dxJoint +{ + dVector3 anchor1; // anchor w.r.t first body + dVector3 anchor2; // anchor w.r.t second body + dVector3 axis1; // axis 1 w.r.t first body + dVector3 axis2; // axis 2 w.r.t second body + dReal c0, s0; // cos,sin of desired angle between axis 1,2 + dVector3 v1, v2; // angle ref vectors embedded in first body + dVector3 w1, w2; // angle ref vectors embedded in second body + dxJointLimitMotor limot1; // limit+motor info for axis 1 + dxJointLimitMotor limot2; // limit+motor info for axis 2 + dReal susp_erp, susp_cfm; // suspension parameters (erp,cfm) + + + dReal measureAngle1() const; + dReal measureAngle2() const; + void makeV1andV2(); + void makeW1andW2(); + + void getAxisInfo(dVector3 ax1, dVector3 ax2, dVector3 axis, + dReal &sin_angle, dReal &cos_Angle) const; + + + + dxJointHinge2( dxWorld *w ); + + virtual void getSureMaxInfo( SureMaxInfo* info ); + virtual void getInfo1( Info1* info ); + virtual void getInfo2( dReal worldFPS, dReal worldERP, + int rowskip, dReal *J1, dReal *J2, + int pairskip, dReal *pairRhsCfm, dReal *pairLoHi, + int *findex ); + virtual dJointType type() const; + virtual sizeint size() const; + + virtual void setRelativeValues(); +}; + + + +#endif diff --git a/libs/ode-0.16.1/ode/src/joints/joint.cpp b/libs/ode-0.16.1/ode/src/joints/joint.cpp new file mode 100644 index 0000000..1b7de7a --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/joint.cpp @@ -0,0 +1,931 @@ +/*************************************************************************
+ * *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
+ * All rights reserved. Email: russ@q12.org Web: www.q12.org *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of EITHER: *
+ * (1) The GNU Lesser General Public License as published by the Free *
+ * Software Foundation; either version 2.1 of the License, or (at *
+ * your option) any later version. The text of the GNU Lesser *
+ * General Public License is included with this library in the *
+ * file LICENSE.TXT. *
+ * (2) The BSD-style license that is included with this library in *
+ * the file LICENSE-BSD.TXT. *
+ * *
+ * This library 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 files *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
+ * *
+ *************************************************************************/
+
+/*
+
+design note: the general principle for giving a joint the option of connecting
+to the static environment (i.e. the absolute frame) is to check the second
+body (joint->node[1].body), and if it is zero then behave as if its body
+transform is the identity.
+
+*/
+
+#include <ode/ode.h>
+#include <ode/rotation.h>
+#include "config.h"
+#include "matrix.h"
+#include "odemath.h"
+#include "joint.h"
+#include "joint_internal.h"
+#include "util.h"
+
+extern void addObjectToList( dObject *obj, dObject **first );
+
+dxJoint::dxJoint( dxWorld *w ) :
+ dObject( w )
+{
+ //printf("constructing %p\n", this);
+ dIASSERT( w );
+ flags = 0;
+ node[0].joint = this;
+ node[0].body = 0;
+ node[0].next = 0;
+ node[1].joint = this;
+ node[1].body = 0;
+ node[1].next = 0;
+ dSetZero( lambda, 6 );
+
+ addObjectToList( this, ( dObject ** ) &w->firstjoint );
+
+ w->nj++;
+ feedback = 0;
+}
+
+dxJoint::~dxJoint()
+{ }
+
+
+/*virtual */
+void dxJoint::setRelativeValues()
+{
+ // Do nothing
+}
+
+bool dxJoint::isEnabled() const
+{
+ return ( (flags & dJOINT_DISABLED) == 0 &&
+ (node[0].body->invMass > 0 ||
+ (node[1].body && node[1].body->invMass > 0)) );
+}
+
+
+sizeint dxJointGroup::exportJoints(dxJoint **jlist)
+{
+ sizeint i=0;
+ dxJoint *j = (dxJoint*) m_stack.rewind();
+ while (j != NULL) {
+ jlist[i++] = j;
+ j = (dxJoint*) (m_stack.next (j->size()));
+ }
+ return i;
+}
+
+void dxJointGroup::freeAll()
+{
+ m_num = 0;
+ m_stack.freeAll();
+}
+
+
+//****************************************************************************
+// externs
+
+// extern "C" void dBodyAddTorque (dBodyID, dReal fx, dReal fy, dReal fz);
+// extern "C" void dBodyAddForce (dBodyID, dReal fx, dReal fy, dReal fz);
+
+//****************************************************************************
+// utility
+
+// set three "ball-and-socket" rows in the constraint equation, and the
+// corresponding right hand side.
+
+void setBall( dxJoint *joint, dReal fps, dReal erp,
+ int rowskip, dReal *J1, dReal *J2,
+ int pairskip, dReal *pairRhsCfm,
+ dVector3 anchor1, dVector3 anchor2 )
+{
+ // anchor points in global coordinates with respect to body PORs.
+ dVector3 a1, a2;
+
+ // set Jacobian
+ J1[dxJoint::GI2_JLX] = 1;
+ J1[rowskip + dxJoint::GI2_JLY] = 1;
+ J1[2 * rowskip + dxJoint::GI2_JLZ] = 1;
+ dMultiply0_331( a1, joint->node[0].body->posr.R, anchor1 );
+ dSetCrossMatrixMinus( J1 + dxJoint::GI2__JA_MIN, a1, rowskip );
+
+ dxBody *b1 = joint->node[1].body;
+ if ( b1 )
+ {
+ J2[dxJoint::GI2_JLX] = -1;
+ J2[rowskip + dxJoint::GI2_JLY] = -1;
+ J2[2 * rowskip + dxJoint::GI2_JLZ] = -1;
+ dMultiply0_331( a2, b1->posr.R, anchor2 );
+ dSetCrossMatrixPlus( J2 + dxJoint::GI2__JA_MIN, a2, rowskip );
+ }
+
+ // set right hand side
+ dReal k = fps * erp;
+ dxBody *b0 = joint->node[0].body;
+ if ( b1 )
+ {
+ dReal *currRhsCfm = pairRhsCfm;
+ for ( int j = dSA__MIN; j != dSA__MAX; j++ )
+ {
+ currRhsCfm[dxJoint::GI2_RHS] = k * ( a2[j] + b1->posr.pos[j] - a1[j] - b0->posr.pos[j] );
+ currRhsCfm += pairskip;
+ }
+ }
+ else
+ {
+ dReal *currRhsCfm = pairRhsCfm;
+ for ( int j = dSA__MIN; j != dSA__MAX; j++ )
+ {
+ currRhsCfm[dxJoint::GI2_RHS] = k * ( anchor2[j] - a1[j] - b0->posr.pos[j] );
+ currRhsCfm += pairskip;
+ }
+ }
+}
+
+
+// this is like setBall(), except that `axis' is a unit length vector
+// (in global coordinates) that should be used for the first jacobian
+// position row (the other two row vectors will be derived from this).
+// `erp1' is the erp value to use along the axis.
+
+void setBall2( dxJoint *joint, dReal fps, dReal erp,
+ int rowskip, dReal *J1, dReal *J2,
+ int pairskip, dReal *pairRhsCfm,
+ dVector3 anchor1, dVector3 anchor2,
+ dVector3 axis, dReal erp1 )
+{
+ // anchor points in global coordinates with respect to body PORs.
+ dVector3 a1, a2;
+
+ // get vectors normal to the axis. in setBall() axis,q1,q2 is [1 0 0],
+ // [0 1 0] and [0 0 1], which makes everything much easier.
+ dVector3 q1, q2;
+ dPlaneSpace( axis, q1, q2 );
+
+ // set Jacobian
+ dCopyVector3(J1 + dxJoint::GI2__JL_MIN, axis);
+ dCopyVector3(J1 + rowskip + dxJoint::GI2__JL_MIN, q1);
+ dCopyVector3(J1 + 2 * rowskip + dxJoint::GI2__JL_MIN, q2);
+ dMultiply0_331( a1, joint->node[0].body->posr.R, anchor1 );
+ dCalcVectorCross3( J1 + dxJoint::GI2__JA_MIN, a1, axis );
+ dCalcVectorCross3( J1 + rowskip + dxJoint::GI2__JA_MIN, a1, q1 );
+ dCalcVectorCross3( J1 + 2 * rowskip + dxJoint::GI2__JA_MIN, a1, q2 );
+
+ dxBody *b0 = joint->node[0].body;
+ dAddVectors3(a1, a1, b0->posr.pos);
+
+ // set right hand side - measure error along (axis,q1,q2)
+ dReal k1 = fps * erp1;
+ dReal k = fps * erp;
+
+ dxBody *b1 = joint->node[1].body;
+ if ( b1 )
+ {
+ dCopyNegatedVector3(J2 + dxJoint::GI2__JL_MIN, axis);
+ dCopyNegatedVector3(J2 + rowskip + dxJoint::GI2__JL_MIN, q1);
+ dCopyNegatedVector3(J2 + 2 * rowskip + dxJoint::GI2__JL_MIN, q2);
+ dMultiply0_331( a2, b1->posr.R, anchor2 );
+ dCalcVectorCross3( J2 + dxJoint::GI2__JA_MIN, axis, a2 ); //== dCalcVectorCross3( J2 + dxJoint::GI2__J2A_MIN, a2, axis ); dNegateVector3( J2 + dxJoint::GI2__J2A_MIN );
+ dCalcVectorCross3( J2 + rowskip + dxJoint::GI2__JA_MIN, q1, a2 ); //== dCalcVectorCross3( J2 + rowskip + dxJoint::GI2__J2A_MIN, a2, q1 ); dNegateVector3( J2 + rowskip + dxJoint::GI2__J2A_MIN );
+ dCalcVectorCross3( J2 + 2 * rowskip + dxJoint::GI2__JA_MIN, q2, a2 ); //== dCalcVectorCross3( J2 + 2 * rowskip + dxJoint::GI2__J2A_MIN, a2, q2 ); dNegateVector3( J2 + 2 * rowskip + dxJoint::GI2__J2A_MIN );
+
+ dAddVectors3(a2, a2, b1->posr.pos);
+
+ dVector3 a2_minus_a1;
+ dSubtractVectors3(a2_minus_a1, a2, a1);
+ pairRhsCfm[dxJoint::GI2_RHS] = k1 * dCalcVectorDot3( axis, a2_minus_a1 );
+ pairRhsCfm[pairskip + dxJoint::GI2_RHS] = k * dCalcVectorDot3( q1, a2_minus_a1 );
+ pairRhsCfm[2 * pairskip + dxJoint::GI2_RHS] = k * dCalcVectorDot3( q2, a2_minus_a1 );
+ }
+ else
+ {
+ dVector3 anchor2_minus_a1;
+ dSubtractVectors3(anchor2_minus_a1, anchor2, a1);
+ pairRhsCfm[dxJoint::GI2_RHS] = k1 * dCalcVectorDot3( axis, anchor2_minus_a1 );
+ pairRhsCfm[pairskip + dxJoint::GI2_RHS] = k * dCalcVectorDot3( q1, anchor2_minus_a1 );
+ pairRhsCfm[2 * pairskip + dxJoint::GI2_RHS] = k * dCalcVectorDot3( q2, anchor2_minus_a1 );
+ }
+}
+
+
+// set three orientation rows in the constraint equation, and the
+// corresponding right hand side.
+
+void setFixedOrientation( dxJoint *joint, dReal fps, dReal erp,
+ int rowskip, dReal *J1, dReal *J2,
+ int pairskip, dReal *pairRhsCfm,
+ dQuaternion qrel )
+{
+ // 3 rows to make body rotations equal
+ J1[dxJoint::GI2_JAX] = 1;
+ J1[rowskip + dxJoint::GI2_JAY] = 1;
+ J1[2 * rowskip + dxJoint::GI2_JAZ] = 1;
+
+ dxBody *b1 = joint->node[1].body;
+ if ( b1 )
+ {
+ J2[dxJoint::GI2_JAX] = -1;
+ J2[rowskip + dxJoint::GI2_JAY] = -1;
+ J2[2 * rowskip + dxJoint::GI2_JAZ] = -1;
+ }
+
+ // compute the right hand side. the first three elements will result in
+ // relative angular velocity of the two bodies - this is set to bring them
+ // back into alignment. the correcting angular velocity is
+ // |angular_velocity| = angle/time = erp*theta / stepsize
+ // = (erp*fps) * theta
+ // angular_velocity = |angular_velocity| * u
+ // = (erp*fps) * theta * u
+ // where rotation along unit length axis u by theta brings body 2's frame
+ // to qrel with respect to body 1's frame. using a small angle approximation
+ // for sin(), this gives
+ // angular_velocity = (erp*fps) * 2 * v
+ // where the quaternion of the relative rotation between the two bodies is
+ // q = [cos(theta/2) sin(theta/2)*u] = [s v]
+
+ // get qerr = relative rotation (rotation error) between two bodies
+ dQuaternion qerr, e;
+ dxBody *b0 = joint->node[0].body;
+ if ( b1 )
+ {
+ dQuaternion qq;
+ dQMultiply1( qq, b0->q, b1->q );
+ dQMultiply2( qerr, qq, qrel );
+ }
+ else
+ {
+ dQMultiply3( qerr, b0->q, qrel );
+ }
+ if ( qerr[0] < 0 )
+ {
+ qerr[1] = -qerr[1]; // adjust sign of qerr to make theta small
+ qerr[2] = -qerr[2];
+ qerr[3] = -qerr[3];
+ }
+ dMultiply0_331( e, b0->posr.R, qerr + 1 ); // @@@ bad SIMD padding!
+ dReal k_mul_2 = fps * erp * REAL(2.0);
+ pairRhsCfm[dxJoint::GI2_RHS] = k_mul_2 * e[dSA_X];
+ pairRhsCfm[pairskip + dxJoint::GI2_RHS] = k_mul_2 * e[dSA_Y];
+ pairRhsCfm[2 * pairskip + dxJoint::GI2_RHS] = k_mul_2 * e[dSA_Z];
+}
+
+
+// compute anchor points relative to bodies
+
+void setAnchors( dxJoint *j, dReal x, dReal y, dReal z,
+ dVector3 anchor1, dVector3 anchor2 )
+{
+ dxBody *b0 = j->node[0].body;
+ if ( b0 )
+ {
+ dReal q[4];
+ q[0] = x - b0->posr.pos[0];
+ q[1] = y - b0->posr.pos[1];
+ q[2] = z - b0->posr.pos[2];
+ q[3] = 0;
+ dMultiply1_331( anchor1, b0->posr.R, q );
+
+ dxBody *b1 = j->node[1].body;
+ if ( b1 )
+ {
+ q[0] = x - b1->posr.pos[0];
+ q[1] = y - b1->posr.pos[1];
+ q[2] = z - b1->posr.pos[2];
+ q[3] = 0;
+ dMultiply1_331( anchor2, b1->posr.R, q );
+ }
+ else
+ {
+ anchor2[0] = x;
+ anchor2[1] = y;
+ anchor2[2] = z;
+ }
+ }
+ anchor1[3] = 0;
+ anchor2[3] = 0;
+}
+
+
+// compute axes relative to bodies. either axis1 or axis2 can be 0.
+
+void setAxes( dxJoint *j, dReal x, dReal y, dReal z,
+ dVector3 axis1, dVector3 axis2 )
+{
+ dxBody *b0 = j->node[0].body;
+ if ( b0 )
+ {
+ dReal q[4];
+ q[0] = x;
+ q[1] = y;
+ q[2] = z;
+ q[3] = 0;
+ dNormalize3( q );
+
+ if ( axis1 )
+ {
+ dMultiply1_331( axis1, b0->posr.R, q );
+ axis1[3] = 0;
+ }
+
+ if ( axis2 )
+ {
+ dxBody *b1 = j->node[1].body;
+ if ( b1 )
+ {
+ dMultiply1_331( axis2, b1->posr.R, q );
+ }
+ else
+ {
+ axis2[0] = x;
+ axis2[1] = y;
+ axis2[2] = z;
+ }
+ axis2[3] = 0;
+ }
+ }
+}
+
+
+void getAnchor( dxJoint *j, dVector3 result, dVector3 anchor1 )
+{
+ dxBody *b0 = j->node[0].body;
+ if ( b0 )
+ {
+ dMultiply0_331( result, b0->posr.R, anchor1 );
+ result[0] += b0->posr.pos[0];
+ result[1] += b0->posr.pos[1];
+ result[2] += b0->posr.pos[2];
+ }
+}
+
+
+void getAnchor2( dxJoint *j, dVector3 result, dVector3 anchor2 )
+{
+ dxBody *b1 = j->node[1].body;
+ if ( b1 )
+ {
+ dMultiply0_331( result, b1->posr.R, anchor2 );
+ result[0] += b1->posr.pos[0];
+ result[1] += b1->posr.pos[1];
+ result[2] += b1->posr.pos[2];
+ }
+ else
+ {
+ result[0] = anchor2[0];
+ result[1] = anchor2[1];
+ result[2] = anchor2[2];
+ }
+}
+
+
+void getAxis( dxJoint *j, dVector3 result, dVector3 axis1 )
+{
+ dxBody *b0 = j->node[0].body;
+ if ( b0 )
+ {
+ dMultiply0_331( result, b0->posr.R, axis1 );
+ }
+}
+
+
+void getAxis2( dxJoint *j, dVector3 result, dVector3 axis2 )
+{
+ dxBody *b1 = j->node[1].body;
+ if ( b1 )
+ {
+ dMultiply0_331( result, b1->posr.R, axis2 );
+ }
+ else
+ {
+ result[0] = axis2[0];
+ result[1] = axis2[1];
+ result[2] = axis2[2];
+ }
+}
+
+
+dReal getHingeAngleFromRelativeQuat( dQuaternion qrel, dVector3 axis )
+{
+ // the angle between the two bodies is extracted from the quaternion that
+ // represents the relative rotation between them. recall that a quaternion
+ // q is:
+ // [s,v] = [ cos(theta/2) , sin(theta/2) * u ]
+ // where s is a scalar and v is a 3-vector. u is a unit length axis and
+ // theta is a rotation along that axis. we can get theta/2 by:
+ // theta/2 = atan2 ( sin(theta/2) , cos(theta/2) )
+ // but we can't get sin(theta/2) directly, only its absolute value, i.e.:
+ // |v| = |sin(theta/2)| * |u|
+ // = |sin(theta/2)|
+ // using this value will have a strange effect. recall that there are two
+ // quaternion representations of a given rotation, q and -q. typically as
+ // a body rotates along the axis it will go through a complete cycle using
+ // one representation and then the next cycle will use the other
+ // representation. this corresponds to u pointing in the direction of the
+ // hinge axis and then in the opposite direction. the result is that theta
+ // will appear to go "backwards" every other cycle. here is a fix: if u
+ // points "away" from the direction of the hinge (motor) axis (i.e. more
+ // than 90 degrees) then use -q instead of q. this represents the same
+ // rotation, but results in the cos(theta/2) value being sign inverted.
+
+ // extract the angle from the quaternion. cost2 = cos(theta/2),
+ // sint2 = |sin(theta/2)|
+ dReal cost2 = qrel[0];
+ dReal sint2 = dSqrt( qrel[1] * qrel[1] + qrel[2] * qrel[2] + qrel[3] * qrel[3] );
+ dReal theta = ( dCalcVectorDot3( qrel + 1, axis ) >= 0 ) ? // @@@ padding assumptions
+ ( 2 * dAtan2( sint2, cost2 ) ) : // if u points in direction of axis
+ ( 2 * dAtan2( sint2, -cost2 ) ); // if u points in opposite direction
+
+ // the angle we get will be between 0..2*pi, but we want to return angles
+ // between -pi..pi
+ if ( theta > M_PI ) theta -= ( dReal )( 2 * M_PI );
+
+ // the angle we've just extracted has the wrong sign
+ theta = -theta;
+
+ return theta;
+}
+
+
+// given two bodies (body1,body2), the hinge axis that they are connected by
+// w.r.t. body1 (axis), and the initial relative orientation between them
+// (q_initial), return the relative rotation angle. the initial relative
+// orientation corresponds to an angle of zero. if body2 is 0 then measure the
+// angle between body1 and the static frame.
+//
+// this will not return the correct angle if the bodies rotate along any axis
+// other than the given hinge axis.
+
+dReal getHingeAngle( dxBody *body1, dxBody *body2, dVector3 axis,
+ dQuaternion q_initial )
+{
+ // get qrel = relative rotation between the two bodies
+ dQuaternion qrel;
+ if ( body2 )
+ {
+ dQuaternion qq;
+ dQMultiply1( qq, body1->q, body2->q );
+ dQMultiply2( qrel, qq, q_initial );
+ }
+ else
+ {
+ // pretend body2->q is the identity
+ dQMultiply3( qrel, body1->q, q_initial );
+ }
+
+ return getHingeAngleFromRelativeQuat( qrel, axis );
+}
+
+//****************************************************************************
+// dxJointLimitMotor
+
+void dxJointLimitMotor::init( dxWorld *world )
+{
+ vel = 0;
+ fmax = 0;
+ lostop = -dInfinity;
+ histop = dInfinity;
+ fudge_factor = 1;
+ normal_cfm = world->global_cfm;
+ stop_erp = world->global_erp;
+ stop_cfm = world->global_cfm;
+ bounce = 0;
+ limit = 0;
+ limit_err = 0;
+}
+
+
+void dxJointLimitMotor::set( int num, dReal value )
+{
+ switch ( num )
+ {
+ case dParamLoStop:
+ lostop = value;
+ break;
+ case dParamHiStop:
+ histop = value;
+ break;
+ case dParamVel:
+ vel = value;
+ break;
+ case dParamFMax:
+ if ( value >= 0 ) fmax = value;
+ break;
+ case dParamFudgeFactor:
+ if ( value >= 0 && value <= 1 ) fudge_factor = value;
+ break;
+ case dParamBounce:
+ bounce = value;
+ break;
+ case dParamCFM:
+ normal_cfm = value;
+ break;
+ case dParamStopERP:
+ stop_erp = value;
+ break;
+ case dParamStopCFM:
+ stop_cfm = value;
+ break;
+ }
+}
+
+
+dReal dxJointLimitMotor::get( int num ) const
+{
+ switch ( num )
+ {
+ case dParamLoStop:
+ return lostop;
+ case dParamHiStop:
+ return histop;
+ case dParamVel:
+ return vel;
+ case dParamFMax:
+ return fmax;
+ case dParamFudgeFactor:
+ return fudge_factor;
+ case dParamBounce:
+ return bounce;
+ case dParamCFM:
+ return normal_cfm;
+ case dParamStopERP:
+ return stop_erp;
+ case dParamStopCFM:
+ return stop_cfm;
+ default:
+ return 0;
+ }
+}
+
+
+bool dxJointLimitMotor::testRotationalLimit( dReal angle )
+{
+ if ( angle <= lostop )
+ {
+ limit = 1;
+ limit_err = angle - lostop;
+ return true;
+ }
+ else if ( angle >= histop )
+ {
+ limit = 2;
+ limit_err = angle - histop;
+ return true;
+ }
+ else
+ {
+ limit = 0;
+ return false;
+ }
+}
+
+
+bool dxJointLimitMotor::addLimot( dxJoint *joint,
+ dReal fps, dReal *J1, dReal *J2, dReal *pairRhsCfm, dReal *pairLoHi,
+ const dVector3 ax1, int rotational )
+{
+ // if the joint is powered, or has joint limits, add in the extra row
+ int powered = fmax > 0;
+ if ( powered || limit )
+ {
+ dReal *J1Used = rotational ? J1 + GI2__JA_MIN : J1 + GI2__JL_MIN;
+ dReal *J2Used = rotational ? J2 + GI2__JA_MIN : J2 + GI2__JL_MIN;
+
+ dCopyVector3(J1Used, ax1);
+
+ dxBody *b1 = joint->node[1].body;
+ if ( b1 )
+ {
+ dCopyNegatedVector3(J2Used, ax1);
+ }
+
+ // linear limot torque decoupling step:
+ //
+ // if this is a linear limot (e.g. from a slider), we have to be careful
+ // that the linear constraint forces (+/- ax1) applied to the two bodies
+ // do not create a torque couple. in other words, the points that the
+ // constraint force is applied at must lie along the same ax1 axis.
+ // a torque couple will result in powered or limited slider-jointed free
+ // bodies from gaining angular momentum.
+ // the solution used here is to apply the constraint forces at the point
+ // halfway between the body centers. there is no penalty (other than an
+ // extra tiny bit of computation) in doing this adjustment. note that we
+ // only need to do this if the constraint connects two bodies.
+
+ dVector3 ltd = {0,0,0}; // Linear Torque Decoupling vector (a torque)
+ if ( !rotational && b1 )
+ {
+ dxBody *b0 = joint->node[0].body;
+ dVector3 c;
+ c[0] = REAL( 0.5 ) * ( b1->posr.pos[0] - b0->posr.pos[0] );
+ c[1] = REAL( 0.5 ) * ( b1->posr.pos[1] - b0->posr.pos[1] );
+ c[2] = REAL( 0.5 ) * ( b1->posr.pos[2] - b0->posr.pos[2] );
+ dCalcVectorCross3( ltd, c, ax1 );
+ dCopyVector3(J1 + dxJoint::GI2__JA_MIN, ltd);
+ dCopyVector3(J2 + dxJoint::GI2__JA_MIN, ltd);
+ }
+
+ // if we're limited low and high simultaneously, the joint motor is
+ // ineffective
+ if ( limit && ( lostop == histop ) ) powered = 0;
+
+ if ( powered )
+ {
+ pairRhsCfm[GI2_CFM] = normal_cfm;
+ if ( ! limit )
+ {
+ pairRhsCfm[GI2_RHS] = vel;
+ pairLoHi[GI2_LO] = -fmax;
+ pairLoHi[GI2_HI] = fmax;
+ }
+ else
+ {
+ // the joint is at a limit, AND is being powered. if the joint is
+ // being powered into the limit then we apply the maximum motor force
+ // in that direction, because the motor is working against the
+ // immovable limit. if the joint is being powered away from the limit
+ // then we have problems because actually we need *two* lcp
+ // constraints to handle this case. so we fake it and apply some
+ // fraction of the maximum force. the fraction to use can be set as
+ // a fudge factor.
+
+ dReal fm = fmax;
+ if (( vel > 0 ) || ( vel == 0 && limit == 2 ) ) fm = -fm;
+
+ // if we're powering away from the limit, apply the fudge factor
+ if (( limit == 1 && vel > 0 ) || ( limit == 2 && vel < 0 ) ) fm *= fudge_factor;
+
+
+ dReal fm_ax1_0 = fm*ax1[0], fm_ax1_1 = fm*ax1[1], fm_ax1_2 = fm*ax1[2];
+
+ dxBody *b0 = joint->node[0].body;
+ dxWorldProcessContext *world_process_context = b0->world->unsafeGetWorldProcessingContext();
+
+ world_process_context->LockForAddLimotSerialization();
+
+ if ( rotational )
+ {
+ dxBody *b1 = joint->node[1].body;
+ if ( b1 != NULL )
+ {
+ dBodyAddTorque( b1, fm_ax1_0, fm_ax1_1, fm_ax1_2 );
+ }
+
+ dBodyAddTorque( b0, -fm_ax1_0, -fm_ax1_1, -fm_ax1_2 );
+ }
+ else
+ {
+ dxBody *b1 = joint->node[1].body;
+ if ( b1 != NULL )
+ {
+ // linear limot torque decoupling step: refer to above discussion
+ dReal neg_fm_ltd_0 = -fm*ltd[0], neg_fm_ltd_1 = -fm*ltd[1], neg_fm_ltd_2 = -fm*ltd[2];
+ dBodyAddTorque( b0, neg_fm_ltd_0, neg_fm_ltd_1, neg_fm_ltd_2 );
+ dBodyAddTorque( b1, neg_fm_ltd_0, neg_fm_ltd_1, neg_fm_ltd_2 );
+
+ dBodyAddForce( b1, fm_ax1_0, fm_ax1_1, fm_ax1_2 );
+ }
+
+ dBodyAddForce( b0, -fm_ax1_0, -fm_ax1_1, -fm_ax1_2 );
+ }
+
+ world_process_context->UnlockForAddLimotSerialization();
+ }
+ }
+
+ if ( limit )
+ {
+ dReal k = fps * stop_erp;
+ pairRhsCfm[GI2_RHS] = -k * limit_err;
+ pairRhsCfm[GI2_CFM] = stop_cfm;
+
+ if ( lostop == histop )
+ {
+ // limited low and high simultaneously
+ pairLoHi[GI2_LO] = -dInfinity;
+ pairLoHi[GI2_HI] = dInfinity;
+ }
+ else
+ {
+ if ( limit == 1 )
+ {
+ // low limit
+ pairLoHi[GI2_LO] = 0;
+ pairLoHi[GI2_HI] = dInfinity;
+ }
+ else
+ {
+ // high limit
+ pairLoHi[GI2_LO] = -dInfinity;
+ pairLoHi[GI2_HI] = 0;
+ }
+
+ // deal with bounce
+ if ( bounce > 0 )
+ {
+ // calculate joint velocity
+ dReal vel;
+ if ( rotational )
+ {
+ vel = dCalcVectorDot3( joint->node[0].body->avel, ax1 );
+ if ( joint->node[1].body )
+ vel -= dCalcVectorDot3( joint->node[1].body->avel, ax1 );
+ }
+ else
+ {
+ vel = dCalcVectorDot3( joint->node[0].body->lvel, ax1 );
+ if ( joint->node[1].body )
+ vel -= dCalcVectorDot3( joint->node[1].body->lvel, 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 )
+ {
+ dReal newc = -bounce * vel;
+ if ( newc > pairRhsCfm[GI2_RHS] ) pairRhsCfm[GI2_RHS] = newc;
+ }
+ }
+ else
+ {
+ // high limit - all those computations are reversed
+ if ( vel > 0 )
+ {
+ dReal newc = -bounce * vel;
+ if ( newc < pairRhsCfm[GI2_RHS] ) pairRhsCfm[GI2_RHS] = newc;
+ }
+ }
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+/**
+ This function generalizes the "linear limot torque decoupling"
+ in addLimot to use anchor points provided by the caller.
+
+ This makes it so that the appropriate torques are applied to
+ a body when it's being linearly motored or limited using anchor points
+ that aren't at the center of mass.
+
+ pt1 and pt2 are centered in body coordinates but use global directions.
+ I.e., they are conveniently found within joint code with:
+ getAxis(joint,pt1,anchor1);
+ getAxis2(joint,pt2,anchor2);
+*/
+bool dxJointLimitMotor::addTwoPointLimot( dxJoint *joint, dReal fps,
+ dReal *J1, dReal *J2, dReal *pairRhsCfm, dReal *pairLoHi,
+ const dVector3 ax1, const dVector3 pt1, const dVector3 pt2 )
+{
+ // if the joint is powered, or has joint limits, add in the extra row
+ int powered = fmax > 0;
+ if ( powered || limit )
+ {
+ // Set the linear portion
+ dCopyVector3(J1 + GI2__JL_MIN, ax1);
+ // Set the angular portion (to move the linear constraint
+ // away from the center of mass).
+ dCalcVectorCross3(J1 + GI2__JA_MIN, pt1, ax1);
+ // Set the constraints for the second body
+ if ( joint->node[1].body ) {
+ dCopyNegatedVector3(J2 + GI2__JL_MIN, ax1);
+ dCalcVectorCross3(J2 + GI2__JA_MIN, pt2, J2 + GI2__JL_MIN);
+ }
+
+ // if we're limited low and high simultaneously, the joint motor is
+ // ineffective
+ if ( limit && ( lostop == histop ) ) powered = 0;
+
+ if ( powered )
+ {
+ pairRhsCfm[GI2_CFM] = normal_cfm;
+ if ( ! limit )
+ {
+ pairRhsCfm[GI2_RHS] = vel;
+ pairLoHi[GI2_LO] = -fmax;
+ pairLoHi[GI2_HI] = fmax;
+ }
+ else
+ {
+ // the joint is at a limit, AND is being powered. if the joint is
+ // being powered into the limit then we apply the maximum motor force
+ // in that direction, because the motor is working against the
+ // immovable limit. if the joint is being powered away from the limit
+ // then we have problems because actually we need *two* lcp
+ // constraints to handle this case. so we fake it and apply some
+ // fraction of the maximum force. the fraction to use can be set as
+ // a fudge factor.
+
+ dReal fm = fmax;
+ if (( vel > 0 ) || ( vel == 0 && limit == 2 ) ) fm = -fm;
+
+ // if we're powering away from the limit, apply the fudge factor
+ if (( limit == 1 && vel > 0 ) || ( limit == 2 && vel < 0 ) ) fm *= fudge_factor;
+
+
+ const dReal* tAx1 = J1 + GI2__JA_MIN;
+ dBodyAddForce( joint->node[0].body, -fm*ax1[dSA_X], -fm*ax1[dSA_Y], -fm*ax1[dSA_Z] );
+ dBodyAddTorque( joint->node[0].body, -fm*tAx1[dSA_X], -fm*tAx1[dSA_Y], -fm*tAx1[dSA_Z] );
+
+ if ( joint->node[1].body )
+ {
+ const dReal* tAx2 = J2 + GI2__JA_MIN;
+ dBodyAddForce( joint->node[1].body, fm*ax1[dSA_X], fm*ax1[dSA_Y], fm*ax1[dSA_Z] );
+ dBodyAddTorque( joint->node[1].body, -fm*tAx2[dSA_X], -fm*tAx2[dSA_Y], -fm*tAx2[dSA_Z] );
+ }
+
+ }
+ }
+
+ if ( limit )
+ {
+ dReal k = fps * stop_erp;
+ pairRhsCfm[GI2_RHS] = -k * limit_err;
+ pairRhsCfm[GI2_CFM] = stop_cfm;
+
+ if ( lostop == histop )
+ {
+ // limited low and high simultaneously
+ pairLoHi[GI2_LO] = -dInfinity;
+ pairLoHi[GI2_HI] = dInfinity;
+ }
+ else
+ {
+ if ( limit == 1 )
+ {
+ // low limit
+ pairLoHi[GI2_LO] = 0;
+ pairLoHi[GI2_HI] = dInfinity;
+ }
+ else
+ {
+ // high limit
+ pairLoHi[GI2_LO] = -dInfinity;
+ pairLoHi[GI2_HI] = 0;
+ }
+
+ // deal with bounce
+ if ( bounce > 0 )
+ {
+ // calculate relative velocity of the two anchor points
+ dReal vel =
+ dCalcVectorDot3( joint->node[0].body->lvel, J1 + GI2__JL_MIN ) +
+ dCalcVectorDot3( joint->node[0].body->avel, J1 + GI2__JA_MIN );
+ if (joint->node[1].body) {
+ vel +=
+ dCalcVectorDot3( joint->node[1].body->lvel, J2 + GI2__JL_MIN ) +
+ dCalcVectorDot3( joint->node[1].body->avel, J2 + GI2__JA_MIN );
+ }
+
+ // 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 )
+ {
+ dReal newc = -bounce * vel;
+ if ( newc > pairRhsCfm[GI2_RHS] ) pairRhsCfm[GI2_RHS] = newc;
+ }
+ }
+ else
+ {
+ // high limit - all those computations are reversed
+ if ( vel > 0 )
+ {
+ dReal newc = -bounce * vel;
+ if ( newc < pairRhsCfm[GI2_RHS] ) pairRhsCfm[GI2_RHS] = newc;
+ }
+ }
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+
+// Local Variables:
+// mode:c++
+// c-basic-offset:4
+// End:
diff --git a/libs/ode-0.16.1/ode/src/joints/joint.h b/libs/ode-0.16.1/ode/src/joints/joint.h new file mode 100644 index 0000000..b6aa81e --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/joint.h @@ -0,0 +1,326 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_JOINT_H_ +#define _ODE_JOINT_H_ + + +#include <ode/contact.h> +#include "../common.h" +#include "../objects.h" +#include "../obstack.h" + + +// joint flags +enum +{ + // if this flag is set, the joint was allocated in a joint group + dJOINT_INGROUP = 1, + + // if this flag is set, the joint was attached with arguments (0,body). + // our convention is to treat all attaches as (body,0), i.e. so node[0].body + // is always nonzero, so this flag records the fact that the arguments were + // swapped. + dJOINT_REVERSE = 2, + + // if this flag is set, the joint can not have just one body attached to it, + // it must have either zero or two bodies attached. + dJOINT_TWOBODIES = 4, + + dJOINT_DISABLED = 8 +}; + + +enum dJointConnectedBody +{ + dJCB__MIN, + + dJCB_FIRST_BODY = dJCB__MIN, + dJCB_SECOND_BODY, + + dJCB__MAX, + +}; + +static inline +dJointConnectedBody EncodeJointOtherConnectedBody(dJointConnectedBody cbBodyKind) +{ + dIASSERT(dIN_RANGE(cbBodyKind, dJCB__MIN, dJCB__MAX)); + dSASSERT(dJCB__MAX == 2); + + return (dJointConnectedBody)(dJCB_FIRST_BODY + dJCB_SECOND_BODY - cbBodyKind); +} + +/* joint body relativity enumeration */ +enum dJointBodyRelativity +{ + dJBR__MIN, + + dJBR_GLOBAL = dJBR__MIN, + + dJBR__BODIES_MIN, + + dJBR_BODY1 = dJBR__BODIES_MIN + dJCB_FIRST_BODY, + dJBR_BODY2 = dJBR__BODIES_MIN + dJCB_SECOND_BODY, + + dJBR__BODIES_MAX = dJBR__BODIES_MIN + dJCB__MAX, + + dJBR__MAX, + + dJBR__DEFAULT = dJBR_GLOBAL, + dJBR__BODIES_COUNT = dJBR__BODIES_MAX - dJBR__BODIES_MIN, + +}; + +ODE_PURE_INLINE int dJBREncodeBodyRelativityStatus(int relativity) +{ + return dIN_RANGE(relativity, dJBR__BODIES_MIN, dJBR__BODIES_MAX); +} + +ODE_PURE_INLINE dJointBodyRelativity dJBRSwapBodyRelativity(int relativity) +{ + dIASSERT(dIN_RANGE(relativity, dJBR__BODIES_MIN, dJBR__BODIES_MAX)); + return (dJointBodyRelativity)(dJBR_BODY1 + dJBR_BODY2 - relativity); +} + + + + +// there are two of these nodes in the joint, one for each connection to a +// body. these are node of a linked list kept by each body of it's connecting +// joints. but note that the body pointer in each node points to the body that +// makes use of the *other* node, not this node. this trick makes it a bit +// easier to traverse the body/joint graph. + +struct dxJointNode +{ + dxJoint *joint; // pointer to enclosing dxJoint object + dxBody *body; // *other* body this joint is connected to + dxJointNode *next; // next node in body's list of connected joints +}; + + +struct dxJoint : public dObject +{ + // naming convention: the "first" body this is connected to is node[0].body, + // and the "second" body is node[1].body. if this joint is only connected + // to one body then the second body is 0. + + // info returned by getInfo1 function. the constraint dimension is m (<=6). + // i.e. that is the total number of rows in the jacobian. `nub' is the + // number of unbounded variables (which have lo,hi = -/+ infinity). + + struct Info1 + { + // Structure size should not exceed sizeof(pointer) bytes to have + // to have good memory pattern in dxQuickStepper() + uint8 m, nub; + }; + + // info returned by getInfo2 function + + enum + { + GI2__J_MIN, + GI2__JL_MIN = GI2__J_MIN + dDA__L_MIN, + + GI2_JLX = GI2__J_MIN + dDA_LX, + GI2_JLY = GI2__J_MIN + dDA_LY, + GI2_JLZ = GI2__J_MIN + dDA_LZ, + + GI2__JL_MAX = GI2__J_MIN + dDA__L_MAX, + + GI2__JA_MIN = GI2__J_MIN + dDA__A_MIN, + + GI2_JAX = GI2__J_MIN + dDA_AX, + GI2_JAY = GI2__J_MIN + dDA_AY, + GI2_JAZ = GI2__J_MIN + dDA_AZ, + + GI2__JA_MAX = GI2__J_MIN + dDA__A_MAX, + GI2__J_MAX = GI2__J_MIN + dDA__MAX, + }; + + enum + { + GI2_RHS, + GI2_CFM, + GI2__RHS_CFM_MAX, + }; + + enum + { + GI2_LO, + GI2_HI, + GI2__LO_HI_MAX, + }; + + // info returned by getSureMaxInfo function. + // The information is used for memory reservation in calculations. + + struct SureMaxInfo + { + // The value of `max_m' must ALWAYS be not less than the value of `m' + // the getInfo1 call can generate in current joint state. Another + // requirement is that the value should be provided very quickly, + // without the excessive calculations. + // If it is hard/impossible to quickly predict the maximal value of `m' + // (which is the case for most joint types) the maximum for current + // joint type in general should be returned. If it can be known the `m' + // will be smaller, it can save a bit of memory from being reserved + // for calculations if that smaller value is returned. + + uint8 max_m; // Estimate of maximal `m' in Info1 + }; + + + unsigned flags; // dJOINT_xxx flags + dxJointNode node[2]; // connections to bodies. node[1].body can be 0 + dJointFeedback *feedback; // optional feedback structure + dReal lambda[6]; // lambda generated by last step + + + dxJoint( dxWorld *w ); + virtual ~dxJoint(); + + bool GetIsJointReverse() const { return (this->flags & dJOINT_REVERSE) != 0; } + + virtual void getInfo1( Info1* info ) = 0; + + // integrator parameters + virtual void getInfo2( + // fps=frames per second (1/stepsize), erp=default error reduction parameter (0..1) + dReal worldFPS, dReal worldERP, + // elements to jump from one row to the next in J's + int rowskip, + // 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. + dReal *J1, dReal *J2, + // elements to jump from one pair of scalars to the next + int pairskip, + // 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. + dReal *pairRhsCfm, + // lo and hi limits for variables (set to -/+ infinity on entry). + dReal *pairLoHi, + // 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) = 0; + // This call quickly!!! estimates maximum value of "m" that could be returned by getInfo1() + // See comments at definition of SureMaxInfo for details. + virtual void getSureMaxInfo( SureMaxInfo* info ) = 0; + virtual dJointType type() const = 0; + virtual sizeint size() const = 0; + + /// Set values which are relative with respect to bodies. + /// Each dxJoint should redefine it if needed. + virtual void setRelativeValues(); + + // Test if this joint should be used in the simulation step + // (has the enabled flag set, and is attached to at least one dynamic body) + bool isEnabled() const; +}; + + +// joint group. NOTE: any joints in the group that have their world destroyed +// will have their world pointer set to 0. + +struct dxJointGroup : public dBase +{ + dxJointGroup(): m_num(0), m_stack() {} + + template<class T> + T *alloc(dWorldID w) + { + T *j = (T *)m_stack.alloc(sizeof(T)); + if (j != NULL) { + ++m_num; + new(j) T(w); + j->flags |= dJOINT_INGROUP; + } + return j; + } + + sizeint getJointCount() const { return m_num; } + sizeint exportJoints(dxJoint **jlist); + + void *beginEnum() { return m_stack.rewind(); } + void *continueEnum(sizeint num_bytes) { return m_stack.next(num_bytes); } + + void freeAll(); + +private: + sizeint m_num; // number of joints on the stack + dObStack m_stack; // a stack of (possibly differently sized) dxJoint objects. +}; + +// common limit and motor information for a single joint axis of movement +struct dxJointLimitMotor +{ + dReal vel, fmax; // powered joint: velocity, max force + dReal lostop, histop; // joint limits, relative to initial position + dReal fudge_factor; // when powering away from joint limits + dReal normal_cfm; // cfm to use when not at a stop + dReal stop_erp, stop_cfm; // erp and cfm for when at joint limit + dReal bounce; // restitution factor + // variables used between getInfo1() and getInfo2() + int limit; // 0=free, 1=at lo limit, 2=at hi limit + dReal limit_err; // if at limit, amount over limit + + void init( dxWorld * ); + void set( int num, dReal value ); + dReal get( int num ) const; + bool testRotationalLimit( dReal angle ); + + enum + { + GI2__JL_MIN = dxJoint::GI2__JL_MIN, + GI2__JA_MIN = dxJoint::GI2__JA_MIN, + GI2_JAX = dxJoint::GI2_JAX, + GI2_JAY = dxJoint::GI2_JAY, + GI2_JAZ = dxJoint::GI2_JAZ, + GI2_RHS = dxJoint::GI2_RHS, + GI2_CFM = dxJoint::GI2_CFM, + GI2_LO = dxJoint::GI2_LO, + GI2_HI = dxJoint::GI2_HI, + }; + + bool addLimot( dxJoint *joint, dReal fps, + dReal *J1, dReal *J2, dReal *pairRhsCfm, dReal *pairLoHi, + const dVector3 ax1, int rotational ); + bool addTwoPointLimot( dxJoint *joint, dReal fps, + dReal *J1, dReal *J2, dReal *pairRhsCfm, dReal *pairLoHi, + const dVector3 ax1, const dVector3 pt1, const dVector3 pt2 ); +}; + + +#endif + + +// Local Variables: +// mode:c++ +// c-basic-offset:4 +// End: diff --git a/libs/ode-0.16.1/ode/src/joints/joint_internal.h b/libs/ode-0.16.1/ode/src/joints/joint_internal.h new file mode 100644 index 0000000..30accb6 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/joint_internal.h @@ -0,0 +1,70 @@ +/*************************************************************************
+ * *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
+ * All rights reserved. Email: russ@q12.org Web: www.q12.org *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of EITHER: *
+ * (1) The GNU Lesser General Public License as published by the Free *
+ * Software Foundation; either version 2.1 of the License, or (at *
+ * your option) any later version. The text of the GNU Lesser *
+ * General Public License is included with this library in the *
+ * file LICENSE.TXT. *
+ * (2) The BSD-style license that is included with this library in *
+ * the file LICENSE-BSD.TXT. *
+ * *
+ * This library 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 files *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
+ * *
+ *************************************************************************/
+
+
+#ifndef _ODE_JOINT_INTERNAL_H_
+#define _ODE_JOINT_INTERNAL_H_
+
+
+#include <ode/rotation.h>
+#include <ode/objects.h>
+#include "matrix.h"
+#include "odemath.h"
+
+
+#define checktype(j,t) dUASSERT(j->type() == dJointType##t, \
+ "joint type is not " #t)
+
+
+void setBall( dxJoint *joint, dReal fps, dReal erp,
+ int rowskip, dReal *J1, dReal *J2,
+ int pairskip, dReal *pairRhsCfm,
+ dVector3 anchor1, dVector3 anchor2 );
+void setBall2( dxJoint *joint, dReal fps, dReal erp,
+ int rowskip, dReal *J1, dReal *J2,
+ int pairskip, dReal *pairRhsCfm,
+ dVector3 anchor1, dVector3 anchor2,
+ dVector3 axis, dReal erp1 );
+
+void setFixedOrientation( dxJoint *joint, dReal fps, dReal erp,
+ int rowskip, dReal *J1, dReal *J2,
+ int pairskip, dReal *pairRhsCfm,
+ dQuaternion qrel );
+
+
+void setAnchors( dxJoint *j, dReal x, dReal y, dReal z,
+ dVector3 anchor1, dVector3 anchor2 );
+
+void getAnchor( dxJoint *j, dVector3 result, dVector3 anchor1 );
+void getAnchor2( dxJoint *j, dVector3 result, dVector3 anchor2 );
+
+void setAxes( dxJoint *j, dReal x, dReal y, dReal z,
+ dVector3 axis1, dVector3 axis2 );
+void getAxis( dxJoint *j, dVector3 result, dVector3 axis1 );
+void getAxis2( dxJoint *j, dVector3 result, dVector3 axis2 );
+
+
+dReal getHingeAngle( dxBody *body1, dxBody *body2, dVector3 axis, dQuaternion q_initial );
+dReal getHingeAngleFromRelativeQuat( dQuaternion qrel, dVector3 axis );
+
+#endif
+
diff --git a/libs/ode-0.16.1/ode/src/joints/joints.h b/libs/ode-0.16.1/ode/src/joints/joints.h new file mode 100644 index 0000000..d06af4d --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/joints.h @@ -0,0 +1,48 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_JOINTS_H_ +#define _ODE_JOINTS_H_ + +#include <ode/common.h> + +#include "joint.h" + +#include "ball.h" +#include "dball.h" +#include "dhinge.h" +#include "transmission.h" +#include "hinge.h" +#include "slider.h" +#include "contact.h" +#include "universal.h" +#include "hinge2.h" +#include "fixed.h" +#include "null.h" +#include "amotor.h" +#include "lmotor.h" +#include "plane2d.h" +#include "pu.h" +#include "pr.h" +#include "piston.h" + +#endif diff --git a/libs/ode-0.16.1/ode/src/joints/lmotor.cpp b/libs/ode-0.16.1/ode/src/joints/lmotor.cpp new file mode 100644 index 0000000..8270188 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/lmotor.cpp @@ -0,0 +1,214 @@ +/*************************************************************************
+ * *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
+ * All rights reserved. Email: russ@q12.org Web: www.q12.org *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of EITHER: *
+ * (1) The GNU Lesser General Public License as published by the Free *
+ * Software Foundation; either version 2.1 of the License, or (at *
+ * your option) any later version. The text of the GNU Lesser *
+ * General Public License is included with this library in the *
+ * file LICENSE.TXT. *
+ * (2) The BSD-style license that is included with this library in *
+ * the file LICENSE-BSD.TXT. *
+ * *
+ * This library 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 files *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
+ * *
+ *************************************************************************/
+
+
+#include <ode/odeconfig.h>
+#include "config.h"
+#include "lmotor.h"
+#include "joint_internal.h"
+
+
+//****************************************************************************
+// lmotor joint
+dxJointLMotor::dxJointLMotor( dxWorld *w ) :
+ dxJoint( w )
+{
+ int i;
+ num = 0;
+ for ( i = 0;i < 3;i++ )
+ {
+ dSetZero( axis[i], 4 );
+ limot[i].init( world );
+ }
+}
+
+void
+dxJointLMotor::computeGlobalAxes( dVector3 ax[3] )
+{
+ for ( int i = 0; i < num; i++ )
+ {
+ if ( rel[i] == 1 )
+ {
+ dMultiply0_331( ax[i], node[0].body->posr.R, axis[i] );
+ }
+ else if ( rel[i] == 2 )
+ {
+ if ( node[1].body ) // jds: don't assert, just ignore
+ {
+ dMultiply0_331( ax[i], node[1].body->posr.R, axis[i] );
+ }
+ }
+ else
+ {
+ ax[i][0] = axis[i][0];
+ ax[i][1] = axis[i][1];
+ ax[i][2] = axis[i][2];
+ }
+ }
+}
+
+void
+dxJointLMotor::getSureMaxInfo( SureMaxInfo* info )
+{
+ info->max_m = num;
+}
+
+void
+dxJointLMotor::getInfo1( dxJoint::Info1 *info )
+{
+ info->m = 0;
+ info->nub = 0;
+ for ( int i = 0; i < num; i++ )
+ {
+ if ( limot[i].fmax > 0 )
+ {
+ info->m++;
+ }
+ }
+}
+
+void
+dxJointLMotor::getInfo2( dReal worldFPS, dReal /*worldERP*/,
+ int rowskip, dReal *J1, dReal *J2,
+ int pairskip, dReal *pairRhsCfm, dReal *pairLoHi,
+ int *findex )
+{
+ dVector3 ax[3];
+ computeGlobalAxes( ax );
+
+ int currRowSkip = 0, currPairSkip = 0;
+ for ( int i = 0; i < num; ++i ) {
+ if (limot[i].addLimot( this, worldFPS, J1 + currRowSkip, J2 + currRowSkip, pairRhsCfm + currPairSkip, pairLoHi + currPairSkip, ax[i], 0 )) {
+ currRowSkip += rowskip; currPairSkip += pairskip;
+ }
+ }
+}
+
+void dJointSetLMotorAxis( dJointID j, int anum, int rel, dReal x, dReal y, dReal z )
+{
+ dxJointLMotor* joint = ( dxJointLMotor* )j;
+ //for now we are ignoring rel!
+ dAASSERT( joint && anum >= 0 && anum <= 2 && rel >= 0 && rel <= 2 );
+ checktype( joint, LMotor );
+
+ if ( anum < 0 ) anum = 0;
+ if ( anum > 2 ) anum = 2;
+
+ if ( !joint->node[1].body && rel == 2 ) rel = 1; //ref 1
+
+ joint->rel[anum] = rel;
+
+ dVector3 r;
+ r[0] = x;
+ r[1] = y;
+ r[2] = z;
+ r[3] = 0;
+ if ( rel > 0 )
+ {
+ if ( rel == 1 )
+ {
+ dMultiply1_331( joint->axis[anum], joint->node[0].body->posr.R, r );
+ }
+ else
+ {
+ //second body has to exists thanks to ref 1 line
+ dMultiply1_331( joint->axis[anum], joint->node[1].body->posr.R, r );
+ }
+ }
+ else
+ {
+ joint->axis[anum][0] = r[0];
+ joint->axis[anum][1] = r[1];
+ joint->axis[anum][2] = r[2];
+ }
+
+ dNormalize3( joint->axis[anum] );
+}
+
+void dJointSetLMotorNumAxes( dJointID j, int num )
+{
+ dxJointLMotor* joint = ( dxJointLMotor* )j;
+ dAASSERT( joint && num >= 0 && num <= 3 );
+ checktype( joint, LMotor );
+ if ( num < 0 ) num = 0;
+ if ( num > 3 ) num = 3;
+ joint->num = num;
+}
+
+void dJointSetLMotorParam( dJointID j, int parameter, dReal value )
+{
+ dxJointLMotor* joint = ( dxJointLMotor* )j;
+ dAASSERT( joint );
+ checktype( joint, LMotor );
+ int anum = parameter >> 8;
+ if ( anum < 0 ) anum = 0;
+ if ( anum > 2 ) anum = 2;
+ parameter &= 0xff;
+ joint->limot[anum].set( parameter, value );
+}
+
+int dJointGetLMotorNumAxes( dJointID j )
+{
+ dxJointLMotor* joint = ( dxJointLMotor* )j;
+ dAASSERT( joint );
+ checktype( joint, LMotor );
+ return joint->num;
+}
+
+
+void dJointGetLMotorAxis( dJointID j, int anum, dVector3 result )
+{
+ dxJointLMotor* joint = ( dxJointLMotor* )j;
+ dAASSERT( joint && anum >= 0 && anum < 3 );
+ checktype( joint, LMotor );
+ if ( anum < 0 ) anum = 0;
+ if ( anum > 2 ) anum = 2;
+ result[0] = joint->axis[anum][0];
+ result[1] = joint->axis[anum][1];
+ result[2] = joint->axis[anum][2];
+}
+
+dReal dJointGetLMotorParam( dJointID j, int parameter )
+{
+ dxJointLMotor* joint = ( dxJointLMotor* )j;
+ dAASSERT( joint );
+ checktype( joint, LMotor );
+ int anum = parameter >> 8;
+ if ( anum < 0 ) anum = 0;
+ if ( anum > 2 ) anum = 2;
+ parameter &= 0xff;
+ return joint->limot[anum].get( parameter );
+}
+
+dJointType
+dxJointLMotor::type() const
+{
+ return dJointTypeLMotor;
+}
+
+
+sizeint
+dxJointLMotor::size() const
+{
+ return sizeof( *this );
+}
+
diff --git a/libs/ode-0.16.1/ode/src/joints/lmotor.h b/libs/ode-0.16.1/ode/src/joints/lmotor.h new file mode 100644 index 0000000..c819a47 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/lmotor.h @@ -0,0 +1,51 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_JOINT_LMOTOR_H_ +#define _ODE_JOINT_LMOTOR_H_ + +#include "joint.h" + +struct dxJointLMotor : public dxJoint +{ + int num; + int rel[3]; + dVector3 axis[3]; + dxJointLimitMotor limot[3]; + + void computeGlobalAxes( dVector3 ax[3] ); + + + dxJointLMotor( dxWorld *w ); + virtual void getSureMaxInfo( SureMaxInfo* info ); + virtual void getInfo1( Info1* info ); + virtual void getInfo2( dReal worldFPS, dReal worldERP, + int rowskip, dReal *J1, dReal *J2, + int pairskip, dReal *pairRhsCfm, dReal *pairLoHi, + int *findex ); + virtual dJointType type() const; + virtual sizeint size() const; +}; + + +#endif + diff --git a/libs/ode-0.16.1/ode/src/joints/null.cpp b/libs/ode-0.16.1/ode/src/joints/null.cpp new file mode 100644 index 0000000..315eea9 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/null.cpp @@ -0,0 +1,74 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + + +#include <ode/odeconfig.h> +#include "config.h" +#include "null.h" +#include "joint_internal.h" + + + +//**************************************************************************** +// null joint +dxJointNull::dxJointNull( dxWorld *w ) : + dxJoint( w ) +{ +} + +void +dxJointNull::getSureMaxInfo( SureMaxInfo* info ) +{ + info->max_m = 0; +} + + +void +dxJointNull::getInfo1( dxJoint::Info1 *info ) +{ + info->m = 0; + info->nub = 0; +} + + +void +dxJointNull::getInfo2( dReal /*worldFPS*/, dReal /*worldERP*/, + int rowskip, dReal *J1, dReal *J2, + int pairskip, dReal *pairRhsCfm, dReal *pairLoHi, + int *findex ) +{ + dDebug( 0, "this should never get called" ); +} + +dJointType +dxJointNull::type() const +{ + return dJointTypeNull; +} + +sizeint +dxJointNull::size() const +{ + return sizeof( *this ); +} + + diff --git a/libs/ode-0.16.1/ode/src/joints/null.h b/libs/ode-0.16.1/ode/src/joints/null.h new file mode 100644 index 0000000..fb3f629 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/null.h @@ -0,0 +1,46 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_JOINT_NULL_H_ +#define _ODE_JOINT_NULL_H_ + +#include "joint.h" + + + +// null joint, for testing only + +struct dxJointNull : public dxJoint +{ + dxJointNull( dxWorld *w ); + virtual void getSureMaxInfo( SureMaxInfo* info ); + virtual void getInfo1( Info1* info ); + virtual void getInfo2( dReal worldFPS, dReal worldERP, + int rowskip, dReal *J1, dReal *J2, + int pairskip, dReal *pairRhsCfm, dReal *pairLoHi, + int *findex ); + virtual dJointType type() const; + virtual sizeint size() const; +}; + +#endif + diff --git a/libs/ode-0.16.1/ode/src/joints/piston.cpp b/libs/ode-0.16.1/ode/src/joints/piston.cpp new file mode 100644 index 0000000..3bd7fd0 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/piston.cpp @@ -0,0 +1,729 @@ +/*************************************************************************
+ * *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
+ * All rights reserved. Email: russ@q12.org Web: www.q12.org *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of EITHER: *
+ * (1) The GNU Lesser General Public License as published by the Free *
+ * Software Foundation; either version 2.1 of the License, or (at *
+ * your option) any later version. The text of the GNU Lesser *
+ * General Public License is included with this library in the *
+ * file LICENSE.TXT. *
+ * (2) The BSD-style license that is included with this library in *
+ * the file LICENSE-BSD.TXT. *
+ * *
+ * This library 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 files *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
+ * *
+ *************************************************************************/
+
+
+#include <ode/odeconfig.h>
+#include "config.h"
+#include "piston.h"
+#include "joint_internal.h"
+
+
+
+//****************************************************************************
+// Piston
+//
+
+dxJointPiston::dxJointPiston ( dxWorld *w ) :
+ dxJoint ( w )
+{
+ dSetZero ( axis1, 4 );
+ dSetZero ( axis2, 4 );
+
+ axis1[0] = 1;
+ axis2[0] = 1;
+
+ dSetZero ( qrel, 4 );
+
+ dSetZero ( anchor1, 4 );
+ dSetZero ( anchor2, 4 );
+
+ limotP.init ( world );
+
+ limotR.init ( world );
+}
+
+
+dReal dJointGetPistonPosition ( dJointID j )
+{
+ dxJointPiston* joint = ( dxJointPiston* ) j;
+ dUASSERT ( joint, "bad joint argument" );
+ checktype ( joint, Piston );
+
+ if ( joint->node[0].body )
+ {
+ dVector3 q;
+ // get the anchor (or offset) in global coordinates
+ dMultiply0_331 ( q, joint->node[0].body->posr.R, joint->anchor1 );
+
+ if ( joint->node[1].body )
+ {
+ dVector3 anchor2;
+ // get the anchor2 in global coordinates
+ dMultiply0_331 ( anchor2, joint->node[1].body->posr.R, joint->anchor2 );
+
+ q[0] = ( ( joint->node[0].body->posr.pos[0] + q[0] ) -
+ ( joint->node[1].body->posr.pos[0] + anchor2[0] ) );
+ q[1] = ( ( joint->node[0].body->posr.pos[1] + q[1] ) -
+ ( joint->node[1].body->posr.pos[1] + anchor2[1] ) );
+ q[2] = ( ( joint->node[0].body->posr.pos[2] + q[2] ) -
+ ( joint->node[1].body->posr.pos[2] + anchor2[2] ) );
+ }
+ else
+ {
+ // N.B. When there is no body 2 the joint->anchor2 is already in
+ // global coordinates
+ q[0] = ( ( joint->node[0].body->posr.pos[0] + q[0] ) -
+ ( joint->anchor2[0] ) );
+ q[1] = ( ( joint->node[0].body->posr.pos[1] + q[1] ) -
+ ( joint->anchor2[1] ) );
+ q[2] = ( ( joint->node[0].body->posr.pos[2] + q[2] ) -
+ ( joint->anchor2[2] ) );
+
+ if ( joint->flags & dJOINT_REVERSE )
+ {
+ q[0] = -q[0];
+ q[1] = -q[1];
+ q[2] = -q[2];
+ }
+ }
+
+ // get axis in global coordinates
+ dVector3 ax;
+ dMultiply0_331 ( ax, joint->node[0].body->posr.R, joint->axis1 );
+
+ return dCalcVectorDot3 ( ax, q );
+ }
+
+ dDEBUGMSG ( "The function always return 0 since no body are attached" );
+ return 0;
+}
+
+
+dReal dJointGetPistonPositionRate ( dJointID j )
+{
+ dxJointPiston* joint = ( dxJointPiston* ) j;
+ dUASSERT ( joint, "bad joint argument" );
+ checktype ( joint, Piston );
+
+ // get axis in global coordinates
+ dVector3 ax;
+ dMultiply0_331 ( ax, joint->node[0].body->posr.R, joint->axis1 );
+
+ // The linear velocity created by the rotation can be discarded since
+ // the rotation is along the prismatic axis and this rotation don't create
+ // linear velocity in the direction of the prismatic axis.
+ if ( joint->node[1].body )
+ {
+ return ( dCalcVectorDot3 ( ax, joint->node[0].body->lvel ) -
+ dCalcVectorDot3 ( ax, joint->node[1].body->lvel ) );
+ }
+ else
+ {
+ dReal rate = dCalcVectorDot3 ( ax, joint->node[0].body->lvel );
+ return ( (joint->flags & dJOINT_REVERSE) ? -rate : rate);
+ }
+}
+
+
+dReal dJointGetPistonAngle ( dJointID j )
+{
+ dxJointPiston* joint = ( dxJointPiston * ) j;
+ dAASSERT ( joint );
+ checktype ( joint, Piston );
+
+ if ( joint->node[0].body )
+ {
+ dReal ang = getHingeAngle ( joint->node[0].body, joint->node[1].body, joint->axis1,
+ joint->qrel );
+ if ( joint->flags & dJOINT_REVERSE )
+ return -ang;
+ else
+ return ang;
+ }
+ else return 0;
+}
+
+
+dReal dJointGetPistonAngleRate ( dJointID j )
+{
+ dxJointPiston* joint = ( dxJointPiston* ) j;
+ dAASSERT ( joint );
+ checktype ( joint, Piston );
+
+ if ( joint->node[0].body )
+ {
+ dVector3 axis;
+ dMultiply0_331 ( axis, joint->node[0].body->posr.R, joint->axis1 );
+ dReal rate = dCalcVectorDot3 ( axis, joint->node[0].body->avel );
+ if ( joint->node[1].body ) rate -= dCalcVectorDot3 ( axis, joint->node[1].body->avel );
+ if ( joint->flags & dJOINT_REVERSE ) rate = - rate;
+ return rate;
+ }
+ else return 0;
+}
+
+
+void
+dxJointPiston::getSureMaxInfo( SureMaxInfo* info )
+{
+ info->max_m = 6;
+}
+
+
+void
+dxJointPiston::getInfo1 ( dxJoint::Info1 *info )
+{
+ info->nub = 4; // Number of unbound variables
+ // The only bound variable is one linear displacement
+
+ info->m = 4; // Default number of constraint row
+
+ // see if we're at a joint limit.
+ limotP.limit = 0;
+ if ( ( limotP.lostop > -dInfinity || limotP.histop < dInfinity ) &&
+ limotP.lostop <= limotP.histop )
+ {
+ // measure joint position
+ dReal pos = dJointGetPistonPosition ( this );
+ limotP.testRotationalLimit ( pos ); // N.B. The fucntion is ill named
+ }
+
+ // powered Piston or at limits needs an extra constraint row
+ if ( limotP.limit || limotP.fmax > 0 ) info->m++;
+
+
+ // see if we're at a joint limit.
+ limotR.limit = 0;
+ if ( ( limotR.lostop > -dInfinity || limotR.histop < dInfinity ) &&
+ limotR.lostop <= limotR.histop )
+ {
+ // measure joint position
+ dReal angle = getHingeAngle ( node[0].body, node[1].body, axis1,
+ qrel );
+ limotR.testRotationalLimit ( angle );
+ }
+
+ // powered Piston or at limits needs an extra constraint row
+ if ( limotR.limit || limotR.fmax > 0 ) info->m++;
+
+}
+
+
+void
+dxJointPiston::getInfo2 ( dReal worldFPS, dReal worldERP,
+ int rowskip, dReal *J1, dReal *J2,
+ int pairskip, dReal *pairRhsCfm, dReal *pairLoHi,
+ int *findex )
+{
+ const dReal k = worldFPS * worldERP;
+
+
+ // Pull out pos and R for both bodies. also get the `connection'
+ // vector pos2-pos1.
+
+ dVector3 dist; // Current position of body_1 w.r.t "anchor"
+ // 2 bodies anchor is center of body 2
+ // 1 bodies anchor is origin
+ dVector3 lanchor2 = { 0,0,0 };
+
+ dReal *pos1 = node[0].body->posr.pos;
+ dReal *R1 = node[0].body->posr.R;
+ dReal *R2 = NULL;
+
+ dxBody *body1 = node[1].body;
+
+ if ( body1 )
+ {
+ dReal *pos2 = body1->posr.pos;
+ R2 = body1->posr.R;
+
+ dMultiply0_331 ( lanchor2, R2, anchor2 );
+ dist[0] = lanchor2[0] + pos2[0] - pos1[0];
+ dist[1] = lanchor2[1] + pos2[1] - pos1[1];
+ dist[2] = lanchor2[2] + pos2[2] - pos1[2];
+ }
+ else
+ {
+ // pos2 = 0; // N.B. We can do that to be safe but it is no necessary
+ // R2 = 0; // N.B. We can do that to be safe but it is no necessary
+ if ( (flags & dJOINT_REVERSE) != 0 )
+ {
+ dSubtractVectors3(dist, pos1, anchor2); // Invert the value
+ }
+ else
+ {
+ dSubtractVectors3(dist, anchor2, pos1);
+ }
+ }
+
+ // ======================================================================
+ // Work on the angular part (i.e. row 0, 1)
+ // Set the two orientation rows. The rotoide axis should be the only
+ // unconstrained rotational axis, the angular velocity of the two bodies
+ // perpendicular to the rotoide axis should be equal.
+ // Thus the constraint equations are:
+ // p*w1 - p*w2 = 0
+ // q*w1 - q*w2 = 0
+ // where p and q are unit vectors normal to the rotoide axis, and w1 and w2
+ // are the angular velocity vectors of the two bodies.
+ // Since the rotoide axis is the same as the prismatic axis.
+ //
+ //
+ // Also, compute the right hand side (RHS) of the rotation constraint equation set.
+ // The first 2 element will result in the relative angular velocity of the two
+ // bodies along axis p and q. This is set to bring the rotoide back into alignment.
+ // 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| * u
+ // = (erp*fps) * theta * u
+ // where rotation along unit length axis u by theta brings body 2's frame
+ //
+ // if theta is smallish, sin(theta) ~= theta and cos(theta) ~= 1
+ // where the quaternion of the relative rotation between the two bodies is
+ // quat = [cos(theta/2) sin(theta/2)*u]
+ // quat = [1 theta/2*u]
+ // => q[0] ~= 1
+ // 2 * q[1+i] = theta * u[i]
+ //
+ // Since there is no constraint along the rotoide axis
+ // only along p and q that we want the same angular velocity and need to reduce
+ // the error
+ dVector3 b, ax1, p, q;
+ dMultiply0_331 ( ax1, node[0].body->posr.R, axis1 );
+
+ // Find the 2 axis perpendicular to the rotoide axis.
+ dPlaneSpace ( ax1, p, q );
+
+ // LHS
+ dCopyVector3 ( J1 + GI2__JA_MIN, p );
+
+ if ( body1 )
+ {
+ dCopyNegatedVector3 ( J2 + GI2__JA_MIN, p );
+ }
+
+ dCopyVector3 ( J1 + rowskip + GI2__JA_MIN, q );
+
+ if ( body1 )
+ {
+ dCopyNegatedVector3 ( J2 + rowskip + GI2__JA_MIN, q );
+
+ // Some math for the RHS
+ dVector3 ax2;
+ dMultiply0_331 ( ax2, R2, axis2 );
+ dCalcVectorCross3( b, ax1, ax2 );
+ }
+ else
+ {
+ // Some math for the RHS
+ dCalcVectorCross3( b, ax1, axis2 );
+ }
+
+ // RHS
+ pairRhsCfm[GI2_RHS] = k * dCalcVectorDot3 ( p, b );
+ pairRhsCfm[pairskip + GI2_RHS] = k * dCalcVectorDot3 ( q, b );
+
+
+ // ======================================================================
+ // Work on the linear part (i.e row 2,3)
+ // p2 + R2 anchor2' = p1 + R1 dist'
+ // v2 + w2 R2 anchor2' + R2 d(anchor2')/dt = v1 + w1 R1 dist' + R1 d(dist')/dt
+ // v2 + w2 x anchor2 = v1 + w1 x dist + v_p
+ // v_p is speed of prismatic joint (i.e. elongation rate)
+ // Since the constraints are perpendicular to v_p we have:
+ // p . v_p = 0 and q . v_p = 0
+ // Along p and q we have (since sliding along the prismatic axis is disregarded):
+ // u . ( v2 + w2 x anchor2 = v1 + w1 x dist + v_p) ( where u is p or q )
+ // Simplify
+ // u . v2 + u. w2 x anchor2 = u . v1 + u . w1 x dist
+ // or
+ // u . v1 - u . v2 + u . w1 x dist - u2 . w2 x anchor2 = 0
+ // using the fact that (a x b = - b x a)
+ // u . v1 - u . v2 - u . dist x w1 + u . anchor2 x w2 = 0
+ // With the help of the triple product:
+ // i.e. a . b x c = b . c x a = c . a x b or a . b x c = a x b . c
+ // Ref: http://mathworld.wolfram.com/ScalarTripleProduct.html
+ // u . v1 - u . v2 - u x dist . w1 + u x anchor2 . w2 = 0
+ // u . v1 - u . v2 + dist x u . w1 - u x anchor2 . w2 = 0
+ //
+ // Coeff for 1er line of: J1l => p, J2l => -p
+ // Coeff for 2er line of: J1l => q, J2l => -q
+ // Coeff for 1er line of: J1a => dist x p, J2a => p x anchor2
+ // Coeff for 2er line of: J1a => dist x q, J2a => q x anchor2
+
+ int currRowSkip = 2 * rowskip;
+ {
+ dCopyVector3 ( J1 + currRowSkip + GI2__JL_MIN, p );
+ dCalcVectorCross3( J1 + currRowSkip + GI2__JA_MIN, dist, p );
+
+ if ( body1 )
+ {
+ // info->J2l[s2+i] = -p[i];
+ dCopyNegatedVector3 ( J2 + currRowSkip + GI2__JL_MIN, p );
+ // q x anchor2 instead of anchor2 x q since we want the negative value
+ dCalcVectorCross3( J2 + currRowSkip + GI2__JA_MIN, p, lanchor2 );
+ }
+ }
+
+ currRowSkip += rowskip;
+ {
+ dCopyVector3 ( J1 + currRowSkip + GI2__JL_MIN, q );
+ dCalcVectorCross3( J1 + currRowSkip + GI2__JA_MIN, dist, q );
+
+ if ( body1 )
+ {
+ // info->J2l[s3+i] = -q[i];
+ dCopyNegatedVector3 ( J2 + currRowSkip + GI2__JL_MIN, q );
+ // The cross product is in reverse order since we want the negative value
+ dCalcVectorCross3( J2 + currRowSkip + GI2__JA_MIN, q, lanchor2 );
+ }
+ }
+
+ // We want to make correction for motion not in the line of the axis
+ // We calculate the displacement w.r.t. the "anchor" pt.
+ // i.e. Find the difference between the current position and the initial
+ // position along the constrained axies (i.e. axis p and q).
+ // The bodies can move w.r.t each other only along the prismatic axis
+ //
+ // Compute the RHS of rows 2 and 3
+ dVector3 err;
+ dMultiply0_331 ( err, R1, anchor1 );
+ dSubtractVectors3( err, dist, err );
+
+ int currPairSkip = 2 * pairskip;
+ {
+ pairRhsCfm[currPairSkip + GI2_RHS] = k * dCalcVectorDot3 ( p, err );
+ }
+
+ currPairSkip += pairskip;
+ {
+ pairRhsCfm[currPairSkip + GI2_RHS] = k * dCalcVectorDot3 ( q, err );
+ }
+
+ currRowSkip += rowskip; currPairSkip += pairskip;
+
+ if ( body1 || (flags & dJOINT_REVERSE) == 0 )
+ {
+ if (limotP.addLimot ( this, worldFPS, J1 + currRowSkip, J2 + currRowSkip, pairRhsCfm + currPairSkip, pairLoHi + currPairSkip, ax1, 0 ))
+ {
+ currRowSkip += rowskip; currPairSkip += pairskip;
+ }
+ }
+ else
+ {
+ dVector3 rAx1;
+ dCopyNegatedVector3(rAx1, ax1);
+
+ if (limotP.addLimot ( this, worldFPS, J1 + currRowSkip, J2 + currRowSkip, pairRhsCfm + currPairSkip, pairLoHi + currPairSkip, rAx1, 0 ))
+ {
+ currRowSkip += rowskip; currPairSkip += pairskip;
+ }
+ }
+
+ limotR.addLimot ( this, worldFPS, J1 + currRowSkip, J2 + currRowSkip, pairRhsCfm + currPairSkip, pairLoHi + currPairSkip, ax1, 1 );
+}
+
+void dJointSetPistonAnchor ( dJointID j, dReal x, dReal y, dReal z )
+{
+ dxJointPiston* joint = ( dxJointPiston* ) j;
+ dUASSERT ( joint, "bad joint argument" );
+ checktype ( joint, Piston );
+ setAnchors ( joint, x, y, z, joint->anchor1, joint->anchor2 );
+ joint->computeInitialRelativeRotation();
+
+}
+
+void dJointSetPistonAnchorOffset (dJointID j, dReal x, dReal y, dReal z,
+ dReal dx, dReal dy, dReal dz)
+{
+ dxJointPiston* joint = (dxJointPiston*) j;
+ dUASSERT (joint,"bad joint argument");
+ checktype ( joint, Piston );
+
+ if (joint->flags & dJOINT_REVERSE)
+ {
+ dx = -dx;
+ dy = -dy;
+ dz = -dz;
+ }
+
+ if (joint->node[0].body)
+ {
+ joint->node[0].body->posr.pos[0] -= dx;
+ joint->node[0].body->posr.pos[1] -= dy;
+ joint->node[0].body->posr.pos[2] -= dz;
+ }
+
+ setAnchors (joint,x ,y, z, joint->anchor1, joint->anchor2);
+
+ if (joint->node[0].body)
+ {
+ joint->node[0].body->posr.pos[0] += dx;
+ joint->node[0].body->posr.pos[1] += dy;
+ joint->node[0].body->posr.pos[2] += dz;
+ }
+
+ joint->computeInitialRelativeRotation();
+}
+
+
+
+void dJointGetPistonAnchor ( dJointID j, dVector3 result )
+{
+ dxJointPiston* joint = ( dxJointPiston* ) j;
+ dUASSERT ( joint, "bad joint argument" );
+ dUASSERT ( result, "bad result argument" );
+ checktype ( joint, Piston );
+ if ( joint->flags & dJOINT_REVERSE )
+ getAnchor2 ( joint, result, joint->anchor2 );
+ else
+ getAnchor ( joint, result, joint->anchor1 );
+}
+
+
+void dJointGetPistonAnchor2 ( dJointID j, dVector3 result )
+{
+ dxJointPiston* joint = ( dxJointPiston* ) j;
+ dUASSERT ( joint, "bad joint argument" );
+ dUASSERT ( result, "bad result argument" );
+ checktype ( joint, Piston );
+ if ( joint->flags & dJOINT_REVERSE )
+ getAnchor ( joint, result, joint->anchor1 );
+ else
+ getAnchor2 ( joint, result, joint->anchor2 );
+}
+
+
+
+void dJointSetPistonAxis ( dJointID j, dReal x, dReal y, dReal z )
+{
+ dxJointPiston* joint = ( dxJointPiston* ) j;
+ dUASSERT ( joint, "bad joint argument" );
+ checktype ( joint, Piston );
+
+ setAxes ( joint, x, y, z, joint->axis1, joint->axis2 );
+
+ joint->computeInitialRelativeRotation();
+}
+
+
+void dJointSetPistonAxisDelta ( dJointID j, dReal x, dReal y, dReal z,
+ dReal dx, dReal dy, dReal dz )
+{
+ dxJointPiston* joint = ( dxJointPiston* ) j;
+ dUASSERT ( joint, "bad joint argument" );
+ checktype ( joint, Piston );
+
+ setAxes ( joint, x, y, z, joint->axis1, joint->axis2 );
+
+ joint->computeInitialRelativeRotation();
+
+ dVector3 c = {0,0,0};
+ if ( joint->node[1].body )
+ {
+ c[0] = ( joint->node[0].body->posr.pos[0] -
+ joint->node[1].body->posr.pos[0] - dx );
+ c[1] = ( joint->node[0].body->posr.pos[1] -
+ joint->node[1].body->posr.pos[1] - dy );
+ c[2] = ( joint->node[0].body->posr.pos[2] -
+ joint->node[1].body->posr.pos[2] - dz );
+ }
+ else /*if ( joint->node[0].body )*/ // -- body[0] should always be present -- there is a matrix multiplication below
+ {
+ c[0] = joint->node[0].body->posr.pos[0] - dx;
+ c[1] = joint->node[0].body->posr.pos[1] - dy;
+ c[2] = joint->node[0].body->posr.pos[2] - dz;
+ }
+
+ // Convert into frame of body 1
+ dMultiply1_331 ( joint->anchor1, joint->node[0].body->posr.R, c );
+}
+
+
+
+void dJointGetPistonAxis ( dJointID j, dVector3 result )
+{
+ dxJointPiston* joint = ( dxJointPiston* ) j;
+ dUASSERT ( joint, "bad joint argument" );
+ dUASSERT ( result, "bad result argument" );
+ checktype ( joint, Piston );
+
+ getAxis ( joint, result, joint->axis1 );
+}
+
+void dJointSetPistonParam ( dJointID j, int parameter, dReal value )
+{
+ dxJointPiston* joint = ( dxJointPiston* ) j;
+ dUASSERT ( joint, "bad joint argument" );
+ checktype ( joint, Piston );
+
+ if ( ( parameter & 0xff00 ) == 0x100 )
+ {
+ joint->limotR.set ( parameter & 0xff, value );
+ }
+ else
+ {
+ joint->limotP.set ( parameter, value );
+ }
+}
+
+
+dReal dJointGetPistonParam ( dJointID j, int parameter )
+{
+ dxJointPiston* joint = ( dxJointPiston* ) j;
+ dUASSERT ( joint, "bad joint argument" );
+ checktype ( joint, Piston );
+
+ if ( ( parameter & 0xff00 ) == 0x100 )
+ {
+ return joint->limotR.get ( parameter & 0xff );
+ }
+ else
+ {
+ return joint->limotP.get ( parameter );
+ }
+}
+
+
+void dJointAddPistonForce ( dJointID j, dReal force )
+{
+ dxJointPiston* joint = ( dxJointPiston* ) j;
+ dUASSERT ( joint, "bad joint argument" );
+ checktype ( joint, Piston );
+
+ if ( joint->flags & dJOINT_REVERSE )
+ force -= force;
+
+ dVector3 axis;
+ getAxis ( joint, axis, joint->axis1 );
+ // axis[i] *= force
+ dScaleVector3( axis, force );
+
+
+ if ( joint->node[0].body != 0 )
+ dBodyAddForce ( joint->node[0].body, axis[0], axis[1], axis[2] );
+ if ( joint->node[1].body != 0 )
+ dBodyAddForce ( joint->node[1].body, -axis[0], -axis[1], -axis[2] );
+
+ if ( joint->node[0].body != 0 && joint->node[1].body != 0 )
+ {
+ // Case where we don't need ltd since center of mass of both bodies
+ // pass by the anchor point '*' when travelling along the prismatic axis.
+ // Body_2
+ // Body_1 -----
+ // --- |-- | |
+ // | |---------------*-------------| | ---> prismatic axis
+ // --- |-- | |
+ // -----
+ // Body_2
+ // Case where we need ltd
+ // Body_1
+ // ---
+ // | |---------
+ // --- |
+ // | |--
+ // -----*----- ---> prismatic axis
+ // |-- |
+ // |
+ // |
+ // | -----
+ // | | |
+ // -------| |
+ // | |
+ // -----
+ // Body_2
+ //
+ // In real life force apply at the '*' point
+ // But in ODE the force are applied on the center of mass of Body_1 and Body_2
+ // So we have to add torques on both bodies to compensate for that when there
+ // is an offset between the anchor point and the center of mass of both bodies.
+ //
+ // We need to add to each body T = r x F
+ // Where r is the distance between the cm and '*'
+
+ dVector3 ltd; // Linear Torque Decoupling vector (a torque)
+ dVector3 c; // Distance of the body w.r.t the anchor
+ // N.B. The distance along the prismatic axis might not
+ // not be included in this variable since it won't add
+ // anything to the ltd.
+
+ // Calculate the distance of the body w.r.t the anchor
+
+ // The anchor1 of body1 can be used since:
+ // Real anchor = Position of body 1 + anchor + d* axis1 = anchor in world frame
+ // d is the position of the prismatic joint (i.e. elongation)
+ // Since axis1 x axis1 == 0
+ // We can do the following.
+ dMultiply0_331 ( c, joint->node[0].body->posr.R, joint->anchor1 );
+ dCalcVectorCross3( ltd, c, axis );
+ dBodyAddTorque ( joint->node[0].body, ltd[0], ltd[1], ltd[2] );
+
+
+ dMultiply0_331 ( c, joint->node[1].body->posr.R, joint->anchor2 );
+ dCalcVectorCross3( ltd, c, axis );
+ dBodyAddTorque ( joint->node[1].body, ltd[0], ltd[1], ltd[2] );
+ }
+}
+
+
+dJointType
+dxJointPiston::type() const
+{
+ return dJointTypePiston;
+}
+
+
+sizeint
+dxJointPiston::size() const
+{
+ return sizeof ( *this );
+}
+
+
+
+void
+dxJointPiston::setRelativeValues()
+{
+ dVector3 vec;
+ dJointGetPistonAnchor(this, vec);
+ setAnchors( this, vec[0], vec[1], vec[2], anchor1, anchor2 );
+
+ dJointGetPistonAxis(this, vec);
+ setAxes( this, vec[0], vec[1], vec[2], axis1, axis2 );
+
+ computeInitialRelativeRotation();
+}
+
+
+
+
+void
+dxJointPiston::computeInitialRelativeRotation()
+{
+ if ( node[0].body )
+ {
+ if ( node[1].body )
+ {
+ dQMultiply1 ( qrel, node[0].body->q, node[1].body->q );
+ }
+ else
+ {
+ // set joint->qrel to the transpose of the first body q
+ qrel[0] = node[0].body->q[0];
+ for ( int i = 1; i < 4; i++ )
+ qrel[i] = -node[0].body->q[i];
+ // WARNING do we need the - in -joint->node[0].body->q[i]; or not
+ }
+ }
+}
diff --git a/libs/ode-0.16.1/ode/src/joints/piston.h b/libs/ode-0.16.1/ode/src/joints/piston.h new file mode 100644 index 0000000..c202c20 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/piston.h @@ -0,0 +1,112 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_JOINT_PISTON_H_ +#define _ODE_JOINT_PISTON_H_ + +#include "joint.h" + + +//////////////////////////////////////////////////////////////////////////////// +/// Component of a Piston joint +/// <PRE> +/// |- Anchor point +/// Body_1 | Body_2 +/// +---------------+ V +------------------+ +/// / /| / /| +/// / / + |-- ______ / / + +/// / x /./........x.......(_____()..../ x /.......> axis +/// +---------------+ / |-- +------------------+ / +/// | |/ | |/ +/// +---------------+ +------------------+ +/// | | +/// | | +/// |------------------> <----------------------------| +/// anchor1 anchor2 +/// +/// +/// </PRE> +/// +/// When the prismatic joint as been elongated (i.e. dJointGetPistonPosition) +/// return a value > 0 +/// <PRE> +/// |- Anchor point +/// Body_1 | Body_2 +/// +---------------+ V +------------------+ +/// / /| / /| +/// / / + |-- ______ / / + +/// / x /./........_____x.......(_____()..../ x /.......> axis +/// +---------------+ / |-- +------------------+ / +/// | |/ | |/ +/// +---------------+ +------------------+ +/// | | +/// | | +/// |------------------> <----------------------------| +/// anchor1 |----| anchor2 +/// ^ +/// |-- This is what dJointGetPistonPosition will +/// return +/// </PRE> +//////////////////////////////////////////////////////////////////////////////// +struct dxJointPiston : public dxJoint +{ + dVector3 axis1; ///< Axis of the prismatic and rotoide w.r.t first body + dVector3 axis2; ///< Axis of the prismatic and rotoide w.r.t second body + + + dQuaternion qrel; ///< Initial relative rotation body1 -> body2 + + /// Anchor w.r.t first body. + /// This is the same as the offset for the Slider joint + /// @note To find the position of the anchor when the body 1 has moved + /// you must add the position of the prismatic joint + /// i.e anchor = R1 * anchor1 + dJointGetPistonPosition() * (R1 * axis1) + dVector3 anchor1; + dVector3 anchor2; //< anchor w.r.t second body + + /// limit and motor information for the prismatic + /// part of the joint + dxJointLimitMotor limotP; + + /// limit and motor information for the rotoide + /// part of the joint + dxJointLimitMotor limotR; + + dxJointPiston( dxWorld *w ); + virtual void getSureMaxInfo( SureMaxInfo* info ); + virtual void getInfo1( Info1* info ); + virtual void getInfo2( dReal worldFPS, dReal worldERP, + int rowskip, dReal *J1, dReal *J2, + int pairskip, dReal *pairRhsCfm, dReal *pairLoHi, + int *findex ); + virtual dJointType type() const; + virtual sizeint size() const; + + virtual void setRelativeValues(); + + void computeInitialRelativeRotation(); +}; + + + +#endif + diff --git a/libs/ode-0.16.1/ode/src/joints/plane2d.cpp b/libs/ode-0.16.1/ode/src/joints/plane2d.cpp new file mode 100644 index 0000000..0caecb3 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/plane2d.cpp @@ -0,0 +1,195 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + + +#include <ode/odeconfig.h> +#include "config.h" +#include "plane2d.h" +#include "joint_internal.h" + + + +//**************************************************************************** +// Plane2D +/* +This code is part of the Plane2D ODE joint +by psero@gmx.de +Wed Apr 23 18:53:43 CEST 2003 +*/ + + +static const dReal Midentity[3][3] = +{ + { 1, 0, 0 }, + { 0, 1, 0 }, + { 0, 0, 1, } +}; + + +dxJointPlane2D::dxJointPlane2D( dxWorld *w ) : + dxJoint( w ) +{ + motor_x.init( world ); + motor_y.init( world ); + motor_angle.init( world ); +} + + +void +dxJointPlane2D::getSureMaxInfo( SureMaxInfo* info ) +{ + info->max_m = 6; +} + + +void +dxJointPlane2D::getInfo1( dxJoint::Info1 *info ) +{ + info->nub = 3; + info->m = 3; + + if ( motor_x.fmax > 0 ) + row_motor_x = info->m++; + else + row_motor_x = 0; + + if ( motor_y.fmax > 0 ) + row_motor_y = info->m++; + else + row_motor_y = 0; + + if ( motor_angle.fmax > 0 ) + row_motor_angle = info->m++; + else + row_motor_angle = 0; +} + + + +void +dxJointPlane2D::getInfo2( dReal worldFPS, dReal worldERP, + int rowskip, dReal *J1, dReal *J2, + int pairskip, dReal *pairRhsCfm, dReal *pairLoHi, + int *findex ) +{ + dReal eps = worldFPS * worldERP; + + /* + v = v1, w = omega1 + (v2, omega2 not important (== static environment)) + + constraint equations: + vz = 0 + wx = 0 + wy = 0 + + <=> ( 0 0 1 ) (vx) ( 0 0 0 ) (wx) ( 0 ) + ( 0 0 0 ) (vy) + ( 1 0 0 ) (wy) = ( 0 ) + ( 0 0 0 ) (vz) ( 0 1 0 ) (wz) ( 0 ) + J1/J1l Omega1/J1a + */ + + // fill in linear and angular coeff. for left hand side: + + J1[GI2_JLZ] = 1; + J1[rowskip + GI2_JAX] = 1; + J1[2 * rowskip + GI2_JAY] = 1; + + // error correction (against drift): + + // a) linear vz, so that z (== pos[2]) == 0 + pairRhsCfm[GI2_RHS] = eps * -node[0].body->posr.pos[2]; + +# if 0 + // b) angular correction? -> left to application !!! + dReal *body_z_axis = &node[0].body->R[8]; + pairRhsCfm[pairskip + GI2_RHS] = eps * + atan2( body_z_axis[1], body_z_axis[2] ); // wx error + pairRhsCfm[2 * pairskip + GI2_RHS] = eps * -atan2( body_z_axis[0], body_z_axis[2] ); // wy error +# endif + + // if the slider is powered, or has joint limits, add in the extra row: + + if ( row_motor_x > 0 ) + { + int currRowSkip = row_motor_x * rowskip, currPairSkip = row_motor_x * pairskip; + motor_x.addLimot( this, worldFPS, J1 + currRowSkip, J2 + currRowSkip, pairRhsCfm + currPairSkip, pairLoHi + currPairSkip, Midentity[0], 0 ); + } + + if ( row_motor_y > 0 ) + { + int currRowSkip = row_motor_y * rowskip, currPairSkip = row_motor_y * pairskip; + motor_y.addLimot( this, worldFPS, J1 + currRowSkip, J2 + currRowSkip, pairRhsCfm + currPairSkip, pairLoHi + currPairSkip, Midentity[1], 0 ); + } + + if ( row_motor_angle > 0 ) + { + int currRowSkip = row_motor_angle * rowskip, currPairSkip = row_motor_angle * pairskip; + motor_angle.addLimot( this, worldFPS, J1 + currRowSkip, J2 + currRowSkip, pairRhsCfm + currPairSkip, pairLoHi + currPairSkip, Midentity[2], 1 ); + } +} + + +dJointType +dxJointPlane2D::type() const +{ + return dJointTypePlane2D; +} + + +sizeint +dxJointPlane2D::size() const +{ + return sizeof( *this ); +} + + + +void dJointSetPlane2DXParam( dxJoint *joint, + int parameter, dReal value ) +{ + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Plane2D ); + dxJointPlane2D* joint2d = ( dxJointPlane2D* )( joint ); + joint2d->motor_x.set( parameter, value ); +} + + +void dJointSetPlane2DYParam( dxJoint *joint, + int parameter, dReal value ) +{ + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Plane2D ); + dxJointPlane2D* joint2d = ( dxJointPlane2D* )( joint ); + joint2d->motor_y.set( parameter, value ); +} + + + +void dJointSetPlane2DAngleParam( dxJoint *joint, + int parameter, dReal value ) +{ + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Plane2D ); + dxJointPlane2D* joint2d = ( dxJointPlane2D* )( joint ); + joint2d->motor_angle.set( parameter, value ); +} + diff --git a/libs/ode-0.16.1/ode/src/joints/plane2d.h b/libs/ode-0.16.1/ode/src/joints/plane2d.h new file mode 100644 index 0000000..a9ccab6 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/plane2d.h @@ -0,0 +1,54 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_JOINT_PLANE2D_H_ +#define _ODE_JOINT_PLANE2D_H_ + +#include "joint.h" + + +// 2d joint, constrains to z == 0 + +struct dxJointPlane2D : public dxJoint +{ + int row_motor_x; + int row_motor_y; + int row_motor_angle; + dxJointLimitMotor motor_x; + dxJointLimitMotor motor_y; + dxJointLimitMotor motor_angle; + + + dxJointPlane2D( dxWorld *w ); + virtual void getSureMaxInfo( SureMaxInfo* info ); + virtual void getInfo1( Info1* info ); + virtual void getInfo2( dReal worldFPS, dReal worldERP, + int rowskip, dReal *J1, dReal *J2, + int pairskip, dReal *pairRhsCfm, dReal *pairLoHi, + int *findex ); + virtual dJointType type() const; + virtual sizeint size() const; +}; + + +#endif + diff --git a/libs/ode-0.16.1/ode/src/joints/pr.cpp b/libs/ode-0.16.1/ode/src/joints/pr.cpp new file mode 100644 index 0000000..7d34ebe --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/pr.cpp @@ -0,0 +1,613 @@ +/*************************************************************************
+ * *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
+ * All rights reserved. Email: russ@q12.org Web: www.q12.org *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of EITHER: *
+ * (1) The GNU Lesser General Public License as published by the Free *
+ * Software Foundation; either version 2.1 of the License, or (at *
+ * your option) any later version. The text of the GNU Lesser *
+ * General Public License is included with this library in the *
+ * file LICENSE.TXT. *
+ * (2) The BSD-style license that is included with this library in *
+ * the file LICENSE-BSD.TXT. *
+ * *
+ * This library 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 files *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
+ * *
+ *************************************************************************/
+
+
+#include <ode/odeconfig.h>
+#include "config.h"
+#include "pr.h"
+#include "joint_internal.h"
+
+
+
+//****************************************************************************
+// Prismatic and Rotoide
+
+dxJointPR::dxJointPR( dxWorld *w ) :
+ dxJoint( w )
+{
+ // Default Position
+ // Z^
+ // | Body 1 P R Body2
+ // |+---------+ _ _ +-----------+
+ // || |----|----(_)--------+ |
+ // |+---------+ - +-----------+
+ // |
+ // X.-----------------------------------------> Y
+ // N.B. X is comming out of the page
+ dSetZero( anchor2, 4 );
+
+ dSetZero( axisR1, 4 );
+ axisR1[0] = 1;
+ dSetZero( axisR2, 4 );
+ axisR2[0] = 1;
+
+ dSetZero( axisP1, 4 );
+ axisP1[1] = 1;
+ dSetZero( qrel, 4 );
+ dSetZero( offset, 4 );
+
+ limotR.init( world );
+ limotP.init( world );
+}
+
+
+dReal dJointGetPRPosition( dJointID j )
+{
+ dxJointPR* joint = ( dxJointPR* ) j;
+ dUASSERT( joint, "bad joint argument" );
+ checktype( joint, PR );
+
+ dVector3 q;
+ // get the offset in global coordinates
+ dMultiply0_331( q, joint->node[0].body->posr.R, joint->offset );
+
+ if ( joint->node[1].body )
+ {
+ dVector3 anchor2;
+
+ // get the anchor2 in global coordinates
+ dMultiply0_331( anchor2, joint->node[1].body->posr.R, joint->anchor2 );
+
+ q[0] = (( joint->node[0].body->posr.pos[0] + q[0] ) -
+ ( joint->node[1].body->posr.pos[0] + anchor2[0] ) );
+ q[1] = (( joint->node[0].body->posr.pos[1] + q[1] ) -
+ ( joint->node[1].body->posr.pos[1] + anchor2[1] ) );
+ q[2] = (( joint->node[0].body->posr.pos[2] + q[2] ) -
+ ( joint->node[1].body->posr.pos[2] + anchor2[2] ) );
+
+ }
+ else
+ {
+ //N.B. When there is no body 2 the joint->anchor2 is already in
+ // global coordinates
+
+ q[0] = (( joint->node[0].body->posr.pos[0] + q[0] ) -
+ ( joint->anchor2[0] ) );
+ q[1] = (( joint->node[0].body->posr.pos[1] + q[1] ) -
+ ( joint->anchor2[1] ) );
+ q[2] = (( joint->node[0].body->posr.pos[2] + q[2] ) -
+ ( joint->anchor2[2] ) );
+
+ if ( joint->flags & dJOINT_REVERSE )
+ {
+ q[0] = -q[0];
+ q[1] = -q[1];
+ q[2] = -q[2];
+ }
+ }
+
+ dVector3 axP;
+ // get prismatic axis in global coordinates
+ dMultiply0_331( axP, joint->node[0].body->posr.R, joint->axisP1 );
+
+ return dCalcVectorDot3( axP, q );
+}
+
+dReal dJointGetPRPositionRate( dJointID j )
+{
+ dxJointPR* joint = ( dxJointPR* ) j;
+ dUASSERT( joint, "bad joint argument" );
+ checktype( joint, PR );
+ // get axis1 in global coordinates
+ dVector3 ax1;
+ dMultiply0_331( ax1, joint->node[0].body->posr.R, joint->axisP1 );
+
+ if ( joint->node[1].body )
+ {
+ dVector3 lv2;
+ dBodyGetRelPointVel( joint->node[1].body, joint->anchor2[0], joint->anchor2[1], joint->anchor2[2], lv2 );
+ return dCalcVectorDot3( ax1, joint->node[0].body->lvel ) - dCalcVectorDot3( ax1, lv2 );
+ }
+ else
+ {
+ dReal rate = dCalcVectorDot3( ax1, joint->node[0].body->lvel );
+ return ( (joint->flags & dJOINT_REVERSE) ? -rate : rate);
+ }
+}
+
+
+
+dReal dJointGetPRAngle( dJointID j )
+{
+ dxJointPR* joint = ( dxJointPR* )j;
+ dAASSERT( joint );
+ checktype( joint, PR );
+ if ( joint->node[0].body )
+ {
+ dReal ang = getHingeAngle( joint->node[0].body,
+ joint->node[1].body,
+ joint->axisR1,
+ joint->qrel );
+ if ( joint->flags & dJOINT_REVERSE )
+ return -ang;
+ else
+ return ang;
+ }
+ else return 0;
+}
+
+
+
+dReal dJointGetPRAngleRate( dJointID j )
+{
+ dxJointPR* joint = ( dxJointPR* )j;
+ dAASSERT( joint );
+ checktype( joint, PR );
+ if ( joint->node[0].body )
+ {
+ dVector3 axis;
+ dMultiply0_331( axis, joint->node[0].body->posr.R, joint->axisR1 );
+ dReal rate = dCalcVectorDot3( axis, joint->node[0].body->avel );
+ if ( joint->node[1].body ) rate -= dCalcVectorDot3( axis, joint->node[1].body->avel );
+ if ( joint->flags & dJOINT_REVERSE ) rate = -rate;
+ return rate;
+ }
+ else return 0;
+}
+
+
+
+
+void
+dxJointPR::getSureMaxInfo( SureMaxInfo* info )
+{
+ info->max_m = 6;
+}
+
+
+
+void
+dxJointPR::getInfo1( dxJoint::Info1 *info )
+{
+ info->nub = 4;
+ info->m = 4;
+
+
+ // see if we're at a joint limit.
+ limotP.limit = 0;
+ if (( limotP.lostop > -dInfinity || limotP.histop < dInfinity ) &&
+ limotP.lostop <= limotP.histop )
+ {
+ // measure joint position
+ dReal pos = dJointGetPRPosition( this );
+ limotP.testRotationalLimit( pos ); // N.B. The function is ill named
+ }
+
+ // powered needs an extra constraint row
+ if ( limotP.limit || limotP.fmax > 0 ) info->m++;
+
+
+ // see if we're at a joint limit.
+ limotR.limit = 0;
+ if (( limotR.lostop >= -M_PI || limotR.histop <= M_PI ) &&
+ limotR.lostop <= limotR.histop )
+ {
+ dReal angle = getHingeAngle( node[0].body,
+ node[1].body,
+ axisR1, qrel );
+ limotR.testRotationalLimit( angle );
+ }
+
+ // powered morit or at limits needs an extra constraint row
+ if ( limotR.limit || limotR.fmax > 0 ) info->m++;
+
+}
+
+
+
+void
+dxJointPR::getInfo2( dReal worldFPS, dReal worldERP,
+ int rowskip, dReal *J1, dReal *J2,
+ int pairskip, dReal *pairRhsCfm, dReal *pairLoHi,
+ int *findex )
+{
+ dReal k = worldFPS * worldERP;
+
+
+ dVector3 q; // plane space of axP and after that axR
+
+ // pull out pos and R for both bodies. also get the `connection'
+ // vector pos2-pos1.
+
+ dReal *pos2 = NULL, *R2 = NULL;
+
+ dReal *pos1 = node[0].body->posr.pos;
+ dReal *R1 = node[0].body->posr.R;
+
+ dxBody *body1 = node[1].body;
+
+ if ( body1 )
+ {
+ pos2 = body1->posr.pos;
+ R2 = body1->posr.R;
+ }
+
+
+ dVector3 axP; // Axis of the prismatic joint in global frame
+ dMultiply0_331( axP, R1, axisP1 );
+
+ // distance between the body1 and the anchor2 in global frame
+ // Calculated in the same way as the offset
+ dVector3 wanchor2 = {0, 0, 0}, dist;
+
+ if ( body1 )
+ {
+ // Calculate anchor2 in world coordinate
+ dMultiply0_331( wanchor2, R2, anchor2 );
+ dist[0] = wanchor2[0] + pos2[0] - pos1[0];
+ dist[1] = wanchor2[1] + pos2[1] - pos1[1];
+ dist[2] = wanchor2[2] + pos2[2] - pos1[2];
+ }
+ else
+ {
+ if ( (flags & dJOINT_REVERSE) != 0 )
+ {
+ dSubtractVectors3(dist, pos1, anchor2); // Invert the value
+ }
+ else
+ {
+ dSubtractVectors3(dist, anchor2, pos1); // Invert the value
+ }
+ }
+
+
+ // ======================================================================
+ // Work on the Rotoide part (i.e. row 0, 1 and maybe 4 if rotoide powered
+
+ // Set the two rotoide rows. The rotoide axis should be the only unconstrained
+ // rotational axis, the angular velocity of the two bodies perpendicular to
+ // the rotoide axis should be equal. Thus the constraint equations are
+ // p*w1 - p*w2 = 0
+ // q*w1 - q*w2 = 0
+ // where p and q are unit vectors normal to the rotoide axis, and w1 and w2
+ // are the angular velocity vectors of the two bodies.
+ dVector3 ax2;
+ dVector3 ax1;
+ dMultiply0_331( ax1, R1, axisR1 );
+ dCalcVectorCross3( q , ax1, axP );
+
+ dCopyVector3(J1 + GI2__JA_MIN, axP);
+
+ if ( body1 )
+ {
+ dCopyNegatedVector3(J2 + GI2__JA_MIN, axP);
+ }
+
+ dCopyVector3(J1 + rowskip + GI2__JA_MIN, q);
+
+ if ( body1 )
+ {
+ dCopyNegatedVector3(J2 + rowskip + GI2__JA_MIN, q);
+ }
+
+ // Compute the right hand side of the constraint equation set. Relative
+ // body velocities along p and q to bring the rotoide back into alignment.
+ // ax1,ax2 are the unit length rotoide axes of body1 and body2 in world frame.
+ // 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.
+
+ if ( body1 )
+ {
+ dMultiply0_331( ax2, R2, axisR2 );
+ }
+ else
+ {
+ dCopyVector3(ax2, axisR2);
+ }
+
+ dVector3 b;
+ dCalcVectorCross3( b, ax1, ax2 );
+ pairRhsCfm[GI2_RHS] = k * dCalcVectorDot3( b, axP );
+ pairRhsCfm[pairskip + GI2_RHS] = k * dCalcVectorDot3( b, q );
+
+
+
+ // ==========================
+ // Work on the Prismatic part (i.e row 2,3 and 4 if only the prismatic is powered
+ // or 5 if rotoide and prismatic powered
+
+ // two rows. we want: vel2 = vel1 + w1 x c ... but this would
+ // result in three equations, so we project along the planespace vectors
+ // so that sliding along the prismatic axis is disregarded. for symmetry we
+ // also substitute (w1+w2)/2 for w1, as w1 is supposed to equal w2.
+
+ // p1 + R1 dist' = p2 + R2 anchor2' ## OLD ## p1 + R1 anchor1' = p2 + R2 dist'
+ // v1 + w1 x R1 dist' + v_p = v2 + w2 x R2 anchor2'## OLD v1 + w1 x R1 anchor1' = v2 + w2 x R2 dist' + v_p
+ // v_p is speed of prismatic joint (i.e. elongation rate)
+ // Since the constraints are perpendicular to v_p we have:
+ // p dot v_p = 0 and q dot v_p = 0
+ // ax1 dot ( v1 + w1 x dist = v2 + w2 x anchor2 )
+ // q dot ( v1 + w1 x dist = v2 + w2 x anchor2 )
+ // ==
+ // ax1 . v1 + ax1 . w1 x dist = ax1 . v2 + ax1 . w2 x anchor2 ## OLD ## ax1 . v1 + ax1 . w1 x anchor1 = ax1 . v2 + ax1 . w2 x dist
+ // since a . (b x c) = - b . (a x c) = - (a x c) . b
+ // and a x b = - b x a
+ // ax1 . v1 - ax1 x dist . w1 - ax1 . v2 - (- ax1 x anchor2 . w2) = 0
+ // ax1 . v1 + dist x ax1 . w1 - ax1 . v2 - anchor2 x ax1 . w2 = 0
+ // Coeff for 1er line of: J1l => ax1, J2l => -ax1
+ // Coeff for 2er line of: J1l => q, J2l => -q
+ // Coeff for 1er line of: J1a => dist x ax1, J2a => - anchor2 x ax1
+ // Coeff for 2er line of: J1a => dist x q, J2a => - anchor2 x q
+
+ int currRowSkip = 2 * rowskip;
+ {
+ dCopyVector3( J1 + currRowSkip + GI2__JL_MIN, ax1 );
+ dCalcVectorCross3( J1 + currRowSkip + GI2__JA_MIN, dist, ax1 );
+
+ if ( body1 )
+ {
+ dCopyNegatedVector3( J2 + currRowSkip + GI2__JL_MIN, ax1 );
+ // ax2 x anchor2 instead of anchor2 x ax2 since we want the negative value
+ dCalcVectorCross3( J2 + currRowSkip + GI2__JA_MIN, ax2, wanchor2 ); // since ax1 == ax2
+ }
+ }
+
+ currRowSkip += rowskip;
+ {
+ dCopyVector3( J1 + currRowSkip + GI2__JL_MIN, q );
+ dCalcVectorCross3(J1 + currRowSkip + GI2__JA_MIN, dist, q );
+
+ if ( body1 )
+ {
+ dCopyNegatedVector3( J2 + currRowSkip + GI2__JL_MIN, q);
+ // The cross product is in reverse order since we want the negative value
+ dCalcVectorCross3( J2 + currRowSkip + GI2__JA_MIN, q, wanchor2 );
+ }
+ }
+
+ // We want to make correction for motion not in the line of the axisP
+ // We calculate the displacement w.r.t. the anchor pt.
+ //
+ // compute the elements 2 and 3 of right hand side.
+ // we want to align the offset point (in body 2's frame) with the center of body 1.
+ // The position should be the same when we are not along the prismatic axis
+ dVector3 err;
+ dMultiply0_331( err, R1, offset );
+ dSubtractVectors3(err, dist, err);
+
+ int currPairSkip = 2 * pairskip;
+ {
+ pairRhsCfm[currPairSkip + GI2_RHS] = k * dCalcVectorDot3( ax1, err );
+ }
+
+ currPairSkip += pairskip;
+ {
+ pairRhsCfm[currPairSkip + GI2_RHS] = k * dCalcVectorDot3( q, err );
+ }
+
+ currRowSkip += rowskip; currPairSkip += pairskip;
+
+ if ( body1 || (flags & dJOINT_REVERSE) == 0 )
+ {
+ if (limotP.addLimot ( this, worldFPS, J1 + currRowSkip, J2 + currRowSkip, pairRhsCfm + currPairSkip, pairLoHi + currPairSkip, axP, 0 ))
+ {
+ currRowSkip += rowskip; currPairSkip += pairskip;
+ }
+ }
+ else
+ {
+ dVector3 rAxP;
+ dCopyNegatedVector3(rAxP, axP);
+
+ if (limotP.addLimot ( this, worldFPS, J1 + currRowSkip, J2 + currRowSkip, pairRhsCfm + currPairSkip, pairLoHi + currPairSkip, rAxP, 0 ))
+ {
+ currRowSkip += rowskip; currPairSkip += pairskip;
+ }
+ }
+
+ limotR.addLimot ( this, worldFPS, J1 + currRowSkip, J2 + currRowSkip, pairRhsCfm + currPairSkip, pairLoHi + currPairSkip, ax1, 1 );
+}
+
+
+// compute initial relative rotation body1 -> body2, or env -> body1
+void
+dxJointPR::computeInitialRelativeRotation()
+{
+ if ( node[0].body )
+ {
+ if ( node[1].body )
+ {
+ dQMultiply1( qrel, node[0].body->q, node[1].body->q );
+ }
+ else
+ {
+ // set joint->qrel to the transpose of the first body q
+ qrel[0] = node[0].body->q[0];
+ for ( int i = 1; i < 4; i++ )
+ qrel[i] = -node[0].body->q[i];
+ // WARNING do we need the - in -joint->node[0].body->q[i]; or not
+ }
+ }
+}
+
+void dJointSetPRAnchor( dJointID j, dReal x, dReal y, dReal z )
+{
+ dxJointPR* joint = ( dxJointPR* ) j;
+ dUASSERT( joint, "bad joint argument" );
+ checktype( joint, PR );
+ setAnchors( joint, x, y, z, joint->offset, joint->anchor2 );
+}
+
+
+void dJointSetPRAxis1( dJointID j, dReal x, dReal y, dReal z )
+{
+ dxJointPR* joint = ( dxJointPR* ) j;
+ dUASSERT( joint, "bad joint argument" );
+ checktype( joint, PR );
+
+ setAxes( joint, x, y, z, joint->axisP1, 0 );
+
+ joint->computeInitialRelativeRotation();
+}
+
+
+void dJointSetPRAxis2( dJointID j, dReal x, dReal y, dReal z )
+{
+ dxJointPR* joint = ( dxJointPR* ) j;
+ dUASSERT( joint, "bad joint argument" );
+ checktype( joint, PR );
+ setAxes( joint, x, y, z, joint->axisR1, joint->axisR2 );
+ joint->computeInitialRelativeRotation();
+}
+
+
+void dJointSetPRParam( dJointID j, int parameter, dReal value )
+{
+ dxJointPR* joint = ( dxJointPR* ) j;
+ dUASSERT( joint, "bad joint argument" );
+ checktype( joint, PR );
+ if (( parameter & 0xff00 ) == 0x100 )
+ {
+ joint->limotR.set( parameter & 0xff, value ); // Take only lower part of the
+ } // parameter alue
+ else
+ {
+ joint->limotP.set( parameter, value );
+ }
+}
+
+void dJointGetPRAnchor( dJointID j, dVector3 result )
+{
+ dxJointPR* joint = ( dxJointPR* ) j;
+ dUASSERT( joint, "bad joint argument" );
+ dUASSERT( result, "bad result argument" );
+ checktype( joint, PR );
+
+ if ( joint->node[1].body )
+ getAnchor2( joint, result, joint->anchor2 );
+ else
+ {
+ result[0] = joint->anchor2[0];
+ result[1] = joint->anchor2[1];
+ result[2] = joint->anchor2[2];
+ }
+}
+
+void dJointGetPRAxis1( dJointID j, dVector3 result )
+{
+ dxJointPR* joint = ( dxJointPR* ) j;
+ dUASSERT( joint, "bad joint argument" );
+ dUASSERT( result, "bad result argument" );
+ checktype( joint, PR );
+ getAxis( joint, result, joint->axisP1 );
+}
+
+void dJointGetPRAxis2( dJointID j, dVector3 result )
+{
+ dxJointPR* joint = ( dxJointPR* ) j;
+ dUASSERT( joint, "bad joint argument" );
+ dUASSERT( result, "bad result argument" );
+ checktype( joint, PR );
+ getAxis( joint, result, joint->axisR1 );
+}
+
+dReal dJointGetPRParam( dJointID j, int parameter )
+{
+ dxJointPR* joint = ( dxJointPR* ) j;
+ dUASSERT( joint, "bad joint argument" );
+ checktype( joint, PR );
+ if (( parameter & 0xff00 ) == 0x100 )
+ {
+ return joint->limotR.get( parameter & 0xff );
+ }
+ else
+ {
+ return joint->limotP.get( parameter );
+ }
+}
+
+void dJointAddPRTorque( dJointID j, dReal torque )
+{
+ dxJointPR* joint = ( dxJointPR* ) j;
+ dVector3 axis;
+ dAASSERT( joint );
+ checktype( joint, PR );
+
+ if ( joint->flags & dJOINT_REVERSE )
+ torque = -torque;
+
+ getAxis( joint, axis, joint->axisR1 );
+ axis[0] *= torque;
+ axis[1] *= torque;
+ axis[2] *= torque;
+
+ if ( joint->node[0].body != 0 )
+ dBodyAddTorque( joint->node[0].body, axis[0], axis[1], axis[2] );
+ if ( joint->node[1].body != 0 )
+ dBodyAddTorque( joint->node[1].body, -axis[0], -axis[1], -axis[2] );
+}
+
+
+dJointType
+dxJointPR::type() const
+{
+ return dJointTypePR;
+}
+
+sizeint
+dxJointPR::size() const
+{
+ return sizeof( *this );
+}
+
+
+void
+dxJointPR::setRelativeValues()
+{
+ dVector3 anchor;
+ dJointGetPRAnchor(this, anchor);
+ setAnchors( this, anchor[0], anchor[1], anchor[2], offset, anchor2 );
+
+ dVector3 axis;
+ dJointGetPRAxis1(this, axis);
+ setAxes( this, axis[0], axis[1], axis[2], axisP1, 0 );
+
+ dJointGetPRAxis2(this, axis);
+ setAxes( this, axis[0], axis[1], axis[2], axisR1, axisR2 );
+
+ computeInitialRelativeRotation();
+}
+
+
+
+
+
diff --git a/libs/ode-0.16.1/ode/src/joints/pr.h b/libs/ode-0.16.1/ode/src/joints/pr.h new file mode 100644 index 0000000..930c0cd --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/pr.h @@ -0,0 +1,100 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_JOINT_PR_H_ +#define _ODE_JOINT_PR_H_ + +#include "joint.h" + + + +/** + * The axisP must be perpendicular to axis2 + * <PRE> + * +-------------+ + * | x | + * +------------\+ + * Prismatic articulation .. .. + * | .. .. + * \/ .. .. + * +--------------+ --| __.. .. anchor2 + * | x | .....|.......(__) .. + * +--------------+ --| ^ < + * |----------------------->| + * Offset |--- Rotoide articulation + * </PRE> + */ +struct dxJointPR : public dxJoint +{ + + /// @brief Position of the rotoide articulation w.r.t second body. + /// @note Position of body 2 in world frame + anchor2 in world frame give + /// the position of the rotoide articulation + dVector3 anchor2; + + + /// axis of the rotoide articulation w.r.t first body. + /// @note This is considered as axis1 from the parameter view. + dVector3 axisR1; + + /// axis of the rotoide articulation w.r.t second body. + /// @note This is considered also as axis1 from the parameter view + dVector3 axisR2; + + /// axis for the prismatic articulation w.r.t first body. + /// @note This is considered as axis2 in from the parameter view + dVector3 axisP1; + + + dQuaternion qrel; ///< initial relative rotation body1 -> body2. + + + /// @brief vector between the body1 and the rotoide articulation. + /// + /// Going from the first to the second in the frame of body1. + /// That should be aligned with body1 center along axisP. + /// This is calculated when the axis are set. + dVector3 offset; + dxJointLimitMotor limotR; ///< limit and motor information for the rotoide articulation. + dxJointLimitMotor limotP; ///< limit and motor information for the prismatic articulation. + + + void computeInitialRelativeRotation(); + + + dxJointPR( dxWorld *w ); + virtual void getSureMaxInfo( SureMaxInfo* info ); + virtual void getInfo1( Info1* info ); + virtual void getInfo2( dReal worldFPS, dReal worldERP, + int rowskip, dReal *J1, dReal *J2, + int pairskip, dReal *pairRhsCfm, dReal *pairLoHi, + int *findex ); + virtual dJointType type() const; + virtual sizeint size() const; + + virtual void setRelativeValues(); +}; + + + +#endif + diff --git a/libs/ode-0.16.1/ode/src/joints/pu.cpp b/libs/ode-0.16.1/ode/src/joints/pu.cpp new file mode 100644 index 0000000..42eaf4b --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/pu.cpp @@ -0,0 +1,756 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + + +#include <ode/odeconfig.h> +#include "config.h" +#include "pu.h" +#include "joint_internal.h" + + +//**************************************************************************** +// Prismatic and Universal + +dxJointPU::dxJointPU( dxWorld *w ) : + dxJointUniversal( w ) +{ + // Default Position + // Y ^ Axis2 + // ^ | + // / | ^ Axis1 + // Z^ / | / + // | / Body 2 | / Body 1 + // | / +---------+ | / +-----------+ + // | / / /| | / / /| + // | / / / + _/ - / / + + // | / / /-/--------(_)----|--- /-----------/-------> AxisP + // | / +---------+ / - +-----------+ / + // | / | |/ | |/ + // | / +---------+ +-----------+ + // |/ + // .-----------------------------------------> X + // |-----------------> + // Anchor2 <--------------| + // Anchor1 + // + + // Setting member variables which are w.r.t body2 + dSetZero( axis1, 4 ); + axis1[1] = 1; + + // Setting member variables which are w.r.t body2 + dSetZero( anchor2, 4 ); + dSetZero( axis2, 4 ); + axis2[2] = 1; + + dSetZero( axisP1, 4 ); + axisP1[0] = 1; + + dSetZero( qrel1, 4 ); + dSetZero( qrel2, 4 ); + + + limotP.init( world ); + limot1.init( world ); + limot2.init( world ); +} + + +dReal dJointGetPUPosition( dJointID j ) +{ + dxJointPU* joint = ( dxJointPU* ) j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, PU ); + + dVector3 q; + // get the offset in global coordinates + dMultiply0_331( q, joint->node[0].body->posr.R, joint->anchor1 ); + + if ( joint->node[1].body ) + { + dVector3 anchor2; + + // get the anchor2 in global coordinates + dMultiply0_331( anchor2, joint->node[1].body->posr.R, joint->anchor2 ); + + q[0] = (( joint->node[0].body->posr.pos[0] + q[0] ) - + ( joint->node[1].body->posr.pos[0] + anchor2[0] ) ); + q[1] = (( joint->node[0].body->posr.pos[1] + q[1] ) - + ( joint->node[1].body->posr.pos[1] + anchor2[1] ) ); + q[2] = (( joint->node[0].body->posr.pos[2] + q[2] ) - + ( joint->node[1].body->posr.pos[2] + anchor2[2] ) ); + } + else + { + //N.B. When there is no body 2 the joint->anchor2 is already in + // global coordinates + + q[0] = (( joint->node[0].body->posr.pos[0] + q[0] ) - + ( joint->anchor2[0] ) ); + q[1] = (( joint->node[0].body->posr.pos[1] + q[1] ) - + ( joint->anchor2[1] ) ); + q[2] = (( joint->node[0].body->posr.pos[2] + q[2] ) - + ( joint->anchor2[2] ) ); + + if ( joint->flags & dJOINT_REVERSE ) + { + q[0] = -q[0]; + q[1] = -q[1]; + q[2] = -q[2]; + } + } + + dVector3 axP; + // get prismatic axis in global coordinates + dMultiply0_331( axP, joint->node[0].body->posr.R, joint->axisP1 ); + + return dCalcVectorDot3( axP, q ); +} + + +dReal dJointGetPUPositionRate( dJointID j ) +{ + dxJointPU* joint = ( dxJointPU* ) j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, PU ); + + if ( joint->node[0].body ) + { + // We want to find the rate of change of the prismatic part of the joint + // We can find it by looking at the speed difference between body1 and the + // anchor point. + + // r will be used to find the distance between body1 and the anchor point + dVector3 r; + dVector3 anchor2 = {0,0,0}; + if ( joint->node[1].body ) + { + // Find joint->anchor2 in global coordinates + dMultiply0_331( anchor2, joint->node[1].body->posr.R, joint->anchor2 ); + + r[0] = ( joint->node[0].body->posr.pos[0] - + ( anchor2[0] + joint->node[1].body->posr.pos[0] ) ); + r[1] = ( joint->node[0].body->posr.pos[1] - + ( anchor2[1] + joint->node[1].body->posr.pos[1] ) ); + r[2] = ( joint->node[0].body->posr.pos[2] - + ( anchor2[2] + joint->node[1].body->posr.pos[2] ) ); + } + else + { + //N.B. When there is no body 2 the joint->anchor2 is already in + // global coordinates + // r = joint->node[0].body->posr.pos - joint->anchor2; + dSubtractVectors3( r, joint->node[0].body->posr.pos, joint->anchor2 ); + } + + // The body1 can have velocity coming from the rotation of + // the rotoide axis. We need to remove this. + + // N.B. We do vel = r X w instead of vel = w x r to have vel negative + // since we want to remove it from the linear velocity of the body + dVector3 lvel1; + dCalcVectorCross3( lvel1, r, joint->node[0].body->avel ); + + // lvel1 += joint->node[0].body->lvel; + dAddVectors3( lvel1, lvel1, joint->node[0].body->lvel ); + + // Since we want rate of change along the prismatic axis + // get axisP1 in global coordinates and get the component + // along this axis only + dVector3 axP1; + dMultiply0_331( axP1, joint->node[0].body->posr.R, joint->axisP1 ); + + if ( joint->node[1].body ) + { + // Find the contribution of the angular rotation to the linear speed + // N.B. We do vel = r X w instead of vel = w x r to have vel negative + // since we want to remove it from the linear velocity of the body + dVector3 lvel2; + dCalcVectorCross3( lvel2, anchor2, joint->node[1].body->avel ); + + // lvel1 -= lvel2 + joint->node[1].body->lvel; + dVector3 tmp; + dAddVectors3( tmp, lvel2, joint->node[1].body->lvel ); + dSubtractVectors3( lvel1, lvel1, tmp ); + + return dCalcVectorDot3( axP1, lvel1 ); + } + else + { + dReal rate = dCalcVectorDot3( axP1, lvel1 ); + return ( (joint->flags & dJOINT_REVERSE) ? -rate : rate); + } + } + + return 0.0; +} + + + +void +dxJointPU::getSureMaxInfo( SureMaxInfo* info ) +{ + info->max_m = 6; +} + + + +void +dxJointPU::getInfo1( dxJoint::Info1 *info ) +{ + info->m = 3; + info->nub = 3; + + // powered needs an extra constraint row + + // see if we're at a joint limit. + limotP.limit = 0; + if (( limotP.lostop > -dInfinity || limotP.histop < dInfinity ) && + limotP.lostop <= limotP.histop ) + { + // measure joint position + dReal pos = dJointGetPUPosition( this ); + limotP.testRotationalLimit( pos ); // N.B. The function is ill named + } + + if ( limotP.limit || limotP.fmax > 0 ) info->m++; + + + bool limiting1 = ( limot1.lostop >= -M_PI || limot1.histop <= M_PI ) && + limot1.lostop <= limot1.histop; + bool limiting2 = ( limot2.lostop >= -M_PI || limot2.histop <= M_PI ) && + limot2.lostop <= limot2.histop; + + // We need to call testRotationLimit() even if we're motored, since it + // records the result. + limot1.limit = 0; + limot2.limit = 0; + if ( limiting1 || limiting2 ) + { + dReal angle1, angle2; + getAngles( &angle1, &angle2 ); + if ( limiting1 ) + limot1.testRotationalLimit( angle1 ); + if ( limiting2 ) + limot2.testRotationalLimit( angle2 ); + } + + if ( limot1.limit || limot1.fmax > 0 ) info->m++; + if ( limot2.limit || limot2.fmax > 0 ) info->m++; +} + + + +void +dxJointPU::getInfo2( dReal worldFPS, dReal worldERP, + int rowskip, dReal *J1, dReal *J2, + int pairskip, dReal *pairRhsCfm, dReal *pairLoHi, + int *findex ) +{ + const dReal k = worldFPS * worldERP; + + // ====================================================================== + // The angular constraint + // + dVector3 ax1, ax2; // Global axes of rotation + getAxis(this, ax1, axis1); + getAxis2(this,ax2, axis2); + + dVector3 uniPerp; // Axis perpendicular to axes of rotation + dCalcVectorCross3(uniPerp,ax1,ax2); + dNormalize3( uniPerp ); + + dCopyVector3( J1 + GI2__JA_MIN, uniPerp ); + + dxBody *body1 = node[1].body; + + if ( body1 ) { + dCopyNegatedVector3( J2 + GI2__JA_MIN , uniPerp ); + } + // Corrective velocity attempting to keep uni axes perpendicular + dReal val = dCalcVectorDot3( ax1, ax2 ); + // Small angle approximation : + // theta = asin(val) + // theta is approximately val when val is near zero. + pairRhsCfm[GI2_RHS] = -k * val; + + // ========================================================================== + // Handle axes orthogonal to the prismatic + dVector3 an1, an2; // Global anchor positions + dVector3 axP, sep; // Prismatic axis and separation vector + getAnchor(this, an1, anchor1); + getAnchor2(this, an2, anchor2); + + if (flags & dJOINT_REVERSE) { + getAxis2(this, axP, axisP1); + } else { + getAxis(this, axP, axisP1); + } + dSubtractVectors3(sep, an2, an1); + + dVector3 p, q; + dPlaneSpace(axP, p, q); + + dCopyVector3( J1 + rowskip + GI2__JL_MIN, p ); + dCopyVector3( J1 + 2 * rowskip + GI2__JL_MIN, q ); + // Make the anchors be body local + // Aliasing isn't a problem here. + dSubtractVectors3(an1, an1, node[0].body->posr.pos); + dCalcVectorCross3( J1 + rowskip + GI2__JA_MIN, an1, p ); + dCalcVectorCross3( J1 + 2 * rowskip + GI2__JA_MIN, an1, q ); + + if (body1) { + dCopyNegatedVector3( J2 + rowskip + GI2__JL_MIN, p ); + dCopyNegatedVector3( J2 + 2 * rowskip + GI2__JL_MIN, q ); + dSubtractVectors3(an2, an2, body1->posr.pos); + dCalcVectorCross3( J2 + rowskip + GI2__JA_MIN, p, an2 ); + dCalcVectorCross3( J2 + 2 * rowskip + GI2__JA_MIN, q, an2 ); + } + + pairRhsCfm[pairskip + GI2_RHS] = k * dCalcVectorDot3( p, sep ); + pairRhsCfm[2 * pairskip + GI2_RHS] = k * dCalcVectorDot3( q, sep ); + + // ========================================================================== + // Handle the limits/motors + int currRowSkip = 3 * rowskip, currPairSkip = 3 * pairskip; + + if (limot1.addLimot( this, worldFPS, J1 + currRowSkip, J2 + currRowSkip, pairRhsCfm + currPairSkip, pairLoHi + currPairSkip, ax1, 1 )) { + currRowSkip += rowskip; currPairSkip += pairskip; + } + + if (limot2.addLimot( this, worldFPS, J1 + currRowSkip, J2 + currRowSkip, pairRhsCfm + currPairSkip, pairLoHi + currPairSkip, ax2, 1 )) { + currRowSkip += rowskip; currPairSkip += pairskip; + } + + if ( body1 || (flags & dJOINT_REVERSE) == 0 ) { + limotP.addTwoPointLimot( this, worldFPS, J1 + currRowSkip, J2 + currRowSkip, pairRhsCfm + currPairSkip, pairLoHi + currPairSkip, axP, an1, an2 ); + } else { + dNegateVector3(axP); + limotP.addTwoPointLimot ( this, worldFPS, J1 + currRowSkip, J2 + currRowSkip, pairRhsCfm + currPairSkip, pairLoHi + currPairSkip, axP, an1, an2 ); + } +} + +void dJointSetPUAnchor( dJointID j, dReal x, dReal y, dReal z ) +{ + dxJointPU* joint = ( dxJointPU* ) j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, PU ); + setAnchors( joint, x, y, z, joint->anchor1, joint->anchor2 ); + joint->computeInitialRelativeRotations(); +} + +/** + * This function initialize the anchor and the relative position of each body + * as if body2 was at its current position + [dx,dy,dy]. + * Ex: + * <PRE> + * dReal offset = 1; + * dVector3 dir; + * dJointGetPUAxis3(jId, dir); + * dJointSetPUAnchor(jId, 0, 0, 0); + * // If you request the position you will have: dJointGetPUPosition(jId) == 0 + * dJointSetPUAnchorDelta(jId, 0, 0, 0, dir[X]*offset, dir[Y]*offset, dir[Z]*offset); + * // If you request the position you will have: dJointGetPUPosition(jId) == -offset + * </PRE> + + * @param j The PU joint for which the anchor point will be set + * @param x The X position of the anchor point in world frame + * @param y The Y position of the anchor point in world frame + * @param z The Z position of the anchor point in world frame + * @param dx A delta to be added to the X position as if the anchor was set + * when body1 was at current_position[X] + dx + * @param dx A delta to be added to the Y position as if the anchor was set + * when body1 was at current_position[Y] + dy + * @param dx A delta to be added to the Z position as if the anchor was set + * when body1 was at current_position[Z] + dz + * @note Should have the same meaning as dJointSetSliderAxisDelta + */ +void dJointSetPUAnchorDelta( dJointID j, dReal x, dReal y, dReal z, + dReal dx, dReal dy, dReal dz ) +{ + dxJointPU* joint = ( dxJointPU* ) j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, PU ); + + if ( joint->node[0].body ) + { + joint->node[0].body->posr.pos[0] += dx; + joint->node[0].body->posr.pos[1] += dy; + joint->node[0].body->posr.pos[2] += dz; + } + + setAnchors( joint, x, y, z, joint->anchor1, joint->anchor2 ); + + if ( joint->node[0].body ) + { + joint->node[0].body->posr.pos[0] -= dx; + joint->node[0].body->posr.pos[1] -= dy; + joint->node[0].body->posr.pos[2] -= dz; + } + + joint->computeInitialRelativeRotations(); +} + +/** + * \brief This function initialize the anchor and the relative position of each body + * such that dJointGetPUPosition will return the dot product of axis and [dx,dy,dy]. + * + * The body 1 is moved to [-dx, -dy, -dx] then the anchor is set. This will be the + * position 0 for the prismatic part of the joint. Then the body 1 is moved to its + * original position. + * + * Ex: + * <PRE> + * dReal offset = 1; + * dVector3 dir; + * dJointGetPUAxis3(jId, dir); + * dJointSetPUAnchor(jId, 0, 0, 0); + * // If you request the position you will have: dJointGetPUPosition(jId) == 0 + * dJointSetPUAnchorDelta(jId, 0, 0, 0, dir[X]*offset, dir[Y]*offset, dir[Z]*offset); + * // If you request the position you will have: dJointGetPUPosition(jId) == offset + * </PRE> + + * @param j The PU joint for which the anchor point will be set + * @param x The X position of the anchor point in world frame + * @param y The Y position of the anchor point in world frame + * @param z The Z position of the anchor point in world frame + * @param dx A delta to be added to the X position as if the anchor was set + * when body1 was at current_position[X] + dx + * @param dx A delta to be added to the Y position as if the anchor was set + * when body1 was at current_position[Y] + dy + * @param dx A delta to be added to the Z position as if the anchor was set + * when body1 was at current_position[Z] + dz + * @note Should have the same meaning as dJointSetSliderAxisDelta + */ +void dJointSetPUAnchorOffset( dJointID j, dReal x, dReal y, dReal z, + dReal dx, dReal dy, dReal dz ) +{ + dxJointPU* joint = ( dxJointPU* ) j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, PU ); + + if (joint->flags & dJOINT_REVERSE) + { + dx = -dx; + dy = -dy; + dz = -dz; + } + + if ( joint->node[0].body ) + { + joint->node[0].body->posr.pos[0] -= dx; + joint->node[0].body->posr.pos[1] -= dy; + joint->node[0].body->posr.pos[2] -= dz; + } + + setAnchors( joint, x, y, z, joint->anchor1, joint->anchor2 ); + + if ( joint->node[0].body ) + { + joint->node[0].body->posr.pos[0] += dx; + joint->node[0].body->posr.pos[1] += dy; + joint->node[0].body->posr.pos[2] += dz; + } + + joint->computeInitialRelativeRotations(); +} + + + + + +void dJointSetPUAxis1( dJointID j, dReal x, dReal y, dReal z ) +{ + dxJointPU* joint = ( dxJointPU* ) j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, PU ); + if ( joint->flags & dJOINT_REVERSE ) + setAxes( joint, x, y, z, NULL, joint->axis2 ); + else + setAxes( joint, x, y, z, joint->axis1, NULL ); + joint->computeInitialRelativeRotations(); +} + +void dJointSetPUAxis2( dJointID j, dReal x, dReal y, dReal z ) +{ + dxJointPU* joint = ( dxJointPU* ) j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, PU ); + if ( joint->flags & dJOINT_REVERSE ) + setAxes( joint, x, y, z, joint->axis1, NULL ); + else + setAxes( joint, x, y, z, NULL, joint->axis2 ); + joint->computeInitialRelativeRotations(); +} + + +void dJointSetPUAxisP( dJointID id, dReal x, dReal y, dReal z ) +{ + dJointSetPUAxis3( id, x, y, z ); +} + + + +void dJointSetPUAxis3( dJointID j, dReal x, dReal y, dReal z ) +{ + dxJointPU* joint = ( dxJointPU* ) j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, PU ); + + setAxes( joint, x, y, z, joint->axisP1, 0 ); + + joint->computeInitialRelativeRotations(); +} + + + + +void dJointGetPUAngles( dJointID j, dReal *angle1, dReal *angle2 ) +{ + dxJointUniversal* joint = ( dxJointUniversal* ) j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, PU ); + if ( joint->flags & dJOINT_REVERSE ) + joint->getAngles( angle2, angle1 ); + else + joint->getAngles( angle1, angle2 ); +} + + +dReal dJointGetPUAngle1( dJointID j ) +{ + dxJointUniversal* joint = ( dxJointUniversal* ) j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, PU ); + if ( joint->flags & dJOINT_REVERSE ) + return joint->getAngle2(); + else + return joint->getAngle1(); +} + + +dReal dJointGetPUAngle2( dJointID j ) +{ + dxJointUniversal* joint = ( dxJointUniversal* ) j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, PU ); + if ( joint->flags & dJOINT_REVERSE ) + return joint->getAngle1(); + else + return joint->getAngle2(); +} + + +dReal dJointGetPUAngle1Rate( dJointID j ) +{ + dxJointPU* joint = ( dxJointPU* ) j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, PU ); + + if ( joint->node[0].body ) + { + dVector3 axis; + + if ( joint->flags & dJOINT_REVERSE ) + getAxis2( joint, axis, joint->axis2 ); + else + getAxis( joint, axis, joint->axis1 ); + + dReal rate = dCalcVectorDot3( axis, joint->node[0].body->avel ); + if ( joint->node[1].body ) rate -= dCalcVectorDot3( axis, joint->node[1].body->avel ); + return rate; + } + return 0; +} + + +dReal dJointGetPUAngle2Rate( dJointID j ) +{ + dxJointPU* joint = ( dxJointPU* ) j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, PU ); + + if ( joint->node[0].body ) + { + dVector3 axis; + + if ( joint->flags & dJOINT_REVERSE ) + getAxis( joint, axis, joint->axis1 ); + else + getAxis2( joint, axis, joint->axis2 ); + + dReal rate = dCalcVectorDot3( axis, joint->node[0].body->avel ); + if ( joint->node[1].body ) rate -= dCalcVectorDot3( axis, joint->node[1].body->avel ); + return rate; + } + return 0; +} + + +void dJointSetPUParam( dJointID j, int parameter, dReal value ) +{ + dxJointPU* joint = ( dxJointPU* ) j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, PU ); + + switch ( parameter & 0xff00 ) + { + case dParamGroup1: + joint->limot1.set( parameter, value ); + break; + case dParamGroup2: + joint->limot2.set( parameter & 0xff, value ); + break; + case dParamGroup3: + joint->limotP.set( parameter & 0xff, value ); + break; + } +} + +void dJointGetPUAnchor( dJointID j, dVector3 result ) +{ + dxJointPU* joint = ( dxJointPU* ) j; + dUASSERT( joint, "bad joint argument" ); + dUASSERT( result, "bad result argument" ); + checktype( joint, PU ); + + if ( joint->node[1].body ) + getAnchor2( joint, result, joint->anchor2 ); + else + { + // result[i] = joint->anchor2[i]; + dCopyVector3( result, joint->anchor2 ); + } +} + +void dJointGetPUAxis1( dJointID j, dVector3 result ) +{ + dxJointPU* joint = ( dxJointPU* ) j; + dUASSERT( joint, "bad joint argument" ); + dUASSERT( result, "bad result argument" ); + checktype( joint, PU ); + if ( joint->flags & dJOINT_REVERSE ) + getAxis2( joint, result, joint->axis2 ); + else + getAxis( joint, result, joint->axis1 ); +} + +void dJointGetPUAxis2( dJointID j, dVector3 result ) +{ + dxJointPU* joint = ( dxJointPU* ) j; + dUASSERT( joint, "bad joint argument" ); + dUASSERT( result, "bad result argument" ); + checktype( joint, PU ); + if ( joint->flags & dJOINT_REVERSE ) + getAxis( joint, result, joint->axis1 ); + else + getAxis2( joint, result, joint->axis2 ); +} + +/** + * @brief Get the prismatic axis + * @ingroup joints + * + * @note This function was added for convenience it is the same as + * dJointGetPUAxis3 + */ +void dJointGetPUAxisP( dJointID id, dVector3 result ) +{ + dJointGetPUAxis3( id, result ); +} + + +void dJointGetPUAxis3( dJointID j, dVector3 result ) +{ + dxJointPU* joint = ( dxJointPU* ) j; + dUASSERT( joint, "bad joint argument" ); + dUASSERT( result, "bad result argument" ); + checktype( joint, PU ); + getAxis( joint, result, joint->axisP1 ); +} + +dReal dJointGetPUParam( dJointID j, int parameter ) +{ + dxJointPU* joint = ( dxJointPU* ) j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, PU ); + + switch ( parameter & 0xff00 ) + { + case dParamGroup1: + return joint->limot1.get( parameter ); + break; + case dParamGroup2: + return joint->limot2.get( parameter & 0xff ); + break; + case dParamGroup3: + return joint->limotP.get( parameter & 0xff ); + break; + } + + return 0; +} + + +dJointType +dxJointPU::type() const +{ + return dJointTypePU; +} + + +sizeint +dxJointPU::size() const +{ + return sizeof( *this ); +} + + +void +dxJointPU::setRelativeValues() +{ + dVector3 anchor; + dJointGetPUAnchor(this, anchor); + setAnchors( this, anchor[0], anchor[1], anchor[2], anchor1, anchor2 ); + + dVector3 ax1, ax2, ax3; + dJointGetPUAxis1(this, ax1); + dJointGetPUAxis2(this, ax2); + dJointGetPUAxis3(this, ax3); + + if ( flags & dJOINT_REVERSE ) + { + setAxes( this, ax1[0], ax1[1], ax1[2], NULL, axis2 ); + setAxes( this, ax2[0], ax2[1], ax2[2], axis1, NULL ); + } + else + { + setAxes( this, ax1[0], ax1[1], ax1[2], axis1, NULL ); + setAxes( this, ax2[0], ax2[1], ax2[2], NULL, axis2 ); + } + + + setAxes( this, ax3[0], ax3[1], ax3[2], axisP1, NULL ); + + computeInitialRelativeRotations(); +} + diff --git a/libs/ode-0.16.1/ode/src/joints/pu.h b/libs/ode-0.16.1/ode/src/joints/pu.h new file mode 100644 index 0000000..34f7392 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/pu.h @@ -0,0 +1,88 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_JOINT_PU_H_ +#define _ODE_JOINT_PU_H_ + +#include "universal.h" + + + +/** + * Component of a Prismatic -- Universal joint. + * The axisP must be perpendicular to axis1. + * The second axis of the universal joint is perpendicular to axis1. + * + * Since the PU joint is derived from the Universal joint. Some variable + * are reused. + * + * anchor1: Vector from body1 to the anchor point + * This vector is calculated when the body are attached or + * when the anchor point is set. It is like the offset of the Slider + * joint. Since their is a prismatic between the anchor and the body1 + * the distance might change as the simulation goes on. + * anchor2: Vector from body2 to the anchor point. + * <PRE> + * Body 2 + * +-------------+ + * | x | + * +------------\+ + * Prismatic articulation .. .. + * | .. .. + * Body 1 v .. .. + * +--------------+ --| __.. .. anchor2 + * <--------| x | .....|.......(__) .. + * axisP +--------------+ --| ^ < + * |----------------------->| + * anchor1 |--- Universal articulation + * axis1 going out of the plane + * axis2 is perpendicular to axis1 + * (i.e. 2 rotoides) + * </PRE> + */ +struct dxJointPU : public dxJointUniversal +{ + + /// @brief Axis for the prismatic articulation w.r.t first body. + /// @note This is considered as axis2 from the parameter view + dVector3 axisP1; + + dxJointLimitMotor limotP; ///< limit and motor information for the prismatic articulation. + + + dxJointPU( dxWorld *w ); + virtual void getSureMaxInfo( SureMaxInfo* info ); + virtual void getInfo1( Info1* info ); + virtual void getInfo2( dReal worldFPS, dReal worldERP, + int rowskip, dReal *J1, dReal *J2, + int pairskip, dReal *pairRhsCfm, dReal *pairLoHi, + int *findex ); + virtual dJointType type() const; + virtual sizeint size() const; + + + virtual void setRelativeValues(); +}; + + +#endif + diff --git a/libs/ode-0.16.1/ode/src/joints/slider.cpp b/libs/ode-0.16.1/ode/src/joints/slider.cpp new file mode 100644 index 0000000..2c9b008 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/slider.cpp @@ -0,0 +1,423 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + + +#include <ode/odeconfig.h> +#include "config.h" +#include "slider.h" +#include "joint_internal.h" + + + +//**************************************************************************** +// slider + +dxJointSlider::dxJointSlider ( dxWorld *w ) : + dxJoint ( w ) +{ + dSetZero ( axis1, 4 ); + axis1[0] = 1; + dSetZero ( qrel, 4 ); + dSetZero ( offset, 4 ); + limot.init ( world ); +} + + +dReal dJointGetSliderPosition ( dJointID j ) +{ + dxJointSlider* joint = ( dxJointSlider* ) j; + dUASSERT ( joint, "bad joint argument" ); + checktype ( joint, Slider ); + + // get axis1 in global coordinates + dVector3 ax1, q; + dMultiply0_331 ( ax1, joint->node[0].body->posr.R, joint->axis1 ); + + if ( joint->node[1].body ) + { + // get body2 + offset point in global coordinates + dMultiply0_331 ( q, joint->node[1].body->posr.R, joint->offset ); + for ( int i = 0; i < 3; i++ ) + q[i] = joint->node[0].body->posr.pos[i] + - q[i] + - joint->node[1].body->posr.pos[i]; + } + else + { + q[0] = joint->node[0].body->posr.pos[0] - joint->offset[0]; + q[1] = joint->node[0].body->posr.pos[1] - joint->offset[1]; + q[2] = joint->node[0].body->posr.pos[2] - joint->offset[2]; + + if ( joint->flags & dJOINT_REVERSE ) + { + // N.B. it could have been simplier to only inverse the sign of + // the dCalcVectorDot3 result but this case is exceptional and doing + // the check for all case can decrease the performance. + ax1[0] = -ax1[0]; + ax1[1] = -ax1[1]; + ax1[2] = -ax1[2]; + } + } + + return dCalcVectorDot3 ( ax1, q ); +} + + +dReal dJointGetSliderPositionRate ( dJointID j ) +{ + dxJointSlider* joint = ( dxJointSlider* ) j; + dUASSERT ( joint, "bad joint argument" ); + checktype ( joint, Slider ); + + // get axis1 in global coordinates + dVector3 ax1; + dMultiply0_331 ( ax1, joint->node[0].body->posr.R, joint->axis1 ); + + if ( joint->node[1].body ) + { + return dCalcVectorDot3 ( ax1, joint->node[0].body->lvel ) - + dCalcVectorDot3 ( ax1, joint->node[1].body->lvel ); + } + else + { + dReal rate = dCalcVectorDot3 ( ax1, joint->node[0].body->lvel ); + if ( joint->flags & dJOINT_REVERSE ) rate = - rate; + return rate; + } +} + + +void +dxJointSlider::getSureMaxInfo( SureMaxInfo* info ) +{ + info->max_m = 6; +} + + +void +dxJointSlider::getInfo1 ( dxJoint::Info1 *info ) +{ + info->nub = 5; + + // see if joint is powered + if ( limot.fmax > 0 ) + info->m = 6; // powered slider needs an extra constraint row + else info->m = 5; + + // see if we're at a joint limit. + limot.limit = 0; + if ( ( limot.lostop > -dInfinity || limot.histop < dInfinity ) && + limot.lostop <= limot.histop ) + { + // measure joint position + dReal pos = dJointGetSliderPosition ( this ); + if ( pos <= limot.lostop ) + { + limot.limit = 1; + limot.limit_err = pos - limot.lostop; + info->m = 6; + } + else if ( pos >= limot.histop ) + { + limot.limit = 2; + limot.limit_err = pos - limot.histop; + info->m = 6; + } + } +} + + +void +dxJointSlider::getInfo2 ( dReal worldFPS, dReal worldERP, + int rowskip, dReal *J1, dReal *J2, + int pairskip, dReal *pairRhsCfm, dReal *pairLoHi, + int *findex ) +{ + // 3 rows to make body rotations equal + setFixedOrientation ( this, worldFPS, worldERP, rowskip, J1, J2, pairskip, pairRhsCfm, qrel ); + + // pull out pos and R for both bodies. also get the `connection' + // vector pos2-pos1. + dVector3 c; + dReal *pos2 = NULL, *R2 = NULL; + + dReal *pos1 = node[0].body->posr.pos; + dReal *R1 = node[0].body->posr.R; + + dVector3 ax1; // joint axis in global coordinates (unit length) + dVector3 p, q; // plane space of ax1 + dMultiply0_331 ( ax1, R1, axis1 ); + dPlaneSpace ( ax1, p, q ); + + dxBody *body1 = node[1].body; + + if ( body1 ) + { + R2 = body1->posr.R; + pos2 = body1->posr.pos; + dSubtractVectors3( c, pos2, pos1 ); + } + + // remaining two rows. we want: vel2 = vel1 + w1 x c ... but this would + // result in three equations, so we project along the planespace vectors + // so that sliding along the slider axis is disregarded. for symmetry we + // also substitute (w1+w2)/2 for w1, as w1 is supposed to equal w2. + int currRowSkip = 3 * rowskip, currPairSkip = 3 * pairskip; + { + dCopyVector3( J1 + currRowSkip + GI2__JL_MIN, p ); + + if ( body1 ) + { + dVector3 tmp; + + dCopyNegatedVector3(J2 + currRowSkip + GI2__JL_MIN, p); + + dCalcVectorCross3( tmp, c, p ); + dCopyScaledVector3( J1 + currRowSkip + GI2__JA_MIN, tmp, REAL(0.5) ); + dCopyVector3( J2 + currRowSkip + GI2__JA_MIN, J1 + currRowSkip + GI2__JA_MIN ); + } + } + + currRowSkip += rowskip; + { + dCopyVector3( J1 + currRowSkip + GI2__JL_MIN, q ); + + if ( body1 ) + { + dVector3 tmp; + + dCopyNegatedVector3(J2 + currRowSkip + GI2__JL_MIN, q); + + dCalcVectorCross3( tmp, c, q ); + dCopyScaledVector3( J1 + currRowSkip + GI2__JA_MIN, tmp, REAL(0.5) ); + dCopyVector3( J2 + currRowSkip + GI2__JA_MIN, J1 + currRowSkip + GI2__JA_MIN ); + } + } + + // compute last two elements of right hand side. we want to align the offset + // point (in body 2's frame) with the center of body 1. + dReal k = worldFPS * worldERP; + + if ( body1 ) + { + dVector3 ofs; // offset point in global coordinates + dMultiply0_331 ( ofs, R2, offset ); + dAddVectors3(c, c, ofs); + + pairRhsCfm[currPairSkip + GI2_RHS] = k * dCalcVectorDot3 ( p, c ); + + currPairSkip += pairskip; + pairRhsCfm[currPairSkip + GI2_RHS] = k * dCalcVectorDot3 ( q, c ); + } + else + { + dVector3 ofs; // offset point in global coordinates + dSubtractVectors3(ofs, offset, pos1); + + pairRhsCfm[currPairSkip + GI2_RHS] = k * dCalcVectorDot3 ( p, ofs ); + + currPairSkip += pairskip; + pairRhsCfm[currPairSkip + GI2_RHS] = k * dCalcVectorDot3 ( q, ofs ); + + if ( (flags & dJOINT_REVERSE) != 0 ) + { + dNegateVector3(ax1); + } + } + + // if the slider is powered, or has joint limits, add in the extra row + currRowSkip += rowskip; currPairSkip += pairskip; + limot.addLimot ( this, worldFPS, J1 + currRowSkip, J2 + currRowSkip, pairRhsCfm + currPairSkip, pairLoHi + currPairSkip, ax1, 0 ); +} + + +void dJointSetSliderAxis ( dJointID j, dReal x, dReal y, dReal z ) +{ + dxJointSlider* joint = ( dxJointSlider* ) j; + dUASSERT ( joint, "bad joint argument" ); + checktype ( joint, Slider ); + setAxes ( joint, x, y, z, joint->axis1, 0 ); + + joint->computeOffset(); + + joint->computeInitialRelativeRotation(); +} + + +void dJointSetSliderAxisDelta ( dJointID j, dReal x, dReal y, dReal z, dReal dx, dReal dy, dReal dz ) +{ + dxJointSlider* joint = ( dxJointSlider* ) j; + dUASSERT ( joint, "bad joint argument" ); + checktype ( joint, Slider ); + setAxes ( joint, x, y, z, joint->axis1, 0 ); + + joint->computeOffset(); + + // compute initial relative rotation body1 -> body2, or env -> body1 + // also compute center of body1 w.r.t body 2 + if ( !(joint->node[1].body) ) + { + joint->offset[0] += dx; + joint->offset[1] += dy; + joint->offset[2] += dz; + } + + joint->computeInitialRelativeRotation(); +} + + + +void dJointGetSliderAxis ( dJointID j, dVector3 result ) +{ + dxJointSlider* joint = ( dxJointSlider* ) j; + dUASSERT ( joint, "bad joint argument" ); + dUASSERT ( result, "bad result argument" ); + checktype ( joint, Slider ); + getAxis ( joint, result, joint->axis1 ); +} + + +void dJointSetSliderParam ( dJointID j, int parameter, dReal value ) +{ + dxJointSlider* joint = ( dxJointSlider* ) j; + dUASSERT ( joint, "bad joint argument" ); + checktype ( joint, Slider ); + joint->limot.set ( parameter, value ); +} + + +dReal dJointGetSliderParam ( dJointID j, int parameter ) +{ + dxJointSlider* joint = ( dxJointSlider* ) j; + dUASSERT ( joint, "bad joint argument" ); + checktype ( joint, Slider ); + return joint->limot.get ( parameter ); +} + + +void dJointAddSliderForce ( dJointID j, dReal force ) +{ + dxJointSlider* joint = ( dxJointSlider* ) j; + dVector3 axis; + dUASSERT ( joint, "bad joint argument" ); + checktype ( joint, Slider ); + + if ( joint->flags & dJOINT_REVERSE ) + force = -force; + + getAxis ( joint, axis, joint->axis1 ); + axis[0] *= force; + axis[1] *= force; + axis[2] *= force; + + if ( joint->node[0].body != 0 ) + dBodyAddForce ( joint->node[0].body, axis[0], axis[1], axis[2] ); + if ( joint->node[1].body != 0 ) + dBodyAddForce ( joint->node[1].body, -axis[0], -axis[1], -axis[2] ); + + if ( joint->node[0].body != 0 && joint->node[1].body != 0 ) + { + // linear torque decoupling: + // we have to compensate the torque, that this slider force may generate + // if body centers are not aligned along the slider axis + + dVector3 ltd; // Linear Torque Decoupling vector (a torque) + + dVector3 c; + c[0] = REAL ( 0.5 ) * ( joint->node[1].body->posr.pos[0] - joint->node[0].body->posr.pos[0] ); + c[1] = REAL ( 0.5 ) * ( joint->node[1].body->posr.pos[1] - joint->node[0].body->posr.pos[1] ); + c[2] = REAL ( 0.5 ) * ( joint->node[1].body->posr.pos[2] - joint->node[0].body->posr.pos[2] ); + dCalcVectorCross3( ltd, c, axis ); + + dBodyAddTorque ( joint->node[0].body, ltd[0], ltd[1], ltd[2] ); + dBodyAddTorque ( joint->node[1].body, ltd[0], ltd[1], ltd[2] ); + } +} + + +dJointType +dxJointSlider::type() const +{ + return dJointTypeSlider; +} + + +sizeint +dxJointSlider::size() const +{ + return sizeof ( *this ); +} + + +void +dxJointSlider::setRelativeValues() +{ + computeOffset(); + computeInitialRelativeRotation(); +} + + + +/// Compute initial relative rotation body1 -> body2, or env -> body1 +void +dxJointSlider::computeInitialRelativeRotation() +{ + if ( node[0].body ) + { + // compute initial relative rotation body1 -> body2, or env -> body1 + // also compute center of body1 w.r.t body 2 + if ( node[1].body ) + { + dQMultiply1 ( qrel, node[0].body->q, node[1].body->q ); + } + else + { + // set qrel to the transpose of the first body's q + qrel[0] = node[0].body->q[0]; + qrel[1] = -node[0].body->q[1]; + qrel[2] = -node[0].body->q[2]; + qrel[3] = -node[0].body->q[3]; + } + } +} + + +/// Compute center of body1 w.r.t body 2 +void +dxJointSlider::computeOffset() +{ + if ( node[1].body ) + { + dVector3 c; + c[0] = node[0].body->posr.pos[0] - node[1].body->posr.pos[0]; + c[1] = node[0].body->posr.pos[1] - node[1].body->posr.pos[1]; + c[2] = node[0].body->posr.pos[2] - node[1].body->posr.pos[2]; + + dMultiply1_331 ( offset, node[1].body->posr.R, c ); + } + else if ( node[0].body ) + { + offset[0] = node[0].body->posr.pos[0]; + offset[1] = node[0].body->posr.pos[1]; + offset[2] = node[0].body->posr.pos[2]; + } +} diff --git a/libs/ode-0.16.1/ode/src/joints/slider.h b/libs/ode-0.16.1/ode/src/joints/slider.h new file mode 100644 index 0000000..de6201e --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/slider.h @@ -0,0 +1,59 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_JOINT_SLIDER_H_ +#define _ODE_JOINT_SLIDER_H_ + +#include "joint.h" + + +// slider. if body2 is 0 then qrel is the absolute rotation of body1 and +// offset is the position of body1 center along axis1. + +struct dxJointSlider : public dxJoint +{ + dVector3 axis1; // axis w.r.t first body + dQuaternion qrel; // initial relative rotation body1 -> body2 + dVector3 offset; // point relative to body2 that should be + // aligned with body1 center along axis1 + dxJointLimitMotor limot; // limit and motor information + + dxJointSlider ( dxWorld *w ); + virtual void getSureMaxInfo( SureMaxInfo* info ); + virtual void getInfo1 ( Info1* info ); + virtual void getInfo2 ( dReal worldFPS, dReal worldERP, + int rowskip, dReal *J1, dReal *J2, + int pairskip, dReal *pairRhsCfm, dReal *pairLoHi, + int *findex ); + virtual dJointType type() const; + virtual sizeint size() const; + + virtual void setRelativeValues(); + + void computeInitialRelativeRotation(); + + void computeOffset(); +}; + + +#endif + diff --git a/libs/ode-0.16.1/ode/src/joints/transmission.cpp b/libs/ode-0.16.1/ode/src/joints/transmission.cpp new file mode 100644 index 0000000..825b9e2 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/transmission.cpp @@ -0,0 +1,698 @@ +/*************************************************************************
+ * *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
+ * All rights reserved. Email: russ@q12.org Web: www.q12.org *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of EITHER: *
+ * (1) The GNU Lesser General Public License as published by the Free *
+ * Software Foundation; either version 2.1 of the License, or (at *
+ * your option) any later version. The text of the GNU Lesser *
+ * General Public License is included with this library in the *
+ * file LICENSE.TXT. *
+ * (2) The BSD-style license that is included with this library in *
+ * the file LICENSE-BSD.TXT. *
+ * *
+ * This library 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 files *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
+ * *
+ *************************************************************************/
+
+
+#include <ode/odeconfig.h>
+#include "config.h"
+#include "transmission.h"
+#include "joint_internal.h"
+
+namespace {
+ static inline dReal clamp(dReal x, dReal minX, dReal maxX)
+ {
+ return x < minX ? minX : (x > maxX ? maxX : x);
+ }
+}
+
+/*
+ * Transmission joint
+ */
+
+dxJointTransmission::dxJointTransmission(dxWorld* w) :
+ dxJoint(w)
+{
+ int i;
+
+ flags |= dJOINT_TWOBODIES;
+ mode = dTransmissionParallelAxes;
+
+ cfm = world->global_cfm;
+ erp = world->global_erp;
+
+ for (i = 0 ; i < 2 ; i += 1) {
+ dSetZero( anchors[i], 4 );
+ dSetZero( axes[i], 4 );
+ axes[i][0] = 1;
+
+ radii[i] = 0;
+ }
+
+ backlash = 0;
+ ratio = 1;
+ update = 1;
+}
+
+void
+dxJointTransmission::getSureMaxInfo( SureMaxInfo* info )
+{
+ info->max_m = 1;
+}
+
+void
+dxJointTransmission::getInfo1( dxJoint::Info1* info )
+{
+ // If there's backlash in the gears then constraint must be
+ // unilateral, that is the driving gear can only push the driven
+ // gear in one direction. In order to push it in the other it
+ // first needs to traverse the backlash gap.
+
+ info->m = 1;
+ info->nub = backlash > 0 ? 0 : 1;
+}
+
+void
+dxJointTransmission::getInfo2( dReal worldFPS, dReal /*worldERP*/,
+ int rowskip, dReal *J1, dReal *J2,
+ int pairskip, dReal *pairRhsCfm, dReal *pairLoHi,
+ int *findex )
+ {
+ dVector3 a[2], n[2], l[2], r[2], c[2], s, t, O, d, z, u, v;
+ dReal theta, delta, nn, na_0, na_1, cosphi, sinphi, m;
+ const dReal *p[2], *omega[2];
+ int i;
+
+ // Transform all needed quantities to the global frame.
+
+ for (i = 0 ; i < 2 ; i += 1) {
+ dBodyGetRelPointPos(node[i].body,
+ anchors[i][0], anchors[i][1], anchors[i][2],
+ a[i]);
+
+ dBodyVectorToWorld(node[i].body, axes[i][0], axes[i][1], axes[i][2],
+ n[i]);
+
+ p[i] = dBodyGetPosition(node[i].body);
+ omega[i] = dBodyGetAngularVel(node[i].body);
+ }
+
+ if (update) {
+ // Make sure both gear reference frames end up with the same
+ // handedness.
+
+ if (dCalcVectorDot3(n[0], n[1]) < 0) {
+ dNegateVector3(axes[0]);
+ dNegateVector3(n[0]);
+ }
+ }
+
+ // Calculate the mesh geometry based on the current mode.
+
+ switch (mode) {
+ case dTransmissionParallelAxes:
+ // Simply calculate the contact point as the point on the
+ // baseline that will yield the correct ratio.
+
+ dIASSERT (ratio > 0);
+
+ dSubtractVectors3(d, a[1], a[0]);
+ dAddVectorScaledVector3(c[0], a[0], d, ratio / (1 + ratio));
+ dCopyVector3(c[1], c[0]);
+
+ dNormalize3(d);
+
+ for (i = 0 ; i < 2 ; i += 1) {
+ dCalcVectorCross3(l[i], d, n[i]);
+ }
+
+ break;
+ case dTransmissionIntersectingAxes:
+ // Calculate the line of intersection between the planes of the
+ // gears.
+
+ dCalcVectorCross3(l[0], n[0], n[1]);
+ dCopyVector3(l[1], l[0]);
+
+ nn = dCalcVectorDot3(n[0], n[1]);
+ dIASSERT(fabs(nn) != 1);
+
+ na_0 = dCalcVectorDot3(n[0], a[0]);
+ na_1 = dCalcVectorDot3(n[1], a[1]);
+
+ dAddScaledVectors3(O, n[0], n[1],
+ (na_0 - na_1 * nn) / (1 - nn * nn),
+ (na_1 - na_0 * nn) / (1 - nn * nn));
+
+ // Find the contact point as:
+ //
+ // c = ((r_a - O) . l) l + O
+ //
+ // where r_a the anchor point of either gear and l, O the tangent
+ // line direction and origin.
+
+ for (i = 0 ; i < 2 ; i += 1) {
+ dSubtractVectors3(d, a[i], O);
+ m = dCalcVectorDot3(d, l[i]);
+ dAddVectorScaledVector3(c[i], O, l[i], m);
+ }
+
+ break;
+ case dTransmissionChainDrive:
+ dSubtractVectors3(d, a[0], a[1]);
+ m = dCalcVectorLength3(d);
+
+ dIASSERT(m > 0);
+
+ // Caclulate the angle of the contact point relative to the
+ // baseline.
+
+ cosphi = clamp((radii[1] - radii[0]) / m, REAL(-1.0), REAL(1.0)); // Force into range to fix possible computation errors
+ sinphi = dSqrt (REAL(1.0) - cosphi * cosphi);
+
+ dNormalize3(d);
+
+ for (i = 0 ; i < 2 ; i += 1) {
+ // Calculate the contact radius in the local reference
+ // frame of the chain. This has axis x pointing along the
+ // baseline, axis y pointing along the sprocket axis and
+ // the remaining axis normal to both.
+
+ u[0] = radii[i] * cosphi;
+ u[1] = 0;
+ u[2] = radii[i] * sinphi;
+
+ // Transform the contact radius into the global frame.
+
+ dCalcVectorCross3(z, d, n[i]);
+
+ v[0] = dCalcVectorDot3(d, u);
+ v[1] = dCalcVectorDot3(n[i], u);
+ v[2] = dCalcVectorDot3(z, u);
+
+ // Finally calculate contact points and l.
+
+ dAddVectors3(c[i], a[i], v);
+ dCalcVectorCross3(l[i], v, n[i]);
+ dNormalize3(l[i]);
+
+ // printf ("%d: %f, %f, %f\n",
+ // i, l[i][0], l[i][1], l[i][2]);
+ }
+
+ break;
+ }
+
+ if (update) {
+ // We need to calculate an initial reference frame for each
+ // wheel which we can measure the current phase against. This
+ // frame will have the initial contact radius as the x axis,
+ // the wheel axis as the z axis and their cross product as the
+ // y axis.
+
+ for (i = 0 ; i < 2 ; i += 1) {
+ dSubtractVectors3 (r[i], c[i], a[i]);
+ radii[i] = dCalcVectorLength3(r[i]);
+ dIASSERT(radii[i] > 0);
+
+ dBodyVectorFromWorld(node[i].body, r[i][0], r[i][1], r[i][2],
+ reference[i]);
+ dNormalize3(reference[i]);
+ dCopyVector3(reference[i] + 8, axes[i]);
+ dCalcVectorCross3(reference[i] + 4, reference[i] + 8, reference[i]);
+
+ // printf ("%f\n", dDOT(r[i], n[i]));
+ // printf ("(%f, %f, %f,\n %f, %f, %f,\n %f, %f, %f)\n",
+ // reference[i][0],reference[i][1],reference[i][2],
+ // reference[i][4],reference[i][5],reference[i][6],
+ // reference[i][8],reference[i][9],reference[i][10]);
+
+ phase[i] = 0;
+ }
+
+ ratio = radii[0] / radii[1];
+ update = 0;
+ }
+
+ for (i = 0 ; i < 2 ; i += 1) {
+ dReal phase_hat;
+
+ dSubtractVectors3 (r[i], c[i], a[i]);
+
+ // Transform the (global) contact radius into the gear's
+ // reference frame.
+
+ dBodyVectorFromWorld (node[i].body, r[i][0], r[i][1], r[i][2], s);
+ dMultiply0_331(t, reference[i], s);
+
+ // Now simply calculate its angle on the plane relative to the
+ // x-axis which is the initial contact radius. This will be
+ // an angle between -pi and pi that is coterminal with the
+ // actual phase of the wheel. To find the real phase we
+ // estimate it by adding omega * dt to the old phase and then
+ // find the closest angle to that, that is coterminal to
+ // theta.
+
+ theta = atan2(t[1], t[0]);
+ phase_hat = phase[i] + dCalcVectorDot3(omega[i], n[i]) / worldFPS;
+
+ if (phase_hat > M_PI_2) {
+ if (theta < 0) {
+ theta += (dReal)(2 * M_PI);
+ }
+
+ theta += (dReal)(floor(phase_hat / (2 * M_PI)) * (2 * M_PI));
+ } else if (phase_hat < -M_PI_2) {
+ if (theta > 0) {
+ theta -= (dReal)(2 * M_PI);
+ }
+
+ theta += (dReal)(ceil(phase_hat / (2 * M_PI)) * (2 * M_PI));
+ }
+
+ if (phase_hat - theta > M_PI) {
+ phase[i] = theta + (dReal)(2 * M_PI);
+ } else if (phase_hat - theta < -M_PI) {
+ phase[i] = theta - (dReal)(2 * M_PI);
+ } else {
+ phase[i] = theta;
+ }
+
+ dIASSERT(fabs(phase_hat - phase[i]) < M_PI);
+ }
+
+ // Calculate the phase error. Depending on the mode the condition
+ // is that the distances traveled by each contact point must be
+ // either equal (chain and sprockets) or opposite (gears).
+
+ if (mode == dTransmissionChainDrive) {
+ delta = (dCalcVectorLength3(r[0]) * phase[0] -
+ dCalcVectorLength3(r[1]) * phase[1]);
+ } else {
+ delta = (dCalcVectorLength3(r[0]) * phase[0] +
+ dCalcVectorLength3(r[1]) * phase[1]);
+ }
+
+ // When in chain mode a torque reversal, signified by the change
+ // in sign of the wheel phase difference, has the added effect of
+ // switching the active chain branch. We must therefore reflect
+ // the contact points and tangents across the baseline.
+
+ if (mode == dTransmissionChainDrive && delta < 0) {
+ dVector3 d;
+
+ dSubtractVectors3(d, a[0], a[1]);
+
+ for (i = 0 ; i < 2 ; i += 1) {
+ dVector3 nn;
+ dReal a;
+
+ dCalcVectorCross3(nn, n[i], d);
+ a = dCalcVectorDot3(nn, nn);
+ dIASSERT(a > 0);
+
+ dAddScaledVectors3(c[i], c[i], nn,
+ 1, -2 * dCalcVectorDot3(c[i], nn) / a);
+ dAddScaledVectors3(l[i], l[i], nn,
+ -1, 2 * dCalcVectorDot3(l[i], nn) / a);
+ }
+ }
+
+ // Do not add the constraint if there's backlash and we're in the
+ // backlash gap.
+
+ if (backlash == 0 || fabs(delta) > backlash) {
+ // The constraint is satisfied if the absolute velocity of the
+ // contact point projected onto the tangent of the wheels is equal
+ // for both gears. This velocity can be calculated as:
+ //
+ // u = v + omega x r_c
+ //
+ // The constraint therefore becomes:
+ // (v_1 + omega_1 x r_c1) . l = (v_2 + omega_2 x r_c2) . l <=>
+ // (v_1 . l + (r_c1 x l) . omega_1 = v_2 . l + (r_c2 x l) . omega_2
+
+ for (i = 0 ; i < 2 ; i += 1) {
+ dSubtractVectors3 (r[i], c[i], p[i]);
+ }
+
+ dCopyVector3(J1 + GI2__JL_MIN, l[0]);
+ dCalcVectorCross3(J1 + GI2__JA_MIN, r[0], l[0]);
+
+ dCopyNegatedVector3(J2 + GI2__JL_MIN, l[1]);
+ dCalcVectorCross3(J2 + GI2__JA_MIN, l[1], r[1]);
+
+ if (delta > 0) {
+ if (backlash > 0) {
+ pairLoHi[GI2_LO] = -dInfinity;
+ pairLoHi[GI2_HI] = 0;
+ }
+
+ pairRhsCfm[GI2_RHS] = -worldFPS * erp * (delta - backlash);
+ } else {
+ if (backlash > 0) {
+ pairLoHi[GI2_LO] = 0;
+ pairLoHi[GI2_HI] = dInfinity;
+ }
+
+ pairRhsCfm[GI2_RHS] = -worldFPS * erp * (delta + backlash);
+ }
+ }
+
+ pairRhsCfm[GI2_CFM] = cfm;
+
+ // printf ("%f, %f, %f, %f, %f\n", delta, phase[0], phase[1], -phase[1] / phase[0], ratio);
+
+ // Cache the contact point (in world coordinates) to avoid
+ // recalculation if requested by the user.
+
+ dCopyVector3(contacts[0], c[0]);
+ dCopyVector3(contacts[1], c[1]);
+}
+
+void dJointSetTransmissionAxis( dJointID j, dReal x, dReal y, dReal z )
+{
+ dxJointTransmission* joint = static_cast<dxJointTransmission*>(j);
+ int i;
+
+ dUASSERT( joint, "bad joint argument" );
+ dUASSERT(joint->mode == dTransmissionParallelAxes ||
+ joint->mode == dTransmissionChainDrive ,
+ "axes must be set individualy in current mode" );
+
+ for (i = 0 ; i < 2 ; i += 1) {
+ if (joint->node[i].body) {
+ dBodyVectorFromWorld(joint->node[i].body, x, y, z, joint->axes[i]);
+ dNormalize3(joint->axes[i]);
+ }
+ }
+
+ joint->update = 1;
+}
+
+void dJointSetTransmissionAxis1( dJointID j, dReal x, dReal y, dReal z )
+{
+ dxJointTransmission* joint = static_cast<dxJointTransmission*>(j);
+ dUASSERT( joint, "bad joint argument" );
+ dUASSERT(joint->mode == dTransmissionIntersectingAxes,
+ "can't set individual axes in current mode" );
+
+ if (joint->node[0].body) {
+ dBodyVectorFromWorld(joint->node[0].body, x, y, z, joint->axes[0]);
+ dNormalize3(joint->axes[0]);
+ }
+
+ joint->update = 1;
+}
+
+void dJointSetTransmissionAxis2( dJointID j, dReal x, dReal y, dReal z )
+{
+ dxJointTransmission* joint = static_cast<dxJointTransmission*>(j);
+ dUASSERT( joint, "bad joint argument" );
+ dUASSERT(joint->mode == dTransmissionIntersectingAxes,
+ "can't set individual axes in current mode" );
+
+ if (joint->node[1].body) {
+ dBodyVectorFromWorld(joint->node[1].body, x, y, z, joint->axes[1]);
+ dNormalize3(joint->axes[1]);
+ }
+
+ joint->update = 1;
+}
+
+void dJointSetTransmissionAnchor1( dJointID j, dReal x, dReal y, dReal z )
+{
+ dxJointTransmission* joint = static_cast<dxJointTransmission*>(j);
+ dUASSERT( joint, "bad joint argument" );
+
+ if (joint->node[0].body) {
+ dBodyGetPosRelPoint(joint->node[0].body, x, y, z, joint->anchors[0]);
+ }
+
+ joint->update = 1;
+}
+
+void dJointSetTransmissionAnchor2( dJointID j, dReal x, dReal y, dReal z )
+{
+ dxJointTransmission* joint = static_cast<dxJointTransmission*>(j);
+ dUASSERT( joint, "bad joint argument" );
+
+ if (joint->node[1].body) {
+ dBodyGetPosRelPoint(joint->node[1].body, x, y, z, joint->anchors[1]);
+ }
+
+ joint->update = 1;
+}
+
+void dJointGetTransmissionContactPoint1( dJointID j, dVector3 result )
+{
+ dxJointTransmission* joint = static_cast<dxJointTransmission*>(j);
+ dUASSERT( joint, "bad joint argument" );
+ dUASSERT( result, "bad result argument" );
+
+ dCopyVector3(result, joint->contacts[0]);
+}
+
+void dJointGetTransmissionContactPoint2( dJointID j, dVector3 result )
+{
+ dxJointTransmission* joint = static_cast<dxJointTransmission*>(j);
+ dUASSERT( joint, "bad joint argument" );
+ dUASSERT( result, "bad result argument" );
+
+ dCopyVector3(result, joint->contacts[1]);
+}
+
+void dJointGetTransmissionAxis( dJointID j, dVector3 result )
+{
+ dxJointTransmission* joint = static_cast<dxJointTransmission*>(j);
+ dUASSERT( joint, "bad joint argument" );
+ dUASSERT( result, "bad result argument" );
+ dUASSERT(joint->mode == dTransmissionParallelAxes,
+ "axes must be queried individualy in current mode" );
+
+ if (joint->node[0].body) {
+ dBodyVectorToWorld(joint->node[0].body,
+ joint->axes[0][0],
+ joint->axes[0][1],
+ joint->axes[0][2],
+ result);
+ }
+}
+
+void dJointGetTransmissionAxis1( dJointID j, dVector3 result )
+{
+ dxJointTransmission* joint = static_cast<dxJointTransmission*>(j);
+ dUASSERT( joint, "bad joint argument" );
+ dUASSERT( result, "bad result argument" );
+
+ if (joint->node[0].body) {
+ dBodyVectorToWorld(joint->node[0].body,
+ joint->axes[0][0],
+ joint->axes[0][1],
+ joint->axes[0][2],
+ result);
+ }
+}
+
+void dJointGetTransmissionAxis2( dJointID j, dVector3 result )
+{
+ dxJointTransmission* joint = static_cast<dxJointTransmission*>(j);
+ dUASSERT( joint, "bad joint argument" );
+ dUASSERT( result, "bad result argument" );
+
+ if (joint->node[1].body) {
+ dBodyVectorToWorld(joint->node[1].body,
+ joint->axes[1][0],
+ joint->axes[1][1],
+ joint->axes[1][2],
+ result);
+ }
+}
+
+void dJointGetTransmissionAnchor1( dJointID j, dVector3 result )
+{
+ dxJointTransmission* joint = static_cast<dxJointTransmission*>(j);
+ dUASSERT( joint, "bad joint argument" );
+ dUASSERT( result, "bad result argument" );
+
+ if (joint->node[0].body) {
+ dBodyGetRelPointPos(joint->node[0].body,
+ joint->anchors[0][0],
+ joint->anchors[0][1],
+ joint->anchors[0][2],
+ result);
+ }
+}
+
+void dJointGetTransmissionAnchor2( dJointID j, dVector3 result )
+{
+ dxJointTransmission* joint = static_cast<dxJointTransmission*>(j);
+ dUASSERT( joint, "bad joint argument" );
+ dUASSERT( result, "bad result argument" );
+
+ if (joint->node[1].body) {
+ dBodyGetRelPointPos(joint->node[1].body,
+ joint->anchors[1][0],
+ joint->anchors[1][1],
+ joint->anchors[1][2],
+ result);
+ }
+}
+
+void dJointSetTransmissionParam( dJointID j, int parameter, dReal value )
+{
+ dxJointTransmission* joint = static_cast<dxJointTransmission*>(j);
+ dUASSERT( joint, "bad joint argument" );
+
+ switch ( parameter ) {
+ case dParamCFM:
+ joint->cfm = value;
+ break;
+ case dParamERP:
+ joint->erp = value;
+ break;
+ }
+}
+
+
+dReal dJointGetTransmissionParam( dJointID j, int parameter )
+{
+ dxJointTransmission* joint = static_cast<dxJointTransmission*>(j);
+ dUASSERT( joint, "bad joint argument" );
+
+ switch ( parameter ) {
+ case dParamCFM:
+ return joint->cfm;
+ case dParamERP:
+ return joint->erp;
+ default:
+ return 0;
+ }
+}
+
+void dJointSetTransmissionMode( dJointID j, int mode )
+{
+ dxJointTransmission* joint = static_cast<dxJointTransmission*>(j);
+ dUASSERT( joint, "bad joint argument" );
+ dUASSERT( mode == dTransmissionParallelAxes ||
+ mode == dTransmissionIntersectingAxes ||
+ mode == dTransmissionChainDrive, "invalid joint mode" );
+
+ joint->mode = mode;
+}
+
+
+int dJointGetTransmissionMode( dJointID j )
+{
+ dxJointTransmission* joint = static_cast<dxJointTransmission*>(j);
+ dUASSERT( joint, "bad joint argument" );
+
+ return joint->mode;
+}
+
+void dJointSetTransmissionRatio( dJointID j, dReal ratio )
+{
+ dxJointTransmission* joint = static_cast<dxJointTransmission*>(j);
+ dUASSERT( joint, "bad joint argument" );
+ dUASSERT( joint->mode == dTransmissionParallelAxes,
+ "can't set ratio explicitly in current mode" );
+ dUASSERT( ratio > 0, "ratio must be positive" );
+
+ joint->ratio = ratio;
+}
+
+
+dReal dJointGetTransmissionRatio( dJointID j )
+{
+ dxJointTransmission* joint = static_cast<dxJointTransmission*>(j);
+ dUASSERT( joint, "bad joint argument" );
+
+ return joint->ratio;
+}
+
+dReal dJointGetTransmissionAngle1( dJointID j )
+{
+ dxJointTransmission* joint = static_cast<dxJointTransmission*>(j);
+ dUASSERT( joint, "bad joint argument" );
+
+ return joint->phase[0];
+}
+
+dReal dJointGetTransmissionAngle2( dJointID j )
+{
+ dxJointTransmission* joint = static_cast<dxJointTransmission*>(j);
+ dUASSERT( joint, "bad joint argument" );
+
+ return joint->phase[1];
+}
+
+dReal dJointGetTransmissionRadius1( dJointID j )
+{
+ dxJointTransmission* joint = static_cast<dxJointTransmission*>(j);
+ dUASSERT( joint, "bad joint argument" );
+
+ return joint->radii[0];
+}
+
+dReal dJointGetTransmissionRadius2( dJointID j )
+{
+ dxJointTransmission* joint = static_cast<dxJointTransmission*>(j);
+ dUASSERT( joint, "bad joint argument" );
+
+ return joint->radii[1];
+}
+
+void dJointSetTransmissionRadius1( dJointID j, dReal radius )
+{
+ dxJointTransmission* joint = static_cast<dxJointTransmission*>(j);
+ dUASSERT( joint, "bad joint argument" );
+ dUASSERT( joint->mode == dTransmissionChainDrive,
+ "can't set wheel radius explicitly in current mode" );
+
+ joint->radii[0] = radius;
+}
+
+void dJointSetTransmissionRadius2( dJointID j, dReal radius )
+{
+ dxJointTransmission* joint = static_cast<dxJointTransmission*>(j);
+ dUASSERT( joint, "bad joint argument" );
+ dUASSERT( joint->mode == dTransmissionChainDrive,
+ "can't set wheel radius explicitly in current mode" );
+
+ joint->radii[1] = radius;
+}
+
+dReal dJointGetTransmissionBacklash( dJointID j )
+{
+ dxJointTransmission* joint = static_cast<dxJointTransmission*>(j);
+ dUASSERT( joint, "bad joint argument" );
+
+ return joint->backlash;
+}
+
+void dJointSetTransmissionBacklash( dJointID j, dReal backlash )
+{
+ dxJointTransmission* joint = static_cast<dxJointTransmission*>(j);
+ dUASSERT( joint, "bad joint argument" );
+
+ joint->backlash = backlash;
+}
+
+dJointType
+dxJointTransmission::type() const
+{
+ return dJointTypeTransmission;
+}
+
+sizeint
+dxJointTransmission::size() const
+{
+ return sizeof( *this );
+}
diff --git a/libs/ode-0.16.1/ode/src/joints/transmission.h b/libs/ode-0.16.1/ode/src/joints/transmission.h new file mode 100644 index 0000000..fae3f4c --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/transmission.h @@ -0,0 +1,51 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_JOINT_TRANSMISSION_ +#define _ODE_JOINT_TRANSMISSION_ + +#include "joint.h" + +struct dxJointTransmission : public dxJoint +{ + int mode, update; + dVector3 contacts[2], axes[2], anchors[2]; + dMatrix3 reference[2]; + dReal phase[2], radii[2], backlash; + dReal ratio; // transmission ratio + dReal erp; // error reduction + dReal cfm; // constraint force mix in + + dxJointTransmission(dxWorld *w); + + virtual void getSureMaxInfo( SureMaxInfo* info ); + virtual void getInfo1( Info1* info ); + virtual void getInfo2( dReal worldFPS, dReal worldERP, + int rowskip, dReal *J1, dReal *J2, + int pairskip, dReal *pairRhsCfm, dReal *pairLoHi, + int *findex ); + virtual dJointType type() const; + virtual sizeint size() const; +}; + + +#endif diff --git a/libs/ode-0.16.1/ode/src/joints/universal.cpp b/libs/ode-0.16.1/ode/src/joints/universal.cpp new file mode 100644 index 0000000..1ef00a7 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/universal.cpp @@ -0,0 +1,803 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + + +#include <ode/odeconfig.h> +#include "config.h" +#include "universal.h" +#include "joint_internal.h" + + + +//**************************************************************************** +// universal + +// I just realized that the universal joint is equivalent to a hinge 2 joint with +// perfectly stiff suspension. By comparing the hinge 2 implementation to +// the universal implementation, you may be able to improve this +// implementation (or, less likely, the hinge2 implementation). + +dxJointUniversal::dxJointUniversal( dxWorld *w ) : + dxJoint( w ) +{ + dSetZero( anchor1, 4 ); + dSetZero( anchor2, 4 ); + dSetZero( axis1, 4 ); + axis1[0] = 1; + dSetZero( axis2, 4 ); + axis2[1] = 1; + dSetZero( qrel1, 4 ); + dSetZero( qrel2, 4 ); + limot1.init( world ); + limot2.init( world ); +} + + +void +dxJointUniversal::getAxes( dVector3 ax1, dVector3 ax2 ) +{ + // This says "ax1 = joint->node[0].body->posr.R * joint->axis1" + dMultiply0_331( ax1, node[0].body->posr.R, axis1 ); + + if ( node[1].body ) + { + dMultiply0_331( ax2, node[1].body->posr.R, axis2 ); + } + else + { + ax2[0] = axis2[0]; + ax2[1] = axis2[1]; + ax2[2] = axis2[2]; + } +} + +void +dxJointUniversal::getAngles( dReal *angle1, dReal *angle2 ) +{ + if ( node[0].body ) + { + // length 1 joint axis in global coordinates, from each body + dVector3 ax1, ax2; + dMatrix3 R; + dQuaternion qcross, qq, qrel; + + getAxes( ax1, ax2 ); + + // It should be possible to get both angles without explicitly + // constructing the rotation matrix of the cross. Basically, + // orientation of the cross about axis1 comes from body 2, + // about axis 2 comes from body 1, and the perpendicular + // axis can come from the two bodies somehow. (We don't really + // want to assume it's 90 degrees, because in general the + // constraints won't be perfectly satisfied, or even very well + // satisfied.) + // + // However, we'd need a version of getHingeAngleFromRElativeQuat() + // that CAN handle when its relative quat is rotated along a direction + // other than the given axis. What I have here works, + // although it's probably much slower than need be. + + dRFrom2Axes( R, ax1[0], ax1[1], ax1[2], ax2[0], ax2[1], ax2[2] ); + + dRtoQ( R, qcross ); + + + // This code is essentialy the same as getHingeAngle(), see the comments + // there for details. + + // get qrel = relative rotation between node[0] and the cross + dQMultiply1( qq, node[0].body->q, qcross ); + dQMultiply2( qrel, qq, qrel1 ); + + *angle1 = getHingeAngleFromRelativeQuat( qrel, axis1 ); + + // This is equivalent to + // dRFrom2Axes(R, ax2[0], ax2[1], ax2[2], ax1[0], ax1[1], ax1[2]); + // You see that the R is constructed from the same 2 axis as for angle1 + // but the first and second axis are swapped. + // So we can take the first R and rapply a rotation to it. + // The rotation is around the axis between the 2 axes (ax1 and ax2). + // We do a rotation of 180deg. + + dQuaternion qcross2; + // Find the vector between ax1 and ax2 (i.e. in the middle) + // We need to turn around this vector by 180deg + + // The 2 axes should be normalize so to find the vector between the 2. + // Add and devide by 2 then normalize or simply normalize + // ax2 + // ^ + // | + // | + /// *------------> ax1 + // We want the vector a 45deg + // + // N.B. We don't need to normalize the ax1 and ax2 since there are + // normalized when we set them. + + // We set the quaternion q = [cos(theta), dir*sin(theta)] = [w, x, y, Z] + qrel[0] = 0; // equivalent to cos(Pi/2) + qrel[1] = ax1[0] + ax2[0]; // equivalent to x*sin(Pi/2); since sin(Pi/2) = 1 + qrel[2] = ax1[1] + ax2[1]; + qrel[3] = ax1[2] + ax2[2]; + + dReal l = dRecip( sqrt( qrel[1] * qrel[1] + qrel[2] * qrel[2] + qrel[3] * qrel[3] ) ); + qrel[1] *= l; + qrel[2] *= l; + qrel[3] *= l; + + dQMultiply0( qcross2, qrel, qcross ); + + if ( node[1].body ) + { + dQMultiply1( qq, node[1].body->q, qcross2 ); + dQMultiply2( qrel, qq, qrel2 ); + } + else + { + // pretend joint->node[1].body->q is the identity + dQMultiply2( qrel, qcross2, qrel2 ); + } + + *angle2 = - getHingeAngleFromRelativeQuat( qrel, axis2 ); + } + else + { + *angle1 = 0; + *angle2 = 0; + } +} + +dReal +dxJointUniversal::getAngle1() +{ + if ( node[0].body ) + { + // length 1 joint axis in global coordinates, from each body + dVector3 ax1, ax2; + dMatrix3 R; + dQuaternion qcross, qq, qrel; + + getAxes( ax1, ax2 ); + + // It should be possible to get both angles without explicitly + // constructing the rotation matrix of the cross. Basically, + // orientation of the cross about axis1 comes from body 2, + // about axis 2 comes from body 1, and the perpendicular + // axis can come from the two bodies somehow. (We don't really + // want to assume it's 90 degrees, because in general the + // constraints won't be perfectly satisfied, or even very well + // satisfied.) + // + // However, we'd need a version of getHingeAngleFromRElativeQuat() + // that CAN handle when its relative quat is rotated along a direction + // other than the given axis. What I have here works, + // although it's probably much slower than need be. + + dRFrom2Axes( R, ax1[0], ax1[1], ax1[2], ax2[0], ax2[1], ax2[2] ); + dRtoQ( R, qcross ); + + // This code is essential the same as getHingeAngle(), see the comments + // there for details. + + // get qrel = relative rotation between node[0] and the cross + dQMultiply1( qq, node[0].body->q, qcross ); + dQMultiply2( qrel, qq, qrel1 ); + + return getHingeAngleFromRelativeQuat( qrel, axis1 ); + } + return 0; +} + + +dReal +dxJointUniversal::getAngle2() +{ + if ( node[0].body ) + { + // length 1 joint axis in global coordinates, from each body + dVector3 ax1, ax2; + dMatrix3 R; + dQuaternion qcross, qq, qrel; + + getAxes( ax1, ax2 ); + + // It should be possible to get both angles without explicitly + // constructing the rotation matrix of the cross. Basically, + // orientation of the cross about axis1 comes from body 2, + // about axis 2 comes from body 1, and the perpendicular + // axis can come from the two bodies somehow. (We don't really + // want to assume it's 90 degrees, because in general the + // constraints won't be perfectly satisfied, or even very well + // satisfied.) + // + // However, we'd need a version of getHingeAngleFromRElativeQuat() + // that CAN handle when its relative quat is rotated along a direction + // other than the given axis. What I have here works, + // although it's probably much slower than need be. + + dRFrom2Axes( R, ax2[0], ax2[1], ax2[2], ax1[0], ax1[1], ax1[2] ); + dRtoQ( R, qcross ); + + if ( node[1].body ) + { + dQMultiply1( qq, node[1].body->q, qcross ); + dQMultiply2( qrel, qq, qrel2 ); + } + else + { + // pretend joint->node[1].body->q is the identity + dQMultiply2( qrel, qcross, qrel2 ); + } + + return - getHingeAngleFromRelativeQuat( qrel, axis2 ); + } + return 0; +} + + +void +dxJointUniversal::getSureMaxInfo( SureMaxInfo* info ) +{ + info->max_m = 6; +} + + +void +dxJointUniversal::getInfo1( dxJoint::Info1 *info ) +{ + info->nub = 4; + info->m = 4; + + bool limiting1 = ( limot1.lostop >= -M_PI || limot1.histop <= M_PI ) && + limot1.lostop <= limot1.histop; + bool limiting2 = ( limot2.lostop >= -M_PI || limot2.histop <= M_PI ) && + limot2.lostop <= limot2.histop; + + // We need to call testRotationLimit() even if we're motored, since it + // records the result. + limot1.limit = 0; + limot2.limit = 0; + + if ( limiting1 || limiting2 ) + { + dReal angle1, angle2; + getAngles( &angle1, &angle2 ); + if ( limiting1 ) + limot1.testRotationalLimit( angle1 ); + if ( limiting2 ) + limot2.testRotationalLimit( angle2 ); + } + + if ( limot1.limit || limot1.fmax > 0 ) info->m++; + if ( limot2.limit || limot2.fmax > 0 ) info->m++; +} + + +void +dxJointUniversal::getInfo2( dReal worldFPS, dReal worldERP, + int rowskip, dReal *J1, dReal *J2, + int pairskip, dReal *pairRhsCfm, dReal *pairLoHi, + int *findex ) +{ + // set the three ball-and-socket rows + setBall( this, worldFPS, worldERP, rowskip, J1, J2, pairskip, pairRhsCfm, anchor1, anchor2 ); + + // set the universal joint row. the angular velocity about an axis + // perpendicular to both joint axes should be equal. thus the constraint + // equation is + // p*w1 - p*w2 = 0 + // where p is a vector normal to both joint axes, and w1 and w2 + // are the angular velocity vectors of the two bodies. + + // length 1 joint axis in global coordinates, from each body + dVector3 ax1, ax2; + // length 1 vector perpendicular to ax1 and ax2. Neither body can rotate + // about this. + dVector3 p; + + // Since axis1 and axis2 may not be perpendicular + // we find a axis2_tmp which is really perpendicular to axis1 + // and in the plane of axis1 and axis2 + getAxes( ax1, ax2 ); + + dReal k = dCalcVectorDot3( ax1, ax2 ); + + dVector3 ax2_temp; + dAddVectorScaledVector3(ax2_temp, ax2, ax1, -k); + dCalcVectorCross3( p, ax1, ax2_temp ); + dNormalize3( p ); + + int currRowSkip = 3 * rowskip; + { + dCopyVector3( J1 + currRowSkip + GI2__JA_MIN, p); + + if ( node[1].body ) + { + dCopyNegatedVector3( J2 + currRowSkip + GI2__JA_MIN, p); + } + } + + // compute the right hand side of the constraint equation. set relative + // body velocities along p to bring the axes back to perpendicular. + // If ax1, ax2 are unit length joint axes as computed from body1 and + // body2, we need to rotate both bodies along the axis p. If theta + // is the angle between ax1 and ax2, we need an angular velocity + // along p to cover the angle erp * (theta - Pi/2) in one step: + // + // |angular_velocity| = angle/time = erp*(theta - Pi/2) / stepsize + // = (erp*fps) * (theta - Pi/2) + // + // if theta is close to Pi/2, + // theta - Pi/2 ~= cos(theta), so + // |angular_velocity| ~= (erp*fps) * (ax1 dot ax2) + + int currPairSkip = 3 * pairskip; + { + pairRhsCfm[currPairSkip + GI2_RHS] = worldFPS * worldERP * (-k); + } + + currRowSkip += rowskip; currPairSkip += pairskip; + + // if the first angle is powered, or has joint limits, add in the stuff + if (limot1.addLimot( this, worldFPS, J1 + currRowSkip, J2 + currRowSkip, pairRhsCfm + currPairSkip, pairLoHi + currPairSkip, ax1, 1 )) + { + currRowSkip += rowskip; currPairSkip += pairskip; + } + + // if the second angle is powered, or has joint limits, add in more stuff + limot2.addLimot( this, worldFPS, J1 + currRowSkip, J2 + currRowSkip, pairRhsCfm + currPairSkip, pairLoHi + currPairSkip, ax2, 1 ); +} + + +void +dxJointUniversal::computeInitialRelativeRotations() +{ + if ( node[0].body ) + { + dVector3 ax1, ax2; + dMatrix3 R; + dQuaternion qcross; + + getAxes( ax1, ax2 ); + + // Axis 1. + dRFrom2Axes( R, ax1[0], ax1[1], ax1[2], ax2[0], ax2[1], ax2[2] ); + dRtoQ( R, qcross ); + dQMultiply1( qrel1, node[0].body->q, qcross ); + + // Axis 2. + dRFrom2Axes( R, ax2[0], ax2[1], ax2[2], ax1[0], ax1[1], ax1[2] ); + dRtoQ( R, qcross ); + if ( node[1].body ) + { + dQMultiply1( qrel2, node[1].body->q, qcross ); + } + else + { + // set joint->qrel to qcross + for ( int i = 0; i < 4; i++ ) qrel2[i] = qcross[i]; + } + } +} + + +void dJointSetUniversalAnchor( dJointID j, dReal x, dReal y, dReal z ) +{ + dxJointUniversal* joint = ( dxJointUniversal* )j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Universal ); + setAnchors( joint, x, y, z, joint->anchor1, joint->anchor2 ); + joint->computeInitialRelativeRotations(); +} + + +void dJointSetUniversalAxis1( dJointID j, dReal x, dReal y, dReal z ) +{ + dxJointUniversal* joint = ( dxJointUniversal* )j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Universal ); + if ( joint->flags & dJOINT_REVERSE ) + setAxes( joint, x, y, z, NULL, joint->axis2 ); + else + setAxes( joint, x, y, z, joint->axis1, NULL ); + joint->computeInitialRelativeRotations(); +} + +void dJointSetUniversalAxis1Offset( dJointID j, dReal x, dReal y, dReal z, + dReal offset1, dReal offset2 ) +{ + dxJointUniversal* joint = ( dxJointUniversal* )j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Universal ); + if ( joint->flags & dJOINT_REVERSE ) + { + setAxes( joint, x, y, z, NULL, joint->axis2 ); + offset1 = -offset1; + offset2 = -offset2; + } + else + setAxes( joint, x, y, z, joint->axis1, NULL ); + + joint->computeInitialRelativeRotations(); + + + dVector3 ax2; + getAxis2( joint, ax2, joint->axis2 ); + + { + dVector3 ax1; + joint->getAxes(ax1, ax2); + } + + + + dQuaternion qAngle; + dQFromAxisAndAngle(qAngle, x, y, z, offset1); + + dMatrix3 R; + dRFrom2Axes( R, x, y, z, ax2[0], ax2[1], ax2[2] ); + + dQuaternion qcross; + dRtoQ( R, qcross ); + + dQuaternion qOffset; + dQMultiply0(qOffset, qAngle, qcross); + + dQMultiply1( joint->qrel1, joint->node[0].body->q, qOffset ); + + // Calculating the second offset + dQFromAxisAndAngle(qAngle, ax2[0], ax2[1], ax2[2], offset2); + + dRFrom2Axes( R, ax2[0], ax2[1], ax2[2], x, y, z ); + dRtoQ( R, qcross ); + + dQMultiply1(qOffset, qAngle, qcross); + if ( joint->node[1].body ) + { + dQMultiply1( joint->qrel2, joint->node[1].body->q, qOffset ); + } + else + { + joint->qrel2[0] = qcross[0]; + joint->qrel2[1] = qcross[1]; + joint->qrel2[2] = qcross[2]; + joint->qrel2[3] = qcross[3]; + } +} + + +void dJointSetUniversalAxis2( dJointID j, dReal x, dReal y, dReal z ) +{ + dxJointUniversal* joint = ( dxJointUniversal* )j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Universal ); + if ( joint->flags & dJOINT_REVERSE ) + setAxes( joint, x, y, z, joint->axis1, NULL ); + else + setAxes( joint, x, y, z, NULL, joint->axis2 ); + joint->computeInitialRelativeRotations(); +} + +void dJointSetUniversalAxis2Offset( dJointID j, dReal x, dReal y, dReal z, + dReal offset1, dReal offset2 ) +{ + dxJointUniversal* joint = ( dxJointUniversal* )j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Universal ); + + if ( joint->flags & dJOINT_REVERSE ) + { + setAxes( joint, x, y, z, joint->axis1, NULL ); + offset1 = -offset2; + offset2 = -offset1; + } + else + setAxes( joint, x, y, z, NULL, joint->axis2 ); + + + joint->computeInitialRelativeRotations(); + + // It is easier to retreive the 2 axes here since + // when there is only one body B2 (the axes switch position) + // Doing this way eliminate the need to write the code differently + // for both case. + dVector3 ax1, ax2; + joint->getAxes(ax1, ax2 ); + + + + dQuaternion qAngle; + dQFromAxisAndAngle(qAngle, ax1[0], ax1[1], ax1[2], offset1); + + dMatrix3 R; + dRFrom2Axes( R, ax1[0], ax1[1], ax1[2], ax2[0], ax2[1], ax2[2]); + + dQuaternion qcross; + dRtoQ( R, qcross ); + + dQuaternion qOffset; + dQMultiply0(qOffset, qAngle, qcross); + + + + dQMultiply1( joint->qrel1, joint->node[0].body->q, qOffset ); + + + // Calculating the second offset + dQFromAxisAndAngle(qAngle, ax2[0], ax2[1], ax2[2], offset2); + + dRFrom2Axes( R, ax2[0], ax2[1], ax2[2], ax1[0], ax1[1], ax1[2]); + dRtoQ( R, qcross ); + + dQMultiply1(qOffset, qAngle, qcross); + if ( joint->node[1].body ) + { + dQMultiply1( joint->qrel2, joint->node[1].body->q, qOffset ); + } + else + { + joint->qrel2[0] = qcross[0]; + joint->qrel2[1] = qcross[1]; + joint->qrel2[2] = qcross[2]; + joint->qrel2[3] = qcross[3]; + } +} + + +void dJointGetUniversalAnchor( dJointID j, dVector3 result ) +{ + dxJointUniversal* joint = ( dxJointUniversal* )j; + dUASSERT( joint, "bad joint argument" ); + dUASSERT( result, "bad result argument" ); + checktype( joint, Universal ); + if ( joint->flags & dJOINT_REVERSE ) + getAnchor2( joint, result, joint->anchor2 ); + else + getAnchor( joint, result, joint->anchor1 ); +} + + +void dJointGetUniversalAnchor2( dJointID j, dVector3 result ) +{ + dxJointUniversal* joint = ( dxJointUniversal* )j; + dUASSERT( joint, "bad joint argument" ); + dUASSERT( result, "bad result argument" ); + checktype( joint, Universal ); + if ( joint->flags & dJOINT_REVERSE ) + getAnchor( joint, result, joint->anchor1 ); + else + getAnchor2( joint, result, joint->anchor2 ); +} + + +void dJointGetUniversalAxis1( dJointID j, dVector3 result ) +{ + dxJointUniversal* joint = ( dxJointUniversal* )j; + dUASSERT( joint, "bad joint argument" ); + dUASSERT( result, "bad result argument" ); + checktype( joint, Universal ); + if ( joint->flags & dJOINT_REVERSE ) + getAxis2( joint, result, joint->axis2 ); + else + getAxis( joint, result, joint->axis1 ); +} + + +void dJointGetUniversalAxis2( dJointID j, dVector3 result ) +{ + dxJointUniversal* joint = ( dxJointUniversal* )j; + dUASSERT( joint, "bad joint argument" ); + dUASSERT( result, "bad result argument" ); + checktype( joint, Universal ); + if ( joint->flags & dJOINT_REVERSE ) + getAxis( joint, result, joint->axis1 ); + else + getAxis2( joint, result, joint->axis2 ); +} + + +void dJointSetUniversalParam( dJointID j, int parameter, dReal value ) +{ + dxJointUniversal* joint = ( dxJointUniversal* )j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Universal ); + if (( parameter & 0xff00 ) == 0x100 ) + { + joint->limot2.set( parameter & 0xff, value ); + } + else + { + joint->limot1.set( parameter, value ); + } +} + + +dReal dJointGetUniversalParam( dJointID j, int parameter ) +{ + dxJointUniversal* joint = ( dxJointUniversal* )j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Universal ); + if (( parameter & 0xff00 ) == 0x100 ) + { + return joint->limot2.get( parameter & 0xff ); + } + else + { + return joint->limot1.get( parameter ); + } +} + +void dJointGetUniversalAngles( dJointID j, dReal *angle1, dReal *angle2 ) +{ + dxJointUniversal* joint = ( dxJointUniversal* )j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Universal ); + if ( joint->flags & dJOINT_REVERSE ) + { + joint->getAngles( angle2, angle1 ); + *angle2 = -(*angle2); + return; + } + else + return joint->getAngles( angle1, angle2 ); +} + + +dReal dJointGetUniversalAngle1( dJointID j ) +{ + dxJointUniversal* joint = ( dxJointUniversal* )j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Universal ); + if ( joint->flags & dJOINT_REVERSE ) + return joint->getAngle2(); + else + return joint->getAngle1(); +} + + +dReal dJointGetUniversalAngle2( dJointID j ) +{ + dxJointUniversal* joint = ( dxJointUniversal* )j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Universal ); + if ( joint->flags & dJOINT_REVERSE ) + return -joint->getAngle1(); + else + return joint->getAngle2(); +} + + +dReal dJointGetUniversalAngle1Rate( dJointID j ) +{ + dxJointUniversal* joint = ( dxJointUniversal* )j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Universal ); + + if ( joint->node[0].body ) + { + dVector3 axis; + + if ( joint->flags & dJOINT_REVERSE ) + getAxis2( joint, axis, joint->axis2 ); + else + getAxis( joint, axis, joint->axis1 ); + + dReal rate = dCalcVectorDot3( axis, joint->node[0].body->avel ); + if ( joint->node[1].body ) + rate -= dCalcVectorDot3( axis, joint->node[1].body->avel ); + return rate; + } + return 0; +} + + +dReal dJointGetUniversalAngle2Rate( dJointID j ) +{ + dxJointUniversal* joint = ( dxJointUniversal* )j; + dUASSERT( joint, "bad joint argument" ); + checktype( joint, Universal ); + + if ( joint->node[0].body ) + { + dVector3 axis; + + if ( joint->flags & dJOINT_REVERSE ) + getAxis( joint, axis, joint->axis1 ); + else + getAxis2( joint, axis, joint->axis2 ); + + dReal rate = dCalcVectorDot3( axis, joint->node[0].body->avel ); + if ( joint->node[1].body ) rate -= dCalcVectorDot3( axis, joint->node[1].body->avel ); + return rate; + } + return 0; +} + + +void dJointAddUniversalTorques( dJointID j, dReal torque1, dReal torque2 ) +{ + dxJointUniversal* joint = ( dxJointUniversal* )j; + dVector3 axis1, axis2; + dAASSERT( joint ); + checktype( joint, Universal ); + + if ( joint->flags & dJOINT_REVERSE ) + { + dReal temp = torque1; + torque1 = - torque2; + torque2 = - temp; + } + + getAxis( joint, axis1, joint->axis1 ); + getAxis2( joint, axis2, joint->axis2 ); + axis1[0] = axis1[0] * torque1 + axis2[0] * torque2; + axis1[1] = axis1[1] * torque1 + axis2[1] * torque2; + axis1[2] = axis1[2] * torque1 + axis2[2] * torque2; + + if ( joint->node[0].body != 0 ) + dBodyAddTorque( joint->node[0].body, axis1[0], axis1[1], axis1[2] ); + if ( joint->node[1].body != 0 ) + dBodyAddTorque( joint->node[1].body, -axis1[0], -axis1[1], -axis1[2] ); +} + + +dJointType +dxJointUniversal::type() const +{ + return dJointTypeUniversal; +} + + +sizeint +dxJointUniversal::size() const +{ + return sizeof( *this ); +} + + + +void +dxJointUniversal::setRelativeValues() +{ + dVector3 anchor; + dJointGetUniversalAnchor(this, anchor); + setAnchors( this, anchor[0], anchor[1], anchor[2], anchor1, anchor2 ); + + dVector3 ax1,ax2; + dJointGetUniversalAxis1(this, ax1); + dJointGetUniversalAxis2(this, ax2); + + if ( flags & dJOINT_REVERSE ) + { + setAxes( this, ax1[0],ax1[1],ax1[2], NULL, axis2 ); + setAxes( this, ax2[0],ax2[1],ax2[2], axis1, NULL ); + } + else + { + setAxes( this, ax1[0],ax1[1],ax1[2], axis1, NULL ); + setAxes( this, ax2[0],ax2[1],ax2[2], NULL, axis2 ); + } + + computeInitialRelativeRotations(); +} + diff --git a/libs/ode-0.16.1/ode/src/joints/universal.h b/libs/ode-0.16.1/ode/src/joints/universal.h new file mode 100644 index 0000000..98e5468 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/joints/universal.h @@ -0,0 +1,64 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_JOINT_UNIVERSAL_H_ +#define _ODE_JOINT_UNIVERSAL_H_ + +#include "joint.h" + +// universal + +struct dxJointUniversal : public dxJoint +{ + dVector3 anchor1; // anchor w.r.t first body + dVector3 anchor2; // anchor w.r.t second body + dVector3 axis1; // axis w.r.t first body + dVector3 axis2; // axis w.r.t second body + dQuaternion qrel1; // initial relative rotation body1 -> virtual cross piece + dQuaternion qrel2; // initial relative rotation virtual cross piece -> body2 + dxJointLimitMotor limot1; // limit and motor information for axis1 + dxJointLimitMotor limot2; // limit and motor information for axis2 + + + void getAxes( dVector3 ax1, dVector3 ax2 ); + void getAngles( dReal *angle1, dReal *angle2 ); + dReal getAngle1(); + dReal getAngle2(); + void computeInitialRelativeRotations(); + + + dxJointUniversal( dxWorld *w ); + virtual void getSureMaxInfo( SureMaxInfo* info ); + virtual void getInfo1( Info1* info ); + virtual void getInfo2( dReal worldFPS, dReal worldERP, + int rowskip, dReal *J1, dReal *J2, + int pairskip, dReal *pairRhsCfm, dReal *pairLoHi, + int *findex); + virtual dJointType type() const; + virtual sizeint size() const; + + virtual void setRelativeValues(); +}; + + +#endif + diff --git a/libs/ode-0.16.1/ode/src/lcp.cpp b/libs/ode-0.16.1/ode/src/lcp.cpp new file mode 100644 index 0000000..58db0bd --- /dev/null +++ b/libs/ode-0.16.1/ode/src/lcp.cpp @@ -0,0 +1,1317 @@ +/*************************************************************************
+ * *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
+ * All rights reserved. Email: russ@q12.org Web: www.q12.org *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of EITHER: *
+ * (1) The GNU Lesser General Public License as published by the Free *
+ * Software Foundation; either version 2.1 of the License, or (at *
+ * your option) any later version. The text of the GNU Lesser *
+ * General Public License is included with this library in the *
+ * file LICENSE.TXT. *
+ * (2) The BSD-style license that is included with this library in *
+ * the file LICENSE-BSD.TXT. *
+ * *
+ * This library 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 files *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
+ * *
+ *************************************************************************/
+
+/*
+
+
+THE ALGORITHM
+-------------
+
+solve A*x = b+w, with x and w subject to certain LCP conditions.
+each x(i),w(i) must lie on one of the three line segments in the following
+diagram. each line segment corresponds to one index set :
+
+ w(i)
+ /|\ | :
+ | | :
+ | |i in N :
+ w>0 | |state[i]=0 :
+ | | :
+ | | : i in C
+ w=0 + +-----------------------+
+ | : |
+ | : |
+ w<0 | : |i in N
+ | : |state[i]=1
+ | : |
+ | : |
+ +-------|-----------|-----------|----------> x(i)
+ lo 0 hi
+
+the Dantzig algorithm proceeds as follows:
+ for i=1:n
+ * if (x(i),w(i)) is not on the line, push x(i) and w(i) positive or
+ negative towards the line. as this is done, the other (x(j),w(j))
+ for j<i are constrained to be on the line. if any (x,w) reaches the
+ end of a line segment then it is switched between index sets.
+ * i is added to the appropriate index set depending on what line segment
+ it hits.
+
+we restrict lo(i) <= 0 and hi(i) >= 0. this makes the algorithm a bit
+simpler, because the starting point for x(i),w(i) is always on the dotted
+line x=0 and x will only ever increase in one direction, so it can only hit
+two out of the three line segments.
+
+
+NOTES
+-----
+
+this is an implementation of "lcp_dantzig2_ldlt.m" and "lcp_dantzig_lohi.m".
+the implementation is split into an LCP problem object (dLCP) and an LCP
+driver function. most optimization occurs in the dLCP object.
+
+a naive implementation of the algorithm requires either a lot of data motion
+or a lot of permutation-array lookup, because we are constantly re-ordering
+rows and columns. to avoid this and make a more optimized algorithm, a
+non-trivial data structure is used to represent the matrix A (this is
+implemented in the fast version of the dLCP object).
+
+during execution of this algorithm, some indexes in A are clamped (set C),
+some are non-clamped (set N), and some are "don't care" (where x=0).
+A,x,b,w (and other problem vectors) are permuted such that the clamped
+indexes are first, the unclamped indexes are next, and the don't-care
+indexes are last. this permutation is recorded in the array `p'.
+initially p = 0..n-1, and as the rows and columns of A,x,b,w are swapped,
+the corresponding elements of p are swapped.
+
+because the C and N elements are grouped together in the rows of A, we can do
+lots of work with a fast dot product function. if A,x,etc were not permuted
+and we only had a permutation array, then those dot products would be much
+slower as we would have a permutation array lookup in some inner loops.
+
+A is accessed through an array of row pointers, so that element (i,j) of the
+permuted matrix is A[i][j]. this makes row swapping fast. for column swapping
+we still have to actually move the data.
+
+during execution of this algorithm we maintain an L*D*L' factorization of
+the clamped submatrix of A (call it `AC') which is the top left nC*nC
+submatrix of A. there are two ways we could arrange the rows/columns in AC.
+
+(1) AC is always permuted such that L*D*L' = AC. this causes a problem
+when a row/column is removed from C, because then all the rows/columns of A
+between the deleted index and the end of C need to be rotated downward.
+this results in a lot of data motion and slows things down.
+(2) L*D*L' is actually a factorization of a *permutation* of AC (which is
+itself a permutation of the underlying A). this is what we do - the
+permutation is recorded in the vector C. call this permutation A[C,C].
+when a row/column is removed from C, all we have to do is swap two
+rows/columns and manipulate C.
+
+*/
+
+#include <ode/common.h>
+#include <ode/misc.h>
+#include <ode/timer.h> // for testing
+#include "config.h"
+#include "lcp.h"
+#include "util.h"
+#include "matrix.h"
+#include "mat.h" // for testing
+#include "threaded_solver_ldlt.h"
+
+#include "fastdot_impl.h"
+#include "fastldltfactor_impl.h"
+#include "fastldltsolve_impl.h"
+
+
+//***************************************************************************
+// code generation parameters
+
+// LCP debugging (mostly for fast dLCP) - this slows things down a lot
+//#define DEBUG_LCP
+
+#define dLCP_FAST // use fast dLCP object
+
+#define NUB_OPTIMIZATIONS // use NUB optimizations
+
+
+// option 1 : matrix row pointers (less data copying)
+#define ROWPTRS
+#define ATYPE dReal **
+#define AROW(i) (m_A[i])
+
+// option 2 : no matrix row pointers (slightly faster inner loops)
+//#define NOROWPTRS
+//#define ATYPE dReal *
+//#define AROW(i) (m_A+(i)*m_nskip)
+
+
+//***************************************************************************
+
+#define dMIN(A,B) ((A)>(B) ? (B) : (A))
+#define dMAX(A,B) ((B)>(A) ? (B) : (A))
+
+
+#define LMATRIX_ALIGNMENT dMAX(64, EFFICIENT_ALIGNMENT)
+
+//***************************************************************************
+
+
+// transfer b-values to x-values
+template<bool zero_b>
+inline
+void transfer_b_to_x(dReal pairsbx[PBX__MAX], unsigned n)
+{
+ dReal *const endbx = pairsbx + (sizeint)n * PBX__MAX;
+ for (dReal *currbx = pairsbx; currbx != endbx; currbx += PBX__MAX) {
+ currbx[PBX_X] = currbx[PBX_B];
+ if (zero_b) {
+ currbx[PBX_B] = REAL(0.0);
+ }
+ }
+}
+
+// swap row/column i1 with i2 in the n*n matrix A. the leading dimension of
+// A is nskip. this only references and swaps the lower triangle.
+// if `do_fast_row_swaps' is nonzero and row pointers are being used, then
+// rows will be swapped by exchanging row pointers. otherwise the data will
+// be copied.
+
+static
+void swapRowsAndCols (ATYPE A, unsigned n, unsigned i1, unsigned i2, unsigned nskip,
+ int do_fast_row_swaps)
+{
+ dAASSERT (A && n > 0 && i1 >= 0 && i2 >= 0 && i1 < n && i2 < n &&
+ nskip >= n && i1 < i2);
+
+# ifdef ROWPTRS
+ dReal *A_i1 = A[i1];
+ dReal *A_i2 = A[i2];
+ for (unsigned i=i1+1; i<i2; ++i) {
+ dReal *A_i_i1 = A[i] + i1;
+ A_i1[i] = *A_i_i1;
+ *A_i_i1 = A_i2[i];
+ }
+ A_i1[i2] = A_i1[i1];
+ A_i1[i1] = A_i2[i1];
+ A_i2[i1] = A_i2[i2];
+ // swap rows, by swapping row pointers
+ if (do_fast_row_swaps) {
+ A[i1] = A_i2;
+ A[i2] = A_i1;
+ }
+ else {
+ // Only swap till i2 column to match A plain storage variant.
+ for (unsigned k = 0; k <= i2; ++k) {
+ dxSwap(A_i1[k], A_i2[k]);
+ }
+ }
+ // swap columns the hard way
+ for (unsigned j = i2 + 1; j < n; ++j) {
+ dReal *A_j = A[j];
+ dxSwap(A_j[i1], A_j[i2]);
+ }
+# else
+ dReal *A_i1 = A + (sizeint)nskip * i1;
+ dReal *A_i2 = A + (sizeint)nskip * i2;
+
+ for (unsigned k = 0; k < i1; ++k) {
+ dxSwap(A_i1[k], A_i2[k]);
+ }
+
+ dReal *A_i = A_i1 + nskip;
+ for (unsigned i= i1 + 1; i < i2; A_i += nskip, ++i) {
+ dxSwap(A_i2[i], A_i[i1]);
+ }
+
+ dxSwap(A_i1[i1], A_i2[i2]);
+
+ dReal *A_j = A_i2 + nskip;
+ for (unsigned j = i2 + 1; j < n; A_j += nskip, ++j) {
+ dxSwap(A_j[i1], A_j[i2]);
+ }
+# endif
+}
+
+
+// swap two indexes in the n*n LCP problem. i1 must be <= i2.
+
+static
+void swapProblem (ATYPE A, dReal pairsbx[PBX__MAX], dReal *w, dReal pairslh[PLH__MAX],
+ unsigned *p, bool *state, int *findex,
+ unsigned n, unsigned i1, unsigned i2, unsigned nskip,
+ int do_fast_row_swaps)
+{
+ dIASSERT (n>0 && i1 < n && i2 < n && nskip >= n && i1 <= i2);
+
+ if (i1 != i2) {
+ swapRowsAndCols (A, n, i1, i2, nskip, do_fast_row_swaps);
+
+ dxSwap((pairsbx + (sizeint)i1 * PBX__MAX)[PBX_B], (pairsbx + (sizeint)i2 * PBX__MAX)[PBX_B]);
+ dxSwap((pairsbx + (sizeint)i1 * PBX__MAX)[PBX_X], (pairsbx + (sizeint)i2 * PBX__MAX)[PBX_X]);
+ dSASSERT(PBX__MAX == 2);
+
+ dxSwap(w[i1], w[i2]);
+
+ dxSwap((pairslh + (sizeint)i1 * PLH__MAX)[PLH_LO], (pairslh + (sizeint)i2 * PLH__MAX)[PLH_LO]);
+ dxSwap((pairslh + (sizeint)i1 * PLH__MAX)[PLH_HI], (pairslh + (sizeint)i2 * PLH__MAX)[PLH_HI]);
+ dSASSERT(PLH__MAX == 2);
+
+ dxSwap(p[i1], p[i2]);
+ dxSwap(state[i1], state[i2]);
+
+ if (findex != NULL) {
+ dxSwap(findex[i1], findex[i2]);
+ }
+ }
+}
+
+
+// for debugging - check that L,d is the factorization of A[C,C].
+// A[C,C] has size nC*nC and leading dimension nskip.
+// L has size nC*nC and leading dimension nskip.
+// d has size nC.
+
+#ifdef DEBUG_LCP
+
+static
+void checkFactorization (ATYPE A, dReal *_L, dReal *_d,
+ unsigned nC, unsigned *C, unsigned nskip)
+{
+ unsigned i, j;
+ if (nC == 0) return;
+
+ // get A1=A, copy the lower triangle to the upper triangle, get A2=A[C,C]
+ dMatrix A1 (nC, nC);
+ for (i=0; i < nC; i++) {
+ for (j = 0; j <= i; j++) A1(i, j) = A1(j, i) = AROW(i)[j];
+ }
+ dMatrix A2 = A1.select (nC, C, nC, C);
+
+ // printf ("A1=\n"); A1.print(); printf ("\n");
+ // printf ("A2=\n"); A2.print(); printf ("\n");
+
+ // compute A3 = L*D*L'
+ dMatrix L (nC, nC, _L, nskip, 1);
+ dMatrix D (nC, nC);
+ for (i = 0; i < nC; i++) D(i, i) = 1.0 / _d[i];
+ L.clearUpperTriangle();
+ for (i = 0; i < nC; i++) L(i, i) = 1;
+ dMatrix A3 = L * D * L.transpose();
+
+ // printf ("L=\n"); L.print(); printf ("\n");
+ // printf ("D=\n"); D.print(); printf ("\n");
+ // printf ("A3=\n"); A2.print(); printf ("\n");
+
+ // compare A2 and A3
+ dReal diff = A2.maxDifference (A3);
+ if (diff > 1e-8)
+ dDebug (0, "L*D*L' check, maximum difference = %.6e\n", diff);
+}
+
+#endif
+
+
+// for debugging
+
+#ifdef DEBUG_LCP
+
+static
+void checkPermutations (unsigned i, unsigned n, unsigned nC, unsigned nN, unsigned *p, unsigned *C)
+{
+ unsigned j,k;
+ dIASSERT (/*nC >= 0 && nN >= 0 && */(nC + nN) == i && i < n);
+ for (k=0; k<i; k++) dIASSERT (p[k] >= 0 && p[k] < i);
+ for (k=i; k<n; k++) dIASSERT (p[k] == k);
+ for (j=0; j<nC; j++) {
+ int C_is_bad = 1;
+ for (k=0; k<nC; k++) if (C[k]==j) C_is_bad = 0;
+ dIASSERT (C_is_bad==0);
+ }
+}
+
+#endif
+
+//***************************************************************************
+// dLCP manipulator object. this represents an n*n LCP problem.
+//
+// two index sets C and N are kept. each set holds a subset of
+// the variable indexes 0..n-1. an index can only be in one set.
+// initially both sets are empty.
+//
+// the index set C is special: solutions to A(C,C)\A(C,i) can be generated.
+
+//***************************************************************************
+// fast implementation of dLCP. see the above definition of dLCP for
+// interface comments.
+//
+// `p' records the permutation of A,x,b,w,etc. p is initially 1:n and is
+// permuted as the other vectors/matrices are permuted.
+//
+// A,x,b,w,lo,hi,state,findex,p,c are permuted such that sets C,N have
+// contiguous indexes. the don't-care indexes follow N.
+//
+// an L*D*L' factorization is maintained of A(C,C), and whenever indexes are
+// added or removed from the set C the factorization is updated.
+// thus L*D*L'=A[C,C], i.e. a permuted top left nC*nC submatrix of A.
+// the leading dimension of the matrix L is always `nskip'.
+//
+// at the start there may be other indexes that are unbounded but are not
+// included in `nub'. dLCP will permute the matrix so that absolutely all
+// unbounded vectors are at the start. thus there may be some initial
+// permutation.
+//
+// the algorithms here assume certain patterns, particularly with respect to
+// index transfer.
+
+#ifdef dLCP_FAST
+
+struct dLCP {
+ const unsigned m_n;
+ const unsigned m_nskip;
+ unsigned m_nub;
+ unsigned m_nC, m_nN; // size of each index set
+ ATYPE const m_A; // A rows
+ dReal *const m_pairsbx, *const m_w, *const m_pairslh; // permuted LCP problem data
+ dReal *const m_L, *const m_d; // L*D*L' factorization of set C
+ dReal *const m_Dell, *const m_ell, *const m_tmp;
+ bool *const m_state;
+ int *const m_findex;
+ unsigned *const m_p, *const m_C;
+
+ dLCP (unsigned _n, unsigned _nskip, unsigned _nub, dReal *_Adata, dReal *_pairsbx, dReal *_w,
+ dReal *_pairslh, dReal *_L, dReal *_d,
+ dReal *_Dell, dReal *_ell, dReal *_tmp,
+ bool *_state, int *_findex, unsigned *_p, unsigned *_C, dReal **Arows);
+ unsigned getNub() const { return m_nub; }
+ void transfer_i_to_C (unsigned i);
+ void transfer_i_to_N (unsigned /*i*/) { m_nN++; } // because we can assume C and N span 1:i-1
+ void transfer_i_from_N_to_C (unsigned i);
+ void transfer_i_from_C_to_N (unsigned i, void *tmpbuf);
+ static sizeint estimate_transfer_i_from_C_to_N_mem_req(unsigned nC, unsigned nskip) { return dEstimateLDLTRemoveTmpbufSize(nC, nskip); }
+ unsigned numC() const { return m_nC; }
+ unsigned numN() const { return m_nN; }
+ unsigned indexC (unsigned i) const { return i; }
+ unsigned indexN (unsigned i) const { return i+m_nC; }
+ dReal Aii (unsigned i) const { return AROW(i)[i]; }
+ template<unsigned q_stride>
+ dReal AiC_times_qC (unsigned i, dReal *q) const { return calculateLargeVectorDot<q_stride> (AROW(i), q, m_nC); }
+ template<unsigned q_stride>
+ dReal AiN_times_qN (unsigned i, dReal *q) const { return calculateLargeVectorDot<q_stride> (AROW(i) + m_nC, q + (sizeint)m_nC * q_stride, m_nN); }
+ void pN_equals_ANC_times_qC (dReal *p, dReal *q);
+ void pN_plusequals_ANi (dReal *p, unsigned i, bool dir_positive);
+ template<unsigned p_stride>
+ void pC_plusequals_s_times_qC (dReal *p, dReal s, dReal *q);
+ void pN_plusequals_s_times_qN (dReal *p, dReal s, dReal *q);
+ void solve1 (dReal *a, unsigned i, bool dir_positive, int only_transfer=0);
+ void unpermute_X();
+ void unpermute_W();
+};
+
+
+dLCP::dLCP (unsigned _n, unsigned _nskip, unsigned _nub, dReal *_Adata, dReal *_pairsbx, dReal *_w,
+ dReal *_pairslh, dReal *_L, dReal *_d,
+ dReal *_Dell, dReal *_ell, dReal *_tmp,
+ bool *_state, int *_findex, unsigned *_p, unsigned *_C, dReal **Arows):
+ m_n(_n), m_nskip(_nskip), m_nub(_nub), m_nC(0), m_nN(0),
+# ifdef ROWPTRS
+ m_A(Arows),
+#else
+ m_A(_Adata),
+#endif
+ m_pairsbx(_pairsbx), m_w(_w), m_pairslh(_pairslh),
+ 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)
+{
+ dxtSetZero<PBX__MAX>(m_pairsbx + PBX_X, m_n);
+
+ {
+# ifdef ROWPTRS
+ // make matrix row pointers
+ dReal *aptr = _Adata;
+ ATYPE A = m_A;
+ const unsigned n = m_n, nskip = m_nskip;
+ for (unsigned k=0; k<n; aptr+=nskip, ++k) A[k] = aptr;
+# endif
+ }
+
+ {
+ unsigned *p = m_p;
+ const unsigned n = m_n;
+ for (unsigned k=0; k != n; ++k) p[k] = k; // initially unpermutted
+ }
+
+ /*
+ // for testing, we can do some random swaps in the area i > nub
+ {
+ const unsigned n = m_n;
+ const unsigned nub = m_nub;
+ if (nub < n) {
+ for (unsigned k=0; k<100; k++) {
+ unsigned i1,i2;
+ do {
+ i1 = dRandInt(n-nub)+nub;
+ i2 = dRandInt(n-nub)+nub;
+ }
+ while (i1 > i2);
+ //printf ("--> %d %d\n",i1,i2);
+ swapProblem (m_A, m_pairsbx, m_w, m_pairslh, m_p, m_state, m_findex, n, i1, i2, m_nskip, 0);
+ }
+ }
+ */
+
+ // 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;
+ dReal *pairslh = m_pairslh;
+ const unsigned n = m_n;
+ for (unsigned k = m_nub; k < n; ++k) {
+ if (findex && findex[k] >= 0) continue;
+ if ((pairslh + (sizeint)k * PLH__MAX)[PLH_LO] == -dInfinity && (pairslh + (sizeint)k * PLH__MAX)[PLH_HI] == dInfinity) {
+ swapProblem (m_A, m_pairsbx, m_w, pairslh, 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 unsigned nub = m_nub;
+ {
+ dReal *Lrow = m_L;
+ const unsigned nskip = m_nskip;
+ for (unsigned j = 0; j < nub; Lrow += nskip, ++j) memcpy(Lrow, AROW(j), (j + 1) * sizeof(dReal));
+ }
+ transfer_b_to_x<false> (m_pairsbx, nub);
+ factorMatrixAsLDLT<1> (m_L, m_d, nub, m_nskip);
+ solveEquationSystemWithLDLT<1, PBX__MAX> (m_L, m_d, m_pairsbx + PBX_X, nub, m_nskip);
+ dSetZero (m_w, nub);
+ {
+ unsigned *C = m_C;
+ for (unsigned 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 unsigned nub = m_nub;
+ int *findex = m_findex;
+ unsigned num_at_end = 0;
+ for (unsigned k = m_n; k > nub; ) {
+ --k;
+ if (findex[k] >= 0) {
+ swapProblem (m_A, m_pairsbx, m_w, m_pairslh, m_p, m_state, findex, m_n, k, m_n - 1 - num_at_end, m_nskip, 1);
+ num_at_end++;
+ }
+ }
+ }
+
+ // print info about indexes
+ /*
+ {
+ const unsigned n = m_n;
+ const unsigned nub = m_nub;
+ for (unsigned k=0; k<n; k++) {
+ if (k<nub) printf ("C");
+ else if ((m_pairslh + (sizeint)k * PLH__MAX)[PLH_LO] == -dInfinity && (m_pairslh + (sizeint)k * PLH__MAX)[PLH_HI] == dInfinity) printf ("c");
+ else printf (".");
+ }
+ printf ("\n");
+ }
+ */
+}
+
+
+void dLCP::transfer_i_to_C (unsigned i)
+{
+ {
+ const unsigned nC = m_nC;
+
+ if (nC > 0) {
+ // ell,Dell were computed by solve1(). note, ell = D \ L1solve (L,A(i,C))
+ dReal *const Ltgt = m_L + (sizeint)m_nskip * nC, *ell = m_ell;
+ memcpy(Ltgt, ell, nC * sizeof(dReal));
+
+ dReal ell_Dell_dot = dxDot(m_ell, m_Dell, nC);
+ dReal AROW_i_i = AROW(i)[i] != ell_Dell_dot ? AROW(i)[i] : dNextAfter(AROW(i)[i], dInfinity); // A hack to avoid getting a zero in the denominator
+ m_d[nC] = dRecip (AROW_i_i - ell_Dell_dot);
+ }
+ else {
+ m_d[0] = dRecip (AROW(i)[i]);
+ }
+
+ swapProblem (m_A, m_pairsbx, m_w, m_pairslh, m_p, m_state, m_findex, m_n, nC, i, m_nskip, 1);
+
+ m_C[nC] = nC;
+ m_nC = nC + 1; // nC value is outdated after this line
+ }
+
+# ifdef DEBUG_LCP
+ checkFactorization (m_A, m_L, m_d, m_nC, m_C, m_nskip);
+ if (i < (m_n-1)) checkPermutations (i+1, m_n, m_nC, m_nN, m_p, m_C);
+# endif
+}
+
+
+void dLCP::transfer_i_from_N_to_C (unsigned i)
+{
+ {
+ const unsigned nC = m_nC;
+ if (nC > 0) {
+ {
+ dReal *const aptr = AROW(i);
+ dReal *Dell = m_Dell;
+ const unsigned *C = m_C;
+# ifdef NUB_OPTIMIZATIONS
+ // if nub>0, initial part of aptr unpermuted
+ const unsigned nub = m_nub;
+ unsigned j=0;
+ for ( ; j<nub; ++j) Dell[j] = aptr[j];
+ for ( ; j<nC; ++j) Dell[j] = aptr[C[j]];
+# else
+ for (unsigned j=0; j<nC; ++j) Dell[j] = aptr[C[j]];
+# endif
+ }
+ solveL1Straight<1>(m_L, m_Dell, nC, m_nskip);
+
+ dReal ell_Dell_dot = REAL(0.0);
+ dReal *const Ltgt = m_L + (sizeint)m_nskip * nC;
+ dReal *ell = m_ell, *Dell = m_Dell, *d = m_d;
+ for (unsigned j = 0; j < nC; ++j) {
+ dReal ell_j, Dell_j = Dell[j];
+ Ltgt[j] = ell[j] = ell_j = Dell_j * d[j];
+ ell_Dell_dot += ell_j * Dell_j;
+ }
+
+ dReal AROW_i_i = AROW(i)[i] != ell_Dell_dot ? AROW(i)[i] : dNextAfter(AROW(i)[i], dInfinity); // A hack to avoid getting a zero in the denominator
+ m_d[nC] = dRecip (AROW_i_i - ell_Dell_dot);
+ }
+ else {
+ m_d[0] = dRecip (AROW(i)[i]);
+ }
+
+ swapProblem (m_A, m_pairsbx, m_w, m_pairslh, m_p, m_state, m_findex, m_n, nC, i, m_nskip, 1);
+
+ 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.
+
+# ifdef DEBUG_LCP
+ checkFactorization (m_A,m_L,m_d,m_nC,m_C,m_nskip);
+# endif
+}
+
+
+void dLCP::transfer_i_from_C_to_N (unsigned i, void *tmpbuf)
+{
+ {
+ unsigned *C = m_C;
+ // remove a row/column from the factorization, and adjust the
+ // indexes (black magic!)
+ int last_idx = -1;
+ const unsigned nC = m_nC;
+ unsigned j = 0;
+ for ( ; j < nC; ++j) {
+ if (C[j] == nC - 1) {
+ last_idx = j;
+ }
+ if (C[j] == i) {
+ dxLDLTRemove (m_A, C, m_L, m_d, m_n, nC, j, m_nskip, tmpbuf);
+ unsigned k;
+ if (last_idx == -1) {
+ for (k = j + 1 ; k < nC; ++k) {
+ if (C[k] == nC - 1) {
+ break;
+ }
+ }
+ dIASSERT (k < nC);
+ }
+ else {
+ k = last_idx;
+ }
+ C[k] = C[j];
+ if (j != (nC - 1)) memmove (C + j, C + j + 1, (nC - j - 1) * sizeof(C[0]));
+ break;
+ }
+ }
+ dIASSERT (j < nC);
+
+ swapProblem (m_A, m_pairsbx, m_w, m_pairslh, m_p, m_state, m_findex, m_n, i, nC - 1, m_nskip, 1);
+
+ m_nN++;
+ m_nC = nC - 1; // nC value is outdated after this line
+ }
+
+# ifdef DEBUG_LCP
+ checkFactorization (m_A, m_L, m_d, m_nC, m_C, m_nskip);
+# endif
+}
+
+
+void dLCP::pN_equals_ANC_times_qC (dReal *p, dReal *q)
+{
+ // we could try to make this matrix-vector multiplication faster using
+ // outer product matrix tricks, e.g. with the dMultidotX() functions.
+ // but i tried it and it actually made things slower on random 100x100
+ // problems because of the overhead involved. so we'll stick with the
+ // simple method for now.
+ const unsigned nC = m_nC;
+ dReal *ptgt = p + nC;
+ const unsigned nN = m_nN;
+ for (unsigned i = 0; i < nN; ++i) {
+ ptgt[i] = dxDot (AROW(i + nC), q, nC);
+ }
+}
+
+
+void dLCP::pN_plusequals_ANi (dReal *p, unsigned i, bool dir_positive)
+{
+ const unsigned nC = m_nC;
+ dReal *aptr = AROW(i) + nC;
+ dReal *ptgt = p + nC;
+ if (dir_positive) {
+ const unsigned nN = m_nN;
+ for (unsigned j=0; j < nN; ++j) ptgt[j] += aptr[j];
+ }
+ else {
+ const unsigned nN = m_nN;
+ for (unsigned j=0; j < nN; ++j) ptgt[j] -= aptr[j];
+ }
+}
+
+template<unsigned p_stride>
+void dLCP::pC_plusequals_s_times_qC (dReal *p, dReal s, dReal *q)
+{
+ const unsigned nC = m_nC;
+ dReal *q_end = q + nC;
+ for (; q != q_end; p += p_stride, ++q) {
+ *p += s * (*q);
+ }
+}
+
+void dLCP::pN_plusequals_s_times_qN (dReal *p, dReal s, dReal *q)
+{
+ const unsigned nC = m_nC;
+ dReal *ptgt = p + nC, *qsrc = q + nC;
+ const unsigned nN = m_nN;
+ for (unsigned i = 0; i < nN; ++i) {
+ ptgt[i] += s * qsrc[i];
+ }
+}
+
+void dLCP::solve1 (dReal *a, unsigned i, bool dir_positive, int only_transfer)
+{
+ // the `Dell' and `ell' that are computed here are saved. if index i is
+ // later added to the factorization then they can be reused.
+ //
+ // @@@ question: do we need to solve for entire delta_x??? yes, but
+ // only if an x goes below 0 during the step.
+
+ const unsigned nC = m_nC;
+ if (nC > 0) {
+ {
+ dReal *Dell = m_Dell;
+ unsigned *C = m_C;
+ dReal *aptr = AROW(i);
+# ifdef NUB_OPTIMIZATIONS
+ // if nub>0, initial part of aptr[] is guaranteed unpermuted
+ const unsigned nub = m_nub;
+ unsigned j = 0;
+ for ( ; j < nub; ++j) Dell[j] = aptr[j];
+ for ( ; j < nC; ++j) Dell[j] = aptr[C[j]];
+# else
+ for (unsigned j = 0; j < nC; ++j) Dell[j] = aptr[C[j]];
+# endif
+ }
+ solveL1Straight<1>(m_L, m_Dell, nC, m_nskip);
+ {
+ dReal *ell = m_ell, *Dell = m_Dell, *d = m_d;
+ for (unsigned j = 0; j < nC; ++j) ell[j] = Dell[j] * d[j];
+ }
+
+ if (!only_transfer) {
+ dReal *tmp = m_tmp, *ell = m_ell;
+ {
+ for (unsigned j = 0; j < nC; ++j) tmp[j] = ell[j];
+ }
+ solveL1Transposed<1>(m_L, tmp, nC, m_nskip);
+ if (dir_positive) {
+ unsigned *C = m_C;
+ dReal *tmp = m_tmp;
+ for (unsigned j = 0; j < nC; ++j) a[C[j]] = -tmp[j];
+ } else {
+ unsigned *C = m_C;
+ dReal *tmp = m_tmp;
+ for (unsigned j = 0; j < nC; ++j) a[C[j]] = tmp[j];
+ }
+ }
+ }
+}
+
+
+void dLCP::unpermute_X()
+{
+ unsigned *p = m_p;
+ dReal *pairsbx = m_pairsbx;
+ const unsigned n = m_n;
+ for (unsigned j = 0; j < n; ++j) {
+ unsigned k = p[j];
+ if (k != j) {
+ // p[j] = j; -- not going to be checked anymore anyway
+ dReal x_j = (pairsbx + (sizeint)j * PBX__MAX)[PBX_X];
+ for (;;) {
+ dxSwap(x_j, (pairsbx + (sizeint)k * PBX__MAX)[PBX_X]);
+
+ unsigned orig_k = p[k];
+ p[k] = k;
+ if (orig_k == j) {
+ break;
+ }
+ k = orig_k;
+ }
+ (pairsbx + (sizeint)j * PBX__MAX)[PBX_X] = x_j;
+ }
+ }
+}
+
+void dLCP::unpermute_W()
+{
+ memcpy (m_tmp, m_w, m_n * sizeof(dReal));
+
+ const unsigned *p = m_p;
+ dReal *w = m_w, *tmp = m_tmp;
+ const unsigned n = m_n;
+ for (unsigned j = 0; j < n; ++j) {
+ unsigned k = p[j];
+ w[k] = tmp[j];
+ }
+}
+
+#endif // dLCP_FAST
+
+
+static void dxSolveLCP_AllUnbounded (dxWorldProcessMemArena *memarena, unsigned n, dReal *A, dReal pairsbx[PBX__MAX]);
+static void dxSolveLCP_Generic (dxWorldProcessMemArena *memarena, unsigned n, dReal *A, dReal pairsbx[PBX__MAX],
+ dReal *outer_w/*=NULL*/, unsigned nub, dReal pairslh[PLH__MAX], int *findex);
+
+/*extern */
+void dxSolveLCP (dxWorldProcessMemArena *memarena, unsigned n, dReal *A, dReal pairsbx[PBX__MAX],
+ dReal *outer_w/*=NULL*/, unsigned nub, dReal pairslh[PLH__MAX], int *findex)
+{
+ if (nub >= n)
+ {
+ dxSolveLCP_AllUnbounded (memarena, n, A, pairsbx);
+ }
+ else
+ {
+ dxSolveLCP_Generic (memarena, n, A, pairsbx, outer_w, nub, pairslh, findex);
+ }
+}
+
+//***************************************************************************
+// if all the variables are unbounded then we can just factor, solve, and return
+
+static
+void dxSolveLCP_AllUnbounded (dxWorldProcessMemArena *memarena, unsigned n, dReal *A, dReal pairsbx[PBX__MAX])
+{
+ dAASSERT(A != NULL);
+ dAASSERT(pairsbx != NULL);
+ dAASSERT(n != 0);
+
+ transfer_b_to_x<true>(pairsbx, n);
+
+ unsigned nskip = dPAD(n);
+ factorMatrixAsLDLT<PBX__MAX> (A, pairsbx + PBX_B, n, nskip);
+ solveEquationSystemWithLDLT<PBX__MAX, PBX__MAX> (A, pairsbx + PBX_B, pairsbx + PBX_X, n, nskip);
+}
+
+//***************************************************************************
+// an optimized Dantzig LCP driver routine for the lo-hi LCP problem.
+
+static
+void dxSolveLCP_Generic (dxWorldProcessMemArena *memarena, unsigned n, dReal *A, dReal pairsbx[PBX__MAX],
+ dReal *outer_w/*=NULL*/, unsigned nub, dReal pairslh[PLH__MAX], int *findex)
+{
+ dAASSERT (n > 0 && A && pairsbx && pairslh && nub >= 0 && nub < n);
+# ifndef dNODEBUG
+ {
+ // check restrictions on lo and hi
+ dReal *endlh = pairslh + (sizeint)n * PLH__MAX;
+ for (dReal *currlh = pairslh; currlh != endlh; currlh += PLH__MAX) dIASSERT (currlh[PLH_LO] <= 0 && currlh[PLH_HI] >= 0);
+ }
+# endif
+
+ const unsigned nskip = dPAD(n);
+ dReal *L = memarena->AllocateOveralignedArray<dReal> ((sizeint)nskip * n, LMATRIX_ALIGNMENT);
+ dReal *d = memarena->AllocateArray<dReal> (n);
+ dReal *w = outer_w != NULL ? outer_w : memarena->AllocateArray<dReal> (n);
+ dReal *delta_w = memarena->AllocateArray<dReal> (n);
+ dReal *delta_x = memarena->AllocateArray<dReal> (n);
+ dReal *Dell = memarena->AllocateArray<dReal> (n);
+ dReal *ell = memarena->AllocateArray<dReal> (n);
+#ifdef ROWPTRS
+ dReal **Arows = memarena->AllocateArray<dReal *> (n);
+#else
+ dReal **Arows = NULL;
+#endif
+ unsigned *p = memarena->AllocateArray<unsigned> (n);
+ unsigned *C = memarena->AllocateArray<unsigned> (n);
+
+ // for i in N, state[i] is 0 if x(i)==lo(i) or 1 if x(i)==hi(i)
+ bool *state = memarena->AllocateArray<bool> (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!
+ dLCP lcp(n, nskip, nub, A, pairsbx, w, pairslh, L, d, Dell, ell, delta_w, state, findex, p, C, Arows);
+ unsigned 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 (unsigned i = adj_nub; i < n; ++i) {
+ bool 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 (unsigned j = 0; j < n; ++j) delta_w[p[j]] = (pairsbx + (sizeint)j * PBX__MAX)[PBX_X];
+
+ // set lo and hi values
+ for (unsigned k = i; k < n; ++k) {
+ dReal *currlh = pairslh + (sizeint)k * PLH__MAX;
+ dReal wfk = delta_w[findex[k]];
+ if (wfk == 0) {
+ currlh[PLH_HI] = 0;
+ currlh[PLH_LO] = 0;
+ }
+ else {
+ currlh[PLH_HI] = dFabs (currlh[PLH_HI] * wfk);
+ currlh[PLH_LO] = -currlh[PLH_HI];
+ }
+ }
+ 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.
+ dReal wPrep = lcp.AiC_times_qC<PBX__MAX> (i, pairsbx + PBX_X) + lcp.AiN_times_qN<PBX__MAX> (i, pairsbx + PBX_X);
+
+ dReal *currbx = pairsbx + (sizeint)i * PBX__MAX;
+
+ w[i] = wPrep - currbx[PBX_B];
+
+ // 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.
+
+ dReal *currlh = pairslh + (sizeint)i * PLH__MAX;
+
+ // see if x(i),w(i) is in a valid region
+ if (currlh[PLH_LO] == 0 && w[i] >= 0) {
+ lcp.transfer_i_to_N (i);
+ state[i] = false;
+ }
+ else if (currlh[PLH_HI] == 0 && w[i] <= 0) {
+ lcp.transfer_i_to_N (i);
+ 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 (delta_x, i, false, 1);
+
+ lcp.transfer_i_to_C (i);
+ }
+ else {
+ // we must push x(i) and w(i)
+ for (;;) {
+ // find direction to push on x(i)
+ bool dir_positive = (w[i] <= 0);
+
+ // compute: delta_x(C) = -dir*A(C,C)\A(C,i)
+ lcp.solve1 (delta_x, i, dir_positive);
+
+ // note that delta_x[i] = (dir_positive ? 1 : -1), 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 (delta_w, delta_x);
+ lcp.pN_plusequals_ANi (delta_w, i, dir_positive);
+ delta_w[i] = dir_positive
+ ? lcp.AiC_times_qC<1> (i, delta_x) + lcp.Aii(i)
+ : lcp.AiC_times_qC<1> (i, delta_x) - lcp.Aii(i);
+
+ // 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
+ unsigned si = 0; // si = index to switch if cmd>3
+
+ dReal s = delta_w[i] != REAL(0.0)
+ ? -w[i] / delta_w[i]
+ : (w[i] != REAL(0.0) ? dCopySign(dInfinity, -w[i]) : REAL(0.0));
+
+ if (dir_positive) {
+ if (currlh[PLH_HI] < dInfinity) {
+ dReal s2 = (currlh[PLH_HI] - currbx[PBX_X]); // was (hi[i]-x[i])/dirf // step to x(i)=hi(i)
+ if (s2 < s) {
+ s = s2;
+ cmd = 3;
+ }
+ }
+ }
+ else {
+ if (currlh[PLH_LO] > -dInfinity) {
+ dReal s2 = (currbx[PBX_X] - currlh[PLH_LO]); // was (lo[i]-x[i])/dirf // step to x(i)=lo(i)
+ if (s2 < s) {
+ s = s2;
+ cmd = 2;
+ }
+ }
+ }
+
+ {
+ const unsigned numN = lcp.numN();
+ for (unsigned k = 0; k < numN; ++k) {
+ const unsigned indexN_k = lcp.indexN(k);
+ if (!state[indexN_k] ? delta_w[indexN_k] < 0 : delta_w[indexN_k] > 0) {
+ // don't bother checking if lo=hi=0
+ dReal *indexlh = pairslh + (sizeint)indexN_k * PLH__MAX;
+ if (indexlh[PLH_LO] == 0 && indexlh[PLH_HI] == 0) continue;
+ dReal s2 = -w[indexN_k] / delta_w[indexN_k];
+ if (s2 < s) {
+ s = s2;
+ cmd = 4;
+ si = indexN_k;
+ }
+ }
+ }
+ }
+
+ {
+ const unsigned numC = lcp.numC();
+ for (unsigned k = adj_nub; k < numC; ++k) {
+ const unsigned indexC_k = lcp.indexC(k);
+ dReal *indexlh = pairslh + (sizeint)indexC_k * PLH__MAX;
+ if (delta_x[indexC_k] < 0 && indexlh[PLH_LO] > -dInfinity) {
+ dReal s2 = (indexlh[PLH_LO] - (pairsbx + (sizeint)indexC_k * PBX__MAX)[PBX_X]) / delta_x[indexC_k];
+ if (s2 < s) {
+ s = s2;
+ cmd = 5;
+ si = indexC_k;
+ }
+ }
+ if (delta_x[indexC_k] > 0 && indexlh[PLH_HI] < dInfinity) {
+ dReal s2 = (indexlh[PLH_HI] - (pairsbx + (sizeint)indexC_k * PBX__MAX)[PBX_X]) / 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 <= REAL(0.0)) {
+ dMessage (d_ERR_LCP, "LCP internal error, s <= 0 (s=%.4e)",(double)s);
+ if (i < n) {
+ dxtSetZero<PBX__MAX>(currbx + PBX_X, n - i);
+ dxSetZero (w + i, n - i);
+ }
+ s_error = true;
+ break;
+ }
+
+ // apply x = x + s * delta_x
+ lcp.pC_plusequals_s_times_qC<PBX__MAX> (pairsbx + PBX_X, s, delta_x);
+ currbx[PBX_X] = dir_positive
+ ? currbx[PBX_X] + s
+ : currbx[PBX_X] - s;
+
+ // apply w = w + s * delta_w
+ lcp.pN_plusequals_s_times_qN (w, s, delta_w);
+ w[i] += s * 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
+ currbx[PBX_X] = currlh[PLH_LO];
+ state[i] = false;
+ lcp.transfer_i_to_N (i);
+ break;
+ case 3: // done
+ currbx[PBX_X] = currlh[PLH_HI];
+ 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
+ (pairsbx + (sizeint)si * PBX__MAX)[PBX_X] = (pairslh + (sizeint)si * PLH__MAX)[PLH_LO];
+ state[si] = false;
+ tmpbuf = memarena->PeekBufferRemainder();
+ lcp.transfer_i_from_C_to_N (si, tmpbuf);
+ break;
+ case 6: // keep going
+ (pairsbx + (sizeint)si * PBX__MAX)[PBX_X] = (pairslh + (sizeint)si * PLH__MAX)[PLH_HI];
+ state[si] = true;
+ tmpbuf = memarena->PeekBufferRemainder();
+ lcp.transfer_i_from_C_to_N (si, tmpbuf);
+ break;
+ }
+
+ if (cmd <= 3) break;
+ } // for (;;)
+ } // else
+
+ if (s_error) {
+ break;
+ }
+ } // for (unsigned i = adj_nub; i < n; ++i)
+
+ // now we have to un-permute x and w
+ if (outer_w != NULL) {
+ lcp.unpermute_W();
+ }
+ lcp.unpermute_X(); // This destroys p[] and must be done last
+}
+
+sizeint dxEstimateSolveLCPMemoryReq(unsigned n, bool outer_w_avail)
+{
+ const unsigned nskip = dPAD(n);
+
+ sizeint res = 0;
+
+ res += dOVERALIGNED_SIZE(sizeof(dReal) * ((sizeint)n * nskip), LMATRIX_ALIGNMENT); // for L
+ res += 5 * dEFFICIENT_SIZE(sizeof(dReal) * n); // for d, delta_w, delta_x, Dell, ell
+ if (!outer_w_avail) {
+ res += dEFFICIENT_SIZE(sizeof(dReal) * n); // for w
+ }
+#ifdef ROWPTRS
+ res += dEFFICIENT_SIZE(sizeof(dReal *) * n); // for Arows
+#endif
+ res += 2 * dEFFICIENT_SIZE(sizeof(unsigned) * n); // for p, C
+ res += dEFFICIENT_SIZE(sizeof(bool) * n); // for state
+
+ // Use n instead of nC as nC varies at runtime while n is greater or equal to nC
+ sizeint lcp_transfer_req = dLCP::estimate_transfer_i_from_C_to_N_mem_req(n, nskip);
+ res += dEFFICIENT_SIZE(lcp_transfer_req); // for dLCP::transfer_i_from_C_to_N
+
+ return res;
+}
+
+
+//***************************************************************************
+// accuracy and timing test
+
+static sizeint EstimateTestSolveLCPMemoryReq(unsigned n)
+{
+ const unsigned nskip = dPAD(n);
+
+ sizeint res = 0;
+
+ res += 2 * dEFFICIENT_SIZE(sizeof(dReal) * ((sizeint)n * nskip)); // for A, A2
+ res += 7 * dEFFICIENT_SIZE(sizeof(dReal) * n); // for x, b, w, lo, hi, tmp1, tmp2
+ res += dEFFICIENT_SIZE(sizeof(dReal) * PBX__MAX * n); // for pairsbx,
+ res += dEFFICIENT_SIZE(sizeof(dReal) * PLH__MAX * n); // for pairslh
+
+ res += dxEstimateSolveLCPMemoryReq(n, true);
+
+ return res;
+}
+
+extern "C" ODE_API int dTestSolveLCP()
+{
+ const unsigned n = 100;
+
+ sizeint memreq = EstimateTestSolveLCPMemoryReq(n);
+ dxWorldProcessMemArena *arena = dxAllocateTemporaryWorldProcessMemArena(memreq, NULL, NULL);
+ if (arena == NULL) {
+ return 0;
+ }
+ arena->ResetState();
+
+ unsigned i,nskip = dPAD(n);
+#ifdef dDOUBLE
+ const dReal tol = REAL(1e-9);
+#endif
+#ifdef dSINGLE
+ const dReal tol = REAL(1e-4);
+#endif
+ printf ("dTestSolveLCP()\n");
+
+ dReal *A = arena->AllocateArray<dReal> (n*nskip);
+ dReal *x = arena->AllocateArray<dReal> (n);
+ dReal *b = arena->AllocateArray<dReal> (n);
+ dReal *w = arena->AllocateArray<dReal> (n);
+ dReal *lo = arena->AllocateArray<dReal> (n);
+ dReal *hi = arena->AllocateArray<dReal> (n);
+
+ dReal *A2 = arena->AllocateArray<dReal> (n*nskip);
+ dReal *pairsbx = arena->AllocateArray<dReal> (n * PBX__MAX);
+ dReal *pairslh = arena->AllocateArray<dReal> (n * PLH__MAX);
+
+ dReal *tmp1 = arena->AllocateArray<dReal> (n);
+ dReal *tmp2 = arena->AllocateArray<dReal> (n);
+
+ double total_time = 0;
+ for (unsigned count=0; count < 1000; count++) {
+ BEGIN_STATE_SAVE(arena, saveInner) {
+
+ // form (A,b) = a random positive definite LCP problem
+ dMakeRandomMatrix (A2,n,n,1.0);
+ dMultiply2 (A,A2,A2,n,n,n);
+ dMakeRandomMatrix (x,n,1,1.0);
+ dMultiply0 (b,A,x,n,n,1);
+ for (i=0; i<n; i++) b[i] += (dRandReal()*REAL(0.2))-REAL(0.1);
+
+ // choose `nub' in the range 0..n-1
+ unsigned nub = 50; //dRandInt (n);
+
+ // make limits
+ for (i=0; i<nub; i++) lo[i] = -dInfinity;
+ for (i=0; i<nub; i++) hi[i] = dInfinity;
+ //for (i=nub; i<n; i++) lo[i] = 0;
+ //for (i=nub; i<n; i++) hi[i] = dInfinity;
+ //for (i=nub; i<n; i++) lo[i] = -dInfinity;
+ //for (i=nub; i<n; i++) hi[i] = 0;
+ for (i=nub; i<n; i++) lo[i] = -(dRandReal()*REAL(1.0))-REAL(0.01);
+ for (i=nub; i<n; i++) hi[i] = (dRandReal()*REAL(1.0))+REAL(0.01);
+
+ // set a few limits to lo=hi=0
+ /*
+ for (i=0; i<10; i++) {
+ unsigned j = dRandInt (n-nub) + nub;
+ lo[j] = 0;
+ hi[j] = 0;
+ }
+ */
+
+ // solve the LCP. we must make copy of A,b,lo,hi (A2,b2,lo2,hi2) for
+ // SolveLCP() to permute. also, we'll clear the upper triangle of A2 to
+ // ensure that it doesn't get referenced (if it does, the answer will be
+ // wrong).
+
+ memcpy (A2, A, n * nskip * sizeof(dReal));
+ dClearUpperTriangle (A2, n);
+ for (i = 0; i != n; ++i) {
+ dReal *currbx = pairsbx + i * PBX__MAX;
+ currbx[PBX_B] = b[i];
+ currbx[PBX_X] = 0;
+ }
+ for (i = 0; i != n; ++i) {
+ dReal *currlh = pairslh + i * PLH__MAX;
+ currlh[PLH_LO] = lo[i];
+ currlh[PLH_HI] = hi[i];
+ }
+ dSetZero (w,n);
+
+ dStopwatch sw;
+ dStopwatchReset (&sw);
+ dStopwatchStart (&sw);
+
+ dxSolveLCP (arena,n,A2,pairsbx,w,nub,pairslh,0);
+
+ dStopwatchStop (&sw);
+ double time = dStopwatchTime(&sw);
+ total_time += time;
+ double average = total_time / double(count+1) * 1000.0;
+
+ for (i = 0; i != n; ++i) {
+ const dReal *currbx = pairsbx + i * PBX__MAX;
+ x[i] = currbx[PBX_X];
+ }
+
+ // check the solution
+
+ dMultiply0 (tmp1,A,x,n,n,1);
+ for (i=0; i<n; i++) tmp2[i] = b[i] + w[i];
+ dReal diff = dMaxDifference (tmp1,tmp2,n,1);
+ // printf ("\tA*x = b+w, maximum difference = %.6e - %s (1)\n",diff,
+ // diff > tol ? "FAILED" : "passed");
+ if (diff > tol) dDebug (0,"A*x = b+w, maximum difference = %.6e",diff);
+ unsigned n1=0,n2=0,n3=0;
+ for (i=0; i<n; i++) {
+ if (x[i]==lo[i] && w[i] >= 0) {
+ n1++; // ok
+ }
+ else if (x[i]==hi[i] && w[i] <= 0) {
+ n2++; // ok
+ }
+ else if (x[i] >= lo[i] && x[i] <= hi[i] && w[i] == 0) {
+ n3++; // ok
+ }
+ else {
+ dDebug (0,"FAILED: i=%d x=%.4e w=%.4e lo=%.4e hi=%.4e",i,
+ x[i],w[i],lo[i],hi[i]);
+ }
+ }
+
+ // pacifier
+ printf ("passed: NL=%3d NH=%3d C=%3d ",n1,n2,n3);
+ printf ("time=%10.3f ms avg=%10.4f\n",time * 1000.0,average);
+
+ } END_STATE_SAVE(arena, saveInner);
+ }
+
+ dxFreeTemporaryWorldProcessMemArena(arena);
+ return 1;
+}
diff --git a/libs/ode-0.16.1/ode/src/lcp.h b/libs/ode-0.16.1/ode/src/lcp.h new file mode 100644 index 0000000..da65d6f --- /dev/null +++ b/libs/ode-0.16.1/ode/src/lcp.h @@ -0,0 +1,81 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +given (A,b,lo,hi), solve the LCP problem: A*x = b+w, where each x(i),w(i) +satisfies one of + (1) x = lo, w >= 0 + (2) x = hi, w <= 0 + (3) lo < x < hi, w = 0 +A is a matrix of dimension n*n, everything else is a vector of size n*1. +lo and hi can be +/- dInfinity as needed. the first `nub' variables are +unbounded, i.e. hi and lo are assumed to be +/- dInfinity. + +we restrict lo(i) <= 0 and hi(i) >= 0. + +the original data (A,b) may be modified by this function. + +if the `findex' (friction index) parameter is nonzero, it points to an array +of index values. in this case constraints that have findex[i] >= 0 are +special. all non-special constraints are solved for, then the lo and hi values +for the special constraints are set: + hi[i] = abs( hi[i] * x[findex[i]] ) + lo[i] = -hi[i] +and the solution continues. this mechanism allows a friction approximation +to be implemented. the first `nub' variables are assumed to have findex < 0. + +*/ + + +#ifndef _ODE_LCP_H_ +#define _ODE_LCP_H_ + +class dxWorldProcessMemArena; + +enum dxLCPBXElement +{ + PBX__MIN, + + PBX_B = PBX__MIN, + PBX_X, + + PBX__MAX, +}; + +enum dxLCPLHElement +{ + PLH__MIN, + + PLH_LO = PLH__MIN, + PLH_HI, + + PLH__MAX, +}; + +void dxSolveLCP (dxWorldProcessMemArena *memarena, + unsigned n, dReal *A, dReal pairsbx[PBX__MAX], dReal *w, + unsigned nub, dReal pairslh[PLH__MAX], int *findex); + +sizeint dxEstimateSolveLCPMemoryReq(unsigned n, bool outer_w_avail); + +#endif diff --git a/libs/ode-0.16.1/ode/src/mass.cpp b/libs/ode-0.16.1/ode/src/mass.cpp new file mode 100644 index 0000000..961b2da --- /dev/null +++ b/libs/ode-0.16.1/ode/src/mass.cpp @@ -0,0 +1,554 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <ode/odeconfig.h> +#include <ode/mass.h> +#include "config.h" +#include "matrix.h" +#include "odemath.h" + +// Local dependencies +#include "collision_kernel.h" + +#if dTRIMESH_ENABLED +#include "collision_trimesh_internal.h" +#endif // dTRIMESH_ENABLED + +#define SQR(x) ((x)*(x)) //!< Returns x square +#define CUBE(x) ((x)*(x)*(x)) //!< Returns x cube + +#define _I(i,j) I[(i)*4+(j)] + + +// return 1 if ok, 0 if bad + +int dMassCheck (const dMass *m) +{ + int i; + + if (m->mass <= 0) { + dDEBUGMSG ("mass must be > 0"); + return 0; + } + if (!dIsPositiveDefinite (m->I,3,NULL)) { + dDEBUGMSG ("inertia must be positive definite"); + return 0; + } + + // verify that the center of mass position is consistent with the mass + // and inertia matrix. this is done by checking that the inertia around + // the center of mass is also positive definite. from the comment in + // dMassTranslate(), if the body is translated so that its center of mass + // is at the point of reference, then the new inertia is: + // I + mass*crossmat(c)^2 + // note that requiring this to be positive definite is exactly equivalent + // to requiring that the spatial inertia matrix + // [ mass*eye(3,3) M*crossmat(c)^T ] + // [ M*crossmat(c) I ] + // is positive definite, given that I is PD and mass>0. see the theorem + // about partitioned PD matrices for proof. + + dMatrix3 I2,chat; + dSetZero (chat,12); + dSetCrossMatrixPlus (chat,m->c,4); + dMultiply0_333 (I2,chat,chat); + for (i=0; i<3; i++) I2[i] = m->I[i] + m->mass*I2[i]; + for (i=4; i<7; i++) I2[i] = m->I[i] + m->mass*I2[i]; + for (i=8; i<11; i++) I2[i] = m->I[i] + m->mass*I2[i]; + if (!dIsPositiveDefinite (I2,3,NULL)) { + dDEBUGMSG ("center of mass inconsistent with mass parameters"); + return 0; + } + return 1; +} + + +void dMassSetZero (dMass *m) +{ + dAASSERT (m); + m->mass = REAL(0.0); + dSetZero (m->c,sizeof(m->c) / sizeof(dReal)); + dSetZero (m->I,sizeof(m->I) / sizeof(dReal)); +} + + +void dMassSetParameters (dMass *m, dReal themass, + dReal cgx, dReal cgy, dReal cgz, + dReal I11, dReal I22, dReal I33, + dReal I12, dReal I13, dReal I23) +{ + dAASSERT (m); + dMassSetZero (m); + m->mass = themass; + m->c[0] = cgx; + m->c[1] = cgy; + m->c[2] = cgz; + m->_I(0,0) = I11; + m->_I(1,1) = I22; + m->_I(2,2) = I33; + m->_I(0,1) = I12; + m->_I(0,2) = I13; + m->_I(1,2) = I23; + m->_I(1,0) = I12; + m->_I(2,0) = I13; + m->_I(2,1) = I23; + dMassCheck (m); +} + + +void dMassSetSphere (dMass *m, dReal density, dReal radius) +{ + dMassSetSphereTotal (m, (dReal) ((REAL(4.0)/REAL(3.0)) * M_PI * + radius*radius*radius * density), radius); +} + + +void dMassSetSphereTotal (dMass *m, dReal total_mass, dReal radius) +{ + dAASSERT (m); + dMassSetZero (m); + m->mass = total_mass; + dReal II = REAL(0.4) * total_mass * radius*radius; + m->_I(0,0) = II; + m->_I(1,1) = II; + m->_I(2,2) = II; + +# ifndef dNODEBUG + dMassCheck (m); +# endif +} + + +void dMassSetCapsule (dMass *m, dReal density, int direction, + dReal radius, dReal length) +{ + dReal M1,M2,Ia,Ib; + dAASSERT (m); + dUASSERT (direction >= 1 && direction <= 3,"bad direction number"); + dMassSetZero (m); + M1 = (dReal) (M_PI*radius*radius*length*density); // cylinder mass + M2 = (dReal) ((REAL(4.0)/REAL(3.0))*M_PI*radius*radius*radius*density); // total cap mass + m->mass = M1+M2; + Ia = M1*(REAL(0.25)*radius*radius + (REAL(1.0)/REAL(12.0))*length*length) + + M2*(REAL(0.4)*radius*radius + REAL(0.375)*radius*length + REAL(0.25)*length*length); + Ib = (M1*REAL(0.5) + M2*REAL(0.4))*radius*radius; + m->_I(0,0) = Ia; + m->_I(1,1) = Ia; + m->_I(2,2) = Ia; + m->_I(direction-1,direction-1) = Ib; + +# ifndef dNODEBUG + dMassCheck (m); +# endif +} + + +void dMassSetCapsuleTotal (dMass *m, dReal total_mass, int direction, + dReal a, dReal b) +{ + dMassSetCapsule (m, 1.0, direction, a, b); + dMassAdjust (m, total_mass); +} + + +void dMassSetCylinder (dMass *m, dReal density, int direction, + dReal radius, dReal length) +{ + dMassSetCylinderTotal (m, (dReal) (M_PI*radius*radius*length*density), + direction, radius, length); +} + +void dMassSetCylinderTotal (dMass *m, dReal total_mass, int direction, + dReal radius, dReal length) +{ + dReal r2,I; + dAASSERT (m); + dUASSERT (direction >= 1 && direction <= 3,"bad direction number"); + dMassSetZero (m); + r2 = radius*radius; + m->mass = total_mass; + I = total_mass*(REAL(0.25)*r2 + (REAL(1.0)/REAL(12.0))*length*length); + m->_I(0,0) = I; + m->_I(1,1) = I; + m->_I(2,2) = I; + m->_I(direction-1,direction-1) = total_mass*REAL(0.5)*r2; + +# ifndef dNODEBUG + dMassCheck (m); +# endif +} + + +void dMassSetBox (dMass *m, dReal density, + dReal lx, dReal ly, dReal lz) +{ + dMassSetBoxTotal (m, lx*ly*lz*density, lx, ly, lz); +} + + +void dMassSetBoxTotal (dMass *m, dReal total_mass, + dReal lx, dReal ly, dReal lz) +{ + dAASSERT (m); + dMassSetZero (m); + m->mass = total_mass; + m->_I(0,0) = total_mass/REAL(12.0) * (ly*ly + lz*lz); + m->_I(1,1) = total_mass/REAL(12.0) * (lx*lx + lz*lz); + m->_I(2,2) = total_mass/REAL(12.0) * (lx*lx + ly*ly); + +# ifndef dNODEBUG + dMassCheck (m); +# endif +} + + + + + + +/* +* dMassSetTrimesh, implementation by Gero Mueller. +* Based on Brian Mirtich, "Fast and Accurate Computation of +* Polyhedral Mass Properties," journal of graphics tools, volume 1, +* number 2, 1996. +*/ +void dMassSetTrimesh( dMass *m, dReal density, dGeomID g ) +{ + dAASSERT (m); + dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); + + dMassSetZero (m); + +#if dTRIMESH_ENABLED + + dxTriMesh *TriMesh = static_cast<dxTriMesh *>(g); + unsigned int triangles = TriMesh->getMeshTriangleCount(); + + dReal nx, ny, nz; + unsigned int i, A, B, C; + // face integrals + dReal Fa, Fb, Fc, Faa, Fbb, Fcc, Faaa, Fbbb, Fccc, Faab, Fbbc, Fcca; + + // projection integrals + dReal P1, Pa, Pb, Paa, Pab, Pbb, Paaa, Paab, Pabb, Pbbb; + + dReal T0 = 0; + dReal T1[3] = {0., 0., 0.}; + dReal T2[3] = {0., 0., 0.}; + dReal TP[3] = {0., 0., 0.}; + + for( i = 0; i < triangles; i++ ) + { + dVector3 v[3]; + TriMesh->fetchMeshTransformedTriangle(v, i); + + dVector3 n, a, b; + dSubtractVectors3( a, v[1], v[0] ); + dSubtractVectors3( b, v[2], v[0] ); + dCalcVectorCross3( n, b, a ); + nx = fabs(n[0]); + ny = fabs(n[1]); + nz = fabs(n[2]); + + if( nx > ny && nx > nz ) + C = 0; + else + C = (ny > nz) ? 1 : 2; + + // Even though all triangles might be initially valid, + // a triangle may degenerate into a segment after applying + // space transformation. + if (n[C] != REAL(0.0)) + { + A = (C + 1) % 3; + B = (A + 1) % 3; + + // calculate face integrals + { + dReal w; + dReal k1, k2, k3, k4; + + //compProjectionIntegrals(f); + { + dReal a0=0, a1=0, da; + dReal b0=0, b1=0, db; + dReal a0_2, a0_3, a0_4, b0_2, b0_3, b0_4; + dReal a1_2, a1_3, b1_2, b1_3; + dReal C1, Ca, Caa, Caaa, Cb, Cbb, Cbbb; + dReal Cab, Kab, Caab, Kaab, Cabb, Kabb; + + P1 = Pa = Pb = Paa = Pab = Pbb = Paaa = Paab = Pabb = Pbbb = 0.0; + + for( int j = 0; j < 3; j++) + { + switch(j) + { + case 0: + a0 = v[0][A]; + b0 = v[0][B]; + a1 = v[1][A]; + b1 = v[1][B]; + break; + case 1: + a0 = v[1][A]; + b0 = v[1][B]; + a1 = v[2][A]; + b1 = v[2][B]; + break; + case 2: + a0 = v[2][A]; + b0 = v[2][B]; + a1 = v[0][A]; + b1 = v[0][B]; + break; + } + da = a1 - a0; + db = b1 - b0; + a0_2 = a0 * a0; a0_3 = a0_2 * a0; a0_4 = a0_3 * a0; + b0_2 = b0 * b0; b0_3 = b0_2 * b0; b0_4 = b0_3 * b0; + a1_2 = a1 * a1; a1_3 = a1_2 * a1; + b1_2 = b1 * b1; b1_3 = b1_2 * b1; + + C1 = a1 + a0; + Ca = a1*C1 + a0_2; Caa = a1*Ca + a0_3; Caaa = a1*Caa + a0_4; + Cb = b1*(b1 + b0) + b0_2; Cbb = b1*Cb + b0_3; Cbbb = b1*Cbb + b0_4; + Cab = 3*a1_2 + 2*a1*a0 + a0_2; Kab = a1_2 + 2*a1*a0 + 3*a0_2; + Caab = a0*Cab + 4*a1_3; Kaab = a1*Kab + 4*a0_3; + Cabb = 4*b1_3 + 3*b1_2*b0 + 2*b1*b0_2 + b0_3; + Kabb = b1_3 + 2*b1_2*b0 + 3*b1*b0_2 + 4*b0_3; + + P1 += db*C1; + Pa += db*Ca; + Paa += db*Caa; + Paaa += db*Caaa; + Pb += da*Cb; + Pbb += da*Cbb; + Pbbb += da*Cbbb; + Pab += db*(b1*Cab + b0*Kab); + Paab += db*(b1*Caab + b0*Kaab); + Pabb += da*(a1*Cabb + a0*Kabb); + } + + P1 /= 2.0; + Pa /= 6.0; + Paa /= 12.0; + Paaa /= 20.0; + Pb /= -6.0; + Pbb /= -12.0; + Pbbb /= -20.0; + Pab /= 24.0; + Paab /= 60.0; + Pabb /= -60.0; + } + + w = - dCalcVectorDot3(n, v[0]); + + k1 = 1 / n[C]; k2 = k1 * k1; k3 = k2 * k1; k4 = k3 * k1; + + Fa = k1 * Pa; + Fb = k1 * Pb; + Fc = -k2 * (n[A]*Pa + n[B]*Pb + w*P1); + + Faa = k1 * Paa; + Fbb = k1 * Pbb; + Fcc = k3 * (SQR(n[A])*Paa + 2*n[A]*n[B]*Pab + SQR(n[B])*Pbb + + w*(2*(n[A]*Pa + n[B]*Pb) + w*P1)); + + Faaa = k1 * Paaa; + Fbbb = k1 * Pbbb; + Fccc = -k4 * (CUBE(n[A])*Paaa + 3*SQR(n[A])*n[B]*Paab + + 3*n[A]*SQR(n[B])*Pabb + CUBE(n[B])*Pbbb + + 3*w*(SQR(n[A])*Paa + 2*n[A]*n[B]*Pab + SQR(n[B])*Pbb) + + w*w*(3*(n[A]*Pa + n[B]*Pb) + w*P1)); + + Faab = k1 * Paab; + Fbbc = -k2 * (n[A]*Pabb + n[B]*Pbbb + w*Pbb); + Fcca = k3 * (SQR(n[A])*Paaa + 2*n[A]*n[B]*Paab + SQR(n[B])*Pabb + + w*(2*(n[A]*Paa + n[B]*Pab) + w*Pa)); + } + + + T0 += n[0] * ((A == 0) ? Fa : ((B == 0) ? Fb : Fc)); + + T1[A] += n[A] * Faa; + T1[B] += n[B] * Fbb; + T1[C] += n[C] * Fcc; + T2[A] += n[A] * Faaa; + T2[B] += n[B] * Fbbb; + T2[C] += n[C] * Fccc; + TP[A] += n[A] * Faab; + TP[B] += n[B] * Fbbc; + TP[C] += n[C] * Fcca; + } + } + + T1[0] /= 2; T1[1] /= 2; T1[2] /= 2; + T2[0] /= 3; T2[1] /= 3; T2[2] /= 3; + TP[0] /= 2; TP[1] /= 2; TP[2] /= 2; + + m->mass = density * T0; + m->_I(0,0) = density * (T2[1] + T2[2]); + m->_I(1,1) = density * (T2[2] + T2[0]); + m->_I(2,2) = density * (T2[0] + T2[1]); + m->_I(0,1) = - density * TP[0]; + m->_I(1,0) = - density * TP[0]; + m->_I(2,1) = - density * TP[1]; + m->_I(1,2) = - density * TP[1]; + m->_I(2,0) = - density * TP[2]; + m->_I(0,2) = - density * TP[2]; + + // Added to address SF bug 1729095 + dMassTranslate( m, T1[0] / T0, T1[1] / T0, T1[2] / T0 ); + +# ifndef dNODEBUG + dMassCheck (m); +# endif + +#endif // dTRIMESH_ENABLED +} + + +void dMassSetTrimeshTotal( dMass *m, dReal total_mass, dGeomID g) +{ + dAASSERT( m ); + dUASSERT( g && g->type == dTriMeshClass, "argument not a trimesh" ); + dMassSetTrimesh( m, 1.0, g ); + dMassAdjust( m, total_mass ); +} + + + + +void dMassAdjust (dMass *m, dReal newmass) +{ + dAASSERT (m); + dReal scale = newmass / m->mass; + m->mass = newmass; + for (int i=0; i<3; i++) for (int j=0; j<3; j++) m->_I(i,j) *= scale; + +# ifndef dNODEBUG + dMassCheck (m); +# endif +} + + +void dMassTranslate (dMass *m, dReal x, dReal y, dReal z) +{ + // if the body is translated by `a' relative to its point of reference, + // the new inertia about the point of reference is: + // + // I + mass*(crossmat(c)^2 - crossmat(c+a)^2) + // + // where c is the existing center of mass and I is the old inertia. + + int i,j; + dMatrix3 ahat,chat,t1,t2; + dReal a[3]; + + dAASSERT (m); + + // adjust inertia matrix + dSetZero (chat,12); + dSetCrossMatrixPlus (chat,m->c,4); + a[0] = x + m->c[0]; + a[1] = y + m->c[1]; + a[2] = z + m->c[2]; + dSetZero (ahat,12); + dSetCrossMatrixPlus (ahat,a,4); + dMultiply0_333 (t1,ahat,ahat); + dMultiply0_333 (t2,chat,chat); + for (i=0; i<3; i++) for (j=0; j<3; j++) + m->_I(i,j) += m->mass * (t2[i*4+j]-t1[i*4+j]); + + // ensure perfect symmetry + m->_I(1,0) = m->_I(0,1); + m->_I(2,0) = m->_I(0,2); + m->_I(2,1) = m->_I(1,2); + + // adjust center of mass + m->c[0] += x; + m->c[1] += y; + m->c[2] += z; + +# ifndef dNODEBUG + dMassCheck (m); +# endif +} + + +void dMassRotate (dMass *m, const dMatrix3 R) +{ + // if the body is rotated by `R' relative to its point of reference, + // the new inertia about the point of reference is: + // + // R * I * R' + // + // where I is the old inertia. + + dMatrix3 t1; + dReal t2[3]; + + dAASSERT (m); + + // rotate inertia matrix + dMultiply2_333 (t1,m->I,R); + dMultiply0_333 (m->I,R,t1); + + // ensure perfect symmetry + m->_I(1,0) = m->_I(0,1); + m->_I(2,0) = m->_I(0,2); + m->_I(2,1) = m->_I(1,2); + + // rotate center of mass + dMultiply0_331 (t2,R,m->c); + m->c[0] = t2[0]; + m->c[1] = t2[1]; + m->c[2] = t2[2]; + +# ifndef dNODEBUG + dMassCheck (m); +# endif +} + + +void dMassAdd (dMass *a, const dMass *b) +{ + int i; + dAASSERT (a && b); + dReal denom = dRecip (a->mass + b->mass); + for (i=0; i<3; i++) a->c[i] = (a->c[i]*a->mass + b->c[i]*b->mass)*denom; + a->mass += b->mass; + for (i=0; i<12; i++) a->I[i] += b->I[i]; +} + + +// Backwards compatible API +void dMassSetCappedCylinder(dMass *a, dReal b, int c, dReal d, dReal e) +{ + return dMassSetCapsule(a,b,c,d,e); +} + +void dMassSetCappedCylinderTotal(dMass *a, dReal b, int c, dReal d, dReal e) +{ + return dMassSetCapsuleTotal(a,b,c,d,e); +} + diff --git a/libs/ode-0.16.1/ode/src/mat.cpp b/libs/ode-0.16.1/ode/src/mat.cpp new file mode 100644 index 0000000..67f5673 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/mat.cpp @@ -0,0 +1,231 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <ode/odeconfig.h> +#include <ode/misc.h> +#include <ode/error.h> +#include <ode/memory.h> +#include "config.h" +#include "matrix.h" +#include "mat.h" + + +dMatrix::dMatrix() +{ + n = 0; + m = 0; + data = 0; +} + + +dMatrix::dMatrix (int rows, int cols) +{ + if (rows < 1 || cols < 1) dDebug (0,"bad matrix size"); + n = rows; + m = cols; + data = (dReal*) dAlloc (n*m*sizeof(dReal)); + dSetZero (data,n*m); +} + + +dMatrix::dMatrix (const dMatrix &a) +{ + n = a.n; + m = a.m; + data = (dReal*) dAlloc (n*m*sizeof(dReal)); + memcpy (data,a.data,n*m*sizeof(dReal)); +} + + +dMatrix::dMatrix (int rows, int cols, + dReal *_data, int rowskip, int colskip) +{ + if (rows < 1 || cols < 1) dDebug (0,"bad matrix size"); + n = rows; + m = cols; + data = (dReal*) dAlloc (n*m*sizeof(dReal)); + for (int i=0; i<n; i++) { + for (int j=0; j<m; j++) data[i*m+j] = _data[i*rowskip + j*colskip]; + } +} + + +dMatrix::~dMatrix() +{ + if (data) dFree (data,n*m*sizeof(dReal)); +} + + +dReal & dMatrix::operator () (int i, int j) +{ + if (i < 0 || i >= n || j < 0 || j >= m) dDebug (0,"bad matrix (i,j)"); + return data [i*m+j]; +} + + +void dMatrix::operator= (const dMatrix &a) +{ + if (data) dFree (data,n*m*sizeof(dReal)); + n = a.n; + m = a.m; + if (n > 0 && m > 0) { + data = (dReal*) dAlloc (n*m*sizeof(dReal)); + memcpy (data,a.data,n*m*sizeof(dReal)); + } + else data = 0; +} + + +void dMatrix::operator= (dReal a) +{ + for (int i=0; i<n*m; i++) data[i] = a; +} + + +dMatrix dMatrix::transpose() +{ + dMatrix r (m,n); + for (int i=0; i<n; i++) { + for (int j=0; j<m; j++) r.data[j*n+i] = data[i*m+j]; + } + return r; +} + + +dMatrix dMatrix::select (int np, int *p, int nq, int *q) +{ + if (np < 1 || nq < 1) dDebug (0,"Matrix select, bad index array sizes"); + dMatrix r (np,nq); + for (int i=0; i<np; i++) { + for (int j=0; j<nq; j++) { + if (p[i] < 0 || p[i] >= n || q[i] < 0 || q[i] >= m) + dDebug (0,"Matrix select, bad index arrays"); + r.data[i*nq+j] = data[p[i]*m+q[j]]; + } + } + return r; +} + + +dMatrix dMatrix::operator + (const dMatrix &a) +{ + if (n != a.n || m != a.m) dDebug (0,"matrix +, mismatched sizes"); + dMatrix r (n,m); + for (int i=0; i<n*m; i++) r.data[i] = data[i] + a.data[i]; + return r; +} + + +dMatrix dMatrix::operator - (const dMatrix &a) +{ + if (n != a.n || m != a.m) dDebug (0,"matrix -, mismatched sizes"); + dMatrix r (n,m); + for (int i=0; i<n*m; i++) r.data[i] = data[i] - a.data[i]; + return r; +} + + +dMatrix dMatrix::operator - () +{ + dMatrix r (n,m); + for (int i=0; i<n*m; i++) r.data[i] = -data[i]; + return r; +} + + +dMatrix dMatrix::operator * (const dMatrix &a) +{ + if (m != a.n) dDebug (0,"matrix *, mismatched sizes"); + dMatrix r (n,a.m); + for (int i=0; i<n; i++) { + for (int j=0; j<a.m; j++) { + dReal sum = 0; + for (int k=0; k<m; k++) sum += data[i*m+k] * a.data[k*a.m+j]; + r.data [i*a.m+j] = sum; + } + } + return r; +} + + +void dMatrix::operator += (const dMatrix &a) +{ + if (n != a.n || m != a.m) dDebug (0,"matrix +=, mismatched sizes"); + for (int i=0; i<n*m; i++) data[i] += a.data[i]; +} + + +void dMatrix::operator -= (const dMatrix &a) +{ + if (n != a.n || m != a.m) dDebug (0,"matrix -=, mismatched sizes"); + for (int i=0; i<n*m; i++) data[i] -= a.data[i]; +} + + +void dMatrix::clearUpperTriangle() +{ + if (n != m) dDebug (0,"clearUpperTriangle() only works on square matrices"); + for (int i=0; i<n; i++) { + for (int j=i+1; j<m; j++) data[i*m+j] = 0; + } +} + + +void dMatrix::clearLowerTriangle() +{ + if (n != m) dDebug (0,"clearLowerTriangle() only works on square matrices"); + for (int i=0; i<n; i++) { + for (int j=0; j<i; j++) data[i*m+j] = 0; + } +} + + +void dMatrix::makeRandom (dReal range) +{ + for (int i=0; i<n; i++) { + for (int j=0; j<m; j++) + data[i*m+j] = (dRandReal()*REAL(2.0)-REAL(1.0))*range; + } +} + + +void dMatrix::print (const char *fmt, FILE *f) +{ + for (int i=0; i<n; i++) { + for (int j=0; j<m; j++) fprintf (f,fmt,data[i*m+j]); + fprintf (f,"\n"); + } +} + + +dReal dMatrix::maxDifference (const dMatrix &a) +{ + if (n != a.n || m != a.m) dDebug (0,"maxDifference(), mismatched sizes"); + dReal max = 0; + for (int i=0; i<n; i++) { + for (int j=0; j<m; j++) { + dReal diff = dFabs(data[i*m+j] - a.data[i*m+j]); + if (diff > max) max = diff; + } + } + return max; +} diff --git a/libs/ode-0.16.1/ode/src/mat.h b/libs/ode-0.16.1/ode/src/mat.h new file mode 100644 index 0000000..920c348 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/mat.h @@ -0,0 +1,71 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// matrix class. this is mostly for convenience in the testing code, it is +// not optimized at all. correctness is much more importance here. + +#ifndef _ODE_MAT_H_ +#define _ODE_MAT_H_ + +#include <ode/common.h> + + +class dMatrix { + int n,m; // matrix dimension, n,m >= 0 + dReal *data; // if nonzero, n*m elements allocated on the heap + +public: + // constructors, destructors + dMatrix(); // make default 0x0 matrix + dMatrix (int rows, int cols); // construct zero matrix of given size + dMatrix (const dMatrix &); // construct copy of given matrix + // create copy of given data - element (i,j) is data[i*rowskip+j*colskip] + dMatrix (int rows, int cols, dReal *_data, int rowskip, int colskip); + ~dMatrix(); // destructor + + // data movement + dReal & operator () (int i, int j); // reference an element + void operator= (const dMatrix &); // matrix = matrix + void operator= (dReal); // matrix = scalar + dMatrix transpose(); // return transposed matrix + // return a permuted submatrix of this matrix, made up of the rows in p + // and the columns in q. p has np elements, q has nq elements. + dMatrix select (int np, int *p, int nq, int *q); + + // operators + dMatrix operator + (const dMatrix &); + dMatrix operator - (const dMatrix &); + dMatrix operator - (); + dMatrix operator * (const dMatrix &); + void operator += (const dMatrix &); + void operator -= (const dMatrix &); + + // utility + void clearUpperTriangle(); + void clearLowerTriangle(); + void makeRandom (dReal range); + void print (const char *fmt = "%10.4f ", FILE *f=stdout); + dReal maxDifference (const dMatrix &); +}; + + +#endif diff --git a/libs/ode-0.16.1/ode/src/matrix.cpp b/libs/ode-0.16.1/ode/src/matrix.cpp new file mode 100644 index 0000000..cdb77af --- /dev/null +++ b/libs/ode-0.16.1/ode/src/matrix.cpp @@ -0,0 +1,593 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <ode/common.h> +#include "config.h" +#include "matrix.h" +#include "objects.h" +#include "threaded_solver_ldlt.h" + +#include <ode/memory.h> + + +// misc defines +#define ALLOCA dALLOCA16 +#define STACK_ALLOC_MAX 8192U + +/*extern */ +void dxMultiply0(dReal *A, const dReal *B, const dReal *C, unsigned p, unsigned q, unsigned r) +{ + dAASSERT (A && B && C && p>0 && q>0 && r>0); + const unsigned qskip = dPAD(q); + const unsigned rskip = dPAD(r); + dReal *aa = A; + const dReal *bb = B; + for (unsigned i = p; i != 0; aa+=rskip, bb+=qskip, --i) { + dReal *a = aa; + const dReal *cc = C, *ccend = C + r; + for (; cc != ccend; ++a, ++cc) { + dReal sum = REAL(0.0); + const dReal *c = cc; + const dReal *b = bb, *bend = bb + q; + for (; b != bend; c+=rskip, ++b) { + sum += (*b) * (*c); + } + (*a) = sum; + } + } +} + + +/*extern */ +void dxMultiply1(dReal *A, const dReal *B, const dReal *C, unsigned p, unsigned q, unsigned r) +{ + dAASSERT (A && B && C && p>0 && q>0 && r>0); + const unsigned pskip = dPAD(p); + const unsigned rskip = dPAD(r); + dReal *aa = A; + const dReal *bb = B, *bbend = B + p; + for (; bb != bbend; aa += rskip, ++bb) { + dReal *a = aa; + const dReal *cc = C, *ccend = C + r; + for (; cc != ccend; ++a, ++cc) { + dReal sum = REAL(0.0); + const dReal *b = bb, *c = cc; + for (unsigned k = q; k != 0; b += pskip, c += rskip, --k) { + sum += (*b) * (*c); + } + (*a) = sum; + } + } +} + + +/*extern */ +void dxMultiply2(dReal *A, const dReal *B, const dReal *C, unsigned p, unsigned q, unsigned r) +{ + dAASSERT (A && B && C && p>0 && q>0 && r>0); + const unsigned rskip = dPAD(r); + const unsigned qskip = dPAD(q); + dReal *aa = A; + const dReal *bb = B; + for (unsigned i = p; i != 0; aa += rskip, bb += qskip, --i) { + dReal *a = aa, *aend = aa + r; + const dReal *cc = C; + for (; a != aend; cc+=qskip, ++a) { + dReal sum = REAL(0.0); + const dReal *b = bb, *c = cc, *cend = cc + q; + for (; c != cend; ++b, ++c) { + sum += (*b) * (*c); + } + (*a) = sum; + } + } +} + + +/*extern */ +int dxFactorCholesky(dReal *A, unsigned n, void *tmpBuf/*[n]*/) +{ + dAASSERT (n > 0 && A); + bool failure = false; + + dReal *alloctedBuf = NULL; + sizeint allocatedSize; + + const unsigned nskip = dPAD (n); + + dReal *recip = (dReal *)tmpBuf; + if (tmpBuf == NULL) { + allocatedSize = n * sizeof(dReal); + alloctedBuf = allocatedSize > STACK_ALLOC_MAX ? (dReal *)dAlloc(allocatedSize) : NULL; + recip = alloctedBuf != NULL ? alloctedBuf : (dReal*)ALLOCA(allocatedSize); + } + + dReal *aa = A; + for (unsigned i = 0; i < n; aa += nskip, ++i) { + dReal *cc = aa; + { + const dReal *bb = A; + for (unsigned j = 0; j < i; bb += nskip, ++cc, ++j) { + dReal sum = *cc; + const dReal *a = aa, *b = bb, *bend = bb + j; + for (; b != bend; ++a, ++b) { + sum -= (*a) * (*b); + } + *cc = sum * recip[j]; + } + } + { + dReal sum = *cc; + dReal *a = aa, *aend = aa + i; + for (; a != aend; ++a) { + sum -= (*a)*(*a); + } + if (sum <= REAL(0.0)) { + failure = true; + break; + } + dReal sumsqrt = dSqrt(sum); + *cc = sumsqrt; + recip[i] = dRecip (sumsqrt); + } + } + + if (alloctedBuf != NULL) { + dFree(alloctedBuf, allocatedSize); + } + + return failure ? 0 : 1; +} + + +/*extern */ +void dxSolveCholesky(const dReal *L, dReal *b, unsigned n, void *tmpBuf/*[n]*/) +{ + dAASSERT (n > 0 && L && b); + + dReal *alloctedBuf = NULL; + sizeint allocatedSize; + + const unsigned nskip = dPAD (n); + + dReal *y = (dReal *)tmpBuf; + if (tmpBuf == NULL) { + allocatedSize = n * sizeof(dReal); + alloctedBuf = allocatedSize > STACK_ALLOC_MAX ? (dReal *)dAlloc(allocatedSize) : NULL; + y = alloctedBuf != NULL ? alloctedBuf : (dReal*)ALLOCA(allocatedSize); + } + + { + const dReal *ll = L; + for (unsigned i = 0; i < n; ll += nskip, ++i) { + dReal sum = REAL(0.0); + for (unsigned k = 0; k < i; ++k) { + sum += ll[k] * y[k]; + } + dIASSERT(ll[i] != dReal(0.0)); + y[i] = (b[i] - sum) / ll[i]; + } + } + { + const dReal *ll = L + (n - 1) * (nskip + 1); + for (unsigned i = n; i > 0; ll -= nskip + 1) { + --i; + dReal sum = REAL(0.0); + const dReal *l = ll + nskip; + for (unsigned k = i + 1; k < n; l += nskip, ++k) { + sum += (*l) * b[k]; + } + dIASSERT(*ll != dReal(0.0)); + b[i] = (y[i] - sum) / (*ll); + } + } + + if (alloctedBuf != NULL) { + dFree(alloctedBuf, allocatedSize); + } +} + + +/*extern */ +int dxInvertPDMatrix(const dReal *A, dReal *Ainv, unsigned n, void *tmpBuf/*[nskip*(n+2)]*/) +{ + dAASSERT (n > 0 && A && Ainv); + bool success = false; + + dReal *alloctedBuf = NULL; + sizeint allocatedSize; + + sizeint choleskyFactorSize = dxEstimateFactorCholeskyTmpbufSize(n); + sizeint choleskySolveSize = dxEstimateSolveCholeskyTmpbufSize(n); + sizeint choleskyMaxSize = dMACRO_MAX(choleskyFactorSize, choleskySolveSize); + dIASSERT(choleskyMaxSize % sizeof(dReal) == 0); + + const unsigned nskip = dPAD (n); + const sizeint nskip_mul_n = (sizeint)nskip * n; + + dReal *tmp = (dReal *)tmpBuf; + if (tmpBuf == NULL) { + allocatedSize = choleskyMaxSize + (nskip + nskip_mul_n) * sizeof(dReal); + alloctedBuf = allocatedSize > STACK_ALLOC_MAX ? (dReal *)dAlloc(allocatedSize) : NULL; + tmp = alloctedBuf != NULL ? alloctedBuf : (dReal*)ALLOCA(allocatedSize); + } + + dReal *X = (dReal *)((char *)tmp + choleskyMaxSize); + dReal *L = X + nskip; + memcpy (L, A, nskip_mul_n * sizeof(dReal)); + if (dxFactorCholesky(L, n, tmp)) { + dSetZero (Ainv, nskip_mul_n); // make sure all padding elements set to 0 + dReal *aa = Ainv, *xi = X, *xiend = X + n; + for (; xi != xiend; ++aa, ++xi) { + dSetZero(X, n); + *xi = REAL(1.0); + dxSolveCholesky(L, X, n, tmp); + dReal *a = aa; + const dReal *x = X, *xend = X + n; + for (; x != xend; a += nskip, ++x) { + *a = *x; + } + } + success = true; + } + + if (alloctedBuf != NULL) { + dFree(alloctedBuf, allocatedSize); + } + + return success ? 1 : 0; +} + + +/*extern */ +int dxIsPositiveDefinite(const dReal *A, unsigned n, void *tmpBuf/*[nskip*(n+1)]*/) +{ + dAASSERT (n > 0 && A); + + dReal *alloctedBuf = NULL; + sizeint allocatedSize; + + sizeint choleskyFactorSize = dxEstimateFactorCholeskyTmpbufSize(n); + dIASSERT(choleskyFactorSize % sizeof(dReal) == 0); + + const unsigned nskip = dPAD (n); + const sizeint nskip_mul_n = (sizeint)nskip * n; + + dReal *tmp = (dReal *)tmpBuf; + if (tmpBuf == NULL) { + allocatedSize = choleskyFactorSize + nskip_mul_n * sizeof(dReal); + alloctedBuf = allocatedSize > STACK_ALLOC_MAX ? (dReal *)dAlloc(allocatedSize) : NULL; + tmp = alloctedBuf != NULL ? alloctedBuf : (dReal*)ALLOCA(allocatedSize); + } + + dReal *Acopy = (dReal *)((char *)tmp + choleskyFactorSize); + memcpy(Acopy, A, nskip_mul_n * sizeof(dReal)); + int factorResult = dxFactorCholesky (Acopy, n, tmp); + + if (alloctedBuf != NULL) { + dFree(alloctedBuf, allocatedSize); + } + + return factorResult; +} + + +/*extern */ +void dxLDLTAddTL(dReal *L, dReal *d, const dReal *a, unsigned n, unsigned nskip, void *tmpBuf/*[2*nskip]*/) +{ + dAASSERT(L && d && a && n > 0 && nskip >= n); + + if (n < 2) return; + + dReal *alloctedBuf = NULL; + sizeint allocatedSize; + + dReal *W1 = (dReal *)tmpBuf; + if (tmpBuf == NULL) { + allocatedSize = nskip * (2 * sizeof(dReal)); + alloctedBuf = allocatedSize > STACK_ALLOC_MAX ? (dReal *)dAlloc(allocatedSize) : NULL; + W1 = alloctedBuf != NULL ? alloctedBuf : (dReal*)ALLOCA(allocatedSize); + } + + dReal *W2 = W1 + nskip; + + W1[0] = REAL(0.0); + W2[0] = REAL(0.0); + for (unsigned j = 1; j < n; ++j) { + W1[j] = W2[j] = (dReal) (a[j] * M_SQRT1_2); + } + dReal W11 = (dReal) ((REAL(0.5)*a[0]+1)*M_SQRT1_2); + dReal W21 = (dReal) ((REAL(0.5)*a[0]-1)*M_SQRT1_2); + + dReal alpha1 = REAL(1.0); + dReal alpha2 = REAL(1.0); + + { + dReal dee = d[0]; + dReal alphanew = alpha1 + (W11*W11)*dee; + dIASSERT(alphanew != dReal(0.0)); + dee /= alphanew; + dReal gamma1 = W11 * dee; + dee *= alpha1; + alpha1 = alphanew; + alphanew = alpha2 - (W21*W21)*dee; + dee /= alphanew; + //dReal gamma2 = W21 * dee; + alpha2 = alphanew; + dReal k1 = REAL(1.0) - W21*gamma1; + dReal k2 = W21*gamma1*W11 - W21; + dReal *ll = L + nskip; + for (unsigned p = 1; p < n; ll += nskip, ++p) { + dReal Wp = W1[p]; + dReal ell = *ll; + W1[p] = Wp - W11*ell; + W2[p] = k1*Wp + k2*ell; + } + } + + dReal *ll = L + (nskip + 1); + for (unsigned j = 1; j < n; ll += nskip + 1, ++j) { + dReal k1 = W1[j]; + dReal k2 = W2[j]; + + dReal dee = d[j]; + dReal alphanew = alpha1 + (k1*k1)*dee; + dIASSERT(alphanew != dReal(0.0)); + dee /= alphanew; + dReal gamma1 = k1 * dee; + dee *= alpha1; + alpha1 = alphanew; + alphanew = alpha2 - (k2*k2)*dee; + dee /= alphanew; + dReal gamma2 = k2 * dee; + dee *= alpha2; + d[j] = dee; + alpha2 = alphanew; + + dReal *l = ll + nskip; + for (unsigned p = j + 1; p < n; l += nskip, ++p) { + dReal ell = *l; + dReal Wp = W1[p] - k1 * ell; + ell += gamma1 * Wp; + W1[p] = Wp; + Wp = W2[p] - k2 * ell; + ell -= gamma2 * Wp; + W2[p] = Wp; + *l = ell; + } + } + + if (alloctedBuf != NULL) { + dFree(alloctedBuf, allocatedSize); + } +} + + +// macros for dLDLTRemove() for accessing A - either access the matrix +// directly or access it via row pointers. we are only supposed to reference +// the lower triangle of A (it is symmetric), but indexes i and j come from +// permutation vectors so they are not predictable. so do a test on the +// indexes - this should not slow things down too much, as we don't do this +// in an inner loop. + +#define _GETA(i,j) (A[i][j]) +//#define _GETA(i,j) (A[(i)*nskip+(j)]) +#define GETA(i,j) ((i > j) ? _GETA(i,j) : _GETA(j,i)) + + +/*extern */ +void dxLDLTRemove(dReal **A, const unsigned *p, dReal *L, dReal *d, + unsigned n1, unsigned n2, unsigned r, unsigned nskip, void *tmpBuf/*n2 + 2*nskip*/) +{ + dAASSERT(A && p && L && d && n1 > 0 && n2 > 0 /*&& r >= 0 */&& r < n2 && + n1 >= n2 && nskip >= n1); +#ifndef dNODEBUG + for (unsigned i = 0; i < n2; ++i) dIASSERT(p[i] >= 0 && p[i] < n1); +#endif + + if (r == n2 - 1) { + return; // deleting the last row/col is easy + } + + dReal *alloctedBuf = NULL; + sizeint allocatedSize; + + sizeint LDLTAddTLSize = dxEstimateLDLTAddTLTmpbufSize(nskip); + dIASSERT(LDLTAddTLSize % sizeof(dReal) == 0); + + dReal *tmp = (dReal *)tmpBuf; + if (tmpBuf == NULL) { + allocatedSize = LDLTAddTLSize + n2 * sizeof(dReal); + alloctedBuf = allocatedSize > STACK_ALLOC_MAX ? (dReal *)dAlloc(allocatedSize) : NULL; + tmp = alloctedBuf != NULL ? alloctedBuf : (dReal*)ALLOCA(allocatedSize); + } + + if (r == 0) { + dReal *a = (dReal *)((char *)tmp + LDLTAddTLSize); + const unsigned p_0 = p[0]; + for (unsigned i = 0; i < n2; ++i) { + a[i] = -GETA(p[i],p_0); + } + a[0] += REAL(1.0); + dxLDLTAddTL (L, d, a, n2, nskip, tmp); + } + else { + dReal *t = (dReal *)((char *)tmp + LDLTAddTLSize); + { + dReal *Lcurr = L + r*nskip; + for (unsigned i = 0; i < r; ++Lcurr, ++i) { + dIASSERT(d[i] != dReal(0.0)); + t[i] = *Lcurr / d[i]; + } + } + dReal *a = t + r; + { + dReal *Lcurr = L + r * nskip; + const unsigned *pp_r = p + r, p_r = *pp_r; + const unsigned n2_minus_r = n2 - r; + for (unsigned i = 0; i < n2_minus_r; Lcurr += nskip, ++i) { + a[i] = dDot(Lcurr, t, r) - GETA(pp_r[i], p_r); + } + } + a[0] += REAL(1.0); + dxLDLTAddTL (L + (sizeint)(nskip + 1) * r, d + r, a, n2 - r, nskip, tmp); + } + + // snip out row/column r from L and d + dxRemoveRowCol (L, n2, nskip, r); + if (r < (n2 - 1)) memmove (d + r, d + r + 1, (n2 - r - 1) * sizeof(dReal)); + + if (alloctedBuf != NULL) { + dFree(alloctedBuf, allocatedSize); + } +} + + +/*extern */ +void dxRemoveRowCol(dReal *A, unsigned n, unsigned nskip, unsigned r) +{ + dAASSERT(A && n > 0 && nskip >= n && r >= 0 && r < n); + if (r >= n - 1) return; + if (r > 0) { + { + const sizeint move_size = (n - r - 1) * sizeof(dReal); + dReal *Adst = A + r; + for (unsigned i = 0; i < r; Adst += nskip, ++i) { + dReal *Asrc = Adst + 1; + memmove (Adst, Asrc, move_size); + } + } + { + const sizeint cpy_size = r * sizeof(dReal); + dReal *Adst = A + (sizeint)nskip * r; + unsigned n1 = n - 1; + for (unsigned i = r; i < n1; ++i) { + dReal *Asrc = Adst + nskip; + memcpy (Adst, Asrc, cpy_size); + Adst = Asrc; + } + } + } + { + const sizeint cpy_size = (n - r - 1) * sizeof(dReal); + dReal *Adst = A + (sizeint)(nskip + 1) * r; + unsigned n1 = n - 1; + for (unsigned i = r; i < n1; ++i) { + dReal *Asrc = Adst + (nskip + 1); + memcpy (Adst, Asrc, cpy_size); + Adst = Asrc - 1; + } + } +} + + +#undef dSetZero +#undef dSetValue +//#undef dDot +#undef dMultiply0 +#undef dMultiply1 +#undef dMultiply2 +#undef dFactorCholesky +#undef dSolveCholesky +#undef dInvertPDMatrix +#undef dIsPositiveDefinite +#undef dLDLTAddTL +#undef dLDLTRemove +#undef dRemoveRowCol + + +/*extern ODE_API */ +void dSetZero(dReal *a, int n) +{ + dxSetZero(a, n); +} + +/*extern ODE_API */ +void dSetValue(dReal *a, int n, dReal value) +{ + dxSetValue(a, n, value); +} + +// dReal dDot (const dReal *a, const dReal *b, int n); + +/*extern ODE_API */ +void dMultiply0(dReal *A, const dReal *B, const dReal *C, int p,int q,int r) +{ + dxMultiply0(A, B, C, p, q, r); +} + +/*extern ODE_API */ +void dMultiply1(dReal *A, const dReal *B, const dReal *C, int p,int q,int r) +{ + dxMultiply1(A, B, C, p, q, r); +} + +/*extern ODE_API */ +void dMultiply2(dReal *A, const dReal *B, const dReal *C, int p,int q,int r) +{ + dxMultiply2(A, B, C, p, q, r); +} + +/*extern ODE_API */ +int dFactorCholesky(dReal *A, int n) +{ + return dxFactorCholesky(A, n, NULL); +} + +/*extern ODE_API */ +void dSolveCholesky(const dReal *L, dReal *b, int n) +{ + dxSolveCholesky(L, b, n, NULL); +} + +/*extern ODE_API */ +int dInvertPDMatrix (const dReal *A, dReal *Ainv, int n) +{ + return dxInvertPDMatrix(A, Ainv, n, NULL); +} + +/*extern ODE_API */ +int dIsPositiveDefinite(const dReal *A, int n) +{ + return dxIsPositiveDefinite(A, n, NULL); +} + + +/*extern ODE_API */ +void dLDLTAddTL(dReal *L, dReal *d, const dReal *a, int n, int nskip) +{ + dxLDLTAddTL(L, d, a, n, nskip, NULL); +} + +/*extern ODE_API */ +void dLDLTRemove(dReal **A, const int *p, dReal *L, dReal *d, int n1, int n2, int r, int nskip) +{ + dxLDLTRemove(A, (const unsigned *)p, L, d, n1, n2, r, nskip, NULL); + dSASSERT(sizeof(unsigned) == sizeof(*p)); +} + +/*extern ODE_API */ +void dRemoveRowCol(dReal *A, int n, int nskip, int r) +{ + dxRemoveRowCol(A, n, nskip, r); +} + diff --git a/libs/ode-0.16.1/ode/src/matrix.h b/libs/ode-0.16.1/ode/src/matrix.h new file mode 100644 index 0000000..b723722 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/matrix.h @@ -0,0 +1,160 @@ +/*************************************************************************
+ * *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
+ * All rights reserved. Email: russ@q12.org Web: www.q12.org *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of EITHER: *
+ * (1) The GNU Lesser General Public License as published by the Free *
+ * Software Foundation; either version 2.1 of the License, or (at *
+ * your option) any later version. The text of the GNU Lesser *
+ * General Public License is included with this library in the *
+ * file LICENSE.TXT. *
+ * (2) The BSD-style license that is included with this library in *
+ * the file LICENSE-BSD.TXT. *
+ * *
+ * This library 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 files *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
+ * *
+ *************************************************************************/
+
+/*
+ * optimized and unoptimized vector and matrix functions
+ * (inlined private versions)
+ */
+
+#ifndef _ODE__PRIVATE_MATRIX_H_
+#define _ODE__PRIVATE_MATRIX_H_
+
+
+#include <ode/matrix.h>
+
+
+#ifdef __cplusplus
+
+template <unsigned a_stride, typename element_type>
+ODE_INLINE
+void dxtSetZero (element_type *a, sizeint n)
+{
+ element_type *const aend = a + n * a_stride;
+ for (element_type *acurr = a; acurr != aend; acurr += a_stride) {
+ *acurr = (element_type)0;
+ }
+}
+
+template <typename element_type>
+ODE_INLINE
+void dxSetZero (element_type *a, sizeint n)
+{
+ dxtSetZero<1>(a, n);
+}
+
+template <typename element_type>
+ODE_INLINE
+void dxSetValue (element_type *a, sizeint n, element_type value)
+{
+ element_type *const aend = a + n;
+ for (element_type *acurr = a; acurr != aend; ++acurr) {
+ *acurr = value;
+ }
+}
+
+
+#else // #ifndef __cplusplus
+
+ODE_PURE_INLINE
+void dxSetZero (dReal *a, sizeint n)
+{
+ dReal *const aend = a + n;
+ dReal *acurr;
+ for (acurr = a; acurr != aend; ++acurr) {
+ *acurr = 0;
+ }
+}
+
+ODE_PURE_INLINE
+void dxSetValue (dReal *a, sizeint n, dReal value)
+{
+ dReal *const aend = a + n;
+ dReal *acurr;
+ for (acurr = a; acurr != aend; ++acurr) {
+ *acurr = value;
+ }
+}
+
+
+#endif // #ifdef __cplusplus
+
+
+dReal dxDot (const dReal *a, const dReal *b, unsigned n);
+void dxMultiply0 (dReal *A, const dReal *B, const dReal *C, unsigned p, unsigned q, unsigned r);
+void dxMultiply1 (dReal *A, const dReal *B, const dReal *C, unsigned p, unsigned q, unsigned r);
+void dxMultiply2 (dReal *A, const dReal *B, const dReal *C, unsigned p, unsigned q, unsigned r);
+int dxFactorCholesky (dReal *A, unsigned n, void *tmpbuf);
+void dxSolveCholesky (const dReal *L, dReal *b, unsigned n, void *tmpbuf);
+int dxInvertPDMatrix (const dReal *A, dReal *Ainv, unsigned n, void *tmpbuf);
+int dxIsPositiveDefinite (const dReal *A, unsigned n, void *tmpbuf);
+void dxLDLTAddTL (dReal *L, dReal *d, const dReal *a, unsigned n, unsigned nskip, void *tmpbuf);
+void dxLDLTRemove (dReal **A, const unsigned *p, dReal *L, dReal *d, unsigned n1, unsigned n2, unsigned r, unsigned nskip, void *tmpbuf);
+void dxRemoveRowCol (dReal *A, unsigned n, unsigned nskip, unsigned r);
+
+ODE_PURE_INLINE sizeint dxEstimateFactorCholeskyTmpbufSize(unsigned n)
+{
+ return dPAD(n) * sizeof(dReal);
+}
+
+ODE_PURE_INLINE sizeint dxEstimateSolveCholeskyTmpbufSize(unsigned n)
+{
+ return dPAD(n) * sizeof(dReal);
+}
+
+ODE_PURE_INLINE sizeint dxEstimateInvertPDMatrixTmpbufSize(unsigned n)
+{
+ sizeint FactorCholesky_size = dxEstimateFactorCholeskyTmpbufSize(n);
+ sizeint SolveCholesky_size = dxEstimateSolveCholeskyTmpbufSize(n);
+ sizeint MaxCholesky_size = FactorCholesky_size > SolveCholesky_size ? FactorCholesky_size : SolveCholesky_size;
+ return (sizeint)dPAD(n) * (n + 1) * sizeof(dReal) + MaxCholesky_size;
+}
+
+ODE_PURE_INLINE sizeint dxEstimateIsPositiveDefiniteTmpbufSize(unsigned n)
+{
+ return (sizeint)dPAD(n) * n * sizeof(dReal) + dxEstimateFactorCholeskyTmpbufSize(n);
+}
+
+ODE_PURE_INLINE sizeint dxEstimateLDLTAddTLTmpbufSize(unsigned nskip)
+{
+ return nskip * (2 * sizeof(dReal));
+}
+
+ODE_PURE_INLINE sizeint dxEstimateLDLTRemoveTmpbufSize(unsigned n2, unsigned nskip)
+{
+ return n2 * sizeof(dReal) + dxEstimateLDLTAddTLTmpbufSize(nskip);
+}
+
+/* For internal use */
+#define dSetZero(a, n) dxSetZero(a, n)
+#define dSetValue(a, n, value) dxSetValue(a, n, value)
+#define dDot(a, b, n) dxDot(a, b, n)
+#define dMultiply0(A, B, C, p, q, r) dxMultiply0(A, B, C, p, q, r)
+#define dMultiply1(A, B, C, p, q, r) dxMultiply1(A, B, C, p, q, r)
+#define dMultiply2(A, B, C, p, q, r) dxMultiply2(A, B, C, p, q, r)
+#define dFactorCholesky(A, n, tmpbuf) dxFactorCholesky(A, n, tmpbuf)
+#define dSolveCholesky(L, b, n, tmpbuf) dxSolveCholesky(L, b, n, tmpbuf)
+#define dInvertPDMatrix(A, Ainv, n, tmpbuf) dxInvertPDMatrix(A, Ainv, n, tmpbuf)
+#define dIsPositiveDefinite(A, n, tmpbuf) dxIsPositiveDefinite(A, n, tmpbuf)
+#define dLDLTAddTL(L, d, a, n, nskip, tmpbuf) dxLDLTAddTL(L, d, a, n, nskip, tmpbuf)
+#define dLDLTRemove(A, p, L, d, n1, n2, r, nskip, tmpbuf) dxLDLTRemove(A, p, L, d, n1, n2, r, nskip, tmpbuf)
+#define dRemoveRowCol(A, n, nskip, r) dxRemoveRowCol(A, n, nskip, r)
+
+
+#define dEstimateFactorCholeskyTmpbufSize(n) dxEstimateFactorCholeskyTmpbufSize(n)
+#define dEstimateSolveCholeskyTmpbufSize(n) dxEstimateSolveCholeskyTmpbufSize(n)
+#define dEstimateInvertPDMatrixTmpbufSize(n) dxEstimateInvertPDMatrixTmpbufSize(n)
+#define dEstimateIsPositiveDefiniteTmpbufSize(n) dxEstimateIsPositiveDefiniteTmpbufSize(n)
+#define dEstimateLDLTAddTLTmpbufSize(nskip) dxEstimateLDLTAddTLTmpbufSize(nskip)
+#define dEstimateLDLTRemoveTmpbufSize(n2, nskip) dxEstimateLDLTRemoveTmpbufSize(n2, nskip)
+
+
+#endif // #ifndef _ODE__PRIVATE_MATRIX_H_
diff --git a/libs/ode-0.16.1/ode/src/memory.cpp b/libs/ode-0.16.1/ode/src/memory.cpp new file mode 100644 index 0000000..5a67448 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/memory.cpp @@ -0,0 +1,95 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <ode/odeconfig.h> +#include <ode/memory.h> +#include <ode/error.h> +#include "config.h" + + +static dAllocFunction *allocfn = 0; +static dReallocFunction *reallocfn = 0; +static dFreeFunction *freefn = 0; + +#ifdef __MINGW32__ +/* +this is a guard against AC_FUNC_MALLOC and AC_FUNC_REALLOC +which break cross compilation, no issues in native MSYS. +*/ +#undef malloc +#undef realloc +#endif + +void dSetAllocHandler (dAllocFunction *fn) +{ + allocfn = fn; +} + + +void dSetReallocHandler (dReallocFunction *fn) +{ + reallocfn = fn; +} + + +void dSetFreeHandler (dFreeFunction *fn) +{ + freefn = fn; +} + + +dAllocFunction *dGetAllocHandler() +{ + return allocfn; +} + + +dReallocFunction *dGetReallocHandler() +{ + return reallocfn; +} + + +dFreeFunction *dGetFreeHandler() +{ + return freefn; +} + + +void * dAlloc (sizeint size) +{ + if (allocfn) return allocfn (size); else return malloc (size); +} + + +void * dRealloc (void *ptr, sizeint oldsize, sizeint newsize) +{ + if (reallocfn) return reallocfn (ptr,oldsize,newsize); + else return realloc (ptr,newsize); +} + + +void dFree (void *ptr, sizeint size) +{ + if (!ptr) return; + if (freefn) freefn (ptr,size); else free (ptr); +} diff --git a/libs/ode-0.16.1/ode/src/misc.cpp b/libs/ode-0.16.1/ode/src/misc.cpp new file mode 100644 index 0000000..e63a029 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/misc.cpp @@ -0,0 +1,217 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <ode/odeconfig.h> +#include <ode/misc.h> +#include "config.h" +#include "matrix.h" +#include "error.h" +#include "odeou.h" + +//**************************************************************************** +// random numbers + +static volatile duint32 seed = 0; + +unsigned long dRand() +{ + duint32 origSeed, newSeed; +#if !dTHREADING_INTF_DISABLED + do { +#endif + origSeed = seed; + newSeed = ((duint32)1664525 * origSeed + (duint32)1013904223) & (duint32)0xffffffff; +#if dTHREADING_INTF_DISABLED + seed = newSeed; +#else + } while (!AtomicCompareExchange((volatile atomicord32 *)&seed, origSeed, newSeed)); +#endif + return newSeed; +} + + +unsigned long dRandGetSeed() +{ + return seed; +} + + +void dRandSetSeed (unsigned long s) +{ + seed = s; +} + + +int dTestRand() +{ + unsigned long oldseed = seed; + int ret = 1; + seed = 0; + if (dRand() != 0x3c6ef35f || dRand() != 0x47502932 || + dRand() != 0xd1ccf6e9 || dRand() != 0xaaf95334 || + dRand() != 0x6252e503) ret = 0; + seed = oldseed; + return ret; +} + + +// adam's all-int straightforward(?) dRandInt (0..n-1) +int dRandInt (int n) +{ + int result; + // Since there is no memory barrier macro in ODE assign via volatile variable + // to prevent compiler reusing seed as value of `r' + volatile unsigned long raw_r = dRand(); + duint32 r = (duint32)raw_r; + + duint32 un = n; + dIASSERT(sizeof(n) == sizeof(un)); + + // 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) { + // r ^= (r >> 16); + // if (un <= 0x00000100UL) { + // r ^= (r >> 8); + // if (un <= 0x00000010UL) { + // r ^= (r >> 4); + // if (un <= 0x00000004UL) { + // r ^= (r >> 2); + // if (un <= 0x00000002UL) { + // r ^= (r >> 1); + // } + // } + // } + // } + // } + // Optimized version of above + if (un <= (duint32)0x00000010) { + r ^= (r >> 16); + r ^= (r >> 8); + r ^= (r >> 4); + if (un <= (duint32)0x00000002) { + r ^= (r >> 2); + r ^= (r >> 1); + result = (r/* & (duint32)0x01*/) & (un >> 1); + } else { + if (un <= (duint32)0x00000004) { + r ^= (r >> 2); + result = ((r & (duint32)0x03) * un) >> 2; + } else { + result = ((r & (duint32)0x0F) * un) >> 4; + } + } + } else { + if (un <= (duint32)0x00000100) { + r ^= (r >> 16); + r ^= (r >> 8); + result = ((r & (duint32)0xFF) * un) >> 8; + } else { + if (un <= (duint32)0x00010000) { + r ^= (r >> 16); + result = ((r & (duint32)0xFFFF) * un) >> 16; + } else { + result = (int)(((duint64)r * un) >> 32); + } + } + } + + return result; +} + + +dReal dRandReal() +{ + return (dReal)(((double) dRand()) / ((double) 0xffffffff)); +} + +//**************************************************************************** +// matrix utility stuff + +void dPrintMatrix (const dReal *A, int n, int m, const char *fmt, FILE *f) +{ + int skip = dPAD(m); + const dReal *Arow = A; + for (int i=0; i<n; Arow+=skip, ++i) { + for (int j=0; j<m; ++j) fprintf (f,fmt,Arow[j]); + fprintf (f,"\n"); + } +} + + +void dMakeRandomVector (dReal *A, int n, dReal range) +{ + int i; + for (i=0; i<n; i++) A[i] = (dRandReal()*REAL(2.0)-REAL(1.0))*range; +} + + +void dMakeRandomMatrix (dReal *A, int n, int m, dReal range) +{ + int skip = dPAD(m); + // dSetZero (A,n*skip); + dReal *Arow = A; + for (int i=0; i<n; Arow+=skip, ++i) { + for (int j=0; j<m; ++j) Arow[j] = (dRandReal()*REAL(2.0)-REAL(1.0))*range; + } +} + + +void dClearUpperTriangle (dReal *A, int n) +{ + int skip = dPAD(n); + dReal *Arow = A; + for (int i=0; i<n; Arow+=skip, ++i) { + for (int j=i+1; j<n; ++j) Arow[j] = 0; + } +} + + +dReal dMaxDifference (const dReal *A, const dReal *B, int n, int m) +{ + int skip = dPAD(m); + dReal max = REAL(0.0); + const dReal *Arow = A, *Brow = B; + for (int i=0; i<n; Arow+=skip, Brow +=skip, ++i) { + for (int j=0; j<m; ++j) { + dReal diff = dFabs(Arow[j] - Brow[j]); + if (diff > max) max = diff; + } + } + return max; +} + + +dReal dMaxDifferenceLowerTriangle (const dReal *A, const dReal *B, int n) +{ + int skip = dPAD(n); + dReal max = REAL(0.0); + const dReal *Arow = A, *Brow = B; + for (int i=0; i<n; Arow+=skip, Brow+=skip, ++i) { + for (int j=0; j<=i; ++j) { + dReal diff = dFabs(Arow[j] - Brow[j]); + if (diff > max) max = diff; + } + } + return max; +} + diff --git a/libs/ode-0.16.1/ode/src/nextafterf.c b/libs/ode-0.16.1/ode/src/nextafterf.c new file mode 100644 index 0000000..78fbe31 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/nextafterf.c @@ -0,0 +1,115 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* _nextafterf() implementation for MSVC */ + +#include <ode/common.h> +#include "config.h" + + +#if defined(_ODE__NEXTAFTERF_REQUIRED) + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* A union which permits us to convert between a float and a 32 bit int. */ + +typedef union +{ + float value; + uint32 word; +} ieee_float_shape_type; + +/* Get a 32 bit int from a float. */ + +#define GET_FLOAT_WORD(i,d) \ + do { \ + volatile ieee_float_shape_type gf_u; \ + gf_u.value = (d); \ + (i) = gf_u.word; \ + } while (0) + +/* Set a float from a 32 bit int. */ + +#define SET_FLOAT_WORD(d,i) \ + do { \ + volatile ieee_float_shape_type sf_u; \ + sf_u.word = (i); \ + (d) = sf_u.value; \ + } while (0) + + +#undef nextafterf +float _nextafterf(float x, float y) +{ + int32 hx,hy,ix,iy; + + GET_FLOAT_WORD(hx,x); + GET_FLOAT_WORD(hy,y); + ix = hx&0x7fffffff; /* |x| */ + iy = hy&0x7fffffff; /* |y| */ + + if((ix>0x7f800000) || /* x is nan */ + (iy>0x7f800000)) /* y is nan */ + return x+y; + if(x==y) return x; /* x=y, return x */ + if(ix==0) { /* x == 0 */ + SET_FLOAT_WORD(x,(hy&0x80000000)|1);/* return +-minsubnormal */ + y = x*x; + if(y==x) return y; else return x; /* raise underflow flag */ + } + if(hx>=0) { /* x > 0 */ + if(hx>hy) { /* x > y, x -= ulp */ + hx -= 1; + } else { /* x < y, x += ulp */ + hx += 1; + } + } else { /* x < 0 */ + if(hy>=0||hx>hy){ /* x < y, x -= ulp */ + hx -= 1; + } else { /* x > y, x += ulp */ + hx += 1; + } + } + hy = hx&0x7f800000; + if(hy>=0x7f800000) return x+x; /* overflow */ + if(hy<0x00800000) { /* underflow */ + y = x*x; + if(y!=x) { /* raise underflow flag */ + SET_FLOAT_WORD(y,hx); + return y; + } + } + SET_FLOAT_WORD(x,hx); + return x; +} + + +#endif /* #if defined(_ODE__NEXTAFTERF_REQUIRED) */ diff --git a/libs/ode-0.16.1/ode/src/objects.cpp b/libs/ode-0.16.1/ode/src/objects.cpp new file mode 100644 index 0000000..e024aca --- /dev/null +++ b/libs/ode-0.16.1/ode/src/objects.cpp @@ -0,0 +1,138 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// Object, body, and world methods. + + +#include <ode/common.h> +#include <ode/threading_impl.h> +#include <ode/objects.h> +#include "config.h" +#include "objects.h" +#include "default_threading.h" +#include "threading_impl.h" +#include "matrix.h" +#include "util.h" + + +#define dWORLD_DEFAULT_GLOBAL_ERP REAL(0.2) + +#if defined(dSINGLE) +#define dWORLD_DEFAULT_GLOBAL_CFM REAL(1e-5) +#elif defined(dDOUBLE) +#define dWORLD_DEFAULT_GLOBAL_CFM REAL(1e-10) +#else +#error dSINGLE or dDOUBLE must be defined +#endif + + +dObject::~dObject() +{ + // Do nothing - a virtual destructor +} + + +dxAutoDisable::dxAutoDisable(void *): + idle_time(REAL(0.0)), + idle_steps(10), + average_samples(1), // Default is 1 sample => Instantaneous velocity + linear_average_threshold(REAL(0.01)*REAL(0.01)), // (magnitude squared) + angular_average_threshold(REAL(0.01)*REAL(0.01)) // (magnitude squared) +{ +} + +dxDampingParameters::dxDampingParameters(void *): + linear_scale(REAL(0.0)), + angular_scale(REAL(0.0)), + linear_threshold(REAL(0.01) * REAL(0.01)), + angular_threshold(REAL(0.01) * REAL(0.01)) +{ +} + +dxQuickStepParameters::dxQuickStepParameters(void *): + num_iterations(20), + w(REAL(1.3)) +{ +} + +dxContactParameters::dxContactParameters(void *): + max_vel(dInfinity), + min_depth(REAL(0.0)) +{ +} + +dxWorld::dxWorld(): + dBase(), + dxThreadingBase(), + firstbody(NULL), + firstjoint(NULL), + nb(0), + nj(0), + global_erp(dWORLD_DEFAULT_GLOBAL_ERP), + global_cfm(dWORLD_DEFAULT_GLOBAL_CFM), + adis(NULL), + body_flags(0), + islands_max_threads(dWORLDSTEP_THREADCOUNT_UNLIMITED), + wmem(NULL), + qs(NULL), + contactp(NULL), + dampingp(NULL), + max_angular_speed(dInfinity), + userdata(0) +{ + dxThreadingBase::setThreadingDefaultImplProvider(this); + + dSetZero (gravity, 4); +} + +dxWorld::~dxWorld() +{ + if (wmem) + { + wmem->CleanupWorldReferences(this); + wmem->Release(); + } +} + + +void dxWorld::assignThreadingImpl(const dxThreadingFunctionsInfo *functions_info, dThreadingImplementationID threading_impl) +{ + if (wmem != NULL) + { + // Free objects allocated with old threading + wmem->CleanupWorldReferences(this); + } + + dxThreadingBase::assignThreadingImpl(functions_info, threading_impl); +} + +dxWorldProcessContext *dxWorld::unsafeGetWorldProcessingContext() const +{ + return wmem->GetWorldProcessingContext(); +} + +const dxThreadingFunctionsInfo *dxWorld::retrieveThreadingDefaultImpl(dThreadingImplementationID &out_defaultImpl) +{ + out_defaultImpl = DefaultThreadingHolder::getDefaultThreadingImpl(); + return DefaultThreadingHolder::getDefaultThreadingFunctions(); +} + diff --git a/libs/ode-0.16.1/ode/src/objects.h b/libs/ode-0.16.1/ode/src/objects.h new file mode 100644 index 0000000..0e7d34f --- /dev/null +++ b/libs/ode-0.16.1/ode/src/objects.h @@ -0,0 +1,206 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// object, body, and world structs. + + +#ifndef _ODE__PRIVATE_OBJECTS_H_ +#define _ODE__PRIVATE_OBJECTS_H_ + + +#include <ode/common.h> +#include <ode/memory.h> +#include <ode/mass.h> +#include "error.h" +#include "array.h" +#include "common.h" +#include "threading_base.h" + + +struct dxJointNode; +class dxStepWorkingMemory; +class dxWorldProcessContext; + + +// some body flags + +enum { + dxBodyFlagFiniteRotation = 1, // use finite rotations + dxBodyFlagFiniteRotationAxis = 2, // use finite rotations only along axis + dxBodyDisabled = 4, // body is disabled + dxBodyNoGravity = 8, // body is not influenced by gravity + dxBodyAutoDisable = 16, // enable auto-disable on body + dxBodyLinearDamping = 32, // use linear damping + dxBodyAngularDamping = 64, // use angular damping + dxBodyMaxAngularSpeed = 128,// use maximum angular speed + dxBodyGyroscopic = 256 // use gyroscopic term +}; + + +// base class that does correct object allocation / deallocation + +struct dBase { + void *operator new (size_t size) { return dAlloc (size); } + void *operator new (size_t, void *p) { return p; } + void operator delete (void *ptr, size_t size) { dFree (ptr,size); } + void *operator new[] (size_t size) { return dAlloc (size); } + void operator delete[] (void *ptr, size_t size) { dFree (ptr,size); } +}; + + +// base class for bodies and joints + +struct dObject : public dBase { + dxWorld *world; // world this object is in + dObject *next; // next object of this type in list + dObject **tome; // pointer to previous object's next ptr + int tag; // used by dynamics algorithms + void *userdata; // user settable data + + explicit dObject(dxWorld *w): world(w), next(NULL), tome(NULL), tag(0), userdata(NULL) {} + virtual ~dObject(); +}; + + +// auto disable parameters +struct dxAutoDisable { + dReal idle_time; // time the body needs to be idle to auto-disable it + int idle_steps; // steps the body needs to be idle to auto-disable it + unsigned int average_samples; // size of the average_lvel and average_avel buffers + dReal linear_average_threshold; // linear (squared) average velocity threshold + dReal angular_average_threshold; // angular (squared) average velocity threshold + + dxAutoDisable() {} + explicit dxAutoDisable(void *); +}; + + +// damping parameters +struct dxDampingParameters { + dReal linear_scale; // multiply the linear velocity by (1 - scale) + dReal angular_scale; // multiply the angular velocity by (1 - scale) + dReal linear_threshold; // linear (squared) average speed threshold + dReal angular_threshold; // angular (squared) average speed threshold + + dxDampingParameters() {} + explicit dxDampingParameters(void *); +}; + + +// quick-step parameters +struct dxQuickStepParameters { + int num_iterations; // number of SOR iterations to perform + dReal w; // the SOR over-relaxation parameter + + dxQuickStepParameters() {} + explicit dxQuickStepParameters(void *); +}; + + +// contact generation parameters +struct dxContactParameters { + dReal max_vel; // maximum correcting velocity + dReal min_depth; // thickness of 'surface layer' + + dxContactParameters() {} + explicit dxContactParameters(void *); +}; + +// position vector and rotation matrix for geometry objects that are not +// connected to bodies. +struct dxPosR { + dVector3 pos; + dMatrix3 R; +}; + +struct dxBody : public dObject { + dxJointNode *firstjoint; // list of attached joints + unsigned flags; // some dxBodyFlagXXX flags + dGeomID geom; // first collision geom associated with body + dMass mass; // mass parameters about POR + dMatrix3 invI; // inverse of mass.I + dReal invMass; // 1 / mass.mass + dxPosR posr; // position and orientation of point of reference + dQuaternion q; // orientation quaternion + dVector3 lvel,avel; // linear and angular velocity of POR + dVector3 facc,tacc; // force and torque accumulators + dVector3 finite_rot_axis; // finite rotation axis, unit length or 0=none + + // auto-disable information + dxAutoDisable adis; // auto-disable parameters + dReal adis_timeleft; // time left to be idle + int adis_stepsleft; // steps left to be idle + dVector3* average_lvel_buffer; // buffer for the linear average velocity calculation + dVector3* average_avel_buffer; // buffer for the angular average velocity calculation + unsigned int average_counter; // counter/index to fill the average-buffers + int average_ready; // indicates ( with = 1 ), if the Body's buffers are ready for average-calculations + + void (*moved_callback)(dxBody*); // let the user know the body moved + dxDampingParameters dampingp; // damping parameters, depends on flags + dReal max_angular_speed; // limit the angular velocity to this magnitude + + dxBody(dxWorld *w); +}; + + +struct dxWorld : public dBase, public dxThreadingBase, private dxIThreadingDefaultImplProvider { + dxBody *firstbody; // body linked list + dxJoint *firstjoint; // joint linked list + int nb,nj; // number of bodies and joints in lists + dVector3 gravity; // gravity vector (m/s/s) + dReal global_erp; // global error reduction parameter + dReal global_cfm; // global constraint force mixing parameter + dxAutoDisable adis; // auto-disable parameters + int body_flags; // flags for new bodies + unsigned islands_max_threads; // maximum threads to allocate for island processing + dxStepWorkingMemory *wmem; // Working memory object for dWorldStep/dWorldQuickStep + + dxQuickStepParameters qs; + dxContactParameters contactp; + dxDampingParameters dampingp; // damping parameters + dReal max_angular_speed; // limit the angular velocity to this magnitude + + void* userdata; + + dxWorld(); + virtual ~dxWorld(); // Compilers issue warnings if a class with virtual methods does not have a virtual destructor :( + + void assignThreadingImpl(const dxThreadingFunctionsInfo *functions_info, dThreadingImplementationID threading_impl); + + unsigned calculateIslandProcessingMaxThreadCount(unsigned *ptrOut_activeThreadCount=NULL) const + { + unsigned activeThreadCount, *ptrActiveThreadCountToUse = ptrOut_activeThreadCount != NULL ? &activeThreadCount : NULL; + unsigned limitedCount = calculateThreadingLimitedThreadCount(islands_max_threads, false, ptrActiveThreadCountToUse); + if (ptrOut_activeThreadCount != NULL) { + *ptrOut_activeThreadCount = dMACRO_MAX(activeThreadCount, 1U); + } + return dMACRO_MAX(limitedCount, 1U); + } + + dxWorldProcessContext *unsafeGetWorldProcessingContext() const; + +private: // dxIThreadingDefaultImplProvider + virtual const dxThreadingFunctionsInfo *retrieveThreadingDefaultImpl(dThreadingImplementationID &out_defaultImpl); +}; + + +#endif // #ifndef _ODE__PRIVATE_OBJECTS_H_ diff --git a/libs/ode-0.16.1/ode/src/obstack.cpp b/libs/ode-0.16.1/ode/src/obstack.cpp new file mode 100644 index 0000000..541f0e3 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/obstack.cpp @@ -0,0 +1,157 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <ode/common.h> +#include <ode/error.h> +#include <ode/memory.h> +#include "config.h" +#include "obstack.h" + + +//**************************************************************************** +// macros and constants + +#define ROUND_UP_OFFSET_TO_EFFICIENT_SIZE(arena,ofs) \ + ofs = (sizeint) (dEFFICIENT_SIZE( ((sizeint)(arena)) + ofs ) - ((sizeint)(arena)) ) + +#define MAX_ALLOC_SIZE \ + ((sizeint)(dOBSTACK_ARENA_SIZE - sizeof (Arena) - EFFICIENT_ALIGNMENT + 1)) + +//**************************************************************************** +// dObStack + +dObStack::dObStack(): + m_first(NULL), m_last(NULL), + m_current_arena(NULL), m_current_ofs(0) +{ +} + + +dObStack::~dObStack() +{ + // free all arenas + Arena *a,*nexta; + a = m_first; + while (a) { + nexta = a->m_next; + dFree (a,dOBSTACK_ARENA_SIZE); + a = nexta; + } +} + + +void *dObStack::alloc (sizeint num_bytes) +{ + if (num_bytes > MAX_ALLOC_SIZE) dDebug (0,"num_bytes too large"); + + bool last_alloc_needed = false, last_init_needed = false; + Arena **last_ptr = NULL; + + if (m_last != NULL) { + if ((m_last->m_used + num_bytes) > dOBSTACK_ARENA_SIZE) { + if (m_last->m_next != NULL) { + m_last = m_last->m_next; + last_init_needed = true; + } else { + last_ptr = &m_last->m_next; + last_alloc_needed = true; + } + } + } else { + last_ptr = &m_last; + last_alloc_needed = true; + } + + if (last_alloc_needed) { + Arena *new_last = (Arena *) dAlloc (dOBSTACK_ARENA_SIZE); + new_last->m_next = 0; + *last_ptr = new_last; + if (m_first == NULL) { + m_first = new_last; + } + m_last = new_last; + last_init_needed = true; + } + + if (last_init_needed) { + m_last->m_used = sizeof (Arena); + ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (m_last,m_last->m_used); + } + + // allocate an area in the arena + char *c = ((char*) m_last) + m_last->m_used; + m_last->m_used += num_bytes; + ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (m_last,m_last->m_used); + return c; +} + + +void dObStack::freeAll() +{ + Arena *current = m_first; + m_last = current; + // It is necessary to reset used sizes in whole arena chain + // otherwise enumeration may proceed to remains of old deleted joints in unused arenas + while (current) { + current->m_used = sizeof(Arena); + ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (current,current->m_used); + current = current->m_next; + } +} + + +void *dObStack::rewind() +{ + return switch_to_arena(m_first); +} + +void *dObStack::next (sizeint num_bytes) +{ + // this functions like alloc, except that no new storage is ever allocated + if (!m_current_arena) { + return 0; + } + + m_current_ofs += num_bytes; + ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (m_current_arena,m_current_ofs); + + if (m_current_ofs < m_current_arena->m_used) { + return ((char*) m_current_arena) + m_current_ofs; + } + + return switch_to_arena(m_current_arena->m_next); +} + +void *dObStack::switch_to_arena(Arena *next_arena) +{ + m_current_arena = next_arena; + if (!next_arena) { + return 0; + } + m_current_ofs = sizeof (Arena); + ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (next_arena, m_current_ofs); + // Check if end of allocation has been reached + if (m_current_ofs >= next_arena->m_used) { + return 0; + } + return ((char*) next_arena) + m_current_ofs; +} diff --git a/libs/ode-0.16.1/ode/src/obstack.h b/libs/ode-0.16.1/ode/src/obstack.h new file mode 100644 index 0000000..8d4f067 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/obstack.h @@ -0,0 +1,73 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_OBSTACK_H_ +#define _ODE_OBSTACK_H_ + +#include "objects.h" + +// each obstack Arena pointer points to a block of this many bytes +#define dOBSTACK_ARENA_SIZE 16384 + + +struct dObStack : public dBase { + dObStack(); + ~dObStack(); + + void *alloc (sizeint num_bytes); + // allocate a block in the last arena, allocating a new arena if necessary. + // it is a runtime error if num_bytes is larger than the arena size. + + void freeAll(); + // free all blocks in all arenas. this does not deallocate the arenas + // themselves, so future alloc()s will reuse them. + + void *rewind(); + // rewind the obstack iterator, and return the address of the first + // allocated block. return 0 if there are no allocated blocks. + + void *next (sizeint num_bytes); + // return the address of the next allocated block. 'num_bytes' is the size + // of the previous block. this returns null if there are no more arenas. + // the sequence of 'num_bytes' parameters passed to next() during a + // traversal of the list must exactly match the parameters passed to alloc(). + +private: + struct Arena { + Arena *m_next; // next arena in linked list + sizeint m_used; // total number of bytes used in this arena, counting + }; // this header + +private: + void *switch_to_arena(Arena *next_arena); + +private: + Arena *m_first; // head of the arena linked list. 0 if no arenas yet + Arena *m_last; // arena where blocks are currently being allocated + + // used for iterator + Arena *m_current_arena; + sizeint m_current_ofs; +}; + + +#endif diff --git a/libs/ode-0.16.1/ode/src/ode.cpp b/libs/ode-0.16.1/ode/src/ode.cpp new file mode 100644 index 0000000..40bfd6a --- /dev/null +++ b/libs/ode-0.16.1/ode/src/ode.cpp @@ -0,0 +1,2325 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifdef _MSC_VER +#pragma warning(disable:4291) // for VC++, no complaints about "no matching operator delete found" +#endif + +// this source file is mostly concerned with the data structures, not the +// numerics. + +#include <ode/ode.h> +#include <ode/memory.h> +#include <ode/error.h> +#include "config.h" +#include "matrix.h" +#include "odemath.h" +#include "objects.h" +#include "joints/joints.h" +#include "step.h" +#include "quickstep.h" +#include "util.h" +#include "odetls.h" + +// misc defines +#define ALLOCA dALLOCA16 + +//**************************************************************************** +// utility + + +// add an object `obj' to the list who's head pointer is pointed to by `first'. + +void addObjectToList (dObject *obj, dObject **first) +{ + obj->next = *first; + obj->tome = first; + if (*first) (*first)->tome = &obj->next; + (*first) = obj; +} + + +// remove the object from the linked list + +static inline void removeObjectFromList (dObject *obj) +{ + if (obj->next) obj->next->tome = obj->tome; + *(obj->tome) = obj->next; + // safeguard + obj->next = NULL; + obj->tome = NULL; +} + + +// remove the joint from neighbour lists of all connected bodies + +static void removeJointReferencesFromAttachedBodies (dxJoint *j) +{ + for (int i=0; i<2; i++) { + dxBody *body = j->node[i].body; + if (body) { + dxJointNode *n = body->firstjoint; + dxJointNode *last = NULL; + while (n) { + if (n->joint == j) { + if (last) last->next = n->next; + else body->firstjoint = n->next; + break; + } + last = n; + n = n->next; + } + } + } + j->node[0].body = NULL; + j->node[0].next = NULL; + j->node[1].body = NULL; + j->node[1].next = NULL; +} + +//**************************************************************************** +// debugging + +// see if an object list loops on itself (if so, it's bad). + +static int listHasLoops (dObject *first) +{ + if (first==0 || first->next==0) return 0; + dObject *a=first,*b=first->next; + int skip=0; + while (b) { + if (a==b) return 1; + b = b->next; + if (skip) a = a->next; + skip ^= 1; + } + return 0; +} + + +// check the validity of the world data structures + +static int g_world_check_tag_generator = 0; + +static inline int generateWorldCheckTag() +{ + // Atomicity is not necessary here + return ++g_world_check_tag_generator; +} + +static void checkWorld (dxWorld *w) +{ + dxBody *b; + dxJoint *j; + + // check there are no loops + if (listHasLoops (w->firstbody)) dDebug (0,"body list has loops"); + if (listHasLoops (w->firstjoint)) dDebug (0,"joint list has loops"); + + // check lists are well formed (check `tome' pointers) + for (b=w->firstbody; b; b=(dxBody*)b->next) { + if (b->next && b->next->tome != &b->next) + dDebug (0,"bad tome pointer in body list"); + } + for (j=w->firstjoint; j; j=(dxJoint*)j->next) { + if (j->next && j->next->tome != &j->next) + dDebug (0,"bad tome pointer in joint list"); + } + + // check counts + int n = 0; + for (b=w->firstbody; b; b=(dxBody*)b->next) n++; + if (w->nb != n) dDebug (0,"body count incorrect"); + n = 0; + for (j=w->firstjoint; j; j=(dxJoint*)j->next) n++; + if (w->nj != n) dDebug (0,"joint count incorrect"); + + // set all tag values to a known value + int count = generateWorldCheckTag(); + for (b=w->firstbody; b; b=(dxBody*)b->next) b->tag = count; + for (j=w->firstjoint; j; j=(dxJoint*)j->next) j->tag = count; + + // check all body/joint world pointers are ok + for (b=w->firstbody; b; b=(dxBody*)b->next) if (b->world != w) + dDebug (0,"bad world pointer in body list"); + for (j=w->firstjoint; j; j=(dxJoint*)j->next) if (j->world != w) + dDebug (0,"bad world pointer in joint list"); + + /* + // check for half-connected joints - actually now these are valid + for (j=w->firstjoint; j; j=(dxJoint*)j->next) { + if (j->node[0].body || j->node[1].body) { + if (!(j->node[0].body && j->node[1].body)) + dDebug (0,"half connected joint found"); + } + } + */ + + // check that every joint node appears in the joint lists of both bodies it + // attaches + for (j=w->firstjoint; j; j=(dxJoint*)j->next) { + for (int i=0; i<2; i++) { + if (j->node[i].body) { + int ok = 0; + for (dxJointNode *n=j->node[i].body->firstjoint; n; n=n->next) { + if (n->joint == j) ok = 1; + } + if (ok==0) dDebug (0,"joint not in joint list of attached body"); + } + } + } + + // check all body joint lists (correct body ptrs) + for (b=w->firstbody; b; b=(dxBody*)b->next) { + for (dxJointNode *n=b->firstjoint; n; n=n->next) { + if (&n->joint->node[0] == n) { + if (n->joint->node[1].body != b) + dDebug (0,"bad body pointer in joint node of body list (1)"); + } + else { + if (n->joint->node[0].body != b) + dDebug (0,"bad body pointer in joint node of body list (2)"); + } + if (n->joint->tag != count) dDebug (0,"bad joint node pointer in body"); + } + } + + // check all body pointers in joints, check they are distinct + for (j=w->firstjoint; j; j=(dxJoint*)j->next) { + if (j->node[0].body && (j->node[0].body == j->node[1].body)) + dDebug (0,"non-distinct body pointers in joint"); + if ((j->node[0].body && j->node[0].body->tag != count) || + (j->node[1].body && j->node[1].body->tag != count)) + dDebug (0,"bad body pointer in joint"); + } +} + + +void dWorldCheck (dxWorld *w) +{ + checkWorld (w); +} + +//**************************************************************************** +// body + +dxBody::dxBody(dxWorld *w) : +dObject(w) +{ + +} + + +dxWorld* dBodyGetWorld (dxBody * b) +{ + dAASSERT (b); + return b->world; +} + +dxBody *dBodyCreate (dxWorld *w) +{ + dAASSERT (w); + dxBody *b = new dxBody(w); + b->firstjoint = NULL; + b->flags = 0; + b->geom = NULL; + b->average_lvel_buffer = NULL; + b->average_avel_buffer = NULL; + dMassSetParameters (&b->mass,1,0,0,0,1,1,1,0,0,0); + dSetZero (b->invI,4*3); + b->invI[0] = 1; + b->invI[5] = 1; + b->invI[10] = 1; + b->invMass = 1; + dSetZero (b->posr.pos,4); + dSetZero (b->q,4); + b->q[0] = 1; + dRSetIdentity (b->posr.R); + dSetZero (b->lvel,4); + dSetZero (b->avel,4); + dSetZero (b->facc,4); + dSetZero (b->tacc,4); + dSetZero (b->finite_rot_axis,4); + addObjectToList (b,(dObject **) &w->firstbody); + w->nb++; + + // set auto-disable parameters + b->average_avel_buffer = b->average_lvel_buffer = NULL; // no buffer at beginning + dBodySetAutoDisableDefaults (b); // must do this after adding to world + b->adis_stepsleft = b->adis.idle_steps; + b->adis_timeleft = b->adis.idle_time; + b->average_counter = 0; + b->average_ready = 0; // average buffer not filled on the beginning + dBodySetAutoDisableAverageSamplesCount(b, b->adis.average_samples); + + b->moved_callback = NULL; + + dBodySetDampingDefaults(b); // must do this after adding to world + + b->flags |= w->body_flags & dxBodyMaxAngularSpeed; + b->max_angular_speed = w->max_angular_speed; + + b->flags |= dxBodyGyroscopic; + + return b; +} + + +void dBodyDestroy (dxBody *b) +{ + dAASSERT (b); + + // all geoms that link to this body must be notified that the body is about + // to disappear. note that the call to dGeomSetBody(geom,0) will result in + // dGeomGetBodyNext() returning 0 for the body, so we must get the next body + // before setting the body to 0. + dxGeom *next_geom = NULL; + for (dxGeom *geom = b->geom; geom; geom = next_geom) { + next_geom = dGeomGetBodyNext (geom); + dGeomSetBody (geom,0); + } + + // detach all neighbouring joints, then delete this body. + dxJointNode *n = b->firstjoint; + while (n) { + // sneaky trick to speed up removal of joint references (black magic) + n->joint->node[(n == n->joint->node)].body = NULL; + + dxJointNode *next = n->next; + n->next = NULL; + removeJointReferencesFromAttachedBodies (n->joint); + n = next; + } + removeObjectFromList (b); + b->world->nb--; + + // delete the average buffers + if(b->average_lvel_buffer) + { + delete[] (b->average_lvel_buffer); + b->average_lvel_buffer = NULL; + } + if(b->average_avel_buffer) + { + delete[] (b->average_avel_buffer); + b->average_avel_buffer = NULL; + } + + delete b; +} + + +void dBodySetData (dBodyID b, void *data) +{ + dAASSERT (b); + b->userdata = data; +} + + +void *dBodyGetData (dBodyID b) +{ + dAASSERT (b); + return b->userdata; +} + + +void dBodySetPosition (dBodyID b, dReal x, dReal y, dReal z) +{ + dAASSERT (b); + b->posr.pos[0] = x; + b->posr.pos[1] = y; + b->posr.pos[2] = z; + + // notify all attached geoms that this body has moved + for (dxGeom *geom = b->geom; geom; geom = dGeomGetBodyNext (geom)) + dGeomMoved (geom); +} + + +void dBodySetRotation (dBodyID b, const dMatrix3 R) +{ + dAASSERT (b && R); + + memcpy(b->posr.R, R, sizeof(dMatrix3)); + + bool bOrthogonalizeResult = dxOrthogonalizeR(b->posr.R); + dAVERIFY(bOrthogonalizeResult); + + dRtoQ (R, b->q); + dNormalize4 (b->q); + + // notify all attached geoms that this body has moved + for (dxGeom *geom = b->geom; geom; geom = dGeomGetBodyNext (geom)) { + dGeomMoved (geom); + } +} + + +void dBodySetQuaternion (dBodyID b, const dQuaternion q) +{ + dAASSERT (b && q); + b->q[0] = q[0]; + b->q[1] = q[1]; + b->q[2] = q[2]; + b->q[3] = q[3]; + dNormalize4 (b->q); + dQtoR (b->q,b->posr.R); + + // notify all attached geoms that this body has moved + for (dxGeom *geom = b->geom; geom; geom = dGeomGetBodyNext (geom)) + dGeomMoved (geom); +} + + +void dBodySetLinearVel (dBodyID b, dReal x, dReal y, dReal z) +{ + dAASSERT (b); + b->lvel[0] = x; + b->lvel[1] = y; + b->lvel[2] = z; +} + + +void dBodySetAngularVel (dBodyID b, dReal x, dReal y, dReal z) +{ + dAASSERT (b); + b->avel[0] = x; + b->avel[1] = y; + b->avel[2] = z; +} + + +const dReal * dBodyGetPosition (dBodyID b) +{ + dAASSERT (b); + return b->posr.pos; +} + + +void dBodyCopyPosition (dBodyID b, dVector3 pos) +{ + dAASSERT (b); + dReal* src = b->posr.pos; + pos[0] = src[0]; + pos[1] = src[1]; + pos[2] = src[2]; +} + + +const dReal * dBodyGetRotation (dBodyID b) +{ + dAASSERT (b); + return b->posr.R; +} + + +void dBodyCopyRotation (dBodyID b, dMatrix3 R) +{ + dAASSERT (b); + const dReal* src = b->posr.R; + R[0] = src[0]; + R[1] = src[1]; + R[2] = src[2]; + R[3] = src[3]; + R[4] = src[4]; + R[5] = src[5]; + R[6] = src[6]; + R[7] = src[7]; + R[8] = src[8]; + R[9] = src[9]; + R[10] = src[10]; + R[11] = src[11]; +} + + +const dReal * dBodyGetQuaternion (dBodyID b) +{ + dAASSERT (b); + return b->q; +} + + +void dBodyCopyQuaternion (dBodyID b, dQuaternion quat) +{ + dAASSERT (b); + dReal* src = b->q; + quat[0] = src[0]; + quat[1] = src[1]; + quat[2] = src[2]; + quat[3] = src[3]; +} + + +const dReal * dBodyGetLinearVel (dBodyID b) +{ + dAASSERT (b); + return b->lvel; +} + + +const dReal * dBodyGetAngularVel (dBodyID b) +{ + dAASSERT (b); + return b->avel; +} + + +void dBodySetMass (dBodyID b, const dMass *mass) +{ + dAASSERT (b && mass ); + dIASSERT(dMassCheck(mass)); + + // The centre of mass must be at the origin. + // Use dMassTranslate( mass, -mass->c[0], -mass->c[1], -mass->c[2] ) to correct it. + dUASSERT( fabs( mass->c[0] ) <= dEpsilon && + fabs( mass->c[1] ) <= dEpsilon && + fabs( mass->c[2] ) <= dEpsilon, "The centre of mass must be at the origin." ); + + b->mass = *mass; + if (dInvertPDMatrix (b->mass.I,b->invI,3,NULL)==0) { + dDEBUGMSG ("inertia must be positive definite!"); + dRSetIdentity (b->invI); + } + b->invMass = dRecip(b->mass.mass); +} + + +void dBodyGetMass (dBodyID b, dMass *mass) +{ + dAASSERT (b && mass); + *mass = b->mass; +} + + +void dBodyAddForce (dBodyID b, dReal fx, dReal fy, dReal fz) +{ + dAASSERT (b); + b->facc[0] += fx; + b->facc[1] += fy; + b->facc[2] += fz; +} + + +void dBodyAddTorque (dBodyID b, dReal fx, dReal fy, dReal fz) +{ + dAASSERT (b); + b->tacc[0] += fx; + b->tacc[1] += fy; + b->tacc[2] += fz; +} + + +void dBodyAddRelForce (dBodyID b, dReal fx, dReal fy, dReal fz) +{ + dAASSERT (b); + dVector3 t1,t2; + t1[0] = fx; + t1[1] = fy; + t1[2] = fz; + t1[3] = 0; + dMultiply0_331 (t2,b->posr.R,t1); + b->facc[0] += t2[0]; + b->facc[1] += t2[1]; + b->facc[2] += t2[2]; +} + + +void dBodyAddRelTorque (dBodyID b, dReal fx, dReal fy, dReal fz) +{ + dAASSERT (b); + dVector3 t1,t2; + t1[0] = fx; + t1[1] = fy; + t1[2] = fz; + t1[3] = 0; + dMultiply0_331 (t2,b->posr.R,t1); + b->tacc[0] += t2[0]; + b->tacc[1] += t2[1]; + b->tacc[2] += t2[2]; +} + + +void dBodyAddForceAtPos (dBodyID b, dReal fx, dReal fy, dReal fz, + dReal px, dReal py, dReal pz) +{ + dAASSERT (b); + b->facc[0] += fx; + b->facc[1] += fy; + b->facc[2] += fz; + dVector3 f,q; + f[0] = fx; + f[1] = fy; + f[2] = fz; + q[0] = px - b->posr.pos[0]; + q[1] = py - b->posr.pos[1]; + q[2] = pz - b->posr.pos[2]; + dAddVectorCross3(b->tacc,q,f); +} + + +void dBodyAddForceAtRelPos (dBodyID b, dReal fx, dReal fy, dReal fz, + dReal px, dReal py, dReal pz) +{ + dAASSERT (b); + dVector3 prel,f,p; + f[0] = fx; + f[1] = fy; + f[2] = fz; + f[3] = 0; + prel[0] = px; + prel[1] = py; + prel[2] = pz; + prel[3] = 0; + dMultiply0_331 (p,b->posr.R,prel); + b->facc[0] += f[0]; + b->facc[1] += f[1]; + b->facc[2] += f[2]; + dAddVectorCross3(b->tacc,p,f); +} + + +void dBodyAddRelForceAtPos (dBodyID b, dReal fx, dReal fy, dReal fz, + dReal px, dReal py, dReal pz) +{ + dAASSERT (b); + dVector3 frel,f; + frel[0] = fx; + frel[1] = fy; + frel[2] = fz; + frel[3] = 0; + dMultiply0_331 (f,b->posr.R,frel); + b->facc[0] += f[0]; + b->facc[1] += f[1]; + b->facc[2] += f[2]; + dVector3 q; + q[0] = px - b->posr.pos[0]; + q[1] = py - b->posr.pos[1]; + q[2] = pz - b->posr.pos[2]; + dAddVectorCross3(b->tacc,q,f); +} + + +void dBodyAddRelForceAtRelPos (dBodyID b, dReal fx, dReal fy, dReal fz, + dReal px, dReal py, dReal pz) +{ + dAASSERT (b); + dVector3 frel,prel,f,p; + frel[0] = fx; + frel[1] = fy; + frel[2] = fz; + frel[3] = 0; + prel[0] = px; + prel[1] = py; + prel[2] = pz; + prel[3] = 0; + dMultiply0_331 (f,b->posr.R,frel); + dMultiply0_331 (p,b->posr.R,prel); + b->facc[0] += f[0]; + b->facc[1] += f[1]; + b->facc[2] += f[2]; + dAddVectorCross3(b->tacc,p,f); +} + + +const dReal * dBodyGetForce (dBodyID b) +{ + dAASSERT (b); + return b->facc; +} + + +const dReal * dBodyGetTorque (dBodyID b) +{ + dAASSERT (b); + return b->tacc; +} + + +void dBodySetForce (dBodyID b, dReal x, dReal y, dReal z) +{ + dAASSERT (b); + b->facc[0] = x; + b->facc[1] = y; + b->facc[2] = z; +} + + +void dBodySetTorque (dBodyID b, dReal x, dReal y, dReal z) +{ + dAASSERT (b); + b->tacc[0] = x; + b->tacc[1] = y; + b->tacc[2] = z; +} + + +void dBodyGetRelPointPos (dBodyID b, dReal px, dReal py, dReal pz, + dVector3 result) +{ + dAASSERT (b); + dVector3 prel,p; + prel[0] = px; + prel[1] = py; + prel[2] = pz; + prel[3] = 0; + dMultiply0_331 (p,b->posr.R,prel); + result[0] = p[0] + b->posr.pos[0]; + result[1] = p[1] + b->posr.pos[1]; + result[2] = p[2] + b->posr.pos[2]; +} + + +void dBodyGetRelPointVel (dBodyID b, dReal px, dReal py, dReal pz, + dVector3 result) +{ + dAASSERT (b); + dVector3 prel,p; + prel[0] = px; + prel[1] = py; + prel[2] = pz; + prel[3] = 0; + dMultiply0_331 (p,b->posr.R,prel); + result[0] = b->lvel[0]; + result[1] = b->lvel[1]; + result[2] = b->lvel[2]; + dAddVectorCross3(result,b->avel,p); +} + + +void dBodyGetPointVel (dBodyID b, dReal px, dReal py, dReal pz, + dVector3 result) +{ + dAASSERT (b); + dVector3 p; + p[0] = px - b->posr.pos[0]; + p[1] = py - b->posr.pos[1]; + p[2] = pz - b->posr.pos[2]; + p[3] = 0; + result[0] = b->lvel[0]; + result[1] = b->lvel[1]; + result[2] = b->lvel[2]; + dAddVectorCross3(result,b->avel,p); +} + + +void dBodyGetPosRelPoint (dBodyID b, dReal px, dReal py, dReal pz, + dVector3 result) +{ + dAASSERT (b); + dVector3 prel; + prel[0] = px - b->posr.pos[0]; + prel[1] = py - b->posr.pos[1]; + prel[2] = pz - b->posr.pos[2]; + prel[3] = 0; + dMultiply1_331 (result,b->posr.R,prel); +} + + +void dBodyVectorToWorld (dBodyID b, dReal px, dReal py, dReal pz, + dVector3 result) +{ + dAASSERT (b); + dVector3 p; + p[0] = px; + p[1] = py; + p[2] = pz; + p[3] = 0; + dMultiply0_331 (result,b->posr.R,p); +} + + +void dBodyVectorFromWorld (dBodyID b, dReal px, dReal py, dReal pz, + dVector3 result) +{ + dAASSERT (b); + dVector3 p; + p[0] = px; + p[1] = py; + p[2] = pz; + p[3] = 0; + dMultiply1_331 (result,b->posr.R,p); +} + + +void dBodySetFiniteRotationMode (dBodyID b, int mode) +{ + dAASSERT (b); + b->flags &= ~(dxBodyFlagFiniteRotation | dxBodyFlagFiniteRotationAxis); + if (mode) { + b->flags |= dxBodyFlagFiniteRotation; + if (b->finite_rot_axis[0] != 0 || b->finite_rot_axis[1] != 0 || + b->finite_rot_axis[2] != 0) { + b->flags |= dxBodyFlagFiniteRotationAxis; + } + } +} + + +void dBodySetFiniteRotationAxis (dBodyID b, dReal x, dReal y, dReal z) +{ + dAASSERT (b); + b->finite_rot_axis[0] = x; + b->finite_rot_axis[1] = y; + b->finite_rot_axis[2] = z; + if (x != 0 || y != 0 || z != 0) { + dNormalize3 (b->finite_rot_axis); + b->flags |= dxBodyFlagFiniteRotationAxis; + } + else { + b->flags &= ~dxBodyFlagFiniteRotationAxis; + } +} + + +int dBodyGetFiniteRotationMode (dBodyID b) +{ + dAASSERT (b); + return ((b->flags & dxBodyFlagFiniteRotation) != 0); +} + + +void dBodyGetFiniteRotationAxis (dBodyID b, dVector3 result) +{ + dAASSERT (b); + result[0] = b->finite_rot_axis[0]; + result[1] = b->finite_rot_axis[1]; + result[2] = b->finite_rot_axis[2]; +} + + +int dBodyGetNumJoints (dBodyID b) +{ + dAASSERT (b); + int count=0; + for (dxJointNode *n=b->firstjoint; n; n=n->next, count++); + return count; +} + + +dJointID dBodyGetJoint (dBodyID b, int index) +{ + dAASSERT (b); + int i=0; + for (dxJointNode *n=b->firstjoint; n; n=n->next, i++) { + if (i == index) return n->joint; + } + return 0; +} + +void dBodySetDynamic (dBodyID b) +{ + dAASSERT (b); + + dBodySetMass(b,&b->mass); +} + +void dBodySetKinematic (dBodyID b) +{ + dAASSERT (b); + dSetZero (b->invI,4*3); + b->invMass = 0; +} + +int dBodyIsKinematic (dBodyID b) +{ + dAASSERT (b); + return b->invMass == 0; +} + +void dBodyEnable (dBodyID b) +{ + dAASSERT (b); + b->flags &= ~dxBodyDisabled; + b->adis_stepsleft = b->adis.idle_steps; + b->adis_timeleft = b->adis.idle_time; + // no code for average-processing needed here +} + + +void dBodyDisable (dBodyID b) +{ + dAASSERT (b); + b->flags |= dxBodyDisabled; +} + + +int dBodyIsEnabled (dBodyID b) +{ + dAASSERT (b); + return ((b->flags & dxBodyDisabled) == 0); +} + + +void dBodySetGravityMode (dBodyID b, int mode) +{ + dAASSERT (b); + if (mode) b->flags &= ~dxBodyNoGravity; + else b->flags |= dxBodyNoGravity; +} + + +int dBodyGetGravityMode (dBodyID b) +{ + dAASSERT (b); + return ((b->flags & dxBodyNoGravity) == 0); +} + + +// body auto-disable functions + +dReal dBodyGetAutoDisableLinearThreshold (dBodyID b) +{ + dAASSERT(b); + return dSqrt (b->adis.linear_average_threshold); +} + + +void dBodySetAutoDisableLinearThreshold (dBodyID b, dReal linear_average_threshold) +{ + dAASSERT(b); + b->adis.linear_average_threshold = linear_average_threshold * linear_average_threshold; +} + + +dReal dBodyGetAutoDisableAngularThreshold (dBodyID b) +{ + dAASSERT(b); + return dSqrt (b->adis.angular_average_threshold); +} + + +void dBodySetAutoDisableAngularThreshold (dBodyID b, dReal angular_average_threshold) +{ + dAASSERT(b); + b->adis.angular_average_threshold = angular_average_threshold * angular_average_threshold; +} + + +int dBodyGetAutoDisableAverageSamplesCount (dBodyID b) +{ + dAASSERT(b); + return b->adis.average_samples; +} + + +void dBodySetAutoDisableAverageSamplesCount (dBodyID b, unsigned int average_samples_count) +{ + dAASSERT(b); + b->adis.average_samples = average_samples_count; + // update the average buffers + if(b->average_lvel_buffer) + { + delete[] b->average_lvel_buffer; + b->average_lvel_buffer = NULL; + } + if(b->average_avel_buffer) + { + delete[] b->average_avel_buffer; + b->average_avel_buffer = NULL; + } + if(b->adis.average_samples > 0) + { + b->average_lvel_buffer = new dVector3[b->adis.average_samples]; + b->average_avel_buffer = new dVector3[b->adis.average_samples]; + } + else + { + b->average_lvel_buffer = NULL; + b->average_avel_buffer = NULL; + } + // new buffer is empty + b->average_counter = 0; + b->average_ready = 0; +} + + +int dBodyGetAutoDisableSteps (dBodyID b) +{ + dAASSERT(b); + return b->adis.idle_steps; +} + + +void dBodySetAutoDisableSteps (dBodyID b, int steps) +{ + dAASSERT(b); + b->adis.idle_steps = steps; +} + + +dReal dBodyGetAutoDisableTime (dBodyID b) +{ + dAASSERT(b); + return b->adis.idle_time; +} + + +void dBodySetAutoDisableTime (dBodyID b, dReal time) +{ + dAASSERT(b); + b->adis.idle_time = time; +} + + +int dBodyGetAutoDisableFlag (dBodyID b) +{ + dAASSERT(b); + return ((b->flags & dxBodyAutoDisable) != 0); +} + + +void dBodySetAutoDisableFlag (dBodyID b, int do_auto_disable) +{ + dAASSERT(b); + if (!do_auto_disable) + { + b->flags &= ~dxBodyAutoDisable; + // (mg) we should also reset the IsDisabled state to correspond to the DoDisabling flag + b->flags &= ~dxBodyDisabled; + b->adis.idle_steps = dWorldGetAutoDisableSteps(b->world); + b->adis.idle_time = dWorldGetAutoDisableTime(b->world); + // resetting the average calculations too + dBodySetAutoDisableAverageSamplesCount(b, dWorldGetAutoDisableAverageSamplesCount(b->world) ); + } + else + { + b->flags |= dxBodyAutoDisable; + } +} + + +void dBodySetAutoDisableDefaults (dBodyID b) +{ + dAASSERT(b); + dWorldID w = b->world; + dAASSERT(w); + b->adis = w->adis; + dBodySetAutoDisableFlag (b, w->body_flags & dxBodyAutoDisable); +} + + +// body damping functions + +dReal dBodyGetLinearDamping(dBodyID b) +{ + dAASSERT(b); + return b->dampingp.linear_scale; +} + +void dBodySetLinearDamping(dBodyID b, dReal scale) +{ + dAASSERT(b); + if (scale) + b->flags |= dxBodyLinearDamping; + else + b->flags &= ~dxBodyLinearDamping; + b->dampingp.linear_scale = scale; +} + +dReal dBodyGetAngularDamping(dBodyID b) +{ + dAASSERT(b); + return b->dampingp.angular_scale; +} + +void dBodySetAngularDamping(dBodyID b, dReal scale) +{ + dAASSERT(b); + if (scale) + b->flags |= dxBodyAngularDamping; + else + b->flags &= ~dxBodyAngularDamping; + b->dampingp.angular_scale = scale; +} + +void dBodySetDamping(dBodyID b, dReal linear_scale, dReal angular_scale) +{ + dAASSERT(b); + dBodySetLinearDamping(b, linear_scale); + dBodySetAngularDamping(b, angular_scale); +} + +dReal dBodyGetLinearDampingThreshold(dBodyID b) +{ + dAASSERT(b); + return dSqrt(b->dampingp.linear_threshold); +} + +void dBodySetLinearDampingThreshold(dBodyID b, dReal threshold) +{ + dAASSERT(b); + b->dampingp.linear_threshold = threshold*threshold; +} + + +dReal dBodyGetAngularDampingThreshold(dBodyID b) +{ + dAASSERT(b); + return dSqrt(b->dampingp.angular_threshold); +} + +void dBodySetAngularDampingThreshold(dBodyID b, dReal threshold) +{ + dAASSERT(b); + b->dampingp.angular_threshold = threshold*threshold; +} + +void dBodySetDampingDefaults(dBodyID b) +{ + dAASSERT(b); + dWorldID w = b->world; + dAASSERT(w); + b->dampingp = w->dampingp; + const unsigned mask = dxBodyLinearDamping | dxBodyAngularDamping; + b->flags &= ~mask; // zero them + b->flags |= w->body_flags & mask; +} + +dReal dBodyGetMaxAngularSpeed(dBodyID b) +{ + dAASSERT(b); + return b->max_angular_speed; +} + +void dBodySetMaxAngularSpeed(dBodyID b, dReal max_speed) +{ + dAASSERT(b); + if (max_speed < dInfinity) + b->flags |= dxBodyMaxAngularSpeed; + else + b->flags &= ~dxBodyMaxAngularSpeed; + b->max_angular_speed = max_speed; +} + +void dBodySetMovedCallback(dBodyID b, void (*callback)(dBodyID)) +{ + dAASSERT(b); + b->moved_callback = callback; +} + + +dGeomID dBodyGetFirstGeom(dBodyID b) +{ + dAASSERT(b); + return b->geom; +} + + +dGeomID dBodyGetNextGeom(dGeomID geom) +{ + dAASSERT(geom); + return dGeomGetBodyNext(geom); +} + + +int dBodyGetGyroscopicMode(dBodyID b) +{ + dAASSERT(b); + return b->flags & dxBodyGyroscopic; +} + +void dBodySetGyroscopicMode(dBodyID b, int enabled) +{ + dAASSERT(b); + if (enabled) + b->flags |= dxBodyGyroscopic; + else + b->flags &= ~dxBodyGyroscopic; +} + + + +//**************************************************************************** +// joints + + + +template<class T> +dxJoint* createJoint(dWorldID w, dJointGroupID group) +{ + dxJoint *j; + if (group) { + j = group->alloc<T>(w); + } else { + j = new T(w); + } + return j; +} + + +dxJoint * dJointCreateBall (dWorldID w, dJointGroupID group) +{ + dAASSERT (w); + return createJoint<dxJointBall>(w,group); +} + + +dxJoint * dJointCreateHinge (dWorldID w, dJointGroupID group) +{ + dAASSERT (w); + return createJoint<dxJointHinge>(w,group); +} + + +dxJoint * dJointCreateSlider (dWorldID w, dJointGroupID group) +{ + dAASSERT (w); + return createJoint<dxJointSlider>(w,group); +} + + +dxJoint * dJointCreateContact (dWorldID w, dJointGroupID group, + const dContact *c) +{ + dAASSERT (w && c); + dxJointContact *j = (dxJointContact *) + createJoint<dxJointContact> (w,group); + j->contact = *c; + return j; +} + + +dxJoint * dJointCreateHinge2 (dWorldID w, dJointGroupID group) +{ + dAASSERT (w); + return createJoint<dxJointHinge2> (w,group); +} + + +dxJoint * dJointCreateUniversal (dWorldID w, dJointGroupID group) +{ + dAASSERT (w); + return createJoint<dxJointUniversal> (w,group); +} + +dxJoint * dJointCreatePR (dWorldID w, dJointGroupID group) +{ + dAASSERT (w); + return createJoint<dxJointPR> (w,group); +} + +dxJoint * dJointCreatePU (dWorldID w, dJointGroupID group) +{ + dAASSERT (w); + return createJoint<dxJointPU> (w,group); +} + +dxJoint * dJointCreatePiston (dWorldID w, dJointGroupID group) +{ + dAASSERT (w); + return createJoint<dxJointPiston> (w,group); +} + +dxJoint * dJointCreateFixed (dWorldID w, dJointGroupID group) +{ + dAASSERT (w); + return createJoint<dxJointFixed> (w,group); +} + + +dxJoint * dJointCreateNull (dWorldID w, dJointGroupID group) +{ + dAASSERT (w); + return createJoint<dxJointNull> (w,group); +} + + +dxJoint * dJointCreateAMotor (dWorldID w, dJointGroupID group) +{ + dAASSERT (w); + return createJoint<dxJointAMotor> (w,group); +} + +dxJoint * dJointCreateLMotor (dWorldID w, dJointGroupID group) +{ + dAASSERT (w); + return createJoint<dxJointLMotor> (w,group); +} + +dxJoint * dJointCreatePlane2D (dWorldID w, dJointGroupID group) +{ + dAASSERT (w); + return createJoint<dxJointPlane2D> (w,group); +} + +dxJoint * dJointCreateDBall (dWorldID w, dJointGroupID group) +{ + dAASSERT (w); + return createJoint<dxJointDBall> (w,group); +} + +dxJoint * dJointCreateDHinge (dWorldID w, dJointGroupID group) +{ + dAASSERT (w); + return createJoint<dxJointDHinge> (w,group); +} + + +dxJoint * dJointCreateTransmission (dWorldID w, dJointGroupID group) +{ + dAASSERT (w); + return createJoint<dxJointTransmission> (w,group); +} + +static void FinalizeAndDestroyJointInstance(dxJoint *j, bool delete_it) +{ + // if any group joints have their world pointer set to 0, their world was + // previously destroyed. no special handling is required for these joints. + if (j->world != NULL) { + removeJointReferencesFromAttachedBodies (j); + removeObjectFromList (j); + j->world->nj--; + } + if (delete_it) { + delete j; + } else { + j->~dxJoint(); + } +} + +void dJointDestroy (dxJoint *j) +{ + dAASSERT (j); + if (!(j->flags & dJOINT_INGROUP)) { + FinalizeAndDestroyJointInstance(j, true); + } +} + + +dJointGroupID dJointGroupCreate (int /*max_size*/) +{ + // not any more ... dUASSERT (max_size > 0,"max size must be > 0"); + dxJointGroup *group = new dxJointGroup(); + return group; +} + + +void dJointGroupDestroy (dJointGroupID group) +{ + dAASSERT (group); + dJointGroupEmpty (group); + delete group; +} + +void dJointGroupEmpty (dJointGroupID group) +{ + dAASSERT (group); + + const sizeint num_joints = group->getJointCount(); + if (num_joints != 0) { + // Local array is used since ALLOCA leads to mysterious NULL values in first array element and crashes under VS2005 :) + const sizeint max_stack_jlist_size = 1024; + dxJoint *stack_jlist[max_stack_jlist_size]; + + const sizeint jlist_size = num_joints * sizeof(dxJoint*); + dxJoint **jlist = num_joints <= max_stack_jlist_size ? stack_jlist : (dxJoint **)dAlloc(jlist_size); + + if (jlist != NULL) { + // the joints in this group are detached starting from the most recently + // added (at the top of the stack). this helps ensure that the various + // linked lists are not traversed too much, as the joints will hopefully + // be at the start of those lists. + sizeint num_exported = group->exportJoints(jlist); + dIVERIFY(num_exported == num_joints); + + for (sizeint i = num_joints; i != 0; ) { + --i; + dxJoint *j = jlist[i]; + FinalizeAndDestroyJointInstance(j, false); + } + } else { + // ...else if there is no memory, go on detaching the way it is possible + sizeint joint_bytes; + for (dxJoint *j = (dxJoint *)group->beginEnum(); j != NULL; j = (dxJoint *)group->continueEnum(joint_bytes)) { + joint_bytes = j->size(); // Get size before object is destroyed! + FinalizeAndDestroyJointInstance(j, false); + } + } + + group->freeAll(); + + if (jlist != stack_jlist && jlist != NULL) { + dFree(jlist, jlist_size); + } + } +} + + +int dJointGetNumBodies(dxJoint *joint) +{ + // check arguments + dUASSERT (joint,"bad joint argument"); + + if ( !joint->node[0].body ) + return 0; + else if ( !joint->node[1].body ) + return 1; + else + return 2; +} + + +void dJointAttach (dxJoint *joint, dxBody *body1, dxBody *body2) +{ + // check arguments + dUASSERT (joint,"bad joint argument"); + dUASSERT (body1 == NULL || body1 != body2, "can't have body1==body2"); + dxWorld *world = joint->world; + dUASSERT ( (body1 == NULL || body1->world == world) && + (body2 == NULL || body2->world == world), + "joint and bodies must be in same world"); + + // check if the joint can not be attached to just one body + dUASSERT (!((joint->flags & dJOINT_TWOBODIES) && + ((body1 != NULL) != (body2 != NULL))), + "joint can not be attached to just one body"); + + // remove any existing body attachments + if (joint->node[0].body != NULL || joint->node[1].body != NULL) { + removeJointReferencesFromAttachedBodies (joint); + } + + // if a body is zero, make sure that it is body2, so 0 --> node[1].body + if (body1 == NULL) { + body1 = body2; + body2 = NULL; + joint->flags |= dJOINT_REVERSE; + } + else { + joint->flags &= (~dJOINT_REVERSE); + } + + // attach to new bodies + joint->node[0].body = body1; + joint->node[1].body = body2; + + if (body1 != NULL) { + joint->node[1].next = body1->firstjoint; + body1->firstjoint = &joint->node[1]; + } + else { + joint->node[1].next = NULL; + } + + if (body2 != NULL) { + joint->node[0].next = body2->firstjoint; + body2->firstjoint = &joint->node[0]; + } + else { + joint->node[0].next = NULL; + } + + // Since the bodies are now set. + // Calculate the values depending on the bodies. + // Only need to calculate relative value if a body exist + if (body1 != NULL || body2 != NULL) { + joint->setRelativeValues(); + } +} + +void dJointEnable (dxJoint *joint) +{ + dAASSERT (joint); + joint->flags &= ~dJOINT_DISABLED; +} + +void dJointDisable (dxJoint *joint) +{ + dAASSERT (joint); + joint->flags |= dJOINT_DISABLED; +} + +int dJointIsEnabled (dxJoint *joint) +{ + dAASSERT (joint); + return (joint->flags & dJOINT_DISABLED) == 0; +} + +void dJointSetData (dxJoint *joint, void *data) +{ + dAASSERT (joint); + joint->userdata = data; +} + + +void *dJointGetData (dxJoint *joint) +{ + dAASSERT (joint); + return joint->userdata; +} + + +dJointType dJointGetType (dxJoint *joint) +{ + dAASSERT (joint); + return joint->type(); +} + + +dBodyID dJointGetBody (dxJoint *joint, int index) +{ + dAASSERT (joint); + if (index == 0 || index == 1) { + if (joint->flags & dJOINT_REVERSE) return joint->node[1-index].body; + else return joint->node[index].body; + } + else return 0; +} + + +void dJointSetFeedback (dxJoint *joint, dJointFeedback *f) +{ + dAASSERT (joint); + joint->feedback = f; +} + + +dJointFeedback *dJointGetFeedback (dxJoint *joint) +{ + dAASSERT (joint); + return joint->feedback; +} + + + +dJointID dConnectingJoint (dBodyID in_b1, dBodyID in_b2) +{ + dAASSERT (in_b1 || in_b2); + + dBodyID b1, b2; + + if (in_b1 == 0) { + b1 = in_b2; + b2 = in_b1; + } + else { + b1 = in_b1; + b2 = in_b2; + } + + // look through b1's neighbour list for b2 + for (dxJointNode *n=b1->firstjoint; n; n=n->next) { + if (n->body == b2) return n->joint; + } + + return 0; +} + + + +int dConnectingJointList (dBodyID in_b1, dBodyID in_b2, dJointID* out_list) +{ + dAASSERT (in_b1 || in_b2); + + + dBodyID b1, b2; + + if (in_b1 == 0) { + b1 = in_b2; + b2 = in_b1; + } + else { + b1 = in_b1; + b2 = in_b2; + } + + // look through b1's neighbour list for b2 + int numConnectingJoints = 0; + for (dxJointNode *n=b1->firstjoint; n; n=n->next) { + if (n->body == b2) + out_list[numConnectingJoints++] = n->joint; + } + + return numConnectingJoints; +} + + +int dAreConnected (dBodyID b1, dBodyID b2) +{ + dAASSERT (b1/* && b2*/); // b2 can be NULL to test for connection to environment + // look through b1's neighbour list for b2 + for (dxJointNode *n=b1->firstjoint; n; n=n->next) { + if (n->body == b2) return 1; + } + return 0; +} + + +int dAreConnectedExcluding (dBodyID b1, dBodyID b2, int joint_type) +{ + dAASSERT (b1/* && b2*/); // b2 can be NULL to test for connection to environment + // look through b1's neighbour list for b2 + for (dxJointNode *n=b1->firstjoint; n; n=n->next) { + if (dJointGetType (n->joint) != joint_type && n->body == b2) return 1; + } + return 0; +} + +//**************************************************************************** +// world + +dxWorld * dWorldCreate() +{ + dxWorld *w = new dxWorld(); + + return w; +} + + +void dWorldDestroy (dxWorld *w) +{ + // delete all bodies and joints + dAASSERT (w); + dxBody *nextb, *b = w->firstbody; + while (b) { + nextb = (dxBody*) b->next; + dBodyDestroy(b); // calling here dBodyDestroy for correct destroying! (i.e. the average buffers) + b = nextb; + } + + dxJoint *nextj, *j = w->firstjoint; + while (j) { + nextj = (dxJoint*)j->next; + if (j->flags & dJOINT_INGROUP) { + // the joint is part of a group, so "deactivate" it instead + j->world = NULL; + j->node[0].body = NULL; + j->node[0].next = NULL; + j->node[1].body = NULL; + j->node[1].next = NULL; + dMessage (0,"warning: destroying world containing grouped joints"); + } + else { + // TODO: shouldn't we call dJointDestroy()? + sizeint sz = j->size(); + j->~dxJoint(); + dFree (j,sz); + } + j = nextj; + } + + delete w; +} + + +void dWorldSetData (dWorldID w, void *data) +{ + dAASSERT (w); + w->userdata = data; +} + + +void* dWorldGetData (dWorldID w) +{ + dAASSERT (w); + return w->userdata; +} + + +void dWorldSetGravity (dWorldID w, dReal x, dReal y, dReal z) +{ + dAASSERT (w); + w->gravity[0] = x; + w->gravity[1] = y; + w->gravity[2] = z; +} + + +void dWorldGetGravity (dWorldID w, dVector3 g) +{ + dAASSERT (w); + g[0] = w->gravity[0]; + g[1] = w->gravity[1]; + g[2] = w->gravity[2]; +} + + +void dWorldSetERP (dWorldID w, dReal erp) +{ + dAASSERT (w); + w->global_erp = erp; +} + + +dReal dWorldGetERP (dWorldID w) +{ + dAASSERT (w); + return w->global_erp; +} + + +void dWorldSetCFM (dWorldID w, dReal cfm) +{ + dAASSERT (w); + w->global_cfm = cfm; +} + + +dReal dWorldGetCFM (dWorldID w) +{ + dAASSERT (w); + return w->global_cfm; +} + + +void dWorldSetStepIslandsProcessingMaxThreadCount(dWorldID w, unsigned count) +{ + dAASSERT (w); + w->islands_max_threads = count; +} + +unsigned dWorldGetStepIslandsProcessingMaxThreadCount(dWorldID w) +{ + dAASSERT (w); + return w->islands_max_threads; +} + +int dWorldUseSharedWorkingMemory(dWorldID w, dWorldID from_world) +{ + dUASSERT (w,"bad world argument"); + + bool result = false; + + if (from_world) + { + dUASSERT (!w->wmem, "world does already have working memory allocated"); // Prevent replacement of one memory object with another to avoid cases when smaller buffer replaces a larger one or memory manager changes. + + dxStepWorkingMemory *wmem = AllocateOnDemand(from_world->wmem); + + if (wmem) + { + // Even though there is an assertion check on entry still release existing + // memory object for extra safety. + if (w->wmem) + { + w->wmem->Release(); + w->wmem = NULL; + } + + wmem->Addref(); + w->wmem = wmem; + + result = true; + } + } + else + { + dxStepWorkingMemory *wmem = w->wmem; + + if (wmem) + { + wmem->Release(); + w->wmem = NULL; + } + + result = true; + } + + return result; +} + +void dWorldCleanupWorkingMemory(dWorldID w) +{ + dUASSERT (w,"bad world argument"); + + dxStepWorkingMemory *wmem = w->wmem; + + if (wmem) + { + wmem->CleanupMemory(); + } +} + +int dWorldSetStepMemoryReservationPolicy(dWorldID w, const dWorldStepReserveInfo *policyinfo) +{ + dUASSERT (w,"bad world argument"); + dUASSERT (!policyinfo || (policyinfo->struct_size >= sizeof(*policyinfo) && policyinfo->reserve_factor >= 1.0f), "Bad policy info"); + + bool result = false; + + dxStepWorkingMemory *wmem = policyinfo ? AllocateOnDemand(w->wmem) : w->wmem; + + if (wmem) + { + if (policyinfo) + { + wmem->SetMemoryReserveInfo(policyinfo->reserve_factor, policyinfo->reserve_minimum); + result = wmem->GetMemoryReserveInfo() != NULL; + } + else + { + wmem->ResetMemoryReserveInfoToDefault(); + result = true; + } + } + else if (!policyinfo) + { + result = true; + } + + return result; +} + +int dWorldSetStepMemoryManager(dWorldID w, const dWorldStepMemoryFunctionsInfo *memfuncs) +{ + dUASSERT (w,"bad world argument"); + dUASSERT (!memfuncs || memfuncs->struct_size >= sizeof(*memfuncs), "Bad memory functions info"); + + bool result = false; + + dxStepWorkingMemory *wmem = memfuncs ? AllocateOnDemand(w->wmem) : w->wmem; + + if (wmem) + { + if (memfuncs) + { + wmem->SetMemoryManager(memfuncs->alloc_block, memfuncs->shrink_block, memfuncs->free_block); + result = wmem->GetMemoryManager() != NULL; + } + else + { + wmem->ResetMemoryManagerToDefault(); + result = true; + } + } + else if (!memfuncs) + { + result = true; + } + + return result; +} + +void dWorldSetStepThreadingImplementation(dWorldID w, + const dxThreadingFunctionsInfo *functions_info, dThreadingImplementationID threading_impl) +{ + dUASSERT (w,"bad world argument"); + dUASSERT (!functions_info || functions_info->struct_size >= sizeof(*functions_info), "Bad threading functions info"); + +#if dTHREADING_INTF_DISABLED + dUASSERT(functions_info == NULL && threading_impl == NULL, "Threading interface is not available"); +#else + w->assignThreadingImpl(functions_info, threading_impl); +#endif +} + + +int dWorldStep (dWorldID w, dReal stepsize) +{ + dUASSERT (w,"bad world argument"); + dUASSERT (stepsize > 0,"stepsize must be > 0"); + + bool result = false; + + dxWorldProcessIslandsInfo islandsinfo; + if (dxReallocateWorldProcessContext (w, islandsinfo, stepsize, &dxEstimateStepMemoryRequirements)) + { + if (dxProcessIslands (w, islandsinfo, stepsize, &dxStepIsland, &dxEstimateStepMaxCallCount)) + { + result = true; + } + } + + return result; +} + +int dWorldQuickStep (dWorldID w, dReal stepsize) +{ + dUASSERT (w,"bad world argument"); + dUASSERT (stepsize > 0,"stepsize must be > 0"); + + bool result = false; + + dxWorldProcessIslandsInfo islandsinfo; + if (dxReallocateWorldProcessContext (w, islandsinfo, stepsize, &dxEstimateQuickStepMemoryRequirements)) + { + if (dxProcessIslands (w, islandsinfo, stepsize, &dxQuickStepIsland, &dxEstimateQuickStepMaxCallCount)) + { + result = true; + } + } + + return result; +} + + +void dWorldImpulseToForce (dWorldID w, dReal stepsize, + dReal ix, dReal iy, dReal iz, + dVector3 force) +{ + dAASSERT (w); + stepsize = dRecip(stepsize); + force[0] = stepsize * ix; + force[1] = stepsize * iy; + force[2] = stepsize * iz; + // @@@ force[3] = 0; +} + + +// world auto-disable functions + +dReal dWorldGetAutoDisableLinearThreshold (dWorldID w) +{ + dAASSERT(w); + return dSqrt (w->adis.linear_average_threshold); +} + + +void dWorldSetAutoDisableLinearThreshold (dWorldID w, dReal linear_average_threshold) +{ + dAASSERT(w); + w->adis.linear_average_threshold = linear_average_threshold * linear_average_threshold; +} + + +dReal dWorldGetAutoDisableAngularThreshold (dWorldID w) +{ + dAASSERT(w); + return dSqrt (w->adis.angular_average_threshold); +} + + +void dWorldSetAutoDisableAngularThreshold (dWorldID w, dReal angular_average_threshold) +{ + dAASSERT(w); + w->adis.angular_average_threshold = angular_average_threshold * angular_average_threshold; +} + + +int dWorldGetAutoDisableAverageSamplesCount (dWorldID w) +{ + dAASSERT(w); + return w->adis.average_samples; +} + + +void dWorldSetAutoDisableAverageSamplesCount (dWorldID w, unsigned int average_samples_count) +{ + dAASSERT(w); + w->adis.average_samples = average_samples_count; +} + + +int dWorldGetAutoDisableSteps (dWorldID w) +{ + dAASSERT(w); + return w->adis.idle_steps; +} + + +void dWorldSetAutoDisableSteps (dWorldID w, int steps) +{ + dAASSERT(w); + w->adis.idle_steps = steps; +} + + +dReal dWorldGetAutoDisableTime (dWorldID w) +{ + dAASSERT(w); + return w->adis.idle_time; +} + + +void dWorldSetAutoDisableTime (dWorldID w, dReal time) +{ + dAASSERT(w); + w->adis.idle_time = time; +} + + +int dWorldGetAutoDisableFlag (dWorldID w) +{ + dAASSERT(w); + return w->body_flags & dxBodyAutoDisable; +} + + +void dWorldSetAutoDisableFlag (dWorldID w, int do_auto_disable) +{ + dAASSERT(w); + if (do_auto_disable) + w->body_flags |= dxBodyAutoDisable; + else + w->body_flags &= ~dxBodyAutoDisable; +} + + +// world damping functions + +dReal dWorldGetLinearDampingThreshold(dWorldID w) +{ + dAASSERT(w); + return dSqrt(w->dampingp.linear_threshold); +} + +void dWorldSetLinearDampingThreshold(dWorldID w, dReal threshold) +{ + dAASSERT(w); + w->dampingp.linear_threshold = threshold*threshold; +} + +dReal dWorldGetAngularDampingThreshold(dWorldID w) +{ + dAASSERT(w); + return dSqrt(w->dampingp.angular_threshold); +} + +void dWorldSetAngularDampingThreshold(dWorldID w, dReal threshold) +{ + dAASSERT(w); + w->dampingp.angular_threshold = threshold*threshold; +} + +dReal dWorldGetLinearDamping(dWorldID w) +{ + dAASSERT(w); + return w->dampingp.linear_scale; +} + +void dWorldSetLinearDamping(dWorldID w, dReal scale) +{ + dAASSERT(w); + if (scale) + w->body_flags |= dxBodyLinearDamping; + else + w->body_flags &= ~dxBodyLinearDamping; + w->dampingp.linear_scale = scale; +} + +dReal dWorldGetAngularDamping(dWorldID w) +{ + dAASSERT(w); + return w->dampingp.angular_scale; +} + +void dWorldSetAngularDamping(dWorldID w, dReal scale) +{ + dAASSERT(w); + if (scale) + w->body_flags |= dxBodyAngularDamping; + else + w->body_flags &= ~dxBodyAngularDamping; + w->dampingp.angular_scale = scale; +} + +void dWorldSetDamping(dWorldID w, dReal linear_scale, dReal angular_scale) +{ + dAASSERT(w); + dWorldSetLinearDamping(w, linear_scale); + dWorldSetAngularDamping(w, angular_scale); +} + +dReal dWorldGetMaxAngularSpeed(dWorldID w) +{ + dAASSERT(w); + return w->max_angular_speed; +} + +void dWorldSetMaxAngularSpeed(dWorldID w, dReal max_speed) +{ + dAASSERT(w); + if (max_speed < dInfinity) + w->body_flags |= dxBodyMaxAngularSpeed; + else + w->body_flags &= ~dxBodyMaxAngularSpeed; + w->max_angular_speed = max_speed; +} + + +void dWorldSetQuickStepNumIterations (dWorldID w, int num) +{ + dAASSERT(w); + w->qs.num_iterations = num; +} + + +int dWorldGetQuickStepNumIterations (dWorldID w) +{ + dAASSERT(w); + return w->qs.num_iterations; +} + + +void dWorldSetQuickStepW (dWorldID w, dReal param) +{ + dAASSERT(w); + w->qs.w = param; +} + + +dReal dWorldGetQuickStepW (dWorldID w) +{ + dAASSERT(w); + return w->qs.w; +} + + +void dWorldSetContactMaxCorrectingVel (dWorldID w, dReal vel) +{ + dAASSERT(w); + w->contactp.max_vel = vel; +} + + +dReal dWorldGetContactMaxCorrectingVel (dWorldID w) +{ + dAASSERT(w); + return w->contactp.max_vel; +} + + +void dWorldSetContactSurfaceLayer (dWorldID w, dReal depth) +{ + dAASSERT(w); + w->contactp.min_depth = depth; +} + + +dReal dWorldGetContactSurfaceLayer (dWorldID w) +{ + dAASSERT(w); + return w->contactp.min_depth; +} + +//**************************************************************************** +// testing + +#define NUM 100 + +#define DO(x) + + +extern "C" void dTestDataStructures() +{ + int i; + DO(printf ("testDynamicsStuff()\n")); + + dBodyID body [NUM]; + int nb = 0; + dJointID joint [NUM]; + int nj = 0; + + for (i=0; i<NUM; i++) body[i] = NULL; + for (i=0; i<NUM; i++) joint[i] = NULL; + + DO(printf ("creating world\n")); + dWorldID w = dWorldCreate(); + checkWorld (w); + + for (;;) { + if (nb < NUM && dRandReal() > 0.5) { + DO(printf ("creating body\n")); + body[nb] = dBodyCreate (w); + DO(printf ("\t--> %p\n",body[nb])); + nb++; + checkWorld (w); + DO(printf ("%d BODIES, %d JOINTS\n",nb,nj)); + } + if (nj < NUM && nb > 2 && dRandReal() > 0.5) { + dBodyID b1 = body [dRand() % nb]; + dBodyID b2 = body [dRand() % nb]; + if (b1 != b2) { + DO(printf ("creating joint, attaching to %p,%p\n",b1,b2)); + joint[nj] = dJointCreateBall (w,0); + DO(printf ("\t-->%p\n",joint[nj])); + checkWorld (w); + dJointAttach (joint[nj],b1,b2); + nj++; + checkWorld (w); + DO(printf ("%d BODIES, %d JOINTS\n",nb,nj)); + } + } + if (nj > 0 && nb > 2 && dRandReal() > 0.5) { + dBodyID b1 = body [dRand() % nb]; + dBodyID b2 = body [dRand() % nb]; + if (b1 != b2) { + int k = dRand() % nj; + DO(printf ("reattaching joint %p\n",joint[k])); + dJointAttach (joint[k],b1,b2); + checkWorld (w); + DO(printf ("%d BODIES, %d JOINTS\n",nb,nj)); + } + } + if (nb > 0 && dRandReal() > 0.5) { + int k = dRand() % nb; + DO(printf ("destroying body %p\n",body[k])); + dBodyDestroy (body[k]); + checkWorld (w); + for (; k < (NUM-1); k++) body[k] = body[k+1]; + nb--; + DO(printf ("%d BODIES, %d JOINTS\n",nb,nj)); + } + if (nj > 0 && dRandReal() > 0.5) { + int k = dRand() % nj; + DO(printf ("destroying joint %p\n",joint[k])); + dJointDestroy (joint[k]); + checkWorld (w); + for (; k < (NUM-1); k++) joint[k] = joint[k+1]; + nj--; + DO(printf ("%d BODIES, %d JOINTS\n",nb,nj)); + } + } + + /* + printf ("creating world\n"); + dWorldID w = dWorldCreate(); + checkWorld (w); + printf ("creating body\n"); + dBodyID b1 = dBodyCreate (w); + checkWorld (w); + printf ("creating body\n"); + dBodyID b2 = dBodyCreate (w); + checkWorld (w); + printf ("creating joint\n"); + dJointID j = dJointCreateBall (w); + checkWorld (w); + printf ("attaching joint\n"); + dJointAttach (j,b1,b2); + checkWorld (w); + printf ("destroying joint\n"); + dJointDestroy (j); + checkWorld (w); + printf ("destroying body\n"); + dBodyDestroy (b1); + checkWorld (w); + printf ("destroying body\n"); + dBodyDestroy (b2); + checkWorld (w); + printf ("destroying world\n"); + dWorldDestroy (w); + */ +} + +//**************************************************************************** +// configuration +#if 1 +#define REGISTER_EXTENSION( __a ) #__a " " +#else +#define REGISTER_EXTENSION( __a ) "__a " +#endif +static const char ode_configuration[] = "ODE " + +// EXTENSION LIST BEGIN +//********************************** + +#ifdef dNODEBUG +REGISTER_EXTENSION( ODE_EXT_no_debug ) +#endif // dNODEBUG + +#if dTRIMESH_ENABLED +REGISTER_EXTENSION( ODE_EXT_trimesh ) + +// tri-mesh extensions +#if dTRIMESH_OPCODE +REGISTER_EXTENSION( ODE_EXT_opcode ) + +// opcode extensions +#if dTRIMESH_16BIT_INDICES +REGISTER_EXTENSION( ODE_OPC_16bit_indices ) +#endif + +#if !dTRIMESH_OPCODE_USE_OLD_TRIMESH_TRIMESH_COLLIDER +REGISTER_EXTENSION( ODE_OPC_new_collider ) +#endif + +#endif // dTRIMESH_OPCODE + +#if dTRIMESH_GIMPACT +REGISTER_EXTENSION( ODE_EXT_gimpact ) + +// gimpact extensions +#endif + +#endif // dTRIMESH_ENABLED + +#if dTLS_ENABLED +REGISTER_EXTENSION( ODE_EXT_mt_collisions ) +#endif // dTLS_ENABLED + +#if !dTHREADING_INTF_DISABLED +REGISTER_EXTENSION( ODE_EXT_threading ) + +#if dBUILTIN_THREADING_IMPL_ENABLED +REGISTER_EXTENSION( ODE_THR_builtin_impl ) +#endif // #if dBUILTIN_THREADING_IMPL_ENABLED +#endif // #if !dTHREADING_INTF_DISABLED + +//********************************** +// EXTENSION LIST END + +// These tokens are mutually exclusive, and always present +#ifdef dSINGLE +"ODE_single_precision" +#else +"ODE_double_precision" +#endif // dDOUBLE + +; // END + +const char* dGetConfiguration (void) +{ + return ode_configuration; +} + + +// Helper to check for a feature of ODE +int dCheckConfiguration( const char* extension ) +{ + const char *start; + char *where, *terminator; + + /* Feature names should not have spaces. */ + where = (char*)strchr(extension, ' '); + if ( where || *extension == '\0') + return 1; + + const char* config = dGetConfiguration(); + + const sizeint ext_length = strlen(extension); + + /* It takes a bit of care to be fool-proof. Don't be fooled by sub-strings, etc. */ + start = config; + for ( ; ; ) + { + where = (char*)strstr((const char *) start, extension); + if (!where) + break; + + terminator = where + ext_length; + + if ( (where == start || *(where - 1) == ' ') && + (*terminator == ' ' || *terminator == '\0') ) + { + return 1; + } + + start = terminator; + } + + return 0; +} + + +// Local Variables: +// c-basic-offset:4 +// End: diff --git a/libs/ode-0.16.1/ode/src/odeinit.cpp b/libs/ode-0.16.1/ode/src/odeinit.cpp new file mode 100644 index 0000000..25cc302 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/odeinit.cpp @@ -0,0 +1,575 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +ODE initialization/finalization code + +*/ + +#include <ode/common.h> +#include <ode/odeinit.h> +// <ode/objects.h> included for dWorldQuickStepCleanup() +#include <ode/objects.h> +#include "config.h" +#include "odemath.h" +#include "collision_kernel.h" +#include "collision_trimesh_internal.h" +#include "odetls.h" +#include "odeou.h" +#include "default_threading.h" + + +//**************************************************************************** +// Initialization tracking variables + +static unsigned int g_uiODEInitCounter = 0; +static unsigned int g_uiODEInitModes = 0; + + +#if dTRIMESH_ENABLED && dTRIMESH_OPCODE + +static +void OPCODEAbort() +{ + dICHECK(!"OPCODE Library Abort"); +} + + +#endif // #if dTRIMESH_ENABLED && dTRIMESH_OPCODE + + +enum EODEINITMODE +{ + OIM__MIN, + + OIM_AUTOTLSCLEANUP = OIM__MIN, + OIM_MANUALTLSCLEANUP, + + OIM__MAX +}; + +#if dTLS_ENABLED +static const EODETLSKIND g_atkTLSKindsByInitMode[OIM__MAX] = +{ + OTK_AUTOCLEANUP, // OIM_AUTOTLSCLEANUP, + OTK_MANUALCLEANUP, // OIM_MANUALTLSCLEANUP, +}; +#endif // #if dTLS_ENABLED + +static inline bool IsODEModeInitialized(EODEINITMODE imInitMode) +{ + return (g_uiODEInitModes & (1U << imInitMode)) != 0; +} + +static inline void SetODEModeInitialized(EODEINITMODE imInitMode) +{ + g_uiODEInitModes |= (1U << imInitMode); +} + +static inline void ResetODEModeInitialized(EODEINITMODE imInitMode) +{ + g_uiODEInitModes &= ~(1U << imInitMode); +} + +static inline bool IsODEAnyModeInitialized() +{ + return g_uiODEInitModes != 0; +} + + +enum +{ + TLD_INTERNAL_COLLISIONDATA_ALLOCATED = 0x00000001 +}; + +static bool AllocateThreadBasicDataIfNecessary(EODEINITMODE imInitMode) +{ + bool bResult = false; + + do + { +#if dTLS_ENABLED + EODETLSKIND tkTlsKind = g_atkTLSKindsByInitMode[imInitMode]; + + const unsigned uDataAllocationFlags = COdeTls::GetDataAllocationFlags(tkTlsKind); + + // If no flags are set it may mean that TLS slot is not allocated yet + if (uDataAllocationFlags == 0) + { + // Assign zero flags to make sure that TLS slot has been allocated + if (!COdeTls::AssignDataAllocationFlags(tkTlsKind, 0)) + { + break; + } + } +#else + (void)imInitMode; // unused +#endif // #if dTLS_ENABLED + + bResult = true; + } + while (false); + + return bResult; +} + +static void FreeThreadBasicDataOnFailureIfNecessary(EODEINITMODE imInitMode) +{ +#if dTLS_ENABLED + + if (imInitMode == OIM_MANUALTLSCLEANUP) + { + EODETLSKIND tkTlsKind = g_atkTLSKindsByInitMode[imInitMode]; + + const unsigned uDataAllocationFlags = COdeTls::GetDataAllocationFlags(tkTlsKind); + + if (uDataAllocationFlags == 0) + { + // So far, only free TLS slot, if no subsystems have data allocated + COdeTls::CleanupForThread(); + } + } +#else + (void)imInitMode; // unused +#endif // #if dTLS_ENABLED +} + +#if dTLS_ENABLED +static bool AllocateThreadCollisionData(EODETLSKIND tkTlsKind) +{ + bool bResult = false; + + do + { + dIASSERT(!(COdeTls::GetDataAllocationFlags(tkTlsKind) & TLD_INTERNAL_COLLISIONDATA_ALLOCATED)); + +#if dTRIMESH_ENABLED + + TrimeshCollidersCache *pccColliderCache = new TrimeshCollidersCache(); + if (!COdeTls::AssignTrimeshCollidersCache(tkTlsKind, pccColliderCache)) + { + delete pccColliderCache; + break; + } + +#endif // dTRIMESH_ENABLED + + COdeTls::SignalDataAllocationFlags(tkTlsKind, TLD_INTERNAL_COLLISIONDATA_ALLOCATED); + + bResult = true; + } + while (false); + + return bResult; +} +#endif // dTLS_ENABLED + +static bool AllocateThreadCollisionDataIfNecessary(EODEINITMODE imInitMode, bool &bOutDataAllocated) +{ + bool bResult = false; + bOutDataAllocated = false; + + do + { +#if dTLS_ENABLED + EODETLSKIND tkTlsKind = g_atkTLSKindsByInitMode[imInitMode]; + + const unsigned uDataAllocationFlags = COdeTls::GetDataAllocationFlags(tkTlsKind); + + if ((uDataAllocationFlags & TLD_INTERNAL_COLLISIONDATA_ALLOCATED) == 0) + { + if (!AllocateThreadCollisionData(tkTlsKind)) + { + break; + } + + bOutDataAllocated = true; + } +#else + (void)imInitMode; // unused +#endif // #if dTLS_ENABLED + + bResult = true; + } + while (false); + + return bResult; +} + +static void FreeThreadCollisionData(EODEINITMODE imInitMode) +{ +#if dTLS_ENABLED + + EODETLSKIND tkTlsKind = g_atkTLSKindsByInitMode[imInitMode]; + + COdeTls::DestroyTrimeshCollidersCache(tkTlsKind); + + COdeTls::DropDataAllocationFlags(tkTlsKind, TLD_INTERNAL_COLLISIONDATA_ALLOCATED); +#else + (void)imInitMode; // unused +#endif // dTLS_ENABLED +} + + +static bool InitODEForMode(EODEINITMODE imInitMode) +{ + bool bResult = false; + +#if dOU_ENABLED + bool bOUCustomizationsDone = false; +#endif +#if dATOMICS_ENABLED + bool bAtomicsInitialized = false; +#endif +#if dTLS_ENABLED + EODETLSKIND tkTLSKindToInit = g_atkTLSKindsByInitMode[imInitMode]; + bool bTlsInitialized = false; +#else + (void)imInitMode; // unused +#endif + + bool bWorldThreadingInitialized = false; + + do + { + bool bAnyModeAlreadyInitialized = IsODEAnyModeInitialized(); + + if (!bAnyModeAlreadyInitialized) + { +#if dOU_ENABLED + if (!COdeOu::DoOUCustomizations()) + { + break; + } + + bOUCustomizationsDone = true; +#endif + +#if dATOMICS_ENABLED + if (!COdeOu::InitializeAtomics()) + { + break; + } + + bAtomicsInitialized = true; +#endif + } + +#if dTLS_ENABLED + if (!COdeTls::Initialize(tkTLSKindToInit)) + { + break; + } + + bTlsInitialized = true; +#endif + + if (!bAnyModeAlreadyInitialized) + { + if (!DefaultThreadingHolder::initializeDefaultThreading()) + { + break; + } + + bWorldThreadingInitialized = true; + +#if dTRIMESH_ENABLED && dTRIMESH_OPCODE + if (!Opcode::InitOpcode(&OPCODEAbort)) + { + break; + } +#endif + +#if dTRIMESH_ENABLED && dTRIMESH_GIMPACT + gimpact_init(); +#endif + + dInitColliders(); + } + + bResult = true; + } + while (false); + + if (!bResult) + { + if (bWorldThreadingInitialized) + { + DefaultThreadingHolder::finalizeDefaultThreading(); + } + +#if dTLS_ENABLED + if (bTlsInitialized) + { + COdeTls::Finalize(tkTLSKindToInit); + } +#endif + +#if dATOMICS_ENABLED + if (bAtomicsInitialized) + { + COdeOu::FinalizeAtomics(); + } +#endif + +#if dOU_ENABLED + if (bOUCustomizationsDone) + { + COdeOu::UndoOUCustomizations(); + } +#endif + } + + return bResult; +} + + +static bool AllocateODEDataForThreadForMode(EODEINITMODE imInitMode, unsigned int uiAllocateFlags) +{ + bool bResult = false; + + bool bCollisionDataAllocated = false; + + do + { + if (!AllocateThreadBasicDataIfNecessary(imInitMode)) + { + break; + } + + if (uiAllocateFlags & dAllocateFlagCollisionData) + { + if (!AllocateThreadCollisionDataIfNecessary(imInitMode, bCollisionDataAllocated)) + { + break; + } + } + + bResult = true; + } + while (false); + + if (!bResult) + { + if (bCollisionDataAllocated) + { + FreeThreadCollisionData(imInitMode); + } + + FreeThreadBasicDataOnFailureIfNecessary(imInitMode); + } + + return bResult; +} + + +static void CloseODEForMode(EODEINITMODE imInitMode) +{ + bool bAnyModeStillInitialized = IsODEAnyModeInitialized(); + + if (!bAnyModeStillInitialized) + { + dClearPosrCache(); + dFinitUserClasses(); + dFinitColliders(); + +#if dTRIMESH_ENABLED && dTRIMESH_GIMPACT + gimpact_terminate(); +#endif + +#if dTRIMESH_ENABLED && dTRIMESH_OPCODE + extern void opcode_collider_cleanup(); + // Free up static allocations in opcode + opcode_collider_cleanup(); + + Opcode::CloseOpcode(); +#endif + + DefaultThreadingHolder::finalizeDefaultThreading(); + } + +#if dTLS_ENABLED + EODETLSKIND tkTLSKindToFinalize = g_atkTLSKindsByInitMode[imInitMode]; + COdeTls::Finalize(tkTLSKindToFinalize); +#else + (void)imInitMode; // unused +#endif + + if (!bAnyModeStillInitialized) + { +#if dATOMICS_ENABLED + COdeOu::FinalizeAtomics(); +#endif + +#if dOU_ENABLED + COdeOu::UndoOUCustomizations(); +#endif + } +} + + +//**************************************************************************** +// internal initialization and close routine implementations + +static bool InternalInitODE(unsigned int uiInitFlags) +{ + bool bResult = false; + + do + { + EODEINITMODE imInitMode = (uiInitFlags & dInitFlagManualThreadCleanup) ? OIM_MANUALTLSCLEANUP : OIM_AUTOTLSCLEANUP; + + if (!IsODEModeInitialized(imInitMode)) + { + if (!InitODEForMode(imInitMode)) + { + break; + } + + SetODEModeInitialized(imInitMode); + } + + ++g_uiODEInitCounter; + bResult = true; + } + while (false); + + return bResult; +} + +static void InternalCloseODE() +{ + unsigned int uiCurrentMode = (--g_uiODEInitCounter == 0) ? OIM__MIN : OIM__MAX; + for (; uiCurrentMode != OIM__MAX; ++uiCurrentMode) + { + if (IsODEModeInitialized((EODEINITMODE)uiCurrentMode)) + { + // Must be called before CloseODEForMode() + ResetODEModeInitialized((EODEINITMODE)uiCurrentMode); + + // Must be called after ResetODEModeInitialized() + CloseODEForMode((EODEINITMODE)uiCurrentMode); + } + } +} + +static bool InternalAllocateODEDataForThread(unsigned int uiAllocateFlags) +{ + bool bAnyFailure = false; + + for (unsigned uiCurrentMode = OIM__MIN; uiCurrentMode != OIM__MAX; ++uiCurrentMode) + { + if (IsODEModeInitialized((EODEINITMODE)uiCurrentMode)) + { + if (!AllocateODEDataForThreadForMode((EODEINITMODE)uiCurrentMode, uiAllocateFlags)) + { + bAnyFailure = true; + break; + } + } + } + + bool bResult = !bAnyFailure; + return bResult; +} + +static void InternalCleanupODEAllDataForThread() +{ +#if dTLS_ENABLED + COdeTls::CleanupForThread(); +#endif +} + +//**************************************************************************** +// initialization and shutdown routines - allocate and initialize data, +// cleanup before exiting + +void dInitODE() +{ + int bInitResult = InternalInitODE(0); + dIVERIFY(bInitResult); + + int ibAllocResult = InternalAllocateODEDataForThread(dAllocateMaskAll); + dIVERIFY(ibAllocResult); +} + +int dInitODE2(unsigned int uiInitFlags/*=0*/) +{ + bool bResult = false; + + bool bODEInitialized = false; + + do + { + if (!InternalInitODE(uiInitFlags)) + { + break; + } + + bODEInitialized = true; + + if (!InternalAllocateODEDataForThread(dAllocateFlagBasicData)) + { + break; + } + + bResult = true; + } + while (false); + + if (!bResult) + { + if (bODEInitialized) + { + InternalCloseODE(); + } + } + + return bResult; +} + + +int dAllocateODEDataForThread(unsigned int uiAllocateFlags) +{ + dUASSERT(g_uiODEInitCounter != 0, "Call dInitODE2 first"); + + bool bResult = InternalAllocateODEDataForThread(uiAllocateFlags); + return bResult; +} + + +void dCleanupODEAllDataForThread() +{ + dUASSERT(g_uiODEInitCounter != 0, "Call dInitODE2 first or delay dCloseODE until all threads exit"); + + InternalCleanupODEAllDataForThread(); +} + + +void dCloseODE() +{ + dUASSERT(g_uiODEInitCounter != 0, "dCloseODE must not be called without dInitODE2 or if dInitODE2 fails"); // dCloseODE must not be called without dInitODE2 or if dInitODE2 fails + + InternalCloseODE(); +} + diff --git a/libs/ode-0.16.1/ode/src/odemath.cpp b/libs/ode-0.16.1/ode/src/odemath.cpp new file mode 100644 index 0000000..5e69b9b --- /dev/null +++ b/libs/ode-0.16.1/ode/src/odemath.cpp @@ -0,0 +1,312 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <ode/common.h> +#include "config.h" +#include "odemath.h" + + +#undef dSafeNormalize3 +#undef dSafeNormalize4 +#undef dNormalize3 +#undef dNormalize4 + +#undef dPlaneSpace +#undef dOrthogonalizeR + + +int dSafeNormalize3 (dVector3 a) +{ + return dxSafeNormalize3(a); +} + +int dSafeNormalize4 (dVector4 a) +{ + return dxSafeNormalize4(a); +} + +void dNormalize3(dVector3 a) +{ + dxNormalize3(a); +} + +void dNormalize4(dVector4 a) +{ + dxNormalize4(a); +} + + +void dPlaneSpace(const dVector3 n, dVector3 p, dVector3 q) +{ + return dxPlaneSpace(n, p, q); +} + +int dOrthogonalizeR(dMatrix3 m) +{ + return dxOrthogonalizeR(m); +} + + +/*extern */ +bool dxCouldBeNormalized3(const dVector3 a) +{ + dAASSERT (a); + + bool ret = false; + + for (unsigned axis = dV3E__AXES_MIN; axis != dV3E__AXES_MAX; ++axis) { + if (a[axis] != REAL(0.0)) { + ret = true; + break; + } + } + + return ret; +} + +// this may be called for vectors `a' with extremely small magnitude, for +// example the result of a cross product on two nearly perpendicular vectors. +// we must be robust to these small vectors. to prevent numerical error, +// first find the component a[i] with the largest magnitude and then scale +// all the components by 1/a[i]. then we can compute the length of `a' and +// scale the components by 1/l. this has been verified to work with vectors +// containing the smallest representable numbers. + +/*extern */ +bool dxSafeNormalize3 (dVector3 a) +{ + dAASSERT (a); + + bool ret = false; + + do { + dReal abs_a0 = dFabs(a[dV3E_X]); + dReal abs_a1 = dFabs(a[dV3E_Y]); + dReal abs_a2 = dFabs(a[dV3E_Z]); + + dVec3Element idx; + + if (abs_a1 > abs_a0) { + if (abs_a2 > abs_a1) { // abs_a2 is the largest + idx = dV3E_Z; + } + else { // abs_a1 is the largest + idx = dV3E_Y; + } + } + else if (abs_a2 > abs_a0) {// abs_a2 is the largest + idx = dV3E_Z; + } + else { // aa[0] might be the largest + if (!(abs_a0 > REAL(0.0))) { + // if all a's are zero, this is where we'll end up. + // return the vector unchanged. + break; + } + + // abs_a0 is the largest + idx = dV3E_X; + } + + if (idx == dV3E_X) { + dReal aa0_recip = dRecip(abs_a0); + dReal a1 = a[dV3E_Y] * aa0_recip; + dReal a2 = a[dV3E_Z] * aa0_recip; + dReal l = dRecipSqrt(REAL(1.0) + a1 * a1 + a2 * a2); + a[dV3E_Y] = a1 * l; + a[dV3E_Z] = a2 * l; + a[dV3E_X] = dCopySign(l, a[dV3E_X]); + } + else if (idx == dV3E_Y) { + dReal aa1_recip = dRecip(abs_a1); + dReal a0 = a[dV3E_X] * aa1_recip; + dReal a2 = a[dV3E_Z] * aa1_recip; + dReal l = dRecipSqrt(REAL(1.0) + a0 * a0 + a2 * a2); + a[dV3E_X] = a0 * l; + a[dV3E_Z] = a2 * l; + a[dV3E_Y] = dCopySign(l, a[dV3E_Y]); + } + else { + dReal aa2_recip = dRecip(abs_a2); + dReal a0 = a[dV3E_X] * aa2_recip; + dReal a1 = a[dV3E_Y] * aa2_recip; + dReal l = dRecipSqrt(REAL(1.0) + a0 * a0 + a1 * a1); + a[dV3E_X] = a0 * l; + a[dV3E_Y] = a1 * l; + a[dV3E_Z] = dCopySign(l, a[dV3E_Z]); + } + + ret = true; + } + while (false); + + return ret; +} + +/* OLD VERSION */ +/* +void dNormalize3 (dVector3 a) +{ + dIASSERT (a); + dReal l = dCalcVectorDot3(a,a); + if (l > 0) { + l = dRecipSqrt(l); + a[0] *= l; + a[1] *= l; + a[2] *= l; + } + else { + a[0] = 1; + a[1] = 0; + a[2] = 0; + } +} +*/ + +/*extern */ +bool dxCouldBeNormalized4(const dVector4 a) +{ + dAASSERT (a); + + bool ret = false; + + for (unsigned axis = dV4E__MIN; axis != dV4E__MAX; ++axis) { + if (a[axis] != REAL(0.0)) { + ret = true; + break; + } + } + + return ret; +} + +/*extern */ +bool dxSafeNormalize4 (dVector4 a) +{ + dAASSERT (a); + + bool ret = false; + + dReal l = a[dV4E_X] * a[dV4E_X] + a[dV4E_Y] * a[dV4E_Y] + a[dV4E_Z] * a[dV4E_Z] + a[dV4E_O] * a[dV4E_O]; + if (l > 0) { + l = dRecipSqrt(l); + a[dV4E_X] *= l; + a[dV4E_Y] *= l; + a[dV4E_Z] *= l; + a[dV4E_O] *= l; + + ret = true; + } + + return ret; +} + + +void dxPlaneSpace (const dVector3 n, dVector3 p, dVector3 q) +{ + dAASSERT (n && p && q); + if (dFabs(n[2]) > M_SQRT1_2) { + // choose p in y-z plane + dReal a = n[1]*n[1] + n[2]*n[2]; + dReal k = dRecipSqrt (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 + dReal a = n[0]*n[0] + n[1]*n[1]; + dReal k = dRecipSqrt (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; + } +} + + +/* +* This takes what is supposed to be a rotation matrix, +* and make sure it is correct. +* Note: this operates on rows, not columns, because for rotations +* both ways give equivalent results. +*/ +bool dxOrthogonalizeR(dMatrix3 m) +{ + bool ret = false; + + do { + if (!dxCouldBeNormalized3(m + dM3E__X_MIN)) { + break; + } + + dReal n0 = dCalcVectorLengthSquare3(m + dM3E__X_MIN); + + dVector3 row2_store; + dReal *row2 = m + dM3E__Y_MIN; + // project row[0] on row[1], should be zero + dReal proj = dCalcVectorDot3(m + dM3E__X_MIN, m + dM3E__Y_MIN); + if (proj != 0) { + // Gram-Schmidt step on row[1] + dReal proj_div_n0 = proj / n0; + row2_store[dV3E_X] = m[dM3E__Y_MIN + dV3E_X] - proj_div_n0 * m[dM3E__X_MIN + dV3E_X] ; + row2_store[dV3E_Y] = m[dM3E__Y_MIN + dV3E_Y] - proj_div_n0 * m[dM3E__X_MIN + dV3E_Y]; + row2_store[dV3E_Z] = m[dM3E__Y_MIN + dV3E_Z] - proj_div_n0 * m[dM3E__X_MIN + dV3E_Z]; + row2 = row2_store; + } + + if (!dxCouldBeNormalized3(row2)) { + break; + } + + if (n0 != REAL(1.0)) { + bool row0_norm_fault = !dxSafeNormalize3(m + dM3E__X_MIN); + dIVERIFY(!row0_norm_fault); + } + + dReal n1 = dCalcVectorLengthSquare3(row2); + if (n1 != REAL(1.0)) { + bool row1_norm_fault = !dxSafeNormalize3(row2); + dICHECK(!row1_norm_fault); + } + + dIASSERT(dFabs(dCalcVectorDot3(m + dM3E__X_MIN, row2)) < 1e-6); + + /* just overwrite row[2], this makes sure the matrix is not + a reflection */ + dCalcVectorCross3(m + dM3E__Z_MIN, m + dM3E__X_MIN, row2); + + m[dM3E_XPAD] = m[dM3E_YPAD] = m[dM3E_ZPAD] = 0; + + ret = true; + } + while (false); + + return ret; +} diff --git a/libs/ode-0.16.1/ode/src/odemath.h b/libs/ode-0.16.1/ode/src/odemath.h new file mode 100644 index 0000000..becf284 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/odemath.h @@ -0,0 +1,72 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE__PRIVATE_ODEMATH_H_ +#define _ODE__PRIVATE_ODEMATH_H_ + +#include <ode/odemath.h> +#include "error.h" + + +bool dxCouldBeNormalized3(const dVector3 a); +bool dxSafeNormalize3 (dVector3 a); +bool dxCouldBeNormalized4(const dVector4 a); +bool dxSafeNormalize4 (dVector4 a); + +ODE_PURE_INLINE +void dxNormalize3(dVector3 a) +{ + bool bSafeNormalize3Fault; + if ((bSafeNormalize3Fault = !dxSafeNormalize3(a))) + { + dIVERIFY(!bSafeNormalize3Fault); + + a[0] = REAL(1.0); a[2] = a[1] = REAL(0.0); + } +} + +ODE_PURE_INLINE +void dxNormalize4(dVector4 a) +{ + bool bSafeNormalize4Fault; + if ((bSafeNormalize4Fault = !dxSafeNormalize4(a))) + { + dIVERIFY(!bSafeNormalize4Fault); + + a[0] = REAL(1.0); a[3] = a[2] = a[1] = REAL(0.0); + } +} + +void dxPlaneSpace (const dVector3 n, dVector3 p, dVector3 q); +bool dxOrthogonalizeR(dMatrix3 m); + +// For internal use +#define dSafeNormalize3(a) dxSafeNormalize3(a) +#define dSafeNormalize4(a) dxSafeNormalize4(a) +#define dNormalize3(a) dxNormalize3(a) +#define dNormalize4(a) dxNormalize4(a) + +#define dPlaneSpace(n, p, q) dxPlaneSpace(n, p, q) +#define dOrthogonalizeR(m) dxOrthogonalizeR(m) + + +#endif diff --git a/libs/ode-0.16.1/ode/src/odeou.cpp b/libs/ode-0.16.1/ode/src/odeou.cpp new file mode 100644 index 0000000..e784c41 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/odeou.cpp @@ -0,0 +1,107 @@ +/************************************************************************* + * * + * OU library interface file for Open Dynamics Engine, * + * Copyright (C) 2008-2019 Oleh Derevenko. All rights reserved. * + * Email: odar@eleks.com (change all "a" to "e") * + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +ODE interface to OU library implementation. + +*/ + + +#include <ode/common.h> +#include <ode/memory.h> +#include "config.h" +#include "odeou.h" + + + +#if dOU_ENABLED + + +using _OU_NAMESPACE::EASSERTIONFAILURESEVERITY; +using _OU_NAMESPACE::AFS__MAX; +using _OU_NAMESPACE::CMemoryManagerCustomization; +using _OU_NAMESPACE::CAssertionCheckCustomization; + + +BEGIN_NAMESPACE_OU(); +template<> +const char *const CEnumUnsortedElementArray<EASSERTIONFAILURESEVERITY, AFS__MAX, const char *>::m_aetElementArray[] = +{ + "assert", // AFS_ASSERT, + "check", // AFS_CHECK, +}; +END_NAMESPACE_OU(); + +static const CEnumUnsortedElementArray<EASSERTIONFAILURESEVERITY, AFS__MAX, const char *> g_aszAssertionFailureSeverityNames; + + +static void _OU_CONVENTION_CALLBACK ForwardOUAssertionFailure(EASSERTIONFAILURESEVERITY fsFailureSeverity, + const char *szAssertionExpression, const char *szAssertionFileName, unsigned int uiAssertionSourceLine) +{ + dDebug(d_ERR_IASSERT, "Assertion failure in OU Library. Kind: %s, expression: \"%s\", file: \"%s\", line: %u", + g_aszAssertionFailureSeverityNames.Encode(fsFailureSeverity), + szAssertionExpression, szAssertionFileName, uiAssertionSourceLine); +} + + +static void *_OU_CONVENTION_CALLBACK ForwardOUMemoryAlloc(size_t nBlockSize) +{ + return dAlloc(nBlockSize); +} + +static void *_OU_CONVENTION_CALLBACK ForwardOUMemoryRealloc(void *pv_ExistingBlock, size_t nBlockNewSize) +{ + return dRealloc(pv_ExistingBlock, 0, nBlockNewSize); +} + +static void _OU_CONVENTION_CALLBACK ForwardOUMemoryFree(void *pv_ExistingBlock) +{ + return dFree(pv_ExistingBlock, 0); +} + + +bool COdeOu::DoOUCustomizations() +{ + CMemoryManagerCustomization::CustomizeMemoryManager(&ForwardOUMemoryAlloc, + &ForwardOUMemoryRealloc, &ForwardOUMemoryFree); + + CAssertionCheckCustomization::CustomizeAssertionChecks(&ForwardOUAssertionFailure); + + return true; +} + +void COdeOu::UndoOUCustomizations() +{ + CAssertionCheckCustomization::CustomizeAssertionChecks(NULL); + + CMemoryManagerCustomization::CustomizeMemoryManager(NULL, NULL, NULL); +} + + +#endif // dOU_ENABLED + diff --git a/libs/ode-0.16.1/ode/src/odeou.h b/libs/ode-0.16.1/ode/src/odeou.h new file mode 100644 index 0000000..a06de8f --- /dev/null +++ b/libs/ode-0.16.1/ode/src/odeou.h @@ -0,0 +1,107 @@ +/************************************************************************* +* * +* OU library interface file for Open Dynamics Engine, * +* Copyright (C) 2008-2019 Oleh Derevenko. All rights reserved. * +* Email: odar@eleks.com (change all "a" to "e") * +* * +* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * +* All rights reserved. Email: russ@q12.org Web: www.q12.org * +* * +* * +* This library is free software; you can redistribute it and/or * +* modify it under the terms of EITHER: * +* (1) The GNU Lesser General Public License as published by the Free * +* Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. The text of the GNU Lesser * +* General Public License is included with this library in the * +* file LICENSE.TXT. * +* (2) The BSD-style license that is included with this library in * +* the file LICENSE-BSD.TXT. * +* * +* This library 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 files * +* LICENSE.TXT and LICENSE-BSD.TXT for more details. * +* * +*************************************************************************/ + +/* + +ODE interface to OU library functions. + +*/ + + +#ifndef _ODE_ODEOU_H_ +#define _ODE_ODEOU_H_ + + +#if dOU_ENABLED + +#include <ou/assert.h> +#include <ou/enumarrays.h> +#include <ou/macros.h> +#include <ou/templates.h> +#include <ou/typewrapper.h> +#include <ou/simpleflags.h> +#include <ou/customization.h> + +#if dATOMICS_ENABLED +#include <ou/atomic.h> +#include <ou/atomicflags.h> +#endif + +#if dTLS_ENABLED +#include <ou/threadlocalstorage.h> +#endif + + +using _OU_NAMESPACE::CEnumUnsortedElementArray; +using _OU_NAMESPACE::CEnumSortedElementArray; + +#if dATOMICS_ENABLED +using _OU_NAMESPACE::atomicord32; +using _OU_NAMESPACE::atomicptr; +using _OU_NAMESPACE::InitializeAtomicAPI; +using _OU_NAMESPACE::FinalizeAtomicAPI; +using _OU_NAMESPACE::AtomicIncrement; +using _OU_NAMESPACE::AtomicDecrement; +using _OU_NAMESPACE::AtomicCompareExchange; +using _OU_NAMESPACE::AtomicExchange; +using _OU_NAMESPACE::AtomicExchangeAddNoResult; +using _OU_NAMESPACE::AtomicExchangeAdd; +using _OU_NAMESPACE::AtomicCompareExchangePointer; +using _OU_NAMESPACE::AtomicExchangePointer; +using _OU_NAMESPACE::AtomicReadReorderBarrier; +using _OU_NAMESPACE::AtomicStore; +using _OU_NAMESPACE::AtomicStorePointer; +#endif + + +class COdeOu +{ +public: + static bool DoOUCustomizations(); + static void UndoOUCustomizations(); + +#if dATOMICS_ENABLED + static bool InitializeAtomics() { return InitializeAtomicAPI(); } + static void FinalizeAtomics() { FinalizeAtomicAPI(); } +#endif +}; + + +#endif + + +#if !dOU_ENABLED || !dATOMICS_ENABLED + +typedef unsigned int atomicord32; +typedef void *atomicptr; + + +#endif // dOU_ENABLED + + + +#endif // _ODE_ODEOU_H_ diff --git a/libs/ode-0.16.1/ode/src/odetls.cpp b/libs/ode-0.16.1/ode/src/odetls.cpp new file mode 100644 index 0000000..5df2845 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/odetls.cpp @@ -0,0 +1,153 @@ +/************************************************************************* + * * + * Thread local storage access stub for Open Dynamics Engine, * + * Copyright (C) 2008-2019 Oleh Derevenko. All rights reserved. * + * Email: odar@eleks.com (change all "a" to "e") * + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +ODE Thread Local Storage access stub implementation. + +*/ + +#include <ode/common.h> +#include "config.h" +#include "odemath.h" +#include "odetls.h" +#include "collision_trimesh_internal.h" + + +#if dTLS_ENABLED + + +using _OU_NAMESPACE::CTLSInitialization; + + +////////////////////////////////////////////////////////////////////////// +// Class static fields + +HTLSKEY COdeTls::m_ahtkStorageKeys[OTK__MAX] = { 0 }; + + +////////////////////////////////////////////////////////////////////////// +// Initialization and finalization + +bool COdeTls::Initialize(EODETLSKIND tkTLSKind) +{ + dIASSERT(!m_ahtkStorageKeys[tkTLSKind]); + + bool bResult = false; + + unsigned uOUFlags = 0; + + if (tkTLSKind == OTK_MANUALCLEANUP) + { + uOUFlags |= CTLSInitialization::SIF_MANUAL_CLEANUP_ON_THREAD_EXIT; + } + + if (CTLSInitialization::InitializeTLSAPI(m_ahtkStorageKeys[tkTLSKind], OTI__MAX, uOUFlags)) + { + bResult = true; + } + + return bResult; +} + +void COdeTls::Finalize(EODETLSKIND tkTLSKind) +{ + CTLSInitialization::FinalizeTLSAPI(); + + m_ahtkStorageKeys[tkTLSKind] = 0; +} + + +void COdeTls::CleanupForThread() +{ + if (m_ahtkStorageKeys[OTK_MANUALCLEANUP]) + { + CTLSInitialization::CleanupOnThreadExit(); + } + else + { + dIASSERT(false); // The class is not intended to be cleaned up manually + } +} + + +////////////////////////////////////////////////////////////////////////// +// Value modifiers + +bool COdeTls::AssignDataAllocationFlags(EODETLSKIND tkTLSKind, unsigned uInitializationFlags) +{ + bool bResult = CThreadLocalStorage::SetStorageValue(m_ahtkStorageKeys[tkTLSKind], OTI_DATA_ALLOCATION_FLAGS, (tlsvaluetype)(sizeint)uInitializationFlags); + return bResult; +} + + +bool COdeTls::AssignTrimeshCollidersCache(EODETLSKIND tkTLSKind, TrimeshCollidersCache *pccInstance) +{ + dIASSERT(!CThreadLocalStorage::GetStorageValue(m_ahtkStorageKeys[tkTLSKind], OTI_TRIMESH_TRIMESH_COLLIDER_CACHE)); + + bool bResult = CThreadLocalStorage::SetStorageValue(m_ahtkStorageKeys[tkTLSKind], OTI_TRIMESH_TRIMESH_COLLIDER_CACHE, (tlsvaluetype)pccInstance, &COdeTls::FreeTrimeshCollidersCache_Callback); + return bResult; +} + +void COdeTls::DestroyTrimeshCollidersCache(EODETLSKIND tkTLSKind) +{ + TrimeshCollidersCache *pccCacheInstance = (TrimeshCollidersCache *)CThreadLocalStorage::GetStorageValue(m_ahtkStorageKeys[tkTLSKind], OTI_TRIMESH_TRIMESH_COLLIDER_CACHE); + + if (pccCacheInstance != NULL) + { + FreeTrimeshCollidersCache(pccCacheInstance); + + CThreadLocalStorage::UnsafeSetStorageValue(m_ahtkStorageKeys[tkTLSKind], OTI_TRIMESH_TRIMESH_COLLIDER_CACHE, (tlsvaluetype)NULL); + } +} + + +////////////////////////////////////////////////////////////////////////// +// Value type destructors + +void COdeTls::FreeTrimeshCollidersCache(TrimeshCollidersCache *pccCacheInstance) +{ +#if dTRIMESH_ENABLED + delete pccCacheInstance; +#else + dIASSERT(pccCacheInstance == NULL); // The cache is not being allocated if the library is configured without trimeshes +#endif +} + + +////////////////////////////////////////////////////////////////////////// +// Value type destructor callbacks + +void COdeTls::FreeTrimeshCollidersCache_Callback(tlsvaluetype vValueData) +{ + TrimeshCollidersCache *pccCacheInstance = (TrimeshCollidersCache *)vValueData; + FreeTrimeshCollidersCache(pccCacheInstance); +} + + +#endif // #if dTLS_ENABLED + diff --git a/libs/ode-0.16.1/ode/src/odetls.h b/libs/ode-0.16.1/ode/src/odetls.h new file mode 100644 index 0000000..db3306b --- /dev/null +++ b/libs/ode-0.16.1/ode/src/odetls.h @@ -0,0 +1,126 @@ +/************************************************************************* + * * + * Thread local storage access stub for Open Dynamics Engine, * + * Copyright (C) 2008-2019 Oleh Derevenko. All rights reserved. * + * Email: odar@eleks.com (change all "a" to "e") * + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +ODE Thread Local Storage access stub interface. + +*/ + + +#ifndef _ODE_ODETLS_H_ +#define _ODE_ODETLS_H_ + + +#include "odeou.h" + + +#if dTLS_ENABLED + + +using _OU_NAMESPACE::tlsvaluetype; +using _OU_NAMESPACE::HTLSKEY; +using _OU_NAMESPACE::CThreadLocalStorage; + + +struct TrimeshCollidersCache; + + +enum EODETLSKIND +{ + OTK__MIN, + + OTK_AUTOCLEANUP = OTK__MIN, + OTK_MANUALCLEANUP, + + OTK__MAX, + + OTK__DEFAULT = OTK_AUTOCLEANUP, +}; + +enum EODETLSITEM +{ + OTI_DATA_ALLOCATION_FLAGS, + OTI_TRIMESH_TRIMESH_COLLIDER_CACHE, + + OTI__MAX, +}; + + +class COdeTls +{ +public: + static bool Initialize(EODETLSKIND tkTLSKind); + static void Finalize(EODETLSKIND tkTLSKind); + + static void CleanupForThread(); + +public: + static unsigned GetDataAllocationFlags(EODETLSKIND tkTLSKind) + { + // Must be a safe call as it is used to test if TLS slot is allocated at all + return (unsigned)(sizeint)CThreadLocalStorage::GetStorageValue(m_ahtkStorageKeys[tkTLSKind], OTI_DATA_ALLOCATION_FLAGS); + } + + static void SignalDataAllocationFlags(EODETLSKIND tkTLSKind, unsigned uFlagsMask) + { + unsigned uCurrentFlags = (unsigned)(sizeint)CThreadLocalStorage::UnsafeGetStorageValue(m_ahtkStorageKeys[tkTLSKind], OTI_DATA_ALLOCATION_FLAGS); + CThreadLocalStorage::UnsafeSetStorageValue(m_ahtkStorageKeys[tkTLSKind], OTI_DATA_ALLOCATION_FLAGS, (tlsvaluetype)(sizeint)(uCurrentFlags | uFlagsMask)); + } + + static void DropDataAllocationFlags(EODETLSKIND tkTLSKind, unsigned uFlagsMask) + { + unsigned uCurrentFlags = (unsigned)(sizeint)CThreadLocalStorage::UnsafeGetStorageValue(m_ahtkStorageKeys[tkTLSKind], OTI_DATA_ALLOCATION_FLAGS); + CThreadLocalStorage::UnsafeSetStorageValue(m_ahtkStorageKeys[tkTLSKind], OTI_DATA_ALLOCATION_FLAGS, (tlsvaluetype)(sizeint)(uCurrentFlags & ~uFlagsMask)); + } + + static TrimeshCollidersCache *GetTrimeshCollidersCache(EODETLSKIND tkTLSKind) + { + return (TrimeshCollidersCache *)CThreadLocalStorage::UnsafeGetStorageValue(m_ahtkStorageKeys[tkTLSKind], OTI_TRIMESH_TRIMESH_COLLIDER_CACHE); + } + +public: + static bool AssignDataAllocationFlags(EODETLSKIND tkTLSKind, unsigned uInitializationFlags); + + static bool AssignTrimeshCollidersCache(EODETLSKIND tkTLSKind, TrimeshCollidersCache *pccInstance); + static void DestroyTrimeshCollidersCache(EODETLSKIND tkTLSKind); + +private: + static void FreeTrimeshCollidersCache(TrimeshCollidersCache *pccCacheInstance); + +private: + static void _OU_CONVENTION_CALLBACK FreeTrimeshCollidersCache_Callback(tlsvaluetype vValueData); + +private: + static HTLSKEY m_ahtkStorageKeys[OTK__MAX]; +}; + + +#endif // dTLS_ENABLED + + +#endif // _ODE_ODETLS_H_ diff --git a/libs/ode-0.16.1/ode/src/plane.cpp b/libs/ode-0.16.1/ode/src/plane.cpp new file mode 100644 index 0000000..b54e894 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/plane.cpp @@ -0,0 +1,146 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +standard ODE geometry primitives: public API and pairwise collision functions. + +the rule is that only the low level primitive collision functions should set +dContactGeom::g1 and dContactGeom::g2. + +*/ + +#include <ode/common.h> +#include <ode/collision.h> +#include <ode/rotation.h> +#include "config.h" +#include "matrix.h" +#include "odemath.h" +#include "collision_kernel.h" +#include "collision_std.h" +#include "collision_util.h" + +#ifdef _MSC_VER +#pragma warning(disable:4291) // for VC++, no complaints about "no matching operator delete found" +#endif + +//**************************************************************************** +// plane public API + +static void make_sure_plane_normal_has_unit_length (dxPlane *g) +{ + dReal l = g->p[0]*g->p[0] + g->p[1]*g->p[1] + g->p[2]*g->p[2]; + if (l > 0) { + l = dRecipSqrt(l); + g->p[0] *= l; + g->p[1] *= l; + g->p[2] *= l; + g->p[3] *= l; + } + else { + g->p[0] = 1; + g->p[1] = 0; + g->p[2] = 0; + g->p[3] = 0; + } +} + + +dxPlane::dxPlane (dSpaceID space, dReal a, dReal b, dReal c, dReal d) : +dxGeom (space,0) +{ + type = dPlaneClass; + p[0] = a; + p[1] = b; + p[2] = c; + p[3] = d; + make_sure_plane_normal_has_unit_length (this); +} + + +void dxPlane::computeAABB() +{ + aabb[0] = -dInfinity; + aabb[1] = dInfinity; + aabb[2] = -dInfinity; + aabb[3] = dInfinity; + aabb[4] = -dInfinity; + aabb[5] = dInfinity; + + // Planes that have normal vectors aligned along an axis can use a + // less comprehensive (half space) bounding box. + + if ( p[1] == 0.0f && p[2] == 0.0f ) { + // normal aligned with x-axis + aabb[0] = (p[0] > 0) ? -dInfinity : -p[3]; + aabb[1] = (p[0] > 0) ? p[3] : dInfinity; + } else + if ( p[0] == 0.0f && p[2] == 0.0f ) { + // normal aligned with y-axis + aabb[2] = (p[1] > 0) ? -dInfinity : -p[3]; + aabb[3] = (p[1] > 0) ? p[3] : dInfinity; + } else + if ( p[0] == 0.0f && p[1] == 0.0f ) { + // normal aligned with z-axis + aabb[4] = (p[2] > 0) ? -dInfinity : -p[3]; + aabb[5] = (p[2] > 0) ? p[3] : dInfinity; + } +} + + +dGeomID dCreatePlane (dSpaceID space, + dReal a, dReal b, dReal c, dReal d) +{ + return new dxPlane (space,a,b,c,d); +} + + +void dGeomPlaneSetParams (dGeomID g, dReal a, dReal b, dReal c, dReal d) +{ + dUASSERT (g && g->type == dPlaneClass,"argument not a plane"); + dxPlane *p = (dxPlane*) g; + p->p[0] = a; + p->p[1] = b; + p->p[2] = c; + p->p[3] = d; + make_sure_plane_normal_has_unit_length (p); + dGeomMoved (g); +} + + +void dGeomPlaneGetParams (dGeomID g, dVector4 result) +{ + dUASSERT (g && g->type == dPlaneClass,"argument not a plane"); + dxPlane *p = (dxPlane*) g; + result[0] = p->p[0]; + result[1] = p->p[1]; + result[2] = p->p[2]; + result[3] = p->p[3]; +} + + +dReal dGeomPlanePointDepth (dGeomID g, dReal x, dReal y, dReal z) +{ + dUASSERT (g && g->type == dPlaneClass,"argument not a plane"); + dxPlane *p = (dxPlane*) g; + return p->p[3] - p->p[0]*x - p->p[1]*y - p->p[2]*z; +} diff --git a/libs/ode-0.16.1/ode/src/quickstep.cpp b/libs/ode-0.16.1/ode/src/quickstep.cpp new file mode 100644 index 0000000..046bc33 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/quickstep.cpp @@ -0,0 +1,3344 @@ +/*************************************************************************
+ * *
+ * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. *
+ * All rights reserved. Email: russ@q12.org Web: www.q12.org *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of EITHER: *
+ * (1) The GNU Lesser General Public License as published by the Free *
+ * Software Foundation; either version 2.1 of the License, or (at *
+ * your option) any later version. The text of the GNU Lesser *
+ * General Public License is included with this library in the *
+ * file LICENSE.TXT. *
+ * (2) The BSD-style license that is included with this library in *
+ * the file LICENSE-BSD.TXT. *
+ * *
+ * This library 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 files *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
+ * *
+ *************************************************************************/
+
+#include <ode/common.h>
+#include <ode/rotation.h>
+#include <ode/timer.h>
+#include <ode/error.h>
+#include <ode/misc.h>
+#include "config.h"
+#include "matrix.h"
+#include "odemath.h"
+#include "objects.h"
+#include "joints/joint.h"
+#include "lcp.h"
+#include "util.h"
+#include "threadingutils.h"
+
+#include <new>
+
+
+//***************************************************************************
+// configuration
+
+// for the SOR and CG methods:
+// uncomment the following line to use warm starting. this definitely
+// help for motor-driven joints. unfortunately it appears to hurt
+// with high-friction contacts using the SOR method. use with care
+
+// #define WARM_STARTING 1
+
+
+#define REORDERING_METHOD__DONT_REORDER 0
+#define REORDERING_METHOD__BY_ERROR 1
+#define REORDERING_METHOD__RANDOMLY 2
+
+// for the SOR method:
+// uncomment the following line to determine a new constraint-solving
+// order for each iteration. however, the qsort per iteration is expensive,
+// and the optimal order is somewhat problem dependent.
+// @@@ try the leaf->root ordering.
+
+// #define CONSTRAINTS_REORDERING_METHOD REORDERING_METHOD__BY_ERROR
+
+
+// for the SOR method:
+// uncomment the following line to randomly reorder constraint rows
+// during the solution. depending on the situation, this can help a lot
+// or hardly at all, but it doesn't seem to hurt.
+
+#define CONSTRAINTS_REORDERING_METHOD REORDERING_METHOD__RANDOMLY
+
+
+#if !defined(CONSTRAINTS_REORDERING_METHOD)
+#define CONSTRAINTS_REORDERING_METHOD REORDERING_METHOD__DONT_REORDER
+#endif
+
+
+#if CONSTRAINTS_REORDERING_METHOD == REORDERING_METHOD__RANDOMLY
+#if !defined(RANDOM_CONSTRAINTS_REORDERING_FREQUENCY)
+#define RANDOM_CONSTRAINTS_REORDERING_FREQUENCY 8U
+#endif
+dSASSERT(RANDOM_CONSTRAINTS_REORDERING_FREQUENCY != 0);
+#endif
+
+enum dxRandomReorderStage
+{
+ RRS__MIN,
+
+ RRS_REORDERING = RRS__MIN,
+
+ RRS__MAX,
+};
+
+
+//***************************************************************************
+// macros, typedefs, forwards and inlines
+
+struct IndexError;
+
+
+#define dMIN(A,B) ((A)>(B) ? (B) : (A))
+#define dMAX(A,B) ((B)>(A) ? (B) : (A))
+
+
+#define dxQUICKSTEPISLAND_STAGE2B_STEP 16U
+#define dxQUICKSTEPISLAND_STAGE2C_STEP 32U
+
+#ifdef WARM_STARTING
+#define dxQUICKSTEPISLAND_STAGE4A_STEP 256U
+#else
+#define dxQUICKSTEPISLAND_STAGE4A_STEP 512U
+#endif
+
+#define dxQUICKSTEPISLAND_STAGE4LCP_IMJ_STEP 8U
+#define dxQUICKSTEPISLAND_STAGE4LCP_AD_STEP 8U
+
+#ifdef WARM_STARTING
+#define dxQUICKSTEPISLAND_STAGE4LCP_FC_STEP 128U
+#define dxQUICKSTEPISLAND_STAGE4LCP_FC_COMPLETE_TO_PREPARE_COMPLEXITY_DIVISOR 4
+#define dxQUICKSTEPISLAND_STAGE4LCP_FC_STEP_PREPARE (dxQUICKSTEPISLAND_STAGE4LCP_FC_STEP * dxQUICKSTEPISLAND_STAGE4LCP_FC_COMPLETE_TO_PREPARE_COMPLEXITY_DIVISOR)
+#define dxQUICKSTEPISLAND_STAGE4LCP_FC_STEP_COMPLETE (dxQUICKSTEPISLAND_STAGE4LCP_FC_STEP)
+#else
+#define dxQUICKSTEPISLAND_STAGE4LCP_FC_STEP (dxQUICKSTEPISLAND_STAGE4A_STEP / 2) // Average info.m is 3 for stage4a, while there are 6 reals per index in fc
+#endif
+
+#define dxQUICKSTEPISLAND_STAGE4B_STEP 256U
+
+#define dxQUICKSTEPISLAND_STAGE6A_STEP 16U
+#define dxQUICKSTEPISLAND_STAGE6B_STEP 1U
+
+template<unsigned int step_size>
+inline unsigned int CalculateOptimalThreadsCount(unsigned int complexity, unsigned int max_threads)
+{
+ unsigned int raw_threads = dMAX(complexity, step_size) / step_size; // Round down on division
+ unsigned int optimum = dMIN(raw_threads, max_threads);
+ return optimum;
+}
+
+#define dxENCODE_INDEX(index) ((unsigned int)((index) + 1))
+#define dxDECODE_INDEX(code) ((unsigned int)((code) - 1))
+#define dxHEAD_INDEX 0
+
+//****************************************************************************
+// special matrix multipliers
+
+// multiply block of B matrix (q x 6) with 12 dReal per row with C vector (q)
+static inline void Multiply1_12q1 (dReal *A, const dReal *B, const dReal *C, unsigned int q)
+{
+ dIASSERT (q>0 && A && B && C);
+
+ dReal a = 0;
+ dReal b = 0;
+ dReal c = 0;
+ dReal d = 0;
+ dReal e = 0;
+ dReal f = 0;
+ dReal s;
+
+ for(unsigned int i=0, k = 0; i<q; k += 12, i++)
+ {
+ s = C[i]; //C[i] and B[n+k] cannot overlap because its value has been read into a temporary.
+
+ //For the rest of the loop, the only memory dependency (array) is from B[]
+ a += B[ k] * s;
+ b += B[1+k] * s;
+ c += B[2+k] * s;
+ d += B[3+k] * s;
+ e += B[4+k] * s;
+ f += B[5+k] * s;
+ }
+
+ A[0] = a;
+ A[1] = b;
+ A[2] = c;
+ A[3] = d;
+ A[4] = e;
+ A[5] = f;
+}
+
+//***************************************************************************
+// testing stuff
+
+#ifdef TIMING
+#define IFTIMING(x) x
+#else
+#define IFTIMING(x) ((void)0)
+#endif
+
+
+struct dJointWithInfo1
+{
+ dxJoint *joint;
+ dxJoint::Info1 info;
+};
+
+
+struct dxMIndexItem
+{
+ unsigned mIndex;
+ unsigned fbIndex;
+};
+
+struct dxJBodiesItem
+{
+ unsigned first;
+ int second; // The index is optional and can equal to -1
+};
+
+enum dxInvIRowElement
+{
+ IIE__MIN,
+
+ IIE__MATRIX_MIN = IIE__MIN,
+ IIE__MATRIX_MAX = IIE__MATRIX_MIN + dM3E__MAX,
+
+ IIE__MAX = IIE__MATRIX_MAX,
+};
+
+enum dxRHSCFMElement
+{
+ RCE_RHS = dxJoint::GI2_RHS,
+ RCE_CFM = dxJoint::GI2_CFM,
+
+ RCE__RHS_CFM_MAX = dxJoint::GI2__RHS_CFM_MAX,
+};
+
+enum dxLoHiElement
+{
+ LHE_LO = dxJoint::GI2_LO,
+ LHE_HI = dxJoint::GI2_HI,
+
+ LHE__LO_HI_MAX = dxJoint::GI2__LO_HI_MAX,
+};
+
+enum dxJacobiVectorElement
+{
+ JVE__MIN,
+
+ JVE__L_MIN = JVE__MIN + dDA__L_MIN,
+
+ JVE_LX = JVE__MIN + dDA_LX,
+ JVE_LY = JVE__MIN + dDA_LY,
+ JVE_LZ = JVE__MIN + dDA_LZ,
+
+ JVE__L_MAX = JVE__MIN + dDA__L_MAX,
+
+ JVE__A_MIN = JVE__MIN + dDA__A_MIN,
+
+ JVE_AX = JVE__MIN + dDA_AX,
+ JVE_AY = JVE__MIN + dDA_AY,
+ JVE_AZ = JVE__MIN + dDA_AZ,
+
+ JVE__A_MAX = JVE__MIN + dDA__A_MAX,
+
+ JVE__MAX = JVE__MIN + dDA__MAX,
+
+ JVE__L_COUNT = JVE__L_MAX - JVE__L_MIN,
+ JVE__A_COUNT = JVE__A_MAX - JVE__A_MIN,
+};
+
+enum dxJacobiMatrixElement
+{
+ JME__MIN,
+
+ JME__J1_MIN = JME__MIN,
+ JME__J1L_MIN = JME__J1_MIN + JVE__L_MIN,
+
+ JME_J1LX = JME__J1_MIN + JVE_LX,
+ JME_J1LY = JME__J1_MIN + JVE_LY,
+ JME_J1LZ = JME__J1_MIN + JVE_LZ,
+
+ JME__J1L_MAX = JME__J1_MIN + JVE__L_MAX,
+
+ JME__J1A_MIN = JME__J1_MIN + JVE__A_MIN,
+
+ JME_J1AX = JME__J1_MIN + JVE_AX,
+ JME_J1AY = JME__J1_MIN + JVE_AY,
+ JME_J1AZ = JME__J1_MIN + JVE_AZ,
+
+ JME__J1A_MAX = JME__J1_MIN + JVE__A_MAX,
+ JME__J1_MAX = JME__J1_MIN + JVE__MAX,
+
+ JME__RHS_CFM_MIN = JME__J1_MAX,
+ JME_RHS = JME__RHS_CFM_MIN + RCE_RHS,
+ JME_CFM = JME__RHS_CFM_MIN + RCE_CFM,
+ JME__RHS_CFM_MAX = JME__RHS_CFM_MIN + RCE__RHS_CFM_MAX,
+
+ JME__J2_MIN = JME__RHS_CFM_MAX,
+ JME__J2L_MIN = JME__J2_MIN + JVE__L_MIN,
+
+ JME_J2LX = JME__J2_MIN + JVE_LX,
+ JME_J2LY = JME__J2_MIN + JVE_LY,
+ JME_J2LZ = JME__J2_MIN + JVE_LZ,
+
+ JME__J2L_MAX = JME__J2_MIN + JVE__L_MAX,
+
+ JME__J2A_MIN = JME__J2_MIN + JVE__A_MIN,
+
+ JME_J2AX = JME__J2_MIN + JVE_AX,
+ JME_J2AY = JME__J2_MIN + JVE_AY,
+ JME_J2AZ = JME__J2_MIN + JVE_AZ,
+
+ JME__J2A_MAX = JME__J2_MIN + JVE__A_MAX,
+ JME__J2_MAX = JME__J2_MIN + JVE__MAX,
+
+ JME__LO_HI_MIN = JME__J2_MAX,
+ JME_LO = JME__LO_HI_MIN + LHE_LO,
+ JME_HI = JME__LO_HI_MIN + LHE_HI,
+ JME__LO_HI_MAX = JME__LO_HI_MIN + LHE__LO_HI_MAX,
+
+ JME__MAX = JME__LO_HI_MAX, // Is not that a luck to have 16 elements here? ;-)
+
+ JME__J1_COUNT = JME__J1_MAX - JME__J1_MIN,
+ JME__J2_COUNT = JME__J2_MAX - JME__J2_MIN,
+ JME__J_COUNT = JVE__MAX,
+};
+
+dSASSERT(JME__J_COUNT == JME__J1_COUNT);
+dSASSERT(JME__J_COUNT == JME__J2_COUNT);
+
+enum dxJacobiCopyElement
+{
+ JCE__MIN,
+
+ JCE__J1_MIN = JCE__MIN,
+ JCE__J1L_MIN = JCE__J1_MIN,
+
+ JCE_J1LX = JCE__J1L_MIN,
+ JCE_J1LY,
+ JCE_J1LZ,
+
+ JCE__J1L_MAX,
+
+ JCE__J1A_MIN = JCE__J1L_MAX,
+
+ JCE_J1AX = JCE__J1A_MIN,
+ JCE_J1AY,
+ JCE_J1AZ,
+
+ JCE__J1A_MAX,
+ JCE__J1_MAX = JCE__J1A_MAX,
+
+ JCE__J2_MIN = JCE__J1_MAX,
+ JCE__J2L_MIN = JCE__J2_MIN,
+
+ JCE_J2LX = JCE__J2L_MIN,
+ JCE_J2LY,
+ JCE_J2LZ,
+
+ JCE__J2L_MAX,
+
+ JCE__J2A_MIN = JCE__J2L_MAX,
+
+ JCE_J2AX = JCE__J2A_MIN,
+ JCE_J2AY,
+ JCE_J2AZ,
+
+ JCE__J2A_MAX,
+ JCE__J2_MAX = JCE__J2A_MAX,
+
+ JCE__MAX = JCE__J2_MAX,
+
+ JCE__J1_COUNT = JCE__J1_MAX - JCE__J1_MIN,
+ JCE__J2_COUNT = JCE__J2_MAX - JCE__J2_MIN,
+ JCE__JMAX_COUNT = dMAX(JCE__J1_COUNT, JCE__J2_COUNT),
+};
+
+enum dxInvMJTElement
+{
+ IMJ__MIN,
+
+ IMJ__1_MIN = IMJ__MIN,
+
+ IMJ__1L_MIN = IMJ__1_MIN + JVE__L_MIN,
+
+ IMJ_1LX = IMJ__1_MIN + JVE_LX,
+ IMJ_1LY = IMJ__1_MIN + JVE_LY,
+ IMJ_1LZ = IMJ__1_MIN + JVE_LZ,
+
+ IMJ__1L_MAX = IMJ__1_MIN + JVE__L_MAX,
+
+ IMJ__1A_MIN = IMJ__1_MIN + JVE__A_MIN,
+
+ IMJ_1AX = IMJ__1_MIN + JVE_AX,
+ IMJ_1AY = IMJ__1_MIN + JVE_AY,
+ IMJ_1AZ = IMJ__1_MIN + JVE_AZ,
+
+ IMJ__1A_MAX = IMJ__1_MIN + JVE__A_MAX,
+
+ IMJ__1_MAX = IMJ__1_MIN + JVE__MAX,
+
+ IMJ__2_MIN = IMJ__1_MAX,
+
+ IMJ__2L_MIN = IMJ__2_MIN + JVE__L_MIN,
+
+ IMJ_2LX = IMJ__2_MIN + JVE_LX,
+ IMJ_2LY = IMJ__2_MIN + JVE_LY,
+ IMJ_2LZ = IMJ__2_MIN + JVE_LZ,
+
+ IMJ__2L_MAX = IMJ__2_MIN + JVE__L_MAX,
+
+ IMJ__2A_MIN = IMJ__2_MIN + JVE__A_MIN,
+
+ IMJ_2AX = IMJ__2_MIN + JVE_AX,
+ IMJ_2AY = IMJ__2_MIN + JVE_AY,
+ IMJ_2AZ = IMJ__2_MIN + JVE_AZ,
+
+ IMJ__2A_MAX = IMJ__2_MIN + JVE__A_MAX,
+
+ IMJ__2_MAX = IMJ__2_MIN + JVE__MAX,
+
+ IMJ__MAX = IMJ__2_MAX,
+};
+
+enum dxContactForceElement
+{
+ CFE__MIN,
+
+ CFE__DYNAMICS_MIN = CFE__MIN,
+
+ CFE__L_MIN = CFE__DYNAMICS_MIN + dDA__L_MIN,
+
+ CFE_LX = CFE__DYNAMICS_MIN + dDA_LX,
+ CFE_LY = CFE__DYNAMICS_MIN + dDA_LY,
+ CFE_LZ = CFE__DYNAMICS_MIN + dDA_LZ,
+
+ CFE__L_MAX = CFE__DYNAMICS_MIN + dDA__L_MAX,
+
+ CFE__A_MIN = CFE__DYNAMICS_MIN + dDA__A_MIN,
+
+ CFE_AX = CFE__DYNAMICS_MIN + dDA_AX,
+ CFE_AY = CFE__DYNAMICS_MIN + dDA_AY,
+ CFE_AZ = CFE__DYNAMICS_MIN + dDA_AZ,
+
+ CFE__A_MAX = CFE__DYNAMICS_MIN + dDA__A_MAX,
+
+ CFE__DYNAMICS_MAX = CFE__DYNAMICS_MIN + dDA__MAX,
+
+ CFE__MAX = CFE__DYNAMICS_MAX,
+};
+
+enum dxRHSElement
+{
+ RHS__MIN,
+
+ RHS__DYNAMICS_MIN = RHS__MIN,
+
+ RHS__L_MIN = RHS__DYNAMICS_MIN + dDA__L_MIN,
+
+ RHS_LX = RHS__DYNAMICS_MIN + dDA_LX,
+ RHS_LY = RHS__DYNAMICS_MIN + dDA_LY,
+ RHS_LZ = RHS__DYNAMICS_MIN + dDA_LZ,
+
+ RHS__L_MAX = RHS__DYNAMICS_MIN + dDA__L_MAX,
+
+ RHS__A_MIN = RHS__DYNAMICS_MIN + dDA__A_MIN,
+
+ RHS_AX = RHS__DYNAMICS_MIN + dDA_AX,
+ RHS_AY = RHS__DYNAMICS_MIN + dDA_AY,
+ RHS_AZ = RHS__DYNAMICS_MIN + dDA_AZ,
+
+ RHS__A_MAX = RHS__DYNAMICS_MIN + dDA__A_MAX,
+
+ RHS__DYNAMICS_MAX = RHS__DYNAMICS_MIN + dDA__MAX,
+
+ RHS__MAX = RHS__DYNAMICS_MAX,
+};
+
+
+#define JACOBIAN_ALIGNMENT dMAX(JME__MAX * sizeof(dReal), EFFICIENT_ALIGNMENT)
+dSASSERT(((JME__MAX - 1) & JME__MAX) == 0); // Otherwise there is no reason to over-align the Jacobian
+
+#define JCOPY_ALIGNMENT dMAX(32, EFFICIENT_ALIGNMENT)
+#define INVI_ALIGNMENT dMAX(32, EFFICIENT_ALIGNMENT)
+#define INVMJ_ALIGNMENT dMAX(32, EFFICIENT_ALIGNMENT)
+
+
+struct dxQuickStepperStage0Outputs
+{
+ unsigned int nj;
+ unsigned int m;
+ unsigned int mfb;
+};
+
+struct dxQuickStepperStage1CallContext
+{
+ void Initialize(const dxStepperProcessingCallContext *stepperCallContext, void *stageMemArenaState, dReal *invI, dJointWithInfo1 *jointinfos)
+ {
+ m_stepperCallContext = stepperCallContext;
+ m_stageMemArenaState = stageMemArenaState;
+ m_invI = invI;
+ m_jointinfos = jointinfos;
+ }
+
+ const dxStepperProcessingCallContext *m_stepperCallContext;
+ void *m_stageMemArenaState;
+ dReal *m_invI;
+ dJointWithInfo1 *m_jointinfos;
+ dxQuickStepperStage0Outputs m_stage0Outputs;
+};
+
+struct dxQuickStepperStage0BodiesCallContext
+{
+ void Initialize(const dxStepperProcessingCallContext *stepperCallContext, dReal *invI)
+ {
+ m_stepperCallContext = stepperCallContext;
+ m_invI = invI;
+ m_tagsTaken = 0;
+ m_gravityTaken = 0;
+ m_inertiaBodyIndex = 0;
+ }
+
+ const dxStepperProcessingCallContext *m_stepperCallContext;
+ dReal *m_invI;
+ atomicord32 m_tagsTaken;
+ atomicord32 m_gravityTaken;
+ volatile atomicord32 m_inertiaBodyIndex;
+};
+
+struct dxQuickStepperStage0JointsCallContext
+{
+ void Initialize(const dxStepperProcessingCallContext *stepperCallContext, dJointWithInfo1 *jointinfos, dxQuickStepperStage0Outputs *stage0Outputs)
+ {
+ m_stepperCallContext = stepperCallContext;
+ m_jointinfos = jointinfos;
+ m_stage0Outputs = stage0Outputs;
+ }
+
+ const dxStepperProcessingCallContext *m_stepperCallContext;
+ dJointWithInfo1 *m_jointinfos;
+ dxQuickStepperStage0Outputs *m_stage0Outputs;
+};
+
+static int dxQuickStepIsland_Stage0_Bodies_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static int dxQuickStepIsland_Stage0_Joints_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static int dxQuickStepIsland_Stage1_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+
+static void dxQuickStepIsland_Stage0_Bodies(dxQuickStepperStage0BodiesCallContext *callContext);
+static void dxQuickStepIsland_Stage0_Joints(dxQuickStepperStage0JointsCallContext *callContext);
+static void dxQuickStepIsland_Stage1(dxQuickStepperStage1CallContext *callContext);
+
+
+struct dxQuickStepperLocalContext
+{
+ void Initialize(dReal *invI, dJointWithInfo1 *jointinfos, unsigned int nj,
+ unsigned int m, unsigned int mfb, const dxMIndexItem *mindex, dxJBodiesItem *jb, int *findex,
+ dReal *J, dReal *Jcopy)
+ {
+ m_invI = invI;
+ m_jointinfos = jointinfos;
+ m_nj = nj;
+ m_m = m;
+ m_mfb = mfb;
+ m_valid_findices = 0;
+ m_mindex = mindex;
+ m_jb = jb;
+ m_findex = findex;
+ m_J = J;
+ m_Jcopy = Jcopy;
+ }
+
+ dReal *m_invI;
+ dJointWithInfo1 *m_jointinfos;
+ unsigned int m_nj;
+ unsigned int m_m;
+ unsigned int m_mfb;
+ volatile atomicord32 m_valid_findices;
+ const dxMIndexItem *m_mindex;
+ dxJBodiesItem *m_jb;
+ int *m_findex;
+ dReal *m_J;
+ dReal *m_Jcopy;
+};
+
+struct dxQuickStepperStage3CallContext
+{
+ void Initialize(const dxStepperProcessingCallContext *callContext, const dxQuickStepperLocalContext *localContext,
+ void *stage1MemArenaState)
+ {
+ m_stepperCallContext = callContext;
+ m_localContext = localContext;
+ m_stage1MemArenaState = stage1MemArenaState;
+ }
+
+ const dxStepperProcessingCallContext *m_stepperCallContext;
+ const dxQuickStepperLocalContext *m_localContext;
+ void *m_stage1MemArenaState;
+};
+
+struct dxQuickStepperStage2CallContext
+{
+ void Initialize(const dxStepperProcessingCallContext *callContext, dxQuickStepperLocalContext *localContext,
+ dReal *rhs_tmp)
+ {
+ m_stepperCallContext = callContext;
+ m_localContext = localContext;
+ m_rhs_tmp = rhs_tmp;
+ m_ji_J = 0;
+ m_ji_jb = 0;
+ m_bi = 0;
+ m_Jrhsi = 0;
+ }
+
+ const dxStepperProcessingCallContext *m_stepperCallContext;
+ dxQuickStepperLocalContext *m_localContext;
+ dReal *m_rhs_tmp;
+ volatile atomicord32 m_ji_J;
+ volatile atomicord32 m_ji_jb;
+ volatile atomicord32 m_bi;
+ volatile atomicord32 m_Jrhsi;
+};
+
+static int dxQuickStepIsland_Stage2a_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static int dxQuickStepIsland_Stage2aSync_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static int dxQuickStepIsland_Stage2b_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static int dxQuickStepIsland_Stage2bSync_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static int dxQuickStepIsland_Stage2c_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static int dxQuickStepIsland_Stage3_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+
+static void dxQuickStepIsland_Stage2a(dxQuickStepperStage2CallContext *stage2CallContext);
+static void dxQuickStepIsland_Stage2b(dxQuickStepperStage2CallContext *stage2CallContext);
+static void dxQuickStepIsland_Stage2c(dxQuickStepperStage2CallContext *stage2CallContext);
+static void dxQuickStepIsland_Stage3(dxQuickStepperStage3CallContext *stage3CallContext);
+
+
+struct dxQuickStepperStage5CallContext
+{
+ void Initialize(const dxStepperProcessingCallContext *callContext, const dxQuickStepperLocalContext *localContext,
+ void *stage3MemArenaState)
+ {
+ m_stepperCallContext = callContext;
+ m_localContext = localContext;
+ m_stage3MemArenaState = stage3MemArenaState;
+ }
+
+ const dxStepperProcessingCallContext *m_stepperCallContext;
+ const dxQuickStepperLocalContext *m_localContext;
+ void *m_stage3MemArenaState;
+};
+
+struct dxQuickStepperStage4CallContext
+{
+ void Initialize(const dxStepperProcessingCallContext *callContext, const dxQuickStepperLocalContext *localContext,
+ dReal *lambda, dReal *cforce, dReal *iMJ, IndexError *order, dReal *last_lambda, atomicord32 *bi_links_or_mi_levels, atomicord32 *mi_links)
+ {
+ m_stepperCallContext = callContext;
+ m_localContext = localContext;
+ m_lambda = lambda;
+ m_cforce = cforce;
+ m_iMJ = iMJ;
+ m_order = order;
+ m_last_lambda = last_lambda;
+ m_bi_links_or_mi_levels = bi_links_or_mi_levels;
+ m_mi_links = mi_links;
+ m_LCP_IterationSyncReleasee = NULL;
+ m_LCP_IterationAllowedThreads = 0;
+ m_LCP_fcStartReleasee = NULL;
+ m_ji_4a = 0;
+ m_mi_iMJ = 0;
+ m_mi_fc = 0;
+ m_mi_Ad = 0;
+ m_LCP_iteration = 0;
+ m_cf_4b = 0;
+ m_ji_4b = 0;
+ }
+
+ void AssignLCP_IterationData(dCallReleaseeID releaseeInstance, unsigned int iterationAllowedThreads)
+ {
+ m_LCP_IterationSyncReleasee = releaseeInstance;
+ m_LCP_IterationAllowedThreads = iterationAllowedThreads;
+ }
+
+ void AssignLCP_fcStartReleasee(dCallReleaseeID releaseeInstance)
+ {
+ m_LCP_fcStartReleasee = releaseeInstance;
+ }
+
+ void AssignLCP_fcAllowedThreads(unsigned int prepareThreads, unsigned int completeThreads)
+ {
+ m_LCP_fcPrepareThreadsRemaining = prepareThreads;
+ m_LCP_fcCompleteThreadsTotal = completeThreads;
+ }
+
+ void ResetLCP_fcComputationIndex()
+ {
+ m_mi_fc = 0;
+ }
+
+ void ResetSOR_ConstraintsReorderVariables(unsigned reorderThreads)
+ {
+ m_SOR_reorderHeadTaken = 0;
+ m_SOR_reorderTailTaken = 0;
+ m_SOR_bi_zeroHeadTaken = 0;
+ m_SOR_bi_zeroTailTaken = 0;
+ m_SOR_mi_zeroHeadTaken = 0;
+ m_SOR_mi_zeroTailTaken = 0;
+ m_SOR_reorderThreadsRemaining = reorderThreads;
+ }
+
+ void RecordLCP_IterationStart(unsigned int totalThreads, dCallReleaseeID nextReleasee)
+ {
+ m_LCP_iterationThreadsTotal = totalThreads;
+ m_LCP_iterationThreadsRemaining = totalThreads;
+ m_LCP_iterationNextReleasee = nextReleasee;
+ }
+
+
+ const dxStepperProcessingCallContext *m_stepperCallContext;
+ const dxQuickStepperLocalContext *m_localContext;
+ dReal *m_lambda;
+ dReal *m_cforce;
+ dReal *m_iMJ;
+ IndexError *m_order;
+ dReal *m_last_lambda;
+ atomicord32 *m_bi_links_or_mi_levels;
+ atomicord32 *m_mi_links;
+ dCallReleaseeID m_LCP_IterationSyncReleasee;
+ unsigned int m_LCP_IterationAllowedThreads;
+ dCallReleaseeID m_LCP_fcStartReleasee;
+ volatile atomicord32 m_ji_4a;
+ volatile atomicord32 m_mi_iMJ;
+ volatile atomicord32 m_mi_fc;
+ volatile atomicord32 m_LCP_fcPrepareThreadsRemaining;
+ unsigned int m_LCP_fcCompleteThreadsTotal;
+ volatile atomicord32 m_mi_Ad;
+ unsigned int m_LCP_iteration;
+ unsigned int m_LCP_iterationThreadsTotal;
+ volatile atomicord32 m_LCP_iterationThreadsRemaining;
+ dCallReleaseeID m_LCP_iterationNextReleasee;
+ volatile atomicord32 m_SOR_reorderHeadTaken;
+ volatile atomicord32 m_SOR_reorderTailTaken;
+ volatile atomicord32 m_SOR_bi_zeroHeadTaken;
+ volatile atomicord32 m_SOR_bi_zeroTailTaken;
+ volatile atomicord32 m_SOR_mi_zeroHeadTaken;
+ volatile atomicord32 m_SOR_mi_zeroTailTaken;
+ volatile atomicord32 m_SOR_reorderThreadsRemaining;
+ volatile atomicord32 m_cf_4b;
+ volatile atomicord32 m_ji_4b;
+};
+
+
+static int dxQuickStepIsland_Stage4a_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static int dxQuickStepIsland_Stage4LCP_iMJ_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static int dxQuickStepIsland_Stage4LCP_iMJSync_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static int dxQuickStepIsland_Stage4LCP_fcStart_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static int dxQuickStepIsland_Stage4LCP_fc_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+#ifdef WARM_STARTING
+static int dxQuickStepIsland_Stage4LCP_fcWarmComplete_Callback(void *_stage4CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+#endif
+static int dxQuickStepIsland_Stage4LCP_Ad_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static int dxQuickStepIsland_Stage4LCP_ReorderPrep_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static int dxQuickStepIsland_Stage4LCP_IterationStart_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static int dxQuickStepIsland_Stage4LCP_ConstraintsReordering_Callback(void *_stage4CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static int dxQuickStepIsland_Stage4LCP_ConstraintsReorderingSync_Callback(void *_stage4CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static int dxQuickStepIsland_Stage4LCP_Iteration_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static int dxQuickStepIsland_Stage4LCP_IterationSync_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static int dxQuickStepIsland_Stage4b_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static int dxQuickStepIsland_Stage5_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+
+static void dxQuickStepIsland_Stage4a(dxQuickStepperStage4CallContext *stage4CallContext);
+static void dxQuickStepIsland_Stage4LCP_iMJComputation(dxQuickStepperStage4CallContext *stage4CallContext);
+static void dxQuickStepIsland_Stage4LCP_MTfcComputation(dxQuickStepperStage4CallContext *stage4CallContext, dCallReleaseeID callThisReleasee);
+#ifdef WARM_STARTING
+static void dxQuickStepIsland_Stage4LCP_MTfcComputation_warm(dxQuickStepperStage4CallContext *stage4CallContext, dCallReleaseeID callThisReleasee);
+static void dxQuickStepIsland_Stage4LCP_MTfcComputation_warmZeroArrays(dxQuickStepperStage4CallContext *stage4CallContext);
+static void dxQuickStepIsland_Stage4LCP_MTfcComputation_warmPrepare(dxQuickStepperStage4CallContext *stage4CallContext);
+static void dxQuickStepIsland_Stage4LCP_MTfcComputation_warmComplete(dxQuickStepperStage4CallContext *stage4CallContext);
+#endif
+static void dxQuickStepIsland_Stage4LCP_MTfcComputation_cold(dxQuickStepperStage4CallContext *stage4CallContext);
+static void dxQuickStepIsland_Stage4LCP_STfcComputation(dxQuickStepperStage4CallContext *stage4CallContext);
+static void dxQuickStepIsland_Stage4LCP_AdComputation(dxQuickStepperStage4CallContext *stage4CallContext);
+static void dxQuickStepIsland_Stage4LCP_ReorderPrep(dxQuickStepperStage4CallContext *stage4CallContext);
+static void dxQuickStepIsland_Stage4LCP_ConstraintsReordering(dxQuickStepperStage4CallContext *stage4CallContext);
+static bool dxQuickStepIsland_Stage4LCP_ConstraintsShuffling(dxQuickStepperStage4CallContext *stage4CallContext, unsigned int iteration);
+static void dxQuickStepIsland_Stage4LCP_LinksArraysZeroing(dxQuickStepperStage4CallContext *stage4CallContext);
+static void dxQuickStepIsland_Stage4LCP_DependencyMapForNewOrderRebuilding(dxQuickStepperStage4CallContext *stage4CallContext);
+static void dxQuickStepIsland_Stage4LCP_DependencyMapFromSavedLevelsReconstruction(dxQuickStepperStage4CallContext *stage4CallContext);
+static void dxQuickStepIsland_Stage4LCP_MTIteration(dxQuickStepperStage4CallContext *stage4CallContext, unsigned int initiallyKnownToBeCompletedLevel);
+static void dxQuickStepIsland_Stage4LCP_STIteration(dxQuickStepperStage4CallContext *stage4CallContext);
+static void dxQuickStepIsland_Stage4LCP_IterationStep(dxQuickStepperStage4CallContext *stage4CallContext, unsigned int i);
+static void dxQuickStepIsland_Stage4b(dxQuickStepperStage4CallContext *stage4CallContext);
+static void dxQuickStepIsland_Stage5(dxQuickStepperStage5CallContext *stage5CallContext);
+
+
+struct dxQuickStepperStage6CallContext
+{
+ void Initialize(const dxStepperProcessingCallContext *callContext, const dxQuickStepperLocalContext *localContext)
+ {
+ m_stepperCallContext = callContext;
+ m_localContext = localContext;
+ m_bi_6a = 0;
+ m_bi_6b = 0;
+ }
+
+ const dxStepperProcessingCallContext *m_stepperCallContext;
+ const dxQuickStepperLocalContext *m_localContext;
+ volatile atomicord32 m_bi_6a;
+ volatile atomicord32 m_bi_6b;
+};
+
+static int dxQuickStepIsland_Stage6a_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static int dxQuickStepIsland_Stage6aSync_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static int dxQuickStepIsland_Stage6b_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+
+static void dxQuickStepIsland_Stage6a(dxQuickStepperStage6CallContext *stage6CallContext);
+static void dxQuickStepIsland_Stage6_VelocityCheck(dxQuickStepperStage6CallContext *stage6CallContext);
+static void dxQuickStepIsland_Stage6b(dxQuickStepperStage6CallContext *stage6CallContext);
+
+//***************************************************************************
+// various common computations involving the matrix J
+
+// compute iMJ = inv(M)*J'
+
+template<unsigned int step_size>
+void compute_invM_JT (volatile atomicord32 *mi_storage, dReal *iMJ,
+ unsigned int m, const dReal *J, const dxJBodiesItem *jb,
+ dxBody * const *body, const dReal *invI)
+{
+ unsigned int m_steps = (m + (step_size - 1)) / step_size;
+
+ unsigned mi_step;
+ while ((mi_step = ThrsafeIncrementIntUpToLimit(mi_storage, m_steps)) != m_steps) {
+ unsigned int mi = mi_step * step_size;
+ const unsigned int miend = mi + dMIN(step_size, m - mi);
+
+ dReal *iMJ_ptr = iMJ + (sizeint)mi * IMJ__MAX;
+ const dReal *J_ptr = J + (sizeint)mi * JME__MAX;
+ while (true) {
+ int b1 = jb[mi].first;
+ int b2 = jb[mi].second;
+
+ dReal k1 = body[(unsigned)b1]->invMass;
+ for (unsigned int j = 0; j != JVE__L_COUNT; j++) iMJ_ptr[IMJ__1L_MIN + j] = k1 * J_ptr[JME__J1L_MIN + j];
+ const dReal *invIrow1 = invI + (sizeint)(unsigned)b1 * IIE__MAX + IIE__MATRIX_MIN;
+ dMultiply0_331 (iMJ_ptr + IMJ__1A_MIN, invIrow1, J_ptr + JME__J1A_MIN);
+
+ if (b2 != -1) {
+ dReal k2 = body[(unsigned)b2]->invMass;
+ for (unsigned int j = 0; j != JVE__L_COUNT; ++j) iMJ_ptr[IMJ__2L_MIN + j] = k2 * J_ptr[JME__J2L_MIN + j];
+ const dReal *invIrow2 = invI + (sizeint)(unsigned)b2 * IIE__MAX + IIE__MATRIX_MIN;
+ dMultiply0_331 (iMJ_ptr + IMJ__2A_MIN, invIrow2, J_ptr + JME__J2A_MIN);
+ }
+
+ if (++mi == miend) {
+ break;
+ }
+ iMJ_ptr += IMJ__MAX;
+ J_ptr += JME__MAX;
+ }
+ }
+}
+
+#ifdef WARM_STARTING
+
+static
+void multiply_invM_JT_init_array(unsigned int nb, atomicord32 *bi_links/*=[nb]*/)
+{
+ // const unsigned businessIndex_none = dxENCODE_INDEX(-1);
+ // for (unsigned int bi = 0; bi != nb; ++bi) {
+ // bi_links[bi] = businessIndex_none;
+ // }
+ memset(bi_links, 0, nb * sizeof(bi_links[0]));
+}
+
+// compute out = inv(M)*J'*in.
+template<unsigned int step_size>
+void multiply_invM_JT_prepare(volatile atomicord32 *mi_storage,
+ unsigned int m, const dxJBodiesItem *jb, atomicord32 *bi_links/*=[nb]*/, atomicord32 *mi_links/*=[2*m]*/)
+{
+ unsigned int m_steps = (m + (step_size - 1)) / step_size;
+
+ unsigned mi_step;
+ while ((mi_step = ThrsafeIncrementIntUpToLimit(mi_storage, m_steps)) != m_steps) {
+ unsigned int mi = mi_step * step_size;
+ const unsigned int miend = mi + dMIN(step_size, m - mi);
+
+ while (true) {
+ int b1 = jb[mi].first;
+ int b2 = jb[mi].second;
+
+ const unsigned encoded_mi = dxENCODE_INDEX(mi);
+ unsigned oldIndex_b1 = ThrsafeExchange(&bi_links[b1], encoded_mi);
+ mi_links[(sizeint)mi * 2] = oldIndex_b1;
+
+ if (b2 != -1) {
+ unsigned oldIndex_b2 = ThrsafeExchange(&bi_links[b2], encoded_mi);
+ mi_links[(sizeint)mi * 2 + 1] = oldIndex_b2;
+ }
+
+ if (++mi == miend) {
+ break;
+ }
+ }
+ }
+}
+
+template<unsigned int step_size, unsigned int out_offset, unsigned int out_stride>
+void multiply_invM_JT_complete(volatile atomicord32 *bi_storage, dReal *out,
+ unsigned int nb, const dReal *iMJ, const dxJBodiesItem *jb, const dReal *in,
+ atomicord32 *bi_links/*=[nb]*/, atomicord32 *mi_links/*=[2*m]*/)
+{
+ const unsigned businessIndex_none = dxENCODE_INDEX(-1);
+
+ unsigned int nb_steps = (nb + (step_size - 1)) / step_size;
+
+ unsigned bi_step;
+ while ((bi_step = ThrsafeIncrementIntUpToLimit(bi_storage, nb_steps)) != nb_steps) {
+ unsigned int bi = bi_step * step_size;
+ const unsigned int biend = bi + dMIN(step_size, nb - bi);
+
+ dReal *out_ptr = out + (sizeint)bi * out_stride + out_offset;
+ while (true) {
+ dReal psum0 = REAL(0.0), psum1 = REAL(0.0), psum2 = REAL(0.0), psum3 = REAL(0.0), psum4 = REAL(0.0), psum5 = REAL(0.0);
+
+ unsigned businessIndex = bi_links[bi];
+ while (businessIndex != businessIndex_none) {
+ unsigned int mi = dxDECODE_INDEX(businessIndex);
+ const dReal *iMJ_ptr;
+
+ if (bi == jb[mi].first) {
+ iMJ_ptr = iMJ + (sizeint)mi * IMJ__MAX + IMJ__1_MIN;
+ businessIndex = mi_links[(sizeint)mi * 2];
+ }
+ else {
+ dIASSERT(bi == jb[mi].second);
+
+ iMJ_ptr = iMJ + (sizeint)mi * IMJ__MAX + IMJ__2_MIN;
+ businessIndex = mi_links[(sizeint)mi * 2 + 1];
+ }
+
+ const dReal in_i = in[mi];
+ psum0 += in_i * iMJ_ptr[JVE_LX]; psum1 += in_i * iMJ_ptr[JVE_LY]; psum2 += in_i * iMJ_ptr[JVE_LZ];
+ psum3 += in_i * iMJ_ptr[JVE_AX]; psum4 += in_i * iMJ_ptr[JVE_AY]; psum5 += in_i * iMJ_ptr[JVE_AZ];
+ }
+
+ out_ptr[dDA_LX] = psum0; out_ptr[dDA_LY] = psum1; out_ptr[dDA_LZ] = psum2;
+ out_ptr[dDA_AX] = psum3; out_ptr[dDA_AY] = psum4; out_ptr[dDA_AZ] = psum5;
+
+ if (++bi == biend) {
+ break;
+ }
+ out_ptr += out_stride;
+ }
+ }
+}
+
+template<unsigned int out_offset, unsigned int out_stride>
+void _multiply_invM_JT (dReal *out,
+ unsigned int m, unsigned int nb, dReal *iMJ, const dxJBodiesItem *jb, const dReal *in)
+{
+ dSetZero (out, (sizeint)nb * out_stride);
+ const dReal *iMJ_ptr = iMJ;
+ for (unsigned int i=0; i<m; i++) {
+ int b1 = jb[i].first;
+ int b2 = jb[i].second;
+ const dReal in_i = in[i];
+
+ dReal *out_ptr = out + (sizeint)(unsigned)b1 * out_stride + out_offset;
+ for (unsigned int j = JVE__MIN; j != JVE__MAX; j++) out_ptr[j - JVE__MIN] += iMJ_ptr[IMJ__1_MIN + j] * in_i;
+ dSASSERT(out_stride - out_offset >= JVE__MAX);
+ dSASSERT(JVE__MAX == (int)dDA__MAX);
+
+ if (b2 != -1) {
+ out_ptr = out + (sizeint)(unsigned)b2 * out_stride + out_offset;
+ for (unsigned int j = JVE__MIN; j != JVE__MAX; j++) out_ptr[j - JVE__MIN] += iMJ_ptr[IMJ__2_MIN + j] * in_i;
+ dSASSERT(out_stride - out_offset >= JVE__MAX);
+ dSASSERT(JVE__MAX == (int)dDA__MAX);
+ }
+
+ iMJ_ptr += IMJ__MAX;
+ }
+}
+#endif
+
+// compute out = J*in.
+template<unsigned int step_size, unsigned int in_offset, unsigned int in_stride>
+void multiplyAdd_J (volatile atomicord32 *mi_storage,
+ unsigned int m, dReal *J, const dxJBodiesItem *jb, const dReal *in)
+{
+ unsigned int m_steps = (m + (step_size - 1)) / step_size;
+
+ unsigned mi_step;
+ while ((mi_step = ThrsafeIncrementIntUpToLimit(mi_storage, m_steps)) != m_steps) {
+ unsigned int mi = mi_step * step_size;
+ const unsigned int miend = mi + dMIN(step_size, m - mi);
+
+ dReal *J_ptr = J + (sizeint)mi * JME__MAX;
+ while (true) {
+ int b1 = jb[mi].first;
+ int b2 = jb[mi].second;
+ dReal sum = REAL(0.0);
+ const dReal *in_ptr = in + (sizeint)(unsigned)b1 * in_stride + in_offset;
+ for (unsigned int j = 0; j != JME__J1_COUNT; ++j) sum += J_ptr[j + JME__J1_MIN] * in_ptr[j];
+ dSASSERT(in_offset + JME__J1_COUNT <= in_stride);
+
+ if (b2 != -1) {
+ in_ptr = in + (sizeint)(unsigned)b2 * in_stride + in_offset;
+ for (unsigned int j = 0; j != JME__J2_COUNT; ++j) sum += J_ptr[j + JME__J2_MIN] * in_ptr[j];
+ dSASSERT(in_offset + JME__J2_COUNT <= in_stride);
+ }
+ J_ptr[JME_RHS] += sum;
+
+ if (++mi == miend) {
+ break;
+ }
+ J_ptr += JME__MAX;
+ }
+ }
+}
+
+
+struct IndexError {
+#if CONSTRAINTS_REORDERING_METHOD == REORDERING_METHOD__BY_ERROR
+ dReal error; // error to sort on
+#endif
+ int index; // row index
+};
+
+
+#if CONSTRAINTS_REORDERING_METHOD == REORDERING_METHOD__BY_ERROR
+
+static int compare_index_error (const void *a, const void *b)
+{
+ const IndexError *i1 = (IndexError*) a;
+ const IndexError *i2 = (IndexError*) b;
+ if (i1->error < i2->error) return -1;
+ if (i1->error > i2->error) return 1;
+ return 0;
+}
+
+#endif // #if CONSTRAINTS_REORDERING_METHOD == REORDERING_METHOD__BY_ERROR
+
+static inline
+bool IsSORConstraintsReorderRequiredForIteration(unsigned iteration)
+{
+ bool result = false;
+
+#if CONSTRAINTS_REORDERING_METHOD == REORDERING_METHOD__BY_ERROR
+
+ result = true;
+
+
+#elif CONSTRAINTS_REORDERING_METHOD == REORDERING_METHOD__RANDOMLY
+
+ // This logic is intended to skip randomization on the very first iteration
+ if (!dIN_RANGE(iteration, 0, RANDOM_CONSTRAINTS_REORDERING_FREQUENCY)
+ ? dIN_RANGE(iteration % RANDOM_CONSTRAINTS_REORDERING_FREQUENCY, RRS__MIN, RRS__MAX)
+ : iteration == 0) {
+ result = true;
+ }
+
+
+#else // #if CONSTRAINTS_REORDERING_METHOD != REORDERING_METHOD__BY_ERROR && CONSTRAINTS_REORDERING_METHOD != REORDERING_METHOD__RANDOMLY
+
+ if (iteration == 0) {
+ result = true;
+ }
+
+
+#endif
+
+ return result;
+}
+
+/*extern */
+void dxQuickStepIsland(const dxStepperProcessingCallContext *callContext)
+{
+ dxWorldProcessMemArena *memarena = callContext->m_stepperArena;
+ unsigned int nb = callContext->m_islandBodiesCount;
+ unsigned int _nj = callContext->m_islandJointsCount;
+
+ dReal *invI = memarena->AllocateOveralignedArray<dReal>((sizeint)nb * IIE__MAX, INVI_ALIGNMENT);
+ dJointWithInfo1 *const jointinfos = memarena->AllocateArray<dJointWithInfo1>(_nj);
+
+ const unsigned allowedThreads = callContext->m_stepperAllowedThreads;
+ dIASSERT(allowedThreads != 0);
+
+ void *stagesMemArenaState = memarena->SaveState();
+
+ dxQuickStepperStage1CallContext *stage1CallContext = (dxQuickStepperStage1CallContext *)memarena->AllocateBlock(sizeof(dxQuickStepperStage1CallContext));
+ stage1CallContext->Initialize(callContext, stagesMemArenaState, invI, jointinfos);
+
+ dxQuickStepperStage0BodiesCallContext *stage0BodiesCallContext = (dxQuickStepperStage0BodiesCallContext *)memarena->AllocateBlock(sizeof(dxQuickStepperStage0BodiesCallContext));
+ stage0BodiesCallContext->Initialize(callContext, invI);
+
+ dxQuickStepperStage0JointsCallContext *stage0JointsCallContext = (dxQuickStepperStage0JointsCallContext *)memarena->AllocateBlock(sizeof(dxQuickStepperStage0JointsCallContext));
+ stage0JointsCallContext->Initialize(callContext, jointinfos, &stage1CallContext->m_stage0Outputs);
+
+ if (allowedThreads == 1)
+ {
+ IFTIMING(dTimerStart("preprocessing"));
+ dxQuickStepIsland_Stage0_Bodies(stage0BodiesCallContext);
+ dxQuickStepIsland_Stage0_Joints(stage0JointsCallContext);
+ dxQuickStepIsland_Stage1(stage1CallContext);
+ }
+ else
+ {
+ unsigned bodyThreads = CalculateOptimalThreadsCount<1U>(nb, allowedThreads);
+ unsigned jointThreads = 1;
+
+ dxWorld *world = callContext->m_world;
+
+ dCallReleaseeID stage1CallReleasee;
+ world->PostThreadedCallForUnawareReleasee(NULL, &stage1CallReleasee, bodyThreads + jointThreads, callContext->m_finalReleasee,
+ NULL, &dxQuickStepIsland_Stage1_Callback, stage1CallContext, 0, "QuickStepIsland Stage1");
+
+ // It is preferable to post single threaded task first to be started sooner
+ world->PostThreadedCall(NULL, NULL, 0, stage1CallReleasee, NULL, &dxQuickStepIsland_Stage0_Joints_Callback, stage0JointsCallContext, 0, "QuickStepIsland Stage0-Joints");
+ dIASSERT(jointThreads == 1);
+
+ if (bodyThreads > 1) {
+ world->PostThreadedCallsGroup(NULL, bodyThreads - 1, stage1CallReleasee, &dxQuickStepIsland_Stage0_Bodies_Callback, stage0BodiesCallContext, "QuickStepIsland Stage0-Bodies");
+ }
+ dxQuickStepIsland_Stage0_Bodies(stage0BodiesCallContext);
+ world->AlterThreadedCallDependenciesCount(stage1CallReleasee, -1);
+ }
+}
+
+static
+int dxQuickStepIsland_Stage0_Bodies_Callback(void *_callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxQuickStepperStage0BodiesCallContext *callContext = (dxQuickStepperStage0BodiesCallContext *)_callContext;
+ dxQuickStepIsland_Stage0_Bodies(callContext);
+ return 1;
+}
+
+static
+void dxQuickStepIsland_Stage0_Bodies(dxQuickStepperStage0BodiesCallContext *callContext)
+{
+ dxBody * const *body = callContext->m_stepperCallContext->m_islandBodiesStart;
+ unsigned int nb = callContext->m_stepperCallContext->m_islandBodiesCount;
+
+ if (ThrsafeExchange(&callContext->m_tagsTaken, 1) == 0)
+ {
+ // number all bodies in the body list - set their tag values
+ for (unsigned int i=0; i<nb; i++) body[i]->tag = i;
+ }
+
+ if (ThrsafeExchange(&callContext->m_gravityTaken, 1) == 0)
+ {
+ dxWorld *world = callContext->m_stepperCallContext->m_world;
+
+ // add the gravity force to all bodies
+ // since gravity does normally have only one component it's more efficient
+ // to run three loops for each individual component
+ dxBody *const *const bodyend = body + nb;
+ dReal gravity_x = world->gravity[0];
+ if (gravity_x) {
+ for (dxBody *const *bodycurr = body; bodycurr != bodyend; bodycurr++) {
+ dxBody *b = *bodycurr;
+ if ((b->flags & dxBodyNoGravity) == 0) {
+ b->facc[0] += b->mass.mass * gravity_x;
+ }
+ }
+ }
+ dReal gravity_y = world->gravity[1];
+ if (gravity_y) {
+ for (dxBody *const *bodycurr = body; bodycurr != bodyend; bodycurr++) {
+ dxBody *b = *bodycurr;
+ if ((b->flags & dxBodyNoGravity) == 0) {
+ b->facc[1] += b->mass.mass * gravity_y;
+ }
+ }
+ }
+ dReal gravity_z = world->gravity[2];
+ if (gravity_z) {
+ for (dxBody *const *bodycurr = body; bodycurr != bodyend; bodycurr++) {
+ dxBody *b = *bodycurr;
+ if ((b->flags & dxBodyNoGravity) == 0) {
+ b->facc[2] += b->mass.mass * gravity_z;
+ }
+ }
+ }
+ }
+
+ // for all bodies, compute the inertia tensor and its inverse in the global
+ // frame, and compute the rotational force and add it to the torque
+ // accumulator. I and invI are a vertical stack of 3x4 matrices, one per body.
+ {
+ dReal *invI = callContext->m_invI;
+ unsigned int bodyIndex;
+ while ((bodyIndex = ThrsafeIncrementIntUpToLimit(&callContext->m_inertiaBodyIndex, nb)) != nb) {
+ dReal *invIrow = invI + (sizeint)bodyIndex * IIE__MAX;
+ dxBody *b = body[bodyIndex];
+
+ dMatrix3 tmp;
+ // compute inverse inertia tensor in global frame
+ dMultiply2_333 (tmp, b->invI, b->posr.R);
+ dMultiply0_333 (invIrow + IIE__MATRIX_MIN, b->posr.R, tmp);
+
+ // Don't apply gyroscopic torques to bodies
+ // if not flagged or the body is kinematic
+ if ((b->flags & dxBodyGyroscopic) && (b->invMass > 0)) {
+ dMatrix3 I;
+ // compute inertia tensor in global frame
+ dMultiply2_333 (tmp, b->mass.I, b->posr.R);
+ dMultiply0_333 (I, b->posr.R, tmp);
+ // compute rotational force
+#if 0
+ // Explicit computation
+ dMultiply0_331 (tmp, I, b->avel);
+ dSubtractVectorCross3(b->tacc, b->avel, tmp);
+#else
+ // Do the implicit computation based on
+ //"Stabilizing Gyroscopic Forces in Rigid Multibody Simulations"
+ // (Lacoursière 2006)
+ dReal h = callContext->m_stepperCallContext->m_stepSize; // Step size
+ dVector3 L; // Compute angular momentum
+ dMultiply0_331(L, I, b->avel);
+
+ // Compute a new effective 'inertia tensor'
+ // for the implicit step: the cross-product
+ // matrix of the angular momentum plus the
+ // old tensor scaled by the timestep.
+ // Itild may not be symmetric pos-definite,
+ // but we can still use it to compute implicit
+ // gyroscopic torques.
+ dMatrix3 Itild = { 0 };
+ dSetCrossMatrixMinus(Itild, L, 4);
+ for (int ii = dM3E__MIN; ii < dM3E__MAX; ++ii) {
+ Itild[ii] = Itild[ii] * h + I[ii];
+ }
+
+ // Scale momentum by inverse time to get
+ // a sort of "torque"
+ dScaleVector3(L, dRecip(h));
+ // Invert the pseudo-tensor
+ dMatrix3 itInv;
+ // This is a closed-form inversion.
+ // It's probably not numerically stable
+ // when dealing with small masses with
+ // a large asymmetry.
+ // An LU decomposition might be better.
+ if (dInvertMatrix3(itInv, Itild) != 0) {
+ // "Divide" the original tensor
+ // by the pseudo-tensor (on the right)
+ dMultiply0_333(Itild, I, itInv);
+ // Subtract an identity matrix
+ Itild[dM3E_XX] -= 1; Itild[dM3E_YY] -= 1; Itild[dM3E_ZZ] -= 1;
+
+ // This new inertia matrix rotates the
+ // momentum to get a new set of torques
+ // that will work correctly when applied
+ // to the old inertia matrix as explicit
+ // torques with a semi-implicit update
+ // step.
+ dVector3 tau0;
+ dMultiply0_331(tau0, Itild, L);
+
+ // Add the gyro torques to the torque
+ // accumulator
+ dAddVectors3(b->tacc, b->tacc, tau0);
+ }
+#endif
+ }
+ }
+ }
+}
+
+static
+int dxQuickStepIsland_Stage0_Joints_Callback(void *_callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxQuickStepperStage0JointsCallContext *callContext = (dxQuickStepperStage0JointsCallContext *)_callContext;
+ dxQuickStepIsland_Stage0_Joints(callContext);
+ return 1;
+}
+
+static
+void dxQuickStepIsland_Stage0_Joints(dxQuickStepperStage0JointsCallContext *callContext)
+{
+ dxJoint * const *_joint = callContext->m_stepperCallContext->m_islandJointsStart;
+ unsigned int _nj = callContext->m_stepperCallContext->m_islandJointsCount;
+
+ // get joint information (m = total constraint dimension, nub = number of unbounded variables).
+ // joints with m=0 are inactive and are removed from the joints array
+ // entirely, so that the code that follows does not consider them.
+ {
+ unsigned int mcurr = 0, mfbcurr = 0;
+ dJointWithInfo1 *jicurr = callContext->m_jointinfos;
+ dxJoint *const *const _jend = _joint + _nj;
+ for (dxJoint *const *_jcurr = _joint; _jcurr != _jend; _jcurr++) { // jicurr=dest, _jcurr=src
+ dxJoint *j = *_jcurr;
+ j->getInfo1 (&jicurr->info);
+ dIASSERT (/*jicurr->info.m >= 0 && */jicurr->info.m <= 6 && /*jicurr->info.nub >= 0 && */jicurr->info.nub <= jicurr->info.m);
+
+ unsigned int jm = jicurr->info.m;
+ if (jm != 0) {
+ mcurr += jm;
+ if (j->feedback != NULL) {
+ mfbcurr += jm;
+ }
+ jicurr->joint = j;
+ jicurr++;
+ }
+ }
+ callContext->m_stage0Outputs->m = mcurr;
+ callContext->m_stage0Outputs->mfb = mfbcurr;
+ callContext->m_stage0Outputs->nj = (unsigned int)(jicurr - callContext->m_jointinfos);
+ dIASSERT((sizeint)(jicurr - callContext->m_jointinfos) < UINT_MAX || (sizeint)(jicurr - callContext->m_jointinfos) == UINT_MAX); // to avoid "...always evaluates to true" warnings
+ }
+}
+
+static
+int dxQuickStepIsland_Stage1_Callback(void *_stage1CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxQuickStepperStage1CallContext *stage1CallContext = (dxQuickStepperStage1CallContext *)_stage1CallContext;
+ dxQuickStepIsland_Stage1(stage1CallContext);
+ return 1;
+}
+
+static
+void dxQuickStepIsland_Stage1(dxQuickStepperStage1CallContext *stage1CallContext)
+{
+ const dxStepperProcessingCallContext *callContext = stage1CallContext->m_stepperCallContext;
+ dReal *invI = stage1CallContext->m_invI;
+ dJointWithInfo1 *jointinfos = stage1CallContext->m_jointinfos;
+ unsigned int nj = stage1CallContext->m_stage0Outputs.nj;
+ unsigned int m = stage1CallContext->m_stage0Outputs.m;
+ unsigned int mfb = stage1CallContext->m_stage0Outputs.mfb;
+
+ dxWorldProcessMemArena *memarena = callContext->m_stepperArena;
+ memarena->RestoreState(stage1CallContext->m_stageMemArenaState);
+ stage1CallContext = NULL; // WARNING! _stage1CallContext is not valid after this point!
+ dIVERIFY(stage1CallContext == NULL); // To suppress unused variable assignment warnings
+
+ {
+ unsigned int _nj = callContext->m_islandJointsCount;
+ memarena->ShrinkArray<dJointWithInfo1>(jointinfos, _nj, nj);
+ }
+
+ dxMIndexItem *mindex = NULL;
+ dxJBodiesItem *jb = NULL;
+ int *findex = NULL;
+ dReal *J = NULL, *Jcopy = NULL;
+
+ // if there are constraints, compute the constraint force
+ if (m > 0) {
+ mindex = memarena->AllocateArray<dxMIndexItem>(nj + 1);
+ {
+ dxMIndexItem *mcurr = mindex;
+ unsigned int moffs = 0, mfboffs = 0;
+ mcurr->mIndex = moffs;
+ mcurr->fbIndex = mfboffs;
+ ++mcurr;
+
+ const dJointWithInfo1 *const jiend = jointinfos + nj;
+ for (const dJointWithInfo1 *jicurr = jointinfos; jicurr != jiend; ++jicurr) {
+ dxJoint *joint = jicurr->joint;
+ moffs += jicurr->info.m;
+ if (joint->feedback) { mfboffs += jicurr->info.m; }
+ mcurr->mIndex = moffs;
+ mcurr->fbIndex = mfboffs;
+ ++mcurr;
+ }
+ }
+
+ jb = memarena->AllocateArray<dxJBodiesItem>(m);
+ findex = memarena->AllocateArray<int>(m);
+ J = memarena->AllocateOveralignedArray<dReal>((sizeint)m * JME__MAX, JACOBIAN_ALIGNMENT);
+ Jcopy = memarena->AllocateOveralignedArray<dReal>((sizeint)mfb * JCE__MAX, JCOPY_ALIGNMENT);
+ }
+
+ dxQuickStepperLocalContext *localContext = (dxQuickStepperLocalContext *)memarena->AllocateBlock(sizeof(dxQuickStepperLocalContext));
+ localContext->Initialize(invI, jointinfos, nj, m, mfb, mindex, jb, findex, J, Jcopy);
+
+ void *stage1MemarenaState = memarena->SaveState();
+ dxQuickStepperStage3CallContext *stage3CallContext = (dxQuickStepperStage3CallContext*)memarena->AllocateBlock(sizeof(dxQuickStepperStage3CallContext));
+ stage3CallContext->Initialize(callContext, localContext, stage1MemarenaState);
+
+ if (m > 0) {
+ unsigned int nb = callContext->m_islandBodiesCount;
+ // create a constraint equation right hand side vector `rhs', a constraint
+ // force mixing vector `cfm', and LCP low and high bound vectors, and an
+ // 'findex' vector.
+ dReal *rhs_tmp = memarena->AllocateArray<dReal>((sizeint)nb * RHS__MAX);
+
+ dxQuickStepperStage2CallContext *stage2CallContext = (dxQuickStepperStage2CallContext*)memarena->AllocateBlock(sizeof(dxQuickStepperStage2CallContext));
+ stage2CallContext->Initialize(callContext, localContext, rhs_tmp);
+
+ const unsigned allowedThreads = callContext->m_stepperAllowedThreads;
+ dIASSERT(allowedThreads != 0);
+
+ if (allowedThreads == 1)
+ {
+ IFTIMING (dTimerNow ("create J"));
+ dxQuickStepIsland_Stage2a(stage2CallContext);
+ IFTIMING (dTimerNow ("compute rhs_tmp"));
+ dxQuickStepIsland_Stage2b(stage2CallContext);
+ dxQuickStepIsland_Stage2c(stage2CallContext);
+ dxQuickStepIsland_Stage3(stage3CallContext);
+ }
+ else
+ {
+ dxWorld *world = callContext->m_world;
+
+ dCallReleaseeID stage3CallReleasee;
+ world->PostThreadedCallForUnawareReleasee(NULL, &stage3CallReleasee, 1, callContext->m_finalReleasee,
+ NULL, &dxQuickStepIsland_Stage3_Callback, stage3CallContext, 0, "QuickStepIsland Stage3");
+
+ dCallReleaseeID stage2bSyncReleasee;
+ world->PostThreadedCall(NULL, &stage2bSyncReleasee, 1, stage3CallReleasee,
+ NULL, &dxQuickStepIsland_Stage2bSync_Callback, stage2CallContext, 0, "QuickStepIsland Stage2b Sync");
+
+ unsigned stage2a_allowedThreads = CalculateOptimalThreadsCount<1U>(nj, allowedThreads);
+
+ dCallReleaseeID stage2aSyncReleasee;
+ world->PostThreadedCall(NULL, &stage2aSyncReleasee, stage2a_allowedThreads, stage2bSyncReleasee,
+ NULL, &dxQuickStepIsland_Stage2aSync_Callback, stage2CallContext, 0, "QuickStepIsland Stage2a Sync");
+
+ if (stage2a_allowedThreads > 1) {
+ world->PostThreadedCallsGroup(NULL, stage2a_allowedThreads - 1, stage2aSyncReleasee, &dxQuickStepIsland_Stage2a_Callback, stage2CallContext, "QuickStepIsland Stage2a");
+ }
+ dxQuickStepIsland_Stage2a(stage2CallContext);
+ world->AlterThreadedCallDependenciesCount(stage2aSyncReleasee, -1);
+ }
+ }
+ else {
+ dxQuickStepIsland_Stage3(stage3CallContext);
+ }
+}
+
+
+static
+int dxQuickStepIsland_Stage2a_Callback(void *_stage2CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxQuickStepperStage2CallContext *stage2CallContext = (dxQuickStepperStage2CallContext *)_stage2CallContext;
+ dxQuickStepIsland_Stage2a(stage2CallContext);
+ return 1;
+}
+
+static
+void dxQuickStepIsland_Stage2a(dxQuickStepperStage2CallContext *stage2CallContext)
+{
+ const dxStepperProcessingCallContext *callContext = stage2CallContext->m_stepperCallContext;
+ dxQuickStepperLocalContext *localContext = stage2CallContext->m_localContext;
+ dJointWithInfo1 *jointinfos = localContext->m_jointinfos;
+ unsigned int nj = localContext->m_nj;
+ const dxMIndexItem *mindex = localContext->m_mindex;
+
+ const dReal stepsizeRecip = dRecip(callContext->m_stepSize);
+ {
+ int *findex = localContext->m_findex;
+ dReal *J = localContext->m_J;
+ dReal *JCopy = localContext->m_Jcopy;
+
+ // get jacobian data from constraints. an m*16 matrix will be created
+ // to store the two jacobian blocks from each constraint. it has this
+ // format:
+ //
+ // l1 l1 l1 a1 a1 a1 rhs cfm l2 l2 l2 a2 a2 a2 lo hi \ .
+ // l1 l1 l1 a1 a1 a1 rhs cfm l2 l2 l2 a2 a2 a2 lo hi }-- jacobian for joint 0, body 1 and body 2 (3 rows)
+ // l1 l1 l1 a1 a1 a1 rhs cfm l2 l2 l2 a2 a2 a2 lo hi /
+ // l1 l1 l1 a1 a1 a1 rhs cfm l2 l2 l2 a2 a2 a2 lo hi }--- jacobian for joint 1, body 1 and body 2 (3 rows)
+ // etc...
+ //
+ // (lll) = linear jacobian data
+ // (aaa) = angular jacobian data
+ //
+ dxWorld *world = callContext->m_world;
+ const dReal worldERP = world->global_erp;
+ const dReal worldCFM = world->global_cfm;
+
+ unsigned validFIndices = 0;
+
+ unsigned ji;
+ while ((ji = ThrsafeIncrementIntUpToLimit(&stage2CallContext->m_ji_J, nj)) != nj) {
+ const unsigned ofsi = mindex[ji].mIndex;
+ const unsigned int infom = mindex[ji + 1].mIndex - ofsi;
+
+ dReal *const JRow = J + (sizeint)ofsi * JME__MAX;
+ {
+ dReal *const JEnd = JRow + infom * JME__MAX;
+ for (dReal *JCurr = JRow; JCurr != JEnd; JCurr += JME__MAX) {
+ dSetZero(JCurr + JME__J1_MIN, JME__J1_COUNT);
+ JCurr[JME_RHS] = REAL(0.0);
+ JCurr[JME_CFM] = worldCFM;
+ dSetZero(JCurr + JME__J2_MIN, JME__J2_COUNT);
+ JCurr[JME_LO] = -dInfinity;
+ JCurr[JME_HI] = dInfinity;
+ dSASSERT(JME__J1_COUNT + 2 + JME__J2_COUNT + 2 == JME__MAX);
+ }
+ }
+ int *findexRow = findex + ofsi;
+ dSetValue(findexRow, infom, -1);
+
+ dxJoint *joint = jointinfos[ji].joint;
+ joint->getInfo2(stepsizeRecip, worldERP, JME__MAX, JRow + JME__J1_MIN, JRow + JME__J2_MIN, JME__MAX, JRow + JME__RHS_CFM_MIN, JRow + JME__LO_HI_MIN, findexRow);
+
+ // findex iteration is compact and is not going to pollute caches - do it first
+ {
+ // adjust returned findex values for global index numbering
+ int *const findicesEnd = findexRow + infom;
+ for (int *findexCurr = findexRow; findexCurr != findicesEnd; ++findexCurr) {
+ int fival = *findexCurr;
+ if (fival != -1) {
+ *findexCurr = fival + ofsi;
+ ++validFIndices;
+ }
+ }
+ }
+ {
+ dReal *const JEnd = JRow + infom * JME__MAX;
+ for (dReal *JCurr = JRow; JCurr != JEnd; JCurr += JME__MAX) {
+ JCurr[JME_RHS] *= stepsizeRecip;
+ JCurr[JME_CFM] *= stepsizeRecip;
+ }
+ }
+ {
+ // we need a copy of Jacobian for joint feedbacks
+ // because it gets destroyed by SOR solver
+ // instead of saving all Jacobian, we can save just rows
+ // for joints, that requested feedback (which is normally much less)
+ unsigned mfbIndex = mindex[ji].fbIndex;
+ if (mfbIndex != mindex[ji + 1].fbIndex) {
+ dReal *const JEnd = JRow + infom * JME__MAX;
+ dReal *JCopyRow = JCopy + mfbIndex * JCE__MAX; // Random access by mfbIndex here! Do not optimize!
+ for (const dReal *JCurr = JRow; ; ) {
+ for (unsigned i = 0; i != JME__J1_COUNT; ++i) { JCopyRow[i + JCE__J1_MIN] = JCurr[i + JME__J1_MIN]; }
+ for (unsigned j = 0; j != JME__J2_COUNT; ++j) { JCopyRow[j + JCE__J2_MIN] = JCurr[j + JME__J2_MIN]; }
+ JCopyRow += JCE__MAX;
+ dSASSERT((unsigned)JCE__J1_COUNT == JME__J1_COUNT);
+ dSASSERT((unsigned)JCE__J2_COUNT == JME__J2_COUNT);
+ dSASSERT(JCE__J1_COUNT + JCE__J2_COUNT == JCE__MAX);
+
+ if ((JCurr += JME__MAX) == JEnd) {
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (validFIndices != 0) {
+ ThrsafeAdd(&localContext->m_valid_findices, validFIndices);
+ }
+ }
+
+ {
+ dxJBodiesItem *jb = localContext->m_jb;
+
+ // create an array of body numbers for each joint row
+ unsigned ji;
+ while ((ji = ThrsafeIncrementIntUpToLimit(&stage2CallContext->m_ji_jb, nj)) != nj) {
+ dxJoint *joint = jointinfos[ji].joint;
+ int b1 = (joint->node[0].body) ? (joint->node[0].body->tag) : -1;
+ int b2 = (joint->node[1].body) ? (joint->node[1].body->tag) : -1;
+
+ dxJBodiesItem *const jb_end = jb + mindex[ji + 1].mIndex;
+ dxJBodiesItem *jb_ptr = jb + mindex[ji].mIndex;
+ for (; jb_ptr != jb_end; ++jb_ptr) {
+ jb_ptr->first = b1;
+ jb_ptr->second = b2;
+ }
+ }
+ }
+}
+
+static
+int dxQuickStepIsland_Stage2aSync_Callback(void *_stage2CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ dxQuickStepperStage2CallContext *stage2CallContext = (dxQuickStepperStage2CallContext *)_stage2CallContext;
+ const dxStepperProcessingCallContext *callContext = stage2CallContext->m_stepperCallContext;
+ const unsigned int nb = callContext->m_islandBodiesCount;
+
+ const unsigned allowedThreads = callContext->m_stepperAllowedThreads;
+ unsigned int stage2b_allowedThreads = CalculateOptimalThreadsCount<dxQUICKSTEPISLAND_STAGE2B_STEP>(nb, allowedThreads);
+
+ if (stage2b_allowedThreads > 1) {
+ dxWorld *world = callContext->m_world;
+ world->AlterThreadedCallDependenciesCount(callThisReleasee, stage2b_allowedThreads - 1);
+ world->PostThreadedCallsGroup(NULL, stage2b_allowedThreads - 1, callThisReleasee, &dxQuickStepIsland_Stage2b_Callback, stage2CallContext, "QuickStepIsland Stage2b");
+ }
+ dxQuickStepIsland_Stage2b(stage2CallContext);
+
+ return 1;
+}
+
+static
+int dxQuickStepIsland_Stage2b_Callback(void *_stage2CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxQuickStepperStage2CallContext *stage2CallContext = (dxQuickStepperStage2CallContext *)_stage2CallContext;
+ dxQuickStepIsland_Stage2b(stage2CallContext);
+ return 1;
+}
+
+static
+void dxQuickStepIsland_Stage2b(dxQuickStepperStage2CallContext *stage2CallContext)
+{
+ const dxStepperProcessingCallContext *callContext = stage2CallContext->m_stepperCallContext;
+ const dxQuickStepperLocalContext *localContext = stage2CallContext->m_localContext;
+
+ const dReal stepsizeRecip = dRecip(callContext->m_stepSize);
+ {
+ // Warning!!!
+ // This code reads facc/tacc fields of body objects which (the fields)
+ // may be modified by dxJoint::getInfo2(). Therefore the code must be
+ // in different sub-stage from Jacobian construction in Stage2a
+ // to ensure proper synchronization and avoid accessing numbers being modified.
+ // Warning!!!
+ dxBody * const *const body = callContext->m_islandBodiesStart;
+ const unsigned int nb = callContext->m_islandBodiesCount;
+ const dReal *invI = localContext->m_invI;
+ dReal *rhs_tmp = stage2CallContext->m_rhs_tmp;
+
+ // compute the right hand side `rhs'
+
+ const unsigned int step_size = dxQUICKSTEPISLAND_STAGE2B_STEP;
+ unsigned int nb_steps = (nb + (step_size - 1)) / step_size;
+
+ // put -(v/h + invM*fe) into rhs_tmp
+ unsigned bi_step;
+ while ((bi_step = ThrsafeIncrementIntUpToLimit(&stage2CallContext->m_bi, nb_steps)) != nb_steps) {
+ unsigned int bi = bi_step * step_size;
+ const unsigned int biend = bi + dMIN(step_size, nb - bi);
+
+ dReal *rhscurr = rhs_tmp + (sizeint)bi * RHS__MAX;
+ const dReal *invIrow = invI + (sizeint)bi * IIE__MAX;
+ while (true) {
+ dxBody *b = body[bi];
+ dReal body_invMass = b->invMass;
+ for (unsigned int j = dSA__MIN; j != dSA__MAX; ++j) rhscurr[RHS__L_MIN + j] = -(b->facc[dV3E__AXES_MIN + j] * body_invMass + b->lvel[dV3E__AXES_MIN + j] * stepsizeRecip);
+ dMultiply0_331 (rhscurr + RHS__A_MIN, invIrow + IIE__MATRIX_MIN, b->tacc);
+ for (unsigned int k = dSA__MIN; k != dSA__MAX; ++k) rhscurr[RHS__A_MIN + k] = -(b->avel[dV3E__AXES_MIN + k] * stepsizeRecip) - rhscurr[RHS__A_MIN + k];
+
+ if (++bi == biend) {
+ break;
+ }
+ rhscurr += RHS__MAX;
+ invIrow += IIE__MAX;
+ }
+ }
+ }
+}
+
+static
+int dxQuickStepIsland_Stage2bSync_Callback(void *_stage2CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ dxQuickStepperStage2CallContext *stage2CallContext = (dxQuickStepperStage2CallContext *)_stage2CallContext;
+ const dxStepperProcessingCallContext *callContext = stage2CallContext->m_stepperCallContext;
+ const unsigned allowedThreads = callContext->m_stepperAllowedThreads;
+
+ const dxQuickStepperLocalContext *localContext = stage2CallContext->m_localContext;
+ unsigned int m = localContext->m_m;
+
+ unsigned int stage2c_allowedThreads = CalculateOptimalThreadsCount<dxQUICKSTEPISLAND_STAGE2C_STEP>(m, allowedThreads);
+
+ if (stage2c_allowedThreads > 1) {
+ dxWorld *world = callContext->m_world;
+ world->AlterThreadedCallDependenciesCount(callThisReleasee, stage2c_allowedThreads - 1);
+ world->PostThreadedCallsGroup(NULL, stage2c_allowedThreads - 1, callThisReleasee, &dxQuickStepIsland_Stage2c_Callback, stage2CallContext, "QuickStepIsland Stage2c");
+ }
+ dxQuickStepIsland_Stage2c(stage2CallContext);
+
+ return 1;
+}
+
+
+static
+int dxQuickStepIsland_Stage2c_Callback(void *_stage2CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxQuickStepperStage2CallContext *stage2CallContext = (dxQuickStepperStage2CallContext *)_stage2CallContext;
+ dxQuickStepIsland_Stage2c(stage2CallContext);
+ return 1;
+}
+
+static
+void dxQuickStepIsland_Stage2c(dxQuickStepperStage2CallContext *stage2CallContext)
+{
+ //const dxStepperProcessingCallContext *callContext = stage2CallContext->m_stepperCallContext;
+ const dxQuickStepperLocalContext *localContext = stage2CallContext->m_localContext;
+
+ //const dReal stepsizeRecip = dRecip(callContext->m_stepSize);
+ {
+ // Warning!!!
+ // This code depends on rhs_tmp and therefore must be in different sub-stage
+ // from rhs_tmp calculation in Stage2b to ensure proper synchronization
+ // and avoid accessing numbers being modified.
+ // Warning!!!
+ dReal *J = localContext->m_J;
+ const dxJBodiesItem *jb = localContext->m_jb;
+ const dReal *rhs_tmp = stage2CallContext->m_rhs_tmp;
+ const unsigned int m = localContext->m_m;
+
+ // add J*rhs_tmp to rhs
+ multiplyAdd_J<dxQUICKSTEPISLAND_STAGE2C_STEP, RHS__DYNAMICS_MIN, RHS__MAX>(&stage2CallContext->m_Jrhsi, m, J, jb, rhs_tmp);
+ }
+}
+
+
+static
+int dxQuickStepIsland_Stage3_Callback(void *_stage3CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxQuickStepperStage3CallContext *stage3CallContext = (dxQuickStepperStage3CallContext *)_stage3CallContext;
+ dxQuickStepIsland_Stage3(stage3CallContext);
+ return 1;
+}
+
+static
+void dxQuickStepIsland_Stage3(dxQuickStepperStage3CallContext *stage3CallContext)
+{
+ const dxStepperProcessingCallContext *callContext = stage3CallContext->m_stepperCallContext;
+ const dxQuickStepperLocalContext *localContext = stage3CallContext->m_localContext;
+
+ dxWorldProcessMemArena *memarena = callContext->m_stepperArena;
+ memarena->RestoreState(stage3CallContext->m_stage1MemArenaState);
+ stage3CallContext = NULL; // WARNING! stage3CallContext is not valid after this point!
+ dIVERIFY(stage3CallContext == NULL); // To suppress unused variable assignment warnings
+
+ void *stage3MemarenaState = memarena->SaveState();
+ dxQuickStepperStage5CallContext *stage5CallContext = (dxQuickStepperStage5CallContext *)memarena->AllocateBlock(sizeof(dxQuickStepperStage5CallContext));
+ stage5CallContext->Initialize(callContext, localContext, stage3MemarenaState);
+
+ unsigned int m = localContext->m_m;
+
+ if (m > 0) {
+ // load lambda from the value saved on the previous iteration
+ dReal *lambda = memarena->AllocateArray<dReal>(m);
+
+ unsigned int nb = callContext->m_islandBodiesCount;
+ dReal *cforce = memarena->AllocateArray<dReal>((sizeint)nb * CFE__MAX);
+ dReal *iMJ = memarena->AllocateOveralignedArray<dReal>((sizeint)m * IMJ__MAX, INVMJ_ALIGNMENT);
+ // order to solve constraint rows in
+ IndexError *order = memarena->AllocateArray<IndexError>(m);
+ dReal *last_lambda = NULL;
+#if CONSTRAINTS_REORDERING_METHOD == REORDERING_METHOD__BY_ERROR
+ // the lambda computed at the previous iteration.
+ // this is used to measure error for when we are reordering the indexes.
+ last_lambda = memarena->AllocateArray<dReal>(m);
+#endif
+
+ const unsigned allowedThreads = callContext->m_stepperAllowedThreads;
+ bool singleThreadedExecution = allowedThreads == 1;
+ dIASSERT(allowedThreads >= 1);
+
+ atomicord32 *bi_links_or_mi_levels = NULL;
+ atomicord32 *mi_links = NULL;
+#if !dTHREADING_INTF_DISABLED
+ bi_links_or_mi_levels = memarena->AllocateArray<atomicord32>(dMAX(nb, m));
+ mi_links = memarena->AllocateArray<atomicord32>(2 * ((sizeint)m + 1));
+#else
+ dIASSERT(singleThreadedExecution);
+#endif
+ dxQuickStepperStage4CallContext *stage4CallContext = (dxQuickStepperStage4CallContext *)memarena->AllocateBlock(sizeof(dxQuickStepperStage4CallContext));
+ stage4CallContext->Initialize(callContext, localContext, lambda, cforce, iMJ, order, last_lambda, bi_links_or_mi_levels, mi_links);
+
+ if (singleThreadedExecution)
+ {
+ dxQuickStepIsland_Stage4a(stage4CallContext);
+
+ IFTIMING (dTimerNow ("solving LCP problem"));
+ dxQuickStepIsland_Stage4LCP_iMJComputation(stage4CallContext);
+ dxQuickStepIsland_Stage4LCP_STfcComputation(stage4CallContext);
+ dxQuickStepIsland_Stage4LCP_AdComputation(stage4CallContext);
+ dxQuickStepIsland_Stage4LCP_ReorderPrep(stage4CallContext);
+
+ dxWorld *world = callContext->m_world;
+ const unsigned int num_iterations = world->qs.num_iterations;
+ for (unsigned int iteration=0; iteration < num_iterations; iteration++) {
+ if (IsSORConstraintsReorderRequiredForIteration(iteration)) {
+ stage4CallContext->ResetSOR_ConstraintsReorderVariables(0);
+ dxQuickStepIsland_Stage4LCP_ConstraintsShuffling(stage4CallContext, iteration);
+ }
+ dxQuickStepIsland_Stage4LCP_STIteration(stage4CallContext);
+ }
+
+ dxQuickStepIsland_Stage4b(stage4CallContext);
+ dxQuickStepIsland_Stage5(stage5CallContext);
+ }
+ else
+ {
+ dxWorld *world = callContext->m_world;
+
+ dCallReleaseeID stage5CallReleasee;
+ world->PostThreadedCallForUnawareReleasee(NULL, &stage5CallReleasee, 1, callContext->m_finalReleasee,
+ NULL, &dxQuickStepIsland_Stage5_Callback, stage5CallContext, 0, "QuickStepIsland Stage5");
+
+ dCallReleaseeID stage4LCP_IterationSyncReleasee;
+ world->PostThreadedCall(NULL, &stage4LCP_IterationSyncReleasee, 1, stage5CallReleasee,
+ NULL, &dxQuickStepIsland_Stage4LCP_IterationSync_Callback, stage4CallContext, 0, "QuickStepIsland Stage4LCP_Iteration Sync");
+
+ unsigned int stage4LCP_Iteration_allowedThreads = CalculateOptimalThreadsCount<1U>(m, allowedThreads);
+ stage4CallContext->AssignLCP_IterationData(stage4LCP_IterationSyncReleasee, stage4LCP_Iteration_allowedThreads);
+
+ dCallReleaseeID stage4LCP_IterationStartReleasee;
+ world->PostThreadedCall(NULL, &stage4LCP_IterationStartReleasee, 3, stage4LCP_IterationSyncReleasee,
+ NULL, &dxQuickStepIsland_Stage4LCP_IterationStart_Callback, stage4CallContext, 0, "QuickStepIsland Stage4LCP_Iteration Start");
+
+ unsigned int nj = localContext->m_nj;
+ unsigned int stage4a_allowedThreads = CalculateOptimalThreadsCount<dxQUICKSTEPISLAND_STAGE4A_STEP>(nj, allowedThreads);
+
+ dCallReleaseeID stage4LCP_fcStartReleasee;
+ // Note: It is unnecessary to make fc dependent on 4a if there is no WARM_STARTING
+ // However I'm doing so to minimize use of preprocessor conditions in sources
+ unsigned stage4LCP_fcDependenciesCountToUse = stage4a_allowedThreads;
+#ifdef WARM_STARTING
+ // Posted with extra dependency to be removed from dxQuickStepIsland_Stage4LCP_iMJSync_Callback
+ stage4LCP_fcDependenciesCountToUse += 1;
+#endif
+ world->PostThreadedCall(NULL, &stage4LCP_fcStartReleasee, stage4LCP_fcDependenciesCountToUse, stage4LCP_IterationStartReleasee,
+ NULL, &dxQuickStepIsland_Stage4LCP_fcStart_Callback, stage4CallContext, 0, "QuickStepIsland Stage4LCP_fc Start");
+#ifdef WARM_STARTING
+ stage4CallContext->AssignLCP_fcStartReleasee(stage4LCP_fcStartReleasee);
+#endif
+
+ unsigned stage4LCP_iMJ_allowedThreads = CalculateOptimalThreadsCount<dxQUICKSTEPISLAND_STAGE4LCP_IMJ_STEP>(m, allowedThreads);
+
+ dCallReleaseeID stage4LCP_iMJSyncReleasee;
+ world->PostThreadedCall(NULL, &stage4LCP_iMJSyncReleasee, stage4LCP_iMJ_allowedThreads, stage4LCP_IterationStartReleasee,
+ NULL, &dxQuickStepIsland_Stage4LCP_iMJSync_Callback, stage4CallContext, 0, "QuickStepIsland Stage4LCP_iMJ Sync");
+
+ world->PostThreadedCall(NULL, NULL, 0, stage4LCP_IterationStartReleasee, NULL, &dxQuickStepIsland_Stage4LCP_ReorderPrep_Callback, stage4CallContext, 0, "QuickStepIsland Stage4LCP_ReorderPrep");
+ world->PostThreadedCallsGroup(NULL, stage4a_allowedThreads, stage4LCP_fcStartReleasee, &dxQuickStepIsland_Stage4a_Callback, stage4CallContext, "QuickStepIsland Stage4a");
+
+ if (stage4LCP_iMJ_allowedThreads > 1) {
+ world->PostThreadedCallsGroup(NULL, stage4LCP_iMJ_allowedThreads - 1, stage4LCP_iMJSyncReleasee, &dxQuickStepIsland_Stage4LCP_iMJ_Callback, stage4CallContext, "QuickStepIsland Stage4LCP_iMJ");
+ }
+ dxQuickStepIsland_Stage4LCP_iMJComputation(stage4CallContext);
+ world->AlterThreadedCallDependenciesCount(stage4LCP_iMJSyncReleasee, -1);
+ }
+ }
+ else {
+ dxQuickStepIsland_Stage5(stage5CallContext);
+ }
+}
+
+static
+int dxQuickStepIsland_Stage4a_Callback(void *_stage4CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxQuickStepperStage4CallContext *stage4CallContext = (dxQuickStepperStage4CallContext *)_stage4CallContext;
+ dxQuickStepIsland_Stage4a(stage4CallContext);
+ return 1;
+}
+
+static
+void dxQuickStepIsland_Stage4a(dxQuickStepperStage4CallContext *stage4CallContext)
+{
+ const dxQuickStepperLocalContext *localContext = stage4CallContext->m_localContext;
+
+ dReal *lambda = stage4CallContext->m_lambda;
+ const dxMIndexItem *mindex = localContext->m_mindex;
+#ifdef WARM_STARTING
+ dJointWithInfo1 *jointinfos = localContext->m_jointinfos;
+#endif
+ unsigned int nj = localContext->m_nj;
+ const unsigned int step_size = dxQUICKSTEPISLAND_STAGE4A_STEP;
+ unsigned int nj_steps = (nj + (step_size - 1)) / step_size;
+
+ unsigned ji_step;
+ while ((ji_step = ThrsafeIncrementIntUpToLimit(&stage4CallContext->m_ji_4a, nj_steps)) != nj_steps) {
+ unsigned int ji = ji_step * step_size;
+ dReal *lambdacurr = lambda + mindex[ji].mIndex;
+#ifdef WARM_STARTING
+ const dJointWithInfo1 *jicurr = jointinfos + ji;
+ const dJointWithInfo1 *const jiend = jicurr + dMIN(step_size, nj - ji);
+
+ do {
+ const dReal *joint_lambdas = jicurr->joint->lambda;
+ dReal *const lambdsnext = lambdacurr + jicurr->info.m;
+
+ while (true) {
+ // for warm starting, multiplication by 0.9 seems to be necessary to prevent
+ // jerkiness in motor-driven joints. I have no idea why this works.
+ *lambdacurr = *joint_lambdas * 0.9;
+
+ if (++lambdacurr == lambdsnext) {
+ break;
+ }
+
+ ++joint_lambdas;
+ }
+ }
+ while (++jicurr != jiend);
+#else
+ dReal *lambdsnext = lambda + mindex[ji + dMIN(step_size, nj - ji)].mIndex;
+ dSetZero(lambdacurr, lambdsnext - lambdacurr);
+#endif
+ }
+}
+
+static
+int dxQuickStepIsland_Stage4LCP_iMJ_Callback(void *_stage4CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxQuickStepperStage4CallContext *stage4CallContext = (dxQuickStepperStage4CallContext *)_stage4CallContext;
+ dxQuickStepIsland_Stage4LCP_iMJComputation(stage4CallContext);
+ return 1;
+}
+
+static
+void dxQuickStepIsland_Stage4LCP_iMJComputation(dxQuickStepperStage4CallContext *stage4CallContext)
+{
+ const dxStepperProcessingCallContext *callContext = stage4CallContext->m_stepperCallContext;
+ const dxQuickStepperLocalContext *localContext = stage4CallContext->m_localContext;
+
+ dReal *iMJ = stage4CallContext->m_iMJ;
+ unsigned int m = localContext->m_m;
+ dReal *J = localContext->m_J;
+ const dxJBodiesItem *jb = localContext->m_jb;
+ dxBody * const *body = callContext->m_islandBodiesStart;
+ dReal *invI = localContext->m_invI;
+
+ // precompute iMJ = inv(M)*J'
+ compute_invM_JT<dxQUICKSTEPISLAND_STAGE4LCP_IMJ_STEP>(&stage4CallContext->m_mi_iMJ, iMJ, m, J, jb, body, invI);
+}
+
+static
+int dxQuickStepIsland_Stage4LCP_iMJSync_Callback(void *_stage4CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ dxQuickStepperStage4CallContext *stage4CallContext = (dxQuickStepperStage4CallContext *)_stage4CallContext;
+ const dxStepperProcessingCallContext *callContext = stage4CallContext->m_stepperCallContext;
+ const dxQuickStepperLocalContext *localContext = stage4CallContext->m_localContext;
+
+ unsigned int m = localContext->m_m;
+ const unsigned allowedThreads = callContext->m_stepperAllowedThreads;
+
+ unsigned int stage4LCP_Ad_allowedThreads = CalculateOptimalThreadsCount<dxQUICKSTEPISLAND_STAGE4LCP_AD_STEP>(m, allowedThreads);
+
+#ifdef WARM_STARTING
+ {
+ dxWorld *world = callContext->m_world;
+ world->AlterThreadedCallDependenciesCount(stage4CallContext->m_LCP_fcStartReleasee, -1);
+ }
+#endif
+
+ if (stage4LCP_Ad_allowedThreads > 1) {
+ dxWorld *world = callContext->m_world;
+ world->AlterThreadedCallDependenciesCount(callThisReleasee, stage4LCP_Ad_allowedThreads - 1);
+ world->PostThreadedCallsGroup(NULL, stage4LCP_Ad_allowedThreads - 1, callThisReleasee, &dxQuickStepIsland_Stage4LCP_Ad_Callback, stage4CallContext, "QuickStepIsland Stage4LCP_Ad");
+ }
+ dxQuickStepIsland_Stage4LCP_AdComputation(stage4CallContext);
+
+ return 1;
+}
+
+static
+int dxQuickStepIsland_Stage4LCP_fcStart_Callback(void *_stage4CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ dxQuickStepperStage4CallContext *stage4CallContext = (dxQuickStepperStage4CallContext *)_stage4CallContext;
+ const dxStepperProcessingCallContext *callContext = stage4CallContext->m_stepperCallContext;
+ const dxQuickStepperLocalContext *localContext = stage4CallContext->m_localContext;
+
+ unsigned int fcPrepareComplexity, fcCompleteComplexity;
+#ifdef WARM_STARTING
+ fcPrepareComplexity = localContext->m_m / dxQUICKSTEPISLAND_STAGE4LCP_FC_COMPLETE_TO_PREPARE_COMPLEXITY_DIVISOR;
+ fcCompleteComplexity = callContext->m_islandBodiesCount;
+#else
+ fcPrepareComplexity = localContext->m_m;
+ fcCompleteComplexity = 0;
+#endif
+ const unsigned allowedThreads = callContext->m_stepperAllowedThreads;
+ unsigned int stage4LCP_fcPrepare_allowedThreads = CalculateOptimalThreadsCount<dxQUICKSTEPISLAND_STAGE4LCP_FC_STEP>(fcPrepareComplexity, allowedThreads);
+ unsigned int stage4LCP_fcComplete_allowedThreads = CalculateOptimalThreadsCount<dxQUICKSTEPISLAND_STAGE4LCP_FC_STEP>(fcCompleteComplexity, allowedThreads);
+ stage4CallContext->AssignLCP_fcAllowedThreads(stage4LCP_fcPrepare_allowedThreads, stage4LCP_fcComplete_allowedThreads);
+
+#ifdef WARM_STARTING
+ dxQuickStepIsland_Stage4LCP_MTfcComputation_warmZeroArrays(stage4CallContext);
+#endif
+
+ if (stage4LCP_fcPrepare_allowedThreads > 1) {
+ dxWorld *world = callContext->m_world;
+ world->AlterThreadedCallDependenciesCount(callThisReleasee, stage4LCP_fcPrepare_allowedThreads - 1);
+ world->PostThreadedCallsGroup(NULL, stage4LCP_fcPrepare_allowedThreads - 1, callThisReleasee, &dxQuickStepIsland_Stage4LCP_fc_Callback, stage4CallContext, "QuickStepIsland Stage4LCP_fc");
+ }
+ dxQuickStepIsland_Stage4LCP_MTfcComputation(stage4CallContext, callThisReleasee);
+
+ return 1;
+}
+
+static
+int dxQuickStepIsland_Stage4LCP_fc_Callback(void *_stage4CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ dxQuickStepperStage4CallContext *stage4CallContext = (dxQuickStepperStage4CallContext *)_stage4CallContext;
+ dxQuickStepIsland_Stage4LCP_MTfcComputation(stage4CallContext, callThisReleasee);
+ return 1;
+}
+
+static
+void dxQuickStepIsland_Stage4LCP_MTfcComputation(dxQuickStepperStage4CallContext *stage4CallContext, dCallReleaseeID callThisReleasee)
+{
+#ifdef WARM_STARTING
+ dxQuickStepIsland_Stage4LCP_MTfcComputation_warm(stage4CallContext, callThisReleasee);
+#else
+ (void)callThisReleasee; // unused
+ dxQuickStepIsland_Stage4LCP_MTfcComputation_cold(stage4CallContext);
+#endif
+}
+
+#ifdef WARM_STARTING
+
+static
+void dxQuickStepIsland_Stage4LCP_MTfcComputation_warm(dxQuickStepperStage4CallContext *stage4CallContext, dCallReleaseeID callThisReleasee)
+{
+ dxQuickStepIsland_Stage4LCP_MTfcComputation_warmPrepare(stage4CallContext);
+
+ if (ThrsafeExchangeAdd(&stage4CallContext->m_LCP_fcPrepareThreadsRemaining, (atomicord32)(-1)) == 1) {
+ stage4CallContext->ResetLCP_fcComputationIndex();
+
+ const dxStepperProcessingCallContext *callContext = stage4CallContext->m_stepperCallContext;
+ unsigned int stage4LCP_fcComplete_allowedThreads = stage4CallContext->m_LCP_fcCompleteThreadsTotal;
+
+ if (stage4LCP_fcComplete_allowedThreads > 1) {
+ dxWorld *world = callContext->m_world;
+ world->AlterThreadedCallDependenciesCount(callThisReleasee, stage4LCP_fcComplete_allowedThreads - 1);
+ world->PostThreadedCallsGroup(NULL, stage4LCP_fcComplete_allowedThreads - 1, callThisReleasee, &dxQuickStepIsland_Stage4LCP_fcWarmComplete_Callback, stage4CallContext, "QuickStepIsland Stage4LCP_fcWarmComplete");
+ }
+ dxQuickStepIsland_Stage4LCP_MTfcComputation_warmComplete(stage4CallContext);
+ }
+}
+
+static
+void dxQuickStepIsland_Stage4LCP_MTfcComputation_warmZeroArrays(dxQuickStepperStage4CallContext *stage4CallContext)
+{
+ const dxStepperProcessingCallContext *callContext = stage4CallContext->m_stepperCallContext;
+
+ unsigned int nb = callContext->m_islandBodiesCount;
+ atomicord32 *bi_links = stage4CallContext->m_bi_links_or_mi_levels;
+
+ multiply_invM_JT_init_array(nb, bi_links);
+}
+
+static
+void dxQuickStepIsland_Stage4LCP_MTfcComputation_warmPrepare(dxQuickStepperStage4CallContext *stage4CallContext)
+{
+ const dxStepperProcessingCallContext *callContext = stage4CallContext->m_stepperCallContext;
+ const dxQuickStepperLocalContext *localContext = stage4CallContext->m_localContext;
+
+ unsigned int m = localContext->m_m;
+ const dxJBodiesItem *jb = localContext->m_jb;
+
+ // Prepare to compute fc=(inv(M)*J')*lambda. we will incrementally maintain fc
+ // as we change lambda.
+ multiply_invM_JT_prepare<dxQUICKSTEPISLAND_STAGE4LCP_FC_STEP_PREPARE>(&stage4CallContext->m_mi_fc, m, jb, stage4CallContext->m_bi_links_or_mi_levels, stage4CallContext->m_mi_links);
+}
+
+static
+int dxQuickStepIsland_Stage4LCP_fcWarmComplete_Callback(void *_stage4CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxQuickStepperStage4CallContext *stage4CallContext = (dxQuickStepperStage4CallContext *)_stage4CallContext;
+
+ dxQuickStepIsland_Stage4LCP_MTfcComputation_warmComplete(stage4CallContext);
+
+ return 1;
+}
+
+static
+void dxQuickStepIsland_Stage4LCP_MTfcComputation_warmComplete(dxQuickStepperStage4CallContext *stage4CallContext)
+{
+ const dxStepperProcessingCallContext *callContext = stage4CallContext->m_stepperCallContext;
+ const dxQuickStepperLocalContext *localContext = stage4CallContext->m_localContext;
+
+ dReal *fc = stage4CallContext->m_cforce;
+ unsigned int nb = callContext->m_islandBodiesCount;
+ dReal *iMJ = stage4CallContext->m_iMJ;
+ const dxJBodiesItem *jb = localContext->m_jb;
+ dReal *lambda = stage4CallContext->m_lambda;
+
+ // Complete computation of fc=(inv(M)*J')*lambda. we will incrementally maintain fc
+ // as we change lambda.
+ multiply_invM_JT_complete<dxQUICKSTEPISLAND_STAGE4LCP_FC_STEP_COMPLETE, CFE__DYNAMICS_MIN, CFE__MAX>(&stage4CallContext->m_mi_fc, fc, nb, iMJ, jb, lambda, stage4CallContext->m_bi_links_or_mi_levels, stage4CallContext->m_mi_links);
+}
+
+#else // #ifndef WARM_STARTING
+
+static
+void dxQuickStepIsland_Stage4LCP_MTfcComputation_cold(dxQuickStepperStage4CallContext *stage4CallContext)
+{
+ const dxStepperProcessingCallContext *callContext = stage4CallContext->m_stepperCallContext;
+
+ dReal *fc = stage4CallContext->m_cforce;
+ unsigned int nb = callContext->m_islandBodiesCount;
+ const unsigned int step_size = dxQUICKSTEPISLAND_STAGE4LCP_FC_STEP;
+ unsigned int nb_steps = (nb + (step_size - 1)) / step_size;
+
+ unsigned bi_step;
+ while ((bi_step = ThrsafeIncrementIntUpToLimit(&stage4CallContext->m_mi_fc, nb_steps)) != nb_steps) {
+ unsigned int bi = bi_step * step_size;
+ unsigned int bicnt = dMIN(step_size, nb - bi);
+ dSetZero(fc + (sizeint)bi * CFE__MAX, (sizeint)bicnt * CFE__MAX);
+ }
+}
+
+#endif // #ifndef WARM_STARTING
+
+
+static
+void dxQuickStepIsland_Stage4LCP_STfcComputation(dxQuickStepperStage4CallContext *stage4CallContext)
+{
+#ifdef WARM_STARTING
+ const dxStepperProcessingCallContext *callContext = stage4CallContext->m_stepperCallContext;
+ const dxQuickStepperLocalContext *localContext = stage4CallContext->m_localContext;
+
+ dReal *fc = stage4CallContext->m_cforce;
+ unsigned int m = localContext->m_m;
+ unsigned int nb = callContext->m_islandBodiesCount;
+ dReal *iMJ = stage4CallContext->m_iMJ;
+ const dxJBodiesItem *jb = localContext->m_jb;
+ dReal *lambda = stage4CallContext->m_lambda;
+
+ // compute fc=(inv(M)*J')*lambda. we will incrementally maintain fc
+ // as we change lambda.
+ _multiply_invM_JT<CFE__DYNAMICS_MIN, CFE__MAX>(fc, m, nb, iMJ, jb, lambda);
+#else
+ dReal *fc = stage4CallContext->m_cforce;
+ const dxStepperProcessingCallContext *callContext = stage4CallContext->m_stepperCallContext;
+ unsigned int nb = callContext->m_islandBodiesCount;
+
+ dSetZero(fc, (sizeint)nb * CFE__MAX);
+#endif
+
+}
+
+static
+int dxQuickStepIsland_Stage4LCP_Ad_Callback(void *_stage4CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxQuickStepperStage4CallContext *stage4CallContext = (dxQuickStepperStage4CallContext *)_stage4CallContext;
+ dxQuickStepIsland_Stage4LCP_AdComputation(stage4CallContext);
+ return 1;
+}
+
+static
+void dxQuickStepIsland_Stage4LCP_AdComputation(dxQuickStepperStage4CallContext *stage4CallContext)
+{
+ const dxStepperProcessingCallContext *callContext = stage4CallContext->m_stepperCallContext;
+ const dxQuickStepperLocalContext *localContext = stage4CallContext->m_localContext;
+
+ const dxJBodiesItem *jb = localContext->m_jb;
+ dReal *J = localContext->m_J;
+ unsigned int m = localContext->m_m;
+
+ dxWorld *world = callContext->m_world;
+ dxQuickStepParameters *qs = &world->qs;
+ const dReal sor_w = qs->w; // SOR over-relaxation parameter
+
+ dReal *iMJ = stage4CallContext->m_iMJ;
+
+ const unsigned int step_size = dxQUICKSTEPISLAND_STAGE4LCP_AD_STEP;
+ unsigned int m_steps = (m + (step_size - 1)) / step_size;
+
+ unsigned mi_step;
+ while ((mi_step = ThrsafeIncrementIntUpToLimit(&stage4CallContext->m_mi_Ad, m_steps)) != m_steps) {
+ unsigned int mi = mi_step * step_size;
+ const unsigned int miend = mi + dMIN(step_size, m - mi);
+
+ const dReal *iMJ_ptr = iMJ + (sizeint)mi * IMJ__MAX;
+ dReal *J_ptr = J + (sizeint)mi * JME__MAX;
+ while (true) {
+ dReal sum = REAL(0.0);
+ {
+ for (unsigned int j = JVE__MIN; j != JVE__MAX; ++j) sum += iMJ_ptr[IMJ__1_MIN + j] * J_ptr[JME__J1_MIN + j];
+ dSASSERT(JME__J1_COUNT == (int)JVE__MAX);
+ }
+
+ int b2 = jb[mi].second;
+ if (b2 != -1) {
+ for (unsigned int k = JVE__MIN; k != JVE__MAX; ++k) sum += iMJ_ptr[IMJ__2_MIN + k] * J_ptr[JME__J2_MIN + k];
+ dSASSERT(JME__J2_COUNT == (int)JVE__MAX);
+ }
+
+ dReal cfm_i = J_ptr[JME_CFM];
+ dReal Ad_i = sor_w / (sum + cfm_i);
+
+ // NOTE: This may seem unnecessary but it's indeed an optimization
+ // to move multiplication by Ad[i] and cfm[i] out of iteration loop.
+
+ // scale cfm, J and b by Ad
+ J_ptr[JME_CFM] = cfm_i * Ad_i;
+ J_ptr[JME_RHS] *= Ad_i;
+
+ {
+ for (unsigned int j = JVE__MIN; j != JVE__MAX; ++j) J_ptr[JME__J1_MIN + j] *= Ad_i;
+ dSASSERT(JME__J1_COUNT == (int)JVE__MAX);
+ }
+
+ if (b2 != -1) {
+ for (unsigned int k = JVE__MIN; k != JVE__MAX; ++k) J_ptr[JME__J2_MIN + k] *= Ad_i;
+ dSASSERT(JME__J2_COUNT == (int)JVE__MAX);
+ }
+
+ if (++mi == miend) {
+ break;
+ }
+ iMJ_ptr += IMJ__MAX;
+ J_ptr += JME__MAX;
+ }
+ }
+}
+
+static
+int dxQuickStepIsland_Stage4LCP_ReorderPrep_Callback(void *_stage4CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxQuickStepperStage4CallContext *stage4CallContext = (dxQuickStepperStage4CallContext *)_stage4CallContext;
+ dxQuickStepIsland_Stage4LCP_ReorderPrep(stage4CallContext);
+ return 1;
+}
+
+static
+void dxQuickStepIsland_Stage4LCP_ReorderPrep(dxQuickStepperStage4CallContext *stage4CallContext)
+{
+ const dxQuickStepperLocalContext *localContext = stage4CallContext->m_localContext;
+ unsigned int m = localContext->m_m;
+ unsigned int valid_findices = localContext->m_valid_findices;
+
+ IndexError *order = stage4CallContext->m_order;
+
+ {
+ // make sure constraints with findex < 0 come first.
+ IndexError *orderhead = order, *ordertail = order + (m - valid_findices);
+ const int *findex = localContext->m_findex;
+
+ // Fill the array from both ends
+ for (unsigned int i = 0; i != m; ++i) {
+ if (findex[i] == -1) {
+ orderhead->index = i; // Place them at the front
+ ++orderhead;
+ } else {
+ ordertail->index = i; // Place them at the end
+ ++ordertail;
+ }
+ }
+ dIASSERT(orderhead == order + (m - valid_findices));
+ dIASSERT(ordertail == order + m);
+ }
+}
+
+static
+int dxQuickStepIsland_Stage4LCP_IterationStart_Callback(void *_stage4CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxQuickStepperStage4CallContext *stage4CallContext = (dxQuickStepperStage4CallContext *)_stage4CallContext;
+ const dxStepperProcessingCallContext *callContext = stage4CallContext->m_stepperCallContext;
+
+ dxWorld *world = callContext->m_world;
+ dxQuickStepParameters *qs = &world->qs;
+
+ const unsigned int num_iterations = qs->num_iterations;
+ unsigned iteration = stage4CallContext->m_LCP_iteration;
+
+ if (iteration < num_iterations)
+ {
+ dCallReleaseeID nextReleasee;
+ dCallReleaseeID stage4LCP_IterationSyncReleasee = stage4CallContext->m_LCP_IterationSyncReleasee;
+ unsigned int stage4LCP_Iteration_allowedThreads = stage4CallContext->m_LCP_IterationAllowedThreads;
+
+ bool reorderRequired = false;
+
+ if (IsSORConstraintsReorderRequiredForIteration(iteration))
+ {
+ reorderRequired = true;
+ }
+
+ unsigned syncCallDependencies = reorderRequired ? 1 : stage4LCP_Iteration_allowedThreads;
+
+ // Increment iterations counter in advance as anyway it needs to be incremented
+ // before independent tasks (the reordering or the iteration) are posted
+ // (otherwise next iteration may complete before the increment
+ // and the same iteration index may be used again).
+ stage4CallContext->m_LCP_iteration = iteration + 1;
+
+ if (iteration + 1 != num_iterations) {
+ dCallReleaseeID stage4LCP_IterationStartReleasee;
+ world->PostThreadedCallForUnawareReleasee(NULL, &stage4LCP_IterationStartReleasee, syncCallDependencies, stage4LCP_IterationSyncReleasee,
+ NULL, &dxQuickStepIsland_Stage4LCP_IterationStart_Callback, stage4CallContext, 0, "QuickStepIsland Stage4LCP_Iteration Start");
+ nextReleasee = stage4LCP_IterationStartReleasee;
+ }
+ else {
+ world->AlterThreadedCallDependenciesCount(stage4LCP_IterationSyncReleasee, syncCallDependencies);
+ nextReleasee = stage4LCP_IterationSyncReleasee;
+ }
+
+ if (reorderRequired) {
+ const unsigned int reorderThreads = 2;
+ dIASSERT(callContext->m_stepperAllowedThreads >= 2); // Otherwise the single-threaded execution path would be taken
+
+ stage4CallContext->ResetSOR_ConstraintsReorderVariables(reorderThreads);
+
+ dCallReleaseeID stage4LCP_ConstraintsReorderingSyncReleasee;
+ world->PostThreadedCall(NULL, &stage4LCP_ConstraintsReorderingSyncReleasee, reorderThreads, nextReleasee,
+ NULL, &dxQuickStepIsland_Stage4LCP_ConstraintsReorderingSync_Callback, stage4CallContext, 0, "QuickStepIsland Stage4LCP_ConstraintsReordering Sync");
+
+ if (reorderThreads > 1) {
+ world->PostThreadedCallsGroup(NULL, reorderThreads - 1, stage4LCP_ConstraintsReorderingSyncReleasee, &dxQuickStepIsland_Stage4LCP_ConstraintsReordering_Callback, stage4CallContext, "QuickStepIsland Stage4LCP_ConstraintsReordering");
+ }
+ dxQuickStepIsland_Stage4LCP_ConstraintsReordering(stage4CallContext);
+ world->AlterThreadedCallDependenciesCount(stage4LCP_ConstraintsReorderingSyncReleasee, -1);
+ }
+ else {
+ dIASSERT(iteration != 0); {
+ dxQuickStepIsland_Stage4LCP_DependencyMapFromSavedLevelsReconstruction(stage4CallContext);
+ }
+
+ stage4CallContext->RecordLCP_IterationStart(stage4LCP_Iteration_allowedThreads, nextReleasee);
+
+ unsigned knownToBeCompletedLevel = dxHEAD_INDEX;
+ if (stage4LCP_Iteration_allowedThreads > 1) {
+ world->PostThreadedCallsIndexOverridenGroup(NULL, stage4LCP_Iteration_allowedThreads - 1, nextReleasee, &dxQuickStepIsland_Stage4LCP_Iteration_Callback, stage4CallContext, knownToBeCompletedLevel, "QuickStepIsland Stage4LCP_Iteration");
+ }
+ dxQuickStepIsland_Stage4LCP_MTIteration(stage4CallContext, knownToBeCompletedLevel);
+ world->AlterThreadedCallDependenciesCount(nextReleasee, -1);
+ }
+ }
+
+ return 1;
+}
+
+static
+int dxQuickStepIsland_Stage4LCP_ConstraintsReordering_Callback(void *_stage4CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxQuickStepperStage4CallContext *stage4CallContext = (dxQuickStepperStage4CallContext *)_stage4CallContext;
+ dxQuickStepIsland_Stage4LCP_ConstraintsReordering(stage4CallContext);
+ return 1;
+}
+
+static
+void dxQuickStepIsland_Stage4LCP_ConstraintsReordering(dxQuickStepperStage4CallContext *stage4CallContext)
+{
+ unsigned int iteration = stage4CallContext->m_LCP_iteration - 1; // Iteration is pre-incremented before scheduled tasks are released for execution
+ if (dxQuickStepIsland_Stage4LCP_ConstraintsShuffling(stage4CallContext, iteration)) {
+
+ dxQuickStepIsland_Stage4LCP_LinksArraysZeroing(stage4CallContext);
+ if (ThrsafeExchangeAdd(&stage4CallContext->m_SOR_reorderThreadsRemaining, (atomicord32)(-1)) == 1) { // If last thread has exited the reordering routine...
+ // Rebuild the object dependency map
+ dxQuickStepIsland_Stage4LCP_DependencyMapForNewOrderRebuilding(stage4CallContext);
+ }
+ }
+ else {
+ // NOTE: So far, this branch is only called in CONSTRAINTS_REORDERING_METHOD == REORDERING_METHOD__BY_ERROR case
+ if (ThrsafeExchangeAdd(&stage4CallContext->m_SOR_reorderThreadsRemaining, (atomicord32)(-1)) == 1) { // If last thread has exited the reordering routine...
+ dIASSERT(iteration != 0);
+ dxQuickStepIsland_Stage4LCP_DependencyMapFromSavedLevelsReconstruction(stage4CallContext);
+ }
+ }
+}
+
+static
+bool dxQuickStepIsland_Stage4LCP_ConstraintsShuffling(dxQuickStepperStage4CallContext *stage4CallContext, unsigned int iteration)
+{
+ bool result = false;
+
+#if CONSTRAINTS_REORDERING_METHOD == REORDERING_METHOD__BY_ERROR
+
+ struct ConstraintsReorderingHelper
+ {
+ void operator ()(dxQuickStepperStage4CallContext *stage4CallContext, unsigned int startIndex, unsigned int endIndex)
+ {
+ const dReal *lambda = stage4CallContext->m_lambda;
+ dReal *last_lambda = stage4CallContext->m_last_lambda;
+ IndexError *order = stage4CallContext->m_order;
+
+ for (unsigned int index = startIndex; index != endIndex; ++index) {
+ unsigned int i = order[index].index;
+ dReal lambda_i = lambda[i];
+ if (lambda_i != REAL(0.0)) {
+ //@@@ relative error: order[i].error = dFabs(lambda[i]-last_lambda[i])/max;
+ order[index].error = dFabs(lambda_i - last_lambda[i]);
+ }
+ else if (last_lambda[i] != REAL(0.0)) {
+ //@@@ relative error: order[i].error = dFabs(lambda[i]-last_lambda[i])/max;
+ order[index].error = dFabs(/*lambda_i - */last_lambda[i]); // lambda_i == 0
+ }
+ else {
+ order[index].error = dInfinity;
+ }
+ // Finally copy the lambda for the next iteration
+ last_lambda[i] = lambda_i;
+ }
+ qsort (order + startIndex, endIndex - startIndex, sizeof(IndexError), &compare_index_error);
+ }
+ };
+
+ if (iteration > 1) { // Only reorder starting from iteration #2
+ // sort the constraints so that the ones converging slowest
+ // get solved last. use the absolute (not relative) error.
+ /*
+ * Full reorder needs to be done.
+ * Even though this contradicts the initial idea of moving dependent constraints
+ * to the order end the algorithm does not work the other way well.
+ * It looks like the iterative method needs a shake after it already found
+ * some initial approximations and those incurred errors help it to converge even better.
+ */
+ if (ThrsafeExchange(&stage4CallContext->m_SOR_reorderHeadTaken, 1) == 0) {
+ // Process the head
+ const dxQuickStepperLocalContext *localContext = stage4CallContext->m_localContext;
+ ConstraintsReorderingHelper()(stage4CallContext, 0, localContext->m_m);
+ }
+
+ result = true;
+ }
+ else if (iteration == 1) {
+ if (ThrsafeExchange(&stage4CallContext->m_SOR_reorderHeadTaken, 1) == 0) {
+ // Process the first half
+ const dxQuickStepperLocalContext *localContext = stage4CallContext->m_localContext;
+ unsigned int startIndex = 0;
+ unsigned int indicesCount = localContext->m_m / 2;
+ // Just copy the lambdas for the next iteration
+ memcpy(stage4CallContext->m_last_lambda + startIndex, stage4CallContext->m_lambda + startIndex, indicesCount * sizeof(dReal));
+ }
+
+ if (ThrsafeExchange(&stage4CallContext->m_SOR_reorderTailTaken, 1) == 0) {
+ // Process the second half
+ const dxQuickStepperLocalContext *localContext = stage4CallContext->m_localContext;
+ unsigned int startIndex = localContext->m_m / 2;
+ unsigned int indicesCount = localContext->m_m - startIndex;
+ // Just copy the lambdas for the next iteration
+ memcpy(stage4CallContext->m_last_lambda + startIndex, stage4CallContext->m_lambda + startIndex, indicesCount * sizeof(dReal));
+ }
+
+ // result = false; -- already 'false'
+ }
+ else /*if (iteration < 1) */{
+ result = true; // return true on 0th iteration to build dependency map for the initial order
+ }
+
+
+#elif CONSTRAINTS_REORDERING_METHOD == REORDERING_METHOD__RANDOMLY
+
+ if (iteration != 0) {
+ dIASSERT(!dIN_RANGE(iteration, 0, RANDOM_CONSTRAINTS_REORDERING_FREQUENCY));
+
+ dIASSERT(iteration % RANDOM_CONSTRAINTS_REORDERING_FREQUENCY == RRS_REORDERING); {
+ struct ConstraintsReorderingHelper
+ {
+ void operator ()(dxQuickStepperStage4CallContext *stage4CallContext, unsigned int startIndex, unsigned int indicesCount)
+ {
+ IndexError *order = stage4CallContext->m_order + startIndex;
+
+ for (unsigned int index = 1; index < indicesCount; ++index) {
+ int swapIndex = dRandInt(index + 1);
+ IndexError tmp = order[index];
+ order[index] = order[swapIndex];
+ order[swapIndex] = tmp;
+ }
+ }
+ };
+
+ /*
+ * Full reorder needs to be done.
+ * Even though this contradicts the initial idea of moving dependent constraints
+ * to the order end the algorithm does not work the other way well.
+ * It looks like the iterative method needs a shake after it already found
+ * some initial approximations and those incurred errors help it to converge even better.
+ */
+ if (ThrsafeExchange(&stage4CallContext->m_SOR_reorderHeadTaken, 1) == 0) {
+ // Process the head
+ const dxQuickStepperLocalContext *localContext = stage4CallContext->m_localContext;
+ ConstraintsReorderingHelper()(stage4CallContext, 0, localContext->m_m);
+ }
+ }
+ dIASSERT((RRS__MAX, true)); // A reference to RRS__MAX to be located by Find in Files
+ }
+ else {
+ // Just return true and skip the randomization for the very first iteration
+ }
+
+ result = true;
+
+#else // #if CONSTRAINTS_REORDERING_METHOD != REORDERING_METHOD__BY_ERROR && CONSTRAINTS_REORDERING_METHOD != REORDERING_METHOD__RANDOMLY
+
+ dIASSERT(iteration == 0); // The reordering request is only returned for the first iteration
+ result = true;
+
+
+#endif
+
+ return result;
+}
+
+static
+void dxQuickStepIsland_Stage4LCP_LinksArraysZeroing(dxQuickStepperStage4CallContext *stage4CallContext)
+{
+ const dxStepperProcessingCallContext *callContext = stage4CallContext->m_stepperCallContext;
+ const dxQuickStepperLocalContext *localContext = stage4CallContext->m_localContext;
+
+ if (ThrsafeExchange(&stage4CallContext->m_SOR_bi_zeroHeadTaken, 1) == 0) {
+ atomicord32 *bi_links = stage4CallContext->m_bi_links_or_mi_levels;/*=[nb]*/
+ unsigned int nb = callContext->m_islandBodiesCount;
+ memset(bi_links, 0, sizeof(bi_links[0]) * (nb / 2));
+ }
+ if (ThrsafeExchange(&stage4CallContext->m_SOR_bi_zeroTailTaken, 1) == 0) {
+ atomicord32 *bi_links = stage4CallContext->m_bi_links_or_mi_levels;/*=[nb]*/
+ unsigned int nb = callContext->m_islandBodiesCount;
+ memset(bi_links + nb / 2, 0, sizeof(bi_links[0]) * (nb - nb / 2));
+ }
+
+ if (ThrsafeExchange(&stage4CallContext->m_SOR_mi_zeroHeadTaken, 1) == 0) {
+ atomicord32 *mi_links = stage4CallContext->m_mi_links;/*=[2*(m + 1)]*/
+ unsigned int m = localContext->m_m;
+ memset(mi_links, 0, sizeof(mi_links[0]) * (m + 1));
+ }
+ if (ThrsafeExchange(&stage4CallContext->m_SOR_mi_zeroTailTaken, 1) == 0) {
+ atomicord32 *mi_links = stage4CallContext->m_mi_links;/*=[2*(m + 1)]*/
+ unsigned int m = localContext->m_m;
+ memset(mi_links + (m + 1), 0, sizeof(mi_links[0]) * (m + 1));
+ }
+}
+
+static
+void dxQuickStepIsland_Stage4LCP_DependencyMapForNewOrderRebuilding(dxQuickStepperStage4CallContext *stage4CallContext)
+{
+ const dxQuickStepperLocalContext *localContext = stage4CallContext->m_localContext;
+
+ atomicord32 *bi_links = stage4CallContext->m_bi_links_or_mi_levels;/*=[nb]*/
+ atomicord32 *mi_links = stage4CallContext->m_mi_links;/*=[2*(m + 1)]*/
+
+ IndexError *order = stage4CallContext->m_order;
+ const dxJBodiesItem *jb = localContext->m_jb;
+
+ unsigned int m = localContext->m_m;
+ for (unsigned int i = 0; i != m; ++i) {
+ unsigned int index = order[i].index;
+
+ int b1 = jb[index].first;
+ int b2 = jb[index].second;
+
+ unsigned int encioded_i = dxENCODE_INDEX(i);
+
+ unsigned int encoded_depi = bi_links[(unsigned int)b1];
+ bi_links[(unsigned int)b1] = encioded_i;
+
+ if (b2 != -1 && b2 != b1) {
+ if (encoded_depi < (unsigned int)bi_links[(unsigned int)b2]) {
+ encoded_depi = bi_links[(unsigned int)b2];
+ }
+ bi_links[(unsigned int)b2] = encioded_i;
+ }
+
+ // OD: There is also a dependency on findex[index],
+ // however the findex can only refer to the rows of the same joint
+ // and hence that index is going to have the same bodies. Since the
+ // indices are sorted in a way that the meaningful findex values
+ // always come last, the dependency of findex[index] is going to
+ // be implicitly satisfied via matching bodies at smaller "i"s.
+
+ // Check that the dependency targets an earlier "i"
+ dIASSERT(encoded_depi < encioded_i);
+
+ unsigned encoded_downi = mi_links[(sizeint)encoded_depi * 2 + 1];
+ mi_links[(sizeint)encoded_depi * 2 + 1] = encioded_i; // Link i as down-dependency for depi
+ mi_links[(sizeint)encioded_i * 2 + 0] = encoded_downi; // Link previous down-chain as the level-dependency with i
+ }
+}
+
+static
+void dxQuickStepIsland_Stage4LCP_DependencyMapFromSavedLevelsReconstruction(dxQuickStepperStage4CallContext *stage4CallContext)
+{
+ const dxQuickStepperLocalContext *localContext = stage4CallContext->m_localContext;
+
+ atomicord32 *mi_levels = stage4CallContext->m_bi_links_or_mi_levels;/*=[m]*/
+ atomicord32 *mi_links = stage4CallContext->m_mi_links;/*=[2*(m + 1)]*/
+
+ // NOTE!
+ // OD: The mi_links array is not zero-filled before the reconstruction.
+ // Iteration ends with all the down links zeroed. And since down links
+ // are moved to the next level links when parent-child relations are established,
+ // the horizontal levels are properly terminated.
+ // The leaf nodes had their links zero-initialized initially
+ // and those zeros remain intact during the solving. This way the down links
+ // are properly terminated as well.
+ // This is very obscure and error prone and would need an assertion check at least
+ // but the simplest assertion approach I can imagine would be
+ // zero filling and building another tree with the memory buffer comparison afterwards.
+ // That would be stupid, obviously.
+ //
+ // NOTE!
+ // OD: This routine can be threaded. However having two threads messing
+ // in one integer array with random access and kicking each other memory lines
+ // out of cache would probably work worse than letting a single thread do the whole job.
+ unsigned int m = localContext->m_m;
+ for (unsigned int i = 0; i != m; ++i) {
+ unsigned int currentLevelRoot = mi_levels[i];
+ unsigned int currentLevelFirstLink = mi_links[2 * (sizeint)currentLevelRoot + 1];
+ unsigned int encoded_i = dxENCODE_INDEX(i);
+ mi_links[2 * (sizeint)currentLevelRoot + 1] = encoded_i;
+ mi_links[2 * (sizeint)encoded_i + 0] = currentLevelFirstLink;
+ }
+
+ // Additionally reset available level root's list head
+ mi_links[2 * dxHEAD_INDEX + 0] = dxHEAD_INDEX;
+}
+
+static
+int dxQuickStepIsland_Stage4LCP_ConstraintsReorderingSync_Callback(void *_stage4CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxQuickStepperStage4CallContext *stage4CallContext = (dxQuickStepperStage4CallContext *)_stage4CallContext;
+ const dxStepperProcessingCallContext *callContext = stage4CallContext->m_stepperCallContext;
+ unsigned int stage4LCP_Iteration_allowedThreads = stage4CallContext->m_LCP_IterationAllowedThreads;
+
+ stage4CallContext->RecordLCP_IterationStart(stage4LCP_Iteration_allowedThreads, callThisReleasee);
+
+ unsigned knownToBeCompletedLevel = dxHEAD_INDEX;
+ if (stage4LCP_Iteration_allowedThreads > 1) {
+ dxWorld *world = callContext->m_world;
+ world->AlterThreadedCallDependenciesCount(callThisReleasee, stage4LCP_Iteration_allowedThreads - 1);
+ world->PostThreadedCallsIndexOverridenGroup(NULL, stage4LCP_Iteration_allowedThreads - 1, callThisReleasee, &dxQuickStepIsland_Stage4LCP_Iteration_Callback, stage4CallContext, knownToBeCompletedLevel, "QuickStepIsland Stage4LCP_Iteration");
+ }
+ dxQuickStepIsland_Stage4LCP_MTIteration(stage4CallContext, knownToBeCompletedLevel);
+
+ return 1;
+}
+
+static
+int dxQuickStepIsland_Stage4LCP_Iteration_Callback(void *_stage4CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxQuickStepperStage4CallContext *stage4CallContext = (dxQuickStepperStage4CallContext *)_stage4CallContext;
+ unsigned int initiallyKnownToBeCompletedLevel = (unsigned int)callInstanceIndex;
+ dIASSERT(initiallyKnownToBeCompletedLevel == callInstanceIndex); // A truncation check...
+
+ dxQuickStepIsland_Stage4LCP_MTIteration(stage4CallContext, initiallyKnownToBeCompletedLevel);
+ return 1;
+}
+
+/*
+ * +0 +0
+ * Root───┬─────────────────┬──...
+ * +1│ +1│
+ * ┌┴â”+0 ┌─â”+0 .
+ * │A├─────┤B├─...
+ * └┬┘ └┬┘
+ * +1│ +1│
+ * ┌┴â”+0 .
+ * │C├─...
+ * └┬┘
+ * +1│
+ * .
+ *
+ * Lower tree levels depend on their parents. Same level nodes are independent with respect to each other.
+ *
+ * 1. B is linked in place of A
+ * 2. A is processed
+ * 3. C is inserted at the Root level
+ *
+ * The tree starts with a single child subtree at the root level ("down" link of slot #0 is used for that).
+ * Then, additional "C" nodes are added to the root level by building horizontal link via slots of
+ * their former parent "A"s that had become free.
+ * The "level" link of slot #0 is used to find the root level head.
+ *
+ * Since the tree is altered during iteration, mi_levels record each node parents so that the tree could be reconstructed.
+ */
+static
+void dxQuickStepIsland_Stage4LCP_MTIteration(dxQuickStepperStage4CallContext *stage4CallContext, unsigned int initiallyKnownToBeCompletedLevel)
+{
+ atomicord32 *mi_levels = stage4CallContext->m_bi_links_or_mi_levels;
+ atomicord32 *mi_links = stage4CallContext->m_mi_links;
+
+ unsigned int knownToBeCompletedLevel = initiallyKnownToBeCompletedLevel;
+
+ while (true) {
+ unsigned int initialLevelRoot = mi_links[2 * dxHEAD_INDEX + 0];
+ if (initialLevelRoot != dxHEAD_INDEX && initialLevelRoot == knownToBeCompletedLevel) {
+ // No work is (currently) available
+ break;
+ }
+
+ for (unsigned int currentLevelRoot = initialLevelRoot; ; currentLevelRoot = mi_links[2 * (sizeint)currentLevelRoot + 0]) {
+ while (true) {
+ const unsigned invalid_link = dxENCODE_INDEX(-1);
+
+ unsigned currentLevelFirstLink = mi_links[2 * (sizeint)currentLevelRoot + 1];
+ if (currentLevelFirstLink == invalid_link) {
+ break;
+ }
+
+ // Try to extract first record from linked list
+ unsigned currentLevelNextLink = mi_links[2 * (sizeint)currentLevelFirstLink + 0];
+ if (ThrsafeCompareExchange(&mi_links[2 * (sizeint)currentLevelRoot + 1], currentLevelFirstLink, currentLevelNextLink)) {
+ // if succeeded, execute selected iteration step...
+ dxQuickStepIsland_Stage4LCP_IterationStep(stage4CallContext, dxDECODE_INDEX(currentLevelFirstLink));
+
+ // Check if there are any dependencies
+ unsigned level0DownLink = mi_links[2 * (sizeint)currentLevelFirstLink + 1];
+ if (level0DownLink != invalid_link) {
+ // ...and if yes, insert the record into the list of available level roots
+ unsigned int levelRootsFirst;
+ do {
+ levelRootsFirst = mi_links[2 * dxHEAD_INDEX + 0];
+ mi_links[2 * (sizeint)currentLevelFirstLink + 0] = levelRootsFirst;
+ }
+ while (!ThrsafeCompareExchange(&mi_links[2 * dxHEAD_INDEX + 0], levelRootsFirst, currentLevelFirstLink));
+
+ // If another level was added and some threads have already exited...
+ unsigned int threadsTotal = stage4CallContext->m_LCP_iterationThreadsTotal;
+ unsigned int threadsRemaining = ThrsafeIncrementIntUpToLimit(&stage4CallContext->m_LCP_iterationThreadsRemaining, threadsTotal);
+ if (threadsRemaining != threadsTotal) {
+ // ...go on an schedule one more...
+ const dxStepperProcessingCallContext *callContext = stage4CallContext->m_stepperCallContext;
+ dxWorld *world = callContext->m_world;
+ // ...passing knownToBeCompletedLevel as the initial one for the spawned call
+ world->PostThreadedCallForUnawareReleasee(NULL, NULL, 0, stage4CallContext->m_LCP_iterationNextReleasee, NULL, &dxQuickStepIsland_Stage4LCP_Iteration_Callback, stage4CallContext, knownToBeCompletedLevel, "QuickStepIsland Stage4LCP_Iteration");
+ // NOTE: it's hard to predict whether it is reasonable to re-post a call
+ // each time a new level is added (provided some calls have already exited, of course).
+ // The efficiency very much depends on dependencies patterns between levels
+ // (i.e. it depends on the amount of available work added with each level).
+ // The strategy of re-posting exited calls as frequently as possible
+ // leads to potential wasting execution cycles in some cores for the aid
+ // of keeping other cores busy as much as possible and not letting all the
+ // work be executed by just a partial cores subset. With emergency of large
+ // available work amounts (the work that is not dependent on anything and
+ // ready to be executed immediately) this strategy is going to transit into
+ // full cores set being busy executing useful work. If amounts of work
+ // emerging from added levels are small, the strategy should lead to
+ // approximately the same efficiency as if the work was done by only a cores subset
+ // with the remaining cores wasting (some) cycles for re-scheduling calls
+ // to those busy cores rather than being idle or handling other islands.
+ }
+ }
+
+ // Finally record the root index of current record's level
+ mi_levels[dxDECODE_INDEX(currentLevelFirstLink)] = currentLevelRoot;
+ }
+ }
+
+ if (currentLevelRoot == knownToBeCompletedLevel) {
+ break;
+ }
+ dIASSERT(currentLevelRoot != dxHEAD_INDEX); // Zero level is expected to be the deepest one in the list and execution must not loop past it.
+ }
+ // Save the level root we started from as known to be completed
+ knownToBeCompletedLevel = initialLevelRoot;
+ }
+
+ // Decrement running threads count on exit
+ ThrsafeAdd(&stage4CallContext->m_LCP_iterationThreadsRemaining, (atomicord32)(-1));
+}
+
+static
+void dxQuickStepIsland_Stage4LCP_STIteration(dxQuickStepperStage4CallContext *stage4CallContext)
+{
+ const dxQuickStepperLocalContext *localContext = stage4CallContext->m_localContext;
+
+ unsigned int m = localContext->m_m;
+ for (unsigned int i = 0; i != m; ++i) {
+ dxQuickStepIsland_Stage4LCP_IterationStep(stage4CallContext, i);
+ }
+}
+
+//***************************************************************************
+// SOR-LCP method
+
+// nb is the number of bodies in the body array.
+// J is an m*16 matrix of constraint rows with rhs, cfm, lo and hi in padding
+// jb is an array of first and second body numbers for each constraint row
+// invI is the global frame inverse inertia for each body (stacked 3x3 matrices)
+//
+// this returns lambda and fc (the constraint force).
+// note: fc is returned as inv(M)*J'*lambda, the constraint force is actually J'*lambda
+//
+// b, lo and hi are modified on exit
+
+static
+void dxQuickStepIsland_Stage4LCP_IterationStep(dxQuickStepperStage4CallContext *stage4CallContext, unsigned int i)
+{
+ const dxQuickStepperLocalContext *localContext = stage4CallContext->m_localContext;
+
+ IndexError *order = stage4CallContext->m_order;
+ unsigned int index = order[i].index;
+
+ dReal *fc_ptr1;
+ dReal *fc_ptr2 = NULL;
+ dReal delta;
+
+ dReal *lambda = stage4CallContext->m_lambda;
+ dReal old_lambda = lambda[index];
+
+ dReal *J = localContext->m_J;
+ const dReal *J_ptr = J + (sizeint)index * JME__MAX;
+
+ {
+ delta = J_ptr[JME_RHS] - old_lambda * J_ptr[JME_CFM];
+
+ dReal *fc = stage4CallContext->m_cforce;
+
+ const dxJBodiesItem *jb = localContext->m_jb;
+ int b2 = jb[index].second;
+ int b1 = jb[index].first;
+
+ // @@@ potential optimization: SIMD-ize this and the b2 >= 0 case
+ fc_ptr1 = fc + (sizeint)(unsigned)b1 * CFE__MAX;
+ delta -= fc_ptr1[CFE_LX] * J_ptr[JME_J1LX] + fc_ptr1[CFE_LY] * J_ptr[JME_J1LY] +
+ fc_ptr1[CFE_LZ] * J_ptr[JME_J1LZ] + fc_ptr1[CFE_AX] * J_ptr[JME_J1AX] +
+ fc_ptr1[CFE_AY] * J_ptr[JME_J1AY] + fc_ptr1[CFE_AZ] * J_ptr[JME_J1AZ];
+ // @@@ potential optimization: handle 1-body constraints in a separate
+ // loop to avoid the cost of test & jump?
+ if (b2 != -1) {
+ fc_ptr2 = fc + (sizeint)(unsigned)b2 * CFE__MAX;
+ delta -= fc_ptr2[CFE_LX] * J_ptr[JME_J2LX] + fc_ptr2[CFE_LY] * J_ptr[JME_J2LY] +
+ fc_ptr2[CFE_LZ] * J_ptr[JME_J2LZ] + fc_ptr2[CFE_AX] * J_ptr[JME_J2AX] +
+ fc_ptr2[CFE_AY] * J_ptr[JME_J2AY] + fc_ptr2[CFE_AZ] * J_ptr[JME_J2AZ];
+ }
+ }
+
+ {
+ dReal hi_act, lo_act;
+
+ // set the limits for this constraint.
+ // this is the place where the QuickStep method differs from the
+ // direct LCP solving method, since that method only performs this
+ // limit adjustment once per time step, whereas this method performs
+ // once per iteration per constraint row.
+ // the constraints are ordered so that all lambda[] values needed have
+ // already been computed.
+ const int *findex = localContext->m_findex;
+ if (findex[index] != -1) {
+ hi_act = dFabs (J_ptr[JME_HI] * lambda[(unsigned)findex[index]]);
+ lo_act = -hi_act;
+ } else {
+ hi_act = J_ptr[JME_HI];
+ lo_act = J_ptr[JME_LO];
+ }
+
+ // compute lambda and clamp it to [lo,hi].
+ // @@@ potential optimization: does SSE have clamping instructions
+ // to save test+jump penalties here?
+ dReal new_lambda = old_lambda + delta;
+ if (new_lambda < lo_act) {
+ delta = lo_act - old_lambda;
+ lambda[index] = lo_act;
+ }
+ else if (new_lambda > hi_act) {
+ delta = hi_act - old_lambda;
+ lambda[index] = hi_act;
+ }
+ else {
+ lambda[index] = new_lambda;
+ }
+ }
+
+ //@@@ a trick that may or may not help
+ //dReal ramp = (1-((dReal)(iteration+1)/(dReal)num_iterations));
+ //delta *= ramp;
+
+ {
+ dReal *iMJ = stage4CallContext->m_iMJ;
+ const dReal *iMJ_ptr = iMJ + (sizeint)index * IMJ__MAX;
+ // update fc.
+ // @@@ potential optimization: SIMD for this and the b2 >= 0 case
+ fc_ptr1[CFE_LX] += delta * iMJ_ptr[IMJ_1LX];
+ fc_ptr1[CFE_LY] += delta * iMJ_ptr[IMJ_1LY];
+ fc_ptr1[CFE_LZ] += delta * iMJ_ptr[IMJ_1LZ];
+ fc_ptr1[CFE_AX] += delta * iMJ_ptr[IMJ_1AX];
+ fc_ptr1[CFE_AY] += delta * iMJ_ptr[IMJ_1AY];
+ fc_ptr1[CFE_AZ] += delta * iMJ_ptr[IMJ_1AZ];
+ // @@@ potential optimization: handle 1-body constraints in a separate
+ // loop to avoid the cost of test & jump?
+ if (fc_ptr2) {
+ fc_ptr2[CFE_LX] += delta * iMJ_ptr[IMJ_2LX];
+ fc_ptr2[CFE_LY] += delta * iMJ_ptr[IMJ_2LY];
+ fc_ptr2[CFE_LZ] += delta * iMJ_ptr[IMJ_2LZ];
+ fc_ptr2[CFE_AX] += delta * iMJ_ptr[IMJ_2AX];
+ fc_ptr2[CFE_AY] += delta * iMJ_ptr[IMJ_2AY];
+ fc_ptr2[CFE_AZ] += delta * iMJ_ptr[IMJ_2AZ];
+ }
+ }
+}
+
+static inline
+bool IsStage4bJointInfosIterationRequired(const dxQuickStepperLocalContext *localContext)
+{
+ return
+#ifdef WARM_STARTING
+ true ||
+#endif
+ localContext->m_mfb > 0;
+}
+
+static
+int dxQuickStepIsland_Stage4LCP_IterationSync_Callback(void *_stage4CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxQuickStepperStage4CallContext *stage4CallContext = (dxQuickStepperStage4CallContext *)_stage4CallContext;
+ const dxStepperProcessingCallContext *callContext = stage4CallContext->m_stepperCallContext;
+ const dxQuickStepperLocalContext *localContext = stage4CallContext->m_localContext;
+
+ unsigned int stage4b_allowedThreads = 1;
+ if (IsStage4bJointInfosIterationRequired(localContext)) {
+ unsigned int allowedThreads = callContext->m_stepperAllowedThreads;
+ dIASSERT(allowedThreads >= stage4b_allowedThreads);
+ stage4b_allowedThreads += CalculateOptimalThreadsCount<dxQUICKSTEPISLAND_STAGE4B_STEP>(localContext->m_nj, allowedThreads - stage4b_allowedThreads);
+ }
+
+ if (stage4b_allowedThreads > 1) {
+ dxWorld *world = callContext->m_world;
+ world->AlterThreadedCallDependenciesCount(callThisReleasee, stage4b_allowedThreads - 1);
+ world->PostThreadedCallsGroup(NULL, stage4b_allowedThreads - 1, callThisReleasee, &dxQuickStepIsland_Stage4b_Callback, stage4CallContext, "QuickStepIsland Stage4b");
+ }
+ dxQuickStepIsland_Stage4b(stage4CallContext);
+
+ return 1;
+}
+
+static
+int dxQuickStepIsland_Stage4b_Callback(void *_stage4CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxQuickStepperStage4CallContext *stage4CallContext = (dxQuickStepperStage4CallContext *)_stage4CallContext;
+ dxQuickStepIsland_Stage4b(stage4CallContext);
+ return 1;
+}
+
+static
+void dxQuickStepIsland_Stage4b(dxQuickStepperStage4CallContext *stage4CallContext)
+{
+ const dxStepperProcessingCallContext *callContext = stage4CallContext->m_stepperCallContext;
+ const dxQuickStepperLocalContext *localContext = stage4CallContext->m_localContext;
+
+ if (ThrsafeExchange(&stage4CallContext->m_cf_4b, 1) == 0) {
+ dxBody * const *body = callContext->m_islandBodiesStart;
+ unsigned int nb = callContext->m_islandBodiesCount;
+ const dReal *cforce = stage4CallContext->m_cforce;
+ dReal stepsize = callContext->m_stepSize;
+ // add stepsize * cforce to the body velocity
+ const dReal *cforcecurr = cforce;
+ dxBody *const *const bodyend = body + nb;
+ for (dxBody *const *bodycurr = body; bodycurr != bodyend; cforcecurr += CFE__MAX, bodycurr++) {
+ dxBody *b = *bodycurr;
+ for (unsigned int j = dSA__MIN; j != dSA__MAX; j++) {
+ b->lvel[dV3E__AXES_MIN + j] += stepsize * cforcecurr[CFE__L_MIN + j];
+ b->avel[dV3E__AXES_MIN + j] += stepsize * cforcecurr[CFE__A_MIN + j];
+ }
+ }
+ }
+
+
+ // note that the SOR method overwrites rhs and J at this point, so
+ // they should not be used again.
+
+ if (IsStage4bJointInfosIterationRequired(localContext)) {
+ dReal data[JVE__MAX];
+ const dReal *Jcopy = localContext->m_Jcopy;
+ const dReal *lambda = stage4CallContext->m_lambda;
+ const dxMIndexItem *mindex = localContext->m_mindex;
+ dJointWithInfo1 *jointinfos = localContext->m_jointinfos;
+
+ unsigned int nj = localContext->m_nj;
+ const unsigned int step_size = dxQUICKSTEPISLAND_STAGE4B_STEP;
+ unsigned int nj_steps = (nj + (step_size - 1)) / step_size;
+
+ unsigned ji_step;
+ while ((ji_step = ThrsafeIncrementIntUpToLimit(&stage4CallContext->m_ji_4b, nj_steps)) != nj_steps) {
+ unsigned int ji = ji_step * step_size;
+ const unsigned int jiend = ji + dMIN(step_size, nj - ji);
+
+ const dReal *Jcopycurr = Jcopy + (sizeint)mindex[ji].fbIndex * JCE__MAX;
+
+ while (true) {
+ // straightforward computation of joint constraint forces:
+ // multiply related lambdas with respective J' block for joints
+ // where feedback was requested
+ const unsigned int fb_infom = mindex[ji + 1].fbIndex - mindex[ji].fbIndex;
+ if (fb_infom != 0) {
+ dIASSERT(fb_infom == mindex[ji + 1].mIndex - mindex[ji].mIndex);
+
+ const dReal *lambdacurr = lambda + mindex[ji].mIndex;
+ dxJoint *joint = jointinfos[ji].joint;
+
+#ifdef WARM_STARTING
+ memcpy(joint->lambda, lambdacurr, fb_infom * sizeof(dReal));
+#endif
+
+ dJointFeedback *fb = joint->feedback;
+
+ if (joint->node[1].body) {
+ Multiply1_12q1 (data, Jcopycurr + JCE__J2_MIN, lambdacurr, fb_infom);
+ dSASSERT(JCE__MAX == 12);
+
+ fb->f2[dSA_X] = data[JVE_LX];
+ fb->f2[dSA_Y] = data[JVE_LY];
+ fb->f2[dSA_Z] = data[JVE_LZ];
+ fb->t2[dSA_X] = data[JVE_AX];
+ fb->t2[dSA_Y] = data[JVE_AY];
+ fb->t2[dSA_Z] = data[JVE_AZ];
+ }
+
+ Multiply1_12q1 (data, Jcopycurr + JCE__J1_MIN, lambdacurr, fb_infom);
+ dSASSERT(JCE__MAX == 12);
+
+ fb->f1[dSA_X] = data[JVE_LX];
+ fb->f1[dSA_Y] = data[JVE_LY];
+ fb->f1[dSA_Z] = data[JVE_LZ];
+ fb->t1[dSA_X] = data[JVE_AX];
+ fb->t1[dSA_Y] = data[JVE_AY];
+ fb->t1[dSA_Z] = data[JVE_AZ];
+
+ Jcopycurr += fb_infom * JCE__MAX;
+ }
+ else {
+#ifdef WARM_STARTING
+ const dReal *lambdacurr = lambda + mindex[ji].mIndex;
+ const unsigned int infom = mindex[ji + 1].mIndex - mindex[ji].mIndex;
+ dxJoint *joint = jointinfos[ji].joint;
+ memcpy(joint->lambda, lambdacurr, infom * sizeof(dReal));
+#endif
+ }
+
+ if (++ji == jiend) {
+ break;
+ }
+ }
+ }
+ }
+}
+
+static
+int dxQuickStepIsland_Stage5_Callback(void *_stage5CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxQuickStepperStage5CallContext *stage5CallContext = (dxQuickStepperStage5CallContext *)_stage5CallContext;
+ dxQuickStepIsland_Stage5(stage5CallContext);
+ return 1;
+}
+
+static
+void dxQuickStepIsland_Stage5(dxQuickStepperStage5CallContext *stage5CallContext)
+{
+ const dxStepperProcessingCallContext *callContext = stage5CallContext->m_stepperCallContext;
+ const dxQuickStepperLocalContext *localContext = stage5CallContext->m_localContext;
+
+ dxWorldProcessMemArena *memarena = callContext->m_stepperArena;
+ memarena->RestoreState(stage5CallContext->m_stage3MemArenaState);
+ stage5CallContext = NULL; // WARNING! stage3CallContext is not valid after this point!
+ dIVERIFY(stage5CallContext == NULL); // To suppress unused variable assignment warnings
+
+ dxQuickStepperStage6CallContext *stage6CallContext = (dxQuickStepperStage6CallContext *)memarena->AllocateBlock(sizeof(dxQuickStepperStage6CallContext));
+ stage6CallContext->Initialize(callContext, localContext);
+
+ const unsigned allowedThreads = callContext->m_stepperAllowedThreads;
+ dIASSERT(allowedThreads >= 1);
+
+ if (allowedThreads == 1) {
+ IFTIMING (dTimerNow ("compute velocity update"));
+ dxQuickStepIsland_Stage6a(stage6CallContext);
+ dxQuickStepIsland_Stage6_VelocityCheck(stage6CallContext);
+ IFTIMING (dTimerNow ("update position and tidy up"));
+ dxQuickStepIsland_Stage6b(stage6CallContext);
+ IFTIMING (dTimerEnd());
+ IFTIMING (if (m > 0) dTimerReport (stdout,1));
+ }
+ else {
+ unsigned int nb = callContext->m_islandBodiesCount;
+ unsigned int stage6a_allowedThreads = CalculateOptimalThreadsCount<dxQUICKSTEPISLAND_STAGE6A_STEP>(nb, allowedThreads);
+
+ dxWorld *world = callContext->m_world;
+
+ dCallReleaseeID stage6aSyncReleasee;
+ world->PostThreadedCallForUnawareReleasee(NULL, &stage6aSyncReleasee, stage6a_allowedThreads, callContext->m_finalReleasee,
+ NULL, &dxQuickStepIsland_Stage6aSync_Callback, stage6CallContext, 0, "QuickStepIsland Stage6a Sync");
+
+ if (stage6a_allowedThreads > 1) {
+ world->PostThreadedCallsGroup(NULL, stage6a_allowedThreads - 1, stage6aSyncReleasee, &dxQuickStepIsland_Stage6a_Callback, stage6CallContext, "QuickStepIsland Stage6a");
+ }
+ dxQuickStepIsland_Stage6a(stage6CallContext);
+ world->AlterThreadedCallDependenciesCount(stage6aSyncReleasee, -1);
+ }
+}
+
+
+static
+int dxQuickStepIsland_Stage6a_Callback(void *_stage6CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxQuickStepperStage6CallContext *stage6CallContext = (dxQuickStepperStage6CallContext *)_stage6CallContext;
+ dxQuickStepIsland_Stage6a(stage6CallContext);
+ return 1;
+}
+
+static
+void dxQuickStepIsland_Stage6a(dxQuickStepperStage6CallContext *stage6CallContext)
+{
+ const dxStepperProcessingCallContext *callContext = stage6CallContext->m_stepperCallContext;
+ const dxQuickStepperLocalContext *localContext = stage6CallContext->m_localContext;
+
+ dReal stepsize = callContext->m_stepSize;
+ dReal *invI = localContext->m_invI;
+ dxBody * const *body = callContext->m_islandBodiesStart;
+
+ unsigned int nb = callContext->m_islandBodiesCount;
+ const unsigned int step_size = dxQUICKSTEPISLAND_STAGE6A_STEP;
+ unsigned int nb_steps = (nb + (step_size - 1)) / step_size;
+
+ unsigned bi_step;
+ while ((bi_step = ThrsafeIncrementIntUpToLimit(&stage6CallContext->m_bi_6a, nb_steps)) != nb_steps) {
+ unsigned int bi = bi_step * step_size;
+ unsigned int bicnt = dMIN(step_size, nb - bi);
+
+ const dReal *invIrow = invI + (sizeint)bi * IIE__MAX;
+ dxBody *const *bodycurr = body + bi;
+ dxBody *const *bodyend = bodycurr + bicnt;
+ while (true) {
+ // compute the velocity update:
+ // add stepsize * invM * fe to the body velocity
+ dxBody *b = *bodycurr;
+ dReal body_invMass_mul_stepsize = stepsize * b->invMass;
+ for (unsigned int j = dSA__MIN; j != dSA__MAX; ++j) {
+ b->lvel[dV3E__AXES_MIN + j] += body_invMass_mul_stepsize * b->facc[dV3E__AXES_MIN + j];
+ b->tacc[dV3E__AXES_MIN + j] *= stepsize;
+ }
+ dMultiplyAdd0_331 (b->avel, invIrow + IIE__MATRIX_MIN, b->tacc);
+
+ if (++bodycurr == bodyend) {
+ break;
+ }
+ invIrow += IIE__MAX;
+ }
+ }
+}
+
+
+static
+int dxQuickStepIsland_Stage6aSync_Callback(void *_stage6CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxQuickStepperStage6CallContext *stage6CallContext = (dxQuickStepperStage6CallContext *)_stage6CallContext;
+ dxQuickStepIsland_Stage6_VelocityCheck(stage6CallContext);
+
+ const dxStepperProcessingCallContext *callContext = stage6CallContext->m_stepperCallContext;
+
+ const unsigned allowedThreads = callContext->m_stepperAllowedThreads;
+ unsigned int nb = callContext->m_islandBodiesCount;
+ unsigned int stage6b_allowedThreads = CalculateOptimalThreadsCount<dxQUICKSTEPISLAND_STAGE6B_STEP>(nb, allowedThreads);
+
+ if (stage6b_allowedThreads > 1) {
+ dxWorld *world = callContext->m_world;
+ world->AlterThreadedCallDependenciesCount(callThisReleasee, stage6b_allowedThreads - 1);
+ world->PostThreadedCallsGroup(NULL, stage6b_allowedThreads - 1, callThisReleasee, &dxQuickStepIsland_Stage6b_Callback, stage6CallContext, "QuickStepIsland Stage6b");
+ }
+ dxQuickStepIsland_Stage6b(stage6CallContext);
+
+ return 1;
+}
+
+static
+void dxQuickStepIsland_Stage6_VelocityCheck(dxQuickStepperStage6CallContext *stage6CallContext)
+{
+ (void)stage6CallContext; // can be unused
+#ifdef CHECK_VELOCITY_OBEYS_CONSTRAINT
+ const dxQuickStepperLocalContext *localContext = stage6CallContext->m_localContext;
+
+ unsigned int m = localContext->m_m;
+ if (m > 0) {
+ const dxStepperProcessingCallContext *callContext = stage6CallContext->m_stepperCallContext;
+ dxBody * const *body = callContext->m_islandBodiesStart;
+ dReal *J = localContext->m_J;
+ const dxJBodiesItem *jb = localContext->m_jb;
+
+ dReal error = 0;
+ const dReal* J_ptr = J;
+ for (unsigned int i = 0; i < m; ++i) {
+ int b1 = jb[i].first;
+ int b2 = jb[i].second;
+ dReal sum = 0;
+ dxBody *bodycurr = body[(unsigned)b1];
+ for (unsigned int j = dSA__MIN; j != dSA__MAX; ++j) sum += J_ptr[JME__J1L_MIN + j] * bodycurr->lvel[dV3E__AXES_MIN + j] + J_ptr[JME__J1A_MIN + j] * bodycurr->avel[dV3E__AXES_MIN + j];
+ if (b2 != -1) {
+ dxBody *bodycurr = body[(unsigned)b2];
+ for (unsigned int k = dSA__MIN; k != dSA__MAX; ++k) sum += J_ptr[JME__J2L_MIN + k] * bodycurr->lvel[dV3E__AXES_MIN + k] + J_ptr[JME__J2A_MIN + k] * bodycurr->avel[dV3E__AXES_MIN + k];
+ }
+ J_ptr += JME__MAX;
+ error += dFabs(sum);
+ }
+ printf ("velocity error = %10.6e\n", error);
+ }
+#endif
+}
+
+static
+int dxQuickStepIsland_Stage6b_Callback(void *_stage6CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxQuickStepperStage6CallContext *stage6CallContext = (dxQuickStepperStage6CallContext *)_stage6CallContext;
+ dxQuickStepIsland_Stage6b(stage6CallContext);
+ return 1;
+}
+
+static
+void dxQuickStepIsland_Stage6b(dxQuickStepperStage6CallContext *stage6CallContext)
+{
+ const dxStepperProcessingCallContext *callContext = stage6CallContext->m_stepperCallContext;
+
+ dReal stepsize = callContext->m_stepSize;
+ dxBody * const *body = callContext->m_islandBodiesStart;
+
+ // update the position and orientation from the new linear/angular velocity
+ // (over the given timestep)
+ unsigned int nb = callContext->m_islandBodiesCount;
+ const unsigned int step_size = dxQUICKSTEPISLAND_STAGE6B_STEP;
+ unsigned int nb_steps = (nb + (step_size - 1)) / step_size;
+
+ unsigned bi_step;
+ while ((bi_step = ThrsafeIncrementIntUpToLimit(&stage6CallContext->m_bi_6b, nb_steps)) != nb_steps) {
+ unsigned int bi = bi_step * step_size;
+ unsigned int bicnt = dMIN(step_size, nb - bi);
+
+ dxBody *const *bodycurr = body + bi;
+ dxBody *const *bodyend = bodycurr + bicnt;
+ while (true) {
+ dxBody *b = *bodycurr;
+ dxStepBody (b, stepsize);
+ dZeroVector3 (b->facc);
+ dZeroVector3 (b->tacc);
+ if (++bodycurr == bodyend) {
+ break;
+ }
+ }
+ }
+}
+
+
+
+/*extern */
+sizeint dxEstimateQuickStepMemoryRequirements (dxBody * const *body,
+ unsigned int nb,
+ dxJoint * const *_joint,
+ unsigned int _nj)
+{
+ (void)body; // unused
+ unsigned int nj, m, mfb;
+
+ {
+ unsigned int njcurr = 0, mcurr = 0, mfbcurr = 0;
+ dxJoint::SureMaxInfo info;
+ dxJoint *const *const _jend = _joint + _nj;
+ for (dxJoint *const *_jcurr = _joint; _jcurr != _jend; _jcurr++) {
+ dxJoint *j = *_jcurr;
+ j->getSureMaxInfo (&info);
+
+ unsigned int jm = info.max_m;
+ if (jm > 0) {
+ njcurr++;
+
+ mcurr += jm;
+ if (j->feedback)
+ mfbcurr += jm;
+ }
+ }
+ nj = njcurr; m = mcurr; mfb = mfbcurr;
+ }
+
+ sizeint res = 0;
+
+ res += dOVERALIGNED_SIZE(sizeof(dReal) * IIE__MAX * nb, INVI_ALIGNMENT); // for invI
+
+ {
+ sizeint sub1_res1 = dEFFICIENT_SIZE(sizeof(dJointWithInfo1) * _nj); // for initial jointinfos
+
+ sizeint sub1_res2 = dEFFICIENT_SIZE(sizeof(dJointWithInfo1) * nj); // for shrunk jointinfos
+ sub1_res2 += dEFFICIENT_SIZE(sizeof(dxQuickStepperLocalContext)); // for dxQuickStepLocalContext
+ if (m > 0) {
+ sub1_res2 += dEFFICIENT_SIZE(sizeof(dxMIndexItem) * (nj + 1)); // for mindex
+ sub1_res2 += dEFFICIENT_SIZE(sizeof(dxJBodiesItem) * m); // for jb
+ sub1_res2 += dEFFICIENT_SIZE(sizeof(int) * m); // for findex
+ sub1_res2 += dOVERALIGNED_SIZE(sizeof(dReal) * JME__MAX * m, JACOBIAN_ALIGNMENT); // for J
+ sub1_res2 += dOVERALIGNED_SIZE(sizeof(dReal) * JCE__MAX * mfb, JCOPY_ALIGNMENT); // for Jcopy
+ {
+ sizeint sub2_res1 = dEFFICIENT_SIZE(sizeof(dxQuickStepperStage3CallContext)); // for dxQuickStepperStage3CallContext
+ sub2_res1 += dEFFICIENT_SIZE(sizeof(dReal) * RHS__MAX * nb); // for rhs_tmp
+ sub2_res1 += dEFFICIENT_SIZE(sizeof(dxQuickStepperStage2CallContext)); // for dxQuickStepperStage2CallContext
+
+ sizeint sub2_res2 = 0;
+ {
+ sizeint sub3_res1 = dEFFICIENT_SIZE(sizeof(dxQuickStepperStage5CallContext)); // for dxQuickStepperStage5CallContext;
+ sub3_res1 += dEFFICIENT_SIZE(sizeof(dReal) * m); // for lambda
+ sub3_res1 += dEFFICIENT_SIZE(sizeof(dReal) * CFE__MAX * nb); // for cforce
+ sub3_res1 += dOVERALIGNED_SIZE(sizeof(dReal) * IMJ__MAX * m, INVMJ_ALIGNMENT); // for iMJ
+ sub3_res1 += dEFFICIENT_SIZE(sizeof(IndexError) * m); // for order
+#if CONSTRAINTS_REORDERING_METHOD == REORDERING_METHOD__BY_ERROR
+ sub3_res1 += dEFFICIENT_SIZE(sizeof(dReal) * m); // for last_lambda
+#endif
+#if !dTHREADING_INTF_DISABLED
+ sub3_res1 += dEFFICIENT_SIZE(sizeof(atomicord32) * dMAX(nb, m)); // for bi_links_or_mi_levels
+ sub3_res1 += dEFFICIENT_SIZE(sizeof(atomicord32) * 2 * ((sizeint)m + 1)); // for mi_links
+#endif
+ sub3_res1 += dEFFICIENT_SIZE(sizeof(dxQuickStepperStage4CallContext)); // for dxQuickStepperStage4CallContext;
+
+ sizeint sub3_res2 = dEFFICIENT_SIZE(sizeof(dxQuickStepperStage6CallContext)); // for dxQuickStepperStage6CallContext;
+
+ sub2_res2 += dMAX(sub3_res1, sub3_res2);
+ }
+
+ sub1_res2 += dMAX(sub2_res1, sub2_res2);
+ }
+ }
+ else {
+ sub1_res2 += dEFFICIENT_SIZE(sizeof(dxQuickStepperStage3CallContext)); // for dxQuickStepperStage3CallContext
+ }
+
+ sizeint sub1_res12_max = dMAX(sub1_res1, sub1_res2);
+ sizeint stage01_contexts = dEFFICIENT_SIZE(sizeof(dxQuickStepperStage0BodiesCallContext))
+ + dEFFICIENT_SIZE(sizeof(dxQuickStepperStage0JointsCallContext))
+ + dEFFICIENT_SIZE(sizeof(dxQuickStepperStage1CallContext));
+ res += dMAX(sub1_res12_max, stage01_contexts);
+ }
+
+ return res;
+}
+
+/*extern */
+unsigned dxEstimateQuickStepMaxCallCount(unsigned activeThreadCount, unsigned allowedThreadCount)
+{
+ (void)activeThreadCount; // unused
+ unsigned result = 1 // dxQuickStepIsland itself
+ + 5 + (2 * allowedThreadCount + 1) // for Stage4 related schedules
+ + 1 // dxStepIsland_Stage5
+ + allowedThreadCount; // Reserve
+ return result;
+}
+
diff --git a/libs/ode-0.16.1/ode/src/quickstep.h b/libs/ode-0.16.1/ode/src/quickstep.h new file mode 100644 index 0000000..4433e9c --- /dev/null +++ b/libs/ode-0.16.1/ode/src/quickstep.h @@ -0,0 +1,39 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_QUICK_STEP_H_ +#define _ODE_QUICK_STEP_H_ + +#include <ode/common.h> + +struct dxStepperProcessingCallContext; + + +sizeint dxEstimateQuickStepMemoryRequirements( + dxBody * const *body, unsigned int nb, dxJoint * const *_joint, unsigned int _nj); +unsigned dxEstimateQuickStepMaxCallCount( + unsigned activeThreadCount, unsigned allowedThreadCount); + +void dxQuickStepIsland(const dxStepperProcessingCallContext *callContext); + + +#endif diff --git a/libs/ode-0.16.1/ode/src/ray.cpp b/libs/ode-0.16.1/ode/src/ray.cpp new file mode 100644 index 0000000..7709e8b --- /dev/null +++ b/libs/ode-0.16.1/ode/src/ray.cpp @@ -0,0 +1,735 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +standard ODE geometry primitives: public API and pairwise collision functions. + +the rule is that only the low level primitive collision functions should set +dContactGeom::g1 and dContactGeom::g2. + +*/ + +#include <ode/common.h> +#include <ode/collision.h> +#include <ode/rotation.h> +#include "config.h" +#include "matrix.h" +#include "odemath.h" +#include "collision_kernel.h" +#include "collision_std.h" +#include "collision_util.h" + +#ifdef _MSC_VER +#pragma warning(disable:4291) // for VC++, no complaints about "no matching operator delete found" +#endif + +//**************************************************************************** +// ray public API + +dxRay::dxRay (dSpaceID space, dReal _length) : dxGeom (space,1) +{ + type = dRayClass; + length = _length; +} + + +void dxRay::computeAABB() +{ + dVector3 e; + e[0] = final_posr->pos[0] + final_posr->R[0*4+2]*length; + e[1] = final_posr->pos[1] + final_posr->R[1*4+2]*length; + e[2] = final_posr->pos[2] + final_posr->R[2*4+2]*length; + + if (final_posr->pos[0] < e[0]){ + aabb[0] = final_posr->pos[0]; + aabb[1] = e[0]; + } + else{ + aabb[0] = e[0]; + aabb[1] = final_posr->pos[0]; + } + + if (final_posr->pos[1] < e[1]){ + aabb[2] = final_posr->pos[1]; + aabb[3] = e[1]; + } + else{ + aabb[2] = e[1]; + aabb[3] = final_posr->pos[1]; + } + + if (final_posr->pos[2] < e[2]){ + aabb[4] = final_posr->pos[2]; + aabb[5] = e[2]; + } + else{ + aabb[4] = e[2]; + aabb[5] = final_posr->pos[2]; + } +} + + +dGeomID dCreateRay (dSpaceID space, dReal length) +{ + return new dxRay (space,length); +} + + +void dGeomRaySetLength (dGeomID g, dReal length) +{ + dUASSERT (g && g->type == dRayClass,"argument not a ray"); + dxRay *r = (dxRay*) g; + r->length = length; + dGeomMoved (g); +} + + +dReal dGeomRayGetLength (dGeomID g) +{ + dUASSERT (g && g->type == dRayClass,"argument not a ray"); + dxRay *r = (dxRay*) g; + return r->length; +} + + +void dGeomRaySet (dGeomID g, dReal px, dReal py, dReal pz, + dReal dx, dReal dy, dReal dz) +{ + dUASSERT (g && g->type == dRayClass,"argument not a ray"); + g->recomputePosr(); + dReal* rot = g->final_posr->R; + dReal* pos = g->final_posr->pos; + dVector3 n; + pos[0] = px; + pos[1] = py; + pos[2] = pz; + + n[0] = dx; + n[1] = dy; + n[2] = dz; + dNormalize3(n); + rot[0*4+2] = n[0]; + rot[1*4+2] = n[1]; + rot[2*4+2] = n[2]; + dGeomMoved (g); +} + + +void dGeomRayGet (dGeomID g, dVector3 start, dVector3 dir) +{ + dUASSERT (g && g->type == dRayClass,"argument not a ray"); + g->recomputePosr(); + start[0] = g->final_posr->pos[0]; + start[1] = g->final_posr->pos[1]; + start[2] = g->final_posr->pos[2]; + dir[0] = g->final_posr->R[0*4+2]; + dir[1] = g->final_posr->R[1*4+2]; + dir[2] = g->final_posr->R[2*4+2]; +} + + +void dGeomRaySetParams (dxGeom *g, int FirstContact, int BackfaceCull) +{ + dUASSERT (g && g->type == dRayClass,"argument not a ray"); + + dGeomRaySetFirstContact(g, FirstContact); + dGeomRaySetBackfaceCull(g, BackfaceCull); +} + + +void dGeomRayGetParams (dxGeom *g, int *FirstContact, int *BackfaceCull) +{ + dUASSERT (g && g->type == dRayClass,"argument not a ray"); + + (*FirstContact) = ((g->gflags & RAY_FIRSTCONTACT) != 0); + (*BackfaceCull) = ((g->gflags & RAY_BACKFACECULL) != 0); +} + + +// set/get backface culling flag +void dGeomRaySetBackfaceCull (dxGeom *g, int backfaceCull) +{ + + dUASSERT (g && g->type == dRayClass,"argument not a ray"); + if (backfaceCull) { + g->gflags |= RAY_BACKFACECULL; + } else { + g->gflags &= ~RAY_BACKFACECULL; + } +} + + +int dGeomRayGetBackfaceCull (dxGeom *g) +{ + dUASSERT (g && g->type == dRayClass,"argument not a ray"); + return ((g->gflags & RAY_BACKFACECULL) != 0); +} + + +// set/get first contact flag +void dGeomRaySetFirstContact (dxGeom *g, int firstContact) +{ + dUASSERT (g && g->type == dRayClass,"argument not a ray"); + if (firstContact) { + g->gflags |= RAY_FIRSTCONTACT; + } else { + g->gflags &= ~RAY_FIRSTCONTACT; + } +} + + +int dGeomRayGetFirstContact (dxGeom *g) +{ + dUASSERT (g && g->type == dRayClass,"argument not a ray"); + return ((g->gflags & RAY_FIRSTCONTACT) != 0); +} + + +void dGeomRaySetClosestHit (dxGeom *g, int closestHit) +{ + dUASSERT (g && g->type == dRayClass,"argument not a ray"); + if (closestHit){ + g->gflags |= RAY_CLOSEST_HIT; + } + else g->gflags &= ~RAY_CLOSEST_HIT; +} + + +int dGeomRayGetClosestHit (dxGeom *g) +{ + dUASSERT (g && g->type == dRayClass,"argument not a ray"); + return ((g->gflags & RAY_CLOSEST_HIT) != 0); +} + + + +// if mode==1 then use the sphere exit contact, not the entry contact + +static int ray_sphere_helper (dxRay *ray, dVector3 sphere_pos, dReal radius, + dContactGeom *contact, int mode) +{ + dVector3 q; + q[0] = ray->final_posr->pos[0] - sphere_pos[0]; + q[1] = ray->final_posr->pos[1] - sphere_pos[1]; + q[2] = ray->final_posr->pos[2] - sphere_pos[2]; + dReal B = dCalcVectorDot3_14(q,ray->final_posr->R+2); + dReal C = dCalcVectorDot3(q,q) - radius*radius; + // note: if C <= 0 then the start of the ray is inside the sphere + dReal k = B*B - C; + if (k < 0) return 0; + k = dSqrt(k); + dReal alpha; + if (mode && C >= 0) { + alpha = -B + k; + if (alpha < 0) return 0; + } + else { + alpha = -B - k; + if (alpha < 0) { + alpha = -B + k; + if (alpha < 0) return 0; + } + } + if (alpha > ray->length) return 0; + contact->pos[0] = ray->final_posr->pos[0] + alpha*ray->final_posr->R[0*4+2]; + contact->pos[1] = ray->final_posr->pos[1] + alpha*ray->final_posr->R[1*4+2]; + contact->pos[2] = ray->final_posr->pos[2] + alpha*ray->final_posr->R[2*4+2]; + dReal nsign = (C < 0 || mode) ? REAL(-1.0) : REAL(1.0); + contact->normal[0] = nsign*(contact->pos[0] - sphere_pos[0]); + contact->normal[1] = nsign*(contact->pos[1] - sphere_pos[1]); + contact->normal[2] = nsign*(contact->pos[2] - sphere_pos[2]); + dNormalize3 (contact->normal); + contact->depth = alpha; + return 1; +} + + +int dCollideRaySphere (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dRayClass); + dIASSERT (o2->type == dSphereClass); + dIASSERT ((flags & NUMC_MASK) >= 1); + + dxRay *ray = (dxRay*) o1; + dxSphere *sphere = (dxSphere*) o2; + contact->g1 = ray; + contact->g2 = sphere; + contact->side1 = -1; + contact->side2 = -1; + return ray_sphere_helper (ray,sphere->final_posr->pos,sphere->radius,contact,0); +} + + +int dCollideRayBox (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dRayClass); + dIASSERT (o2->type == dBoxClass); + dIASSERT ((flags & NUMC_MASK) >= 1); + + dxRay *ray = (dxRay*) o1; + dxBox *box = (dxBox*) o2; + + contact->g1 = ray; + contact->g2 = box; + contact->side1 = -1; + contact->side2 = -1; + + int i; + + // compute the start and delta of the ray relative to the box. + // we will do all subsequent computations in this box-relative coordinate + // system. we have to do a translation and rotation for each point. + dVector3 tmp,s,v; + tmp[0] = ray->final_posr->pos[0] - box->final_posr->pos[0]; + tmp[1] = ray->final_posr->pos[1] - box->final_posr->pos[1]; + tmp[2] = ray->final_posr->pos[2] - box->final_posr->pos[2]; + dMultiply1_331 (s,box->final_posr->R,tmp); + tmp[0] = ray->final_posr->R[0*4+2]; + tmp[1] = ray->final_posr->R[1*4+2]; + tmp[2] = ray->final_posr->R[2*4+2]; + dMultiply1_331 (v,box->final_posr->R,tmp); + + // mirror the line so that v has all components >= 0 + dVector3 sign; + for (i=0; i<3; i++) { + if (v[i] < 0) { + s[i] = -s[i]; + v[i] = -v[i]; + sign[i] = 1; + } + else sign[i] = -1; + } + + // compute the half-sides of the box + dReal h[3]; + h[0] = REAL(0.5) * box->side[0]; + h[1] = REAL(0.5) * box->side[1]; + h[2] = REAL(0.5) * box->side[2]; + + // do a few early exit tests + if ((s[0] < -h[0] && v[0] <= 0) || s[0] > h[0] || + (s[1] < -h[1] && v[1] <= 0) || s[1] > h[1] || + (s[2] < -h[2] && v[2] <= 0) || s[2] > h[2] || + (v[0] == 0 && v[1] == 0 && v[2] == 0)) { + return 0; + } + + // compute the t=[lo..hi] range for where s+v*t intersects the box + dReal lo = -dInfinity; + dReal hi = dInfinity; + int nlo = 0, nhi = 0; + for (i=0; i<3; i++) { + if (v[i] != 0) { + dReal k = (-h[i] - s[i])/v[i]; + if (k > lo) { + lo = k; + nlo = i; + } + k = (h[i] - s[i])/v[i]; + if (k < hi) { + hi = k; + nhi = i; + } + } + } + + // check if the ray intersects + if (lo > hi) return 0; + dReal alpha; + int n; + if (lo >= 0) { + alpha = lo; + n = nlo; + } + else { + alpha = hi; + n = nhi; + } + if (alpha < 0 || alpha > ray->length) return 0; + contact->pos[0] = ray->final_posr->pos[0] + alpha*ray->final_posr->R[0*4+2]; + contact->pos[1] = ray->final_posr->pos[1] + alpha*ray->final_posr->R[1*4+2]; + contact->pos[2] = ray->final_posr->pos[2] + alpha*ray->final_posr->R[2*4+2]; + contact->normal[0] = box->final_posr->R[0*4+n] * sign[n]; + contact->normal[1] = box->final_posr->R[1*4+n] * sign[n]; + contact->normal[2] = box->final_posr->R[2*4+n] * sign[n]; + contact->depth = alpha; + return 1; +} + + +int dCollideRayCapsule (dxGeom *o1, dxGeom *o2, + int flags, dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dRayClass); + dIASSERT (o2->type == dCapsuleClass); + dIASSERT ((flags & NUMC_MASK) >= 1); + + dxRay *ray = (dxRay*) o1; + dxCapsule *ccyl = (dxCapsule*) o2; + + contact->g1 = ray; + contact->g2 = ccyl; + contact->side1 = -1; + contact->side2 = -1; + + dReal lz2 = ccyl->lz * REAL(0.5); + + // compute some useful info + dVector3 cs,q,r; + dReal C,k; + cs[0] = ray->final_posr->pos[0] - ccyl->final_posr->pos[0]; + cs[1] = ray->final_posr->pos[1] - ccyl->final_posr->pos[1]; + cs[2] = ray->final_posr->pos[2] - ccyl->final_posr->pos[2]; + k = dCalcVectorDot3_41(ccyl->final_posr->R+2,cs); // position of ray start along ccyl axis + q[0] = k*ccyl->final_posr->R[0*4+2] - cs[0]; + q[1] = k*ccyl->final_posr->R[1*4+2] - cs[1]; + q[2] = k*ccyl->final_posr->R[2*4+2] - cs[2]; + C = dCalcVectorDot3(q,q) - ccyl->radius*ccyl->radius; + // if C < 0 then ray start position within infinite extension of cylinder + + // see if ray start position is inside the capped cylinder + int inside_ccyl = 0; + if (C < 0) { + if (k < -lz2) k = -lz2; + else if (k > lz2) k = lz2; + r[0] = ccyl->final_posr->pos[0] + k*ccyl->final_posr->R[0*4+2]; + r[1] = ccyl->final_posr->pos[1] + k*ccyl->final_posr->R[1*4+2]; + r[2] = ccyl->final_posr->pos[2] + k*ccyl->final_posr->R[2*4+2]; + if ((ray->final_posr->pos[0]-r[0])*(ray->final_posr->pos[0]-r[0]) + + (ray->final_posr->pos[1]-r[1])*(ray->final_posr->pos[1]-r[1]) + + (ray->final_posr->pos[2]-r[2])*(ray->final_posr->pos[2]-r[2]) < ccyl->radius*ccyl->radius) { + inside_ccyl = 1; + } + } + + // compute ray collision with infinite cylinder, except for the case where + // the ray is outside the capped cylinder but within the infinite cylinder + // (it that case the ray can only hit endcaps) + if (!inside_ccyl && C < 0) { + // set k to cap position to check + if (k < 0) k = -lz2; else k = lz2; + } + else { + dReal uv = dCalcVectorDot3_44(ccyl->final_posr->R+2,ray->final_posr->R+2); + r[0] = uv*ccyl->final_posr->R[0*4+2] - ray->final_posr->R[0*4+2]; + r[1] = uv*ccyl->final_posr->R[1*4+2] - ray->final_posr->R[1*4+2]; + r[2] = uv*ccyl->final_posr->R[2*4+2] - ray->final_posr->R[2*4+2]; + dReal A = dCalcVectorDot3(r,r); + // A == 0 means that the ray and ccylinder axes are parallel + if (A == 0) { // There is a division by A below... + // set k to cap position to check + if (uv < 0) k = -lz2; else k = lz2; + } + else { + dReal B = 2*dCalcVectorDot3(q,r); + k = B*B-4*A*C; + if (k < 0) { + // the ray does not intersect the infinite cylinder, but if the ray is + // inside and parallel to the cylinder axis it may intersect the end + // caps. set k to cap position to check. + if (!inside_ccyl) return 0; + if (uv < 0) k = -lz2; else k = lz2; + } + else { + k = dSqrt(k); + A = dRecip (2*A); + dReal alpha = (-B-k)*A; + if (alpha < 0) { + alpha = (-B+k)*A; + if (alpha < 0) return 0; + } + if (alpha > ray->length) return 0; + + // the ray intersects the infinite cylinder. check to see if the + // intersection point is between the caps + contact->pos[0] = ray->final_posr->pos[0] + alpha*ray->final_posr->R[0*4+2]; + contact->pos[1] = ray->final_posr->pos[1] + alpha*ray->final_posr->R[1*4+2]; + contact->pos[2] = ray->final_posr->pos[2] + alpha*ray->final_posr->R[2*4+2]; + q[0] = contact->pos[0] - ccyl->final_posr->pos[0]; + q[1] = contact->pos[1] - ccyl->final_posr->pos[1]; + q[2] = contact->pos[2] - ccyl->final_posr->pos[2]; + k = dCalcVectorDot3_14(q,ccyl->final_posr->R+2); + dReal nsign = inside_ccyl ? REAL(-1.0) : REAL(1.0); + if (k >= -lz2 && k <= lz2) { + contact->normal[0] = nsign * (contact->pos[0] - + (ccyl->final_posr->pos[0] + k*ccyl->final_posr->R[0*4+2])); + contact->normal[1] = nsign * (contact->pos[1] - + (ccyl->final_posr->pos[1] + k*ccyl->final_posr->R[1*4+2])); + contact->normal[2] = nsign * (contact->pos[2] - + (ccyl->final_posr->pos[2] + k*ccyl->final_posr->R[2*4+2])); + dNormalize3 (contact->normal); + contact->depth = alpha; + return 1; + } + + // the infinite cylinder intersection point is not between the caps. + // set k to cap position to check. + if (k < 0) k = -lz2; else k = lz2; + } + } + } + + // check for ray intersection with the caps. k must indicate the cap + // position to check + q[0] = ccyl->final_posr->pos[0] + k*ccyl->final_posr->R[0*4+2]; + q[1] = ccyl->final_posr->pos[1] + k*ccyl->final_posr->R[1*4+2]; + q[2] = ccyl->final_posr->pos[2] + k*ccyl->final_posr->R[2*4+2]; + return ray_sphere_helper (ray,q,ccyl->radius,contact, inside_ccyl); +} + + +int dCollideRayPlane (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dRayClass); + dIASSERT (o2->type == dPlaneClass); + dIASSERT ((flags & NUMC_MASK) >= 1); + + dxRay *ray = (dxRay*) o1; + dxPlane *plane = (dxPlane*) o2; + + dReal alpha = plane->p[3] - dCalcVectorDot3 (plane->p,ray->final_posr->pos); + // note: if alpha > 0 the starting point is below the plane + dReal nsign = (alpha > 0) ? REAL(-1.0) : REAL(1.0); + dReal k = dCalcVectorDot3_14(plane->p,ray->final_posr->R+2); + if (k==0) return 0; // ray parallel to plane + alpha /= k; + if (alpha < 0 || alpha > ray->length) return 0; + contact->pos[0] = ray->final_posr->pos[0] + alpha*ray->final_posr->R[0*4+2]; + contact->pos[1] = ray->final_posr->pos[1] + alpha*ray->final_posr->R[1*4+2]; + contact->pos[2] = ray->final_posr->pos[2] + alpha*ray->final_posr->R[2*4+2]; + contact->normal[0] = nsign*plane->p[0]; + contact->normal[1] = nsign*plane->p[1]; + contact->normal[2] = nsign*plane->p[2]; + contact->depth = alpha; + contact->g1 = ray; + contact->g2 = plane; + contact->side1 = -1; + contact->side2 = -1; + return 1; +} + +// Ray-Cylinder collider by Joseph Cooper (2011) +int dCollideRayCylinder( dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip ) +{ + dIASSERT( skip >= (int)sizeof( dContactGeom ) ); + dIASSERT( o1->type == dRayClass ); + dIASSERT( o2->type == dCylinderClass ); + dIASSERT( (flags & NUMC_MASK) >= 1 ); + + dxRay* ray = (dxRay*)( o1 ); + dxCylinder* cyl = (dxCylinder*)( o2 ); + + // Fill in contact information. + contact->g1 = ray; + contact->g2 = cyl; + contact->side1 = -1; + contact->side2 = -1; + + const dReal half_length = cyl->lz * REAL( 0.5 ); + + + /* Possible collision cases: + * Ray origin between/outside caps + * Ray origin within/outside radius + * Ray direction left/right/perpendicular + * Ray direction parallel/perpendicular/other + * + * Ray origin cases (ignoring origin on surface) + * + * A B + * /-\-----------\ + * C ( ) D ) + * \_/___________/ + * + * Cases A and D can collide with caps or cylinder + * Case C can only collide with the caps + * Case B can only collide with the cylinder + * Case D will produce inverted normals + * If the ray is perpendicular, only check the cylinder + * If the ray is parallel to cylinder axis, + * we can only check caps + * If the ray points right, + * Case A,C Check left cap + * Case D Check right cap + * If the ray points left + * Case A,C Check right cap + * Case D Check left cap + * Case B, check only first possible cylinder collision + * Case D, check only second possible cylinder collision + */ + // Find the ray in the cylinder coordinate frame: + dVector3 tmp; + dVector3 pos; // Ray origin in cylinder frame + dVector3 dir; // Ray direction in cylinder frame + // Translate ray start by inverse cyl + dSubtractVectors3(tmp,ray->final_posr->pos,cyl->final_posr->pos); + // Rotate ray start by inverse cyl + dMultiply1_331(pos,cyl->final_posr->R,tmp); + + // Get the ray's direction + tmp[0] = ray->final_posr->R[2]; + tmp[1] = ray->final_posr->R[6]; + tmp[2] = ray->final_posr->R[10]; + // Rotate the ray direction by inverse cyl + dMultiply1_331(dir,cyl->final_posr->R,tmp); + + // Is the ray origin inside of the (extended) cylinder? + dReal r2 = cyl->radius*cyl->radius; + dReal C = pos[0]*pos[0] + pos[1]*pos[1] - r2; + + // Find the different cases + // Is ray parallel to the cylinder length? + int parallel = (dir[0]==0 && dir[1]==0); + // Is ray perpendicular to the cylinder length? + int perpendicular = (dir[2]==0); + // Is ray origin within the radius of the caps? + int inRadius = (C<=0); + // Is ray origin between the top and bottom caps? + int inCaps = (dFabs(pos[2])<=half_length); + + int checkCaps = (!perpendicular && (!inCaps || inRadius)); + int checkCyl = (!parallel && (!inRadius || inCaps)); + int flipNormals = (inCaps&&inRadius); + + dReal tt=-dInfinity; // Depth to intersection + dVector3 tmpNorm = {dNaN, dNaN, dNaN}; // ensure we don't leak garbage + + if (checkCaps) { + // Make it so we only need to check one cap + int flipDir = 0; + // Wish c had logical xor... + if ((dir[2]<0 && flipNormals) || (dir[2]>0 && !flipNormals)) { + flipDir = 1; + dir[2]=-dir[2]; + pos[2]=-pos[2]; + } + // The cap is half the cylinder's length + // from the cylinder's origin + // We only checkCaps if dir[2]!=0 + tt = (half_length-pos[2])/dir[2]; + if (tt>=0 && tt<=ray->length) { + tmp[0] = pos[0] + tt*dir[0]; + tmp[1] = pos[1] + tt*dir[1]; + // Ensure collision point is within cap circle + if (tmp[0]*tmp[0] + tmp[1]*tmp[1] <= r2) { + // Successful collision + tmp[2] = (flipDir)?-half_length:half_length; + tmpNorm[0]=0; + tmpNorm[1]=0; + tmpNorm[2]=(flipDir!=flipNormals)?-REAL(1.0):REAL(1.0); + checkCyl = 0; // Short circuit cylinder check + } else { + // Ray hits cap plane outside of cap circle + tt=-dInfinity; // No collision yet + } + } else { + // The cap plane is beyond (or behind) the ray length + tt=-dInfinity; // No collision yet + } + if (flipDir) { + // Flip back + dir[2]=-dir[2]; + pos[2]=-pos[2]; + } + } + if (checkCyl) { + // Compute quadratic formula for parametric ray equation + dReal A = dir[0]*dir[0] + dir[1]*dir[1]; + dReal B = 2*(pos[0]*dir[0] + pos[1]*dir[1]); + // Already computed C + + dReal k = B*B - 4*A*C; + // Check collision with infinite cylinder + // k<0 means the ray passes outside the cylinder + // k==0 means ray is tangent to cylinder (or parallel) + // + // Our quadratic formula: tt = (-B +- sqrt(k))/(2*A) + // + // A must be positive (otherwise we wouldn't be checking + // cylinder because ray is parallel) + // if (k<0) ray doesn't collide with sphere + // if (B > sqrt(k)) then both times are negative + // -- don't calculate + // if (B<-sqrt(k)) then both times are positive (Case A or B) + // -- only calculate first, if first isn't valid + // -- second can't be without first going through a cap + // otherwise (fabs(B)<=sqrt(k)) then C<=0 (ray-origin inside/on cylinder) + // -- only calculate second collision + if (k>=0 && (B<0 || B*B<=k)) { + k = dSqrt(k); + A = dRecip(2*A); + if (dFabs(B)<=k) { + tt = (-B + k)*A; // Second solution + // If ray origin is on surface and pointed out, we + // can get a tt=0 solution... + } else { + tt = (-B - k)*A; // First solution + } + if (tt<=ray->length) { + tmp[2] = pos[2] + tt*dir[2]; + if (dFabs(tmp[2])<=half_length) { + // Valid solution + tmp[0] = pos[0] + tt*dir[0]; + tmp[1] = pos[1] + tt*dir[1]; + tmpNorm[0] = tmp[0]/cyl->radius; + tmpNorm[1] = tmp[1]/cyl->radius; + tmpNorm[2] = 0; + if (flipNormals) { + // Ray origin was inside cylinder + tmpNorm[0] = -tmpNorm[0]; + tmpNorm[1] = -tmpNorm[1]; + } + } else { + // Ray hits cylinder outside of caps + tt=-dInfinity; + } + } else { + // Ray doesn't reach the cylinder + tt=-dInfinity; + } + } + } + + if (tt>0) { + contact->depth = tt; + // Transform the point back to world coordinates + tmpNorm[3]=0; + tmp[3] = 0; + dMultiply0_331(contact->normal,cyl->final_posr->R,tmpNorm); + dMultiply0_331(contact->pos,cyl->final_posr->R,tmp); + contact->pos[0]+=cyl->final_posr->pos[0]; + contact->pos[1]+=cyl->final_posr->pos[1]; + contact->pos[2]+=cyl->final_posr->pos[2]; + + return 1; + } + // No contact with anything. + return 0; +} diff --git a/libs/ode-0.16.1/ode/src/resource_control.cpp b/libs/ode-0.16.1/ode/src/resource_control.cpp new file mode 100644 index 0000000..29a3d83 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/resource_control.cpp @@ -0,0 +1,259 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * Resource accounting/preallocation class implementations + * Copyright (c) 2017-2019 Oleh Derevenko, odar@eleks.com (change all "a" to "e") + */ + + +#include <ode/common.h> +#include <ode/cooperative.h> +#include "config.h" +#include "resource_control.h" +#include "simple_cooperative.h" + + +////////////////////////////////////////////////////////////////////////// +// dxResourceRequirementDescriptor(); + +dxResourceRequirementDescriptor::~dxResourceRequirementDescriptor() +{ + // Do nothing +} + + +////////////////////////////////////////////////////////////////////////// +// dxRequiredResourceContainer + +dxRequiredResourceContainer::~dxRequiredResourceContainer() +{ + freeResources(); +} + + +bool dxRequiredResourceContainer::allocateResources(const dxResourceRequirementDescriptor &requirementDescriptor) +{ + bool result = false; + + bool bufferAllocated = false; + + do + { + sizeint memorySizeRequirement = requirementDescriptor.getMemorySizeRequirement(); + + if (memorySizeRequirement != 0) + { + unsigned memoryAlignmentRequirement = requirementDescriptor.getMemoryAlignmentRequirement(); + void *bufferAllocated = m_memoryAllocation.allocAligned(memorySizeRequirement, memoryAlignmentRequirement); + if (bufferAllocated == NULL) + { + break; + } + } + bufferAllocated = true; + + dxThreadingBase *relatedThreading = requirementDescriptor.getrelatedThreading(); + dIASSERT(relatedThreading != NULL); + + unsigned simultaneousCallRequirement = requirementDescriptor.getSimultaneousCallRequirement(); + if (simultaneousCallRequirement != 0) + { + if (!relatedThreading->PreallocateResourcesForThreadedCalls(simultaneousCallRequirement)) + { + break; + } + } + + dCallWaitID stockCallWait = NULL; + + if (requirementDescriptor.getIsStockCallWaitRequired()) + { + stockCallWait = relatedThreading->AllocateOrRetrieveStockCallWaitID(); + if (stockCallWait == NULL) + { + break; + } + } + + m_relatedThreading = relatedThreading; + m_stockCallWait = stockCallWait; + + result = true; + } + while (false); + + if (!result) + { + if (bufferAllocated) + { + m_memoryAllocation.freeAllocation(); + } + } + + return result; + +} + +void dxRequiredResourceContainer::freeResources() +{ + if (m_relatedThreading != NULL) + { + m_relatedThreading = NULL; + m_stockCallWait = NULL; + m_memoryAllocation.freeAllocation(); + } + else + { + dIASSERT(m_stockCallWait == NULL); + dIASSERT(m_memoryAllocation.getUserAreaPointer() == NULL); + } +} + + +////////////////////////////////////////////////////////////////////////// +// Public interface functions + +static inline +dResourceRequirementsID encodeResourceRequirementsID(dxResourceRequirementDescriptor *requirementsDescriptor) +{ + return (dResourceRequirementsID)requirementsDescriptor; +} + + +/*extern ODE_API */ +dResourceRequirementsID dResourceRequirementsCreate(dCooperativeID cooperative) +{ + dAASSERT(cooperative != NULL); + + dxSimpleCooperative *cooperativeInstance = decodeCooperativeID(cooperative); + dxThreadingBase *threading = cooperativeInstance->getRelatedThreading(); + + dxResourceRequirementDescriptor *requirementsDescriptor = new dxResourceRequirementDescriptor(threading); + + dResourceRequirementsID result = encodeResourceRequirementsID(requirementsDescriptor); + return result; +} + +/*extern ODE_API */ +void dResourceRequirementsDestroy(dResourceRequirementsID requirements) +{ + dxResourceRequirementDescriptor *requirementsDescriptor = decodeResourceRequirementsID(requirements); + + if (requirementsDescriptor != NULL) + { + delete requirementsDescriptor; + } +} + + +/*extern ODE_API */ +dResourceRequirementsID dResourceRequirementsClone(/*const */dResourceRequirementsID requirements) +{ + dAASSERT(requirements != NULL); + + dxResourceRequirementDescriptor *requirementsDescriptor = decodeResourceRequirementsID(requirements); + + dxResourceRequirementDescriptor *descriptorClone = new dxResourceRequirementDescriptor(*requirementsDescriptor); + + dResourceRequirementsID result = encodeResourceRequirementsID(descriptorClone); + return result; +} + +/*extern ODE_API */ +void dResourceRequirementsMergeIn(dResourceRequirementsID summaryRequirements, /*const */dResourceRequirementsID extraRequirements) +{ + dAASSERT(summaryRequirements != NULL); + dAASSERT(extraRequirements != NULL); + + dxResourceRequirementDescriptor *summaryDescriptor = decodeResourceRequirementsID(summaryRequirements); + dxResourceRequirementDescriptor *extraDescriptor = decodeResourceRequirementsID(extraRequirements); + + summaryDescriptor->mergeAnotherDescriptorIn(*extraDescriptor); +} + + +////////////////////////////////////////////////////////////////////////// + +static inline +dResourceContainerID encodeResourceContainerID(dxRequiredResourceContainer *containerInstance) +{ + return (dResourceContainerID)containerInstance; +} + + +/*extern ODE_API */ +dResourceContainerID dResourceContainerAcquire(/*const */dResourceRequirementsID requirements) +{ + dAASSERT(requirements != NULL); + + dResourceContainerID result = NULL; + bool allocationSucceeded = false; + + dxRequiredResourceContainer *containerInstance; + bool containerAllocated = false; + + dxResourceRequirementDescriptor *requirementsInstance = decodeResourceRequirementsID(requirements); + + do + { + containerInstance = new dxRequiredResourceContainer(); + + if (containerInstance == NULL) + { + break; + } + + containerAllocated = true; + + if (!containerInstance->allocateResources(*requirementsInstance)) + { + break; + } + + result = encodeResourceContainerID(containerInstance); + allocationSucceeded = true; + } + while (false); + + if (!allocationSucceeded) + { + if (containerAllocated) + { + delete containerInstance; + } + } + + return result; +} + +/*extern ODE_API */ +void dResourceContainerDestroy(dResourceContainerID resources) +{ + dxRequiredResourceContainer *containerInstance = decodeResourceContainerID(resources); + + if (containerInstance != NULL) + { + delete containerInstance; + } +} + diff --git a/libs/ode-0.16.1/ode/src/resource_control.h b/libs/ode-0.16.1/ode/src/resource_control.h new file mode 100644 index 0000000..cadae0e --- /dev/null +++ b/libs/ode-0.16.1/ode/src/resource_control.h @@ -0,0 +1,151 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * Resource accounting/preallocation class declarations + * Copyright (c) 2017-2019 Oleh Derevenko, odar@eleks.com (change all "a" to "e") + */ + +#ifndef _ODE__PRIVATE_RESOURCE_CONTRIOL_H_ +#define _ODE__PRIVATE_RESOURCE_CONTRIOL_H_ + + +#include "objects.h" +#include "threading_base.h" +#include "odeou.h" +#include "common.h" +#include "error.h" + + +using _OU_NAMESPACE::CSimpleFlags; + + +class dxResourceRequirementDescriptor: + public dBase +{ +public: + explicit dxResourceRequirementDescriptor(dxThreadingBase *relatedThreading): + dBase(), + m_relatedThreading(relatedThreading), + m_memorySizeRequirement(0), + m_memoryAlignmentRequirement(0), + m_simultaneousCallRequirement(0), + m_featureRequirements() + { + } + + ~dxResourceRequirementDescriptor(); + + enum + { + STOCK_CALLWAIT_REQUIRED = 0x00000001, + }; + + void mergeAnotherDescriptorIn(const dxResourceRequirementDescriptor &anotherDescriptor) + { + dIASSERT(getrelatedThreading() == anotherDescriptor.getrelatedThreading()); // m_simultaneousCallRequirement typically depends on threading used + + CSimpleFlags::value_type allOtherFeatureFlags = anotherDescriptor.queryAllFeatureFlags(); + mergeAnotherDescriptorIn(anotherDescriptor.m_memorySizeRequirement, anotherDescriptor.m_memoryAlignmentRequirement, anotherDescriptor.m_simultaneousCallRequirement, allOtherFeatureFlags); + } + + void mergeAnotherDescriptorIn(sizeint memorySizeRequirement/*=0*/, unsigned memoryAlignmentRequirement, + unsigned simultaneousCallRequirement/*=0*/, unsigned featureRequirement/*=0*/) + { + m_memorySizeRequirement = dMACRO_MAX(m_memorySizeRequirement, memorySizeRequirement); + m_memoryAlignmentRequirement = dMACRO_MAX(m_memoryAlignmentRequirement, memoryAlignmentRequirement); + m_simultaneousCallRequirement = dMACRO_MAX(m_simultaneousCallRequirement, simultaneousCallRequirement); + mergeFeatureFlags(featureRequirement); + } + +public: + dxThreadingBase *getrelatedThreading() const { return m_relatedThreading; } + sizeint getMemorySizeRequirement() const { return m_memorySizeRequirement; } + unsigned getMemoryAlignmentRequirement() const { return m_memoryAlignmentRequirement; } + + unsigned getSimultaneousCallRequirement() const { return m_simultaneousCallRequirement; } + + bool getIsStockCallWaitRequired() const { return getStockCallWaitRequiredFlag(); } + +private: + enum + { + FL_STOCK_CALLWAIT_REQUIRED = STOCK_CALLWAIT_REQUIRED, + }; + + bool getStockCallWaitRequiredFlag() const { return m_featureRequirements.GetFlagsMaskValue(FL_STOCK_CALLWAIT_REQUIRED); } + + CSimpleFlags::value_type queryAllFeatureFlags() const { return m_featureRequirements.QueryFlagsAllValues(); } + void mergeFeatureFlags(CSimpleFlags::value_type flagValues) { m_featureRequirements.SignalFlagsMaskValue(flagValues); } + +private: + dxThreadingBase *m_relatedThreading; + sizeint m_memorySizeRequirement; + unsigned m_memoryAlignmentRequirement; + unsigned m_simultaneousCallRequirement; + CSimpleFlags m_featureRequirements; +}; + +static inline +dxResourceRequirementDescriptor *decodeResourceRequirementsID(dResourceRequirementsID requirements) +{ + return (dxResourceRequirementDescriptor *)requirements; +} + + +class dxRequiredResourceContainer: + public dBase +{ +public: + dxRequiredResourceContainer(): + dBase(), + m_relatedThreading(NULL), + m_stockCallWait(NULL), + m_memoryAllocation() + { + } + + ~dxRequiredResourceContainer(); + + bool allocateResources(const dxResourceRequirementDescriptor &requirementDescriptor); + void freeResources(); + +public: + dxThreadingBase *getThreadingInstance() const { return m_relatedThreading; } + dCallWaitID getStockCallWait() const { return m_stockCallWait; } + void *getMemoryBufferPointer() const { return m_memoryAllocation.getUserAreaPointer(); } + sizeint getMemoryBufferSize() const { return m_memoryAllocation.getUserAreaSize(); } + +private: + dxThreadingBase *m_relatedThreading; + dCallWaitID m_stockCallWait; + dxAlignedAllocation m_memoryAllocation; +}; + +static inline +dxRequiredResourceContainer *decodeResourceContainerID(dResourceContainerID resources) +{ + return (dxRequiredResourceContainer *)resources; +} + + +#endif // #ifndef _ODE__PRIVATE_RESOURCE_CONTRIOL_H_ diff --git a/libs/ode-0.16.1/ode/src/rotation.cpp b/libs/ode-0.16.1/ode/src/rotation.cpp new file mode 100644 index 0000000..e813ba3 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/rotation.cpp @@ -0,0 +1,317 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +quaternions have the format: (s,vx,vy,vz) where (vx,vy,vz) is the +"rotation axis" and s is the "rotation angle". + +*/ + +#include <ode/rotation.h> +#include "config.h" +#include "odemath.h" + + +#define _R(i,j) R[(i)*4+(j)] + +#define SET_3x3_IDENTITY \ + _R(0,0) = REAL(1.0); \ + _R(0,1) = REAL(0.0); \ + _R(0,2) = REAL(0.0); \ + _R(0,3) = REAL(0.0); \ + _R(1,0) = REAL(0.0); \ + _R(1,1) = REAL(1.0); \ + _R(1,2) = REAL(0.0); \ + _R(1,3) = REAL(0.0); \ + _R(2,0) = REAL(0.0); \ + _R(2,1) = REAL(0.0); \ + _R(2,2) = REAL(1.0); \ + _R(2,3) = REAL(0.0); + + +void dRSetIdentity (dMatrix3 R) +{ + dAASSERT (R); + SET_3x3_IDENTITY; +} + + +void dRFromAxisAndAngle (dMatrix3 R, dReal ax, dReal ay, dReal az, + dReal angle) +{ + dAASSERT (R); + dQuaternion q; + dQFromAxisAndAngle (q,ax,ay,az,angle); + dQtoR (q,R); +} + + +void dRFromEulerAngles (dMatrix3 R, dReal phi, dReal theta, dReal psi) +{ + dReal sphi,cphi,stheta,ctheta,spsi,cpsi; + dAASSERT (R); + sphi = dSin(phi); + cphi = dCos(phi); + stheta = dSin(theta); + ctheta = dCos(theta); + spsi = dSin(psi); + cpsi = dCos(psi); + _R(0,0) = cpsi*ctheta; + _R(0,1) = spsi*ctheta; + _R(0,2) =-stheta; + _R(0,3) = REAL(0.0); + _R(1,0) = cpsi*stheta*sphi - spsi*cphi; + _R(1,1) = spsi*stheta*sphi + cpsi*cphi; + _R(1,2) = ctheta*sphi; + _R(1,3) = REAL(0.0); + _R(2,0) = cpsi*stheta*cphi + spsi*sphi; + _R(2,1) = spsi*stheta*cphi - cpsi*sphi; + _R(2,2) = ctheta*cphi; + _R(2,3) = REAL(0.0); +} + + +void dRFrom2Axes (dMatrix3 R, dReal ax, dReal ay, dReal az, + dReal bx, dReal by, dReal bz) +{ + dReal l,k; + dAASSERT (R); + l = dSqrt (ax*ax + ay*ay + az*az); + if (l <= REAL(0.0)) { + dDEBUGMSG ("zero length vector"); + return; + } + l = dRecip(l); + ax *= l; + ay *= l; + az *= l; + k = ax*bx + ay*by + az*bz; + bx -= k*ax; + by -= k*ay; + bz -= k*az; + l = dSqrt (bx*bx + by*by + bz*bz); + if (l <= REAL(0.0)) { + dDEBUGMSG ("zero length vector"); + return; + } + l = dRecip(l); + bx *= l; + by *= l; + bz *= l; + _R(0,0) = ax; + _R(1,0) = ay; + _R(2,0) = az; + _R(0,1) = bx; + _R(1,1) = by; + _R(2,1) = bz; + _R(0,2) = - by*az + ay*bz; + _R(1,2) = - bz*ax + az*bx; + _R(2,2) = - bx*ay + ax*by; + _R(0,3) = REAL(0.0); + _R(1,3) = REAL(0.0); + _R(2,3) = REAL(0.0); +} + + +void dRFromZAxis (dMatrix3 R, dReal ax, dReal ay, dReal az) +{ + dVector3 n,p,q; + n[0] = ax; + n[1] = ay; + n[2] = az; + dNormalize3 (n); + dPlaneSpace (n,p,q); + _R(0,0) = p[0]; + _R(1,0) = p[1]; + _R(2,0) = p[2]; + _R(0,1) = q[0]; + _R(1,1) = q[1]; + _R(2,1) = q[2]; + _R(0,2) = n[0]; + _R(1,2) = n[1]; + _R(2,2) = n[2]; + _R(0,3) = REAL(0.0); + _R(1,3) = REAL(0.0); + _R(2,3) = REAL(0.0); +} + + +void dQSetIdentity (dQuaternion q) +{ + dAASSERT (q); + q[0] = 1; + q[1] = 0; + q[2] = 0; + q[3] = 0; +} + + +void dQFromAxisAndAngle (dQuaternion q, dReal ax, dReal ay, dReal az, + dReal angle) +{ + dAASSERT (q); + dReal l = ax*ax + ay*ay + az*az; + if (l > REAL(0.0)) { + angle *= REAL(0.5); + q[0] = dCos (angle); + l = dSin(angle) * dRecipSqrt(l); + q[1] = ax*l; + q[2] = ay*l; + q[3] = az*l; + } + else { + q[0] = 1; + q[1] = 0; + q[2] = 0; + q[3] = 0; + } +} + + +void dQMultiply0 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc) +{ + dAASSERT (qa && qb && qc); + qa[0] = qb[0]*qc[0] - qb[1]*qc[1] - qb[2]*qc[2] - qb[3]*qc[3]; + qa[1] = qb[0]*qc[1] + qb[1]*qc[0] + qb[2]*qc[3] - qb[3]*qc[2]; + qa[2] = qb[0]*qc[2] + qb[2]*qc[0] + qb[3]*qc[1] - qb[1]*qc[3]; + qa[3] = qb[0]*qc[3] + qb[3]*qc[0] + qb[1]*qc[2] - qb[2]*qc[1]; +} + + +void dQMultiply1 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc) +{ + dAASSERT (qa && qb && qc); + qa[0] = qb[0]*qc[0] + qb[1]*qc[1] + qb[2]*qc[2] + qb[3]*qc[3]; + qa[1] = qb[0]*qc[1] - qb[1]*qc[0] - qb[2]*qc[3] + qb[3]*qc[2]; + qa[2] = qb[0]*qc[2] - qb[2]*qc[0] - qb[3]*qc[1] + qb[1]*qc[3]; + qa[3] = qb[0]*qc[3] - qb[3]*qc[0] - qb[1]*qc[2] + qb[2]*qc[1]; +} + + +void dQMultiply2 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc) +{ + dAASSERT (qa && qb && qc); + qa[0] = qb[0]*qc[0] + qb[1]*qc[1] + qb[2]*qc[2] + qb[3]*qc[3]; + qa[1] = -qb[0]*qc[1] + qb[1]*qc[0] - qb[2]*qc[3] + qb[3]*qc[2]; + qa[2] = -qb[0]*qc[2] + qb[2]*qc[0] - qb[3]*qc[1] + qb[1]*qc[3]; + qa[3] = -qb[0]*qc[3] + qb[3]*qc[0] - qb[1]*qc[2] + qb[2]*qc[1]; +} + + +void dQMultiply3 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc) +{ + dAASSERT (qa && qb && qc); + qa[0] = qb[0]*qc[0] - qb[1]*qc[1] - qb[2]*qc[2] - qb[3]*qc[3]; + qa[1] = -qb[0]*qc[1] - qb[1]*qc[0] + qb[2]*qc[3] - qb[3]*qc[2]; + qa[2] = -qb[0]*qc[2] - qb[2]*qc[0] + qb[3]*qc[1] - qb[1]*qc[3]; + qa[3] = -qb[0]*qc[3] - qb[3]*qc[0] + qb[1]*qc[2] - qb[2]*qc[1]; +} + + +// dRfromQ(), dQfromR() and dDQfromW() are derived from equations in "An Introduction +// to Physically Based Modeling: Rigid Body Simulation - 1: Unconstrained +// Rigid Body Dynamics" by David Baraff, Robotics Institute, Carnegie Mellon +// University, 1997. + +void dRfromQ (dMatrix3 R, const dQuaternion q) +{ + dAASSERT (q && R); + // q = (s,vx,vy,vz) + dReal qq1 = 2*q[1]*q[1]; + dReal qq2 = 2*q[2]*q[2]; + dReal qq3 = 2*q[3]*q[3]; + _R(0,0) = 1 - qq2 - qq3; + _R(0,1) = 2*(q[1]*q[2] - q[0]*q[3]); + _R(0,2) = 2*(q[1]*q[3] + q[0]*q[2]); + _R(0,3) = REAL(0.0); + _R(1,0) = 2*(q[1]*q[2] + q[0]*q[3]); + _R(1,1) = 1 - qq1 - qq3; + _R(1,2) = 2*(q[2]*q[3] - q[0]*q[1]); + _R(1,3) = REAL(0.0); + _R(2,0) = 2*(q[1]*q[3] - q[0]*q[2]); + _R(2,1) = 2*(q[2]*q[3] + q[0]*q[1]); + _R(2,2) = 1 - qq1 - qq2; + _R(2,3) = REAL(0.0); +} + + +void dQfromR (dQuaternion q, const dMatrix3 R) +{ + dAASSERT (q && R); + dReal tr,s; + tr = _R(0,0) + _R(1,1) + _R(2,2); + if (tr >= 0) { + s = dSqrt (tr + 1); + q[0] = REAL(0.5) * s; + s = REAL(0.5) * dRecip(s); + q[1] = (_R(2,1) - _R(1,2)) * s; + q[2] = (_R(0,2) - _R(2,0)) * s; + q[3] = (_R(1,0) - _R(0,1)) * s; + } + else { + // find the largest diagonal element and jump to the appropriate case + if (_R(1,1) > _R(0,0)) { + if (_R(2,2) > _R(1,1)) goto case_2; + goto case_1; + } + if (_R(2,2) > _R(0,0)) goto case_2; + goto case_0; + +case_0: + s = dSqrt((_R(0,0) - (_R(1,1) + _R(2,2))) + 1); + q[1] = REAL(0.5) * s; + s = REAL(0.5) * dRecip(s); + q[2] = (_R(0,1) + _R(1,0)) * s; + q[3] = (_R(2,0) + _R(0,2)) * s; + q[0] = (_R(2,1) - _R(1,2)) * s; + return; + +case_1: + s = dSqrt((_R(1,1) - (_R(2,2) + _R(0,0))) + 1); + q[2] = REAL(0.5) * s; + s = REAL(0.5) * dRecip(s); + q[3] = (_R(1,2) + _R(2,1)) * s; + q[1] = (_R(0,1) + _R(1,0)) * s; + q[0] = (_R(0,2) - _R(2,0)) * s; + return; + +case_2: + s = dSqrt((_R(2,2) - (_R(0,0) + _R(1,1))) + 1); + q[3] = REAL(0.5) * s; + s = REAL(0.5) * dRecip(s); + q[1] = (_R(2,0) + _R(0,2)) * s; + q[2] = (_R(1,2) + _R(2,1)) * s; + q[0] = (_R(1,0) - _R(0,1)) * s; + return; + } +} + + +void dDQfromW (dReal dq[4], const dVector3 w, const dQuaternion q) +{ + dAASSERT (w && q && dq); + dq[0] = REAL(0.5)*(- w[0]*q[1] - w[1]*q[2] - w[2]*q[3]); + dq[1] = REAL(0.5)*( w[0]*q[0] + w[1]*q[3] - w[2]*q[2]); + dq[2] = REAL(0.5)*(- w[0]*q[3] + w[1]*q[0] + w[2]*q[1]); + dq[3] = REAL(0.5)*( w[0]*q[2] - w[1]*q[1] + w[2]*q[0]); +} diff --git a/libs/ode-0.16.1/ode/src/simple_cooperative.cpp b/libs/ode-0.16.1/ode/src/simple_cooperative.cpp new file mode 100644 index 0000000..f8f6f7d --- /dev/null +++ b/libs/ode-0.16.1/ode/src/simple_cooperative.cpp @@ -0,0 +1,84 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * Threading base wrapper class header file. * + * Copyright (C) 2011-2019 Oleh Derevenko. All rights reserved. * + * e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * The simple cooperative class implementation + * Copyright (c) 2017-2019 Oleh Derevenko, odar@eleks.com (change all "a" to "e") + */ + + +#include <ode/common.h> +#include <ode/cooperative.h> +#include "config.h" +#include "simple_cooperative.h" +#include "default_threading.h" + + +/*virtual */ +dxSimpleCooperative::~dxSimpleCooperative() +{ + // The virtual destructor +} + + +/*virtual */ +const dxThreadingFunctionsInfo *dxSimpleCooperative::retrieveThreadingDefaultImpl(dThreadingImplementationID &out_defaultImpl) +{ + out_defaultImpl = DefaultThreadingHolder::getDefaultThreadingImpl(); + return DefaultThreadingHolder::getDefaultThreadingFunctions(); +} + + +////////////////////////////////////////////////////////////////////////// +// Public interface functions + +static inline +dCooperativeID encodeCooperativeID(dxSimpleCooperative *cooperativeInstance) +{ + return (dCooperativeID)cooperativeInstance; +} + + +/*extern ODE_API */ +dCooperativeID dCooperativeCreate(const dThreadingFunctionsInfo *functionInfo/*=NULL*/, dThreadingImplementationID threadingImpl/*=NULL*/) +{ + dxSimpleCooperative *cooperativeInstance = new dxSimpleCooperative(functionInfo, threadingImpl); + + dCooperativeID result = encodeCooperativeID(cooperativeInstance); + return result; +} + +/*extern ODE_API */ +void dCooperativeDestroy(dCooperativeID cooperative) +{ + dxSimpleCooperative *cooperativeInstance = decodeCooperativeID(cooperative); + + if (cooperativeInstance != NULL) + { + delete cooperativeInstance; + } +} + diff --git a/libs/ode-0.16.1/ode/src/simple_cooperative.h b/libs/ode-0.16.1/ode/src/simple_cooperative.h new file mode 100644 index 0000000..8fcbc99 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/simple_cooperative.h @@ -0,0 +1,73 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * Threading base wrapper class header file. * + * Copyright (C) 2011-2019 Oleh Derevenko. All rights reserved. * + * e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * A simple cooperative class definition + * Copyright (c) 2017-2019 Oleh Derevenko, odar@eleks.com (change all "a" to "e") + */ + + +#ifndef _ODE__PRIVATE_SIMPLE_COOPERATIVE_H_ +#define _ODE__PRIVATE_SIMPLE_COOPERATIVE_H_ + + +#include "objects.h" +#include "threading_base.h" + + +typedef dxThreadingBase dxSimpleCooperative_ThreadingParent; +class dxSimpleCooperative: + public dBase, + public dxSimpleCooperative_ThreadingParent, + private dxIThreadingDefaultImplProvider +{ +public: + dxSimpleCooperative(const dxThreadingFunctionsInfo *functionInfo, dThreadingImplementationID threadingImpl): + dBase(), + dxSimpleCooperative_ThreadingParent() + { + dxSimpleCooperative_ThreadingParent::setThreadingDefaultImplProvider(this); + dxSimpleCooperative_ThreadingParent::assignThreadingImpl(functionInfo, threadingImpl); + } + + virtual ~dxSimpleCooperative(); + +public: + dxThreadingBase *getRelatedThreading() const { return const_cast<dxSimpleCooperative *>(this); } + +private: // dxIThreadingDefaultImplProvider + virtual const dxThreadingFunctionsInfo *retrieveThreadingDefaultImpl(dThreadingImplementationID &out_defaultImpl); +}; + + +static inline +dxSimpleCooperative *decodeCooperativeID(dCooperativeID cooperative) +{ + return (dxSimpleCooperative *)cooperative; +} + + +#endif // #ifndef _ODE__PRIVATE_SIMPLE_COOPERATIVE_H_ diff --git a/libs/ode-0.16.1/ode/src/sphere.cpp b/libs/ode-0.16.1/ode/src/sphere.cpp new file mode 100644 index 0000000..e894bac --- /dev/null +++ b/libs/ode-0.16.1/ode/src/sphere.cpp @@ -0,0 +1,251 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +standard ODE geometry primitives: public API and pairwise collision functions. + +the rule is that only the low level primitive collision functions should set +dContactGeom::g1 and dContactGeom::g2. + +*/ + +#include <ode/common.h> +#include <ode/collision.h> +#include <ode/rotation.h> +#include "config.h" +#include "matrix.h" +#include "odemath.h" +#include "collision_kernel.h" +#include "collision_std.h" +#include "collision_util.h" + +#ifdef _MSC_VER +#pragma warning(disable:4291) // for VC++, no complaints about "no matching operator delete found" +#endif + + +//**************************************************************************** +// sphere public API + +dxSphere::dxSphere (dSpaceID space, dReal _radius) : dxGeom (space,1) +{ + dAASSERT (_radius >= 0); + type = dSphereClass; + radius = _radius; + updateZeroSizedFlag(!_radius); +} + + +void dxSphere::computeAABB() +{ + aabb[0] = final_posr->pos[0] - radius; + aabb[1] = final_posr->pos[0] + radius; + aabb[2] = final_posr->pos[1] - radius; + aabb[3] = final_posr->pos[1] + radius; + aabb[4] = final_posr->pos[2] - radius; + aabb[5] = final_posr->pos[2] + radius; +} + + +dGeomID dCreateSphere (dSpaceID space, dReal radius) +{ + return new dxSphere (space,radius); +} + + +void dGeomSphereSetRadius (dGeomID g, dReal radius) +{ + dUASSERT (g && g->type == dSphereClass,"argument not a sphere"); + dAASSERT (radius >= 0); + dxSphere *s = (dxSphere*) g; + s->radius = radius; + s->updateZeroSizedFlag(!radius); + dGeomMoved (g); +} + + +dReal dGeomSphereGetRadius (dGeomID g) +{ + dUASSERT (g && g->type == dSphereClass,"argument not a sphere"); + dxSphere *s = (dxSphere*) g; + return s->radius; +} + + +dReal dGeomSpherePointDepth (dGeomID g, dReal x, dReal y, dReal z) +{ + dUASSERT (g && g->type == dSphereClass,"argument not a sphere"); + g->recomputePosr(); + + dxSphere *s = (dxSphere*) g; + dReal * pos = s->final_posr->pos; + return s->radius - dSqrt ((x-pos[0])*(x-pos[0]) + + (y-pos[1])*(y-pos[1]) + + (z-pos[2])*(z-pos[2])); +} + +//**************************************************************************** +// pairwise collision functions for standard geom types + +int dCollideSphereSphere (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dSphereClass); + dIASSERT (o2->type == dSphereClass); + dIASSERT ((flags & NUMC_MASK) >= 1); + + dxSphere *sphere1 = (dxSphere*) o1; + dxSphere *sphere2 = (dxSphere*) o2; + + contact->g1 = o1; + contact->g2 = o2; + contact->side1 = -1; + contact->side2 = -1; + + return dCollideSpheres (o1->final_posr->pos,sphere1->radius, + o2->final_posr->pos,sphere2->radius,contact); +} + + +int dCollideSphereBox (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dSphereClass); + dIASSERT (o2->type == dBoxClass); + dIASSERT ((flags & NUMC_MASK) >= 1); + + // this is easy. get the sphere center `p' relative to the box, and then clip + // that to the boundary of the box (call that point `q'). if q is on the + // boundary of the box and |p-q| is <= sphere radius, they touch. + // if q is inside the box, the sphere is inside the box, so set a contact + // normal to push the sphere to the closest box face. + + dVector3 l,t,p,q,r; + dReal depth; + int onborder = 0; + + dxSphere *sphere = (dxSphere*) o1; + dxBox *box = (dxBox*) o2; + + contact->g1 = o1; + contact->g2 = o2; + contact->side1 = -1; + contact->side2 = -1; + + p[0] = o1->final_posr->pos[0] - o2->final_posr->pos[0]; + p[1] = o1->final_posr->pos[1] - o2->final_posr->pos[1]; + p[2] = o1->final_posr->pos[2] - o2->final_posr->pos[2]; + + l[0] = box->side[0]*REAL(0.5); + t[0] = dCalcVectorDot3_14(p,o2->final_posr->R); + if (t[0] < -l[0]) { t[0] = -l[0]; onborder = 1; } + if (t[0] > l[0]) { t[0] = l[0]; onborder = 1; } + + l[1] = box->side[1]*REAL(0.5); + t[1] = dCalcVectorDot3_14(p,o2->final_posr->R+1); + if (t[1] < -l[1]) { t[1] = -l[1]; onborder = 1; } + if (t[1] > l[1]) { t[1] = l[1]; onborder = 1; } + + t[2] = dCalcVectorDot3_14(p,o2->final_posr->R+2); + l[2] = box->side[2]*REAL(0.5); + if (t[2] < -l[2]) { t[2] = -l[2]; onborder = 1; } + if (t[2] > l[2]) { t[2] = l[2]; onborder = 1; } + + if (!onborder) { + // sphere center inside box. find closest face to `t' + dReal min_distance = l[0] - dFabs(t[0]); + int mini = 0; + for (int i=1; i<3; i++) { + dReal face_distance = l[i] - dFabs(t[i]); + if (face_distance < min_distance) { + min_distance = face_distance; + mini = i; + } + } + // contact position = sphere center + contact->pos[0] = o1->final_posr->pos[0]; + contact->pos[1] = o1->final_posr->pos[1]; + contact->pos[2] = o1->final_posr->pos[2]; + // contact normal points to closest face + dVector3 tmp; + tmp[0] = 0; + tmp[1] = 0; + tmp[2] = 0; + tmp[mini] = (t[mini] > 0) ? REAL(1.0) : REAL(-1.0); + dMultiply0_331 (contact->normal,o2->final_posr->R,tmp); + // contact depth = distance to wall along normal plus radius + contact->depth = min_distance + sphere->radius; + return 1; + } + + t[3] = 0; //@@@ hmmm + dMultiply0_331 (q,o2->final_posr->R,t); + r[0] = p[0] - q[0]; + r[1] = p[1] - q[1]; + r[2] = p[2] - q[2]; + depth = sphere->radius - dSqrt(dCalcVectorDot3(r,r)); + if (depth < 0) return 0; + contact->pos[0] = q[0] + o2->final_posr->pos[0]; + contact->pos[1] = q[1] + o2->final_posr->pos[1]; + contact->pos[2] = q[2] + o2->final_posr->pos[2]; + contact->normal[0] = r[0]; + contact->normal[1] = r[1]; + contact->normal[2] = r[2]; + dNormalize3 (contact->normal); + contact->depth = depth; + return 1; +} + + +int dCollideSpherePlane (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dSphereClass); + dIASSERT (o2->type == dPlaneClass); + dIASSERT ((flags & NUMC_MASK) >= 1); + + dxSphere *sphere = (dxSphere*) o1; + dxPlane *plane = (dxPlane*) o2; + + contact->g1 = o1; + contact->g2 = o2; + contact->side1 = -1; + contact->side2 = -1; + + dReal k = dCalcVectorDot3 (o1->final_posr->pos,plane->p); + dReal depth = plane->p[3] - k + sphere->radius; + if (depth >= 0) { + contact->normal[0] = plane->p[0]; + contact->normal[1] = plane->p[1]; + contact->normal[2] = plane->p[2]; + contact->pos[0] = o1->final_posr->pos[0] - plane->p[0] * sphere->radius; + contact->pos[1] = o1->final_posr->pos[1] - plane->p[1] * sphere->radius; + contact->pos[2] = o1->final_posr->pos[2] - plane->p[2] * sphere->radius; + contact->depth = depth; + return 1; + } + else return 0; +} diff --git a/libs/ode-0.16.1/ode/src/step.cpp b/libs/ode-0.16.1/ode/src/step.cpp new file mode 100644 index 0000000..033e879 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/step.cpp @@ -0,0 +1,1672 @@ +/*************************************************************************
+ * *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
+ * All rights reserved. Email: russ@q12.org Web: www.q12.org *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of EITHER: *
+ * (1) The GNU Lesser General Public License as published by the Free *
+ * Software Foundation; either version 2.1 of the License, or (at *
+ * your option) any later version. The text of the GNU Lesser *
+ * General Public License is included with this library in the *
+ * file LICENSE.TXT. *
+ * (2) The BSD-style license that is included with this library in *
+ * the file LICENSE-BSD.TXT. *
+ * *
+ * This library 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 files *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
+ * *
+ *************************************************************************/
+
+#include <ode/odeconfig.h>
+#include <ode/rotation.h>
+#include <ode/timer.h>
+#include <ode/error.h>
+#include "config.h"
+#include "odemath.h"
+#include "matrix.h"
+#include "objects.h"
+#include "joints/joint.h"
+#include "lcp.h"
+#include "util.h"
+#include "threadingutils.h"
+
+#include <new>
+
+
+#define dMIN(A,B) ((A)>(B) ? (B) : (A))
+#define dMAX(A,B) ((B)>(A) ? (B) : (A))
+
+//****************************************************************************
+// misc defines
+
+//#define TIMING
+
+
+#ifdef TIMING
+#define IFTIMING(x) x
+#else
+#define IFTIMING(x) ((void)0)
+#endif
+
+
+struct dJointWithInfo1
+{
+ dxJoint *joint;
+ dxJoint::Info1 info;
+};
+
+enum dxRHSCFMElement
+{
+ RCE_RHS = dxJoint::GI2_RHS,
+ RCE_CFM = dxJoint::GI2_CFM,
+
+ // Elements for array reuse
+ RLE_RHS = RCE_RHS,
+ RLE_LAMBDA = RCE_CFM,
+
+ RCE__RHS_CFM_MAX = dxJoint::GI2__RHS_CFM_MAX,
+ RLE__RHS_LAMBDA_MAX = RCE__RHS_CFM_MAX,
+};
+
+enum dxLoHiElement
+{
+ LHE_LO = dxJoint::GI2_LO,
+ LHE_HI = dxJoint::GI2_HI,
+
+ LHE__LO_HI_MAX = dxJoint::GI2__LO_HI_MAX,
+};
+
+enum dxJacobiVectorElement
+{
+ JVE__MIN,
+
+ JVE__L_MIN = JVE__MIN + dDA__L_MIN,
+
+ JVE_LX = JVE__L_MIN + dSA_X,
+ JVE_LY = JVE__L_MIN + dSA_Y,
+ JVE_LZ = JVE__L_MIN + dSA_Z,
+
+ JVE__L_MAX = JVE__L_MIN + dSA__MAX,
+
+ JVE__A_MIN = JVE__MIN + dDA__A_MIN,
+
+ JVE_AX = JVE__A_MIN + dSA_X,
+ JVE_AY = JVE__A_MIN + dSA_Y,
+ JVE_AZ = JVE__A_MIN + dSA_Z,
+
+ JVE__A_MAX = JVE__A_MIN + dSA__MAX,
+
+ JVE__MAX = JVE__MIN + dDA__MAX,
+
+ JVE__L_COUNT = JVE__L_MAX - JVE__L_MIN,
+ JVE__A_COUNT = JVE__A_MAX - JVE__A_MIN,
+};
+
+
+enum dxJacobiMatrixElement
+{
+ JME__MIN,
+
+ JME__J_MIN = JME__MIN,
+ JME__JL_MIN = JME__J_MIN + JVE__L_MIN,
+
+ JME_JLX = JME__J_MIN + JVE_LX,
+ JME_JLY = JME__J_MIN + JVE_LY,
+ JME_JLZ = JME__J_MIN + JVE_LZ,
+
+ JME__JL_MAX = JME__J_MIN + JVE__L_MAX,
+
+ JME__JA_MIN = JME__J_MIN + JVE__A_MIN,
+
+ JME_JAX = JME__J_MIN + JVE_AX,
+ JME_JAY = JME__J_MIN + JVE_AY,
+ JME_JAZ = JME__J_MIN + JVE_AZ,
+
+ JME__JA_MAX = JME__J_MIN + JVE__A_MAX,
+ JME__J_MAX = JME__J_MIN + JVE__MAX,
+
+ JME__MAX = JME__J_MAX,
+
+ JME__J_COUNT = JME__J_MAX - JME__J_MIN,
+};
+
+enum dxJInvMElement
+{
+ JIM__MIN,
+
+ JIM__L_MIN = JIM__MIN + dMD_LINEAR * dV3E__MAX,
+
+ JIM__L_AXES_MIN = JIM__L_MIN + dV3E__AXES_MIN,
+
+ JIM_LX = JIM__L_MIN + dV3E_X,
+ JIM_LY = JIM__L_MIN + dV3E_Y,
+ JIM_LZ = JIM__L_MIN + dV3E_Z,
+
+ JIM__L_AXES_MAX = JIM__L_MIN + dV3E__AXES_MAX,
+
+ JIM_LPAD = JIM__L_MIN + dV3E_PAD,
+
+ JIM__L_MAX = JIM__L_MIN + dV3E__MAX,
+
+ JIM__A_MIN = JIM__MIN + dMD_ANGULAR * dV3E__MAX,
+
+ JIM__A_AXES_MIN = JIM__A_MIN + dV3E__AXES_MIN,
+
+ JIM_AX = JIM__A_MIN + dV3E_X,
+ JIM_AY = JIM__A_MIN + dV3E_Y,
+ JIM_AZ = JIM__A_MIN + dV3E_Z,
+
+ JIM__A_AXES_MAX = JIM__A_MIN + dV3E__AXES_MAX,
+
+ JIM_APAD = JIM__A_MIN + dV3E_PAD,
+
+ JIM__A_MAX = JIM__A_MIN + dV3E__MAX,
+
+ JIM__MAX = JIM__MIN + dMD__MAX * dV3E__MAX,
+};
+
+enum dxContactForceElement
+{
+ CFE__MIN,
+
+ CFE__DYNAMICS_MIN = CFE__MIN,
+
+ CFE__L_MIN = CFE__DYNAMICS_MIN + dDA__L_MIN,
+
+ CFE_LX = CFE__DYNAMICS_MIN + dDA_LX,
+ CFE_LY = CFE__DYNAMICS_MIN + dDA_LY,
+ CFE_LZ = CFE__DYNAMICS_MIN + dDA_LZ,
+
+ CFE__L_MAX = CFE__DYNAMICS_MIN + dDA__L_MAX,
+
+ CFE__A_MIN = CFE__DYNAMICS_MIN + dDA__A_MIN,
+
+ CFE_AX = CFE__DYNAMICS_MIN + dDA_AX,
+ CFE_AY = CFE__DYNAMICS_MIN + dDA_AY,
+ CFE_AZ = CFE__DYNAMICS_MIN + dDA_AZ,
+
+ CFE__A_MAX = CFE__DYNAMICS_MIN + dDA__A_MAX,
+
+ CFE__DYNAMICS_MAX = CFE__DYNAMICS_MIN + dDA__MAX,
+
+ CFE__MAX = CFE__DYNAMICS_MAX,
+};
+
+
+#define AMATRIX_ALIGNMENT dMAX(64, EFFICIENT_ALIGNMENT)
+#define INVI_ALIGNMENT dMAX(32, EFFICIENT_ALIGNMENT)
+#define JINVM_ALIGNMENT dMAX(64, EFFICIENT_ALIGNMENT)
+
+struct dxStepperStage0Outputs
+{
+ sizeint ji_start;
+ sizeint ji_end;
+ unsigned int m;
+ unsigned int nub;
+};
+
+struct dxStepperStage1CallContext
+{
+ void Initialize(const dxStepperProcessingCallContext *stepperCallContext, void *stageMemArenaState, dReal *invI, dJointWithInfo1 *jointinfos)
+ {
+ m_stepperCallContext = stepperCallContext;
+ m_stageMemArenaState = stageMemArenaState;
+ m_invI = invI;
+ m_jointinfos = jointinfos;
+ }
+
+ const dxStepperProcessingCallContext *m_stepperCallContext;
+ void *m_stageMemArenaState;
+ dReal *m_invI;
+ dJointWithInfo1 *m_jointinfos;
+ dxStepperStage0Outputs m_stage0Outputs;
+};
+
+struct dxStepperStage0BodiesCallContext
+{
+ void Initialize(const dxStepperProcessingCallContext *stepperCallContext, dReal *invI)
+ {
+ m_stepperCallContext = stepperCallContext;
+ m_invI = invI;
+ m_tagsTaken = 0;
+ m_gravityTaken = 0;
+ m_inertiaBodyIndex = 0;
+ }
+
+ const dxStepperProcessingCallContext *m_stepperCallContext;
+ dReal *m_invI;
+ atomicord32 m_tagsTaken;
+ atomicord32 m_gravityTaken;
+ volatile atomicord32 m_inertiaBodyIndex;
+};
+
+struct dxStepperStage0JointsCallContext
+{
+ void Initialize(const dxStepperProcessingCallContext *stepperCallContext, dJointWithInfo1 *jointinfos, dxStepperStage0Outputs *stage0Outputs)
+ {
+ m_stepperCallContext = stepperCallContext;
+ m_jointinfos = jointinfos;
+ m_stage0Outputs = stage0Outputs;
+ }
+
+ const dxStepperProcessingCallContext *m_stepperCallContext;
+ dJointWithInfo1 *m_jointinfos;
+ dxStepperStage0Outputs *m_stage0Outputs;
+};
+
+static int dxStepIsland_Stage0_Bodies_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+// static int dxStepIsland_Stage0_Joints_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static int dxStepIsland_Stage1_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+
+static void dxStepIsland_Stage0_Bodies(dxStepperStage0BodiesCallContext *callContext);
+static void dxStepIsland_Stage0_Joints(dxStepperStage0JointsCallContext *callContext);
+static void dxStepIsland_Stage1(dxStepperStage1CallContext *callContext);
+
+
+struct dxStepperLocalContext
+{
+ void Initialize(dReal *invI, dJointWithInfo1 *jointinfos, unsigned int nj,
+ unsigned int m, unsigned int nub, const unsigned int *mindex, int *findex,
+ dReal *J, dReal *A, dReal *pairsRhsCfm, dReal *pairsLoHi,
+ atomicord32 *bodyStartJoints, atomicord32 *bodyJointLinks)
+ {
+ m_invI = invI;
+ m_jointinfos = jointinfos;
+ m_nj = nj;
+ m_m = m;
+ m_nub = nub;
+ m_mindex = mindex;
+ m_findex = findex;
+ m_J = J;
+ m_A = A;
+ m_pairsRhsCfm = pairsRhsCfm;
+ m_pairsLoHi = pairsLoHi;
+ m_bodyStartJoints = bodyStartJoints;
+ m_bodyJointLinks = bodyJointLinks;
+ }
+
+ dReal *m_invI;
+ dJointWithInfo1 *m_jointinfos;
+ unsigned int m_nj;
+ unsigned int m_m;
+ unsigned int m_nub;
+ const unsigned int *m_mindex;
+ int *m_findex;
+ dReal *m_J;
+ dReal *m_A;
+ dReal *m_pairsRhsCfm;
+ dReal *m_pairsLoHi;
+ atomicord32 *m_bodyStartJoints;
+ atomicord32 *m_bodyJointLinks;
+};
+
+struct dxStepperStage2CallContext
+{
+ void Initialize(const dxStepperProcessingCallContext *callContext, const dxStepperLocalContext *localContext,
+ dReal *JinvM, dReal *rhs_tmp)
+ {
+ m_stepperCallContext = callContext;
+ m_localContext = localContext;
+ m_JinvM = JinvM;
+ m_rhs_tmp = rhs_tmp;
+ m_ji_J = 0;
+ m_ji_Ainit = 0;
+ m_ji_JinvM = 0;
+ m_ji_Aaddjb = 0;
+ m_bi_rhs_tmp = 0;
+ m_ji_rhs = 0;
+ }
+
+ const dxStepperProcessingCallContext *m_stepperCallContext;
+ const dxStepperLocalContext *m_localContext;
+ dReal *m_JinvM;
+ dReal *m_rhs_tmp;
+ volatile atomicord32 m_ji_J;
+ volatile atomicord32 m_ji_Ainit;
+ volatile atomicord32 m_ji_JinvM;
+ volatile atomicord32 m_ji_Aaddjb;
+ volatile atomicord32 m_bi_rhs_tmp;
+ volatile atomicord32 m_ji_rhs;
+};
+
+struct dxStepperStage3CallContext
+{
+ void Initialize(const dxStepperProcessingCallContext *callContext, const dxStepperLocalContext *localContext,
+ void *stage1MemArenaState)
+ {
+ m_stepperCallContext = callContext;
+ m_localContext = localContext;
+ m_stage1MemArenaState = stage1MemArenaState;
+ }
+
+ const dxStepperProcessingCallContext *m_stepperCallContext;
+ const dxStepperLocalContext *m_localContext;
+ void *m_stage1MemArenaState;
+};
+
+struct dxStepperStage4CallContext
+{
+ void Initialize(const dxStepperProcessingCallContext *callContext, const dxStepperLocalContext *localContext/*,
+ void *stage3MemarenaState*/)
+ {
+ m_stepperCallContext = callContext;
+ m_localContext = localContext;
+ // m_stage3MemarenaState = stage3MemarenaState;
+ m_bi_constrForce = 0;
+ }
+
+ const dxStepperProcessingCallContext *m_stepperCallContext;
+ const dxStepperLocalContext *m_localContext;
+ // void *m_stage3MemarenaState;
+ volatile atomicord32 m_bi_constrForce;
+};
+
+static int dxStepIsland_Stage2a_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static int dxStepIsland_Stage2aSync_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static int dxStepIsland_Stage2b_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static int dxStepIsland_Stage2bSync_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static int dxStepIsland_Stage2c_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static int dxStepIsland_Stage3_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+
+static void dxStepIsland_Stage2a(dxStepperStage2CallContext *callContext);
+static void dxStepIsland_Stage2b(dxStepperStage2CallContext *callContext);
+static void dxStepIsland_Stage2c(dxStepperStage2CallContext *callContext);
+static void dxStepIsland_Stage3(dxStepperStage3CallContext *callContext);
+
+static int dxStepIsland_Stage4_Callback(void *_stage4CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee);
+static void dxStepIsland_Stage4(dxStepperStage4CallContext *stage4CallContext);
+
+
+//****************************************************************************
+// special matrix multipliers
+
+
+// this assumes the 4th and 8th rows of B and C are zero.
+
+static inline
+void MultiplyAddJinvMxJToA (dReal *Arow, const dReal *JinvMRow, const dReal *JRow,
+ unsigned int infomJinvM, unsigned int infomJ, unsigned int mskip)
+{
+ dIASSERT (infomJinvM > 0 && infomJ > 0 && Arow && JinvMRow && JRow);
+ const unsigned int mskip_munus_infomJ_plus_1 = mskip - infomJ + 1;
+ dIASSERT(mskip >= infomJ);
+ dReal *currA = Arow;
+ const dReal *currJinvM = JinvMRow;
+ for (unsigned int i = infomJinvM; ; ) {
+ dReal JiM0 = currJinvM[JIM_LX];
+ dReal JiM1 = currJinvM[JIM_LY];
+ dReal JiM2 = currJinvM[JIM_LZ];
+ dReal JiM4 = currJinvM[JIM_AX];
+ dReal JiM5 = currJinvM[JIM_AY];
+ dReal JiM6 = currJinvM[JIM_AZ];
+ const dReal *currJ = JRow;
+ for (unsigned int j = infomJ; ; ) {
+ dReal sum;
+ sum = JiM0 * currJ[JME_JLX];
+ sum += JiM1 * currJ[JME_JLY];
+ sum += JiM2 * currJ[JME_JLZ];
+ sum += JiM4 * currJ[JME_JAX];
+ sum += JiM5 * currJ[JME_JAY];
+ sum += JiM6 * currJ[JME_JAZ];
+ *currA += sum;
+ if (--j == 0) {
+ break;
+ }
+ ++currA;
+ currJ += JME__MAX;
+ }
+ if (--i == 0) {
+ break;
+ }
+ currJinvM += JIM__MAX;
+ currA += mskip_munus_infomJ_plus_1;
+ }
+}
+
+
+// this assumes the 4th and 8th rows of B are zero.
+
+static inline
+void MultiplySubJxRhsTmpFromRHS (dReal *rowRhsCfm, const dReal *JRow, const dReal *rowRhsTmp, unsigned int infom)
+{
+ dIASSERT (infom > 0 && rowRhsCfm && JRow && rowRhsTmp);
+ dReal *currRhs = rowRhsCfm + RCE_RHS;
+ const dReal *currJ = JRow;
+ const dReal RT_LX = rowRhsTmp[dDA_LX], RT_LY = rowRhsTmp[dDA_LY], RT_LZ = rowRhsTmp[dDA_LZ];
+ const dReal RT_AX = rowRhsTmp[dDA_AX], RT_AY = rowRhsTmp[dDA_AY], RT_AZ = rowRhsTmp[dDA_AZ];
+ for (unsigned int i = infom; ; ) {
+ dReal sum;
+ sum = currJ[JME_JLX] * RT_LX;
+ sum += currJ[JME_JLY] * RT_LY;
+ sum += currJ[JME_JLZ] * RT_LZ;
+ sum += currJ[JME_JAX] * RT_AX;
+ sum += currJ[JME_JAY] * RT_AY;
+ sum += currJ[JME_JAZ] * RT_AZ;
+ *currRhs -= sum;
+ if (--i == 0) {
+ break;
+ }
+ currRhs += RCE__RHS_CFM_MAX;
+ currJ += JME__MAX;
+ }
+}
+
+
+static inline
+void MultiplyAddJxLambdaToCForce(dReal cforce[CFE__MAX],
+ const dReal *JRow, const dReal *rowRhsLambda, unsigned int infom,
+ dJointFeedback *fb/*=NULL*/, unsigned jointBodyIndex)
+{
+ dIASSERT (infom > 0 && cforce && JRow && rowRhsLambda);
+ dReal sumLX = 0, sumLY = 0, sumLZ = 0, sumAX=0, sumAY = 0, sumAZ = 0;
+ const dReal *currJ = JRow, *currLambda = rowRhsLambda + RLE_LAMBDA;
+ for (unsigned int k = infom; ; ) {
+ const dReal lambda = *currLambda;
+ sumLX += currJ[JME_JLX] * lambda;
+ sumLY += currJ[JME_JLY] * lambda;
+ sumLZ += currJ[JME_JLZ] * lambda;
+ sumAX += currJ[JME_JAX] * lambda;
+ sumAY += currJ[JME_JAY] * lambda;
+ sumAZ += currJ[JME_JAZ] * lambda;
+ if (--k == 0) {
+ break;
+ }
+ currJ += JME__MAX;
+ currLambda += RLE__RHS_LAMBDA_MAX;
+ }
+ if (fb != NULL) {
+ if (jointBodyIndex == dJCB__MIN) {
+ fb->f1[dV3E_X] = sumLX;
+ fb->f1[dV3E_Y] = sumLY;
+ fb->f1[dV3E_Z] = sumLZ;
+ fb->t1[dV3E_X] = sumAX;
+ fb->t1[dV3E_Y] = sumAY;
+ fb->t1[dV3E_Z] = sumAZ;
+ }
+ else {
+ dIASSERT(jointBodyIndex == dJCB__MIN + 1);
+ dSASSERT(dJCB__MAX == 2);
+
+ fb->f2[dV3E_X] = sumLX;
+ fb->f2[dV3E_Y] = sumLY;
+ fb->f2[dV3E_Z] = sumLZ;
+ fb->t2[dV3E_X] = sumAX;
+ fb->t2[dV3E_Y] = sumAY;
+ fb->t2[dV3E_Z] = sumAZ;
+ }
+ }
+ cforce[CFE_LX] += sumLX;
+ cforce[CFE_LY] += sumLY;
+ cforce[CFE_LZ] += sumLZ;
+ cforce[CFE_AX] += sumAX;
+ cforce[CFE_AY] += sumAY;
+ cforce[CFE_AZ] += sumAZ;
+}
+
+
+//****************************************************************************
+
+/*extern */
+void dxStepIsland(const dxStepperProcessingCallContext *callContext)
+{
+ IFTIMING(dTimerStart("preprocessing"));
+
+ dxWorldProcessMemArena *memarena = callContext->m_stepperArena;
+ dxWorld *world = callContext->m_world;
+ unsigned int nb = callContext->m_islandBodiesCount;
+ unsigned int _nj = callContext->m_islandJointsCount;
+
+ dReal *invI = memarena->AllocateOveralignedArray<dReal>(dM3E__MAX * (sizeint)nb, INVI_ALIGNMENT);
+ // Reserve twice as much memory and start from the middle so that regardless of
+ // what direction the array grows to there would be sufficient room available.
+ const sizeint ji_reserve_count = 2 * (sizeint)_nj;
+ dJointWithInfo1 *const jointinfos = memarena->AllocateArray<dJointWithInfo1>(ji_reserve_count);
+
+ const unsigned allowedThreads = callContext->m_stepperAllowedThreads;
+ dIASSERT(allowedThreads != 0);
+
+ void *stagesMemArenaState = memarena->SaveState();
+
+ dxStepperStage1CallContext *stage1CallContext = (dxStepperStage1CallContext *)memarena->AllocateBlock(sizeof(dxStepperStage1CallContext));
+ stage1CallContext->Initialize(callContext, stagesMemArenaState, invI, jointinfos);
+
+ dxStepperStage0BodiesCallContext *stage0BodiesCallContext = (dxStepperStage0BodiesCallContext *)memarena->AllocateBlock(sizeof(dxStepperStage0BodiesCallContext));
+ stage0BodiesCallContext->Initialize(callContext, invI);
+
+ dxStepperStage0JointsCallContext *stage0JointsCallContext = (dxStepperStage0JointsCallContext *)memarena->AllocateBlock(sizeof(dxStepperStage0JointsCallContext));
+ stage0JointsCallContext->Initialize(callContext, jointinfos, &stage1CallContext->m_stage0Outputs);
+
+ if (allowedThreads == 1)
+ {
+ dxStepIsland_Stage0_Bodies(stage0BodiesCallContext);
+ dxStepIsland_Stage0_Joints(stage0JointsCallContext);
+ dxStepIsland_Stage1(stage1CallContext);
+ }
+ else
+ {
+ unsigned bodyThreads = allowedThreads;
+ unsigned jointThreads = 1;
+
+ dCallReleaseeID stage1CallReleasee;
+ world->PostThreadedCallForUnawareReleasee(NULL, &stage1CallReleasee, bodyThreads + jointThreads, callContext->m_finalReleasee,
+ NULL, &dxStepIsland_Stage1_Callback, stage1CallContext, 0, "StepIsland Stage1");
+
+ world->PostThreadedCallsGroup(NULL, bodyThreads, stage1CallReleasee, &dxStepIsland_Stage0_Bodies_Callback, stage0BodiesCallContext, "StepIsland Stage0-Bodies");
+
+ dxStepIsland_Stage0_Joints(stage0JointsCallContext);
+ world->AlterThreadedCallDependenciesCount(stage1CallReleasee, -1);
+ dIASSERT(jointThreads == 1);
+ }
+}
+
+static
+int dxStepIsland_Stage0_Bodies_Callback(void *_callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxStepperStage0BodiesCallContext *callContext = (dxStepperStage0BodiesCallContext *)_callContext;
+ dxStepIsland_Stage0_Bodies(callContext);
+ return 1;
+}
+
+static
+void dxStepIsland_Stage0_Bodies(dxStepperStage0BodiesCallContext *callContext)
+{
+ dxBody * const *body = callContext->m_stepperCallContext->m_islandBodiesStart;
+ unsigned int nb = callContext->m_stepperCallContext->m_islandBodiesCount;
+
+ if (ThrsafeExchange(&callContext->m_tagsTaken, 1) == 0)
+ {
+ // number all bodies in the body list - set their tag values
+ for (unsigned int i=0; i<nb; i++) body[i]->tag = i;
+ }
+
+ if (ThrsafeExchange(&callContext->m_gravityTaken, 1) == 0)
+ {
+ dxWorld *world = callContext->m_stepperCallContext->m_world;
+
+ // add the gravity force to all bodies
+ // since gravity does normally have only one component it's more efficient
+ // to run three loops for each individual component
+ dxBody *const *const bodyend = body + nb;
+ dReal gravity_x = world->gravity[0];
+ if (gravity_x) {
+ for (dxBody *const *bodycurr = body; bodycurr != bodyend; ++bodycurr) {
+ dxBody *b = *bodycurr;
+ if ((b->flags & dxBodyNoGravity) == 0) {
+ b->facc[dV3E_X] += b->mass.mass * gravity_x;
+ }
+ }
+ }
+ dReal gravity_y = world->gravity[1];
+ if (gravity_y) {
+ for (dxBody *const *bodycurr = body; bodycurr != bodyend; ++bodycurr) {
+ dxBody *b = *bodycurr;
+ if ((b->flags & dxBodyNoGravity) == 0) {
+ b->facc[dV3E_Y] += b->mass.mass * gravity_y;
+ }
+ }
+ }
+ dReal gravity_z = world->gravity[2];
+ if (gravity_z) {
+ for (dxBody *const *bodycurr = body; bodycurr != bodyend; ++bodycurr) {
+ dxBody *b = *bodycurr;
+ if ((b->flags & dxBodyNoGravity) == 0) {
+ b->facc[dV3E_Z] += b->mass.mass * gravity_z;
+ }
+ }
+ }
+ }
+
+ // for all bodies, compute the inertia tensor and its inverse in the global
+ // frame, and compute the rotational force and add it to the torque
+ // accumulator. I and invI are a vertical stack of 3x4 matrices, one per body.
+ {
+ dReal *invIrow = callContext->m_invI;
+ unsigned int bodyIndex = ThrsafeIncrementIntUpToLimit(&callContext->m_inertiaBodyIndex, nb);
+
+ for (unsigned int i = 0; i != nb; invIrow += dM3E__MAX, ++i) {
+ if (i == bodyIndex) {
+ dMatrix3 tmp;
+ dxBody *b = body[i];
+
+ // compute inverse inertia tensor in global frame
+ dMultiply2_333 (tmp, b->invI, b->posr.R);
+ dMultiply0_333 (invIrow, b->posr.R, tmp);
+
+ // Don't apply gyroscopic torques to bodies
+ // if not flagged or the body is kinematic
+ if ((b->flags & dxBodyGyroscopic) && (b->invMass > 0)) {
+ dMatrix3 I;
+ // compute inertia tensor in global frame
+ dMultiply2_333 (tmp,b->mass.I,b->posr.R);
+ dMultiply0_333 (I,b->posr.R,tmp);
+ // compute rotational force
+#if 0
+ // Explicit computation
+ dMultiply0_331 (tmp,I,b->avel);
+ dSubtractVectorCross3(b->tacc,b->avel,tmp);
+#else
+ // Do the implicit computation based on
+ //"Stabilizing Gyroscopic Forces in Rigid Multibody Simulations"
+ // (Lacoursière 2006)
+ dReal h = callContext->m_stepperCallContext->m_stepSize; // Step size
+ dVector3 L; // Compute angular momentum
+ dMultiply0_331(L, I, b->avel);
+
+ // Compute a new effective 'inertia tensor'
+ // for the implicit step: the cross-product
+ // matrix of the angular momentum plus the
+ // old tensor scaled by the timestep.
+ // Itild may not be symmetric pos-definite,
+ // but we can still use it to compute implicit
+ // gyroscopic torques.
+ dMatrix3 Itild = { 0 };
+ dSetCrossMatrixMinus(Itild, L, dV3E__MAX);
+ for (int ii = dM3E__MIN; ii != dM3E__MAX; ++ii) {
+ Itild[ii] = Itild[ii] * h + I[ii];
+ }
+
+ // Scale momentum by inverse time to get
+ // a sort of "torque"
+ dScaleVector3(L, dRecip(h));
+ // Invert the pseudo-tensor
+ dMatrix3 itInv;
+ // This is a closed-form inversion.
+ // It's probably not numerically stable
+ // when dealing with small masses with
+ // a large asymmetry.
+ // An LU decomposition might be better.
+ if (dInvertMatrix3(itInv, Itild) != 0) {
+ // "Divide" the original tensor
+ // by the pseudo-tensor (on the right)
+ dMultiply0_333(Itild, I, itInv);
+ // Subtract an identity matrix
+ Itild[dM3E_XX] -= 1; Itild[dM3E_YY] -= 1; Itild[dM3E_ZZ] -= 1;
+
+ // This new inertia matrix rotates the
+ // momentum to get a new set of torques
+ // that will work correctly when applied
+ // to the old inertia matrix as explicit
+ // torques with a semi-implicit update
+ // step.
+ dVector3 tau0;
+ dMultiply0_331(tau0,Itild,L);
+
+ // Add the gyro torques to the torque
+ // accumulator
+ for (int ii = dSA__MIN; ii != dSA__MAX; ++ii) {
+ b->tacc[dV3E__AXES_MIN + ii] += tau0[dV3E__AXES_MIN + ii];
+ }
+ }
+#endif
+ }
+
+ bodyIndex = ThrsafeIncrementIntUpToLimit(&callContext->m_inertiaBodyIndex, nb);
+ }
+ }
+ }
+}
+
+// static
+// int dxStepIsland_Stage0_Joints_Callback(void *_callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+// {
+// (void)callInstanceIndex; // unused
+// (void)callThisReleasee; // unused
+// dxStepperStage0JointsCallContext *callContext = (dxStepperStage0JointsCallContext *)_callContext;
+// dxStepIsland_Stage0_Joints(callContext);
+// return 1;
+// }
+
+static
+void dxStepIsland_Stage0_Joints(dxStepperStage0JointsCallContext *callContext)
+{
+ dxJoint * const *_joint = callContext->m_stepperCallContext->m_islandJointsStart;
+ dJointWithInfo1 *jointinfos = callContext->m_jointinfos;
+ unsigned int _nj = callContext->m_stepperCallContext->m_islandJointsCount;
+
+ // get m = total constraint dimension, nub = number of unbounded variables.
+ // create constraint offset array and number-of-rows array for all joints.
+ // the constraints are re-ordered as follows: the purely unbounded
+ // constraints, the mixed unbounded + LCP constraints, and last the purely
+ // LCP constraints. this assists the LCP solver to put all unbounded
+ // variables at the start for a quick factorization.
+ //
+ // joints with m=0 are inactive and are removed from the joints array
+ // entirely, so that the code that follows does not consider them.
+ // also number all active joints in the joint list (set their tag values).
+ // inactive joints receive a tag value of -1.
+
+ sizeint ji_start, ji_end;
+ {
+ unsigned int mcurr = 0;
+ sizeint unb_start, mix_start, mix_end, lcp_end;
+ unb_start = mix_start = mix_end = lcp_end = _nj;
+
+ dJointWithInfo1 *jicurr = jointinfos + lcp_end;
+ dxJoint *const *const _jend = _joint + _nj;
+ dxJoint *const *_jcurr = _joint;
+ while (true) {
+ // -------------------------------------------------------------------------
+ // Switch to growing array forward
+ {
+ bool fwd_end_reached = false;
+ dJointWithInfo1 *jimixend = jointinfos + mix_end;
+ while (true) { // jicurr=dest, _jcurr=src
+ if (_jcurr == _jend) {
+ lcp_end = jicurr - jointinfos;
+ fwd_end_reached = true;
+ break;
+ }
+ dxJoint *j = *_jcurr++;
+ j->getInfo1 (&jicurr->info);
+ dIASSERT (/*jicurr->info.m >= 0 && */jicurr->info.m <= 6 && /*jicurr->info.nub >= 0 && */jicurr->info.nub <= jicurr->info.m);
+ if (jicurr->info.m != 0) {
+ mcurr += jicurr->info.m;
+ if (jicurr->info.nub == 0) { // A lcp info - a correct guess!!!
+ jicurr->joint = j;
+ ++jicurr;
+ } else if (jicurr->info.nub < jicurr->info.m) { // A mixed case
+ if (unb_start == mix_start) { // no unbounded infos yet - just move to opposite side of mixed-s
+ unb_start = mix_start = mix_start - 1;
+ dJointWithInfo1 *jimixstart = jointinfos + mix_start;
+ jimixstart->info = jicurr->info;
+ jimixstart->joint = j;
+ } else if (jimixend != jicurr) { // have to swap to the tail of mixed-s
+ dxJoint::Info1 tmp_info = jicurr->info;
+ *jicurr = *jimixend;
+ jimixend->info = tmp_info;
+ jimixend->joint = j;
+ ++jimixend; ++jicurr;
+ } else { // no need to swap as there are no LCP info-s yet
+ jicurr->joint = j;
+ jimixend = jicurr = jicurr + 1;
+ }
+ } else { // A purely unbounded case -- break out and proceed growing in opposite direction
+ unb_start = unb_start - 1;
+ dJointWithInfo1 *jiunbstart = jointinfos + unb_start;
+ jiunbstart->info = jicurr->info;
+ jiunbstart->joint = j;
+ lcp_end = jicurr - jointinfos;
+ mix_end = jimixend - jointinfos;
+ jicurr = jiunbstart - 1;
+ break;
+ }
+ } else {
+ j->tag = -1;
+ }
+ }
+ if (fwd_end_reached) {
+ break;
+ }
+ }
+ // -------------------------------------------------------------------------
+ // Switch to growing array backward
+ {
+ bool bkw_end_reached = false;
+ dJointWithInfo1 *jimixstart = jointinfos + mix_start - 1;
+ while (true) { // jicurr=dest, _jcurr=src
+ if (_jcurr == _jend) {
+ unb_start = (jicurr + 1) - jointinfos;
+ mix_start = (jimixstart + 1) - jointinfos;
+ bkw_end_reached = true;
+ break;
+ }
+ dxJoint *j = *_jcurr++;
+ j->getInfo1 (&jicurr->info);
+ dIASSERT (/*jicurr->info.m >= 0 && */jicurr->info.m <= 6 && /*jicurr->info.nub >= 0 && */jicurr->info.nub <= jicurr->info.m);
+ if (jicurr->info.m != 0) {
+ mcurr += jicurr->info.m;
+ if (jicurr->info.nub == jicurr->info.m) { // An unbounded info - a correct guess!!!
+ jicurr->joint = j;
+ --jicurr;
+ } else if (jicurr->info.nub != 0) { // A mixed case
+ if (mix_end == lcp_end) { // no lcp infos yet - just move to opposite side of mixed-s
+ dJointWithInfo1 *jimixend = jointinfos + mix_end;
+ lcp_end = mix_end = mix_end + 1;
+ jimixend->info = jicurr->info;
+ jimixend->joint = j;
+ } else if (jimixstart != jicurr) { // have to swap to the head of mixed-s
+ dxJoint::Info1 tmp_info = jicurr->info;
+ *jicurr = *jimixstart;
+ jimixstart->info = tmp_info;
+ jimixstart->joint = j;
+ --jimixstart; --jicurr;
+ } else { // no need to swap as there are no unbounded info-s yet
+ jicurr->joint = j;
+ jimixstart = jicurr = jicurr - 1;
+ }
+ } else { // A purely lcp case -- break out and proceed growing in opposite direction
+ dJointWithInfo1 *jilcpend = jointinfos + lcp_end;
+ lcp_end = lcp_end + 1;
+ jilcpend->info = jicurr->info;
+ jilcpend->joint = j;
+ unb_start = (jicurr + 1) - jointinfos;
+ mix_start = (jimixstart + 1) - jointinfos;
+ jicurr = jilcpend + 1;
+ break;
+ }
+ } else {
+ j->tag = -1;
+ }
+ }
+ if (bkw_end_reached) {
+ break;
+ }
+ }
+ }
+
+ callContext->m_stage0Outputs->m = mcurr;
+ callContext->m_stage0Outputs->nub = (unsigned)(mix_start - unb_start);
+ dIASSERT((sizeint)(mix_start - unb_start) <= (sizeint)UINT_MAX);
+ ji_start = unb_start;
+ ji_end = lcp_end;
+ }
+
+ {
+ const dJointWithInfo1 *jicurr = jointinfos + ji_start;
+ const dJointWithInfo1 *const jiend = jointinfos + ji_end;
+ for (unsigned int i = 0; jicurr != jiend; i++, ++jicurr) {
+ jicurr->joint->tag = i;
+ }
+ }
+
+ callContext->m_stage0Outputs->ji_start = ji_start;
+ callContext->m_stage0Outputs->ji_end = ji_end;
+}
+
+static
+int dxStepIsland_Stage1_Callback(void *_stage1CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxStepperStage1CallContext *stage1CallContext = (dxStepperStage1CallContext *)_stage1CallContext;
+ dxStepIsland_Stage1(stage1CallContext);
+ return 1;
+}
+
+static
+void dxStepIsland_Stage1(dxStepperStage1CallContext *stage1CallContext)
+{
+ const dxStepperProcessingCallContext *callContext = stage1CallContext->m_stepperCallContext;
+ dJointWithInfo1 *_jointinfos = stage1CallContext->m_jointinfos;
+ dReal *invI = stage1CallContext->m_invI;
+ sizeint ji_start = stage1CallContext->m_stage0Outputs.ji_start;
+ sizeint ji_end = stage1CallContext->m_stage0Outputs.ji_end;
+ unsigned int m = stage1CallContext->m_stage0Outputs.m;
+ unsigned int nub = stage1CallContext->m_stage0Outputs.nub;
+
+ dxWorldProcessMemArena *memarena = callContext->m_stepperArena;
+ {
+ memarena->RestoreState(stage1CallContext->m_stageMemArenaState);
+ stage1CallContext = NULL; // WARNING! _stage1CallContext is not valid after this point!
+ dIVERIFY(stage1CallContext == NULL); // To suppress compiler warnings about unused variable assignment
+
+ unsigned int _nj = callContext->m_islandJointsCount;
+ const sizeint ji_reserve_count = 2 * (sizeint)_nj;
+ memarena->ShrinkArray<dJointWithInfo1>(_jointinfos, ji_reserve_count, ji_end);
+ }
+
+ dJointWithInfo1 *jointinfos = _jointinfos + ji_start;
+ unsigned int nj = (unsigned int)(ji_end - ji_start);
+ dIASSERT((sizeint)(ji_end - ji_start) <= (sizeint)UINT_MAX);
+
+ unsigned int *mindex = NULL;
+ dReal *J = NULL, *A = NULL, *pairsRhsCfm = NULL, *pairsLoHi = NULL;
+ int *findex = NULL;
+ atomicord32 *bodyStartJoints = NULL, *bodyJointLinks = NULL;
+
+ // if there are constraints, compute constrForce
+ if (m > 0) {
+ mindex = memarena->AllocateArray<unsigned int>((sizeint)(nj + 1));
+ {
+ unsigned int *mcurr = mindex;
+ unsigned int moffs = 0;
+ mcurr[0] = moffs;
+ mcurr += 1;
+
+ const dJointWithInfo1 *const jiend = jointinfos + nj;
+ for (const dJointWithInfo1 *jicurr = jointinfos; jicurr != jiend; ++jicurr) {
+ //dxJoint *joint = jicurr->joint;
+ moffs += jicurr->info.m;
+ mcurr[0] = moffs;
+ mcurr += 1;
+ }
+ }
+
+ // create a constraint equation right hand side vector `c', a constraint
+ // force mixing vector `cfm', and LCP low and high bound vectors, and an
+ // 'findex' vector.
+ findex = memarena->AllocateArray<int>(m);
+ J = memarena->AllocateArray<dReal>((sizeint)m * (2 * JME__MAX));
+ A = memarena->AllocateOveralignedArray<dReal>((sizeint)m * dPAD(m), AMATRIX_ALIGNMENT);
+ pairsRhsCfm = memarena->AllocateArray<dReal>((sizeint)m * RCE__RHS_CFM_MAX);
+ pairsLoHi = memarena->AllocateArray<dReal>((sizeint)m * LHE__LO_HI_MAX);
+ const unsigned int nb = callContext->m_islandBodiesCount;
+ bodyStartJoints = memarena->AllocateArray<atomicord32>(nb);
+ bodyJointLinks = memarena->AllocateArray<atomicord32>((sizeint)nj * dJCB__MAX);
+ dICHECK(nj < ~((atomicord32)0) / dJCB__MAX); // If larger joint counts are to be used, pointers (or sizeint) need to be stored rather than atomicord32 indices
+ }
+
+ dxStepperLocalContext *localContext = (dxStepperLocalContext *)memarena->AllocateBlock(sizeof(dxStepperLocalContext));
+ localContext->Initialize(invI, jointinfos, nj, m, nub, mindex, findex, J, A, pairsRhsCfm, pairsLoHi, bodyStartJoints, bodyJointLinks);
+
+ void *stage1MemarenaState = memarena->SaveState();
+ dxStepperStage3CallContext *stage3CallContext = (dxStepperStage3CallContext*)memarena->AllocateBlock(sizeof(dxStepperStage3CallContext));
+ stage3CallContext->Initialize(callContext, localContext, stage1MemarenaState);
+
+ if (m > 0) {
+ dReal *JinvM = memarena->AllocateOveralignedArray<dReal>((sizeint)m * (2 * JIM__MAX), JINVM_ALIGNMENT);
+ const unsigned int nb = callContext->m_islandBodiesCount;
+ dReal *rhs_tmp = memarena->AllocateArray<dReal>((sizeint)nb * dDA__MAX);
+
+ dxStepperStage2CallContext *stage2CallContext = (dxStepperStage2CallContext *)memarena->AllocateBlock(sizeof(dxStepperStage2CallContext));
+ stage2CallContext->Initialize(callContext, localContext, JinvM, rhs_tmp);
+
+ const unsigned allowedThreads = callContext->m_stepperAllowedThreads;
+ dIASSERT(allowedThreads != 0);
+
+ if (allowedThreads == 1) {
+ IFTIMING(dTimerNow("create J"));
+ dxStepIsland_Stage2a(stage2CallContext);
+ IFTIMING(dTimerNow("compute Adiag, JinvM and rhs_tmp"));
+ dxStepIsland_Stage2b(stage2CallContext);
+ IFTIMING(dTimerNow("compute A and rhs"));
+ dxStepIsland_Stage2c(stage2CallContext);
+ dxStepIsland_Stage3(stage3CallContext);
+ }
+ else {
+ dxWorld *world = callContext->m_world;
+ dCallReleaseeID stage3CallReleasee;
+ world->PostThreadedCallForUnawareReleasee(NULL, &stage3CallReleasee, 1, callContext->m_finalReleasee,
+ NULL, &dxStepIsland_Stage3_Callback, stage3CallContext, 0, "StepIsland Stage3");
+
+ dCallReleaseeID stage2bSyncReleasee;
+ world->PostThreadedCall(NULL, &stage2bSyncReleasee, 1, stage3CallReleasee,
+ NULL, &dxStepIsland_Stage2bSync_Callback, stage2CallContext, 0, "StepIsland Stage2b Sync");
+
+ dCallReleaseeID stage2aSyncReleasee;
+ world->PostThreadedCall(NULL, &stage2aSyncReleasee, allowedThreads, stage2bSyncReleasee,
+ NULL, &dxStepIsland_Stage2aSync_Callback, stage2CallContext, 0, "StepIsland Stage2a Sync");
+
+ dIASSERT(allowedThreads > 1); /*if (allowedThreads > 1) */{
+ world->PostThreadedCallsGroup(NULL, allowedThreads - 1, stage2aSyncReleasee, &dxStepIsland_Stage2a_Callback, stage2CallContext, "StepIsland Stage2a");
+ }
+ dxStepIsland_Stage2a(stage2CallContext);
+ world->AlterThreadedCallDependenciesCount(stage2aSyncReleasee, -1);
+ }
+ }
+ else {
+ dxStepIsland_Stage3(stage3CallContext);
+ }
+}
+
+
+static
+int dxStepIsland_Stage2a_Callback(void *_stage2CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxStepperStage2CallContext *stage2CallContext = (dxStepperStage2CallContext *)_stage2CallContext;
+ dxStepIsland_Stage2a(stage2CallContext);
+ return 1;
+}
+
+static
+void dxStepIsland_Stage2a(dxStepperStage2CallContext *stage2CallContext)
+{
+ const dxStepperProcessingCallContext *callContext = stage2CallContext->m_stepperCallContext;
+ const dxStepperLocalContext *localContext = stage2CallContext->m_localContext;
+ dJointWithInfo1 *jointinfos = localContext->m_jointinfos;
+ unsigned int nj = localContext->m_nj;
+ const unsigned int *mindex = localContext->m_mindex;
+
+ const dReal stepsizeRecip = dRecip(callContext->m_stepSize);
+ dxWorld *world = callContext->m_world;
+
+ {
+ int *findex = localContext->m_findex;
+ dReal *J = localContext->m_J;
+ dReal *pairsRhsCfm = localContext->m_pairsRhsCfm;
+ dReal *pairsLoHi = localContext->m_pairsLoHi;
+
+ // get jacobian data from constraints. a (2*m)x8 matrix will be created
+ // to store the two jacobian blocks from each constraint. it has this
+ // format:
+ //
+ // l l l 0 a a a 0 \ .
+ // l l l 0 a a a 0 }-- jacobian body 1 block for joint 0 (3 rows)
+ // l l l 0 a a a 0 /
+ // l l l 0 a a a 0 \ .
+ // l l l 0 a a a 0 }-- jacobian body 2 block for joint 0 (3 rows)
+ // l l l 0 a a a 0 /
+ // l l l 0 a a a 0 }--- jacobian body 1 block for joint 1 (1 row)
+ // l l l 0 a a a 0 }--- jacobian body 2 block for joint 1 (1 row)
+ // etc...
+ //
+ // (lll) = linear jacobian data
+ // (aaa) = angular jacobian data
+ //
+
+ const dReal worldERP = world->global_erp;
+ const dReal worldCFM = world->global_cfm;
+
+ unsigned ji;
+ while ((ji = ThrsafeIncrementIntUpToLimit(&stage2CallContext->m_ji_J, nj)) != nj) {
+ const unsigned ofsi = mindex[ji];
+ const unsigned int infom = mindex[ji + 1] - ofsi;
+
+ dReal *const JRow = J + (sizeint)ofsi * (2 * JME__MAX);
+ dReal *rowRhsCfm = pairsRhsCfm + (sizeint)ofsi * RCE__RHS_CFM_MAX;
+ dReal *rowLoHi = pairsLoHi + (sizeint)ofsi * LHE__LO_HI_MAX;
+ {
+ dSetZero (JRow, infom * (2 * JME__MAX));
+
+ dReal *const endRhsCfm = rowRhsCfm + infom * RCE__RHS_CFM_MAX;
+ for (dReal *currRhsCfm = rowRhsCfm; currRhsCfm != endRhsCfm; currRhsCfm += RCE__RHS_CFM_MAX) {
+ currRhsCfm[RCE_RHS] = REAL(0.0);
+ currRhsCfm[RCE_CFM] = worldCFM;
+ }
+
+ dReal *const endLoHi = rowLoHi + infom * LHE__LO_HI_MAX;
+ for (dReal *currLoHi = rowLoHi; currLoHi != endLoHi; currLoHi += LHE__LO_HI_MAX) {
+ currLoHi[LHE_LO] = -dInfinity;
+ currLoHi[LHE_HI] = dInfinity;
+ }
+ }
+ int *findexRow = findex + ofsi;
+ dSetValue(findexRow, infom, -1);
+
+ dxJoint *joint = jointinfos[ji].joint;
+ joint->getInfo2(stepsizeRecip, worldERP, JME__MAX, JRow + JME__J_MIN, JRow + infom * JME__MAX + JME__J_MIN, RCE__RHS_CFM_MAX, rowRhsCfm, rowLoHi, findexRow);
+ dSASSERT((int)LHE__LO_HI_MAX == RCE__RHS_CFM_MAX); // To make sure same step fits for both pairs in the call to dxJoint::getInfo2() above
+
+ // findex iteration is compact and is not going to pollute caches - do it first
+ {
+ // adjust returned findex values for global index numbering
+ int *const findicesEnd = findexRow + infom;
+ for (int *findexCurr = findexRow; findexCurr != findicesEnd; ++findexCurr) {
+ int fival = *findexCurr;
+ if (fival != -1) {
+ *findexCurr = fival + ofsi;
+ }
+ }
+ }
+ {
+ dReal *const endRhsCfm = rowRhsCfm + infom * RCE__RHS_CFM_MAX;
+ for (dReal *currRhsCfm = rowRhsCfm; currRhsCfm != endRhsCfm; currRhsCfm += RCE__RHS_CFM_MAX) {
+ currRhsCfm[RCE_RHS] *= stepsizeRecip;
+ currRhsCfm[RCE_CFM] *= stepsizeRecip;
+ }
+ }
+ }
+ }
+}
+
+static
+int dxStepIsland_Stage2aSync_Callback(void *_stage2CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ dxStepperStage2CallContext *stage2CallContext = (dxStepperStage2CallContext *)_stage2CallContext;
+ const dxStepperProcessingCallContext *callContext = stage2CallContext->m_stepperCallContext;
+ const unsigned allowedThreads = callContext->m_stepperAllowedThreads;
+
+ dIASSERT(allowedThreads > 1); /*if (allowedThreads > 1) */{ // The allowed thread count is greater than one as otherwise current function would not be scheduled for execution from the previous stage
+ dxWorld *world = callContext->m_world;
+ world->AlterThreadedCallDependenciesCount(callThisReleasee, allowedThreads - 1);
+ world->PostThreadedCallsGroup(NULL, allowedThreads - 1, callThisReleasee, &dxStepIsland_Stage2b_Callback, stage2CallContext, "StepIsland Stage2b");
+ }
+ dxStepIsland_Stage2b(stage2CallContext);
+
+ return 1;
+}
+
+static
+int dxStepIsland_Stage2b_Callback(void *_stage2CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxStepperStage2CallContext *stage2CallContext = (dxStepperStage2CallContext *)_stage2CallContext;
+ dxStepIsland_Stage2b(stage2CallContext);
+ return 1;
+}
+
+static
+void dxStepIsland_Stage2b(dxStepperStage2CallContext *stage2CallContext)
+{
+ const dxStepperProcessingCallContext *callContext = stage2CallContext->m_stepperCallContext;
+ const dxStepperLocalContext *localContext = stage2CallContext->m_localContext;
+ dJointWithInfo1 *jointinfos = localContext->m_jointinfos;
+ unsigned int nj = localContext->m_nj;
+ const unsigned int *mindex = localContext->m_mindex;
+
+ {
+ // Warning!!!
+ // This code depends on cfm elements and therefore must be in different sub-stage
+ // from Jacobian construction in Stage2a to ensure proper synchronization
+ // and avoid accessing numbers being modified.
+ // Warning!!!
+ dReal *A = localContext->m_A;
+ const dReal *pairsRhsCfm = localContext->m_pairsRhsCfm;
+ const unsigned m = localContext->m_m;
+
+ const unsigned int mskip = dPAD(m);
+
+ unsigned ji;
+ while ((ji = ThrsafeIncrementIntUpToLimit(&stage2CallContext->m_ji_Ainit, nj)) != nj) {
+ const unsigned ofsi = mindex[ji];
+ const unsigned int infom = mindex[ji + 1] - ofsi;
+
+ dReal *Arow = A + (sizeint)mskip * ofsi;
+ dSetZero(Arow, (sizeint)mskip * infom);
+ dReal *Adiag = Arow + ofsi;
+ const dReal *rowRfsCrm = pairsRhsCfm + (sizeint)ofsi * RCE__RHS_CFM_MAX;
+ for (unsigned int i = 0; i != infom; Adiag += mskip, ++i) {
+ Adiag[i] = (rowRfsCrm + i * RCE__RHS_CFM_MAX)[RCE_CFM];
+ }
+ }
+ }
+
+ {
+ // Warning!!!
+ // This code depends on J elements and therefore must be in different sub-stage
+ // from Jacobian construction in Stage2a to ensure proper synchronization
+ // and avoid accessing numbers being modified.
+ // Warning!!!
+ const dReal *invI = localContext->m_invI;
+ const dReal *J = localContext->m_J;
+ dReal *JinvM = stage2CallContext->m_JinvM;
+
+ // compute A = J*invM*J'. first compute JinvM = J*invM. this has the same
+ // format as J so we just go through the constraints in J multiplying by
+ // the appropriate scalars and matrices.
+ unsigned ji;
+ while ((ji = ThrsafeIncrementIntUpToLimit(&stage2CallContext->m_ji_JinvM, nj)) != nj) {
+ const unsigned ofsi = mindex[ji];
+ const unsigned int infom = mindex[ji + 1] - ofsi;
+
+ dReal *Jdst = JinvM + (sizeint)ofsi * (2 * JIM__MAX);
+ dSetZero(Jdst, infom * (2 * JIM__MAX));
+
+ const dReal *Jsrc = J + (sizeint)ofsi * (2 * JME__MAX);
+ dxJoint *joint = jointinfos[ji].joint;
+
+ dxBody *jb0 = joint->node[0].body;
+ if (true || jb0 != NULL) { // -- always true
+ dReal body_invMass0 = jb0->invMass;
+ const dReal *body_invI0 = invI + (sizeint)(unsigned int)jb0->tag * dM3E__MAX;
+ for (unsigned int j = infom; j != 0; --j) {
+ for (unsigned int k = dSA__MIN; k != dSA__MAX; ++k) Jdst[JIM__L_AXES_MIN + k] = Jsrc[JME__JL_MIN + k] * body_invMass0;
+ dMultiply0_133(Jdst + JIM__A_AXES_MIN, Jsrc + JME__JA_MIN, body_invI0);
+ Jsrc += JME__MAX;
+ Jdst += JIM__MAX;
+ }
+ }
+
+ dxBody *jb1 = joint->node[1].body;
+ if (jb1 != NULL) {
+ dReal body_invMass1 = jb1->invMass;
+ const dReal *body_invI1 = invI + (sizeint)(unsigned int)jb1->tag * dM3E__MAX;
+ for (unsigned int j = infom; j != 0; --j) {
+ for (unsigned int k = dSA__MIN; k != dSA__MAX; ++k) Jdst[JIM__L_AXES_MIN + k] = Jsrc[JME__JL_MIN + k] * body_invMass1;
+ dMultiply0_133 (Jdst + JIM__A_AXES_MIN, Jsrc + JME__JA_MIN, body_invI1);
+ Jsrc += JME__MAX;
+ Jdst += JIM__MAX;
+ }
+ }
+ }
+ }
+
+ {
+ // Warning!!!
+ // This code reads facc/tacc fields of body objects which (the fields)
+ // may be modified by dxJoint::getInfo2(). Therefore the code must be
+ // in different sub-stage from Jacobian construction in Stage2a
+ // to ensure proper synchronization and avoid accessing numbers being modified.
+ // Warning!!!
+ dxBody * const *const body = callContext->m_islandBodiesStart;
+ const unsigned int nb = callContext->m_islandBodiesCount;
+ const dReal *invI = localContext->m_invI;
+ atomicord32 *bodyStartJoints = localContext->m_bodyStartJoints;
+ dReal *rhs_tmp = stage2CallContext->m_rhs_tmp;
+
+ // compute the right hand side `rhs'
+ const dReal stepsizeRecip = dRecip(callContext->m_stepSize);
+
+ // put v/h + invM*fe into rhs_tmp
+ unsigned bi;
+ while ((bi = ThrsafeIncrementIntUpToLimit(&stage2CallContext->m_bi_rhs_tmp, nb)) != nb) {
+ dReal *tmp1curr = rhs_tmp + (sizeint)bi * dDA__MAX;
+ const dReal *invIrow = invI + (sizeint)bi * dM3E__MAX;
+ dxBody *b = body[bi];
+ // dSetZero(tmp1curr, 8); -- not needed
+ for (unsigned int j = dSA__MIN; j != dSA__MAX; ++j) tmp1curr[dDA__L_MIN + j] = b->facc[dV3E__AXES_MIN + j] * b->invMass + b->lvel[dV3E__AXES_MIN + j] * stepsizeRecip;
+ dMultiply0_331 (tmp1curr + dDA__A_MIN, invIrow, b->tacc);
+ for (unsigned int k = dSA__MIN; k != dSA__MAX; ++k) tmp1curr[dDA__A_MIN + k] += b->avel[dV3E__AXES_MIN + k] * stepsizeRecip;
+ // Initialize body start joint indices -- this will be needed later for building body related joint list in dxStepIsland_Stage2c
+ bodyStartJoints[bi] = 0;
+ }
+ }
+}
+
+static
+int dxStepIsland_Stage2bSync_Callback(void *_stage2CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ dxStepperStage2CallContext *stage2CallContext = (dxStepperStage2CallContext *)_stage2CallContext;
+ const dxStepperProcessingCallContext *callContext = stage2CallContext->m_stepperCallContext;
+ const unsigned allowedThreads = callContext->m_stepperAllowedThreads;
+
+ dIASSERT(allowedThreads > 1); /*if (allowedThreads > 1) */{ // The allowed thread count is greater than one as otherwise current function would not be scheduled for execution from the previous stage
+ dxWorld *world = callContext->m_world;
+ world->AlterThreadedCallDependenciesCount(callThisReleasee, allowedThreads - 1);
+ world->PostThreadedCallsGroup(NULL, allowedThreads - 1, callThisReleasee, &dxStepIsland_Stage2c_Callback, stage2CallContext, "StepIsland Stage2c");
+ }
+ dxStepIsland_Stage2c(stage2CallContext);
+
+ return 1;
+}
+
+
+static
+int dxStepIsland_Stage2c_Callback(void *_stage2CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxStepperStage2CallContext *stage2CallContext = (dxStepperStage2CallContext *)_stage2CallContext;
+ dxStepIsland_Stage2c(stage2CallContext);
+ return 1;
+}
+
+static
+void dxStepIsland_Stage2c(dxStepperStage2CallContext *stage2CallContext)
+{
+ //const dxStepperProcessingCallContext *callContext = stage2CallContext->m_stepperCallContext;
+ const dxStepperLocalContext *localContext = stage2CallContext->m_localContext;
+ dJointWithInfo1 *jointinfos = localContext->m_jointinfos;
+ unsigned int nj = localContext->m_nj;
+ const unsigned int *mindex = localContext->m_mindex;
+
+ {
+ // Warning!!!
+ // This code depends on A elements and JinvM elements and therefore
+ // must be in different sub-stage from A initialization and JinvM calculation in Stage2b
+ // to ensure proper synchronization and avoid accessing numbers being modified.
+ // Warning!!!
+ dReal *A = localContext->m_A;
+ const dReal *JinvM = stage2CallContext->m_JinvM;
+ const dReal *J = localContext->m_J;
+ const unsigned m = localContext->m_m;
+
+ // now compute A = JinvM * J'. A's rows and columns are grouped by joint,
+ // i.e. in the same way as the rows of J. block (i,j) of A is only nonzero
+ // if joints i and j have at least one body in common.
+ const unsigned int mskip = dPAD(m);
+
+ unsigned ji;
+ while ((ji = ThrsafeIncrementIntUpToLimit(&stage2CallContext->m_ji_Aaddjb, nj)) != nj) {
+ const unsigned ofsi = mindex[ji];
+ const unsigned int infom = mindex[ji + 1] - ofsi;
+
+ dReal *Arow = A + (sizeint)mskip * ofsi;
+ const dReal *JinvMRow = JinvM + (sizeint)ofsi * (2 * JIM__MAX);
+ dxJoint *joint = jointinfos[ji].joint;
+
+ dxBody *jb0 = joint->node[0].body;
+ if (true || jb0 != NULL) { // -- always true
+ // compute diagonal block of A
+ const dReal *JRow = J + (sizeint)ofsi * (2 * JME__MAX);
+ MultiplyAddJinvMxJToA (Arow + ofsi, JinvMRow, JRow, infom, infom, mskip);
+
+ for (dxJointNode *n0 = (ji != 0 ? jb0->firstjoint : NULL); n0; n0 = n0->next) {
+ // if joint was tagged as -1 then it is an inactive (m=0 or disabled)
+ // joint that should not be considered
+ int j0 = n0->joint->tag;
+ if (j0 != -1 && (unsigned)j0 < ji) {
+ const unsigned int jiother_ofsi = mindex[j0];
+ const unsigned int jiother_infom = mindex[j0 + 1] - jiother_ofsi;
+ const dJointWithInfo1 *jiother = jointinfos + j0;
+ unsigned int smart_infom = (jiother->joint->node[1].body == jb0) ? jiother_infom : 0;
+ // set block of A
+ const dReal *JOther = J + ((sizeint)jiother_ofsi * 2 + smart_infom) * JME__MAX;
+ MultiplyAddJinvMxJToA (Arow + jiother_ofsi, JinvMRow, JOther, infom, jiother_infom, mskip);
+ }
+ }
+ }
+
+ dxBody *jb1 = joint->node[1].body;
+ dIASSERT(jb1 != jb0);
+ if (jb1 != NULL) {
+ const dReal *JinvMOther = JinvMRow + infom * JIM__MAX;
+ // compute diagonal block of A
+ const dReal *JRow = J + ((sizeint)ofsi * 2 + infom) * JME__MAX;
+ MultiplyAddJinvMxJToA (Arow + ofsi, JinvMOther, JRow, infom, infom, mskip);
+
+ for (dxJointNode *n1 = (ji != 0 ? jb1->firstjoint : NULL); n1; n1 = n1->next) {
+ // if joint was tagged as -1 then it is an inactive (m=0 or disabled)
+ // joint that should not be considered
+ int j1 = n1->joint->tag;
+ if (j1 != -1 && (unsigned)j1 < ji) {
+ const unsigned int jiother_ofsi = mindex[j1];
+ const unsigned int jiother_infom = mindex[j1 + 1] - jiother_ofsi;
+ const dJointWithInfo1 *jiother = jointinfos + j1;
+ unsigned int smart_infom = (jiother->joint->node[1].body == jb1) ? jiother_infom : 0;
+ // set block of A
+ const dReal *JOther = J + ((sizeint)jiother_ofsi * 2 + smart_infom) * JME__MAX;
+ MultiplyAddJinvMxJToA (Arow + jiother_ofsi, JinvMOther, JOther, infom, jiother_infom, mskip);
+ }
+ }
+ }
+ }
+ }
+
+ {
+ // Warning!!!
+ // This code depends on rhs_tmp elements and therefore must be in
+ // different sub-stage from rhs_tmp calculation in Stage2b to ensure
+ // proper synchronization and avoid accessing numbers being modified.
+ // Warning!!!
+ const dReal *J = localContext->m_J;
+ const dReal *rhs_tmp = stage2CallContext->m_rhs_tmp;
+ dReal *pairsRhsCfm = localContext->m_pairsRhsCfm;
+ atomicord32 *bodyStartJoints = localContext->m_bodyStartJoints;
+ atomicord32 *bodyJointLinks = localContext->m_bodyJointLinks;
+
+ // compute the right hand side `rhs'
+ // put J*rhs_tmp into rhs
+ unsigned ji;
+ while ((ji = ThrsafeIncrementIntUpToLimit(&stage2CallContext->m_ji_rhs, nj)) != nj) {
+ const unsigned ofsi = mindex[ji];
+ const unsigned int infom = mindex[ji + 1] - ofsi;
+
+ dReal *currRhsCfm = pairsRhsCfm + (sizeint)ofsi * RCE__RHS_CFM_MAX;
+ const dReal *JRow = J + (sizeint)ofsi * (2 * JME__MAX);
+
+ dxJoint *joint = jointinfos[ji].joint;
+
+ dxBody *jb0 = joint->node[0].body;
+ if (true || jb0 != NULL) { // -- always true
+ unsigned bodyIndex = (unsigned)jb0->tag;
+ MultiplySubJxRhsTmpFromRHS (currRhsCfm, JRow, rhs_tmp + (sizeint)bodyIndex * dDA__MAX, infom);
+
+ // Link joints connected to each body into a list to be used on results incorporation. The bodyStartJoints have been initialized in dxStepIsland_Stage2b.
+ const atomicord32 linkIndex = (atomicord32)((sizeint)ji * dJCB__MAX + dJCB_FIRST_BODY); // It is asserted at links buffer allocation that the indices can't overflow atomicord32
+ for (atomicord32 oldStartIndex = bodyStartJoints[bodyIndex]; ; oldStartIndex = bodyStartJoints[bodyIndex]) {
+ bodyJointLinks[linkIndex] = oldStartIndex;
+ if (ThrsafeCompareExchange(&bodyStartJoints[bodyIndex], oldStartIndex, linkIndex + 1)) { // The link index is stored incremented to allow 0 as end indicator
+ break;
+ }
+ }
+ }
+
+ dxBody *jb1 = joint->node[1].body;
+ if (jb1 != NULL) {
+ unsigned bodyIndex = (unsigned)jb1->tag;
+ MultiplySubJxRhsTmpFromRHS (currRhsCfm, JRow + infom * JME__MAX, rhs_tmp + (sizeint)bodyIndex * dDA__MAX, infom);
+
+ // Link joints connected to each body into a list to be used on results incorporation. The bodyStartJoints have been initialized in dxStepIsland_Stage2b
+ const atomicord32 linkIndex = (atomicord32)((sizeint)ji * dJCB__MAX + dJCB_SECOND_BODY); // It is asserted at links buffer allocation that the indices can't overflow atomicord32
+ for (atomicord32 oldStartIndex = bodyStartJoints[bodyIndex]; ; oldStartIndex = bodyStartJoints[bodyIndex]) {
+ bodyJointLinks[linkIndex] = oldStartIndex;
+ if (ThrsafeCompareExchange(&bodyStartJoints[bodyIndex], oldStartIndex, linkIndex + 1)) { // The link index is stored incremented to allow 0 as end indicator
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+static
+int dxStepIsland_Stage3_Callback(void *_stage3CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxStepperStage3CallContext *stage3CallContext = (dxStepperStage3CallContext *)_stage3CallContext;
+ dxStepIsland_Stage3(stage3CallContext);
+ return 1;
+}
+
+static
+void dxStepIsland_Stage3(dxStepperStage3CallContext *stage3CallContext)
+{
+ const dxStepperProcessingCallContext *callContext = stage3CallContext->m_stepperCallContext;
+ const dxStepperLocalContext *localContext = stage3CallContext->m_localContext;
+
+ dxWorldProcessMemArena *memarena = callContext->m_stepperArena;
+ memarena->RestoreState(stage3CallContext->m_stage1MemArenaState);
+ stage3CallContext = NULL; // WARNING! stage3CallContext is not valid after this point!
+ dIVERIFY(stage3CallContext == NULL); // To suppress unused variable assignment warnings
+
+ unsigned int m = localContext->m_m;
+ unsigned int nub = localContext->m_nub;
+ //const unsigned int *mindex = localContext->m_mindex;
+ int *findex = localContext->m_findex;
+ dReal *A = localContext->m_A;
+ dReal *pairsRhsLambda = localContext->m_pairsRhsCfm; // Reuse cfm buffer for lambdas as the former values are not needed any more
+ dReal *pairsLoHi = localContext->m_pairsLoHi;
+
+ if (m > 0) {
+ BEGIN_STATE_SAVE(memarena, lcpstate) {
+ IFTIMING(dTimerNow ("solve LCP problem"));
+
+ // solve the LCP problem and get lambda.
+ // this will destroy A but that's OK
+ dxSolveLCP (memarena, m, A, pairsRhsLambda, NULL, nub, pairsLoHi, findex);
+ dSASSERT((int)RLE__RHS_LAMBDA_MAX == PBX__MAX && (int)RLE_RHS == PBX_B && (int)RLE_LAMBDA == PBX_X);
+ dSASSERT((int)LHE__LO_HI_MAX == PLH__MAX && (int)LHE_LO == PLH_LO && (int)LHE_HI == PLH_HI);
+
+ } END_STATE_SAVE(memarena, lcpstate);
+ }
+
+ // void *stage3MemarenaState = memarena->SaveState();
+
+ dxStepperStage4CallContext *stage4CallContext = (dxStepperStage4CallContext *)memarena->AllocateBlock(sizeof(dxStepperStage4CallContext));
+ stage4CallContext->Initialize(callContext, localContext/*, stage3MemarenaState*/);
+
+ const unsigned allowedThreads = callContext->m_stepperAllowedThreads;
+ dIASSERT(allowedThreads != 0);
+
+ if (allowedThreads == 1) {
+ IFTIMING(dTimerNow ("compute and apply constraint force"));
+ dxStepIsland_Stage4(stage4CallContext);
+ IFTIMING(dTimerEnd());
+
+ if (m > 0) {
+ IFTIMING(dTimerReport(stdout,1));
+ }
+ }
+ else {
+ dCallReleaseeID finalReleasee = callContext->m_finalReleasee;
+ dxWorld *world = callContext->m_world;
+ world->AlterThreadedCallDependenciesCount(finalReleasee, allowedThreads - 1);
+ world->PostThreadedCallsGroup(NULL, allowedThreads - 1, finalReleasee, &dxStepIsland_Stage4_Callback, stage4CallContext, "StepIsland Stage4");
+ // Note: Adding another dependency for the finalReleasee is not necessary as it already depends on the current call
+ dxStepIsland_Stage4(stage4CallContext);
+ }
+}
+
+static
+int dxStepIsland_Stage4_Callback(void *_stage4CallContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee)
+{
+ (void)callInstanceIndex; // unused
+ (void)callThisReleasee; // unused
+ dxStepperStage4CallContext *stage4CallContext = (dxStepperStage4CallContext *)_stage4CallContext;
+ dxStepIsland_Stage4(stage4CallContext);
+ return 1;
+}
+
+static
+void dxStepIsland_Stage4(dxStepperStage4CallContext *stage4CallContext)
+{
+ const dxStepperProcessingCallContext *callContext = stage4CallContext->m_stepperCallContext;
+ const dxStepperLocalContext *localContext = stage4CallContext->m_localContext;
+
+ const dReal stepSize = callContext->m_stepSize;
+ dxBody *const *bodies = callContext->m_islandBodiesStart;
+ dReal *invI = localContext->m_invI;
+ dJointWithInfo1 *jointInfos = localContext->m_jointinfos;
+ dReal *J = localContext->m_J;
+ dReal *pairsRhsLambda = localContext->m_pairsRhsCfm;
+ const unsigned int *mIndex = localContext->m_mindex;
+ atomicord32 *bodyStartJoints = localContext->m_bodyStartJoints;
+ atomicord32 *bodyJointLinks = localContext->m_bodyJointLinks;
+ const unsigned int nb = callContext->m_islandBodiesCount;
+
+ unsigned bi;
+ while ((bi = ThrsafeIncrementIntUpToLimit(&stage4CallContext->m_bi_constrForce, nb)) != nb) {
+ dVector3 angularForceAccumulator;
+ dxBody *b = bodies[bi];
+ const dReal *invIrow = invI + (sizeint)bi * dM3E__MAX;
+ dReal body_invMass_mul_stepSize = stepSize * b->invMass;
+
+ dReal bodyConstrForce[CFE__MAX];
+ bool constrForceAvailable = false;
+
+ unsigned linkIndex = bodyStartJoints != NULL ? bodyStartJoints[bi] : 0;
+ if (linkIndex != 0) {
+ dSetZero(bodyConstrForce, dARRAY_SIZE(bodyConstrForce));
+ }
+
+ // compute the constraint force as constrForce = J'*lambda
+ for (; linkIndex != 0; constrForceAvailable = true, linkIndex = bodyJointLinks[linkIndex - 1]) {
+ unsigned jointIndex = (linkIndex - 1) / dJCB__MAX;
+ unsigned jointBodyIndex = (linkIndex - 1) % dJCB__MAX;
+
+ const dJointWithInfo1 *currJointInfo = jointInfos + jointIndex;
+ unsigned ofsi = mIndex[jointIndex];
+ dIASSERT(dIN_RANGE(jointIndex, 0, localContext->m_nj));
+
+ const dReal *JRow = J + (sizeint)ofsi * (2 * JME__MAX);
+ const dReal *rowRhsLambda = pairsRhsLambda + (sizeint)ofsi * RLE__RHS_LAMBDA_MAX;
+
+ dxJoint *joint = currJointInfo->joint;
+ const unsigned int infom = currJointInfo->info.m;
+
+ // unsigned jRowExtraOffset = jointBodyIndex * infom * JME__MAX;
+ unsigned jRowExtraOffset = jointBodyIndex != dJCB__MIN ? infom * JME__MAX : 0;
+ dSASSERT(dJCB__MAX == 2);
+
+ dJointFeedback *fb = joint->feedback;
+ MultiplyAddJxLambdaToCForce(bodyConstrForce, JRow + jRowExtraOffset, rowRhsLambda, infom, fb, jointBodyIndex);
+ }
+
+ // compute the velocity update
+ if (constrForceAvailable) {
+ // add fe to cforce and multiply cforce by stepSize
+ for (unsigned int j = dSA__MIN; j != dSA__MAX; ++j) {
+ b->lvel[dV3E__AXES_MIN + j] += (bodyConstrForce[CFE__L_MIN + j] + b->facc[dV3E__AXES_MIN + j]) * body_invMass_mul_stepSize;
+ }
+ for (unsigned int k = dSA__MIN; k != dSA__MAX; ++k) {
+ angularForceAccumulator[dV3E__AXES_MIN + k] = (bodyConstrForce[CFE__A_MIN + k] + b->tacc[dV3E__AXES_MIN + k]) * stepSize;
+ }
+ }
+ else {
+ // add fe to cforce and multiply cforce by stepSize
+ dAddVectorScaledVector3(b->lvel, b->lvel, b->facc, body_invMass_mul_stepSize);
+ dCopyScaledVector3(angularForceAccumulator, b->tacc, stepSize);
+ }
+
+ dMultiplyAdd0_331 (b->avel, invIrow, angularForceAccumulator + dV3E__AXES_MIN);
+
+ // update the position and orientation from the new linear/angular velocity
+ // (over the given time step)
+ dxStepBody (b, stepSize);
+
+ // zero all force accumulators
+ dZeroVector3(b->facc);
+ dZeroVector3(b->tacc);
+ }
+}
+
+
+//****************************************************************************
+
+/*extern */
+sizeint dxEstimateStepMemoryRequirements (dxBody * const *body, unsigned int nb, dxJoint * const *_joint, unsigned int _nj)
+{
+ (void)body; // unused
+ unsigned int nj, m;
+
+ {
+ unsigned int njcurr = 0, mcurr = 0;
+ dxJoint::SureMaxInfo info;
+ dxJoint *const *const _jend = _joint + _nj;
+ for (dxJoint *const *_jcurr = _joint; _jcurr != _jend; ++_jcurr) {
+ dxJoint *j = *_jcurr;
+ j->getSureMaxInfo (&info);
+
+ unsigned int jm = info.max_m;
+ if (jm > 0) {
+ njcurr++;
+
+ mcurr += jm;
+ }
+ }
+ nj = njcurr; m = mcurr;
+ }
+
+ sizeint res = 0;
+
+ res += dOVERALIGNED_SIZE(sizeof(dReal) * dM3E__MAX * nb, INVI_ALIGNMENT); // for invI
+
+ {
+ sizeint sub1_res1 = dEFFICIENT_SIZE(sizeof(dJointWithInfo1) * 2 * _nj); // for initial jointinfos
+
+ // The array can't grow right more than by nj
+ sizeint sub1_res2 = dEFFICIENT_SIZE(sizeof(dJointWithInfo1) * ((sizeint)_nj + (sizeint)nj)); // for shrunk jointinfos
+ sub1_res2 += dEFFICIENT_SIZE(sizeof(dxStepperLocalContext)); //for dxStepperLocalContext
+ if (m > 0) {
+ sub1_res2 += dEFFICIENT_SIZE(sizeof(unsigned int) * (nj + 1)); // for mindex
+ sub1_res2 += dEFFICIENT_SIZE(sizeof(int) * m); // for findex
+ sub1_res2 += dEFFICIENT_SIZE(sizeof(dReal) * 2 * JME__MAX * m); // for J
+ unsigned int mskip = dPAD(m);
+ sub1_res2 += dOVERALIGNED_SIZE(sizeof(dReal) * mskip * m, AMATRIX_ALIGNMENT); // for A
+ sub1_res2 += dEFFICIENT_SIZE(sizeof(dReal) * RCE__RHS_CFM_MAX * m); // for pairsRhsCfm
+ sub1_res2 += dEFFICIENT_SIZE(sizeof(dReal) * LHE__LO_HI_MAX * m); // for pairsLoHi
+ sub1_res2 += dEFFICIENT_SIZE(sizeof(atomicord32) * nb); // for bodyStartJoints
+ sub1_res2 += dEFFICIENT_SIZE(sizeof(atomicord32)* dJCB__MAX * nj); // for bodyJointLinks
+ }
+
+ {
+ sizeint sub2_res1 = dEFFICIENT_SIZE(sizeof(dxStepperStage3CallContext)); // for dxStepperStage3CallContext
+
+ sizeint sub2_res2 = 0;
+
+ sizeint sub2_res3 = dEFFICIENT_SIZE(sizeof(dxStepperStage4CallContext)); // for dxStepperStage4CallContext
+
+ if (m > 0) {
+ sub2_res1 += dOVERALIGNED_SIZE(sizeof(dReal) * 2 * JIM__MAX * m, JINVM_ALIGNMENT); // for JinvM
+ sub2_res1 += dEFFICIENT_SIZE(sizeof(dReal) * dDA__MAX * nb); // for rhs_tmp
+ sub2_res1 += dEFFICIENT_SIZE(sizeof(dxStepperStage2CallContext)); // for dxStepperStage2CallContext
+
+ sub2_res2 += dxEstimateSolveLCPMemoryReq(m, false);
+ }
+
+ sub1_res2 += dMAX(sub2_res1, dMAX(sub2_res2, sub2_res3));
+ }
+
+ sizeint sub1_res12_max = dMAX(sub1_res1, sub1_res2);
+ sizeint stage01_contexts = dEFFICIENT_SIZE(sizeof(dxStepperStage0BodiesCallContext))
+ + dEFFICIENT_SIZE(sizeof(dxStepperStage0JointsCallContext))
+ + dEFFICIENT_SIZE(sizeof(dxStepperStage1CallContext));
+ res += dMAX(sub1_res12_max, stage01_contexts);
+ }
+
+ return res;
+}
+
+
+/*extern */
+unsigned dxEstimateStepMaxCallCount(
+ unsigned /*activeThreadCount*/, unsigned allowedThreadCount)
+{
+ unsigned result = 1 // dxStepIsland itself
+ + (2 * allowedThreadCount + 2) // (dxStepIsland_Stage2a + dxStepIsland_Stage2b) * allowedThreadCount + 2 * dxStepIsland_Stage2?_Sync
+ + 1; // dxStepIsland_Stage3
+ return result;
+}
diff --git a/libs/ode-0.16.1/ode/src/step.h b/libs/ode-0.16.1/ode/src/step.h new file mode 100644 index 0000000..dc8331a --- /dev/null +++ b/libs/ode-0.16.1/ode/src/step.h @@ -0,0 +1,40 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_STEP_H_ +#define _ODE_STEP_H_ + +#include <ode/common.h> + +struct dxStepperProcessingCallContext; + + +sizeint dxEstimateStepMemoryRequirements( + dxBody * const *body, unsigned int nb, dxJoint * const *_joint, unsigned int _nj); +unsigned dxEstimateStepMaxCallCount( + unsigned activeThreadCount, unsigned allowedThreadCount); + +void dxStepIsland(const dxStepperProcessingCallContext *callContext); + + + +#endif diff --git a/libs/ode-0.16.1/ode/src/threaded_solver_ldlt.h b/libs/ode-0.16.1/ode/src/threaded_solver_ldlt.h new file mode 100644 index 0000000..c791508 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/threaded_solver_ldlt.h @@ -0,0 +1,809 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * Equation System Threaded Solver + * Copyright (c) 2017-2019 Oleh Derevenko, odar@eleks.com (change all "a" to "e") + */ + + + +#ifndef _ODE_THREADED_SOLVER_LDLT_H_ +#define _ODE_THREADED_SOLVER_LDLT_H_ + + +#include "coop_matrix_types.h" +#include <ode/threading.h> + + +class dxThreadingBase; +class dxResourceRequirementDescriptor; +class dxRequiredResourceContainer; + + +class ThreadedEquationSolverLDLT +{ +public: + static void estimateCooperativeFactoringLDLTResourceRequirements(dxResourceRequirementDescriptor *summaryRequirementsDescriptor, + unsigned allowedThreadCount, unsigned rowCount); + static void cooperativelyFactorLDLT(dxRequiredResourceContainer *resourceContainer, unsigned allowedThreadCount, + dReal *A, dReal *d, unsigned rowCount, unsigned rowSkip); + + static void estimateCooperativeSolvingL1StraightResourceRequirements(dxResourceRequirementDescriptor *summaryRequirementsDescriptor, + unsigned allowedThreadCount, unsigned rowCount); + static void cooperativelySolveL1Straight(dxRequiredResourceContainer *resourceContainer, unsigned allowedThreadCount, + const dReal *L, dReal *b, unsigned rowCount, unsigned rowSkip); + + static void estimateCooperativeSolvingL1TransposedResourceRequirements(dxResourceRequirementDescriptor *summaryRequirementsDescriptor, + unsigned allowedThreadCount, unsigned rowCount); + static void cooperativelySolveL1Transposed(dxRequiredResourceContainer *resourceContainer, unsigned allowedThreadCount, + const dReal *L, dReal *b, unsigned rowCount, unsigned rowSkip); + + static void estimateCooperativeScalingVectorResourceRequirements(dxResourceRequirementDescriptor *summaryRequirementsDescriptor, + unsigned allowedThreadCount, unsigned elementCount); + static void cooperativelyScaleVector(dxRequiredResourceContainer *resourceContainer, unsigned allowedThreadCount, + dReal *vectorData, const dReal *scaleData, unsigned elementCount); + + static void estimateCooperativeSolvingLDLTResourceRequirements(dxResourceRequirementDescriptor *summaryRequirementsDescriptor, + unsigned allowedThreadCount, unsigned rowCount); + static void cooperativelySolveLDLT(dxRequiredResourceContainer *resourceContainer, unsigned allowedThreadCount, + const dReal *L, const dReal *d, dReal *b, unsigned rowCount, unsigned rowSkip); + +public: + enum + { + ALLOCATION_DEFAULT_ALIGNMENT = COOP_THREAD_DATA_ALIGNMENT_SIZE, + }; + +private: + struct FactorizationSolveL1StripeCellContext; + struct FactorizationFactorizeL1StripeThreadContext; + + enum + { + FLDLT_D_STRIDE = 1, + FLDLT_COOPERATIVE_BLOCK_COUNT_MINIMUM = 5, + + FSL1S_BLOCK_SIZE = 2, + + FSL1S_REGULAR_B_ROWS = FSL1S_BLOCK_SIZE, + FSL1S_FINAL_B_ROWS = 1, + + FFL1S_REGULAR_A_ROWS = FSL1S_BLOCK_SIZE, + FFL1S_FINAL_A_ROWS = 1, + FFL1S_REGULAR_BLOCK_SIZE = 16, // A suitable by magnitude number being a power of 2 and (naturally) not being divisible by 6 + FFL1S_FINAL_BLOCK_SIZE = 32, // A suitable by magnitude number being a power of 2 and (naturally) not being divisible by 6 + }; + + static unsigned restrictFactoringLDLTAllowedThreadCount( + dxThreadingBase *threading, unsigned allowedThreadCount, unsigned rowCount); + static void doEstimateCooperativeFactoringLDLTResourceRequirementsValidated( + dxResourceRequirementDescriptor *summaryRequirementsDescriptor, + unsigned allowedThreadCount, unsigned rowCount); + static void doCooperativelyFactorLDLTValidated( + dxRequiredResourceContainer *resourceContainer, unsigned allowedThreadCount, + dReal *A, dReal *d, unsigned rowCount, unsigned rowSkip); + + + static unsigned deriveSolvingL1StripeBlockCount(unsigned rowCount, unsigned blockStep) + { + return (rowCount + (blockStep - 1)) / blockStep; + } + + struct FactorizationSolvingL1StripeMemoryEstimates + { + void assignData(sizeint descriptorSizeRequired, sizeint contextSizeRequired) + { + m_descriptorSizeRequired = descriptorSizeRequired; + m_contextSizeRequired = contextSizeRequired; + } + + sizeint m_descriptorSizeRequired; + sizeint m_contextSizeRequired; + }; + + static unsigned deriveSolvingL1StripeThreadCount(unsigned blockCount, unsigned allowedThreadCount) + { + dIASSERT(allowedThreadCount >= 1); + + unsigned maximumCount = blockCount / 2; + return maximumCount >= allowedThreadCount ? allowedThreadCount : dMACRO_MAX(maximumCount, 1U); + } + + static sizeint estimateCooperativelySolvingL1Stripe_XMemoryRequirement(unsigned blockCount, + FactorizationSolvingL1StripeMemoryEstimates &ref_memoryEstimates) + { + sizeint descriptorSizeRequired = dOVERALIGNED_SIZE(sizeof(cellindexint) * blockCount, COOP_THREAD_DATA_ALIGNMENT_SIZE); + sizeint contextSizeRequired = dOVERALIGNED_SIZE(sizeof(FactorizationSolveL1StripeCellContext) * (CCI__MAX + 1) * blockCount, COOP_THREAD_DATA_ALIGNMENT_SIZE); + ref_memoryEstimates.assignData(descriptorSizeRequired, contextSizeRequired); + + sizeint totalSizeRequired = descriptorSizeRequired + contextSizeRequired; + return totalSizeRequired; + } + + static void *markCooperativelySolvingL1Stripe_XMemoryStructuresOut(void *buffer, + const FactorizationSolvingL1StripeMemoryEstimates &memoryEstimates, + cellindexint *&out_blockProgressDescriptors, FactorizationSolveL1StripeCellContext *&out_cellContexts) + { + void *currentLocation = buffer; + + out_blockProgressDescriptors = (cellindexint *)currentLocation; currentLocation = (uint8 *)currentLocation + memoryEstimates.m_descriptorSizeRequired; + out_cellContexts = (FactorizationSolveL1StripeCellContext *)currentLocation; currentLocation = (uint8 *)currentLocation + memoryEstimates.m_contextSizeRequired; + + return currentLocation; + } + + static void initializeCooperativelySolvingL1Stripe_XMemoryStructures(unsigned blockCount, + atomicord32 &out_blockCompletionProgress, cellindexint *blockProgressDescriptors, FactorizationSolveL1StripeCellContext *dUNUSED(cellContexts)) + { + out_blockCompletionProgress = 0; + memset(blockProgressDescriptors, 0, blockCount * sizeof(*blockProgressDescriptors)); + } + + template<unsigned int block_step, unsigned int b_rows> + static void participateSolvingL1Stripe_X(const dReal *L, dReal *B, unsigned blockCount, unsigned rowSkip, + volatile atomicord32 &refBlockCompletionProgress/*=0*/, volatile cellindexint *blockProgressDescriptors/*=[blockCount]*/, + FactorizationSolveL1StripeCellContext *cellContexts/*=[CCI__MAX x blockCount] + [blockCount]*/, unsigned ownThreadIndex); + + static unsigned deriveScalingAndFactorizingL1StripeBlockCountFromSolvingBlockIndex(unsigned solvingBlockIndex, unsigned solvingBlockStep, unsigned blockARows) + { + unsigned factorizingBlockSize = deriveScalingAndFactorizingL1StripeBlockSize(blockARows); + return deriveScalingAndFactorizingL1StripeBlockCountFromFactorizationRow(solvingBlockIndex * solvingBlockStep, factorizingBlockSize); + } + + static unsigned deriveScalingAndFactorizingL1StripeBlockCountFromFactorizationRow(unsigned factorizationRowIndex, unsigned factorizationBlockSize) + { + return (factorizationRowIndex + (factorizationBlockSize - 1)) / factorizationBlockSize; + } + + static unsigned deriveScalingAndFactorizingL1StripeBlockSize(unsigned blockARows) + { + unsigned result = blockARows != 1 ? FFL1S_REGULAR_BLOCK_SIZE : FFL1S_FINAL_BLOCK_SIZE; + dIASSERT(blockARows >= 1 && blockARows <= 2); + + return result; + } + + + static unsigned deriveScalingAndFactorizingL1StripeThreadCount(unsigned blockCount, unsigned allowedThreadCount) + { + dIASSERT(blockCount != 0); + dIASSERT(allowedThreadCount >= 1); + + return dMACRO_MIN(blockCount, allowedThreadCount); + } + + struct FactorizationFactorizeL1StripeContext; + + struct FactorizationScalingAndFactorizingL1StripeMemoryEstimates + { + void assignData(sizeint contextSizeRequired) + { + m_contextSizeRequired = contextSizeRequired; + } + + sizeint m_contextSizeRequired; + }; + + static sizeint estimateCooperativelyScalingAndFactorizingL1Stripe_XMemoryRequirement(unsigned factorizingMaximumThreads, + FactorizationScalingAndFactorizingL1StripeMemoryEstimates &ref_memoryEstimates) + { + dIASSERT(factorizingMaximumThreads != 0); + + sizeint contextSizeRequired = dOVERALIGNED_SIZE(sizeof(FactorizationFactorizeL1StripeContext) + sizeof(FactorizationFactorizeL1StripeThreadContext) * (factorizingMaximumThreads - 1), COOP_THREAD_DATA_ALIGNMENT_SIZE); + ref_memoryEstimates.assignData(contextSizeRequired); + + sizeint totalSizeRequired = contextSizeRequired; + return totalSizeRequired; + } + + static void *markCooperativelyScalingAndFactorizingL1Stripe_XMemoryStructuresOut(void *buffer, + const FactorizationScalingAndFactorizingL1StripeMemoryEstimates &memoryEstimates, FactorizationFactorizeL1StripeContext *&out_factorizationContext) + { + void *currentLocation = buffer; + + out_factorizationContext = (FactorizationFactorizeL1StripeContext *)currentLocation; currentLocation = (uint8 *)currentLocation + memoryEstimates.m_contextSizeRequired; + + return currentLocation; + } + + static void initializeCooperativelyScalingAndFactorizingL1Stripe_XMemoryStructures( + FactorizationFactorizeL1StripeContext *factorizationContext, unsigned threadCount) + { + factorizationContext->initialize(threadCount); + } + + + template<unsigned int a_rows, unsigned int d_stride> + static void participateScalingAndFactorizingL1Stripe_X(dReal *ARow, dReal *d, unsigned factorizationRow, unsigned rowSkip, + FactorizationFactorizeL1StripeContext *factorizationContext, unsigned ownThreadIndex); + +private: + struct FactorLDLTWorkerContext + { + FactorLDLTWorkerContext(dxThreadingBase *threading, unsigned allowedThreadCount, + dReal *A, dReal *d, unsigned totalBlockCount, unsigned rowCount, unsigned rowSkip, + atomicord32 &ref_solvingBlockCompletionProgress, cellindexint *solvingBlockProgressDescriptors, + FactorizationSolveL1StripeCellContext *solvingCellContexts, + FactorizationFactorizeL1StripeContext *factorizingFactorizationContext, + dCallReleaseeID calculationFinishReleasee): + m_threading(threading), + m_allowedThreadCount(allowedThreadCount), + m_A(A), + m_ARow(A), + m_d(d), + m_solvingBlockIndex(0), + m_totalBlockCount(totalBlockCount), + m_rowCount(rowCount), + m_rowSkip(rowSkip), + m_refSolvingBlockCompletionProgress(ref_solvingBlockCompletionProgress), + m_solvingBlockProgressDescriptors(solvingBlockProgressDescriptors), + m_solvingCellContexts(solvingCellContexts), + m_factorizingFactorizationContext(factorizingFactorizationContext), + m_calculationFinishReleasee(calculationFinishReleasee) + { + } + + void incrementForNextBlock() + { + const unsigned blockStep = FSL1S_BLOCK_SIZE; + + m_ARow += blockStep * m_rowSkip; + m_solvingBlockIndex += 1; + } + + dxThreadingBase *m_threading; + unsigned m_allowedThreadCount; + dReal *m_A; + dReal *m_ARow; + dReal *m_d; + unsigned m_solvingBlockIndex; + unsigned m_totalBlockCount; + unsigned m_rowCount; + unsigned m_rowSkip; + atomicord32 &m_refSolvingBlockCompletionProgress; + cellindexint *m_solvingBlockProgressDescriptors; + FactorizationSolveL1StripeCellContext *m_solvingCellContexts; + FactorizationFactorizeL1StripeContext *m_factorizingFactorizationContext; + dCallReleaseeID m_calculationFinishReleasee; + }; + + static int factotLDLT_solvingComplete_callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee); + static void factotLDLT_solvingComplete(FactorLDLTWorkerContext &ref_context, unsigned ownThreadIndex); + + static int factotLDLT_solvingCompleteSync_callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee); + static void factotLDLT_solvingCompleteSync(FactorLDLTWorkerContext &ref_workerContext); + + static int factotLDLT_scalingAndFactorizingComplete_callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee); + static void factotLDLT_scalingAndFactorizingComplete(FactorLDLTWorkerContext &ref_workerContext, unsigned ownThreadIndex); + + static int factotLDLT_scalingAndFactorizingCompleteSync_callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee); + static void factotLDLT_scalingAndFactorizingCompleteSync(FactorLDLTWorkerContext &ref_workerContext); + + static int factotLDLT_solvingFinal_callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee); + static void factotLDLT_solvingFinal(FactorLDLTWorkerContext &ref_context, unsigned ownThreadIndex); + + static int factotLDLT_solvingFinalSync_callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee); + static void factotLDLT_solvingFinalSync(FactorLDLTWorkerContext &ref_workerContext); + + static int factotLDLT_scalingAndFactorizingFinal_callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee); + static void factotLDLT_scalingAndFactorizingFinal(FactorLDLTWorkerContext &ref_workerContext, unsigned ownThreadIndex); + + static int factotLDLT_completion_callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee); + +private: + struct FactorizationSolveL1StripeCellContext + { + template<unsigned int block_step, unsigned int b_rows> + static void initializePrecalculatedZs(dReal (&Z)[block_step][b_rows]) + { + Z[0][0] = 0; + if (b_rows >= 2) + { + Z[0][1] = 0; + } + Z[1][0] = 0; + if (b_rows >= 2) + { + Z[1][1] = 0; + } + dSASSERT(block_step == 2); + dSASSERT(b_rows >= 1 && b_rows <= 2); + } + + template<unsigned int block_step, unsigned int b_rows> + void loadPrecalculatedZs(dReal (&Z)[block_step][b_rows]) const + { + dSASSERT(block_step <= dARRAY_SIZE(m_c)); + dSASSERT(b_rows <= dARRAY_SIZE(m_c[0])); + + Z[0][0] = m_c[0][0]; + if (b_rows >= 2) + { + Z[0][1] = m_c[0][1]; + } + Z[1][0] = m_c[1][0]; + if (b_rows >= 2) + { + Z[1][1] = m_c[1][1]; + } + dSASSERT(block_step == 2); + dSASSERT(b_rows >= 1 && b_rows <= 2); + } + + template<unsigned int block_step, unsigned int b_rows> + void storePrecalculatedZs(const dReal (&Z)[block_step][b_rows]) + { + dSASSERT(block_step <= dARRAY_SIZE(m_c)); + dSASSERT(b_rows <= dARRAY_SIZE(m_c[0])); + + m_c[0][0] = Z[0][0]; + if (b_rows >= 2) + { + m_c[0][1] = Z[0][1]; + } + m_c[1][0] = Z[1][0]; + if (b_rows >= 2) + { + m_c[1][1] = Z[1][1]; + } + dSASSERT(block_step == 2); + dSASSERT(b_rows >= 1 && b_rows <= 2); + } + + dReal m_c[FSL1S_BLOCK_SIZE][FSL1S_REGULAR_B_ROWS]; + // dReal m_reserved[4]; + }; + + static FactorizationSolveL1StripeCellContext &buildBlockContextRef(FactorizationSolveL1StripeCellContext *cellContexts, unsigned blockIndex, CellContextInstance contextInstance) + { + return cellContexts[blockIndex * CCI__MAX + contextInstance]; + } + + static FactorizationSolveL1StripeCellContext &buildResultContextRef(FactorizationSolveL1StripeCellContext *cellContexts, unsigned blockIndex, unsigned blockCount) + { + return cellContexts[blockCount * CCI__MAX + blockIndex]; + } + +private: + struct FactorizationFactorizeL1StripeThreadContext + { + template<unsigned int a_rows> + void assignDataSum(const dReal (&sameZ)[a_rows], const dReal (&mixedZ)[dMACRO_MAX(a_rows - 1, 1)], + const FactorizationFactorizeL1StripeThreadContext &partialSumContext) + { + m_sameZ[0] = sameZ[0] + partialSumContext.m_sameZ[0]; + if (a_rows >= 2) + { + m_sameZ[1] = sameZ[1] + partialSumContext.m_sameZ[1]; + m_mixedZ[0] = mixedZ[0] + partialSumContext.m_mixedZ[0]; + } + } + + template<unsigned int a_rows> + void assignDataAlone(const dReal (&sameZ)[a_rows], const dReal (&mixedZ)[dMACRO_MAX(a_rows - 1, 1)]) + { + m_sameZ[0] = sameZ[0]; + if (a_rows >= 2) + { + m_sameZ[1] = sameZ[1]; + m_mixedZ[0] = mixedZ[0]; + } + } + + template<unsigned int a_rows> + void retrieveData(dReal (&out_sameZ)[a_rows], dReal (&out_mixedZ)[dMACRO_MAX(a_rows - 1, 1)]) const + { + out_sameZ[0] = m_sameZ[0]; + if (a_rows >= 2) + { + out_sameZ[1] = m_sameZ[1]; + out_mixedZ[0] = m_mixedZ[0]; + } + dAASSERT(a_rows >= 1 && a_rows <= 2); + } + + dReal m_sameZ[FFL1S_REGULAR_A_ROWS]; + dReal m_mixedZ[dMACRO_MAX(FFL1S_REGULAR_A_ROWS - 1, 1)]; + dReal m_reserved[1]; // [5]; // for alignment + }; + + struct FactorizationFactorizeL1StripeContext + { + void initialize(unsigned threadCount) + { + m_threadsRunning = threadCount; + m_nextColumnIndex = 0; + m_sumThreadIndex = 0; + } + + atomicord32 m_threadsRunning; + atomicord32 m_nextColumnIndex; + volatile atomicord32 m_sumThreadIndex; + atomicord32 m_reserved[1]; // [13]; // for alignment + FactorizationFactorizeL1StripeThreadContext m_threadContexts[1]; // =[threadCount] + }; + +private: + struct SolveL1StraightCellContext; + + enum + { + SL1S_COOPERATIVE_BLOCK_COUNT_MINIMUM = 8, + + SL1S_B_STRIDE = 1, + SL1S_BLOCK_SIZE = 4, + }; + + static unsigned restrictSolvingL1StraightAllowedThreadCount( + dxThreadingBase *threading, unsigned allowedThreadCount, unsigned rowCount); + static void doEstimateCooperativeSolvingL1StraightResourceRequirementsValidated( + dxResourceRequirementDescriptor *summaryRequirementsDescriptor, + unsigned allowedThreadCount, unsigned rowCount); + static void doCooperativelySolveL1StraightValidated( + dxRequiredResourceContainer *resourceContainer, unsigned allowedThreadCount, + const dReal *L, dReal *b, unsigned rowCount, unsigned rowSkip); + + static unsigned deriveSolvingL1StraightBlockCount(unsigned rowCount, unsigned blockStep) + { + return (rowCount + (blockStep - 1)) / blockStep; + } + + struct SolvingL1StraightMemoryEstimates + { + void assignData(sizeint descriptorSizeRequired, sizeint contextSizeRequired) + { + m_descriptorSizeRequired = descriptorSizeRequired; + m_contextSizeRequired = contextSizeRequired; + } + + sizeint m_descriptorSizeRequired; + sizeint m_contextSizeRequired; + }; + + static unsigned deriveSolvingL1StraightThreadCount(unsigned blockCount, unsigned allowedThreadCount) + { + dIASSERT(allowedThreadCount >= 1); + + unsigned maximumCount = 1 + blockCount / SL1S_COOPERATIVE_BLOCK_COUNT_MINIMUM; + return maximumCount >= allowedThreadCount ? allowedThreadCount : dMACRO_MAX(maximumCount, 1U); + } + + template<unsigned int block_step> + static sizeint estimateCooperativelySolvingL1StraightMemoryRequirement(unsigned rowCount, SolvingL1StraightMemoryEstimates &ref_solvingMemoryEstimates); + + static void *markCooperativelySolvingL1StraightMemoryStructuresOut(void *buffer, + const SolvingL1StraightMemoryEstimates &solvingMemoryEstimates, + cellindexint *&out_blockProgressDescriptors, SolveL1StraightCellContext *&out_cellContexts) + { + void *currentLocation = buffer; + + out_blockProgressDescriptors = (cellindexint *)currentLocation; currentLocation = (uint8 *)currentLocation + solvingMemoryEstimates.m_descriptorSizeRequired; + out_cellContexts = (SolveL1StraightCellContext *)currentLocation; currentLocation = (uint8 *)currentLocation + solvingMemoryEstimates.m_contextSizeRequired; + return currentLocation; + } + + template<unsigned int block_step> + static void initializeCooperativelySolveL1StraightMemoryStructures(unsigned rowCount, + atomicord32 &out_blockCompletionProgress, cellindexint *blockProgressDescriptors, SolveL1StraightCellContext *cellContexts); + template<unsigned int block_step, unsigned int b_stride> + static void participateSolvingL1Straight(const dReal *L, dReal *B, unsigned rowCount, unsigned rowSkip, + volatile atomicord32 &refBlockCompletionProgress/*=0*/, volatile cellindexint *blockProgressDescriptors/*=[blockCount]*/, + SolveL1StraightCellContext *cellContexts/*=[CCI__MAX x blockCount] + [blockCount]*/, unsigned ownThreadIndex); + +private: + struct SolveL1StraightWorkerContext + { + void init(const dReal *L, dReal *b, unsigned rowCount, unsigned rowSkip, + atomicord32 &ref_blockCompletionProgress, cellindexint *blockProgressDescriptors, SolveL1StraightCellContext *cellContexts) + { + m_L = L; + m_b = b; + m_rowCount = rowCount; + m_rowSkip = rowSkip; + m_ptrBlockCompletionProgress = &ref_blockCompletionProgress; + m_blockProgressDescriptors = blockProgressDescriptors; + m_cellContexts = cellContexts; + } + + const dReal *m_L; + dReal *m_b; + unsigned m_rowCount; + unsigned m_rowSkip; + atomicord32 *m_ptrBlockCompletionProgress; + cellindexint *m_blockProgressDescriptors; + SolveL1StraightCellContext *m_cellContexts; + }; + + static int solveL1Straight_worker_callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee); + static void solveL1Straight_worker(SolveL1StraightWorkerContext &ref_context, unsigned ownThreadIndex); + + static int solveL1Straight_completion_callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee); + +private: + struct SolveL1StraightCellContext + { + template<unsigned int block_step> + static void initializePrecalculatedZs(dReal (&Z)[block_step]) + { + std::fill(Z, Z + block_step, REAL(0.0)); + } + + template<unsigned int block_step> + void loadPrecalculatedZs(dReal (&Z)[block_step]) const + { + dSASSERT(block_step <= dARRAY_SIZE(m_c)); + + std::copy(m_c, m_c + block_step, Z); + } + + template<unsigned int block_step> + void storePrecalculatedZs(const dReal (&Z)[block_step]) + { + dSASSERT(block_step <= dARRAY_SIZE(m_c)); + + std::copy(Z, Z + block_step, m_c); + } + + dReal m_c[SL1S_BLOCK_SIZE]; + }; + + + static SolveL1StraightCellContext &buildBlockContextRef(SolveL1StraightCellContext *cellContexts, unsigned blockIndex, CellContextInstance contextInstance) + { + return cellContexts[blockIndex * CCI__MAX + contextInstance]; + } + + static SolveL1StraightCellContext &buildResultContextRef(SolveL1StraightCellContext *cellContexts, unsigned blockIndex, unsigned blockCount) + { + return cellContexts[blockCount * CCI__MAX + blockIndex]; + } + + +private: + struct SolveL1TransposedCellContext; + + enum + { + SL1T_COOPERATIVE_BLOCK_COUNT_MINIMUM = SL1S_COOPERATIVE_BLOCK_COUNT_MINIMUM, + + SL1T_B_STRIDE = SL1S_B_STRIDE, + SL1T_BLOCK_SIZE = 4, + }; + + static unsigned restrictSolvingL1TransposedAllowedThreadCount( + dxThreadingBase *threading, unsigned allowedThreadCount, unsigned rowCount); + static void doEstimateCooperativeSolvingL1TransposedResourceRequirementsValidated( + dxResourceRequirementDescriptor *summaryRequirementsDescriptor, + unsigned allowedThreadCount, unsigned rowCount); + static void doCooperativelySolveL1TransposedValidated( + dxRequiredResourceContainer *resourceContainer, unsigned allowedThreadCount, + const dReal *L, dReal *b, unsigned rowCount, unsigned rowSkip); + + static unsigned deriveSolvingL1TransposedBlockCount(unsigned rowCount, unsigned blockStep) + { + return (rowCount + (blockStep - 1)) / blockStep; + } + + struct SolvingL1TransposedMemoryEstimates + { + void assignData(sizeint descriptorSizeRequired, sizeint contextSizeRequired) + { + m_descriptorSizeRequired = descriptorSizeRequired; + m_contextSizeRequired = contextSizeRequired; + } + + sizeint m_descriptorSizeRequired; + sizeint m_contextSizeRequired; + }; + + static unsigned deriveSolvingL1TransposedThreadCount(unsigned blockCount, unsigned allowedThreadCount) + { + dSASSERT(SL1T_COOPERATIVE_BLOCK_COUNT_MINIMUM + 0 == SL1S_COOPERATIVE_BLOCK_COUNT_MINIMUM); + + return deriveSolvingL1StraightThreadCount(blockCount, allowedThreadCount); + } + + template<unsigned int block_step> + static sizeint estimateCooperativelySolvingL1TransposedMemoryRequirement(unsigned rowCount, SolvingL1TransposedMemoryEstimates &ref_solvingMemoryEstimates); + + static void *markCooperativelySolvingL1TransposedMemoryStructuresOut(void *buffer, + const SolvingL1TransposedMemoryEstimates &solvingMemoryEstimates, + cellindexint *&out_blockProgressDescriptors, SolveL1TransposedCellContext *&out_cellContexts) + { + void *currentLocation = buffer; + + out_blockProgressDescriptors = (cellindexint *)currentLocation; currentLocation = (uint8 *)currentLocation + solvingMemoryEstimates.m_descriptorSizeRequired; + out_cellContexts = (SolveL1TransposedCellContext *)currentLocation; currentLocation = (uint8 *)currentLocation + solvingMemoryEstimates.m_contextSizeRequired; + return currentLocation; + } + + template<unsigned int block_step> + static void *allocateCooperativelySolveL1TransposedMemoryStructures(sizeint &out_sizeAllocated, unsigned rowCount, + cellindexint *&out_blockProgressDescriptors, SolveL1TransposedCellContext *&out_cellContexts); + template<unsigned int block_step> + static void initializeCooperativelySolveL1TransposedMemoryStructures(unsigned rowCount, + atomicord32 &out_blockCompletionProgress, cellindexint *blockProgressDescriptors, SolveL1TransposedCellContext *cellContexts); + template<unsigned int block_step, unsigned int b_stride> + static void participateSolvingL1Transposed(const dReal *L, dReal *B, unsigned rowCount, unsigned rowSkip, + volatile atomicord32 &refBlockCompletionProgress/*=0*/, volatile cellindexint *blockProgressDescriptors/*=[blockCount]*/, + SolveL1TransposedCellContext *cellContexts/*=[CCI__MAX x blockCount] + [blockCount]*/, unsigned ownThreadIndex); + +private: + struct SolveL1TransposedWorkerContext + { + void init(const dReal *L, dReal *b, unsigned rowCount, unsigned rowSkip, + atomicord32 &ref_blockCompletionProgress, cellindexint *blockProgressDescriptors, SolveL1TransposedCellContext *cellContexts) + { + m_L = L; + m_b = b; + m_rowCount = rowCount; + m_rowSkip = rowSkip; + m_ptrBlockCompletionProgress = &ref_blockCompletionProgress; + m_blockProgressDescriptors = blockProgressDescriptors; + m_cellContexts = cellContexts; + } + + const dReal *m_L; + dReal *m_b; + unsigned m_rowCount; + unsigned m_rowSkip; + atomicord32 *m_ptrBlockCompletionProgress; + cellindexint *m_blockProgressDescriptors; + SolveL1TransposedCellContext *m_cellContexts; + }; + + static int solveL1Transposed_worker_callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee); + static void solveL1Transposed_worker(SolveL1TransposedWorkerContext &ref_context, unsigned ownThreadIndex); + + static int solveL1Transposed_completion_callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee); + +private: + struct SolveL1TransposedCellContext + { + template<unsigned int block_step> + static void initializePrecalculatedZs(dReal (&Z)[block_step]) + { + std::fill(Z, Z + block_step, REAL(0.0)); + } + + template<unsigned int block_step> + void loadPrecalculatedZs(dReal (&Z)[block_step]) const + { + dSASSERT(block_step <= dARRAY_SIZE(m_c)); + + std::copy(m_c, m_c + block_step, Z); + } + + template<unsigned int block_step> + void storePrecalculatedZs(const dReal (&Z)[block_step]) + { + dSASSERT(block_step <= dARRAY_SIZE(m_c)); + + std::copy(Z, Z + block_step, m_c); + } + + dReal m_c[SL1T_BLOCK_SIZE]; + }; + + static SolveL1TransposedCellContext &buildBlockContextRef(SolveL1TransposedCellContext *cellContexts, unsigned blockIndex, CellContextInstance contextInstance) + { + return cellContexts[blockIndex * CCI__MAX + contextInstance]; + } + + static SolveL1TransposedCellContext &buildResultContextRef(SolveL1TransposedCellContext *cellContexts, unsigned blockIndex, unsigned blockCount) + { + return cellContexts[blockCount * CCI__MAX + blockIndex]; + } + +private: + enum + { + SV_A_STRIDE = 1, + SV_D_STRIDE = 1, + + SV_BLOCK_SIZE = 128, + SV_COOPERATIVE_BLOCK_COUNT_MINIMUM = 3, + }; + + static unsigned restrictScalingVectorAllowedThreadCount( + dxThreadingBase *threading, unsigned allowedThreadCount, unsigned elementCount); + static void doEstimateCooperativeScalingVectorResourceRequirementsValidated( + dxResourceRequirementDescriptor *summaryRequirementsDescriptor, + unsigned allowedThreadCount, unsigned elementCount); + static void doCooperativelyScaleVectorValidated(dxRequiredResourceContainer *resourceContainer, unsigned allowedThreadCount, + dReal *vectorData, const dReal *scaleData, unsigned elementCount); + + static unsigned deriveScalingVectorBlockCount(unsigned elementCount, unsigned blockStep) + { + return (elementCount + (blockStep - 1)) / blockStep; + } + + static unsigned deriveScalingVectorThreadCount(unsigned lastBlockIndex, unsigned allowedThreadCount) + { + dIASSERT(allowedThreadCount >= 1); + + unsigned maximumCount = lastBlockIndex; + return maximumCount >= allowedThreadCount ? allowedThreadCount : dMACRO_MAX(maximumCount, 1U); + } + + static void initializeCooperativelyScaleVectorMemoryStructures(atomicord32 &out_blockCompletionProgress) + { + out_blockCompletionProgress = 0; + } + template<unsigned int block_step, unsigned int a_stride, unsigned int d_stride> + static void participateScalingVector(dReal *ptrAStart, const dReal *ptrDStart, const unsigned elementCount, + volatile atomicord32 &refBlockCompletionProgress/*=0*/); + +private: + struct ScaleVectorWorkerContext + { + void init(dReal *vectorData, const dReal *scaleData, unsigned elementCount, + atomicord32 &ref_blockCompletionProgress) + { + m_vectorData = vectorData; + m_scaleData = scaleData; + m_elementCount = elementCount; + m_ptrBlockCompletionProgress = &ref_blockCompletionProgress; + } + + dReal *m_vectorData; + const dReal *m_scaleData; + unsigned m_elementCount; + atomicord32 *m_ptrBlockCompletionProgress; + }; + + static int scaleVector_worker_callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee); + static void scaleVector_worker(ScaleVectorWorkerContext &ref_context); + + static int scaleVector_completion_callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee); + + +private: + enum SolvingLDLTStage + { + SLDLTS__MIN, + + SLDLTS_SOLVING_STRAIGHT = SLDLTS__MIN, + SLDLTS_SCALING_VECTOR, + SLDLTS_SOLVING_TRANSPOSED, + + SLDLTS__MAX, + }; + + enum + { + SLDLT_B_STRIDE = SL1S_B_STRIDE, + SLDLT_D_STRIDE = FLDLT_D_STRIDE, + }; + + static unsigned restrictSolvingLDLTAllowedThreadCount( + dxThreadingBase *threading, unsigned allowedThreadCount, unsigned rowCount, unsigned &out_stageBlockCountSifficiencyMask); + + static void doCooperativelySolveLDLTValidated( + dxRequiredResourceContainer *resourceContainer, unsigned allowedThreadCount, unsigned stageBlockCountSifficiencyMask, + const dReal *L, const dReal *d, dReal *b, unsigned rowCount, unsigned rowSkip); +}; + + +#endif + diff --git a/libs/ode-0.16.1/ode/src/threading_atomics_provs.h b/libs/ode-0.16.1/ode/src/threading_atomics_provs.h new file mode 100644 index 0000000..3afc7b3 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/threading_atomics_provs.h @@ -0,0 +1,194 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * Threading atomics providers file. * + * Copyright (C) 2011-2019 Oleh Derevenko. All rights reserved. * + * e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * Fake atomics provider for built-in threading support provider. + * OU-based atomics provider for built-in threading support provider. + * + * The classes have been moved into a separate header as they are to be used + * in both WIN and POSIX implementations. + */ + + +#ifndef _ODE_THREADING_ATOMICS_PROVS_H_ +#define _ODE_THREADING_ATOMICS_PROVS_H_ + + +#include <ode/odeconfig.h> +#include <ode/error.h> + + +/************************************************************************/ +/* Fake atomics provider class implementation */ +/************************************************************************/ + +class dxFakeAtomicsProvider +{ +public: + typedef unsigned long atomicord_t; + typedef void *atomicptr_t; + +public: + static void IncrementTargetNoRet(volatile atomicord_t *value_accumulator_ptr) + { + ++(*value_accumulator_ptr); + } + + static void DecrementTargetNoRet(volatile atomicord_t *value_accumulator_ptr) + { + --(*value_accumulator_ptr); + } + + static atomicord_t QueryTargetValue(volatile atomicord_t *value_storage_ptr) + { + return *value_storage_ptr; + } + + template<unsigned type_size> + static sizeint AddValueToTarget(volatile void *value_accumulator_ptr, diffint value_addend); + + static bool CompareExchangeTargetPtr(volatile atomicptr_t *pointer_storage_ptr, + atomicptr_t comparand_value, atomicptr_t new_value) + { + bool exchange_result = false; + + atomicptr_t original_value = *pointer_storage_ptr; + + if (original_value == comparand_value) + { + *pointer_storage_ptr = new_value; + + exchange_result = true; + } + + return exchange_result; + } +}; + +template<> +inline sizeint dxFakeAtomicsProvider::AddValueToTarget<sizeof(dxFakeAtomicsProvider::atomicord_t)>(volatile void *value_accumulator_ptr, diffint value_addend) +{ + atomicord_t original_value = *(volatile atomicord_t *)value_accumulator_ptr; + + *(volatile atomicord_t *)value_accumulator_ptr = original_value + (atomicord_t)value_addend; + + return original_value; +} + +template<> +inline sizeint dxFakeAtomicsProvider::AddValueToTarget<2 * sizeof(dxFakeAtomicsProvider::atomicord_t)>(volatile void *value_accumulator_ptr, diffint value_addend) +{ + atomicptr_t original_value = *(volatile atomicptr_t *)value_accumulator_ptr; + + *(volatile atomicptr_t *)value_accumulator_ptr = (atomicptr_t)((sizeint)original_value + (sizeint)value_addend); + + return (sizeint)original_value; +} + + +#if dBUILTIN_THREADING_IMPL_ENABLED + +/************************************************************************/ +/* dxOUAtomicsProvider class implementation */ +/************************************************************************/ + +#if !dOU_ENABLED +#error OU library must be enabled for this to compile +#elif !dATOMICS_ENABLED +#error OU Atomics must be enabled for this to compile +#endif +#include "odeou.h" + +class dxOUAtomicsProvider +{ +public: + typedef _OU_NAMESPACE::atomicord32 atomicord_t; + typedef _OU_NAMESPACE::atomicptr atomicptr_t; + +public: + static void IncrementTargetNoRet(volatile atomicord_t *value_accumulator_ptr) + { + _OU_NAMESPACE::AtomicIncrementNoResult(value_accumulator_ptr); + } + + static void DecrementTargetNoRet(volatile atomicord_t *value_accumulator_ptr) + { + _OU_NAMESPACE::AtomicDecrementNoResult(value_accumulator_ptr); + } + + static atomicord_t QueryTargetValue(volatile atomicord_t *value_storage_ptr) + { + // Query value with memory barrier before + atomicord_t result_value = *value_storage_ptr; + + if (!_OU_NAMESPACE::AtomicCompareExchange(value_storage_ptr, result_value, result_value)) + { + result_value = *value_storage_ptr; + } + + return result_value; + } + + template<unsigned type_size> + static sizeint AddValueToTarget(volatile void *value_accumulator_ptr, diffint value_addend); + + static bool CompareExchangeTargetPtr(volatile atomicptr_t *pointer_storage_ptr, + atomicptr_t comparand_value, atomicptr_t new_value) + { + return _OU_NAMESPACE::AtomicCompareExchangePointer(pointer_storage_ptr, comparand_value, new_value); + } +}; + +template<> +inline sizeint dxOUAtomicsProvider::AddValueToTarget<sizeof(dxOUAtomicsProvider::atomicord_t)>(volatile void *value_accumulator_ptr, diffint value_addend) +{ + return _OU_NAMESPACE::AtomicExchangeAdd((volatile atomicord_t *)value_accumulator_ptr, (atomicord_t)value_addend); +} + +template<> +inline sizeint dxOUAtomicsProvider::AddValueToTarget<2 * sizeof(dxOUAtomicsProvider::atomicord_t)>(volatile void *value_accumulator_ptr, diffint value_addend) +{ + atomicptr_t original_value; + + while (true) + { + original_value = *(volatile atomicptr_t *)value_accumulator_ptr; + + atomicptr_t new_value = (atomicptr_t)((sizeint)original_value + (sizeint)value_addend); + if (_OU_NAMESPACE::AtomicCompareExchangePointer((volatile atomicptr_t *)value_accumulator_ptr, original_value, new_value)) + { + break; + } + } + + return (sizeint)original_value; +} + + +#endif // #if dBUILTIN_THREADING_IMPL_ENABLED + + +#endif // #ifndef _ODE_THREADING_ATOMICS_PROVS_H_ diff --git a/libs/ode-0.16.1/ode/src/threading_base.cpp b/libs/ode-0.16.1/ode/src/threading_base.cpp new file mode 100644 index 0000000..9272eff --- /dev/null +++ b/libs/ode-0.16.1/ode/src/threading_base.cpp @@ -0,0 +1,135 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * Threading base wrapper class implementation file. * + * Copyright (C) 2011-2019 Oleh Derevenko. All rights reserved. * + * e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * Threading base class to be used for inheritance by dxWorld, dxSpace and others + * to take advantage of threaded execution. + */ + + +#include <ode/common.h> +#include "config.h" +#include "error.h" +#include "threading_base.h" + + +dxThreadingBase::~dxThreadingBase() +{ + DoFreeStockCallWait(); +} + + +void dxThreadingBase::PostThreadedCallsGroup( + int *out_summary_fault/*=NULL*/, + ddependencycount_t member_count, dCallReleaseeID dependent_releasee/*=NULL*/, + dThreadedCallFunction *call_func, void *call_context, + const char *call_name/*=NULL*/) const +{ + dIASSERT(member_count != 0); + + dThreadingImplementationID impl; + const dxThreadingFunctionsInfo *functions = FindThreadingImpl(impl); + + for (unsigned member_index = 0; member_index != member_count; ++member_index) { + // Post individual group member jobs + functions->post_call(impl, out_summary_fault, NULL, 0, dependent_releasee, NULL, call_func, call_context, member_index, call_name); + } +} + +void dxThreadingBase::PostThreadedCallsIndexOverridenGroup(int *out_summary_fault/*=NULL*/, + ddependencycount_t member_count, dCallReleaseeID dependent_releasee/*=NULL*/, + dThreadedCallFunction *call_func, void *call_context, unsigned index_override, + const char *call_name/*=NULL*/) const +{ + dIASSERT(member_count != 0); + + dThreadingImplementationID impl; + const dxThreadingFunctionsInfo *functions = FindThreadingImpl(impl); + + for (unsigned member_index = 0; member_index != member_count; ++member_index) { + // Post individual group member jobs + functions->post_call(impl, out_summary_fault, NULL, 0, dependent_releasee, NULL, call_func, call_context, index_override, call_name); + } +} + +void dxThreadingBase::PostThreadedCallForUnawareReleasee( + int *out_summary_fault/*=NULL*/, + dCallReleaseeID *out_post_releasee/*=NULL*/, ddependencycount_t dependencies_count, dCallReleaseeID dependent_releasee/*=NULL*/, + dCallWaitID call_wait/*=NULL*/, + dThreadedCallFunction *call_func, void *call_context, dcallindex_t instance_index, + const char *call_name/*=NULL*/) const +{ + dThreadingImplementationID impl; + const dxThreadingFunctionsInfo *functions = FindThreadingImpl(impl); + + functions->alter_call_dependencies_count(impl, dependent_releasee, 1); + functions->post_call(impl, out_summary_fault, out_post_releasee, dependencies_count, dependent_releasee, call_wait, call_func, call_context, instance_index, call_name); +} + + +const dxThreadingFunctionsInfo *dxThreadingBase::FindThreadingImpl(dThreadingImplementationID &out_impl_found) const +{ + const dxThreadingFunctionsInfo *functions_found = GetFunctionsInfo(); + + if (functions_found != NULL) + { + out_impl_found = GetThreadingImpl(); + } + else + { + functions_found = m_default_impl_provider->retrieveThreadingDefaultImpl(out_impl_found); + } + + return functions_found; +} + + +dCallWaitID dxThreadingBase::DoAllocateStockCallWait() +{ + dIASSERT(GetStockCallWait() == NULL); + + dCallWaitID stock_wait_id = AllocThreadedCallWait(); + + if (stock_wait_id != NULL) + { + SetStockCallWait(stock_wait_id); + } + + return stock_wait_id; +} + +void dxThreadingBase::DoFreeStockCallWait() +{ + dCallWaitID stock_wait_id = GetStockCallWait(); + + if (stock_wait_id != NULL) + { + FreeThreadedCallWait(stock_wait_id); + + SetStockCallWait(NULL); + } +} + diff --git a/libs/ode-0.16.1/ode/src/threading_base.h b/libs/ode-0.16.1/ode/src/threading_base.h new file mode 100644 index 0000000..cb38f7f --- /dev/null +++ b/libs/ode-0.16.1/ode/src/threading_base.h @@ -0,0 +1,291 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * Threading base wrapper class header file. * + * Copyright (C) 2011-2019 Oleh Derevenko. All rights reserved. * + * e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * Threading base class to be used for inheritance by dxWorld, dxSpace and others + * to take advantage of threaded execution. + */ + + +#ifndef _ODE_THREADING_BASE_H_ +#define _ODE_THREADING_BASE_H_ + + +#include "common.h" +#include <ode/threading.h> + + +struct dxIThreadingDefaultImplProvider +{ +public: + virtual const dxThreadingFunctionsInfo *retrieveThreadingDefaultImpl(dThreadingImplementationID &out_defaultImpl) = 0; +}; + + +class dxThreadingBase +{ +protected: + dxThreadingBase(): + m_default_impl_provider(NULL), + m_functions_info(NULL), + m_threading_impl(NULL), + m_stock_call_wait(NULL) + { + } + + // This ought to be done via constructor, but passing 'this' in base class initializer emits a warning in MSVC :( + void setThreadingDefaultImplProvider(dxIThreadingDefaultImplProvider *default_impl_provider) + { + m_default_impl_provider = default_impl_provider; + dIASSERT(GetStockCallWait() == NULL); + } + + ~dxThreadingBase(); + +public: + void assignThreadingImpl(const dxThreadingFunctionsInfo *functions_info, dThreadingImplementationID threading_impl) + { + dAASSERT((functions_info == NULL) == (threading_impl == NULL)); + + // Free the stock call wait first to have it executed before new pointer values are assigned + DoFreeStockCallWait(); + + m_functions_info = functions_info; + m_threading_impl = threading_impl; + } + +public: + unsigned calculateThreadingLimitedThreadCount(unsigned limitValue, bool countCallerAsExtraThread, unsigned *ptrOut_activeThreadCount=NULL) const + { + unsigned activeThreadCount = RetrieveThreadingThreadCount(); + + if (ptrOut_activeThreadCount != NULL) + { + *ptrOut_activeThreadCount = activeThreadCount; + } + + unsigned adjustedActiveThreads = countCallerAsExtraThread && activeThreadCount != UINT_MAX ? activeThreadCount + 1 : activeThreadCount; + return limitValue == dTHREADING_THREAD_COUNT_UNLIMITED + ? adjustedActiveThreads + : dMACRO_MIN(limitValue, adjustedActiveThreads); + } + +public: + dCallWaitID AllocateOrRetrieveStockCallWaitID() + { + dCallWaitID stock_wait_id = GetStockCallWait(); + return stock_wait_id != NULL ? (ResetThreadedCallWait(stock_wait_id), stock_wait_id) : DoAllocateStockCallWait(); + } + +public: + dMutexGroupID AllocMutexGroup(dmutexindex_t Mutex_count, const char *const *Mutex_names_ptr/*=NULL*/) const + { + dThreadingImplementationID impl; + const dxThreadingFunctionsInfo *functions = FindThreadingImpl(impl); + return functions->alloc_mutex_group(impl, Mutex_count, Mutex_names_ptr); + } + + void FreeMutexGroup(dMutexGroupID mutex_group) const + { + dThreadingImplementationID impl; + const dxThreadingFunctionsInfo *functions = FindThreadingImpl(impl); + functions->free_mutex_group(impl, mutex_group); + } + + void LockMutexGroupMutex(dMutexGroupID mutex_group, dmutexindex_t mutex_index) const + { + dThreadingImplementationID impl; + const dxThreadingFunctionsInfo *functions = FindThreadingImpl(impl); + functions->lock_group_mutex(impl, mutex_group, mutex_index); + } + +// bool TryLockMutexGroupMutex(dMutexGroupID mutex_group, dmutexindex_t mutex_index) const +// { +// dThreadingImplementationID impl; +// const dxThreadingFunctionsInfo *functions = FindThreadingImpl(impl); +// return functions->trylock_group_mutex(impl, mutex_group, mutex_index) != 0; +// } + + void UnlockMutexGroupMutex(dMutexGroupID mutex_group, dmutexindex_t mutex_index) const + { + dThreadingImplementationID impl; + const dxThreadingFunctionsInfo *functions = FindThreadingImpl(impl); + functions->unlock_group_mutex(impl, mutex_group, mutex_index); + } + + dCallWaitID AllocThreadedCallWait() const + { + dThreadingImplementationID impl; + const dxThreadingFunctionsInfo *functions = FindThreadingImpl(impl); + return functions->alloc_call_wait(impl); + } + + void ResetThreadedCallWait(dCallWaitID call_wait) const + { + dThreadingImplementationID impl; + const dxThreadingFunctionsInfo *functions = FindThreadingImpl(impl); + functions->reset_call_wait(impl, call_wait); + } + + void FreeThreadedCallWait(dCallWaitID call_wait) const + { + dThreadingImplementationID impl; + const dxThreadingFunctionsInfo *functions = FindThreadingImpl(impl); + functions->free_call_wait(impl, call_wait); + } + + void PostThreadedCall(int *out_summary_fault/*=NULL*/, + dCallReleaseeID *out_post_releasee/*=NULL*/, ddependencycount_t dependencies_count, dCallReleaseeID dependent_releasee/*=NULL*/, + dCallWaitID call_wait/*=NULL*/, + dThreadedCallFunction *call_func, void *call_context, dcallindex_t instance_index, + const char *call_name/*=NULL*/) const + { + dThreadingImplementationID impl; + const dxThreadingFunctionsInfo *functions = FindThreadingImpl(impl); + functions->post_call(impl, out_summary_fault, out_post_releasee, dependencies_count, dependent_releasee, call_wait, call_func, call_context, instance_index, call_name); + } + + void AlterThreadedCallDependenciesCount(dCallReleaseeID target_releasee, + ddependencychange_t dependencies_count_change) const + { + dThreadingImplementationID impl; + const dxThreadingFunctionsInfo *functions = FindThreadingImpl(impl); + functions->alter_call_dependencies_count(impl, target_releasee, dependencies_count_change); + } + + void WaitThreadedCallExclusively(int *out_wait_status/*=NULL*/, + dCallWaitID call_wait, const dThreadedWaitTime *timeout_time_ptr/*=NULL*/, + const char *wait_name/*=NULL*/) const + { + dThreadingImplementationID impl; + const dxThreadingFunctionsInfo *functions = FindThreadingImpl(impl); + functions->wait_call(impl, out_wait_status, call_wait, timeout_time_ptr, wait_name); + functions->reset_call_wait(impl, call_wait); + } + + void WaitThreadedCallCollectively(int *out_wait_status/*=NULL*/, + dCallWaitID call_wait, const dThreadedWaitTime *timeout_time_ptr/*=NULL*/, + const char *wait_name/*=NULL*/) const + { + dThreadingImplementationID impl; + const dxThreadingFunctionsInfo *functions = FindThreadingImpl(impl); + functions->wait_call(impl, out_wait_status, call_wait, timeout_time_ptr, wait_name); + } + + unsigned RetrieveThreadingThreadCount() const + { + dThreadingImplementationID impl; + const dxThreadingFunctionsInfo *functions = FindThreadingImpl(impl); + return functions->retrieve_thread_count(impl); + } + + bool PreallocateResourcesForThreadedCalls(unsigned max_simultaneous_calls_estimate) const + { + dThreadingImplementationID impl; + const dxThreadingFunctionsInfo *functions = FindThreadingImpl(impl); + return functions->preallocate_resources_for_calls(impl, max_simultaneous_calls_estimate) != 0; + } + +public: + void PostThreadedCallsGroup(int *out_summary_fault/*=NULL*/, + ddependencycount_t member_count, dCallReleaseeID dependent_releasee/*=NULL*/, + dThreadedCallFunction *call_func, void *call_context, + const char *call_name/*=NULL*/) const; + void PostThreadedCallsIndexOverridenGroup(int *out_summary_fault/*=NULL*/, + ddependencycount_t member_count, dCallReleaseeID dependent_releasee/*=NULL*/, + dThreadedCallFunction *call_func, void *call_context, unsigned index_override, + const char *call_name/*=NULL*/) const; + void PostThreadedCallForUnawareReleasee(int *out_summary_fault/*=NULL*/, + dCallReleaseeID *out_post_releasee/*=NULL*/, ddependencycount_t dependencies_count, dCallReleaseeID dependent_releasee/*=NULL*/, + dCallWaitID call_wait/*=NULL*/, + dThreadedCallFunction *call_func, void *call_context, dcallindex_t instance_index, + const char *call_name/*=NULL*/) const; + +protected: + const dxThreadingFunctionsInfo *FindThreadingImpl(dThreadingImplementationID &out_impl_found) const; + +private: + dCallWaitID DoAllocateStockCallWait(); + void DoFreeStockCallWait(); + +private: + const dxThreadingFunctionsInfo *GetFunctionsInfo() const { return m_functions_info; } + dThreadingImplementationID GetThreadingImpl() const { return m_threading_impl; } + + void SetStockCallWait(dCallWaitID value) { m_stock_call_wait = value; } + dCallWaitID GetStockCallWait() const { return m_stock_call_wait; } + +private: + dxIThreadingDefaultImplProvider *m_default_impl_provider; + const dxThreadingFunctionsInfo *m_functions_info; + dThreadingImplementationID m_threading_impl; + dCallWaitID m_stock_call_wait; +}; + +class dxMutexGroupLockHelper +{ +public: + dxMutexGroupLockHelper(dxThreadingBase *threading_base, dMutexGroupID mutex_group, dmutexindex_t mutex_index): + m_threading_base(threading_base), + m_mutex_group(mutex_group), + m_mutex_index(mutex_index), + m_mutex_locked(true) + { + threading_base->LockMutexGroupMutex(mutex_group, mutex_index); + } + + ~dxMutexGroupLockHelper() + { + if (m_mutex_locked) + { + m_threading_base->UnlockMutexGroupMutex(m_mutex_group, m_mutex_index); + } + } + + void UnlockMutex() + { + dIASSERT(m_mutex_locked); + + m_threading_base->UnlockMutexGroupMutex(m_mutex_group, m_mutex_index); + m_mutex_locked = false; + } + + void RelockMutex() + { + dIASSERT(!m_mutex_locked); + + m_threading_base->LockMutexGroupMutex(m_mutex_group, m_mutex_index); + m_mutex_locked = true; + } + +private: + dxThreadingBase *m_threading_base; + dMutexGroupID m_mutex_group; + dmutexindex_t m_mutex_index; + bool m_mutex_locked; +}; + +#endif // #ifndef _ODE_THREADING_BASE_H_ diff --git a/libs/ode-0.16.1/ode/src/threading_fake_sync.h b/libs/ode-0.16.1/ode/src/threading_fake_sync.h new file mode 100644 index 0000000..d1c2524 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/threading_fake_sync.h @@ -0,0 +1,128 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * Threading fake synchronization objects file. * + * Copyright (C) 2011-2019 Oleh Derevenko. All rights reserved. * + * e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * Self-wakeup implementation for built-in threading support provider. + * Fake mutex implementation for built-in threading support provider. + * + * The classes have been moved into a separate header as they are to be used + * in both WIN and POSIX implementations. + */ + + +#ifndef _ODE_THREADING_FAKE_SYNC_H_ +#define _ODE_THREADING_FAKE_SYNC_H_ + + +#include <ode/odeconfig.h> +#include <ode/error.h> + + +/************************************************************************/ +/* dxSelfWakeup class definition */ +/************************************************************************/ + +class dxSelfWakeup +{ +public: + dxSelfWakeup(): + m_wakeup_state(false), + m_state_is_permanent(false) + { + } + + bool InitializeObject() { return true; } + +public: + void ResetWakeup() { m_wakeup_state = false; m_state_is_permanent = false; } + void WakeupAThread() { dIASSERT(!m_state_is_permanent); m_wakeup_state = true; } // Wakeup should not be used after permanent signal + void WakeupAllThreads() { m_wakeup_state = true; m_state_is_permanent = true; } + + bool WaitWakeup(const dThreadedWaitTime *timeout_time_ptr); + +private: + bool m_wakeup_state; + bool m_state_is_permanent; +}; + + +bool dxSelfWakeup::WaitWakeup(const dThreadedWaitTime *timeout_time_ptr) +{ + (void)timeout_time_ptr; // unused + bool wait_result = m_wakeup_state; + + if (m_wakeup_state) + { + m_wakeup_state = m_state_is_permanent; + } + else + { + dICHECK(false); // Self-wakeup should only be used in cases when waiting is called after object is signaled + } + + return wait_result; +} + + +/************************************************************************/ +/* Fake mutex class implementation */ +/************************************************************************/ + +class dxFakeMutex +{ +public: + dxFakeMutex() {} + + bool InitializeObject() { return true; } + +public: + void LockMutex() { /* Do nothing */ } + bool TryLockMutex() { /* Do nothing */ return true; } + void UnlockMutex() { /* Do nothing */ } +}; + + +/************************************************************************/ +/* Fake lull class implementation */ +/************************************************************************/ + +class dxFakeLull +{ +public: + dxFakeLull() {} + + bool InitializeObject() { return true; } + +public: + void RegisterToLull() { /* Do nothing */ } + void WaitForLullAlarm() { dICHECK(false); } // Fake lull can't be waited + void UnregisterFromLull() { /* Do nothing */ } + + void SignalLullAlarmIfAnyRegistrants() { /* Do nothing */ } +}; + + +#endif // #ifndef _ODE_THREADING_FAKE_SYNC_H_ diff --git a/libs/ode-0.16.1/ode/src/threading_impl.cpp b/libs/ode-0.16.1/ode/src/threading_impl.cpp new file mode 100644 index 0000000..aa30883 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/threading_impl.cpp @@ -0,0 +1,282 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * Threading subsystem implementation file. * + * Copyright (C) 2011-2019 Oleh Derevenko. All rights reserved. * + * e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * Subsystem APIs implementation for built-in threading support provider. + */ + + +#include <ode/common.h> +#include <ode/threading_impl.h> +#include "config.h" +#include "threading_impl_posix.h" +#include "threading_impl_win.h" +#include "threading_impl.h" + + +static dMutexGroupID AllocMutexGroup(dThreadingImplementationID impl, dmutexindex_t Mutex_count, const char *const *Mutex_names_ptr/*=NULL*/); +static void FreeMutexGroup(dThreadingImplementationID impl, dMutexGroupID mutex_group); +static void LockMutexGroupMutex(dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index); +// static int TryLockMutexGroupMutex(dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index); +static void UnlockMutexGroupMutex(dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index); + +static dCallWaitID AllocThreadedCallWait(dThreadingImplementationID impl); +static void ResetThreadedCallWait(dThreadingImplementationID impl, dCallWaitID call_wait); +static void FreeThreadedCallWait(dThreadingImplementationID impl, dCallWaitID call_wait); + +static void PostThreadedCall( + dThreadingImplementationID impl, int *out_summary_fault/*=NULL*/, + dCallReleaseeID *out_post_releasee/*=NULL*/, ddependencycount_t dependencies_count, dCallReleaseeID dependent_releasee/*=NULL*/, + dCallWaitID call_wait/*=NULL*/, + dThreadedCallFunction *call_func, void *call_context, dcallindex_t instance_index, + const char *call_name/*=NULL*/); +static void AlterThreadedCallDependenciesCount( + dThreadingImplementationID impl, dCallReleaseeID target_releasee, + ddependencychange_t dependencies_count_change); +static void WaitThreadedCall( + dThreadingImplementationID impl, int *out_wait_status/*=NULL*/, + dCallWaitID call_wait, const dThreadedWaitTime *timeout_time_ptr/*=NULL*/, + const char *wait_name/*=NULL*/); + +static unsigned RetrieveThreadingThreadCount(dThreadingImplementationID impl); +static int PreallocateResourcesForThreadedCalls(dThreadingImplementationID impl, ddependencycount_t max_simultaneous_calls_estimate); + + +static const dxThreadingFunctionsInfo g_builtin_threading_functions = +{ + sizeof(dxThreadingFunctionsInfo), // unsigned struct_size; + + &AllocMutexGroup, // dMutexGroupAllocFunction *alloc_mutex_group; + &FreeMutexGroup, // dMutexGroupFreeFunction *free_mutex_group; + &LockMutexGroupMutex, // dMutexGroupMutexLockFunction *lock_group_mutex; + &UnlockMutexGroupMutex, // dMutexGroupMutexUnlockFunction *unlock_group_mutex; + + &AllocThreadedCallWait, // dThreadedCallWaitAllocFunction *alloc_call_wait; + &ResetThreadedCallWait, // dThreadedCallWaitResetFunction *reset_call_wait; + &FreeThreadedCallWait, // dThreadedCallWaitFreeFunction *free_call_wait; + + &PostThreadedCall, // dThreadedCallPostFunction *post_call; + &AlterThreadedCallDependenciesCount, // dThreadedCallDependenciesCountAlterFunction *alter_call_dependencies_count; + &WaitThreadedCall, // dThreadedCallWaitFunction *wait_call; + + &RetrieveThreadingThreadCount, // dThreadingImplThreadCountRetrieveFunction *retrieve_thread_count; + &PreallocateResourcesForThreadedCalls, // dThreadingImplResourcesForCallsPreallocateFunction *preallocate_resources_for_calls; + + // &TryLockMutexGroupMutex, // dMutexGroupMutexTryLockFunction *trylock_group_mutex; +}; + + +/*extern */dThreadingImplementationID dThreadingAllocateSelfThreadedImplementation() +{ + dxSelfThreadedThreading *threading = new dxSelfThreadedThreading(); + + if (threading != NULL && !threading->InitializeObject()) + { + delete threading; + threading = NULL; + } + + dxIThreadingImplementation *impl = threading; + return (dThreadingImplementationID)impl; +} + +/*extern */dThreadingImplementationID dThreadingAllocateMultiThreadedImplementation() +{ +#if dBUILTIN_THREADING_IMPL_ENABLED + dxMultiThreadedThreading *threading = new dxMultiThreadedThreading(); + + if (threading != NULL && !threading->InitializeObject()) + { + delete threading; + threading = NULL; + } +#else + dxIThreadingImplementation *threading = NULL; +#endif // #if dBUILTIN_THREADING_IMPL_ENABLED + + dxIThreadingImplementation *impl = threading; + return (dThreadingImplementationID)impl; +} + +/*extern */const dThreadingFunctionsInfo *dThreadingImplementationGetFunctions(dThreadingImplementationID impl) +{ +#if dBUILTIN_THREADING_IMPL_ENABLED + dAASSERT(impl != NULL); +#endif // #if dBUILTIN_THREADING_IMPL_ENABLED + + const dThreadingFunctionsInfo *functions = NULL; + +#if !dBUILTIN_THREADING_IMPL_ENABLED + if (impl != NULL) +#endif // #if !dBUILTIN_THREADING_IMPL_ENABLED + { + functions = &g_builtin_threading_functions; + } + + return functions; +} + +/*extern */void dThreadingImplementationShutdownProcessing(dThreadingImplementationID impl) +{ +#if dBUILTIN_THREADING_IMPL_ENABLED + dAASSERT(impl != NULL); +#endif // #if dBUILTIN_THREADING_IMPL_ENABLED + +#if !dBUILTIN_THREADING_IMPL_ENABLED + if (impl != NULL) +#endif // #if !dBUILTIN_THREADING_IMPL_ENABLED + { + ((dxIThreadingImplementation *)impl)->ShutdownProcessing(); + } +} + +/*extern */void dThreadingImplementationCleanupForRestart(dThreadingImplementationID impl) +{ +#if dBUILTIN_THREADING_IMPL_ENABLED + dAASSERT(impl != NULL); +#endif // #if dBUILTIN_THREADING_IMPL_ENABLED + +#if !dBUILTIN_THREADING_IMPL_ENABLED + if (impl != NULL) +#endif // #if !dBUILTIN_THREADING_IMPL_ENABLED + { + ((dxIThreadingImplementation *)impl)->CleanupForRestart(); + } +} + +/*extern */void dThreadingFreeImplementation(dThreadingImplementationID impl) +{ + if (impl != NULL) + { + ((dxIThreadingImplementation *)impl)->FreeInstance(); + } +} + + +/*extern */void dExternalThreadingServeMultiThreadedImplementation(dThreadingImplementationID impl, + dThreadReadyToServeCallback *readiness_callback/*=NULL*/, void *callback_context/*=NULL*/) +{ +#if dBUILTIN_THREADING_IMPL_ENABLED + dAASSERT(impl != NULL); +#endif // #if dBUILTIN_THREADING_IMPL_ENABLED + +#if !dBUILTIN_THREADING_IMPL_ENABLED + if (impl != NULL) +#endif // #if !dBUILTIN_THREADING_IMPL_ENABLED + { + ((dxIThreadingImplementation *)impl)->StickToJobsProcessing(readiness_callback, callback_context); + } +} + + +////////////////////////////////////////////////////////////////////////// + +static dMutexGroupID AllocMutexGroup(dThreadingImplementationID impl, dmutexindex_t Mutex_count, const char *const *Mutex_names_ptr/*=NULL*/) +{ + (void)Mutex_names_ptr; // unused + dIMutexGroup *mutex_group = ((dxIThreadingImplementation *)impl)->AllocMutexGroup(Mutex_count); + return (dMutexGroupID)mutex_group; +} + +static void FreeMutexGroup(dThreadingImplementationID impl, dMutexGroupID mutex_group) +{ + ((dxIThreadingImplementation *)impl)->FreeMutexGroup((dIMutexGroup *)mutex_group); +} + +static void LockMutexGroupMutex(dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index) +{ + ((dxIThreadingImplementation *)impl)->LockMutexGroupMutex((dIMutexGroup *)mutex_group, mutex_index); +} + +// static int TryLockMutexGroupMutex(dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index) +// { +// bool trylock_result = ((dxIThreadingImplementation *)impl)->TryLockMutexGroupMutex((dIMutexGroup *)mutex_group, mutex_index); +// return trylock_result; +// } + +static void UnlockMutexGroupMutex(dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index) +{ + ((dxIThreadingImplementation *)impl)->UnlockMutexGroupMutex((dIMutexGroup *)mutex_group, mutex_index); +} + + +static dCallWaitID AllocThreadedCallWait(dThreadingImplementationID impl) +{ + dxICallWait *call_wait = ((dxIThreadingImplementation *)impl)->AllocACallWait(); + return (dCallWaitID)call_wait; +} + +static void ResetThreadedCallWait(dThreadingImplementationID impl, dCallWaitID call_wait) +{ + ((dxIThreadingImplementation *)impl)->ResetACallWait((dxICallWait *)call_wait); +} + +static void FreeThreadedCallWait(dThreadingImplementationID impl, dCallWaitID call_wait) +{ + ((dxIThreadingImplementation *)impl)->FreeACallWait((dxICallWait *)call_wait); +} + + +static void PostThreadedCall( + dThreadingImplementationID impl, int *out_summary_fault/*=NULL*/, + dCallReleaseeID *out_post_releasee/*=NULL*/, ddependencycount_t dependencies_count, dCallReleaseeID dependent_releasee/*=NULL*/, + dCallWaitID call_wait/*=NULL*/, + dThreadedCallFunction *call_func, void *call_context, dcallindex_t instance_index, + const char *call_name/*=NULL*/) +{ + (void)call_name; // unused + ((dxIThreadingImplementation *)impl)->ScheduleNewJob(out_summary_fault, out_post_releasee, + dependencies_count, dependent_releasee, (dxICallWait *)call_wait, call_func, call_context, instance_index); +} + +static void AlterThreadedCallDependenciesCount( + dThreadingImplementationID impl, dCallReleaseeID target_releasee, + ddependencychange_t dependencies_count_change) +{ + ((dxIThreadingImplementation *)impl)->AlterJobDependenciesCount(target_releasee, dependencies_count_change); +} + +static void WaitThreadedCall( + dThreadingImplementationID impl, int *out_wait_status/*=NULL*/, + dCallWaitID call_wait, const dThreadedWaitTime *timeout_time_ptr/*=NULL*/, + const char *wait_name/*=NULL*/) +{ + (void)wait_name; // unused + ((dxIThreadingImplementation *)impl)->WaitJobCompletion(out_wait_status, (dxICallWait *)call_wait, timeout_time_ptr); +} + + +static unsigned RetrieveThreadingThreadCount(dThreadingImplementationID impl) +{ + return ((dxIThreadingImplementation *)impl)->RetrieveActiveThreadsCount(); +} + +static int PreallocateResourcesForThreadedCalls(dThreadingImplementationID impl, ddependencycount_t max_simultaneous_calls_estimate) +{ + return ((dxIThreadingImplementation *)impl)->PreallocateJobInfos(max_simultaneous_calls_estimate); +} + + diff --git a/libs/ode-0.16.1/ode/src/threading_impl.h b/libs/ode-0.16.1/ode/src/threading_impl.h new file mode 100644 index 0000000..7fb5c60 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/threading_impl.h @@ -0,0 +1,40 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * Threading implementation private header file. * + * Copyright (C) 2011-2019 Oleh Derevenko. All rights reserved. * + * e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * Threading implementation header for library private functions. + */ + + +#ifndef _ODE__PRIVATE_THREADING_IMPL_H_ +#define _ODE__PRIVATE_THREADING_IMPL_H_ + + +#include <ode/threading_impl.h> + + + +#endif // #ifndef _ODE__PRIVATE_THREADING_IMPL_H_ diff --git a/libs/ode-0.16.1/ode/src/threading_impl_posix.h b/libs/ode-0.16.1/ode/src/threading_impl_posix.h new file mode 100644 index 0000000..0aaf4ae --- /dev/null +++ b/libs/ode-0.16.1/ode/src/threading_impl_posix.h @@ -0,0 +1,638 @@ +/*************************************************************************
+ * *
+ * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. *
+ * All rights reserved. Email: russ@q12.org Web: www.q12.org *
+ * *
+ * Threading POSIX implementation file. *
+ * Copyright (C) 2011-2019 Oleh Derevenko. All rights reserved. *
+ * e-mail: odar@eleks.com (change all "a" to "e") *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of EITHER: *
+ * (1) The GNU Lesser General Public License as published by the Free *
+ * Software Foundation; either version 2.1 of the License, or (at *
+ * your option) any later version. The text of the GNU Lesser *
+ * General Public License is included with this library in the *
+ * file LICENSE.TXT. *
+ * (2) The BSD-style license that is included with this library in *
+ * the file LICENSE-BSD.TXT. *
+ * *
+ * This library 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 files *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
+ * *
+ *************************************************************************/
+
+/*
+ * Threading POSIX implementation for built-in threading support provider.
+ */
+
+
+#ifndef _ODE_THREADING_IMPL_POSIX_H_
+#define _ODE_THREADING_IMPL_POSIX_H_
+
+
+#include <ode/common.h>
+
+
+#if !defined(_WIN32)
+
+
+#include "threading_impl_templates.h"
+#include "threading_fake_sync.h"
+#include "threading_atomics_provs.h"
+
+
+#if dBUILTIN_THREADING_IMPL_ENABLED
+
+#include <pthread.h>
+#include <time.h>
+#include <errno.h>
+
+#if !defined(EOK)
+#define EOK 0
+#endif
+
+
+#if defined(__APPLE__)
+
+#if HAVE_GETTIMEOFDAY
+
+#include <sys/time.h>
+
+#if !defined(CLOCK_MONOTONIC)
+#define CLOCK_MONOTONIC 2
+#endif
+
+static inline
+int _condvar_clock_gettime(int clock_type, timespec *ts)
+{
+ (void)clock_type; // Unused
+ timeval tv;
+ return gettimeofday(&tv, NULL) == 0 ? (ts->tv_sec = tv.tv_sec, ts->tv_nsec = tv.tv_usec * 1000, 0) : (-1);
+}
+
+
+#else // #if !HAVE_GETTIMEOFDAY
+
+#error It is necessary to check manuals for the correct way of getting condvar wait time for this Apple system
+
+
+#endif // #if !HAVE_GETTIMEOFDAY
+
+
+#else // #if !defined(__APPLE__)
+
+#if !HAVE_PTHREAD_CONDATTR_SETCLOCK && !HAVE_NO_PTHREAD_CONDATTR_SETCLOCK
+
+// The code must be compiled without autoconf run, having the project generated by other means.
+// Assume the pthread_condattr_setclock() is available as it is true in most cases and it is the best we can do in such cases.
+#define HAVE_PTHREAD_CONDATTR_SETCLOCK 1
+
+
+#endif // #if !HAVE_PTHREAD_CONDATTR_SETCLOCK && !HAVE_NO_PTHREAD_CONDATTR_SETCLOCK
+
+
+#if HAVE_PTHREAD_CONDATTR_SETCLOCK
+
+static inline
+int _condvar_clock_gettime(int clock_type, timespec *ts)
+{
+ return clock_gettime(clock_type, ts);
+}
+
+
+#else // #if !HAVE_PTHREAD_CONDATTR_SETCLOCK
+
+#error It is necessary to check manuals for the correct way of getting condvar wait time for this system
+
+
+#endif // #if !HAVE_PTHREAD_CONDATTR_SETCLOCK
+
+
+#endif // #if !defined(__APPLE__)
+
+
+/************************************************************************/
+/* dxCondvarWakeup class implementation */
+/************************************************************************/
+
+class dxCondvarWakeup
+{
+public:
+ dxCondvarWakeup(): m_waiters_list(NULL), m_signaled_state(false), m_state_is_permanent(false), m_object_initialized(false) {}
+ ~dxCondvarWakeup() { DoFinalizeObject(); }
+
+ bool InitializeObject() { return DoInitializeObject(); }
+
+private:
+ bool DoInitializeObject();
+ void DoFinalizeObject();
+
+public:
+ void ResetWakeup();
+ void WakeupAThread();
+ void WakeupAllThreads();
+
+ bool WaitWakeup(const dThreadedWaitTime *timeout_time_ptr);
+
+private:
+ bool BlockAsAWaiter(const dThreadedWaitTime *timeout_time_ptr);
+
+private:
+ struct dxWaiterInfo
+ {
+ dxWaiterInfo(): m_signal_state(false) {}
+
+ dxWaiterInfo **m_prev_info_ptr;
+ dxWaiterInfo *m_next_info;
+ bool m_signal_state;
+ };
+
+ void RegisterWaiterInList(dxWaiterInfo *waiter_info);
+ void UnregisterWaiterFromList(dxWaiterInfo *waiter_info);
+
+ bool MarkSignaledFirstWaiter();
+ static bool MarkSignaledFirstWaiterMeaningful(dxWaiterInfo *first_waiter);
+ bool MarkSignaledAllWaiters();
+ static bool MarkSignaledAllWaitersMeaningful(dxWaiterInfo *first_waiter);
+
+private:
+ dxWaiterInfo *m_waiters_list;
+ bool m_signaled_state;
+ bool m_state_is_permanent;
+ bool m_object_initialized;
+ pthread_mutex_t m_wakeup_mutex;
+ pthread_cond_t m_wakeup_cond;
+};
+
+
+bool dxCondvarWakeup::DoInitializeObject()
+{
+ dIASSERT(!m_object_initialized);
+
+ bool init_result = false;
+
+ pthread_condattr_t cond_condattr;
+ bool mutex_initialized = false, condattr_initialized = false;
+
+ do
+ {
+ int mutex_result = pthread_mutex_init(&m_wakeup_mutex, NULL);
+ if (mutex_result != EOK)
+ {
+ errno = mutex_result;
+ break;
+ }
+
+ mutex_initialized = true;
+
+ int condattr_init_result = pthread_condattr_init(&cond_condattr);
+ if (condattr_init_result != EOK)
+ {
+ errno = condattr_init_result;
+ break;
+ }
+
+ condattr_initialized = true;
+
+#if HAVE_PTHREAD_CONDATTR_SETCLOCK
+ int condattr_clock_result = pthread_condattr_setclock(&cond_condattr, CLOCK_MONOTONIC);
+ if (condattr_clock_result != EOK)
+ {
+ errno = condattr_clock_result;
+ break;
+ }
+#endif // #if HAVE_PTHREAD_CONDATTR_SETCLOCK
+
+ int cond_result = pthread_cond_init(&m_wakeup_cond, &cond_condattr);
+ if (cond_result != EOK)
+ {
+ errno = cond_result;
+ break;
+ }
+
+ pthread_condattr_destroy(&cond_condattr); // result can be ignored
+
+ m_object_initialized = true;
+ init_result = true;
+ }
+ while (false);
+
+ if (!init_result)
+ {
+ if (mutex_initialized)
+ {
+ if (condattr_initialized)
+ {
+ int condattr_destroy_result = pthread_condattr_destroy(&cond_condattr);
+ dICHECK(condattr_destroy_result == EOK || ((errno = condattr_destroy_result), false));
+ }
+
+ int mutex_destroy_result = pthread_mutex_destroy(&m_wakeup_mutex);
+ dICHECK(mutex_destroy_result == EOK || ((errno = mutex_destroy_result), false));
+ }
+ }
+
+ return init_result;
+
+}
+
+void dxCondvarWakeup::DoFinalizeObject()
+{
+ if (m_object_initialized)
+ {
+ int cond_result = pthread_cond_destroy(&m_wakeup_cond);
+ dICHECK(cond_result == EOK || ((errno = cond_result), false));
+
+ int mutex_result = pthread_mutex_destroy(&m_wakeup_mutex);
+ dICHECK(mutex_result == EOK || ((errno = mutex_result), false));
+
+ m_object_initialized = false;
+ }
+}
+
+
+void dxCondvarWakeup::ResetWakeup()
+{
+ int lock_result = pthread_mutex_lock(&m_wakeup_mutex);
+ dICHECK(lock_result == EOK || ((errno = lock_result), false));
+
+ m_signaled_state = false;
+ m_state_is_permanent = false;
+
+ int unlock_result = pthread_mutex_unlock(&m_wakeup_mutex);
+ dICHECK(unlock_result == EOK || ((errno = unlock_result), false));
+}
+
+void dxCondvarWakeup::WakeupAThread()
+{
+ int lock_result = pthread_mutex_lock(&m_wakeup_mutex);
+ dICHECK(lock_result == EOK || ((errno = lock_result), false));
+
+ dIASSERT(!m_state_is_permanent); // Wakeup should not be used after permanent signal
+
+ if (!m_signaled_state)
+ {
+ if (MarkSignaledFirstWaiter())
+ {
+ // All threads must be woken up regardless to the fact that only one waiter is marked.
+ // It is not possible to wake up a chosen thread personally
+ // and if a random thread is woken up it can't know if there was a condition signal for it
+ // or the sleep was interrupted by POSIX signal.
+ // On the other hand, without this it is not possible to guarantee that a thread
+ // will be woken up per each WakeupAThread() call if there is more than one waiter
+ // and wakeup requests will not accumulate if there are no waiters.
+ int broadcast_result = pthread_cond_broadcast(&m_wakeup_cond);
+ dICHECK(broadcast_result == EOK || ((errno = broadcast_result), false));
+ }
+ else
+ {
+ m_signaled_state = true;
+ }
+ }
+
+ int unlock_result = pthread_mutex_unlock(&m_wakeup_mutex);
+ dICHECK(unlock_result == EOK || ((errno = unlock_result), false));
+}
+
+void dxCondvarWakeup::WakeupAllThreads()
+{
+ int lock_result = pthread_mutex_lock(&m_wakeup_mutex);
+ dICHECK(lock_result == EOK || ((errno = lock_result), false));
+
+ m_state_is_permanent = true;
+
+ if (!m_signaled_state)
+ {
+ m_signaled_state = true;
+
+ if (MarkSignaledAllWaiters())
+ {
+ int broadcast_result = pthread_cond_broadcast(&m_wakeup_cond);
+ dICHECK(broadcast_result == EOK || ((errno = broadcast_result), false));
+ }
+ }
+
+ int unlock_result = pthread_mutex_unlock(&m_wakeup_mutex);
+ dICHECK(unlock_result == EOK || ((errno = unlock_result), false));
+}
+
+
+bool dxCondvarWakeup::WaitWakeup(const dThreadedWaitTime *timeout_time_ptr)
+{
+ bool wait_result;
+
+ int lock_result = pthread_mutex_lock(&m_wakeup_mutex);
+ dICHECK(lock_result == EOK || ((errno = lock_result), false));
+
+ if (!m_signaled_state)
+ {
+ if (!timeout_time_ptr || timeout_time_ptr->wait_nsec != 0 || timeout_time_ptr->wait_sec != 0)
+ {
+ wait_result = BlockAsAWaiter(timeout_time_ptr);
+ }
+ else
+ {
+ wait_result = false;
+ }
+ }
+ else
+ {
+ m_signaled_state = m_state_is_permanent;
+ wait_result = true;
+ }
+
+ int unlock_result = pthread_mutex_unlock(&m_wakeup_mutex);
+ dICHECK(unlock_result == EOK || ((errno = unlock_result), false));
+
+ return wait_result;
+}
+
+bool dxCondvarWakeup::BlockAsAWaiter(const dThreadedWaitTime *timeout_time_ptr)
+{
+ bool wait_result = false;
+
+ dxWaiterInfo waiter_info;
+ RegisterWaiterInList(&waiter_info);
+
+ timespec wakeup_time;
+
+ if (timeout_time_ptr != NULL)
+ {
+ timespec current_time;
+
+ int clock_result = _condvar_clock_gettime(CLOCK_MONOTONIC, ¤t_time);
+ dICHECK(clock_result != -1);
+
+ time_t wakeup_sec = current_time.tv_sec + timeout_time_ptr->wait_sec;
+ unsigned long wakeup_nsec = current_time.tv_nsec + timeout_time_ptr->wait_nsec;
+
+ if (wakeup_nsec >= 1000000000)
+ {
+ wakeup_nsec -= 1000000000;
+ wakeup_sec += 1;
+ }
+
+ wakeup_time.tv_sec = wakeup_sec;
+ wakeup_time.tv_nsec = wakeup_nsec;
+ }
+
+ while (true)
+ {
+ int cond_result = (timeout_time_ptr != NULL)
+ ? pthread_cond_timedwait(&m_wakeup_cond, &m_wakeup_mutex, &wakeup_time)
+ : pthread_cond_wait(&m_wakeup_cond, &m_wakeup_mutex);
+ dICHECK(cond_result == EOK || cond_result == ETIMEDOUT || ((errno = cond_result), false));
+
+ if (waiter_info.m_signal_state)
+ {
+ wait_result = true;
+ break;
+ }
+
+ if (cond_result == ETIMEDOUT)
+ {
+ dIASSERT(timeout_time_ptr != NULL);
+ break;
+ }
+ }
+
+ UnregisterWaiterFromList(&waiter_info);
+
+ return wait_result;
+}
+
+
+void dxCondvarWakeup::RegisterWaiterInList(dxWaiterInfo *waiter_info)
+{
+ dxWaiterInfo *const first_waiter = m_waiters_list;
+
+ if (first_waiter == NULL)
+ {
+ waiter_info->m_next_info = waiter_info;
+ waiter_info->m_prev_info_ptr = &waiter_info->m_next_info;
+ m_waiters_list = waiter_info;
+ }
+ else
+ {
+ waiter_info->m_next_info = first_waiter;
+ waiter_info->m_prev_info_ptr = first_waiter->m_prev_info_ptr;
+ *first_waiter->m_prev_info_ptr = waiter_info;
+ first_waiter->m_prev_info_ptr = &waiter_info->m_next_info;
+ }
+}
+
+void dxCondvarWakeup::UnregisterWaiterFromList(dxWaiterInfo *waiter_info)
+{
+ dxWaiterInfo *next_info = waiter_info->m_next_info;
+
+ if (next_info == waiter_info)
+ {
+ m_waiters_list = NULL;
+ }
+ else
+ {
+ next_info->m_prev_info_ptr = waiter_info->m_prev_info_ptr;
+ *waiter_info->m_prev_info_ptr = next_info;
+
+ if (waiter_info == m_waiters_list)
+ {
+ m_waiters_list = next_info;
+ }
+ }
+}
+
+
+bool dxCondvarWakeup::MarkSignaledFirstWaiter()
+{
+ bool waiter_found = false;
+
+ dxWaiterInfo *const first_waiter = m_waiters_list;
+
+ if (first_waiter)
+ {
+ waiter_found = MarkSignaledFirstWaiterMeaningful(first_waiter);
+ }
+
+ return waiter_found;
+}
+
+bool dxCondvarWakeup::MarkSignaledFirstWaiterMeaningful(dxWaiterInfo *first_waiter)
+{
+ bool waiter_found = false;
+
+ dxWaiterInfo *current_waiter = first_waiter;
+
+ while (true)
+ {
+ if (!current_waiter->m_signal_state)
+ {
+ current_waiter->m_signal_state = true;
+ waiter_found = true;
+ break;
+ }
+
+ current_waiter = current_waiter->m_next_info;
+ if (current_waiter == first_waiter)
+ {
+ break;
+ }
+ }
+
+ return waiter_found;
+}
+
+bool dxCondvarWakeup::MarkSignaledAllWaiters()
+{
+ bool waiter_found = false;
+
+ dxWaiterInfo *const first_waiter = m_waiters_list;
+
+ if (first_waiter)
+ {
+ waiter_found = MarkSignaledAllWaitersMeaningful(first_waiter);
+ }
+
+ return waiter_found;
+}
+
+bool dxCondvarWakeup::MarkSignaledAllWaitersMeaningful(dxWaiterInfo *first_waiter)
+{
+ bool waiter_found = false;
+
+ dxWaiterInfo *current_waiter = first_waiter;
+
+ while (true)
+ {
+ if (!current_waiter->m_signal_state)
+ {
+ current_waiter->m_signal_state = true;
+ waiter_found = true;
+ }
+
+ current_waiter = current_waiter->m_next_info;
+ if (current_waiter == first_waiter)
+ {
+ break;
+ }
+ }
+
+ return waiter_found;
+}
+
+
+/************************************************************************/
+/* dxMutexMutex class implementation */
+/************************************************************************/
+
+class dxMutexMutex
+{
+public:
+ dxMutexMutex(): m_mutex_allocated(false) {}
+ ~dxMutexMutex() { DoFinalizeObject(); }
+
+ bool InitializeObject() { return DoInitializeObject(); }
+
+private:
+ bool DoInitializeObject();
+ void DoFinalizeObject();
+
+public:
+ void LockMutex();
+ bool TryLockMutex();
+ void UnlockMutex();
+
+private:
+ pthread_mutex_t m_mutex_instance;
+ bool m_mutex_allocated;
+};
+
+
+bool dxMutexMutex::DoInitializeObject()
+{
+ dIASSERT(!m_mutex_allocated);
+
+ bool init_result = false;
+
+ do
+ {
+ int mutex_result = pthread_mutex_init(&m_mutex_instance, NULL);
+ if (mutex_result != EOK)
+ {
+ errno = mutex_result;
+ break;
+ }
+
+ m_mutex_allocated = true;
+ init_result = true;
+ }
+ while (false);
+
+ return init_result;
+}
+
+void dxMutexMutex::DoFinalizeObject()
+{
+ if (m_mutex_allocated)
+ {
+ int mutex_result = pthread_mutex_destroy(&m_mutex_instance);
+ dICHECK(mutex_result == EOK || ((errno = mutex_result), false));
+
+ m_mutex_allocated = false;
+ }
+}
+
+
+void dxMutexMutex::LockMutex()
+{
+ int lock_result = pthread_mutex_lock(&m_mutex_instance);
+ dICHECK(lock_result == EOK || ((errno = lock_result), false));
+}
+
+bool dxMutexMutex::TryLockMutex()
+{
+ int trylock_result = pthread_mutex_trylock(&m_mutex_instance);
+ dICHECK(trylock_result == EOK || trylock_result == EBUSY || ((errno = trylock_result), false));
+
+ return trylock_result == EOK;
+}
+
+void dxMutexMutex::UnlockMutex()
+{
+ int unlock_result = pthread_mutex_unlock(&m_mutex_instance);
+ dICHECK(unlock_result == EOK || ((errno = unlock_result), false));
+}
+
+
+#endif // #if dBUILTIN_THREADING_IMPL_ENABLED
+
+
+/************************************************************************/
+/* Self-threaded job list definition */
+/************************************************************************/
+
+typedef dxtemplateJobListContainer<dxFakeLull, dxFakeMutex, dxFakeAtomicsProvider> dxSelfThreadedJobListContainer;
+typedef dxtemplateJobListSelfHandler<dxSelfWakeup, dxSelfThreadedJobListContainer> dxSelfThreadedJobListHandler;
+typedef dxtemplateThreadingImplementation<dxSelfThreadedJobListContainer, dxSelfThreadedJobListHandler> dxSelfThreadedThreading;
+
+
+#if dBUILTIN_THREADING_IMPL_ENABLED
+
+/************************************************************************/
+/* Multi-threaded job list definition */
+/************************************************************************/
+
+typedef dxtemplateJobListContainer<dxtemplateThreadedLull<dxCondvarWakeup, dxOUAtomicsProvider, false>, dxMutexMutex, dxOUAtomicsProvider> dxMultiThreadedJobListContainer;
+typedef dxtemplateJobListThreadedHandler<dxCondvarWakeup, dxMultiThreadedJobListContainer> dxMultiThreadedJobListHandler;
+typedef dxtemplateThreadingImplementation<dxMultiThreadedJobListContainer, dxMultiThreadedJobListHandler> dxMultiThreadedThreading;
+
+
+#endif // #if dBUILTIN_THREADING_IMPL_ENABLED
+
+
+#endif // #if !defined(_WIN32)
+
+
+#endif // #ifndef _ODE_THREADING_IMPL_POSIX_H_
diff --git a/libs/ode-0.16.1/ode/src/threading_impl_templates.h b/libs/ode-0.16.1/ode/src/threading_impl_templates.h new file mode 100644 index 0000000..acecbc3 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/threading_impl_templates.h @@ -0,0 +1,1265 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * Threading implementation templates file. * + * Copyright (C) 2011-2019 Oleh Derevenko. All rights reserved. * + * e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * Job list and Mutex group implementation templates for built-in threading + * support provider. + */ + + +#ifndef _ODE_THREADING_IMPL_TEMPLATES_H_ +#define _ODE_THREADING_IMPL_TEMPLATES_H_ + + +#include <ode/common.h> +#include <ode/memory.h> + +#include <ode/threading.h> + +#include "objects.h" + +#include <new> + + +#define dMAKE_JOBINSTANCE_RELEASEE(job_instance) ((dCallReleaseeID)(job_instance)) +#define dMAKE_RELEASEE_JOBINSTANCE(releasee) ((dxThreadedJobInfo *)(releasee)) + + +template <class tThreadMutex> +class dxtemplateMutexGroup +{ +private: + dxtemplateMutexGroup() {} + ~dxtemplateMutexGroup() {} + +public: + static dxtemplateMutexGroup<tThreadMutex> *AllocateInstance(dmutexindex_t Mutex_count); + static void FreeInstance(dxtemplateMutexGroup<tThreadMutex> *mutex_group); + +private: + bool InitializeMutexArray(dmutexindex_t Mutex_count); + void FinalizeMutexArray(dmutexindex_t Mutex_count); + +public: + void LockMutex(dmutexindex_t mutex_index) { dIASSERT(mutex_index < m_un.m_mutex_count); m_Mutex_array[mutex_index].LockMutex(); } + bool TryLockMutex(dmutexindex_t mutex_index) { dIASSERT(mutex_index < m_un.m_mutex_count); return m_Mutex_array[mutex_index].TryLockMutex(); } + void UnlockMutex(dmutexindex_t mutex_index) { dIASSERT(mutex_index < m_un.m_mutex_count); m_Mutex_array[mutex_index].UnlockMutex(); } + +private: + union + { + dmutexindex_t m_mutex_count; + unsigned long m_reserved_for_allignment[2]; + + } m_un; + + tThreadMutex m_Mutex_array[1]; +}; + +template<class tThreadWakeup> +class dxtemplateCallWait: + public dBase +{ +public: + dxtemplateCallWait() {} + ~dxtemplateCallWait() { DoFinalizeObject(); } + + bool InitializeObject() { return DoInitializeObject(); } + +private: + bool DoInitializeObject() { return m_wait_wakeup.InitializeObject(); } + void DoFinalizeObject() { /* Do nothing */ } + +public: + typedef dxtemplateCallWait<tThreadWakeup> dxCallWait; + +public: + void ResetTheWait() { m_wait_wakeup.ResetWakeup(); } + void SignalTheWait() { m_wait_wakeup.WakeupAllThreads(); } + bool PerformWaiting(const dThreadedWaitTime *timeout_time_ptr/*=NULL*/) { return m_wait_wakeup.WaitWakeup(timeout_time_ptr); } + +public: + static void AbstractSignalTheWait(void *wait_wakeup_ptr) { ((dxCallWait *)wait_wakeup_ptr)->SignalTheWait(); } + +private: + tThreadWakeup m_wait_wakeup; +}; + + +#if dBUILTIN_THREADING_IMPL_ENABLED + +template<class tThreadWakeup, class tAtomicsProvider, const bool tatomic_test_required> +class dxtemplateThreadedLull +{ +public: + dxtemplateThreadedLull(): m_registrant_count(0), m_alarm_wakeup() {} + ~dxtemplateThreadedLull() { dIASSERT(m_registrant_count == 0); DoFinalizeObject(); } + + bool InitializeObject() { return DoInitializeObject(); } + +private: + bool DoInitializeObject() { return m_alarm_wakeup.InitializeObject(); } + void DoFinalizeObject() { /* Do nothing */ } + +private: + typedef typename tAtomicsProvider::atomicord_t atomicord_t; + +public: + void RegisterToLull() { tAtomicsProvider::IncrementTargetNoRet(&m_registrant_count); } + void WaitForLullAlarm() { dIASSERT(m_registrant_count != 0); m_alarm_wakeup.WaitWakeup(NULL); } + void UnregisterFromLull() { tAtomicsProvider::DecrementTargetNoRet(&m_registrant_count); } + + void SignalLullAlarmIfAnyRegistrants() + { + if (tatomic_test_required ? (tAtomicsProvider::QueryTargetValue(&m_registrant_count) != 0) : (m_registrant_count != 0)) + { + m_alarm_wakeup.WakeupAThread(); + } + } + +private: + atomicord_t m_registrant_count; + tThreadWakeup m_alarm_wakeup; +}; + + +#endif // #if dBUILTIN_THREADING_IMPL_ENABLED + + +struct dxThreadedJobInfo: + public dBase +{ + dxThreadedJobInfo() {} + explicit dxThreadedJobInfo(void *): m_next_job(NULL) {} + + void AssignJobData(ddependencycount_t dependencies_count, dxThreadedJobInfo *dependent_job, void *call_wait, + int *fault_accumulator_ptr, dThreadedCallFunction *call_function, void *call_context, dcallindex_t call_index) + { + m_dependencies_count = dependencies_count; + m_dependent_job = dependent_job; + m_call_wait = call_wait; + m_fault_accumulator_ptr = fault_accumulator_ptr; + + m_call_fault = 0; + m_call_function = call_function; + m_call_context = call_context; + m_call_index = call_index; + } + + bool InvokeCallFunction() + { + int call_result = m_call_function(m_call_context, m_call_index, dMAKE_JOBINSTANCE_RELEASEE(this)); + return call_result != 0; + } + + dxThreadedJobInfo *m_next_job; + dxThreadedJobInfo **m_prev_job_next_ptr; + + ddependencycount_t m_dependencies_count; + dxThreadedJobInfo *m_dependent_job; + void *m_call_wait; + int *m_fault_accumulator_ptr; + + int m_call_fault; + dThreadedCallFunction *m_call_function; + void *m_call_context; + dcallindex_t m_call_index; +}; + + +template<class tThreadMutex> +class dxtemplateThreadingLockHelper +{ +public: + dxtemplateThreadingLockHelper(tThreadMutex &mutex_instance): m_mutex_instance(mutex_instance), m_lock_indicator_flag(false) { LockMutex(); } + ~dxtemplateThreadingLockHelper() { if (m_lock_indicator_flag) { UnlockMutex(); } } + + void LockMutex() { dIASSERT(!m_lock_indicator_flag); m_mutex_instance.LockMutex(); m_lock_indicator_flag = true; } + void UnlockMutex() { dIASSERT(m_lock_indicator_flag); m_mutex_instance.UnlockMutex(); m_lock_indicator_flag = false; } + +private: + tThreadMutex &m_mutex_instance; + bool m_lock_indicator_flag; +}; + +template<class tThreadLull, class tThreadMutex, class tAtomicsProvider> +class dxtemplateJobListContainer +{ +public: + dxtemplateJobListContainer(): + m_job_list(NULL), + m_info_pool((atomicptr_t)NULL), + m_pool_access_lock(), + m_list_access_lock(), + m_info_wait_lull(), + m_info_count_known_to_be_preallocated(0) + { + } + + ~dxtemplateJobListContainer() + { + dIASSERT(m_job_list == NULL); // Would not it be nice to wait for jobs to complete before deleting the list? + + FreeJobInfoPoolInfos(); + DoFinalizeObject(); + } + + bool InitializeObject() { return DoInitializeObject(); } + +private: + bool DoInitializeObject() { return m_pool_access_lock.InitializeObject() && m_list_access_lock.InitializeObject() && m_info_wait_lull.InitializeObject(); } + void DoFinalizeObject() { /* Do nothing */ } + +public: + typedef tAtomicsProvider dxAtomicsProvider; + typedef typename tAtomicsProvider::atomicord_t atomicord_t; + typedef typename tAtomicsProvider::atomicptr_t atomicptr_t; + typedef tThreadMutex dxThreadMutex; + typedef dxtemplateThreadingLockHelper<tThreadMutex> dxMutexLockHelper; + typedef void dWaitSignallingFunction(void *job_call_wait); + +public: + dxThreadedJobInfo *ReleaseAJobAndPickNextPendingOne( + dxThreadedJobInfo *job_to_release, bool job_result, dWaitSignallingFunction *wait_signal_proc_ptr, + bool &out_last_job_flag); + +private: + dxThreadedJobInfo *PickNextPendingJob(bool &out_last_job_flag); + void ReleaseAJob(dxThreadedJobInfo *job_instance, bool job_result, dWaitSignallingFunction *wait_signal_proc_ptr); + +public: + inline dxThreadedJobInfo *AllocateJobInfoFromPool(); + void QueueJobForProcessing(dxThreadedJobInfo *job_instance); + + void AlterJobProcessingDependencies(dxThreadedJobInfo *job_instance, ddependencychange_t dependencies_count_change, + bool &out_job_has_become_ready); + +private: + inline ddependencycount_t SmartAddJobDependenciesCount(dxThreadedJobInfo *job_instance, ddependencychange_t dependencies_count_change); + + inline void InsertJobInfoIntoListHead(dxThreadedJobInfo *job_instance); + inline void RemoveJobInfoFromList(dxThreadedJobInfo *job_instance); + + dxThreadedJobInfo *ExtractJobInfoFromPoolOrAllocate(); + inline void ReleaseJobInfoIntoPool(dxThreadedJobInfo *job_instance); + +private: + void FreeJobInfoPoolInfos(); + +public: + bool EnsureNumberOfJobInfosIsPreallocated(ddependencycount_t required_info_count); + +private: + bool DoPreallocateJobInfos(ddependencycount_t required_info_count); + +public: + bool IsJobListReadyForShutdown() const { return m_job_list == NULL; } + +private: + dxThreadedJobInfo *m_job_list; + volatile atomicptr_t m_info_pool; // dxThreadedJobInfo * + tThreadMutex m_pool_access_lock; + tThreadMutex m_list_access_lock; + tThreadLull m_info_wait_lull; + ddependencycount_t m_info_count_known_to_be_preallocated; +}; + + +typedef void (dxThreadReadyToServeCallback)(void *callback_context); + + +#if dBUILTIN_THREADING_IMPL_ENABLED + +template<class tThreadWakeup, class tJobListContainer> +class dxtemplateJobListThreadedHandler +{ +public: + dxtemplateJobListThreadedHandler(tJobListContainer *list_container_ptr): + m_job_list_ptr(list_container_ptr), + m_processing_wakeup(), + m_active_thread_count(0), + m_shutdown_requested(0) + { + } + + ~dxtemplateJobListThreadedHandler() + { + dIASSERT(m_active_thread_count == 0); + + DoFinalizeObject(); + } + + bool InitializeObject() { return DoInitializeObject(); } + +private: + bool DoInitializeObject() { return m_processing_wakeup.InitializeObject(); } + void DoFinalizeObject() { /* Do nothing */ } + +public: + typedef dxtemplateCallWait<tThreadWakeup> dxCallWait; + +public: + inline void ProcessActiveJobAddition(); + inline void PrepareForWaitingAJobCompletion(); + +public: + inline unsigned RetrieveActiveThreadsCount(); + inline void StickToJobsProcessing(dxThreadReadyToServeCallback *readiness_callback/*=NULL*/, void *callback_context/*=NULL*/); + +private: + void PerformJobProcessingUntilShutdown(); + void PerformJobProcessingSession(); + + void BlockAsIdleThread(); + void ActivateAnIdleThread(); + +public: + inline void ShutdownProcessing(); + inline void CleanupForRestart(); + +private: + bool IsShutdownRequested() const { return m_shutdown_requested != 0; } + +private: + typedef typename tJobListContainer::dxAtomicsProvider dxAtomicsProvider; + typedef typename tJobListContainer::atomicord_t atomicord_t; + + atomicord_t GetActiveThreadsCount() const { return m_active_thread_count; } + void RegisterAsActiveThread() { dxAtomicsProvider::template AddValueToTarget<sizeof(atomicord_t)>((volatile void *)&m_active_thread_count, 1); } + void UnregisterAsActiveThread() { dxAtomicsProvider::template AddValueToTarget<sizeof(atomicord_t)>((volatile void *)&m_active_thread_count, -1); } + +private: + tJobListContainer *m_job_list_ptr; + tThreadWakeup m_processing_wakeup; + volatile atomicord_t m_active_thread_count; + int m_shutdown_requested; +}; + + +#endif // #if dBUILTIN_THREADING_IMPL_ENABLED + + +template<class tThreadWakeup, class tJobListContainer> +class dxtemplateJobListSelfHandler +{ +public: + dxtemplateJobListSelfHandler(tJobListContainer *list_container_ptr): + m_job_list_ptr(list_container_ptr) + { + } + + ~dxtemplateJobListSelfHandler() + { + // Do nothing + } + + bool InitializeObject() { return true; } + +public: + typedef dxtemplateCallWait<tThreadWakeup> dxCallWait; + +public: + inline void ProcessActiveJobAddition(); + inline void PrepareForWaitingAJobCompletion(); + +public: + inline unsigned RetrieveActiveThreadsCount(); + inline void StickToJobsProcessing(dxThreadReadyToServeCallback *readiness_callback/*=NULL*/, void *callback_context/*=NULL*/); + +private: + void PerformJobProcessingUntilExhaustion(); + void PerformJobProcessingSession(); + +public: + inline void ShutdownProcessing(); + inline void CleanupForRestart(); + +private: + tJobListContainer *m_job_list_ptr; +}; + + +struct dIMutexGroup; +struct dxICallWait; + +class dxIThreadingImplementation +{ +public: + virtual void FreeInstance() = 0; + +public: + virtual dIMutexGroup *AllocMutexGroup(dmutexindex_t Mutex_count) = 0; + virtual void FreeMutexGroup(dIMutexGroup *mutex_group) = 0; + virtual void LockMutexGroupMutex(dIMutexGroup *mutex_group, dmutexindex_t mutex_index) = 0; + // virtual bool TryLockMutexGroupMutex(dIMutexGroup *mutex_group, dmutexindex_t mutex_index) = 0; + virtual void UnlockMutexGroupMutex(dIMutexGroup *mutex_group, dmutexindex_t mutex_index) = 0; + +public: + virtual dxICallWait *AllocACallWait() = 0; + virtual void ResetACallWait(dxICallWait *call_wait) = 0; + virtual void FreeACallWait(dxICallWait *call_wait) = 0; + +public: + virtual bool PreallocateJobInfos(ddependencycount_t max_simultaneous_calls_estimate) = 0; + virtual void ScheduleNewJob(int *fault_accumulator_ptr/*=NULL*/, + dCallReleaseeID *out_post_releasee_ptr/*=NULL*/, ddependencycount_t dependencies_count, dCallReleaseeID dependent_releasee/*=NULL*/, + dxICallWait *call_wait/*=NULL*/, + dThreadedCallFunction *call_func, void *call_context, dcallindex_t instance_index) = 0; + virtual void AlterJobDependenciesCount(dCallReleaseeID target_releasee, ddependencychange_t dependencies_count_change) = 0; + virtual void WaitJobCompletion(int *out_wait_status_ptr/*=NULL*/, + dxICallWait *call_wait, const dThreadedWaitTime *timeout_time_ptr/*=NULL*/) = 0; + +public: + virtual unsigned RetrieveActiveThreadsCount() = 0; + virtual void StickToJobsProcessing(dxThreadReadyToServeCallback *readiness_callback/*=NULL*/, void *callback_context/*=NULL*/) = 0; + virtual void ShutdownProcessing() = 0; + virtual void CleanupForRestart() = 0; +}; + + +template<class tJobListContainer, class tJobListHandler> +class dxtemplateThreadingImplementation: + public dBase, + public dxIThreadingImplementation +{ +public: + dxtemplateThreadingImplementation(): + dBase(), + m_list_container(), + m_list_handler(&m_list_container) + { + } + + virtual ~dxtemplateThreadingImplementation() + { + DoFinalizeObject(); + } + + bool InitializeObject() { return DoInitializeObject(); } + +private: + bool DoInitializeObject() { return m_list_container.InitializeObject() && m_list_handler.InitializeObject(); } + void DoFinalizeObject() { /* Do nothing */ } + +protected: + virtual void FreeInstance(); + +private: + typedef dxtemplateMutexGroup<typename tJobListContainer::dxThreadMutex> dxMutexGroup; + typedef typename tJobListHandler::dxCallWait dxCallWait; + +protected: + virtual dIMutexGroup *AllocMutexGroup(dmutexindex_t Mutex_count); + virtual void FreeMutexGroup(dIMutexGroup *mutex_group); + virtual void LockMutexGroupMutex(dIMutexGroup *mutex_group, dmutexindex_t mutex_index); + // virtual bool TryLockMutexGroupMutex(dIMutexGroup *mutex_group, dmutexindex_t mutex_index); + virtual void UnlockMutexGroupMutex(dIMutexGroup *mutex_group, dmutexindex_t mutex_index); + +protected: + virtual dxICallWait *AllocACallWait(); + virtual void ResetACallWait(dxICallWait *call_wait); + virtual void FreeACallWait(dxICallWait *call_wait); + +protected: + virtual bool PreallocateJobInfos(ddependencycount_t max_simultaneous_calls_estimate); + virtual void ScheduleNewJob(int *fault_accumulator_ptr/*=NULL*/, + dCallReleaseeID *out_post_releasee_ptr/*=NULL*/, ddependencycount_t dependencies_count, dCallReleaseeID dependent_releasee/*=NULL*/, + dxICallWait *call_wait/*=NULL*/, + dThreadedCallFunction *call_func, void *call_context, dcallindex_t instance_index); + virtual void AlterJobDependenciesCount(dCallReleaseeID target_releasee, ddependencychange_t dependencies_count_change); + virtual void WaitJobCompletion(int *out_wait_status_ptr/*=NULL*/, + dxICallWait *call_wait, const dThreadedWaitTime *timeout_time_ptr/*=NULL*/); + +protected: + virtual unsigned RetrieveActiveThreadsCount(); + virtual void StickToJobsProcessing(dxThreadReadyToServeCallback *readiness_callback/*=NULL*/, void *callback_context/*=NULL*/); + virtual void ShutdownProcessing(); + virtual void CleanupForRestart(); + +private: + tJobListContainer m_list_container; + tJobListHandler m_list_handler; +}; + + +/************************************************************************/ +/* Implementation of dxtemplateMutexGroup */ +/************************************************************************/ + +template<class tThreadMutex> +/*static */dxtemplateMutexGroup<tThreadMutex> *dxtemplateMutexGroup<tThreadMutex>::AllocateInstance(dmutexindex_t Mutex_count) +{ + dAASSERT(Mutex_count != 0); + + const dxtemplateMutexGroup<tThreadMutex> *const dummy_group = (dxtemplateMutexGroup<tThreadMutex> *)(sizeint)8; + const sizeint size_requited = ((sizeint)(&dummy_group->m_Mutex_array) - (sizeint)dummy_group) + Mutex_count * sizeof(tThreadMutex); + dxtemplateMutexGroup<tThreadMutex> *mutex_group = (dxtemplateMutexGroup<tThreadMutex> *)dAlloc(size_requited); + + if (mutex_group != NULL) + { + mutex_group->m_un.m_mutex_count = Mutex_count; + + if (!mutex_group->InitializeMutexArray(Mutex_count)) + { + dFree((void *)mutex_group, size_requited); + mutex_group = NULL; + } + } + + return mutex_group; +} + +template<class tThreadMutex> +/*static */void dxtemplateMutexGroup<tThreadMutex>::FreeInstance(dxtemplateMutexGroup<tThreadMutex> *mutex_group) +{ + if (mutex_group != NULL) + { + dmutexindex_t Mutex_count = mutex_group->m_un.m_mutex_count; + mutex_group->FinalizeMutexArray(Mutex_count); + + const sizeint anyting_not_zero = 2 * sizeof(sizeint); + const dxtemplateMutexGroup<tThreadMutex> *const dummy_group = (dxtemplateMutexGroup<tThreadMutex> *)anyting_not_zero; + const sizeint size_requited = ((sizeint)(&dummy_group->m_Mutex_array) - (sizeint)dummy_group) + Mutex_count * sizeof(tThreadMutex); + dFree((void *)mutex_group, size_requited); + } +} + +template<class tThreadMutex> +bool dxtemplateMutexGroup<tThreadMutex>::InitializeMutexArray(dmutexindex_t Mutex_count) +{ + bool any_fault = false; + + dmutexindex_t mutex_index = 0; + for (; mutex_index != Mutex_count; ++mutex_index) + { + tThreadMutex *mutex_storage = m_Mutex_array + mutex_index; + + new(mutex_storage) tThreadMutex; + + if (!mutex_storage->InitializeObject()) + { + mutex_storage->tThreadMutex::~tThreadMutex(); + + any_fault = true; + break; + } + } + + if (any_fault) + { + FinalizeMutexArray(mutex_index); + } + + bool init_result = !any_fault; + return init_result; +} + +template<class tThreadMutex> +void dxtemplateMutexGroup<tThreadMutex>::FinalizeMutexArray(dmutexindex_t Mutex_count) +{ + for (dmutexindex_t mutex_index = 0; mutex_index != Mutex_count; ++mutex_index) + { + tThreadMutex *mutex_storage = m_Mutex_array + mutex_index; + + mutex_storage->tThreadMutex::~tThreadMutex(); + } +} + +/************************************************************************/ +/* Implementation of dxtemplateJobListContainer */ +/************************************************************************/ + +template<class tThreadLull, class tThreadMutex, class tAtomicsProvider> +dxThreadedJobInfo *dxtemplateJobListContainer<tThreadLull, tThreadMutex, tAtomicsProvider>::ReleaseAJobAndPickNextPendingOne( + dxThreadedJobInfo *job_to_release, bool job_result, dWaitSignallingFunction *wait_signal_proc_ptr, bool &out_last_job_flag) +{ + if (job_to_release != NULL) + { + ReleaseAJob(job_to_release, job_result, wait_signal_proc_ptr); + } + + dxMutexLockHelper list_access(m_list_access_lock); + + dxThreadedJobInfo *picked_job = PickNextPendingJob(out_last_job_flag); + return picked_job; +} + +template<class tThreadLull, class tThreadMutex, class tAtomicsProvider> +dxThreadedJobInfo *dxtemplateJobListContainer<tThreadLull, tThreadMutex, tAtomicsProvider>::PickNextPendingJob( + bool &out_last_job_flag) +{ + dxThreadedJobInfo *current_job = m_job_list; + bool last_job_flag = false; + + while (current_job != NULL) + { + if (current_job->m_dependencies_count == 0) + { + // It is OK to assign in unsafe manner - dependencies count should not be changed + // after the job has become ready for execution + current_job->m_dependencies_count = 1; + last_job_flag = current_job->m_next_job == NULL; + + RemoveJobInfoFromList(current_job); + break; + } + + current_job = current_job->m_next_job; + } + + out_last_job_flag = last_job_flag; + return current_job; +} + +template<class tThreadLull, class tThreadMutex, class tAtomicsProvider> +void dxtemplateJobListContainer<tThreadLull, tThreadMutex, tAtomicsProvider>::ReleaseAJob( + dxThreadedJobInfo *job_instance, bool job_result, dWaitSignallingFunction *wait_signal_proc_ptr) +{ + dxThreadedJobInfo *current_job = job_instance; + + if (!job_result) + { + // Accumulate call fault (be careful to not reset it!!!) + current_job->m_call_fault = 1; + } + + bool job_dequeued = true; + dIASSERT(current_job->m_prev_job_next_ptr == NULL); + + while (true) + { + dIASSERT(current_job->m_dependencies_count != 0); + + ddependencycount_t new_dependencies_count = SmartAddJobDependenciesCount(current_job, -1); + + if (new_dependencies_count != 0 || !job_dequeued) + { + break; + } + + void *job_call_wait = current_job->m_call_wait; + + if (job_call_wait != NULL) + { + wait_signal_proc_ptr(job_call_wait); + } + + int call_fault = current_job->m_call_fault; + + if (current_job->m_fault_accumulator_ptr) + { + *current_job->m_fault_accumulator_ptr = call_fault; + } + + dxThreadedJobInfo *dependent_job = current_job->m_dependent_job; + ReleaseJobInfoIntoPool(current_job); + + if (dependent_job == NULL) + { + break; + } + + if (call_fault) + { + // Accumulate call fault (be careful to not reset it!!!) + dependent_job->m_call_fault = 1; + } + + current_job = dependent_job; + job_dequeued = dependent_job->m_prev_job_next_ptr == NULL; + } +} + +template<class tThreadLull, class tThreadMutex, class tAtomicsProvider> +dxThreadedJobInfo *dxtemplateJobListContainer<tThreadLull, tThreadMutex, tAtomicsProvider>::AllocateJobInfoFromPool() +{ + // No locking is necessary + dxThreadedJobInfo *job_instance = ExtractJobInfoFromPoolOrAllocate(); + return job_instance; +} + +template<class tThreadLull, class tThreadMutex, class tAtomicsProvider> +void dxtemplateJobListContainer<tThreadLull, tThreadMutex, tAtomicsProvider>::QueueJobForProcessing(dxThreadedJobInfo *job_instance) +{ + dxMutexLockHelper list_access(m_list_access_lock); + + InsertJobInfoIntoListHead(job_instance); +} + + +template<class tThreadLull, class tThreadMutex, class tAtomicsProvider> +void dxtemplateJobListContainer<tThreadLull, tThreadMutex, tAtomicsProvider>::AlterJobProcessingDependencies(dxThreadedJobInfo *job_instance, ddependencychange_t dependencies_count_change, + bool &out_job_has_become_ready) +{ + // Dependencies should not be changed when job has already become ready for execution + dIASSERT(job_instance->m_dependencies_count != 0); + // It's OK that access is not atomic - that is to be handled by external logic + dIASSERT(dependencies_count_change < 0 ? (job_instance->m_dependencies_count >= (ddependencycount_t)(-dependencies_count_change)) : ((ddependencycount_t)(-(ddependencychange_t)job_instance->m_dependencies_count) > (ddependencycount_t)dependencies_count_change)); + + ddependencycount_t new_dependencies_count = SmartAddJobDependenciesCount(job_instance, dependencies_count_change); + out_job_has_become_ready = new_dependencies_count == 0; +} + + +template<class tThreadLull, class tThreadMutex, class tAtomicsProvider> +ddependencycount_t dxtemplateJobListContainer<tThreadLull, tThreadMutex, tAtomicsProvider>::SmartAddJobDependenciesCount( + dxThreadedJobInfo *job_instance, ddependencychange_t dependencies_count_change) +{ + ddependencycount_t new_dependencies_count = tAtomicsProvider::template AddValueToTarget<sizeof(ddependencycount_t)>((volatile void *)&job_instance->m_dependencies_count, dependencies_count_change) + dependencies_count_change; + return new_dependencies_count; +} + + +template<class tThreadLull, class tThreadMutex, class tAtomicsProvider> +void dxtemplateJobListContainer<tThreadLull, tThreadMutex, tAtomicsProvider>::InsertJobInfoIntoListHead( + dxThreadedJobInfo *job_instance) +{ + dxThreadedJobInfo *job_list_head = m_job_list; + job_instance->m_next_job = job_list_head; + + if (job_list_head != NULL) + { + job_list_head->m_prev_job_next_ptr = &job_instance->m_next_job; + } + + job_instance->m_prev_job_next_ptr = &m_job_list; + m_job_list = job_instance; +} + +template<class tThreadLull, class tThreadMutex, class tAtomicsProvider> +void dxtemplateJobListContainer<tThreadLull, tThreadMutex, tAtomicsProvider>::RemoveJobInfoFromList( + dxThreadedJobInfo *job_instance) +{ + if (job_instance->m_next_job) + { + job_instance->m_next_job->m_prev_job_next_ptr = job_instance->m_prev_job_next_ptr; + } + + *job_instance->m_prev_job_next_ptr = job_instance->m_next_job; + // Assign NULL to m_prev_job_next_ptr as an indicator that instance has been dequeued + job_instance->m_prev_job_next_ptr = NULL; +} + +template<class tThreadLull, class tThreadMutex, class tAtomicsProvider> +dxThreadedJobInfo *dxtemplateJobListContainer<tThreadLull, tThreadMutex, tAtomicsProvider>::ExtractJobInfoFromPoolOrAllocate() +{ + dxThreadedJobInfo *result_info; + + bool waited_lull = false; + m_info_wait_lull.RegisterToLull(); + + while (true) + { + dxThreadedJobInfo *raw_head_info = (dxThreadedJobInfo *)m_info_pool; + + if (raw_head_info == NULL) + { + result_info = new dxThreadedJobInfo(); + + if (result_info != NULL) + { + break; + } + + m_info_wait_lull.WaitForLullAlarm(); + waited_lull = true; + } + + // Extraction must be locked so that other thread does not "steal" head info, + // use it and then reinsert back with a different "next" + dxMutexLockHelper pool_access(m_pool_access_lock); + + dxThreadedJobInfo *head_info = (dxThreadedJobInfo *)m_info_pool; // Head info must be re-read after mutex had been locked + + if (head_info != NULL) + { + dxThreadedJobInfo *next_info = head_info->m_next_job; + if (tAtomicsProvider::CompareExchangeTargetPtr(&m_info_pool, (atomicptr_t)head_info, (atomicptr_t)next_info)) + { + result_info = head_info; + break; + } + } + } + + m_info_wait_lull.UnregisterFromLull(); + + if (waited_lull) + { + // It is necessary to re-signal lull alarm if current thread was waiting as + // there might be other threads waiting which might have not received alarm signal. + m_info_wait_lull.SignalLullAlarmIfAnyRegistrants(); + } + + return result_info; +} + +template<class tThreadLull, class tThreadMutex, class tAtomicsProvider> +void dxtemplateJobListContainer<tThreadLull, tThreadMutex, tAtomicsProvider>::ReleaseJobInfoIntoPool( + dxThreadedJobInfo *job_instance) +{ + while (true) + { + dxThreadedJobInfo *next_info = (dxThreadedJobInfo *)m_info_pool; + job_instance->m_next_job = next_info; + + if (tAtomicsProvider::CompareExchangeTargetPtr(&m_info_pool, (atomicptr_t)next_info, (atomicptr_t)job_instance)) + { + break; + } + } + + m_info_wait_lull.SignalLullAlarmIfAnyRegistrants(); +} + +template<class tThreadLull, class tThreadMutex, class tAtomicsProvider> +void dxtemplateJobListContainer<tThreadLull, tThreadMutex, tAtomicsProvider>::FreeJobInfoPoolInfos() +{ + dxThreadedJobInfo *current_info = (dxThreadedJobInfo *)m_info_pool; + + while (current_info != NULL) + { + dxThreadedJobInfo *info_save = current_info; + current_info = current_info->m_next_job; + + delete info_save; + } + + m_info_pool = (atomicptr_t)NULL; +} + +template<class tThreadLull, class tThreadMutex, class tAtomicsProvider> +bool dxtemplateJobListContainer<tThreadLull, tThreadMutex, tAtomicsProvider>::EnsureNumberOfJobInfosIsPreallocated(ddependencycount_t required_info_count) +{ + bool result = required_info_count <= m_info_count_known_to_be_preallocated + || DoPreallocateJobInfos(required_info_count); + return result; +} + +template<class tThreadLull, class tThreadMutex, class tAtomicsProvider> +bool dxtemplateJobListContainer<tThreadLull, tThreadMutex, tAtomicsProvider>::DoPreallocateJobInfos(ddependencycount_t required_info_count) +{ + dIASSERT(required_info_count > m_info_count_known_to_be_preallocated); // Also ensures required_info_count > 0 + + bool allocation_failure = false; + + dxThreadedJobInfo *info_pool = (dxThreadedJobInfo *)m_info_pool; + + ddependencycount_t info_index = 0; + for (dxThreadedJobInfo **current_info_ptr = &info_pool; ; ) + { + dxThreadedJobInfo *current_info = *current_info_ptr; + + if (current_info == NULL) + { + current_info = new dxThreadedJobInfo(NULL); + + if (current_info == NULL) + { + allocation_failure = true; + break; + } + + *current_info_ptr = current_info; + } + + if (++info_index == required_info_count) + { + m_info_count_known_to_be_preallocated = info_index; + break; + } + + current_info_ptr = ¤t_info->m_next_job; + } + + // Make sure m_info_pool was not changed + dIASSERT(m_info_pool == NULL || m_info_pool == (atomicptr_t)info_pool); + + m_info_pool = (atomicptr_t)info_pool; + + bool result = !allocation_failure; + return result; +} + + +#if dBUILTIN_THREADING_IMPL_ENABLED + +/************************************************************************/ +/* Implementation of dxtemplateJobListThreadedHandler */ +/************************************************************************/ + +template<class tThreadWakeup, class tJobListContainer> +void dxtemplateJobListThreadedHandler<tThreadWakeup, tJobListContainer>::ProcessActiveJobAddition() +{ + ActivateAnIdleThread(); +} + +template<class tThreadWakeup, class tJobListContainer> +void dxtemplateJobListThreadedHandler<tThreadWakeup, tJobListContainer>::PrepareForWaitingAJobCompletion() +{ + // Do nothing +} + +template<class tThreadWakeup, class tJobListContainer> +unsigned dxtemplateJobListThreadedHandler<tThreadWakeup, tJobListContainer>::RetrieveActiveThreadsCount() +{ + return GetActiveThreadsCount(); +} + +template<class tThreadWakeup, class tJobListContainer> +void dxtemplateJobListThreadedHandler<tThreadWakeup, tJobListContainer>::StickToJobsProcessing(dxThreadReadyToServeCallback *readiness_callback/*=NULL*/, void *callback_context/*=NULL*/) +{ + RegisterAsActiveThread(); + + if (readiness_callback != NULL) + { + (*readiness_callback)(callback_context); + } + + PerformJobProcessingUntilShutdown(); + + UnregisterAsActiveThread(); +} + + +template<class tThreadWakeup, class tJobListContainer> +void dxtemplateJobListThreadedHandler<tThreadWakeup, tJobListContainer>::PerformJobProcessingUntilShutdown() +{ + while (true) + { + // It is expected that new jobs will not be queued any longer after shutdown had been requested + if (IsShutdownRequested() && m_job_list_ptr->IsJobListReadyForShutdown()) + { + break; + } + + PerformJobProcessingSession(); + + // It is expected that new jobs will not be queued any longer after shutdown had been requested + if (IsShutdownRequested() && m_job_list_ptr->IsJobListReadyForShutdown()) + { + break; + } + + BlockAsIdleThread(); + } +} + +template<class tThreadWakeup, class tJobListContainer> +void dxtemplateJobListThreadedHandler<tThreadWakeup, tJobListContainer>::PerformJobProcessingSession() +{ + dxThreadedJobInfo *current_job = NULL; + bool job_result = false; + + while (true) + { + bool last_job_flag; + current_job = m_job_list_ptr->ReleaseAJobAndPickNextPendingOne(current_job, job_result, &dxCallWait::AbstractSignalTheWait, last_job_flag); + + if (!current_job) + { + break; + } + + if (!last_job_flag) + { + ActivateAnIdleThread(); + } + + job_result = current_job->InvokeCallFunction(); + } +} + + +template<class tThreadWakeup, class tJobListContainer> +void dxtemplateJobListThreadedHandler<tThreadWakeup, tJobListContainer>::BlockAsIdleThread() +{ + m_processing_wakeup.WaitWakeup(NULL); +} + +template<class tThreadWakeup, class tJobListContainer> +void dxtemplateJobListThreadedHandler<tThreadWakeup, tJobListContainer>::ActivateAnIdleThread() +{ + m_processing_wakeup.WakeupAThread(); +} + + +template<class tThreadWakeup, class tJobListContainer> +void dxtemplateJobListThreadedHandler<tThreadWakeup, tJobListContainer>::ShutdownProcessing() +{ + m_shutdown_requested = true; + m_processing_wakeup.WakeupAllThreads(); +} + +template<class tThreadWakeup, class tJobListContainer> +void dxtemplateJobListThreadedHandler<tThreadWakeup, tJobListContainer>::CleanupForRestart() +{ + m_shutdown_requested = false; + m_processing_wakeup.ResetWakeup(); +} + + +#endif // #if dBUILTIN_THREADING_IMPL_ENABLED + + +/************************************************************************/ +/* Implementation of dxtemplateJobListSelfHandler */ +/************************************************************************/ + +template<class tThreadWakeup, class tJobListContainer> +void dxtemplateJobListSelfHandler<tThreadWakeup, tJobListContainer>::ProcessActiveJobAddition() +{ + // Do nothing +} + +template<class tThreadWakeup, class tJobListContainer> +void dxtemplateJobListSelfHandler<tThreadWakeup, tJobListContainer>::PrepareForWaitingAJobCompletion() +{ + PerformJobProcessingUntilExhaustion(); +} + + +template<class tThreadWakeup, class tJobListContainer> +unsigned dxtemplateJobListSelfHandler<tThreadWakeup, tJobListContainer>::RetrieveActiveThreadsCount() +{ + return 0U; // Return zero to indicate that there are no actual active threads provided. +} + +template<class tThreadWakeup, class tJobListContainer> +void dxtemplateJobListSelfHandler<tThreadWakeup, tJobListContainer>::StickToJobsProcessing(dxThreadReadyToServeCallback *readiness_callback/*=NULL*/, void *callback_context/*=NULL*/) +{ + (void)readiness_callback; // unused + (void)callback_context; // unused + dIASSERT(false); // This method is not expected to be called for Self-Handler +} + + +template<class tThreadWakeup, class tJobListContainer> +void dxtemplateJobListSelfHandler<tThreadWakeup, tJobListContainer>::PerformJobProcessingUntilExhaustion() +{ + PerformJobProcessingSession(); +} + +template<class tThreadWakeup, class tJobListContainer> +void dxtemplateJobListSelfHandler<tThreadWakeup, tJobListContainer>::PerformJobProcessingSession() +{ + dxThreadedJobInfo *current_job = NULL; + bool job_result = false; + + while (true) + { + bool dummy_last_job_flag; + current_job = m_job_list_ptr->ReleaseAJobAndPickNextPendingOne(current_job, job_result, &dxCallWait::AbstractSignalTheWait, dummy_last_job_flag); + + if (!current_job) + { + break; + } + + job_result = current_job->InvokeCallFunction(); + } +} + +template<class tThreadWakeup, class tJobListContainer> +void dxtemplateJobListSelfHandler<tThreadWakeup, tJobListContainer>::ShutdownProcessing() +{ + // Do nothing +} + +template<class tThreadWakeup, class tJobListContainer> +void dxtemplateJobListSelfHandler<tThreadWakeup, tJobListContainer>::CleanupForRestart() +{ + // Do nothing +} + + +/************************************************************************/ +/* Implementation of dxtemplateThreadingImplementation */ +/************************************************************************/ + +template<class tJobListContainer, class tJobListHandler> +void dxtemplateThreadingImplementation<tJobListContainer, tJobListHandler>::FreeInstance() +{ + delete this; +} + + +template<class tJobListContainer, class tJobListHandler> +dIMutexGroup *dxtemplateThreadingImplementation<tJobListContainer, tJobListHandler>::AllocMutexGroup(dmutexindex_t Mutex_count) +{ + dxMutexGroup *mutex_group = dxMutexGroup::AllocateInstance(Mutex_count); + return (dIMutexGroup *)mutex_group; +} + +template<class tJobListContainer, class tJobListHandler> +void dxtemplateThreadingImplementation<tJobListContainer, tJobListHandler>::FreeMutexGroup(dIMutexGroup *mutex_group) +{ + dxMutexGroup::FreeInstance((dxMutexGroup *)mutex_group); +} + +template<class tJobListContainer, class tJobListHandler> +void dxtemplateThreadingImplementation<tJobListContainer, tJobListHandler>::LockMutexGroupMutex(dIMutexGroup *mutex_group, dmutexindex_t mutex_index) +{ + ((dxMutexGroup *)mutex_group)->LockMutex(mutex_index); +} + +// template<class tJobListContainer, class tJobListHandler> +// bool dxtemplateThreadingImplementation<tJobListContainer, tJobListHandler>::TryLockMutexGroupMutex(dIMutexGroup *mutex_group, dmutexindex_t mutex_index) +// { +// return ((dxMutexGroup *)mutex_group)->TryLockMutex(mutex_index); +// } + +template<class tJobListContainer, class tJobListHandler> +void dxtemplateThreadingImplementation<tJobListContainer, tJobListHandler>::UnlockMutexGroupMutex(dIMutexGroup *mutex_group, dmutexindex_t mutex_index) +{ + ((dxMutexGroup *)mutex_group)->UnlockMutex(mutex_index); +} + + +template<class tJobListContainer, class tJobListHandler> +dxICallWait *dxtemplateThreadingImplementation<tJobListContainer, tJobListHandler>::AllocACallWait() +{ + dxCallWait *call_wait = new dxCallWait(); + + if (call_wait != NULL && !call_wait->InitializeObject()) + { + delete call_wait; + call_wait = NULL; + } + + return (dxICallWait *)call_wait; +} + +template<class tJobListContainer, class tJobListHandler> +void dxtemplateThreadingImplementation<tJobListContainer, tJobListHandler>::ResetACallWait(dxICallWait *call_wait) +{ + ((dxCallWait *)call_wait)->ResetTheWait(); +} + +template<class tJobListContainer, class tJobListHandler> +void dxtemplateThreadingImplementation<tJobListContainer, tJobListHandler>::FreeACallWait(dxICallWait *call_wait) +{ + delete ((dxCallWait *)call_wait); +} + + +template<class tJobListContainer, class tJobListHandler> +bool dxtemplateThreadingImplementation<tJobListContainer, tJobListHandler>::PreallocateJobInfos(ddependencycount_t max_simultaneous_calls_estimate) +{ + // No multithreading protection here! + // Resources are to be preallocated before jobs start to be scheduled + // as otherwise there is no way to implement the preallocation. + bool result = m_list_container.EnsureNumberOfJobInfosIsPreallocated(max_simultaneous_calls_estimate); + return result; +} + +template<class tJobListContainer, class tJobListHandler> +void dxtemplateThreadingImplementation<tJobListContainer, tJobListHandler>::ScheduleNewJob( + int *fault_accumulator_ptr/*=NULL*/, + dCallReleaseeID *out_post_releasee_ptr/*=NULL*/, ddependencycount_t dependencies_count, dCallReleaseeID dependent_releasee/*=NULL*/, + dxICallWait *call_wait/*=NULL*/, + dThreadedCallFunction *call_func, void *call_context, dcallindex_t instance_index) +{ + dxThreadedJobInfo *new_job = m_list_container.AllocateJobInfoFromPool(); + dIASSERT(new_job != NULL); + + new_job->AssignJobData(dependencies_count, dMAKE_RELEASEE_JOBINSTANCE(dependent_releasee), (dxCallWait *)call_wait, fault_accumulator_ptr, call_func, call_context, instance_index); + + if (out_post_releasee_ptr != NULL) + { + *out_post_releasee_ptr = dMAKE_JOBINSTANCE_RELEASEE(new_job); + } + + m_list_container.QueueJobForProcessing(new_job); + + if (dependencies_count == 0) + { + m_list_handler.ProcessActiveJobAddition(); + } +} + +template<class tJobListContainer, class tJobListHandler> +void dxtemplateThreadingImplementation<tJobListContainer, tJobListHandler>::AlterJobDependenciesCount( + dCallReleaseeID target_releasee, ddependencychange_t dependencies_count_change) +{ + dIASSERT(dependencies_count_change != 0); + + dxThreadedJobInfo *job_instance = dMAKE_RELEASEE_JOBINSTANCE(target_releasee); + + bool job_has_become_ready; + m_list_container.AlterJobProcessingDependencies(job_instance, dependencies_count_change, job_has_become_ready); + + if (job_has_become_ready) + { + m_list_handler.ProcessActiveJobAddition(); + } +} + +template<class tJobListContainer, class tJobListHandler> +void dxtemplateThreadingImplementation<tJobListContainer, tJobListHandler>::WaitJobCompletion( + int *out_wait_status_ptr/*=NULL*/, + dxICallWait *call_wait, const dThreadedWaitTime *timeout_time_ptr/*=NULL*/) +{ + dIASSERT(call_wait != NULL); + + m_list_handler.PrepareForWaitingAJobCompletion(); + + bool wait_status = ((dxCallWait *)call_wait)->PerformWaiting(timeout_time_ptr); + dIASSERT(timeout_time_ptr != NULL || wait_status); + + if (out_wait_status_ptr) + { + *out_wait_status_ptr = wait_status; + } +} + + +template<class tJobListContainer, class tJobListHandler> +unsigned dxtemplateThreadingImplementation<tJobListContainer, tJobListHandler>::RetrieveActiveThreadsCount() +{ + return m_list_handler.RetrieveActiveThreadsCount(); +} + +template<class tJobListContainer, class tJobListHandler> +void dxtemplateThreadingImplementation<tJobListContainer, tJobListHandler>::StickToJobsProcessing(dxThreadReadyToServeCallback *readiness_callback/*=NULL*/, void *callback_context/*=NULL*/) +{ + m_list_handler.StickToJobsProcessing(readiness_callback, callback_context); +} + +template<class tJobListContainer, class tJobListHandler> +void dxtemplateThreadingImplementation<tJobListContainer, tJobListHandler>::ShutdownProcessing() +{ + m_list_handler.ShutdownProcessing(); +} + +template<class tJobListContainer, class tJobListHandler> +void dxtemplateThreadingImplementation<tJobListContainer, tJobListHandler>::CleanupForRestart() +{ + m_list_handler.CleanupForRestart(); +} + + +#endif // #ifndef _ODE_THREADING_IMPL_TEMPLATES_H_ diff --git a/libs/ode-0.16.1/ode/src/threading_impl_win.h b/libs/ode-0.16.1/ode/src/threading_impl_win.h new file mode 100644 index 0000000..f3cb489 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/threading_impl_win.h @@ -0,0 +1,273 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * Threading Windows implementation file. * + * Copyright (C) 2011-2019 Oleh Derevenko. All rights reserved. * + * e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * Threading Windows implementation for built-in threading support provider. + */ + + +#ifndef _ODE_THREADING_IMPL_WIN_H_ +#define _ODE_THREADING_IMPL_WIN_H_ + + +#include <ode/common.h> + + +#if defined(_WIN32) + +#if dBUILTIN_THREADING_IMPL_ENABLED + +#if !defined(_WIN32_WINNT) +#define _WIN32_WINNT 0x0400 +#endif +#include <windows.h> + + +#endif // #if dBUILTIN_THREADING_IMPL_ENABLED + + +#include "threading_impl_templates.h" +#include "threading_fake_sync.h" +#include "threading_atomics_provs.h" + + +#if dBUILTIN_THREADING_IMPL_ENABLED + +/************************************************************************/ +/* dxEventWakeup class implementation */ +/************************************************************************/ + +class dxEventWakeup +{ +public: + dxEventWakeup(): m_state_is_permanent(false), m_event_handle(NULL) {} + ~dxEventWakeup() { DoFinalizeObject(); } + + bool InitializeObject() { return DoInitializeObject(); } + +private: + bool DoInitializeObject(); + void DoFinalizeObject(); + +public: + void ResetWakeup(); + void WakeupAThread(); + void WakeupAllThreads(); + + bool WaitWakeup(const dThreadedWaitTime *timeout_time_ptr); + +private: + bool m_state_is_permanent; + HANDLE m_event_handle; +}; + + +bool dxEventWakeup::DoInitializeObject() +{ + dIASSERT(m_event_handle == NULL); + + bool init_result = false; + + do + { + HANDLE event_handle = CreateEvent(NULL, FALSE, FALSE, NULL); + if (event_handle == NULL) + { + break; + } + + m_event_handle = event_handle; + init_result = true; + } + while (false); + + return init_result; +} + +void dxEventWakeup::DoFinalizeObject() +{ + HANDLE event_handle = m_event_handle; + + if (event_handle != NULL) + { + BOOL close_result = CloseHandle(event_handle); + dICHECK(close_result != FALSE); + + m_event_handle = NULL; + } +} + + +void dxEventWakeup::ResetWakeup() +{ + // Order of assignment and resetting event is not important but it is preferable to be performed this way. + m_state_is_permanent = false; + + BOOL event_set_result = ResetEvent(m_event_handle); + dICHECK(event_set_result); +} + +void dxEventWakeup::WakeupAThread() +{ + dIASSERT(!m_state_is_permanent); // Wakeup should not be used after permanent signal + + BOOL event_reset_result = SetEvent(m_event_handle); + dICHECK(event_reset_result); +} + +void dxEventWakeup::WakeupAllThreads() +{ + // Order of assignment and setting event is important! + m_state_is_permanent = true; + + BOOL event_set_result = SetEvent(m_event_handle); + dICHECK(event_set_result); +} + + +bool dxEventWakeup::WaitWakeup(const dThreadedWaitTime *timeout_time_ptr) +{ + bool wait_result; + + if (timeout_time_ptr == NULL) + { + DWORD event_wait_result = WaitForSingleObject(m_event_handle, INFINITE); + dICHECK(event_wait_result == WAIT_OBJECT_0); + + wait_result = true; + } + else if (timeout_time_ptr->wait_sec == 0 && timeout_time_ptr->wait_nsec == 0) + { + DWORD event_wait_result = WaitForSingleObject(m_event_handle, 0); + + wait_result = event_wait_result == WAIT_OBJECT_0; + dICHECK(wait_result || event_wait_result == WAIT_TIMEOUT); + } + else + { + dIASSERT(timeout_time_ptr->wait_nsec < 1000000000UL); + + const DWORD max_wait_seconds_in_a_shot = ((INFINITE - 1) / 1000U) - 1; + + time_t timeout_seconds_remaining = timeout_time_ptr->wait_sec; + DWORD wait_timeout = timeout_time_ptr->wait_nsec != 0 ? ((timeout_time_ptr->wait_nsec + 999999UL) / 1000000UL) : 0; + + while (true) + { + if (timeout_seconds_remaining >= (time_t)max_wait_seconds_in_a_shot) + { + wait_timeout += max_wait_seconds_in_a_shot * 1000U; + timeout_seconds_remaining -= max_wait_seconds_in_a_shot; + } + else + { + wait_timeout += (DWORD)timeout_seconds_remaining * 1000U; + timeout_seconds_remaining = 0; + } + + DWORD event_wait_result = WaitForSingleObject(m_event_handle, wait_timeout); + + if (event_wait_result == WAIT_OBJECT_0) + { + wait_result = true; + break; + } + + dICHECK(event_wait_result == WAIT_TIMEOUT); + + if (timeout_seconds_remaining == 0) + { + wait_result = false; + break; + } + + wait_timeout = 0; + } + } + + if (wait_result && m_state_is_permanent) + { + // Since event is automatic it is necessary to set it back for the upcoming waiters + BOOL event_set_result = SetEvent(m_event_handle); + dICHECK(event_set_result); + } + + return wait_result; +} + + +/************************************************************************/ +/* dxCriticalSectionMutex class implementation */ +/************************************************************************/ + +class dxCriticalSectionMutex +{ +public: + dxCriticalSectionMutex() { InitializeCriticalSection(&m_critical_section); } + ~dxCriticalSectionMutex() { DeleteCriticalSection(&m_critical_section); } + + bool InitializeObject() { return true; } + +public: + void LockMutex() { EnterCriticalSection(&m_critical_section); } + bool TryLockMutex() { return TryEnterCriticalSection(&m_critical_section) != FALSE; } + void UnlockMutex() { LeaveCriticalSection(&m_critical_section); } + +private: + CRITICAL_SECTION m_critical_section; +}; + + +#endif // #if dBUILTIN_THREADING_IMPL_ENABLED + + +/************************************************************************/ +/* Self-threaded job list definition */ +/************************************************************************/ + +typedef dxtemplateJobListContainer<dxFakeLull, dxFakeMutex, dxFakeAtomicsProvider> dxSelfThreadedJobListContainer; +typedef dxtemplateJobListSelfHandler<dxSelfWakeup, dxSelfThreadedJobListContainer> dxSelfThreadedJobListHandler; +typedef dxtemplateThreadingImplementation<dxSelfThreadedJobListContainer, dxSelfThreadedJobListHandler> dxSelfThreadedThreading; + + +#if dBUILTIN_THREADING_IMPL_ENABLED + +/************************************************************************/ +/* Multi-threaded job list definition */ +/************************************************************************/ + +typedef dxtemplateJobListContainer<dxtemplateThreadedLull<dxEventWakeup, dxOUAtomicsProvider, false>, dxCriticalSectionMutex, dxOUAtomicsProvider> dxMultiThreadedJobListContainer; +typedef dxtemplateJobListThreadedHandler<dxEventWakeup, dxMultiThreadedJobListContainer> dxMultiThreadedJobListHandler; +typedef dxtemplateThreadingImplementation<dxMultiThreadedJobListContainer, dxMultiThreadedJobListHandler> dxMultiThreadedThreading; + + +#endif // #if dBUILTIN_THREADING_IMPL_ENABLED + + +#endif // #if defined(_WIN32) + + +#endif // #ifndef _ODE_THREADING_IMPL_WIN_H_ diff --git a/libs/ode-0.16.1/ode/src/threading_pool_posix.cpp b/libs/ode-0.16.1/ode/src/threading_pool_posix.cpp new file mode 100644 index 0000000..39d0d56 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/threading_pool_posix.cpp @@ -0,0 +1,823 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * Threading POSIX thread pool implementation file. * + * Copyright (C) 2011-2019 Oleh Derevenko. All rights reserved. * + * e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * POSIX thread pool implementation for built-in threading support provider. + */ + + +#if !defined(_WIN32) + +#include <ode/odeconfig.h> +#include <ode/error.h> +#include <ode/threading_impl.h> +#include <ode/odeinit.h> +#include "config.h" +#include "objects.h" +#include "threading_impl_templates.h" + + +#if dBUILTIN_THREADING_IMPL_ENABLED + +#include <new> +#include <pthread.h> +#include <signal.h> +#include <errno.h> + +#if !defined(EOK) +#define EOK 0 +#endif + + +#endif // #if dBUILTIN_THREADING_IMPL_ENABLED + + +#if dBUILTIN_THREADING_IMPL_ENABLED + +struct dxEventObject +{ +public: + dxEventObject(): m_event_allocated(false), m_event_manual(false), m_event_value(false) {} + ~dxEventObject() { FinalizeObject(); } + + bool InitializeObject(bool manual_reset, bool initial_state); + void FinalizeObject(); + + // WARNING! To make implementation simpler, event only releases a single thread even for manual mode. + bool WaitInfinitely(); + void SetEvent(); + void ResetEvent(); + +private: + bool m_event_allocated; + bool m_event_manual; + bool m_event_value; + pthread_mutex_t m_event_mutex; + pthread_cond_t m_event_cond; +}; + +bool dxEventObject::InitializeObject(bool manual_reset, bool initial_state) +{ + dIASSERT(!m_event_allocated); + + bool result = false; + + bool cond_allocated = false; + + do + { + int cond_result = pthread_cond_init(&m_event_cond, NULL); + if (cond_result != EOK) + { + errno = cond_result; + break; + } + + cond_allocated = true; + + int mutex_result = pthread_mutex_init(&m_event_mutex, NULL); + if (mutex_result != EOK) + { + errno = mutex_result; + break; + } + + m_event_manual = manual_reset; + m_event_value = initial_state; + m_event_allocated = true; + result = true; + } + while (false); + + if (!result) + { + if (cond_allocated) + { + int cond_destroy_result = pthread_cond_destroy(&m_event_cond); + dIVERIFY(cond_destroy_result == EOK); + } + } + + return result; +} + +void dxEventObject::FinalizeObject() +{ + if (m_event_allocated) + { + int mutex_destroy_result = pthread_mutex_destroy(&m_event_mutex); + dICHECK(mutex_destroy_result == EOK); // Why would mutex be unable to be destroyed? + + int cond_destroy_result = pthread_cond_destroy(&m_event_cond); + dICHECK(cond_destroy_result == EOK); // Why would condvar be unable to be destroyed? + + m_event_allocated = false; + } +} + +bool dxEventObject::WaitInfinitely() +{ + bool result = false; + + int lock_result = pthread_mutex_lock(&m_event_mutex); + dICHECK(lock_result == EOK); + + int wait_result = EOK; + if (!m_event_value) + { + wait_result = pthread_cond_wait(&m_event_cond, &m_event_mutex); + dICHECK(wait_result != EINTR); // Would caller be so kind to disable signal handling for thread for duration of the call to ODE at least? + } + + if (wait_result == EOK) + { + dIASSERT(m_event_value); + + if (!m_event_manual) + { + m_event_value = false; + } + + result = true; + } + + int unlock_result = pthread_mutex_unlock(&m_event_mutex); + dICHECK(unlock_result == EOK); + + return result; +} + +void dxEventObject::SetEvent() +{ + int lock_result = pthread_mutex_lock(&m_event_mutex); + dICHECK(lock_result == EOK); + + if (!m_event_value) + { + m_event_value = true; + + // NOTE! Event only releases a single thread even for manual mode to simplify implementation. + int signal_result = pthread_cond_signal(&m_event_cond); + dICHECK(signal_result == EOK); + } + + int unlock_result = pthread_mutex_unlock(&m_event_mutex); + dICHECK(unlock_result == EOK); +} + +void dxEventObject::ResetEvent() +{ + int lock_result = pthread_mutex_lock(&m_event_mutex); + dICHECK(lock_result == EOK); + + m_event_value = false; + + int unlock_result = pthread_mutex_unlock(&m_event_mutex); + dICHECK(unlock_result == EOK); +} + + +struct dxThreadPoolThreadInfo +{ +public: + dxThreadPoolThreadInfo(); + ~dxThreadPoolThreadInfo(); + + bool Initialize(sizeint stack_size, unsigned int ode_data_allocate_flags); + +private: + bool InitializeThreadAttributes(pthread_attr_t *thread_attr, sizeint stack_size); + void FinalizeThreadAttributes(pthread_attr_t *thread_attr); + bool WaitInitStatus(); + +private: + void Finalize(); + void WaitAndCloseThreadHandle(pthread_t thread_handle); + +public: + enum dxTHREADCOMMAND + { + dxTHREAD_COMMAND_EXIT, + dxTHREAD_COMMAND_NOOP, + dxTHREAD_COMMAND_SERVE_IMPLEMENTATION, + }; + + struct dxServeImplementationParams + { + dxServeImplementationParams(dThreadingImplementationID impl, dxEventObject *ready_wait_event): + m_impl(impl), m_ready_wait_event(ready_wait_event) + { + } + + dThreadingImplementationID m_impl; + dxEventObject *m_ready_wait_event; + }; + + void ExecuteThreadCommand(dxTHREADCOMMAND command, void *param, bool wait_response); + +private: + static void *ThreadProcedure_Callback(void *thread_param); + void ThreadProcedure(); + bool DisableSignalHandlers(); + void ReportInitStatus(bool init_result); + void RunCommandHandlingLoop(); + + void ThreadedServeImplementation(dThreadingImplementationID impl, dxEventObject *ready_wait_event); + static void ProcessThreadServeReadiness_Callback(void *context); + +private: + pthread_t m_thread_handle; + bool m_thread_allocated; + + unsigned int m_ode_data_allocate_flags; + dxTHREADCOMMAND m_command_code; + dxEventObject m_command_event; + dxEventObject m_acknowledgement_event; + void *m_command_param; +}; + + +dxThreadPoolThreadInfo::dxThreadPoolThreadInfo(): +m_thread_handle(), +m_thread_allocated(false), +m_ode_data_allocate_flags(0), +m_command_code(dxTHREAD_COMMAND_EXIT), +m_command_event(), +m_acknowledgement_event(), +m_command_param(NULL) +{ +} + +dxThreadPoolThreadInfo::~dxThreadPoolThreadInfo() +{ + Finalize(); +} + + +bool dxThreadPoolThreadInfo::Initialize(sizeint stack_size, unsigned int ode_data_allocate_flags) +{ + bool result = false; + + bool command_event_allocated = false, acknowledgement_event_allocated = false; + + do + { + // -- There is no implicit limit on stack size in POSIX implementation + // if (stack_size > ...) + // { + // errno = EINVAL; + // break; + // } + + if (!m_command_event.InitializeObject(false, false)) + { + break; + } + + command_event_allocated = true; + + if (!m_acknowledgement_event.InitializeObject(true, false)) + { + break; + } + + acknowledgement_event_allocated = true; + + m_ode_data_allocate_flags = ode_data_allocate_flags; + + pthread_attr_t thread_attr; + if (!InitializeThreadAttributes(&thread_attr, stack_size)) + { + break; + } + + int thread_create_result = pthread_create(&m_thread_handle, &thread_attr, &ThreadProcedure_Callback, (void *)this); + + FinalizeThreadAttributes(&thread_attr); + + if (thread_create_result != EOK) + { + errno = thread_create_result; + break; + } + + bool thread_init_result = WaitInitStatus(); + if (!thread_init_result) + { + WaitAndCloseThreadHandle(m_thread_handle); + break; + } + + m_thread_allocated = true; + result = true; + } + while (false); + + if (!result) + { + if (command_event_allocated) + { + if (acknowledgement_event_allocated) + { + m_acknowledgement_event.FinalizeObject(); + } + + m_command_event.FinalizeObject(); + } + } + + return result; +} + +bool dxThreadPoolThreadInfo::InitializeThreadAttributes(pthread_attr_t *thread_attr, sizeint stack_size) +{ + bool result = false; + + bool attr_inited = false; + + do + { + int init_result = pthread_attr_init(thread_attr); + if (init_result != EOK) + { + errno = init_result; + break; + } + + attr_inited = true; + + int set_result; + if ((set_result = pthread_attr_setdetachstate(thread_attr, PTHREAD_CREATE_JOINABLE)) != EOK +#if (HAVE_PTHREAD_ATTR_SETINHERITSCHED) + || (set_result = pthread_attr_setinheritsched(thread_attr, PTHREAD_INHERIT_SCHED)) != EOK +#endif +#if (HAVE_PTHREAD_ATTR_SETSTACKLAZY) + || (set_result = pthread_attr_setstacklazy(thread_attr, PTHREAD_STACK_NOTLAZY)) != EOK +#endif + || (stack_size != 0 && (set_result = pthread_attr_setstacksize(thread_attr, stack_size)) != EOK)) + { + errno = set_result; + break; + } + + result = true; + } + while (false); + + if (!result) + { + if (attr_inited) + { + int destroy_result = pthread_attr_destroy(thread_attr); + dIVERIFY(destroy_result == EOK); + } + } + + return result; +} + +void dxThreadPoolThreadInfo::FinalizeThreadAttributes(pthread_attr_t *thread_attr) +{ + int destroy_result = pthread_attr_destroy(thread_attr); + dIVERIFY(destroy_result == EOK); +} + +bool dxThreadPoolThreadInfo::WaitInitStatus() +{ + bool acknowledgement_wait_result = m_acknowledgement_event.WaitInfinitely(); + dICHECK(acknowledgement_wait_result); + + int error_code = (int)(sizeint)m_command_param; + + bool init_status = error_code == EOK ? true : ((errno = error_code), false); + return init_status; +} + +void dxThreadPoolThreadInfo::Finalize() +{ + if (m_thread_allocated) + { + ExecuteThreadCommand(dxTHREAD_COMMAND_EXIT, NULL, false); + + WaitAndCloseThreadHandle(m_thread_handle); + m_thread_allocated = false; + + m_command_event.FinalizeObject(); + m_acknowledgement_event.FinalizeObject(); + } +} + +void dxThreadPoolThreadInfo::WaitAndCloseThreadHandle(pthread_t thread_handle) +{ + int join_result = pthread_join(thread_handle, NULL); + dICHECK(join_result == EOK); +} + +void dxThreadPoolThreadInfo::ExecuteThreadCommand(dxTHREADCOMMAND command, void *param, bool wait_response) +{ + bool acknowledgement_wait_result = m_acknowledgement_event.WaitInfinitely(); + dICHECK(acknowledgement_wait_result); + + m_acknowledgement_event.ResetEvent(); + + m_command_code = command; + m_command_param = param; + + m_command_event.SetEvent(); + + if (wait_response) + { + bool new_acknowledgement_wait_result = m_acknowledgement_event.WaitInfinitely(); + dICHECK(new_acknowledgement_wait_result); + } +} + +void *dxThreadPoolThreadInfo::ThreadProcedure_Callback(void *thread_param) +{ + dxThreadPoolThreadInfo *thread_info = (dxThreadPoolThreadInfo *)thread_param; + thread_info->ThreadProcedure(); + + return 0; +} + +void dxThreadPoolThreadInfo::ThreadProcedure() +{ + bool init_result = dAllocateODEDataForThread(m_ode_data_allocate_flags) != 0 + && DisableSignalHandlers(); + + ReportInitStatus(init_result); + + if (init_result) + { + RunCommandHandlingLoop(); + + // dCleanupODEAllDataForThread(); -- this function can only be called if ODE was initialized for manual cleanup. And that is unknown here... + } +} + +bool dxThreadPoolThreadInfo::DisableSignalHandlers() +{ + bool result = false; + + sigset_t set; + sigfillset( &set ); + + if (sigprocmask( SIG_BLOCK, &set, NULL ) != -1) + { + result = true; + } + + return result; +} + +void dxThreadPoolThreadInfo::ReportInitStatus(bool init_result) +{ + m_command_param = (void *)(sizeint)(init_result ? EOK : ((errno != EOK) ? errno : EFAULT)); + + m_acknowledgement_event.SetEvent(); +} + +void dxThreadPoolThreadInfo::RunCommandHandlingLoop() +{ + bool exit_requested = false; + + while (!exit_requested) + { + bool command_wait_result = m_command_event.WaitInfinitely(); + dICHECK(command_wait_result); + + const dxTHREADCOMMAND command_code = m_command_code; + switch (command_code) + { + case dxTHREAD_COMMAND_EXIT: + { + m_acknowledgement_event.SetEvent(); + + exit_requested = true; + break; + } + + default: + { + dIASSERT(false); + // break; -- proceed to case dxTHREAD_COMMAND_NOOP + } + + case dxTHREAD_COMMAND_NOOP: + { + m_acknowledgement_event.SetEvent(); + + // Do nothing + break; + } + + case dxTHREAD_COMMAND_SERVE_IMPLEMENTATION: + { + const dxServeImplementationParams *serve_params = (const dxServeImplementationParams *)m_command_param; + dThreadingImplementationID impl = serve_params->m_impl; + dxEventObject *ready_wait_event = serve_params->m_ready_wait_event; + + m_acknowledgement_event.SetEvent(); + + ThreadedServeImplementation(impl, ready_wait_event); + break; + } + } + } +} + +void dxThreadPoolThreadInfo::ThreadedServeImplementation(dThreadingImplementationID impl, dxEventObject *ready_wait_event) +{ + ((dxIThreadingImplementation *)impl)->StickToJobsProcessing(&ProcessThreadServeReadiness_Callback, (void *)ready_wait_event); +} + +void dxThreadPoolThreadInfo::ProcessThreadServeReadiness_Callback(void *context) +{ + dxEventObject *ready_wait_event = (dxEventObject *)context; + + ready_wait_event->SetEvent(); +} + + + +struct dxThreadingThreadPool: + public dBase +{ +public: + dxThreadingThreadPool(); + ~dxThreadingThreadPool(); + + bool InitializeThreads(sizeint thread_count, sizeint stack_size, unsigned int ode_data_allocate_flags); + +private: + void FinalizeThreads(); + + bool InitializeIndividualThreadInfos(dxThreadPoolThreadInfo *thread_infos, sizeint thread_count, sizeint stack_size, unsigned int ode_data_allocate_flags); + void FinalizeIndividualThreadInfos(dxThreadPoolThreadInfo *thread_infos, sizeint thread_count); + + bool InitializeSingleThreadInfo(dxThreadPoolThreadInfo *thread_info, sizeint stack_size, unsigned int ode_data_allocate_flags); + void FinalizeSingleThreadInfo(dxThreadPoolThreadInfo *thread_info); + +public: + void ServeThreadingImplementation(dThreadingImplementationID impl); + void WaitIdleState(); + +private: + dxThreadPoolThreadInfo *m_thread_infos; + sizeint m_thread_count; + dxEventObject m_ready_wait_event; +}; + + +dxThreadingThreadPool::dxThreadingThreadPool(): +m_thread_infos(NULL), +m_thread_count(0), +m_ready_wait_event() +{ +} + +dxThreadingThreadPool::~dxThreadingThreadPool() +{ + FinalizeThreads(); +} + + +bool dxThreadingThreadPool::InitializeThreads(sizeint thread_count, sizeint stack_size, unsigned int ode_data_allocate_flags) +{ + dIASSERT(m_thread_infos == NULL); + + bool result = false; + + bool wait_event_allocated = false; + + dxThreadPoolThreadInfo *thread_infos = NULL; + bool thread_infos_allocated = false; + + do + { + if (!m_ready_wait_event.InitializeObject(false, false)) + { + break; + } + + wait_event_allocated = true; + + thread_infos = (dxThreadPoolThreadInfo *)dAlloc(thread_count * sizeof(dxThreadPoolThreadInfo)); + if (thread_infos == NULL) + { + break; + } + + thread_infos_allocated = true; + + if (!InitializeIndividualThreadInfos(thread_infos, thread_count, stack_size, ode_data_allocate_flags)) + { + break; + } + + m_thread_infos = thread_infos; + m_thread_count = thread_count; + result = true; + } + while (false); + + if (!result) + { + if (wait_event_allocated) + { + if (thread_infos_allocated) + { + dFree(thread_infos, thread_count * sizeof(dxThreadPoolThreadInfo)); + } + + m_ready_wait_event.FinalizeObject(); + } + } + + return result; +} + +void dxThreadingThreadPool::FinalizeThreads() +{ + dxThreadPoolThreadInfo *thread_infos = m_thread_infos; + if (thread_infos != NULL) + { + sizeint thread_count = m_thread_count; + + FinalizeIndividualThreadInfos(thread_infos, thread_count); + dFree(thread_infos, thread_count * sizeof(dxThreadPoolThreadInfo)); + + m_ready_wait_event.FinalizeObject(); + } +} + + +bool dxThreadingThreadPool::InitializeIndividualThreadInfos(dxThreadPoolThreadInfo *thread_infos, sizeint thread_count, sizeint stack_size, unsigned int ode_data_allocate_flags) +{ + bool any_fault = false; + + dxThreadPoolThreadInfo *const infos_end = thread_infos + thread_count; + for (dxThreadPoolThreadInfo *current_info = thread_infos; current_info != infos_end; ++current_info) + { + if (!InitializeSingleThreadInfo(current_info, stack_size, ode_data_allocate_flags)) + { + FinalizeIndividualThreadInfos(thread_infos, current_info - thread_infos); + + any_fault = true; + break; + } + } + + bool result = !any_fault; + return result; +} + +void dxThreadingThreadPool::FinalizeIndividualThreadInfos(dxThreadPoolThreadInfo *thread_infos, sizeint thread_count) +{ + dxThreadPoolThreadInfo *const infos_end = thread_infos + thread_count; + for (dxThreadPoolThreadInfo *current_info = thread_infos; current_info != infos_end; ++current_info) + { + FinalizeSingleThreadInfo(current_info); + } +} + + +bool dxThreadingThreadPool::InitializeSingleThreadInfo(dxThreadPoolThreadInfo *thread_info, sizeint stack_size, unsigned int ode_data_allocate_flags) +{ + bool result = false; + + new(thread_info) dxThreadPoolThreadInfo(); + + if (thread_info->Initialize(stack_size, ode_data_allocate_flags)) + { + result = true; + } + else + { + thread_info->dxThreadPoolThreadInfo::~dxThreadPoolThreadInfo(); + } + + return result; +} + +void dxThreadingThreadPool::FinalizeSingleThreadInfo(dxThreadPoolThreadInfo *thread_info) +{ + if (thread_info != NULL) + { + thread_info->dxThreadPoolThreadInfo::~dxThreadPoolThreadInfo(); + } +} + + +void dxThreadingThreadPool::ServeThreadingImplementation(dThreadingImplementationID impl) +{ + dxThreadPoolThreadInfo::dxServeImplementationParams params(impl, &m_ready_wait_event); + + dxThreadPoolThreadInfo *const infos_end = m_thread_infos + m_thread_count; + for (dxThreadPoolThreadInfo *current_info = m_thread_infos; current_info != infos_end; ++current_info) + { + current_info->ExecuteThreadCommand(dxThreadPoolThreadInfo::dxTHREAD_COMMAND_SERVE_IMPLEMENTATION, ¶ms, true); + + bool ready_wait_result = m_ready_wait_event.WaitInfinitely(); + dICHECK(ready_wait_result); + } +} + +void dxThreadingThreadPool::WaitIdleState() +{ + dxThreadPoolThreadInfo *const infos_end = m_thread_infos + m_thread_count; + for (dxThreadPoolThreadInfo *current_info = m_thread_infos; current_info != infos_end; ++current_info) + { + current_info->ExecuteThreadCommand(dxThreadPoolThreadInfo::dxTHREAD_COMMAND_NOOP, NULL, true); + } +} + + +#endif // #if dBUILTIN_THREADING_IMPL_ENABLED + + +/*extern */dThreadingThreadPoolID dThreadingAllocateThreadPool(unsigned thread_count, + sizeint stack_size, unsigned int ode_data_allocate_flags, void *reserved/*=NULL*/) +{ + dAASSERT(thread_count != 0); + +#if dBUILTIN_THREADING_IMPL_ENABLED + dxThreadingThreadPool *thread_pool = new dxThreadingThreadPool(); + if (thread_pool != NULL) + { + if (thread_pool->InitializeThreads(thread_count, stack_size, ode_data_allocate_flags)) + { + // do nothing + } + else + { + delete thread_pool; + thread_pool = NULL; + } + } +#else + dThreadingThreadPoolID thread_pool = NULL; + (void)stack_size; // unused + (void)ode_data_allocate_flags; // unused + (void)reserved; // unused +#endif // #if dBUILTIN_THREADING_IMPL_ENABLED + + return (dThreadingThreadPoolID)thread_pool; +} + +/*extern */void dThreadingThreadPoolServeMultiThreadedImplementation(dThreadingThreadPoolID pool, dThreadingImplementationID impl) +{ +#if dBUILTIN_THREADING_IMPL_ENABLED + dxThreadingThreadPool *thread_pool = (dxThreadingThreadPool *)pool; + thread_pool->ServeThreadingImplementation(impl); +#else + (void)pool; // unused + (void)impl; // unused +#endif // #if dBUILTIN_THREADING_IMPL_ENABLED +} + +/*extern */void dThreadingThreadPoolWaitIdleState(dThreadingThreadPoolID pool) +{ +#if dBUILTIN_THREADING_IMPL_ENABLED + dxThreadingThreadPool *thread_pool = (dxThreadingThreadPool *)pool; + thread_pool->WaitIdleState(); +#else + (void)pool; // unused +#endif // #if dBUILTIN_THREADING_IMPL_ENABLED +} + +/*extern */void dThreadingFreeThreadPool(dThreadingThreadPoolID pool) +{ +#if dBUILTIN_THREADING_IMPL_ENABLED + dxThreadingThreadPool *thread_pool = (dxThreadingThreadPool *)pool; + delete thread_pool; +#else + (void)pool; // unused +#endif // #if dBUILTIN_THREADING_IMPL_ENABLED +} + + +#endif // #if !defined(_WIN32) diff --git a/libs/ode-0.16.1/ode/src/threading_pool_win.cpp b/libs/ode-0.16.1/ode/src/threading_pool_win.cpp new file mode 100644 index 0000000..5c17f10 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/threading_pool_win.cpp @@ -0,0 +1,670 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * Threading Windows thread pool implementation file. * + * Copyright (C) 2011-2019 Oleh Derevenko. All rights reserved. * + * e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + * Windows thread pool implementation for built-in threading support provider. + */ + + +#if defined(_WIN32) + +#include <ode/odeconfig.h> +#include <ode/error.h> +#include <ode/threading_impl.h> +#include <ode/odeinit.h> +#include "config.h" +#include "objects.h" +#include "threading_impl_templates.h" + + +#if dBUILTIN_THREADING_IMPL_ENABLED + +#include <Windows.h> +#include <process.h> +#include <new> + + +#endif // #if dBUILTIN_THREADING_IMPL_ENABLED + + +#if dBUILTIN_THREADING_IMPL_ENABLED + +#define THREAD_STACK_MAX ((sizeint)(UINT_MAX - 1)) // The absolute maximum would be UINT_MAX but let it be a little bit less to avoid "Comparison is always false" warnings. ;) + + +struct dxEventObject +{ +public: + dxEventObject(): m_event_handle(NULL) {} + ~dxEventObject() { FinalizeObject(); } + + bool InitializeObject(bool manual_reset, bool initial_state); + void FinalizeObject(); + + bool WaitInfinitely() { return ::WaitForSingleObject(m_event_handle, INFINITE) == WAIT_OBJECT_0; } + void SetEvent(); + void ResetEvent(); + +private: + HANDLE m_event_handle; +}; + +bool dxEventObject::InitializeObject(bool manual_reset, bool initial_state) +{ + dIASSERT(m_event_handle == NULL); + + bool result = false; + + do + { + HANDLE event_handle = ::CreateEvent(NULL, manual_reset, initial_state, NULL); + if (event_handle == NULL) + { + break; + } + + m_event_handle = event_handle; + result = true; + } + while (false); + + return result; +} + +void dxEventObject::FinalizeObject() +{ + HANDLE event_handle = m_event_handle; + if (event_handle != NULL) + { + BOOL close_result = ::CloseHandle(event_handle); + dICHECK(close_result); // Object destruction should always succeed + + m_event_handle = NULL; + } +} + +void dxEventObject::SetEvent() +{ + BOOL set_result = ::SetEvent(m_event_handle); + dICHECK(set_result); +} + +void dxEventObject::ResetEvent() +{ + BOOL reset_result = ::ResetEvent(m_event_handle); + dICHECK(reset_result); +} + + + +struct dxThreadPoolThreadInfo +{ +public: + dxThreadPoolThreadInfo(); + ~dxThreadPoolThreadInfo(); + + bool Initialize(sizeint stack_size, unsigned int ode_data_allocate_flags); + +private: + bool WaitInitStatus(); + +private: + void Finalize(); + void WaitAndCloseThreadHandle(HANDLE thread_handle); + +public: + enum dxTHREADCOMMAND + { + dxTHREAD_COMMAND_EXIT, + dxTHREAD_COMMAND_NOOP, + dxTHREAD_COMMAND_SERVE_IMPLEMENTATION, + }; + + struct dxServeImplementationParams + { + dxServeImplementationParams(dThreadingImplementationID impl, dxEventObject *ready_wait_event): + m_impl(impl), m_ready_wait_event(ready_wait_event) + { + } + + dThreadingImplementationID m_impl; + dxEventObject *m_ready_wait_event; + }; + + void ExecuteThreadCommand(dxTHREADCOMMAND command, void *param, bool wait_response); + +private: + static unsigned CALLBACK ThreadProcedure_Callback(void *thread_param); + void ThreadProcedure(); + void ReportInitStatus(bool init_result); + void RunCommandHandlingLoop(); + + void ThreadedServeImplementation(dThreadingImplementationID impl, dxEventObject *ready_wait_event); + static void ProcessThreadServeReadiness_Callback(void *context); + +private: + HANDLE m_thread_handle; + + unsigned int m_ode_data_allocate_flags; + dxTHREADCOMMAND m_command_code; + dxEventObject m_command_event; + dxEventObject m_acknowledgement_event; + void *m_command_param; +}; + + +dxThreadPoolThreadInfo::dxThreadPoolThreadInfo(): +m_thread_handle(NULL), +m_ode_data_allocate_flags(0), +m_command_code(dxTHREAD_COMMAND_EXIT), +m_command_event(), +m_acknowledgement_event(), +m_command_param(NULL) +{ +} + +dxThreadPoolThreadInfo::~dxThreadPoolThreadInfo() +{ + Finalize(); +} + + +bool dxThreadPoolThreadInfo::Initialize(sizeint stack_size, unsigned int ode_data_allocate_flags) +{ + bool result = false; + + bool command_event_allocated = false, acknowledgement_event_allocated = false; + + HANDLE thread_handle = NULL; + + do + { + if (stack_size > THREAD_STACK_MAX) + { + SetLastError(ERROR_INVALID_PARAMETER); + break; + } + + if (!m_command_event.InitializeObject(false, false)) + { + break; + } + + command_event_allocated = true; + + if (!m_acknowledgement_event.InitializeObject(true, false)) + { + break; + } + + acknowledgement_event_allocated = true; + + m_ode_data_allocate_flags = ode_data_allocate_flags; + + thread_handle = (HANDLE)_beginthreadex(NULL, (unsigned)stack_size, &ThreadProcedure_Callback, (void *)this, 0, NULL); + if (thread_handle == NULL) // Not a bug!!! _beginthreadex() returns NULL on failure + { + break; + } + + // It is OK to alter priority for thread without creating it in suspended state as + // it is anyway going to be waited for (waited for its init result) and + // will not be issues commands until after that. + int own_priority = GetThreadPriority(GetCurrentThread()); + if (own_priority != THREAD_PRIORITY_ERROR_RETURN) + { + if (!SetThreadPriority(thread_handle, own_priority)) + { + // own_priority = THREAD_PRIORITY_ERROR_RETURN; -- Well, if priority inheritance fails - just ignore it :-/ + } + } + + bool thread_init_result = WaitInitStatus(); + if (!thread_init_result) + { + DWORD error_save = GetLastError(); + WaitAndCloseThreadHandle(thread_handle); + SetLastError(error_save); + break; + } + + m_thread_handle = thread_handle; + result = true; + } + while (false); + + if (!result) + { + if (command_event_allocated) + { + if (acknowledgement_event_allocated) + { + m_acknowledgement_event.FinalizeObject(); + } + + m_command_event.FinalizeObject(); + } + } + + return result; +} + +bool dxThreadPoolThreadInfo::WaitInitStatus() +{ + bool acknowledgement_wait_result = m_acknowledgement_event.WaitInfinitely(); + dICHECK(acknowledgement_wait_result); + + DWORD error_code = (DWORD)(sizeint)m_command_param; + + bool init_status = error_code == ERROR_SUCCESS ? true : (SetLastError(error_code), false); + return init_status; +} + +void dxThreadPoolThreadInfo::Finalize() +{ + HANDLE thread_handle = m_thread_handle; + if (thread_handle != NULL) + { + ExecuteThreadCommand(dxTHREAD_COMMAND_EXIT, NULL, false); + + WaitAndCloseThreadHandle(thread_handle); + m_thread_handle = NULL; + + m_command_event.FinalizeObject(); + m_acknowledgement_event.FinalizeObject(); + } +} + +void dxThreadPoolThreadInfo::WaitAndCloseThreadHandle(HANDLE thread_handle) +{ + DWORD thread_wait_result = WaitForSingleObject(thread_handle, INFINITE); + dICHECK(thread_wait_result == WAIT_OBJECT_0); + + BOOL thread_close_result = CloseHandle(thread_handle); + dIVERIFY(thread_close_result); + +} + +void dxThreadPoolThreadInfo::ExecuteThreadCommand(dxTHREADCOMMAND command, void *param, bool wait_response) +{ + bool acknowledgement_wait_result = m_acknowledgement_event.WaitInfinitely(); + dICHECK(acknowledgement_wait_result); + + m_acknowledgement_event.ResetEvent(); + + m_command_code = command; + m_command_param = param; + + m_command_event.SetEvent(); + + if (wait_response) + { + bool new_acknowledgement_wait_result = m_acknowledgement_event.WaitInfinitely(); + dICHECK(new_acknowledgement_wait_result); + } +} + +unsigned CALLBACK dxThreadPoolThreadInfo::ThreadProcedure_Callback(void *thread_param) +{ + dxThreadPoolThreadInfo *thread_info = (dxThreadPoolThreadInfo *)thread_param; + thread_info->ThreadProcedure(); + + return 0; +} + +void dxThreadPoolThreadInfo::ThreadProcedure() +{ + bool init_result = dAllocateODEDataForThread(m_ode_data_allocate_flags) != 0; + + ReportInitStatus(init_result); + + if (init_result) + { + RunCommandHandlingLoop(); + + // dCleanupODEAllDataForThread(); -- this function can only be called if ODE was initialized for manual cleanup. And that is unknown here... + } +} + +void dxThreadPoolThreadInfo::ReportInitStatus(bool init_result) +{ + DWORD error_code; + m_command_param = (void *)(sizeint)(init_result ? ERROR_SUCCESS : ((error_code = GetLastError()) != ERROR_SUCCESS ? error_code : ERROR_INTERNAL_ERROR)); + + m_acknowledgement_event.SetEvent(); +} + +void dxThreadPoolThreadInfo::RunCommandHandlingLoop() +{ + bool exit_requested = false; + + while (!exit_requested) + { + bool command_wait_result = m_command_event.WaitInfinitely(); + dICHECK(command_wait_result); + + const dxTHREADCOMMAND command_code = m_command_code; + switch (command_code) + { + case dxTHREAD_COMMAND_EXIT: + { + m_acknowledgement_event.SetEvent(); + + exit_requested = true; + break; + } + + default: + { + dIASSERT(false); + // break; -- proceed to case dxTHREAD_COMMAND_NOOP + } + + case dxTHREAD_COMMAND_NOOP: + { + m_acknowledgement_event.SetEvent(); + + // Do nothing + break; + } + + case dxTHREAD_COMMAND_SERVE_IMPLEMENTATION: + { + const dxServeImplementationParams *serve_params = (const dxServeImplementationParams *)m_command_param; + dThreadingImplementationID impl = serve_params->m_impl; + dxEventObject *ready_wait_event = serve_params->m_ready_wait_event; + + m_acknowledgement_event.SetEvent(); + + ThreadedServeImplementation(impl, ready_wait_event); + break; + } + } + } +} + +void dxThreadPoolThreadInfo::ThreadedServeImplementation(dThreadingImplementationID impl, dxEventObject *ready_wait_event) +{ + ((dxIThreadingImplementation *)impl)->StickToJobsProcessing(&ProcessThreadServeReadiness_Callback, (void *)ready_wait_event); +} + +void dxThreadPoolThreadInfo::ProcessThreadServeReadiness_Callback(void *context) +{ + dxEventObject *ready_wait_event = (dxEventObject *)context; + + ready_wait_event->SetEvent(); +} + + + +struct dxThreadingThreadPool: + public dBase +{ +public: + dxThreadingThreadPool(); + ~dxThreadingThreadPool(); + + bool InitializeThreads(sizeint thread_count, sizeint stack_size, unsigned int ode_data_allocate_flags); + +private: + void FinalizeThreads(); + + bool InitializeIndividualThreadInfos(dxThreadPoolThreadInfo *thread_infos, sizeint thread_count, sizeint stack_size, unsigned int ode_data_allocate_flags); + void FinalizeIndividualThreadInfos(dxThreadPoolThreadInfo *thread_infos, sizeint thread_count); + + bool InitializeSingleThreadInfo(dxThreadPoolThreadInfo *thread_info, sizeint stack_size, unsigned int ode_data_allocate_flags); + void FinalizeSingleThreadInfo(dxThreadPoolThreadInfo *thread_info); + +public: + void ServeThreadingImplementation(dThreadingImplementationID impl); + void WaitIdleState(); + +private: + dxThreadPoolThreadInfo *m_thread_infos; + sizeint m_thread_count; + dxEventObject m_ready_wait_event; +}; + + +dxThreadingThreadPool::dxThreadingThreadPool(): +m_thread_infos(NULL), +m_thread_count(0), +m_ready_wait_event() +{ +} + +dxThreadingThreadPool::~dxThreadingThreadPool() +{ + FinalizeThreads(); +} + + +bool dxThreadingThreadPool::InitializeThreads(sizeint thread_count, sizeint stack_size, unsigned int ode_data_allocate_flags) +{ + dIASSERT(m_thread_infos == NULL); + + bool result = false; + + bool wait_event_allocated = false; + + dxThreadPoolThreadInfo *thread_infos = NULL; + bool thread_infos_allocated = false; + + do + { + if (!m_ready_wait_event.InitializeObject(false, false)) + { + break; + } + + wait_event_allocated = true; + + thread_infos = (dxThreadPoolThreadInfo *)dAlloc(thread_count * sizeof(dxThreadPoolThreadInfo)); + if (thread_infos == NULL) + { + break; + } + + thread_infos_allocated = true; + + if (!InitializeIndividualThreadInfos(thread_infos, thread_count, stack_size, ode_data_allocate_flags)) + { + break; + } + + m_thread_infos = thread_infos; + m_thread_count = thread_count; + result = true; + } + while (false); + + if (!result) + { + if (wait_event_allocated) + { + if (thread_infos_allocated) + { + dFree(thread_infos, thread_count * sizeof(dxThreadPoolThreadInfo)); + } + + m_ready_wait_event.FinalizeObject(); + } + } + + return result; +} + +void dxThreadingThreadPool::FinalizeThreads() +{ + dxThreadPoolThreadInfo *thread_infos = m_thread_infos; + if (thread_infos != NULL) + { + sizeint thread_count = m_thread_count; + + FinalizeIndividualThreadInfos(thread_infos, thread_count); + dFree(thread_infos, thread_count * sizeof(dxThreadPoolThreadInfo)); + + m_ready_wait_event.FinalizeObject(); + } +} + + +bool dxThreadingThreadPool::InitializeIndividualThreadInfos(dxThreadPoolThreadInfo *thread_infos, sizeint thread_count, sizeint stack_size, unsigned int ode_data_allocate_flags) +{ + bool any_fault = false; + + dxThreadPoolThreadInfo *const infos_end = thread_infos + thread_count; + for (dxThreadPoolThreadInfo *current_info = thread_infos; current_info != infos_end; ++current_info) + { + if (!InitializeSingleThreadInfo(current_info, stack_size, ode_data_allocate_flags)) + { + FinalizeIndividualThreadInfos(thread_infos, current_info - thread_infos); + + any_fault = true; + break; + } + } + + bool result = !any_fault; + return result; +} + +void dxThreadingThreadPool::FinalizeIndividualThreadInfos(dxThreadPoolThreadInfo *thread_infos, sizeint thread_count) +{ + dxThreadPoolThreadInfo *const infos_end = thread_infos + thread_count; + for (dxThreadPoolThreadInfo *current_info = thread_infos; current_info != infos_end; ++current_info) + { + FinalizeSingleThreadInfo(current_info); + } +} + + +bool dxThreadingThreadPool::InitializeSingleThreadInfo(dxThreadPoolThreadInfo *thread_info, sizeint stack_size, unsigned int ode_data_allocate_flags) +{ + bool result = false; + + new(thread_info) dxThreadPoolThreadInfo(); + + if (thread_info->Initialize(stack_size, ode_data_allocate_flags)) + { + result = true; + } + else + { + thread_info->dxThreadPoolThreadInfo::~dxThreadPoolThreadInfo(); + } + + return result; +} + +void dxThreadingThreadPool::FinalizeSingleThreadInfo(dxThreadPoolThreadInfo *thread_info) +{ + if (thread_info != NULL) + { + thread_info->dxThreadPoolThreadInfo::~dxThreadPoolThreadInfo(); + } +} + + +void dxThreadingThreadPool::ServeThreadingImplementation(dThreadingImplementationID impl) +{ + dxThreadPoolThreadInfo::dxServeImplementationParams params(impl, &m_ready_wait_event); + + dxThreadPoolThreadInfo *const infos_end = m_thread_infos + m_thread_count; + for (dxThreadPoolThreadInfo *current_info = m_thread_infos; current_info != infos_end; ++current_info) + { + current_info->ExecuteThreadCommand(dxThreadPoolThreadInfo::dxTHREAD_COMMAND_SERVE_IMPLEMENTATION, ¶ms, true); + + bool ready_wait_result = m_ready_wait_event.WaitInfinitely(); + dICHECK(ready_wait_result); + } +} + +void dxThreadingThreadPool::WaitIdleState() +{ + dxThreadPoolThreadInfo *const infos_end = m_thread_infos + m_thread_count; + for (dxThreadPoolThreadInfo *current_info = m_thread_infos; current_info != infos_end; ++current_info) + { + current_info->ExecuteThreadCommand(dxThreadPoolThreadInfo::dxTHREAD_COMMAND_NOOP, NULL, true); + } +} + + +#endif // #if dBUILTIN_THREADING_IMPL_ENABLED + + +/*extern */dThreadingThreadPoolID dThreadingAllocateThreadPool(unsigned thread_count, + sizeint stack_size, unsigned int ode_data_allocate_flags, void *reserved/*=NULL*/) +{ + dAASSERT(thread_count != 0); + +#if dBUILTIN_THREADING_IMPL_ENABLED + dxThreadingThreadPool *thread_pool = new dxThreadingThreadPool(); + if (thread_pool != NULL) + { + if (thread_pool->InitializeThreads(thread_count, stack_size, ode_data_allocate_flags)) + { + // do nothing + } + else + { + delete thread_pool; + thread_pool = NULL; + } + } +#else + dThreadingThreadPoolID thread_pool = NULL; +#endif // #if dBUILTIN_THREADING_IMPL_ENABLED + + return (dThreadingThreadPoolID)thread_pool; +} + +/*extern */void dThreadingThreadPoolServeMultiThreadedImplementation(dThreadingThreadPoolID pool, dThreadingImplementationID impl) +{ +#if dBUILTIN_THREADING_IMPL_ENABLED + dxThreadingThreadPool *thread_pool = (dxThreadingThreadPool *)pool; + thread_pool->ServeThreadingImplementation(impl); +#endif // #if dBUILTIN_THREADING_IMPL_ENABLED +} + +/*extern */void dThreadingThreadPoolWaitIdleState(dThreadingThreadPoolID pool) +{ +#if dBUILTIN_THREADING_IMPL_ENABLED + dxThreadingThreadPool *thread_pool = (dxThreadingThreadPool *)pool; + thread_pool->WaitIdleState(); +#endif // #if dBUILTIN_THREADING_IMPL_ENABLED +} + +/*extern */void dThreadingFreeThreadPool(dThreadingThreadPoolID pool) +{ +#if dBUILTIN_THREADING_IMPL_ENABLED + dxThreadingThreadPool *thread_pool = (dxThreadingThreadPool *)pool; + delete thread_pool; +#endif // #if dBUILTIN_THREADING_IMPL_ENABLED +} + + +#endif // #if defined(_WIN32) diff --git a/libs/ode-0.16.1/ode/src/threadingutils.h b/libs/ode-0.16.1/ode/src/threadingutils.h new file mode 100644 index 0000000..fb67052 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/threadingutils.h @@ -0,0 +1,157 @@ +/*************************************************************************
+ * *
+ * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
+ * All rights reserved. Email: russ@q12.org Web: www.q12.org *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of EITHER: *
+ * (1) The GNU Lesser General Public License as published by the Free *
+ * Software Foundation; either version 2.1 of the License, or (at *
+ * your option) any later version. The text of the GNU Lesser *
+ * General Public License is included with this library in the *
+ * file LICENSE.TXT. *
+ * (2) The BSD-style license that is included with this library in *
+ * the file LICENSE-BSD.TXT. *
+ * *
+ * This library 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 files *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
+ * *
+ *************************************************************************/
+
+#ifndef _ODE_THREADINGUTILS_H_
+#define _ODE_THREADINGUTILS_H_
+
+
+#include "odeou.h"
+
+
+#if !dTHREADING_INTF_DISABLED
+
+static inline
+bool ThrsafeCompareExchange(volatile atomicord32 *paoDestination, atomicord32 aoComparand, atomicord32 aoExchange)
+{
+ return AtomicCompareExchange(paoDestination, aoComparand, aoExchange);
+}
+
+static inline
+atomicord32 ThrsafeExchange(volatile atomicord32 *paoDestination, atomicord32 aoExchange)
+{
+ return AtomicExchange(paoDestination, aoExchange);
+}
+
+static inline
+void ThrsafeAdd(volatile atomicord32 *paoDestination, atomicord32 aoAddend)
+{
+ AtomicExchangeAddNoResult(paoDestination, aoAddend);
+}
+
+static inline
+atomicord32 ThrsafeExchangeAdd(volatile atomicord32 *paoDestination, atomicord32 aoAddend)
+{
+ return AtomicExchangeAdd(paoDestination, aoAddend);
+}
+
+static inline
+bool ThrsafeCompareExchangePointer(volatile atomicptr *papDestination, atomicptr apComparand, atomicptr apExchange)
+{
+ return AtomicCompareExchangePointer(papDestination, apComparand, apExchange);
+}
+
+static inline
+atomicptr ThrsafeExchangePointer(volatile atomicptr *papDestination, atomicptr apExchange)
+{
+ return AtomicExchangePointer(papDestination, apExchange);
+}
+
+
+#else // #if dTHREADING_INTF_DISABLED
+
+static inline
+bool ThrsafeCompareExchange(volatile atomicord32 *paoDestination, atomicord32 aoComparand, atomicord32 aoExchange)
+{
+ return (*paoDestination == aoComparand) ? ((*paoDestination = aoExchange), true) : false;
+}
+
+static inline
+atomicord32 ThrsafeExchange(volatile atomicord32 *paoDestination, atomicord32 aoExchange)
+{
+ atomicord32 aoDestinationValue = *paoDestination;
+ *paoDestination = aoExchange;
+ return aoDestinationValue;
+}
+
+static inline
+void ThrsafeAdd(volatile atomicord32 *paoDestination, atomicord32 aoAddend)
+{
+ *paoDestination += aoAddend;
+}
+
+static inline
+atomicord32 ThrsafeExchangeAdd(volatile atomicord32 *paoDestination, atomicord32 aoAddend)
+{
+ atomicord32 aoDestinationValue = *paoDestination;
+ *paoDestination += aoAddend;
+ return aoDestinationValue;
+}
+
+static inline
+bool ThrsafeCompareExchangePointer(volatile atomicptr *papDestination, atomicptr apComparand, atomicptr apExchange)
+{
+ return (*papDestination == apComparand) ? ((*papDestination = apExchange), true) : false;
+}
+
+static inline
+atomicptr ThrsafeExchangePointer(volatile atomicptr *papDestination, atomicptr apExchange)
+{
+ atomicptr apDestinationValue = *papDestination;
+ *papDestination = apExchange;
+ return apDestinationValue;
+}
+
+
+#endif // #if dTHREADING_INTF_DISABLED
+
+
+static inline
+unsigned int ThrsafeIncrementIntUpToLimit(volatile atomicord32 *storagePointer, unsigned int limitValue)
+{
+ unsigned int resultValue;
+ while (true) {
+ resultValue = *storagePointer;
+ // The ">=" comparison is used here to allow continuing incrementing the destination
+ // without waiting for all the threads to pass the barrier of checking its value
+ if (resultValue >= limitValue) {
+ resultValue = limitValue;
+ break;
+ }
+ if (ThrsafeCompareExchange(storagePointer, (atomicord32)resultValue, (atomicord32)(resultValue + 1))) {
+ break;
+ }
+ }
+ return resultValue;
+}
+
+static inline
+sizeint ThrsafeIncrementSizeUpToLimit(volatile sizeint *storagePointer, sizeint limitValue)
+{
+ sizeint resultValue;
+ while (true) {
+ resultValue = *storagePointer;
+ // The ">=" comparison is not required here at present ("==" could be used).
+ // It is just used this way to match the other function above.
+ if (resultValue >= limitValue) {
+ resultValue = limitValue;
+ break;
+ }
+ if (ThrsafeCompareExchangePointer((volatile atomicptr *)storagePointer, (atomicptr)resultValue, (atomicptr)(resultValue + 1))) {
+ break;
+ }
+ }
+ return resultValue;
+}
+
+
+
+#endif // _ODE_THREADINGUTILS_H_
diff --git a/libs/ode-0.16.1/ode/src/timer.cpp b/libs/ode-0.16.1/ode/src/timer.cpp new file mode 100644 index 0000000..4f3434a --- /dev/null +++ b/libs/ode-0.16.1/ode/src/timer.cpp @@ -0,0 +1,424 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +TODO +---- + +* gettimeofday() and the pentium time stamp counter return the real time, + not the process time. fix this somehow! + +*/ + +#include <ode/common.h> +#include <ode/timer.h> +#include "config.h" +#include "common.h" + + +// misc defines +#define ALLOCA dALLOCA16 + +//**************************************************************************** +// implementation for windows based on the multimedia performance counter. + +#ifdef WIN32 + +#include "windows.h" + +static inline void getClockCount (unsigned long cc[2]) +{ + LARGE_INTEGER a; + QueryPerformanceCounter (&a); + cc[0] = a.LowPart; + cc[1] = a.HighPart; +} + + +static inline void serialize() +{ +} + + +static inline double loadClockCount (unsigned long cc[2]) +{ + LARGE_INTEGER a; + a.LowPart = cc[0]; + a.HighPart = cc[1]; + return double(a.QuadPart); +} + + +double dTimerResolution() +{ + return 1.0/dTimerTicksPerSecond(); +} + + +double dTimerTicksPerSecond() +{ + static int query=0; + static double hz=0.0; + if (!query) { + LARGE_INTEGER a; + QueryPerformanceFrequency (&a); + hz = double(a.QuadPart); + query = 1; + } + return hz; +} + +#endif + +//**************************************************************************** +// implementation based on the pentium time stamp counter. the timer functions +// can be serializing or non-serializing. serializing will ensure that all +// instructions have executed and data has been written back before the cpu +// time stamp counter is read. the CPUID instruction is used to serialize. + +#if defined(PENTIUM) && !defined(WIN32) + +// we need to know the clock rate so that the timing function can report +// accurate times. this number only needs to be set accurately if we're +// doing performance tests and care about real-world time numbers - otherwise, +// just ignore this. i have not worked out how to determine this number +// automatically yet. + +#define PENTIUM_HZ (500e6) + +static inline void getClockCount (unsigned long cc[2]) +{ +#ifndef X86_64_SYSTEM + asm volatile ( + "rdtsc\n" + "movl %%eax,(%%esi)\n" + "movl %%edx,4(%%esi)\n" + : : "S" (cc) : "%eax","%edx","cc","memory"); +#else + asm volatile ( + "rdtsc\n" + "movl %%eax,(%%rsi)\n" + "movl %%edx,4(%%rsi)\n" + : : "S" (cc) : "%eax","%edx","cc","memory"); +#endif +} + + +static inline void serialize() +{ +#ifndef X86_64_SYSTEM + asm volatile ( + "mov $0,%%eax\n" + "push %%ebx\n" + "cpuid\n" + "pop %%ebx\n" + : : : "%eax","%ecx","%edx","cc","memory"); +#else + asm volatile ( + "mov $0,%%rax\n" + "push %%rbx\n" + "cpuid\n" + "pop %%rbx\n" + : : : "%rax","%rcx","%rdx","cc","memory"); +#endif +} + + +static inline double loadClockCount (unsigned long a[2]) +{ + double ret; +#ifndef X86_64_SYSTEM + asm volatile ("fildll %1; fstpl %0" : "=m" (ret) : "m" (a[0]) : + "cc","memory"); +#else + asm volatile ("fildll %1; fstpl %0" : "=m" (ret) : "m" (a[0]) : + "cc","memory"); +#endif + return ret; +} + + +double dTimerResolution() +{ + return 1.0/PENTIUM_HZ; +} + + +double dTimerTicksPerSecond() +{ + return PENTIUM_HZ; +} + +#endif + +//**************************************************************************** +// otherwise, do the implementation based on gettimeofday(). + +#if !defined(PENTIUM) && !defined(WIN32) + +#ifndef macintosh + +#include <sys/time.h> +#include <unistd.h> + + +static inline void getClockCount (unsigned long cc[2]) +{ + struct timeval tv; + gettimeofday (&tv,0); + cc[0] = tv.tv_usec; + cc[1] = tv.tv_sec; +} + +#else // macintosh + +#include <CoreServices/CoreServices.h> +#include <ode/Timer.h> + +static inline void getClockCount (unsigned long cc[2]) +{ + UnsignedWide ms; + Microseconds (&ms); + cc[1] = ms.lo / 1000000; + cc[0] = ms.lo - ( cc[1] * 1000000 ); +} + +#endif + + +static inline void serialize() +{ +} + + +static inline double loadClockCount (unsigned long a[2]) +{ + return a[1]*1.0e6 + a[0]; +} + + +double dTimerResolution() +{ + unsigned long cc1[2],cc2[2]; + getClockCount (cc1); + do { + getClockCount (cc2); + } + while (cc1[0]==cc2[0] && cc1[1]==cc2[1]); + do { + getClockCount (cc1); + } + while (cc1[0]==cc2[0] && cc1[1]==cc2[1]); + double t1 = loadClockCount (cc1); + double t2 = loadClockCount (cc2); + return (t1-t2) / dTimerTicksPerSecond(); +} + + +double dTimerTicksPerSecond() +{ + return 1000000; +} + +#endif + +//**************************************************************************** +// stop watches + +void dStopwatchReset (dStopwatch *s) +{ + s->time = 0; + s->cc[0] = 0; + s->cc[1] = 0; +} + + +void dStopwatchStart (dStopwatch *s) +{ + serialize(); + getClockCount (s->cc); +} + + +void dStopwatchStop (dStopwatch *s) +{ + unsigned long cc[2]; + serialize(); + getClockCount (cc); + double t1 = loadClockCount (s->cc); + double t2 = loadClockCount (cc); + s->time += t2-t1; +} + + +double dStopwatchTime (dStopwatch *s) +{ + return s->time / dTimerTicksPerSecond(); +} + +//**************************************************************************** +// code timers + +// maximum number of events to record +#define MAXNUM 100 + +static int num = 0; // number of entries used in event array +static struct { + unsigned long cc[2]; // clock counts + double total_t; // total clocks used in this slot. + double total_p; // total percentage points used in this slot. + int count; // number of times this slot has been updated. + const char *description; // pointer to static string +} event[MAXNUM]; + + +// make sure all slot totals and counts reset to 0 at start + +static void initSlots() +{ + static int initialized=0; + if (!initialized) { + for (int i=0; i<MAXNUM; i++) { + event[i].count = 0; + event[i].total_t = 0; + event[i].total_p = 0; + } + initialized = 1; + } +} + + +void dTimerStart (const char *description) +{ + initSlots(); + event[0].description = const_cast<char*> (description); + num = 1; + serialize(); + getClockCount (event[0].cc); +} + + +void dTimerNow (const char *description) +{ + if (num < MAXNUM) { + // do not serialize + getClockCount (event[num].cc); + event[num].description = const_cast<char*> (description); + num++; + } +} + + +void dTimerEnd() +{ + if (num < MAXNUM) { + serialize(); + getClockCount (event[num].cc); + event[num].description = "TOTAL"; + num++; + } +} + +//**************************************************************************** +// print report + +static void fprintDoubleWithPrefix (FILE *f, double a, const char *fmt) +{ + if (a >= 0.999999) { + fprintf (f,fmt,a); + return; + } + a *= 1000.0; + if (a >= 0.999999) { + fprintf (f,fmt,a); + fprintf (f,"m"); + return; + } + a *= 1000.0; + if (a >= 0.999999) { + fprintf (f,fmt,a); + fprintf (f,"u"); + return; + } + a *= 1000.0; + fprintf (f,fmt,a); + fprintf (f,"n"); +} + + +void dTimerReport (FILE *fout, int average) +{ + int i; + sizeint maxl; + double ccunit = 1.0/dTimerTicksPerSecond(); + fprintf (fout,"\nTimer Report ("); + fprintDoubleWithPrefix (fout,ccunit,"%.2f "); + fprintf (fout,"s resolution)\n------------\n"); + if (num < 1) return; + + // get maximum description length + maxl = 0; + for (i=0; i<num; i++) { + sizeint l = strlen (event[i].description); + if (l > maxl) maxl = l; + } + + // calculate total time + double t1 = loadClockCount (event[0].cc); + double t2 = loadClockCount (event[num-1].cc); + double total = t2 - t1; + if (total <= 0) total = 1; + + // compute time difference for all slots except the last one. update totals + double *times = (double*) ALLOCA (num * sizeof(double)); + for (i=0; i < (num-1); i++) { + double t1 = loadClockCount (event[i].cc); + double t2 = loadClockCount (event[i+1].cc); + times[i] = t2 - t1; + event[i].count++; + event[i].total_t += times[i]; + event[i].total_p += times[i]/total * 100.0; + } + + // print report (with optional averages) + for (i=0; i<num; i++) { + double t,p; + if (i < (num-1)) { + t = times[i]; + p = t/total * 100.0; + } + else { + t = total; + p = 100.0; + } + fprintf (fout,"%-*s %7.2fms %6.2f%%",(int)maxl,event[i].description, + t*ccunit * 1000.0, p); + if (average && i < (num-1)) { + fprintf (fout," (avg %7.2fms %6.2f%%)", + (event[i].total_t / event[i].count)*ccunit * 1000.0, + event[i].total_p / event[i].count); + } + fprintf (fout,"\n"); + } + fprintf (fout,"\n"); +} diff --git a/libs/ode-0.16.1/ode/src/typedefs.h b/libs/ode-0.16.1/ode/src/typedefs.h new file mode 100644 index 0000000..c8164c3 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/typedefs.h @@ -0,0 +1,74 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_TYPEDEFS_H_ +#define _ODE_TYPEDEFS_H_ + +#include <ode/odeconfig.h> + +#include "error.h" + + +/* + * Internal typedefs to map public types into more convenient private types + */ + + +typedef dint64 int64; +dSASSERT(sizeof(int64) == 8); + +typedef duint64 uint64; +dSASSERT(sizeof(uint64) == 8); + +typedef dint32 int32; +dSASSERT(sizeof(int32) == 4); + +typedef duint32 uint32; +dSASSERT(sizeof(uint32) == 4); + +typedef dint16 int16; +dSASSERT(sizeof(int16) == 2); + +typedef duint16 uint16; +dSASSERT(sizeof(uint16) == 2); + +typedef dint8 int8; +dSASSERT(sizeof(int8) == 1); + +typedef duint8 uint8; +dSASSERT(sizeof(uint8) == 1); + + +typedef dintptr intptr; +dSASSERT(sizeof(intptr) == sizeof(void *)); + +typedef duintptr uintptr; +dSASSERT(sizeof(uintptr) == sizeof(void *)); + +typedef ddiffint diffint; +dSASSERT(sizeof(diffint) == sizeof(void *)); // So far, we choose to not support systems that have accessible memory segment size smaller than the pointer size + +typedef dsizeint sizeint; +dSASSERT(sizeof(sizeint) == sizeof(void *)); // So far, we choose to not support systems that have accessible memory segment size smaller than the pointer size + + +#endif diff --git a/libs/ode-0.16.1/ode/src/util.cpp b/libs/ode-0.16.1/ode/src/util.cpp new file mode 100644 index 0000000..17b9e8a --- /dev/null +++ b/libs/ode-0.16.1/ode/src/util.cpp @@ -0,0 +1,1231 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include <ode/ode.h> +#include "config.h" +#include "util.h" +#include "objects.h" +#include "joints/joint.h" +#include "threadingutils.h" + +#include <new> + + +#define dMIN(A,B) ((A)>(B) ? (B) : (A)) +#define dMAX(A,B) ((B)>(A) ? (B) : (A)) + + +//**************************************************************************** +// Malloc based world stepping memory manager + +/*extern */dxWorldProcessMemoryManager g_WorldProcessMallocMemoryManager(dAlloc, dRealloc, dFree); +/*extern */dxWorldProcessMemoryReserveInfo g_WorldProcessDefaultReserveInfo(dWORLDSTEP_RESERVEFACTOR_DEFAULT, dWORLDSTEP_RESERVESIZE_DEFAULT); + + +//**************************************************************************** +// dxWorldProcessContext + +const char *const dxWorldProcessContext::m_aszContextMutexNames[dxPCM__MAX] = +{ + "Stepper Arena Obtain Lock" , // dxPCM_STEPPER_ARENA_OBTAIN, + "Joint addLimot Serialize Lock" , // dxPCM_STEPPER_ADDLIMOT_SERIALIZE + "Stepper StepBody Serialize Lock" , // dxPCM_STEPPER_STEPBODY_SERIALIZE, +}; + +dxWorldProcessContext::dxWorldProcessContext(): + m_pmaIslandsArena(NULL), + m_pmaStepperArenas(NULL), + m_pswObjectsAllocWorld(NULL), + m_pmgStepperMutexGroup(NULL), + m_pcwIslandsSteppingWait(NULL) +{ + // Do nothing +} + +dxWorldProcessContext::~dxWorldProcessContext() +{ + dIASSERT((m_pswObjectsAllocWorld != NULL) == (m_pmgStepperMutexGroup != NULL)); + dIASSERT((m_pswObjectsAllocWorld != NULL) == (m_pcwIslandsSteppingWait != NULL)); + + if (m_pswObjectsAllocWorld != NULL) + { + m_pswObjectsAllocWorld->FreeMutexGroup(m_pmgStepperMutexGroup); + // m_pswObjectsAllocWorld->FreeThreadedCallWait(m_pcwIslandsSteppingWait); -- The stock call wait can not be freed + } + + dxWorldProcessMemArena *pmaStepperArenas = m_pmaStepperArenas; + if (pmaStepperArenas != NULL) + { + FreeArenasList(pmaStepperArenas); + } + + if (m_pmaIslandsArena != NULL) + { + dxWorldProcessMemArena::FreeMemArena(m_pmaIslandsArena); + } +} + +void dxWorldProcessContext::CleanupWorldReferences(dxWorld *pswWorldInstance) +{ + dIASSERT((m_pswObjectsAllocWorld != NULL) == (m_pmgStepperMutexGroup != NULL)); + dIASSERT((m_pswObjectsAllocWorld != NULL) == (m_pcwIslandsSteppingWait != NULL)); + + if (m_pswObjectsAllocWorld == pswWorldInstance) + { + m_pswObjectsAllocWorld->FreeMutexGroup(m_pmgStepperMutexGroup); + // m_pswObjectsAllocWorld->FreeThreadedCallWait(m_pcwIslandsSteppingWait); -- The stock call wait can not be freed + + m_pswObjectsAllocWorld = NULL; + m_pmgStepperMutexGroup = NULL; + m_pcwIslandsSteppingWait = NULL; + } +} + +bool dxWorldProcessContext::EnsureStepperSyncObjectsAreAllocated(dxWorld *pswWorldInstance) +{ + dIASSERT((m_pswObjectsAllocWorld != NULL) == (m_pmgStepperMutexGroup != NULL)); + dIASSERT((m_pswObjectsAllocWorld != NULL) == (m_pcwIslandsSteppingWait != NULL)); + + bool bResult = false; + + dMutexGroupID pmbStepperMutexGroup = NULL; + bool bStepperMutexGroupAllocated = false; + + do + { + if (m_pswObjectsAllocWorld == NULL) + { + pmbStepperMutexGroup = pswWorldInstance->AllocMutexGroup(dxPCM__MAX, m_aszContextMutexNames); + if (pmbStepperMutexGroup == NULL) + { + break; + } + + bStepperMutexGroupAllocated = true; + + dCallWaitID pcwIslandsSteppingWait = pswWorldInstance->AllocateOrRetrieveStockCallWaitID(); + if (pcwIslandsSteppingWait == NULL) + { + break; + } + + m_pswObjectsAllocWorld = pswWorldInstance; + m_pmgStepperMutexGroup = pmbStepperMutexGroup; + m_pcwIslandsSteppingWait = pcwIslandsSteppingWait; + } + + bResult = true; + } + while (false); + + if (!bResult) + { + if (bStepperMutexGroupAllocated) + { + pswWorldInstance->FreeMutexGroup(pmbStepperMutexGroup); + } + } + + return bResult; +} + + +dxWorldProcessMemArena *dxWorldProcessContext::ObtainStepperMemArena() +{ + dxWorldProcessMemArena *pmaArenaInstance = NULL; + + while (true) + { + dxWorldProcessMemArena *pmaRawArenasHead = GetStepperArenasHead(); + if (pmaRawArenasHead == NULL) + { + break; + } + + // Extraction must be locked so that other thread does not "steal" head arena, + // use it and then reinsert back with a different "next" + dxMutexGroupLockHelper lhLockHelper(m_pswObjectsAllocWorld, m_pmgStepperMutexGroup, dxPCM_STEPPER_ARENA_OBTAIN); + + dxWorldProcessMemArena *pmaArenasHead = GetStepperArenasHead(); // Arenas head must be re-extracted after mutex has been locked + bool bExchangeResult = pmaArenasHead != NULL && TryExtractingStepperArenasHead(pmaArenasHead); + + lhLockHelper.UnlockMutex(); + + if (bExchangeResult) + { + pmaArenasHead->ResetState(); + pmaArenaInstance = pmaArenasHead; + break; + } + } + + return pmaArenaInstance; +} + +void dxWorldProcessContext::ReturnStepperMemArena(dxWorldProcessMemArena *pmaArenaInstance) +{ + while (true) + { + dxWorldProcessMemArena *pmaArenasHead = GetStepperArenasHead(); + pmaArenaInstance->SetNextMemArena(pmaArenasHead); + + if (TryInsertingStepperArenasHead(pmaArenaInstance, pmaArenasHead)) + { + break; + } + } +} + + +dxWorldProcessMemArena *dxWorldProcessContext::ReallocateIslandsMemArena(sizeint nMemoryRequirement, + const dxWorldProcessMemoryManager *pmmMemortManager, float fReserveFactor, unsigned uiReserveMinimum) +{ + dxWorldProcessMemArena *pmaExistingArena = GetIslandsMemArena(); + dxWorldProcessMemArena *pmaNewMemArena = dxWorldProcessMemArena::ReallocateMemArena(pmaExistingArena, nMemoryRequirement, pmmMemortManager, fReserveFactor, uiReserveMinimum); + SetIslandsMemArena(pmaNewMemArena); + + pmaNewMemArena->ResetState(); + + return pmaNewMemArena; +} + +bool dxWorldProcessContext::ReallocateStepperMemArenas( + dxWorld *world, unsigned nIslandThreadsCount, sizeint nMemoryRequirement, + const dxWorldProcessMemoryManager *pmmMemortManager, float fReserveFactor, unsigned uiReserveMinimum) +{ + dxWorldProcessMemArena *pmaRebuiltArenasHead = NULL, *pmaRebuiltArenasTail = NULL; + dxWorldProcessMemArena *pmaExistingArenas = GetStepperArenasList(); + unsigned nArenasToProcess = nIslandThreadsCount; + + (void)world; // unused + + // NOTE! + // The list is reallocated in a way to assure the largest arenas are at end + // and if number of threads decreases they will be freed first of all. + + while (true) + { + if (nArenasToProcess == 0) + { + FreeArenasList(pmaExistingArenas); + break; + } + + dxWorldProcessMemArena *pmaOldMemArena = pmaExistingArenas; + + if (pmaExistingArenas != NULL) + { + pmaExistingArenas = pmaExistingArenas->GetNextMemArena(); + } + else + { + // If existing arenas ended, terminate and erase tail so that new arenas + // would be appended to list head. + if (pmaRebuiltArenasTail != NULL) + { + pmaRebuiltArenasTail->SetNextMemArena(NULL); + pmaRebuiltArenasTail = NULL; + } + } + + dxWorldProcessMemArena *pmaNewMemArena = dxWorldProcessMemArena::ReallocateMemArena(pmaOldMemArena, nMemoryRequirement, pmmMemortManager, fReserveFactor, uiReserveMinimum); + + if (pmaNewMemArena != NULL) + { + // Append reallocated arenas to list tail while old arenas still exist... + if (pmaRebuiltArenasTail != NULL) + { + pmaRebuiltArenasTail->SetNextMemArena(pmaNewMemArena); + pmaRebuiltArenasTail = pmaNewMemArena; + } + else if (pmaRebuiltArenasHead == NULL) + { + pmaRebuiltArenasHead = pmaNewMemArena; + pmaRebuiltArenasTail = pmaNewMemArena; + } + // ...and append them to list head if those are additional arenas created + else + { + pmaNewMemArena->SetNextMemArena(pmaRebuiltArenasHead); + pmaRebuiltArenasHead = pmaNewMemArena; + } + + --nArenasToProcess; + } + else if (pmaOldMemArena == NULL) + { + break; + } + } + + if (pmaRebuiltArenasTail != NULL) + { + pmaRebuiltArenasTail->SetNextMemArena(NULL); + } + + SetStepperArenasList(pmaRebuiltArenasHead); + + bool bResult = nArenasToProcess == 0; + return bResult; +} + +void dxWorldProcessContext::FreeArenasList(dxWorldProcessMemArena *pmaExistingArenas) +{ + while (pmaExistingArenas != NULL) + { + dxWorldProcessMemArena *pmaCurrentMemArena = pmaExistingArenas; + pmaExistingArenas = pmaExistingArenas->GetNextMemArena(); + + dxWorldProcessMemArena::FreeMemArena(pmaCurrentMemArena); + } +} + +dxWorldProcessMemArena *dxWorldProcessContext::GetStepperArenasHead() const +{ + return m_pmaStepperArenas; +} + +bool dxWorldProcessContext::TryExtractingStepperArenasHead(dxWorldProcessMemArena *pmaHeadInstance) +{ + dxWorldProcessMemArena *pmaNextInstance = pmaHeadInstance->GetNextMemArena(); + return ThrsafeCompareExchangePointer((volatile atomicptr *)&m_pmaStepperArenas, (atomicptr)pmaHeadInstance, (atomicptr)pmaNextInstance); +} + +bool dxWorldProcessContext::TryInsertingStepperArenasHead(dxWorldProcessMemArena *pmaArenaInstance, dxWorldProcessMemArena *pmaExistingHead) +{ + return ThrsafeCompareExchangePointer((volatile atomicptr *)&m_pmaStepperArenas, (atomicptr)pmaExistingHead, (atomicptr)pmaArenaInstance); +} + + +void dxWorldProcessContext::LockForAddLimotSerialization() +{ + m_pswObjectsAllocWorld->LockMutexGroupMutex(m_pmgStepperMutexGroup, dxPCM_STEPPER_ADDLIMOT_SERIALIZE); +} + +void dxWorldProcessContext::UnlockForAddLimotSerialization() +{ + m_pswObjectsAllocWorld->UnlockMutexGroupMutex(m_pmgStepperMutexGroup, dxPCM_STEPPER_ADDLIMOT_SERIALIZE); +} + + +void dxWorldProcessContext::LockForStepbodySerialization() +{ + m_pswObjectsAllocWorld->LockMutexGroupMutex(m_pmgStepperMutexGroup, dxPCM_STEPPER_STEPBODY_SERIALIZE); +} + +void dxWorldProcessContext::UnlockForStepbodySerialization() +{ + m_pswObjectsAllocWorld->UnlockMutexGroupMutex(m_pmgStepperMutexGroup, dxPCM_STEPPER_STEPBODY_SERIALIZE); +} + + +//**************************************************************************** +// Threading call contexts + +struct dxSingleIslandCallContext; + +struct dxIslandsProcessingCallContext +{ + dxIslandsProcessingCallContext(dxWorld *world, const dxWorldProcessIslandsInfo &islandsInfo, dReal stepSize, dstepper_fn_t stepper): + m_world(world), m_islandsInfo(islandsInfo), m_stepSize(stepSize), m_stepper(stepper), + m_groupReleasee(NULL), m_islandToProcessStorage(0), m_stepperAllowedThreads(0) + { + } + + void AssignGroupReleasee(dCallReleaseeID groupReleasee) { m_groupReleasee = groupReleasee; } + void SetStepperAllowedThreads(unsigned allowedThreadsLimit) { m_stepperAllowedThreads = allowedThreadsLimit; } + + static int ThreadedProcessGroup_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee); + bool ThreadedProcessGroup(); + + static int ThreadedProcessJobStart_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee); + void ThreadedProcessJobStart(); + + static int ThreadedProcessIslandSearch_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee); + void ThreadedProcessIslandSearch(dxSingleIslandCallContext *stepperCallContext); + + static int ThreadedProcessIslandStepper_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee); + void ThreadedProcessIslandStepper(dxSingleIslandCallContext *stepperCallContext); + + sizeint ObtainNextIslandToBeProcessed(sizeint islandsCount); + + dxWorld *const m_world; + dxWorldProcessIslandsInfo const &m_islandsInfo; + dReal const m_stepSize; + dstepper_fn_t const m_stepper; + dCallReleaseeID m_groupReleasee; + sizeint volatile m_islandToProcessStorage; + unsigned m_stepperAllowedThreads; +}; + + +struct dxSingleIslandCallContext +{ + dxSingleIslandCallContext(dxIslandsProcessingCallContext *islandsProcessingContext, + dxWorldProcessMemArena *stepperArena, void *arenaInitialState, + dxBody *const *islandBodiesStart, dxJoint *const *islandJointsStart): + m_islandsProcessingContext(islandsProcessingContext), m_islandIndex(0), + m_stepperArena(stepperArena), m_arenaInitialState(arenaInitialState), + m_stepperCallContext(islandsProcessingContext->m_world, islandsProcessingContext->m_stepSize, islandsProcessingContext->m_stepperAllowedThreads, stepperArena, islandBodiesStart, islandJointsStart) + { + } + + void AssignIslandSearchProgress(sizeint islandIndex) + { + m_islandIndex = islandIndex; + } + + void AssignIslandSelection(dxBody *const *islandBodiesStart, dxJoint *const *islandJointsStart, + unsigned islandBodiesCount, unsigned islandJointsCount) + { + m_stepperCallContext.AssignIslandSelection(islandBodiesStart, islandJointsStart, islandBodiesCount, islandJointsCount); + } + + dxBody *const *GetSelectedIslandBodiesEnd() const { return m_stepperCallContext.GetSelectedIslandBodiesEnd(); } + dxJoint *const *GetSelectedIslandJointsEnd() const { return m_stepperCallContext.GetSelectedIslandJointsEnd(); } + + void RestoreSavedMemArenaStateForStepper() + { + m_stepperArena->RestoreState(m_arenaInitialState); + } + + void AssignStepperCallFinalReleasee(dCallReleaseeID finalReleasee) + { + m_stepperCallContext.AssignStepperCallFinalReleasee(finalReleasee); + } + + dxIslandsProcessingCallContext *m_islandsProcessingContext; + sizeint m_islandIndex; + dxWorldProcessMemArena *m_stepperArena; + void *m_arenaInitialState; + dxStepperProcessingCallContext m_stepperCallContext; +}; + + +//**************************************************************************** +// Auto disabling + +void dInternalHandleAutoDisabling (dxWorld *world, dReal stepsize) +{ + dxBody *bb; + for ( bb=world->firstbody; bb; bb=(dxBody*)bb->next ) + { + // don't freeze objects mid-air (patch 1586738) + if ( bb->firstjoint == NULL ) continue; + + // nothing to do unless this body is currently enabled and has + // the auto-disable flag set + if ( (bb->flags & (dxBodyAutoDisable|dxBodyDisabled)) != dxBodyAutoDisable ) continue; + + // if sampling / threshold testing is disabled, we can never sleep. + if ( bb->adis.average_samples == 0 ) continue; + + // + // see if the body is idle + // + +#ifndef dNODEBUG + // sanity check + if ( bb->average_counter >= bb->adis.average_samples ) + { + dUASSERT( bb->average_counter < bb->adis.average_samples, "buffer overflow" ); + + // something is going wrong, reset the average-calculations + bb->average_ready = 0; // not ready for average calculation + bb->average_counter = 0; // reset the buffer index + } +#endif // dNODEBUG + + // sample the linear and angular velocity + bb->average_lvel_buffer[bb->average_counter][0] = bb->lvel[0]; + bb->average_lvel_buffer[bb->average_counter][1] = bb->lvel[1]; + bb->average_lvel_buffer[bb->average_counter][2] = bb->lvel[2]; + bb->average_avel_buffer[bb->average_counter][0] = bb->avel[0]; + bb->average_avel_buffer[bb->average_counter][1] = bb->avel[1]; + bb->average_avel_buffer[bb->average_counter][2] = bb->avel[2]; + bb->average_counter++; + + // buffer ready test + if ( bb->average_counter >= bb->adis.average_samples ) + { + bb->average_counter = 0; // fill the buffer from the beginning + bb->average_ready = 1; // this body is ready now for average calculation + } + + int idle = 0; // Assume it's in motion unless we have samples to disprove it. + + // enough samples? + if ( bb->average_ready ) + { + idle = 1; // Initial assumption: IDLE + + // the sample buffers are filled and ready for calculation + dVector3 average_lvel, average_avel; + + // Store first velocity samples + average_lvel[0] = bb->average_lvel_buffer[0][0]; + average_avel[0] = bb->average_avel_buffer[0][0]; + average_lvel[1] = bb->average_lvel_buffer[0][1]; + average_avel[1] = bb->average_avel_buffer[0][1]; + average_lvel[2] = bb->average_lvel_buffer[0][2]; + average_avel[2] = bb->average_avel_buffer[0][2]; + + // If we're not in "instantaneous mode" + if ( bb->adis.average_samples > 1 ) + { + // add remaining velocities together + for ( unsigned int i = 1; i < bb->adis.average_samples; ++i ) + { + average_lvel[0] += bb->average_lvel_buffer[i][0]; + average_avel[0] += bb->average_avel_buffer[i][0]; + average_lvel[1] += bb->average_lvel_buffer[i][1]; + average_avel[1] += bb->average_avel_buffer[i][1]; + average_lvel[2] += bb->average_lvel_buffer[i][2]; + average_avel[2] += bb->average_avel_buffer[i][2]; + } + + // make average + dReal r1 = dReal( 1.0 ) / dReal( bb->adis.average_samples ); + + average_lvel[0] *= r1; + average_avel[0] *= r1; + average_lvel[1] *= r1; + average_avel[1] *= r1; + average_lvel[2] *= r1; + average_avel[2] *= r1; + } + + // threshold test + dReal av_lspeed, av_aspeed; + av_lspeed = dCalcVectorDot3( average_lvel, average_lvel ); + if ( av_lspeed > bb->adis.linear_average_threshold ) + { + idle = 0; // average linear velocity is too high for idle + } + else + { + av_aspeed = dCalcVectorDot3( average_avel, average_avel ); + if ( av_aspeed > bb->adis.angular_average_threshold ) + { + idle = 0; // average angular velocity is too high for idle + } + } + } + + // if it's idle, accumulate steps and time. + // these counters won't overflow because this code doesn't run for disabled bodies. + if (idle) { + bb->adis_stepsleft--; + bb->adis_timeleft -= stepsize; + } + else { + // Reset countdowns + bb->adis_stepsleft = bb->adis.idle_steps; + bb->adis_timeleft = bb->adis.idle_time; + } + + // disable the body if it's idle for a long enough time + if ( bb->adis_stepsleft <= 0 && bb->adis_timeleft <= 0 ) + { + bb->flags |= dxBodyDisabled; // set the disable flag + + // disabling bodies should also include resetting the velocity + // should prevent jittering in big "islands" + bb->lvel[0] = 0; + bb->lvel[1] = 0; + bb->lvel[2] = 0; + bb->avel[0] = 0; + bb->avel[1] = 0; + bb->avel[2] = 0; + } + } +} + + +//**************************************************************************** +// body rotation + +// return sin(x)/x. this has a singularity at 0 so special handling is needed +// for small arguments. + +static inline dReal sinc (dReal x) +{ + // if |x| < 1e-4 then use a taylor series expansion. this two term expansion + // is actually accurate to one LS bit within this range if double precision + // is being used - so don't worry! + if (dFabs(x) < 1.0e-4) return REAL(1.0) - x*x*REAL(0.166666666666666666667); + else return dSin(x)/x; +} + + +// given a body b, apply its linear and angular rotation over the time +// interval h, thereby adjusting its position and orientation. + +void dxStepBody (dxBody *b, dReal h) +{ + // cap the angular velocity + if (b->flags & dxBodyMaxAngularSpeed) { + const dReal max_ang_speed = b->max_angular_speed; + const dReal aspeed = dCalcVectorDot3( b->avel, b->avel ); + if (aspeed > max_ang_speed*max_ang_speed) { + const dReal coef = max_ang_speed/dSqrt(aspeed); + dScaleVector3(b->avel, coef); + } + } + // end of angular velocity cap + + + // handle linear velocity + for (unsigned int j=0; j<3; j++) b->posr.pos[j] += h * b->lvel[j]; + + if (b->flags & dxBodyFlagFiniteRotation) { + dVector3 irv; // infitesimal rotation vector + dQuaternion q; // quaternion for finite rotation + + if (b->flags & dxBodyFlagFiniteRotationAxis) { + // split the angular velocity vector into a component along the finite + // rotation axis, and a component orthogonal to it. + dVector3 frv; // finite rotation vector + dReal k = dCalcVectorDot3 (b->finite_rot_axis,b->avel); + frv[0] = b->finite_rot_axis[0] * k; + frv[1] = b->finite_rot_axis[1] * k; + frv[2] = b->finite_rot_axis[2] * k; + irv[0] = b->avel[0] - frv[0]; + irv[1] = b->avel[1] - frv[1]; + irv[2] = b->avel[2] - frv[2]; + + // make a rotation quaternion q that corresponds to frv * h. + // compare this with the full-finite-rotation case below. + h *= REAL(0.5); + dReal theta = k * h; + q[0] = dCos(theta); + dReal s = sinc(theta) * h; + q[1] = frv[0] * s; + q[2] = frv[1] * s; + q[3] = frv[2] * s; + } + else { + // make a rotation quaternion q that corresponds to w * h + dReal wlen = dSqrt (b->avel[0]*b->avel[0] + b->avel[1]*b->avel[1] + + b->avel[2]*b->avel[2]); + h *= REAL(0.5); + dReal theta = wlen * h; + q[0] = dCos(theta); + dReal s = sinc(theta) * h; + q[1] = b->avel[0] * s; + q[2] = b->avel[1] * s; + q[3] = b->avel[2] * s; + } + + // do the finite rotation + dQuaternion q2; + dQMultiply0 (q2,q,b->q); + for (unsigned int j=0; j<4; j++) b->q[j] = q2[j]; + + // do the infitesimal rotation if required + if (b->flags & dxBodyFlagFiniteRotationAxis) { + dReal dq[4]; + dWtoDQ (irv,b->q,dq); + for (unsigned int j=0; j<4; j++) b->q[j] += h * dq[j]; + } + } + else { + // the normal way - do an infitesimal rotation + dReal dq[4]; + dWtoDQ (b->avel,b->q,dq); + for (unsigned int j=0; j<4; j++) b->q[j] += h * dq[j]; + } + + // normalize the quaternion and convert it to a rotation matrix + dNormalize4 (b->q); + dQtoR (b->q,b->posr.R); + + // notify all attached geoms that this body has moved + dxWorldProcessContext *world_process_context = b->world->unsafeGetWorldProcessingContext(); + for (dxGeom *geom = b->geom; geom; geom = dGeomGetBodyNext (geom)) { + world_process_context->LockForStepbodySerialization(); + dGeomMoved (geom); + world_process_context->UnlockForStepbodySerialization(); + } + + // notify the user + if (b->moved_callback != NULL) { + b->moved_callback(b); + } + + // damping + if (b->flags & dxBodyLinearDamping) { + const dReal lin_threshold = b->dampingp.linear_threshold; + const dReal lin_speed = dCalcVectorDot3( b->lvel, b->lvel ); + if ( lin_speed > lin_threshold) { + const dReal k = 1 - b->dampingp.linear_scale; + dScaleVector3(b->lvel, k); + } + } + if (b->flags & dxBodyAngularDamping) { + const dReal ang_threshold = b->dampingp.angular_threshold; + const dReal ang_speed = dCalcVectorDot3( b->avel, b->avel ); + if ( ang_speed > ang_threshold) { + const dReal k = 1 - b->dampingp.angular_scale; + dScaleVector3(b->avel, k); + } + } +} + + +//**************************************************************************** +// island processing + +enum dxISLANDSIZESELEMENT +{ + dxISE_BODIES_COUNT, + dxISE_JOINTS_COUNT, + + dxISE__MAX +}; + +// This estimates dynamic memory requirements for dxProcessIslands +static sizeint EstimateIslandProcessingMemoryRequirements(dxWorld *world) +{ + sizeint res = 0; + + sizeint islandcounts = dEFFICIENT_SIZE((sizeint)(unsigned)world->nb * 2 * sizeof(int)); + res += islandcounts; + + sizeint bodiessize = dEFFICIENT_SIZE((sizeint)(unsigned)world->nb * sizeof(dxBody*)); + sizeint jointssize = dEFFICIENT_SIZE((sizeint)(unsigned)world->nj * sizeof(dxJoint*)); + res += bodiessize + jointssize; + + sizeint sesize = (bodiessize < jointssize) ? bodiessize : jointssize; + res += sesize; + + return res; +} + +static sizeint BuildIslandsAndEstimateStepperMemoryRequirements( + dxWorldProcessIslandsInfo &islandsinfo, dxWorldProcessMemArena *memarena, + dxWorld *world, dReal stepsize, dmemestimate_fn_t stepperestimate) +{ + sizeint maxreq = 0; + + // handle auto-disabling of bodies + dInternalHandleAutoDisabling (world,stepsize); + + unsigned int nb = world->nb, nj = world->nj; + // Make array for island body/joint counts + unsigned int *islandsizes = memarena->AllocateArray<unsigned int>(2 * (sizeint)nb); + unsigned int *sizescurr; + + // make arrays for body and joint lists (for a single island) to go into + dxBody **body = memarena->AllocateArray<dxBody *>(nb); + dxJoint **joint = memarena->AllocateArray<dxJoint *>(nj); + + BEGIN_STATE_SAVE(memarena, stackstate) { + // allocate a stack of unvisited bodies in the island. the maximum size of + // the stack can be the lesser of the number of bodies or joints, because + // new bodies are only ever added to the stack by going through untagged + // joints. all the bodies in the stack must be tagged! + unsigned int stackalloc = (nj < nb) ? nj : nb; + dxBody **stack = memarena->AllocateArray<dxBody *>(stackalloc); + + { + // set all body/joint tags to 0 + for (dxBody *b=world->firstbody; b; b=(dxBody*)b->next) b->tag = 0; + for (dxJoint *j=world->firstjoint; j; j=(dxJoint*)j->next) j->tag = 0; + } + + sizescurr = islandsizes; + dxBody **bodystart = body; + dxJoint **jointstart = joint; + for (dxBody *bb=world->firstbody; bb; bb=(dxBody*)bb->next) { + // get bb = the next enabled, untagged body, and tag it + if (!bb->tag) { + if (!(bb->flags & dxBodyDisabled)) { + bb->tag = 1; + + dxBody **bodycurr = bodystart; + dxJoint **jointcurr = jointstart; + + // tag all bodies and joints starting from bb. + *bodycurr++ = bb; + + unsigned int stacksize = 0; + dxBody *b = bb; + + while (true) { + // traverse and tag all body's joints, add untagged connected bodies + // to stack + for (dxJointNode *n=b->firstjoint; n; n=n->next) { + dxJoint *njoint = n->joint; + if (!njoint->tag) { + if (njoint->isEnabled()) { + njoint->tag = 1; + *jointcurr++ = njoint; + + dxBody *nbody = n->body; + // Body disabled flag is not checked here. This is how auto-enable works. + if (nbody && nbody->tag <= 0) { + nbody->tag = 1; + // Make sure all bodies are in the enabled state. + nbody->flags &= ~dxBodyDisabled; + stack[stacksize++] = nbody; + } + } else { + njoint->tag = -1; // Used in Step to prevent search over disabled joints (not needed for QuickStep so far) + } + } + } + dIASSERT(stacksize <= (unsigned int)world->nb); + dIASSERT(stacksize <= (unsigned int)world->nj); + + if (stacksize == 0) { + break; + } + + b = stack[--stacksize]; // pop body off stack + *bodycurr++ = b; // put body on body list + } + + unsigned int bcount = (unsigned int)(bodycurr - bodystart); + unsigned int jcount = (unsigned int)(jointcurr - jointstart); + dIASSERT((sizeint)(bodycurr - bodystart) <= (sizeint)UINT_MAX); + dIASSERT((sizeint)(jointcurr - jointstart) <= (sizeint)UINT_MAX); + + sizescurr[dxISE_BODIES_COUNT] = bcount; + sizescurr[dxISE_JOINTS_COUNT] = jcount; + sizescurr += dxISE__MAX; + + sizeint islandreq = stepperestimate(bodystart, bcount, jointstart, jcount); + maxreq = (maxreq > islandreq) ? maxreq : islandreq; + + bodystart = bodycurr; + jointstart = jointcurr; + } else { + bb->tag = -1; // Not used so far (assigned to retain consistency with joints) + } + } + } + } END_STATE_SAVE(memarena, stackstate); + +# ifndef dNODEBUG + // if debugging, check that all objects (except for disabled bodies, + // unconnected joints, and joints that are connected to disabled bodies) + // were tagged. + { + for (dxBody *b=world->firstbody; b; b=(dxBody*)b->next) { + if (b->flags & dxBodyDisabled) { + if (b->tag > 0) dDebug (0,"disabled body tagged"); + } + else { + if (b->tag <= 0) dDebug (0,"enabled body not tagged"); + } + } + for (dxJoint *j=world->firstjoint; j; j=(dxJoint*)j->next) { + if ( (( j->node[0].body && (j->node[0].body->flags & dxBodyDisabled)==0 ) || + (j->node[1].body && (j->node[1].body->flags & dxBodyDisabled)==0) ) + && + j->isEnabled() ) { + if (j->tag <= 0) dDebug (0,"attached enabled joint not tagged"); + } + else { + if (j->tag > 0) dDebug (0,"unattached or disabled joint tagged"); + } + } + } +# endif + + sizeint islandcount = ((sizeint)(sizescurr - islandsizes) / dxISE__MAX); + islandsinfo.AssignInfo(islandcount, islandsizes, body, joint); + + return maxreq; +} + +static unsigned EstimateIslandProcessingSimultaneousCallsMaximumCount(unsigned activeThreadCount, unsigned islandsAllowedThreadCount, + unsigned stepperAllowedThreadCount, dmaxcallcountestimate_fn_t maxCallCountEstimator) +{ + unsigned stepperCallsMaximum = maxCallCountEstimator(activeThreadCount, stepperAllowedThreadCount); + unsigned islandsIntermediateCallsMaximum = (1 + 2); // ThreadedProcessIslandSearch_Callback + (ThreadedProcessIslandStepper_Callback && ThreadedProcessIslandSearch_Callback) + + unsigned result = + 1 // ThreadedProcessGroup_Callback + + islandsAllowedThreadCount * dMAX(stepperCallsMaximum, islandsIntermediateCallsMaximum) + + dMIN(islandsAllowedThreadCount, (unsigned)(activeThreadCount - islandsAllowedThreadCount)) // ThreadedProcessJobStart_Callback + /*...the end*/; + return result; +} + +// this groups all joints and bodies in a world into islands. all objects +// in an island are reachable by going through connected bodies and joints. +// each island can be simulated separately. +// note that joints that are not attached to anything will not be included +// in any island, an so they do not affect the simulation. +// +// this function starts new island from unvisited bodies. however, it will +// never start a new islands from a disabled body. thus islands of disabled +// bodies will not be included in the simulation. disabled bodies are +// re-enabled if they are found to be part of an active island. +bool dxProcessIslands (dxWorld *world, const dxWorldProcessIslandsInfo &islandsInfo, + dReal stepSize, dstepper_fn_t stepper, dmaxcallcountestimate_fn_t maxCallCountEstimator) +{ + bool result = false; + + dxIslandsProcessingCallContext callContext(world, islandsInfo, stepSize, stepper); + + do { + dxStepWorkingMemory *wmem = world->wmem; + dIASSERT(wmem != NULL); + dxWorldProcessContext *context = wmem->GetWorldProcessingContext(); + dIASSERT(context != NULL); + dCallWaitID pcwGroupCallWait = context->GetIslandsSteppingWait(); + + int summaryFault = 0; + + unsigned activeThreadCount; + const unsigned islandsAllowedThreadCount = world->calculateIslandProcessingMaxThreadCount(&activeThreadCount); + dIASSERT(islandsAllowedThreadCount != 0); + dIASSERT(activeThreadCount >= islandsAllowedThreadCount); + + unsigned stepperAllowedThreadCount = islandsAllowedThreadCount; // For now, set stepper allowed threads equal to island stepping threads + + unsigned simultaneousCallsCount = EstimateIslandProcessingSimultaneousCallsMaximumCount(activeThreadCount, islandsAllowedThreadCount, stepperAllowedThreadCount, maxCallCountEstimator); + if (!world->PreallocateResourcesForThreadedCalls(simultaneousCallsCount)) { + break; + } + + dCallReleaseeID groupReleasee; + // First post a group call with dependency count set to number of expected threads + world->PostThreadedCall(&summaryFault, &groupReleasee, islandsAllowedThreadCount, NULL, pcwGroupCallWait, + &dxIslandsProcessingCallContext::ThreadedProcessGroup_Callback, (void *)&callContext, 0, "World Islands Stepping Group"); + + callContext.AssignGroupReleasee(groupReleasee); + callContext.SetStepperAllowedThreads(stepperAllowedThreadCount); + + // Summary fault flag may be omitted as any failures will automatically propagate to dependent releasee (i.e. to groupReleasee) + world->PostThreadedCallsGroup(NULL, islandsAllowedThreadCount, groupReleasee, + &dxIslandsProcessingCallContext::ThreadedProcessJobStart_Callback, (void *)&callContext, "World Islands Stepping Start"); + + // Wait until group completes (since jobs were the dependencies of the group the group is going to complete only after all the jobs end) + world->WaitThreadedCallExclusively(NULL, pcwGroupCallWait, NULL, "World Islands Stepping Wait"); + + if (summaryFault != 0) { + break; + } + + result = true; + } + while (false); + + return result; +} + + +int dxIslandsProcessingCallContext::ThreadedProcessGroup_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee) +{ + (void)callInstanceIndex; // unused + (void)callThisReleasee; // unused + return static_cast<dxIslandsProcessingCallContext *>(callContext)->ThreadedProcessGroup(); +} + +bool dxIslandsProcessingCallContext::ThreadedProcessGroup() +{ + // Do nothing - it's just a wrapper call + return true; +} + +int dxIslandsProcessingCallContext::ThreadedProcessJobStart_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee) +{ + (void)callInstanceIndex; // unused + (void)callThisReleasee; // unused + static_cast<dxIslandsProcessingCallContext *>(callContext)->ThreadedProcessJobStart(); + return true; +} + +void dxIslandsProcessingCallContext::ThreadedProcessJobStart() +{ + dxWorldProcessContext *context = m_world->unsafeGetWorldProcessingContext(); + + dxWorldProcessMemArena *stepperArena = context->ObtainStepperMemArena(); + dIASSERT(stepperArena != NULL && stepperArena->IsStructureValid()); + + const dxWorldProcessIslandsInfo &islandsInfo = m_islandsInfo; + dxBody *const *islandBodiesStart = islandsInfo.GetBodiesArray(); + dxJoint *const *islandJointsStart = islandsInfo.GetJointsArray(); + + dxSingleIslandCallContext *stepperCallContext = (dxSingleIslandCallContext *)stepperArena->AllocateBlock(sizeof(dxSingleIslandCallContext)); + // Save area state after context allocation to be restored for the stepper + void *arenaState = stepperArena->SaveState(); + new(stepperCallContext) dxSingleIslandCallContext(this, stepperArena, arenaState, islandBodiesStart, islandJointsStart); + + // Summary fault flag may be omitted as any failures will automatically propagate to dependent releasee (i.e. to m_groupReleasee) + m_world->PostThreadedCallForUnawareReleasee(NULL, NULL, 0, m_groupReleasee, NULL, + &dxIslandsProcessingCallContext::ThreadedProcessIslandSearch_Callback, (void *)stepperCallContext, 0, "World Islands Stepping Selection"); +} + +int dxIslandsProcessingCallContext::ThreadedProcessIslandSearch_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee) +{ + (void)callInstanceIndex; // unused + (void)callThisReleasee; // unused + dxSingleIslandCallContext *stepperCallContext = static_cast<dxSingleIslandCallContext *>(callContext); + stepperCallContext->m_islandsProcessingContext->ThreadedProcessIslandSearch(stepperCallContext); + return true; +} + +void dxIslandsProcessingCallContext::ThreadedProcessIslandSearch(dxSingleIslandCallContext *stepperCallContext) +{ + bool finalizeJob = false; + + const dxWorldProcessIslandsInfo &islandsInfo = m_islandsInfo; + unsigned int const *islandSizes = islandsInfo.GetIslandSizes(); + + const sizeint islandsCount = islandsInfo.GetIslandsCount(); + sizeint islandToProcess = ObtainNextIslandToBeProcessed(islandsCount); + + if (islandToProcess != islandsCount) { + // First time, the counts are zeros and on next passes, adding counts will skip island that has just been processed by stepper + dxBody *const *islandBodiesStart = stepperCallContext->GetSelectedIslandBodiesEnd(); + dxJoint *const *islandJointsStart = stepperCallContext->GetSelectedIslandJointsEnd(); + sizeint islandIndex = stepperCallContext->m_islandIndex; + + for (; ; ++islandIndex) { + unsigned int bcount = islandSizes[islandIndex * dxISE__MAX + dxISE_BODIES_COUNT]; + unsigned int jcount = islandSizes[islandIndex * dxISE__MAX + dxISE_JOINTS_COUNT]; + + if (islandIndex == islandToProcess) { + // Store selected island details + stepperCallContext->AssignIslandSelection(islandBodiesStart, islandJointsStart, bcount, jcount); + + // Store next island index to continue search from + ++islandIndex; + stepperCallContext->AssignIslandSearchProgress(islandIndex); + + // Restore saved stepper memory arena position + stepperCallContext->RestoreSavedMemArenaStateForStepper(); + + dCallReleaseeID nextSearchReleasee; + + // Summary fault flag may be omitted as any failures will automatically propagate to dependent releasee (i.e. to m_groupReleasee) + m_world->PostThreadedCallForUnawareReleasee(NULL, &nextSearchReleasee, 1, m_groupReleasee, NULL, + &dxIslandsProcessingCallContext::ThreadedProcessIslandSearch_Callback, (void *)stepperCallContext, 0, "World Islands Stepping Selection"); + + stepperCallContext->AssignStepperCallFinalReleasee(nextSearchReleasee); + + m_world->PostThreadedCall(NULL, NULL, 0, nextSearchReleasee, NULL, + &dxIslandsProcessingCallContext::ThreadedProcessIslandStepper_Callback, (void *)stepperCallContext, 0, "Island Stepping Job Start"); + + break; + } + + islandBodiesStart += bcount; + islandJointsStart += jcount; + } + } + else { + finalizeJob = true; + } + + if (finalizeJob) { + dxWorldProcessMemArena *stepperArena = stepperCallContext->m_stepperArena; + stepperCallContext->dxSingleIslandCallContext::~dxSingleIslandCallContext(); + + dxWorldProcessContext *context = m_world->unsafeGetWorldProcessingContext(); + context->ReturnStepperMemArena(stepperArena); + } +} + +int dxIslandsProcessingCallContext::ThreadedProcessIslandStepper_Callback(void *callContext, dcallindex_t callInstanceIndex, dCallReleaseeID callThisReleasee) +{ + (void)callInstanceIndex; // unused + (void)callThisReleasee; // unused + dxSingleIslandCallContext *stepperCallContext = static_cast<dxSingleIslandCallContext *>(callContext); + stepperCallContext->m_islandsProcessingContext->ThreadedProcessIslandStepper(stepperCallContext); + return true; +} + +void dxIslandsProcessingCallContext::ThreadedProcessIslandStepper(dxSingleIslandCallContext *stepperCallContext) +{ + m_stepper(&stepperCallContext->m_stepperCallContext); +} + +sizeint dxIslandsProcessingCallContext::ObtainNextIslandToBeProcessed(sizeint islandsCount) +{ + return ThrsafeIncrementSizeUpToLimit(&m_islandToProcessStorage, islandsCount); +} + + +//**************************************************************************** +// World processing context management + +dxWorldProcessMemArena *dxWorldProcessMemArena::ReallocateMemArena ( + dxWorldProcessMemArena *oldarena, sizeint memreq, + const dxWorldProcessMemoryManager *memmgr, float rsrvfactor, unsigned rsrvminimum) +{ + dxWorldProcessMemArena *arena = oldarena; + bool allocsuccess = false; + + sizeint nOldArenaSize; + void *pOldArenaBuffer; + + do { + sizeint oldmemsize = oldarena ? oldarena->GetMemorySize() : 0; + if (oldarena == NULL || oldmemsize < memreq) { + nOldArenaSize = oldarena ? dxWorldProcessMemArena::MakeArenaSize(oldmemsize) : 0; + pOldArenaBuffer = oldarena ? oldarena->m_pArenaBegin : NULL; + + if (!dxWorldProcessMemArena::IsArenaPossible(memreq)) { + break; + } + + sizeint arenareq = dxWorldProcessMemArena::MakeArenaSize(memreq); + sizeint arenareq_with_reserve = AdjustArenaSizeForReserveRequirements(arenareq, rsrvfactor, rsrvminimum); + sizeint memreq_with_reserve = memreq + (arenareq_with_reserve - arenareq); + + if (oldarena != NULL) { + oldarena->m_pArenaMemMgr->m_fnFree(pOldArenaBuffer, nOldArenaSize); + oldarena = NULL; + + // Zero variables to avoid another freeing on exit + pOldArenaBuffer = NULL; + nOldArenaSize = 0; + } + + // Allocate new arena + void *pNewArenaBuffer = memmgr->m_fnAlloc(arenareq_with_reserve); + if (pNewArenaBuffer == NULL) { + break; + } + + arena = (dxWorldProcessMemArena *)dEFFICIENT_PTR(pNewArenaBuffer); + + void *blockbegin = dEFFICIENT_PTR(arena + 1); + void *blockend = dOFFSET_EFFICIENTLY(blockbegin, memreq_with_reserve); + + arena->m_pAllocBegin = blockbegin; + arena->m_pAllocEnd = blockend; + arena->m_pArenaBegin = pNewArenaBuffer; + arena->m_pAllocCurrentOrNextArena = NULL; + arena->m_pArenaMemMgr = memmgr; + } + + allocsuccess = true; + } + while (false); + + if (!allocsuccess) { + if (pOldArenaBuffer != NULL) { + dIASSERT(oldarena != NULL); + oldarena->m_pArenaMemMgr->m_fnFree(pOldArenaBuffer, nOldArenaSize); + } + arena = NULL; + } + + return arena; +} + +void dxWorldProcessMemArena::FreeMemArena (dxWorldProcessMemArena *arena) +{ + sizeint memsize = arena->GetMemorySize(); + sizeint arenasize = dxWorldProcessMemArena::MakeArenaSize(memsize); + + void *pArenaBegin = arena->m_pArenaBegin; + arena->m_pArenaMemMgr->m_fnFree(pArenaBegin, arenasize); +} + + +sizeint dxWorldProcessMemArena::AdjustArenaSizeForReserveRequirements(sizeint arenareq, float rsrvfactor, unsigned rsrvminimum) +{ + float scaledarena = arenareq * rsrvfactor; + sizeint adjustedarena = (scaledarena < SIZE_MAX) ? (sizeint)scaledarena : SIZE_MAX; + sizeint boundedarena = (adjustedarena > rsrvminimum) ? adjustedarena : (sizeint)rsrvminimum; + return dEFFICIENT_SIZE(boundedarena); +} + + +bool dxReallocateWorldProcessContext (dxWorld *world, dxWorldProcessIslandsInfo &islandsInfo, + dReal stepSize, dmemestimate_fn_t stepperEstimate) +{ + bool result = false; + + do + { + dxStepWorkingMemory *wmem = AllocateOnDemand(world->wmem); + if (wmem == NULL) + { + break; + } + + dxWorldProcessContext *context = wmem->SureGetWorldProcessingContext(); + if (context == NULL) + { + break; + } + + if (!context->EnsureStepperSyncObjectsAreAllocated(world)) + { + break; + } + + const dxWorldProcessMemoryReserveInfo *reserveInfo = wmem->SureGetMemoryReserveInfo(); + const dxWorldProcessMemoryManager *memmgr = wmem->SureGetMemoryManager(); + + sizeint islandsReq = EstimateIslandProcessingMemoryRequirements(world); + dIASSERT(islandsReq == dEFFICIENT_SIZE(islandsReq)); + + dxWorldProcessMemArena *islandsArena = context->ReallocateIslandsMemArena(islandsReq, memmgr, 1.0f, reserveInfo->m_uiReserveMinimum); + if (islandsArena == NULL) + { + break; + } + dIASSERT(islandsArena->IsStructureValid()); + + sizeint stepperReq = BuildIslandsAndEstimateStepperMemoryRequirements(islandsInfo, islandsArena, world, stepSize, stepperEstimate); + dIASSERT(stepperReq == dEFFICIENT_SIZE(stepperReq)); + + sizeint stepperReqWithCallContext = stepperReq + dEFFICIENT_SIZE(sizeof(dxSingleIslandCallContext)); + + unsigned islandThreadsCount = world->calculateIslandProcessingMaxThreadCount(); + if (!context->ReallocateStepperMemArenas(world, islandThreadsCount, stepperReqWithCallContext, + memmgr, reserveInfo->m_fReserveFactor, reserveInfo->m_uiReserveMinimum)) + { + break; + } + + result = true; + } + while (false); + + return result; +} + +dxWorldProcessMemArena *dxAllocateTemporaryWorldProcessMemArena( + sizeint memreq, const dxWorldProcessMemoryManager *memmgr/*=NULL*/, const dxWorldProcessMemoryReserveInfo *reserveinfo/*=NULL*/) +{ + const dxWorldProcessMemoryManager *surememmgr = memmgr ? memmgr : &g_WorldProcessMallocMemoryManager; + const dxWorldProcessMemoryReserveInfo *surereserveinfo = reserveinfo ? reserveinfo : &g_WorldProcessDefaultReserveInfo; + dxWorldProcessMemArena *arena = dxWorldProcessMemArena::ReallocateMemArena(NULL, memreq, surememmgr, surereserveinfo->m_fReserveFactor, surereserveinfo->m_uiReserveMinimum); + return arena; +} + +void dxFreeTemporaryWorldProcessMemArena(dxWorldProcessMemArena *arena) +{ + dxWorldProcessMemArena::FreeMemArena(arena); +} + diff --git a/libs/ode-0.16.1/ode/src/util.h b/libs/ode-0.16.1/ode/src/util.h new file mode 100644 index 0000000..ca222ac --- /dev/null +++ b/libs/ode-0.16.1/ode/src/util.h @@ -0,0 +1,440 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_UTIL_H_ +#define _ODE_UTIL_H_ + +#include "objects.h" +#include "common.h" + + +/* utility */ + +void dInternalHandleAutoDisabling (dxWorld *world, dReal stepsize); +void dxStepBody (dxBody *b, dReal h); + + +struct dxWorldProcessMemoryManager: + public dBase +{ + typedef void *(*alloc_block_fn_t)(sizeint block_size); + typedef void *(*shrink_block_fn_t)(void *block_pointer, sizeint block_current_size, sizeint block_smaller_size); + typedef void (*free_block_fn_t)(void *block_pointer, sizeint block_current_size); + + dxWorldProcessMemoryManager(alloc_block_fn_t fnAlloc, shrink_block_fn_t fnShrink, free_block_fn_t fnFree) + { + Assign(fnAlloc, fnShrink, fnFree); + } + + void Assign(alloc_block_fn_t fnAlloc, shrink_block_fn_t fnShrink, free_block_fn_t fnFree) + { + m_fnAlloc = fnAlloc; + m_fnShrink = fnShrink; + m_fnFree = fnFree; + } + + alloc_block_fn_t m_fnAlloc; + shrink_block_fn_t m_fnShrink; + free_block_fn_t m_fnFree; +}; + +extern dxWorldProcessMemoryManager g_WorldProcessMallocMemoryManager; + +struct dxWorldProcessMemoryReserveInfo: + public dBase +{ + dxWorldProcessMemoryReserveInfo(float fReserveFactor, unsigned uiReserveMinimum) + { + Assign(fReserveFactor, uiReserveMinimum); + } + + void Assign(float fReserveFactor, unsigned uiReserveMinimum) + { + m_fReserveFactor = fReserveFactor; + m_uiReserveMinimum = uiReserveMinimum; + } + + float m_fReserveFactor; // Use float as precision does not matter here + unsigned m_uiReserveMinimum; +}; + +extern dxWorldProcessMemoryReserveInfo g_WorldProcessDefaultReserveInfo; + + +class dxWorldProcessMemArena: + private dBase // new/delete must not be called for this class +{ +public: +#define BUFFER_TO_ARENA_EXTRA (EFFICIENT_ALIGNMENT + dEFFICIENT_SIZE(sizeof(dxWorldProcessMemArena))) + static bool IsArenaPossible(sizeint nBufferSize) + { + return SIZE_MAX - BUFFER_TO_ARENA_EXTRA >= nBufferSize; // This ensures there will be no overflow + } + + static sizeint MakeBufferSize(sizeint nArenaSize) + { + return nArenaSize - BUFFER_TO_ARENA_EXTRA; + } + + static sizeint MakeArenaSize(sizeint nBufferSize) + { + return BUFFER_TO_ARENA_EXTRA + nBufferSize; + } +#undef BUFFER_TO_ARENA_EXTRA + + bool IsStructureValid() const + { + return m_pAllocBegin != NULL && m_pAllocEnd != NULL && m_pAllocBegin <= m_pAllocEnd + && (m_pAllocCurrentOrNextArena == NULL || m_pAllocCurrentOrNextArena == m_pAllocBegin) + && m_pArenaBegin != NULL && m_pArenaBegin <= m_pAllocBegin; + } + + sizeint GetMemorySize() const + { + return (sizeint)m_pAllocEnd - (sizeint)m_pAllocBegin; + } + + void *SaveState() const + { + return m_pAllocCurrentOrNextArena; + } + + void RestoreState(void *state) + { + m_pAllocCurrentOrNextArena = state; + } + + void ResetState() + { + m_pAllocCurrentOrNextArena = m_pAllocBegin; + } + + void *PeekBufferRemainder() const + { + return m_pAllocCurrentOrNextArena; + } + + void *AllocateBlock(sizeint size) + { + void *arena = m_pAllocCurrentOrNextArena; + m_pAllocCurrentOrNextArena = dOFFSET_EFFICIENTLY(arena, size); + dIASSERT(m_pAllocCurrentOrNextArena <= m_pAllocEnd); + dIASSERT(dEFFICIENT_PTR(arena) == arena); + + return arena; + } + + void *AllocateOveralignedBlock(sizeint size, unsigned alignment) + { + void *arena = m_pAllocCurrentOrNextArena; + m_pAllocCurrentOrNextArena = dOFFSET_OVERALIGNEDLY(arena, size, alignment); + dIASSERT(m_pAllocCurrentOrNextArena <= m_pAllocEnd); + + void *block = dOVERALIGNED_PTR(arena, alignment); + return block; + } + + template<typename ElementType> + ElementType *AllocateArray(sizeint count) + { + return (ElementType *)AllocateBlock(count * sizeof(ElementType)); + } + + template<typename ElementType> + ElementType *AllocateOveralignedArray(sizeint count, unsigned alignment) + { + return (ElementType *)AllocateOveralignedBlock(count * sizeof(ElementType), alignment); + } + + template<typename ElementType> + void ShrinkArray(ElementType *arr, sizeint oldcount, sizeint newcount) + { + dIASSERT(newcount <= oldcount); + dIASSERT(dOFFSET_EFFICIENTLY(arr, oldcount * sizeof(ElementType)) == m_pAllocCurrentOrNextArena); + m_pAllocCurrentOrNextArena = dOFFSET_EFFICIENTLY(arr, newcount * sizeof(ElementType)); + } + +public: + static dxWorldProcessMemArena *ReallocateMemArena ( + dxWorldProcessMemArena *oldarena, sizeint memreq, + const dxWorldProcessMemoryManager *memmgr, float rsrvfactor, unsigned rsrvminimum); + static void FreeMemArena (dxWorldProcessMemArena *arena); + + dxWorldProcessMemArena *GetNextMemArena() const { return (dxWorldProcessMemArena *)m_pAllocCurrentOrNextArena; } + void SetNextMemArena(dxWorldProcessMemArena *pArenaInstance) { m_pAllocCurrentOrNextArena = pArenaInstance; } + +private: + static sizeint AdjustArenaSizeForReserveRequirements(sizeint arenareq, float rsrvfactor, unsigned rsrvminimum); + +private: + void *m_pAllocCurrentOrNextArena; + void *m_pAllocBegin; + void *m_pAllocEnd; + void *m_pArenaBegin; + + const dxWorldProcessMemoryManager *m_pArenaMemMgr; +}; + +class dxWorldProcessContext: + public dBase +{ +public: + dxWorldProcessContext(); + ~dxWorldProcessContext(); + + void CleanupWorldReferences(dxWorld *pswWorldInstance); + +public: + bool EnsureStepperSyncObjectsAreAllocated(dxWorld *pswWorldInstance); + dCallWaitID GetIslandsSteppingWait() const { return m_pcwIslandsSteppingWait; } + +public: + dxWorldProcessMemArena *ObtainStepperMemArena(); + void ReturnStepperMemArena(dxWorldProcessMemArena *pmaArenaInstance); + + dxWorldProcessMemArena *ReallocateIslandsMemArena(sizeint nMemoryRequirement, + const dxWorldProcessMemoryManager *pmmMemortManager, float fReserveFactor, unsigned uiReserveMinimum); + bool ReallocateStepperMemArenas(dxWorld *world, unsigned nIslandThreadsCount, sizeint nMemoryRequirement, + const dxWorldProcessMemoryManager *pmmMemortManager, float fReserveFactor, unsigned uiReserveMinimum); + +private: + static void FreeArenasList(dxWorldProcessMemArena *pmaExistingArenas); + +private: + void SetIslandsMemArena(dxWorldProcessMemArena *pmaInstance) { m_pmaIslandsArena = pmaInstance; } + dxWorldProcessMemArena *GetIslandsMemArena() const { return m_pmaIslandsArena; } + + void SetStepperArenasList(dxWorldProcessMemArena *pmaInstance) { m_pmaStepperArenas = pmaInstance; } + dxWorldProcessMemArena *GetStepperArenasList() const { return m_pmaStepperArenas; } + + inline dxWorldProcessMemArena *GetStepperArenasHead() const; + inline bool TryExtractingStepperArenasHead(dxWorldProcessMemArena *pmaHeadInstance); + inline bool TryInsertingStepperArenasHead(dxWorldProcessMemArena *pmaArenaInstance, dxWorldProcessMemArena *pmaExistingHead); + +public: + void LockForAddLimotSerialization(); + void UnlockForAddLimotSerialization(); + void LockForStepbodySerialization(); + void UnlockForStepbodySerialization(); + +private: + enum dxProcessContextMutex + { + dxPCM_STEPPER_ARENA_OBTAIN, + dxPCM_STEPPER_ADDLIMOT_SERIALIZE, + dxPCM_STEPPER_STEPBODY_SERIALIZE, + + dxPCM__MAX + }; + + static const char *const m_aszContextMutexNames[dxPCM__MAX]; + +private: + dxWorldProcessMemArena *m_pmaIslandsArena; + dxWorldProcessMemArena *volatile m_pmaStepperArenas; + dxWorld *m_pswObjectsAllocWorld; + dMutexGroupID m_pmgStepperMutexGroup; + dCallWaitID m_pcwIslandsSteppingWait; +}; + +struct dxWorldProcessIslandsInfo +{ + void AssignInfo(sizeint islandcount, unsigned int const *islandsizes, dxBody *const *bodies, dxJoint *const *joints) + { + m_IslandCount = islandcount; + m_pIslandSizes = islandsizes; + m_pBodies = bodies; + m_pJoints = joints; + } + + sizeint GetIslandsCount() const { return m_IslandCount; } + unsigned int const *GetIslandSizes() const { return m_pIslandSizes; } + dxBody *const *GetBodiesArray() const { return m_pBodies; } + dxJoint *const *GetJointsArray() const { return m_pJoints; } + +private: + sizeint m_IslandCount; + unsigned int const *m_pIslandSizes; + dxBody *const *m_pBodies; + dxJoint *const *m_pJoints; +}; + +struct dxStepperProcessingCallContext +{ + dxStepperProcessingCallContext(dxWorld *world, dReal stepSize, unsigned stepperAllowedThreads, + dxWorldProcessMemArena *stepperArena, dxBody *const *islandBodiesStart, dxJoint *const *islandJointsStart): + m_world(world), m_stepSize(stepSize), m_stepperArena(stepperArena), m_finalReleasee(NULL), + m_islandBodiesStart(islandBodiesStart), m_islandJointsStart(islandJointsStart), m_islandBodiesCount(0), m_islandJointsCount(0), + m_stepperAllowedThreads(stepperAllowedThreads) + { + } + + void AssignIslandSelection(dxBody *const *islandBodiesStart, dxJoint *const *islandJointsStart, + unsigned islandBodiesCount, unsigned islandJointsCount) + { + m_islandBodiesStart = islandBodiesStart; + m_islandJointsStart = islandJointsStart; + m_islandBodiesCount = islandBodiesCount; + m_islandJointsCount = islandJointsCount; + } + + dxBody *const *GetSelectedIslandBodiesEnd() const { return m_islandBodiesStart + m_islandBodiesCount; } + dxJoint *const *GetSelectedIslandJointsEnd() const { return m_islandJointsStart + m_islandJointsCount; } + + void AssignStepperCallFinalReleasee(dCallReleaseeID finalReleasee) + { + m_finalReleasee = finalReleasee; + } + + dxWorld *const m_world; + dReal const m_stepSize; + dxWorldProcessMemArena *m_stepperArena; + dCallReleaseeID m_finalReleasee; + dxBody *const *m_islandBodiesStart; + dxJoint *const *m_islandJointsStart; + unsigned m_islandBodiesCount; + unsigned m_islandJointsCount; + unsigned m_stepperAllowedThreads; +}; + +#define BEGIN_STATE_SAVE(memarena, state) void *state = memarena->SaveState(); +#define END_STATE_SAVE(memarena, state) memarena->RestoreState(state) + +typedef void (*dstepper_fn_t) (const dxStepperProcessingCallContext *callContext); +typedef unsigned (*dmaxcallcountestimate_fn_t) (unsigned activeThreadCount, unsigned allowedThreadCount); + +bool dxProcessIslands (dxWorld *world, const dxWorldProcessIslandsInfo &islandsInfo, + dReal stepSize, dstepper_fn_t stepper, dmaxcallcountestimate_fn_t maxCallCountEstimator); + + +typedef sizeint (*dmemestimate_fn_t) (dxBody * const *body, unsigned int nb, + dxJoint * const *_joint, unsigned int _nj); + +bool dxReallocateWorldProcessContext (dxWorld *world, dxWorldProcessIslandsInfo &islandsinfo, + dReal stepsize, dmemestimate_fn_t stepperestimate); + +dxWorldProcessMemArena *dxAllocateTemporaryWorldProcessMemArena( + sizeint memreq, const dxWorldProcessMemoryManager *memmgr/*=NULL*/, const dxWorldProcessMemoryReserveInfo *reserveinfo/*=NULL*/); +void dxFreeTemporaryWorldProcessMemArena(dxWorldProcessMemArena *arena); + + +template<class ClassType> +inline ClassType *AllocateOnDemand(ClassType *&pctStorage) +{ + ClassType *pctCurrentInstance = pctStorage; + + if (!pctCurrentInstance) + { + pctCurrentInstance = new ClassType(); + pctStorage = pctCurrentInstance; + } + + return pctCurrentInstance; +} + + +// World stepping working memory object +class dxStepWorkingMemory: + public dBase +{ +public: + dxStepWorkingMemory(): m_uiRefCount(1), m_ppcProcessingContext(NULL), m_priReserveInfo(NULL), m_pmmMemoryManager(NULL) {} + +private: + friend struct dBase; // To avoid GCC warning regarding private destructor + ~dxStepWorkingMemory() // Use Release() instead + { + delete m_ppcProcessingContext; + delete m_priReserveInfo; + delete m_pmmMemoryManager; + } + +public: + void Addref() + { + dIASSERT(~m_uiRefCount != 0); + ++m_uiRefCount; + } + + void Release() + { + dIASSERT(m_uiRefCount != 0); + if (--m_uiRefCount == 0) + { + delete this; + } + } + +public: + void CleanupMemory() + { + delete m_ppcProcessingContext; + m_ppcProcessingContext = NULL; + } + + void CleanupWorldReferences(dxWorld *world) + { + if (m_ppcProcessingContext != NULL) + { + m_ppcProcessingContext->CleanupWorldReferences(world); + } + } + +public: + dxWorldProcessContext *SureGetWorldProcessingContext() { return AllocateOnDemand(m_ppcProcessingContext); } + dxWorldProcessContext *GetWorldProcessingContext() const { return m_ppcProcessingContext; } + + const dxWorldProcessMemoryReserveInfo *GetMemoryReserveInfo() const { return m_priReserveInfo; } + const dxWorldProcessMemoryReserveInfo *SureGetMemoryReserveInfo() const { return m_priReserveInfo ? m_priReserveInfo : &g_WorldProcessDefaultReserveInfo; } + void SetMemoryReserveInfo(float fReserveFactor, unsigned uiReserveMinimum) + { + if (m_priReserveInfo) { m_priReserveInfo->Assign(fReserveFactor, uiReserveMinimum); } + else { m_priReserveInfo = new dxWorldProcessMemoryReserveInfo(fReserveFactor, uiReserveMinimum); } + } + void ResetMemoryReserveInfoToDefault() + { + if (m_priReserveInfo) { delete m_priReserveInfo; m_priReserveInfo = NULL; } + } + + const dxWorldProcessMemoryManager *GetMemoryManager() const { return m_pmmMemoryManager; } + const dxWorldProcessMemoryManager *SureGetMemoryManager() const { return m_pmmMemoryManager ? m_pmmMemoryManager : &g_WorldProcessMallocMemoryManager; } + void SetMemoryManager(dxWorldProcessMemoryManager::alloc_block_fn_t fnAlloc, + dxWorldProcessMemoryManager::shrink_block_fn_t fnShrink, + dxWorldProcessMemoryManager::free_block_fn_t fnFree) + { + if (m_pmmMemoryManager) { m_pmmMemoryManager->Assign(fnAlloc, fnShrink, fnFree); } + else { m_pmmMemoryManager = new dxWorldProcessMemoryManager(fnAlloc, fnShrink, fnFree); } + } + void ResetMemoryManagerToDefault() + { + if (m_pmmMemoryManager) { delete m_pmmMemoryManager; m_pmmMemoryManager = NULL; } + } + +private: + unsigned m_uiRefCount; + dxWorldProcessContext *m_ppcProcessingContext; + dxWorldProcessMemoryReserveInfo *m_priReserveInfo; + dxWorldProcessMemoryManager *m_pmmMemoryManager; +}; + + +#endif diff --git a/libs/ode-0.16.1/ou/CHANGELOG.TXT b/libs/ode-0.16.1/ou/CHANGELOG.TXT new file mode 100644 index 0000000..0aad6e1 --- /dev/null +++ b/libs/ode-0.16.1/ou/CHANGELOG.TXT @@ -0,0 +1,55 @@ +=======================
+Legend
+=======================
+ [+] A feature added
+ [-] A bug fixed
+ [*] A change
+ [!] An important note
+=======================
+
+2015/12/28 oleh_derevenko
+
+ [*] Atomics assembler implementation has been improved and enabled for
+ GCC and _OU_TARGET_ARCH_X86/_OU_TARGET_ARCH_X64 with _OU_TARGET_OS_GENUNIX
+
+2010/04/24 oleh_derevenko
+
+ [+] A cast operator to non-const reference of contained type added for
+ CTypeSimpleWrapper.
+
+2009/10/07 oleh_derevenko
+
+ [-] Tests corrected to avoid checking int64ou alignment on Macs
+ (just like for uint64ou)
+
+2009/09/08 oleh_derevenko
+
+ [-] Enumerated type increment/decrement operators re-implemented in a way that
+ can't produce bad code with modern GCCs due to aliasing rules violation.
+
+2008/06/26 oleh_derevenko
+
+ [+] --disable-asserts option support added for configure.
+
+2008/04/19 oleh_derevenko
+
+ [+] Atomic functions via i486 assembler implementation added (manuall
+ selection with a preprocessor symbol only).
+
+2008/04/16 oleh_derevenko
+
+ [-] Fixed bug with storage memory not being properly zeroed at allocation.
+
+ [*] Memory customization changed to match assertion failure handler
+ customization. Now it is not necessary to save original pointers,
+ just NULL-s are to be assigned to revert from customized to
+ default memory menager.
+
+2008/04/08 oleh_derevenko
+
+ [!] Licensing changed: permission to distribute/use library under zlib/libpng
+ license added.
+
+2008/04/07 oleh_derevenko
+
+ [+] Initial commit
diff --git a/libs/ode-0.16.1/ou/INSTALL.TXT b/libs/ode-0.16.1/ou/INSTALL.TXT new file mode 100644 index 0000000..f250edc --- /dev/null +++ b/libs/ode-0.16.1/ou/INSTALL.TXT @@ -0,0 +1,14 @@ +Currently OU provides project files for Visual Studio 6, Visual Studio 2005
+and makefile for GCC. These are located in "build" directory.
+Makefile is quite simple and may not work on some platforms. Makefile does not
+have "clean" targets and does not track header changes. Further in this file
+you can find how to delete build output files to re-run a clean build.
+
+There is also a test project file in "test" directory that covers all the
+library functionality and allows to make sure everything is fine on
+a particular platform.
+
+All the intermediate files are generated in "intermediate" directory.
+Library output files are placed in "lib" directory.
+Test binary is placed in "bin" directory.
+Having these three folders deleted you can return to initial state.
diff --git a/libs/ode-0.16.1/ou/LICENSE-BSD.TXT b/libs/ode-0.16.1/ou/LICENSE-BSD.TXT new file mode 100644 index 0000000..a465bd9 --- /dev/null +++ b/libs/ode-0.16.1/ou/LICENSE-BSD.TXT @@ -0,0 +1,34 @@ +
+This is the BSD-style license for the ODER's Utilities Library
+--------------------------------------------------------------
+
+ODER's Utilities Library
+Copyright (c) 2008, Oleh Derevenko.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+
+Neither the names of ODER's Utilities' copyright owner nor the names of
+its contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+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
+OWNER 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.
diff --git a/libs/ode-0.16.1/ou/LICENSE-LESSER.TXT b/libs/ode-0.16.1/ou/LICENSE-LESSER.TXT new file mode 100644 index 0000000..95ff192 --- /dev/null +++ b/libs/ode-0.16.1/ou/LICENSE-LESSER.TXT @@ -0,0 +1,166 @@ + GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
+
diff --git a/libs/ode-0.16.1/ou/LICENSE-ZLIB.TXT b/libs/ode-0.16.1/ou/LICENSE-ZLIB.TXT new file mode 100644 index 0000000..1a17187 --- /dev/null +++ b/libs/ode-0.16.1/ou/LICENSE-ZLIB.TXT @@ -0,0 +1,22 @@ +The zlib/libpng License for the ODER's Utilities Library
+
+Copyright (c) 2008 Oleh Derevenko
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+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.
+
+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.
diff --git a/libs/ode-0.16.1/ou/LICENSE.TXT b/libs/ode-0.16.1/ou/LICENSE.TXT new file mode 100644 index 0000000..f2d137d --- /dev/null +++ b/libs/ode-0.16.1/ou/LICENSE.TXT @@ -0,0 +1,675 @@ + GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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 <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+
diff --git a/libs/ode-0.16.1/ou/Makefile.am b/libs/ode-0.16.1/ou/Makefile.am new file mode 100644 index 0000000..7129a82 --- /dev/null +++ b/libs/ode-0.16.1/ou/Makefile.am @@ -0,0 +1,10 @@ +AUTOMAKE_OPTIONS = foreign + +EXTRA_DIST = bootstrap \ + CHANGELOG.TXT INSTALL.TXT \ + LICENSE.TXT LICENSE-BSD.TXT LICENSE-LESSER.TXT LICENSE-ZLIB.TXT \ + README.TXT \ + build + +SUBDIRS = include/ou src/ou test + diff --git a/libs/ode-0.16.1/ou/Makefile.in b/libs/ode-0.16.1/ou/Makefile.in new file mode 100644 index 0000000..f812a93 --- /dev/null +++ b/libs/ode-0.16.1/ou/Makefile.in @@ -0,0 +1,804 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(am__DIST_COMMON) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + cscope distdir dist dist-all distcheck +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +CSCOPE = cscope +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/../compile \ + $(top_srcdir)/../config.guess $(top_srcdir)/../config.sub \ + $(top_srcdir)/../install-sh $(top_srcdir)/../ltmain.sh \ + $(top_srcdir)/../missing +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +DIST_TARGETS = dist-gzip +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +OU_FEATURE_SET = @OU_FEATURE_SET@ +OU_NAMESPACE = @OU_NAMESPACE@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = foreign +EXTRA_DIST = bootstrap \ + CHANGELOG.TXT INSTALL.TXT \ + LICENSE.TXT LICENSE-BSD.TXT LICENSE-LESSER.TXT LICENSE-ZLIB.TXT \ + README.TXT \ + build + +SUBDIRS = include/ou src/ou test +all: all-recursive + +.SUFFIXES: +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__post_remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + +dist-tarZ: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__post_remove_distdir) + +dist-shar: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__post_remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__post_remove_distdir) + +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build/sub \ + && ../../configure \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=../.. --prefix="$$dc_install_base" \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__post_remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--refresh check check-am clean clean-cscope clean-generic \ + clean-libtool cscope cscopelist-am ctags ctags-am dist \ + dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ + dist-xz dist-zip distcheck distclean distclean-generic \ + distclean-libtool distclean-tags distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/ou/README.TXT b/libs/ode-0.16.1/ou/README.TXT new file mode 100644 index 0000000..f4a8440 --- /dev/null +++ b/libs/ode-0.16.1/ou/README.TXT @@ -0,0 +1,42 @@ +ODER's Utilities Library (OU), Copyright (C) 2008 Oleh Derevenko,
+E-mail: odar@eleks.com (change all "a" to "e").
+-------------------------------------------------------------------------
+
+OU is a free multi-platform library that provides basic API for
+atomic (interlocked) operations and thread local storage. It also
+implements assertion checking macros, classes for flags manipulations
+(both with ordinary and atomic access), templates for enumerated
+values decoding/encoding by static arrays, and some more useful macros
+and templates. Most of the library is implemented as inlined code.
+Library allows customization of assertion failure handlers and memory
+management functions. It is possible to link OU more than once into
+a single binary as parts of other libraries.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of EITHER:
+ (1) The GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version. The text of the GNU Lesser
+ General Public License is included with this library in the
+ file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL
+ the text of GNU General Public License is also provided for
+ your information in file LICENSE.TXT.
+ (2) The BSD-style license that is included with this library in
+ the file LICENSE-BSD.TXT.
+ (3) The zlib/libpng license that is included with this library in
+ the file LICENSE-ZLIB.TXT
+
+This library is distributed WITHOUT ANY WARRANTY, including implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT
+or LICENSE-ZLIB.TXT for more details.
+
+ * Installation instructions are in the INSTALL.TXT file
+
+All contributions are copyright by their owners, but the owners
+automatically transfer unrestricted rights in those changes to the OU
+project, which is released under the threefold licenses as indicated.
+The owners can also use the contributions in other projects under other
+licenses if they want (including sell them), but they can't prevent
+anyone from releasing the contributions under the threefold OU licenses
+as part of an OU release.
diff --git a/libs/ode-0.16.1/ou/aclocal.m4 b/libs/ode-0.16.1/ou/aclocal.m4 new file mode 100644 index 0000000..f7ad092 --- /dev/null +++ b/libs/ode-0.16.1/ou/aclocal.m4 @@ -0,0 +1,10200 @@ +# generated automatically by aclocal 1.15 -*- Autoconf -*- + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. + +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 2014 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool 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 2 of of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 <http://www.gnu.org/licenses/>. +]) + +# serial 58 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK +AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS=$ltmain + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_PREPARE_CC_BASENAME +# ----------------------- +m4_defun([_LT_PREPARE_CC_BASENAME], [ +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in @S|@*""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} +])# _LT_PREPARE_CC_BASENAME + + +# _LT_CC_BASENAME(CC) +# ------------------- +# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, +# but that macro is also expanded into generated libtool script, which +# arranges for $SED and $ECHO to be set by different means. +m4_defun([_LT_CC_BASENAME], +[m4_require([_LT_PREPARE_CC_BASENAME])dnl +AC_REQUIRE([_LT_DECL_SED])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl +func_cc_basename $1 +cc_basename=$func_cc_basename_result +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl + +_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl +dnl +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_WITH_SYSROOT])dnl +m4_require([_LT_CMD_TRUNCATE])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options that allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld=$lt_cv_prog_gnu_ld + +old_CC=$CC +old_CFLAGS=$CFLAGS + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. +m4_defun([_LT_PREPARE_SED_QUOTE_VARS], +[# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' +]) + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from 'configure', and 'config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# 'config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain=$ac_aux_dir/ltmain.sh +])# _LT_PROG_LTMAIN + + + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the 'libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to 'config.status' so that its +# declaration there will have the same value as in 'configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags='_LT_TAGS'dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into 'config.status', and then the shell code to quote escape them in +# for loops in 'config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$[]1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +_LT_OUTPUT_LIBTOOL_INIT +]) + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# Generate a child script FILE with all initialization necessary to +# reuse the environment learned by the parent script, and make the +# file executable. If COMMENT is supplied, it is inserted after the +# '#!' sequence but before initialization text begins. After this +# macro, additional text can be appended to FILE to form the body of +# the child script. The macro ends with non-zero status if the +# file could not be fully written (such as if the disk is full). +m4_ifdef([AS_INIT_GENERATED], +[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], +[m4_defun([_LT_GENERATED_FILE_INIT], +[m4_require([AS_PREPARE])]dnl +[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl +[lt_write_fail=0 +cat >$1 <<_ASEOF || lt_write_fail=1 +#! $SHELL +# Generated by $as_me. +$2 +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$1 <<\_ASEOF || lt_write_fail=1 +AS_SHELL_SANITIZE +_AS_PREPARE +exec AS_MESSAGE_FD>&1 +_ASEOF +test 0 = "$lt_write_fail" && chmod +x $1[]dnl +m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +'$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to <bug-libtool@gnu.org>." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2011 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test 0 != $[#] +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try '$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try '$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +lt_cl_success=: +test yes = "$silent" && + lt_config_lt_args="$lt_config_lt_args --quiet" +exec AS_MESSAGE_LOG_FD>/dev/null +$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options that allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST + fi + + cfgfile=${ofile}T + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL +# Generated automatically by $as_me ($PACKAGE) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + +_LT_COPYING +_LT_LIBTOOL_TAGS + +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +_LT_PREPARE_MUNGE_PATH_LIST +_LT_PREPARE_CC_BASENAME + +# ### END FUNCTIONS SHARED WITH CONFIGURE + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Go], [_LT_LANG(GO)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +m4_ifndef([AC_PROG_GO], [ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_GO. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +m4_defun([AC_PROG_GO], +[AC_LANG_PUSH(Go)dnl +AC_ARG_VAR([GOC], [Go compiler command])dnl +AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl +_AC_ARG_VAR_LDFLAGS()dnl +AC_CHECK_TOOL(GOC, gccgo) +if test -z "$GOC"; then + if test -n "$ac_tool_prefix"; then + AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) + fi +fi +if test -z "$GOC"; then + AC_CHECK_PROG(GOC, gccgo, gccgo, false) +fi +])#m4_defun +])#m4_ifndef + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([AC_PROG_GO], + [LT_LANG(GO)], + [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) +dnl AC_DEFUN([AC_LIBTOOL_RC], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "$LT_MULTI_MODULE"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS=$save_LDFLAGS + ]) + + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], + [lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD + echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD + $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + 10.[[012]][[,.]]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test yes = "$lt_cv_apple_cc_single_mod"; then + _lt_dar_single_mod='$single_module' + fi + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' + fi + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES([TAG]) +# --------------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + if test yes = "$lt_cv_ld_force_load"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], + [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + m4_if([$1], [CXX], +[ if test yes != "$lt_cv_apple_cc_single_mod"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) +# ---------------------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +# Store the results from the different compilers for each TAGNAME. +# Allow to override them for all tags through lt_cv_aix_libpath. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], + [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ + lt_aix_libpath_sed='[ + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }]' + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi],[]) + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib + fi + ]) + aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) +fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[m4_divert_text([M4SH-INIT], [$1 +])])# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Find how we can fake an echo command that does not interpret backslash. +# In particular, with Autoconf 2.60 or later we add some code to the start +# of the generated configure script that will find a shell with a builtin +# printf (that we can use as an echo command). +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +AC_MSG_CHECKING([how to print strings]) +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$[]1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +case $ECHO in + printf*) AC_MSG_RESULT([printf]) ;; + print*) AC_MSG_RESULT([print -r]) ;; + *) AC_MSG_RESULT([cat]) ;; +esac + +m4_ifdef([_AS_DETECT_SUGGESTED], +[_AS_DETECT_SUGGESTED([ + test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test "X`printf %s $ECHO`" = "X$ECHO" \ + || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) + +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_WITH_SYSROOT +# ---------------- +AC_DEFUN([_LT_WITH_SYSROOT], +[AC_MSG_CHECKING([for sysroot]) +AC_ARG_WITH([sysroot], +[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], + [Search for dependent libraries within DIR (or the compiler's sysroot + if not specified).])], +[], [with_sysroot=no]) + +dnl lt_sysroot will always be passed unquoted. We quote it here +dnl in case the user passed a directory name. +lt_sysroot= +case $with_sysroot in #( + yes) + if test yes = "$GCC"; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + AC_MSG_RESULT([$with_sysroot]) + AC_MSG_ERROR([The sysroot must be an absolute path.]) + ;; +esac + + AC_MSG_RESULT([${lt_sysroot:-no}]) +_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl +[dependent libraries, and where our libraries should be installed.])]) + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test no = "$enable_libtool_lock" || enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE=32 + ;; + *ELF-64*) + HPUX_IA64_MODE=64 + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test yes = "$lt_cv_prog_gnu_ld"; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test yes != "$lt_cv_cc_needs_belf"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS=$SAVE_CFLAGS + fi + ;; +*-*solaris*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*|x86_64-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD=${LD-ld}_sol2 + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks=$enable_libtool_lock +])# _LT_ENABLE_LOCK + + +# _LT_PROG_AR +# ----------- +m4_defun([_LT_PROG_AR], +[AC_CHECK_TOOLS(AR, [ar], false) +: ${AR=ar} +: ${AR_FLAGS=cru} +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], + [lt_cv_ar_at_file=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([lt_ar_try]) + if test 0 -eq "$ac_status"; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + AC_TRY_EVAL([lt_ar_try]) + if test 0 -ne "$ac_status"; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + ]) + ]) + +if test no = "$lt_cv_ar_at_file"; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi +_LT_DECL([], [archiver_list_spec], [1], + [How to feed a file listing to the archiver]) +])# _LT_PROG_AR + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[_LT_PROG_AR + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + bitrig* | openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +_LT_DECL([], [lock_old_archive_extraction], [0], + [Whether to use a lock for old archive extraction]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test yes = "[$]$2"; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS +]) + +if test yes = "[$]$2"; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring=ABCD + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test 17 != "$i" # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n "$lt_cv_sys_max_cmd_len"; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test yes = "$cross_compiling"; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test yes != "$enable_dlopen"; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen=load_add_on + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen=LoadLibrary + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ + lt_cv_dlopen=dyld + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen=shl_load], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen=dlopen], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test no = "$lt_cv_dlopen"; then + enable_dlopen=no + else + enable_dlopen=yes + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS=$LDFLAGS + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS=$LIBS + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test yes = "$lt_cv_dlopen_self"; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links=nottested +if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test no = "$hard_links"; then + AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", + [Define to the sub-directory where libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then + + # We can hardcode non-existent directories. + if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && + test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || + test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP"; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_PREPARE_MUNGE_PATH_LIST +# --------------------------- +# Make sure func_munge_path_list() is defined correctly. +m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], +[[# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x@S|@2 in + x) + ;; + *:) + eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" + ;; + x:*) + eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" + ;; + *) + eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" + ;; + esac +} +]])# _LT_PREPARE_PATH_LIST + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test yes = "$GCC"; then + case $host_os in + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary... + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo = "/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +AC_ARG_VAR([LT_SYS_LIBRARY_PATH], +[User-defined run-time library search path.]) + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[[4-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib<name>.so + # instead of lib<name>.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a[(]lib.so.V[)]' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[23]].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[[3-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], + [lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [lt_cv_shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + ]) + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [install_override_mode], [1], + [Permission mode override for installation of shared libraries]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], + [Detected run-time system search path for libraries]) +_LT_DECL([], [configure_time_lt_sys_library_path], [2], + [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program that can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$1"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac]) +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program that can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PROG_ECHO_BACKSLASH])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test no = "$withval" || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in + *GNU* | *'with BFD'*) + test no != "$with_gnu_ld" && break + ;; + *) + test yes != "$with_gnu_ld" && break + ;; + esac + fi + done + IFS=$lt_save_ifs +else + lt_cv_path_LD=$LD # Let the user override the test with a path. +fi]) +LD=$lt_cv_path_LD +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +_LT_PATH_LD_GNU +AC_SUBST([LD]) + +_LT_TAGDECL([], [LD], [1], [The linker used to build libraries]) +])# LT_PATH_LD + +# Old names: +AU_ALIAS([AM_PROG_LD], [LT_PATH_LD]) +AU_ALIAS([AC_PROG_LD], [LT_PATH_LD]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_LD], []) +dnl AC_DEFUN([AC_PROG_LD], []) + + +# _LT_PATH_LD_GNU +#- -------------- +m4_defun([_LT_PATH_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + lt_cv_prog_gnu_ld=yes + ;; +*) + lt_cv_prog_gnu_ld=no + ;; +esac]) +with_gnu_ld=$lt_cv_prog_gnu_ld +])# _LT_PATH_LD_GNU + + +# _LT_CMD_RELOAD +# -------------- +# find reload flag for linker +# -- PORTME Some linkers may need a different reload flag. +m4_defun([_LT_CMD_RELOAD], +[AC_CACHE_CHECK([for $LD option to reload object files], + lt_cv_ld_reload_flag, + [lt_cv_ld_reload_flag='-r']) +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test yes != "$GCC"; then + reload_cmds=false + fi + ;; + darwin*) + if test yes = "$GCC"; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac +_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl +_LT_TAGDECL([], [reload_cmds], [2])dnl +])# _LT_CMD_RELOAD + + +# _LT_PATH_DD +# ----------- +# find a working dd +m4_defun([_LT_PATH_DD], +[AC_CACHE_CHECK([for a working dd], [ac_cv_path_lt_DD], +[printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], +[if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi]) +rm -f conftest.i conftest2.i conftest.out]) +])# _LT_PATH_DD + + +# _LT_CMD_TRUNCATE +# ---------------- +# find command to truncate a binary pipe +m4_defun([_LT_CMD_TRUNCATE], +[m4_require([_LT_PATH_DD]) +AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], +[printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) +_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], + [Command to truncate a binary pipe]) +])# _LT_CMD_TRUNCATE + + +# _LT_CHECK_MAGIC_METHOD +# ---------------------- +# how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_MAGIC_METHOD], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +AC_CACHE_CHECK([how to recognize dependent libraries], +lt_cv_deplibs_check_method, +[lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# 'unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[[4-9]]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[[45]]*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method = "file_magic"]) +_LT_DECL([], [file_magic_glob], [1], + [How to find potential files when deplibs_check_method = "file_magic"]) +_LT_DECL([], [want_nocaseglob], [1], + [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM=$NM +else + lt_nm_to_check=${ac_tool_prefix}nm + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break 2 + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break 2 + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS=$lt_save_ifs + done + : ${lt_cv_path_NM=no} +fi]) +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols -headers" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test : != "$DUMPBIN"; then + NM=$DUMPBIN + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + +# _LT_CHECK_SHAREDLIB_FROM_LINKLIB +# -------------------------------- +# how to determine the name of the shared library +# associated with a specific link library. +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +m4_require([_LT_DECL_DLLTOOL]) +AC_CACHE_CHECK([how to associate runtime and link libraries], +lt_cv_sharedlib_from_linklib_cmd, +[lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd=$ECHO + ;; +esac +]) +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + +_LT_DECL([], [sharedlib_from_linklib_cmd], [1], + [Command to associate shared and link libraries]) +])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB + + +# _LT_PATH_MANIFEST_TOOL +# ---------------------- +# locate the manifest tool +m4_defun([_LT_PATH_MANIFEST_TOOL], +[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], + [lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&AS_MESSAGE_LOG_FD + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest*]) +if test yes != "$lt_cv_path_mainfest_tool"; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + + +# _LT_DLL_DEF_P([FILE]) +# --------------------- +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with func_dll_def_p in the libtool script +AC_DEFUN([_LT_DLL_DEF_P], +[dnl + test DEF = "`$SED -n dnl + -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace + -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments + -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl + -e q dnl Only consider the first "real" line + $1`" dnl +])# _LT_DLL_DEF_P + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM=-lm) + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test yes = "$GCC"; then + case $cc_basename in + nvcc*) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; + *) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; + esac + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test ia64 = "$host_cpu"; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS=conftstm.$ac_objext + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test yes = "$pipe_works"; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], + [Transform the output of nm into a list of symbols to manually relocate]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([nm_interface], [lt_cv_nm_interface], [1], + [The name lister interface]) +_LT_DECL([], [nm_file_list_spec], [1], + [Specify filename containing input files for $NM]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test yes = "$GXX"; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + if test ia64 != "$host_cpu"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64, which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test yes = "$GCC"; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' + if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + *Sun\ F* | *Sun*Fortran*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Intel*\ [[CF]]*Compiler*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + *Portland\ Group*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +AC_CACHE_CHECK([for $compiler option to produce PIC], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + ;; + esac + ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test yes != "$GCC"; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd* | bitrig*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test yes = "$with_gnu_ld"; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; + *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test yes = "$lt_use_gnu_ld_interface"; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='$wl' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test ia64 != "$host_cpu"; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test linux-dietlibc = "$host_os"; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test no = "$tmp_diet" + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; + xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + tcc*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' + ;; + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then + aix_use_runtimelinking=yes + break + fi + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + ;; + esac + + if test yes = "$GCC"; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + esac + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + ;; + + hpux10*) + if test yes,no = "$GCC,$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test yes,no = "$GCC,$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + m4_if($1, [], [ + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + _LT_LINKER_OPTION([if $CC understands -b], + _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + ;; + esac + fi + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], + [lt_cv_irix_exported_symbol], + [save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" + AC_LINK_IFELSE( + [AC_LANG_SOURCE( + [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], + [C++], [[int foo (void) { return 0; }]], + [Fortran 77], [[ + subroutine foo + end]], + [Fortran], [[ + subroutine foo + end]])])], + [lt_cv_irix_exported_symbol=yes], + [lt_cv_irix_exported_symbol=no]) + LDFLAGS=$save_LDFLAGS]) + if test yes = "$lt_cv_irix_exported_symbol"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' + fi + _LT_TAGVAR(link_all_deplibs, $1)=no + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(ld_shlibs, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + osf3*) + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test yes = "$GCC"; then + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. GCC discards it without '$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test yes = "$GCC"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test sequent = "$host_vendor"; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test sni = "$host_vendor"; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_CACHE_CHECK([whether -lc should be explicitly linked in], + [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), + [$RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + ]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting $shlibpath_var if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [postlink_cmds], [2], + [Commands necessary for finishing linking programs]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC=$CC +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report what library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC=$lt_save_CC +])# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +if test -n "$CXX" && ( test no != "$CXX" && + ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || + (test g++ != "$CXX"))); then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_caught_CXX_error"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test yes = "$GXX"; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test yes = "$GXX"; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test yes = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='$wl' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + ;; + esac + + if test yes = "$GXX"; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag=$shared_flag' $wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + # The "-G" linker flag allows undefined symbols. + _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared + # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require '-G' NOT '-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ + '"$_LT_TAGVAR(old_archive_cmds, $1)" + _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ + '"$_LT_TAGVAR(reload_cmds, $1)" + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no + + _LT_TAGVAR(GCC, $1)=$GXX + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test yes != "$_lt_caught_CXX_error" + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_FUNC_STRIPNAME_CNF +# ---------------------- +# func_stripname_cnf prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# +# This function is identical to the (non-XSI) version of func_stripname, +# except this one can be used by m4 code that may be executed by configure, +# rather than the libtool script. +m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl +AC_REQUIRE([_LT_DECL_SED]) +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) +func_stripname_cnf () +{ + case @S|@2 in + .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; + *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; + esac +} # func_stripname_cnf +])# _LT_FUNC_STRIPNAME_CNF + + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF +package foo +func foo() { +} +_LT_EOF +]) + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $prev$p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test x-L = "$p" || + test x-R = "$p"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test no = "$pre_test_object_deps_done"; then + case $prev in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)=$prev$p + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test no = "$pre_test_object_deps_done"; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)=$p + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)=$p + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_LANG_PUSH(Fortran 77) +if test -z "$F77" || test no = "$F77"; then + _lt_disable_F77=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_disable_F77"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${F77-"f77"} + CFLAGS=$FFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)=$G77 + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test yes != "$_lt_disable_F77" + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_LANG_PUSH(Fortran) + +if test -z "$FC" || test no = "$FC"; then + _lt_disable_FC=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_disable_FC"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${FC-"f95"} + CFLAGS=$FCFLAGS + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test yes != "$_lt_disable_FC" + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +CFLAGS=$GCJFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)=$LD +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_GO_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Go compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_GO_CONFIG], +[AC_REQUIRE([LT_PROG_GO])dnl +AC_LANG_SAVE + +# Source file extension for Go test sources. +ac_ext=go + +# Object file extension for compiled Go test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="package main; func main() { }" + +# Code to be used in simple link tests +lt_simple_link_test_code='package main; func main() { }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GOC-"gccgo"} +CFLAGS=$GOFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)=$LD +_LT_CC_BASENAME([$compiler]) + +# Go did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GO_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code=$lt_simple_compile_test_code + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +CFLAGS= +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_GO +# ---------- +AC_DEFUN([LT_PROG_GO], +[AC_CHECK_TOOL(GOC, gccgo,) +]) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + +# _LT_DECL_DLLTOOL +# ---------------- +# Ensure DLLTOOL variable is set. +m4_defun([_LT_DECL_DLLTOOL], +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) +AC_SUBST([DLLTOOL]) +]) + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f "$lt_ac_sed" && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test 10 -lt "$lt_ac_count" && break + lt_ac_count=`expr $lt_ac_count + 1` + if test "$lt_ac_count" -gt "$lt_ac_max"; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PATH_CONVERSION_FUNCTIONS +# ----------------------------- +# Determine what file name conversion functions should be used by +# func_to_host_file (and, implicitly, by func_to_host_path). These are needed +# for certain cross-compile configurations and native mingw. +m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_MSG_CHECKING([how to convert $build file names to $host format]) +AC_CACHE_VAL(lt_cv_to_host_file_cmd, +[case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac +]) +to_host_file_cmd=$lt_cv_to_host_file_cmd +AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) +_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], + [0], [convert $build file names to $host format])dnl + +AC_MSG_CHECKING([how to convert $build file names to toolchain format]) +AC_CACHE_VAL(lt_cv_to_tool_file_cmd, +[#assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac +]) +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) +_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], + [0], [convert $build files to toolchain format])dnl +])# _LT_PATH_CONVERSION_FUNCTIONS + +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software +# Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 8 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option '$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl 'shared' nor 'disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], + [_LT_WITH_AIX_SONAME([aix])]) + ]) +])# _LT_SET_OPTIONS + + + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [1], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the 'shared' and +# 'disable-shared' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the 'static' and +# 'disable-static' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the 'fast-install' +# and 'disable-fast-install' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the 'fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the 'disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_AIX_SONAME([DEFAULT]) +# ---------------------------------- +# implement the --with-aix-soname flag, and support the `aix-soname=aix' +# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT +# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. +m4_define([_LT_WITH_AIX_SONAME], +[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl +shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[[5-9]]*,yes) + AC_MSG_CHECKING([which variant of shared library versioning to provide]) + AC_ARG_WITH([aix-soname], + [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], + [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], + [case $withval in + aix|svr4|both) + ;; + *) + AC_MSG_ERROR([Unknown argument to --with-aix-soname]) + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname], + [AC_CACHE_VAL([lt_cv_with_aix_soname], + [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) + with_aix_soname=$lt_cv_with_aix_soname]) + AC_MSG_RESULT([$with_aix_soname]) + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + +_LT_DECL([], [shared_archive_member_spec], [0], + [Shared archive member basename, for filename based shared library versioning on AIX])dnl +])# _LT_WITH_AIX_SONAME + +LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) +LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) +LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the 'pic-only' and 'no-pic' +# LT_INIT options. +# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [pic_mode=m4_default([$1], [default])]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) + +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software +# Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59, which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) + +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# @configure_input@ + +# serial 4179 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.4.6]) +m4_define([LT_PACKAGE_REVISION], [2.4.6]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.4.6' +macro_revision='2.4.6' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) + +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software +# Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 5 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) +m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) +m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) +m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) +m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) +m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) +m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) + +# Copyright (C) 2002-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.15' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.15], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.15])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is '.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each '.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.65])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl +]) +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: <http://www.gnu.org/software/coreutils/>. + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi +dnl The trailing newline in this macro's definition is deliberate, for +dnl backward compatibility and to allow trailing 'dnl'-style comments +dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. +]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST([install_sh])]) + +# Copyright (C) 2003-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + AC_MSG_WARN(['missing' script is too old or missing]) +fi +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) + +# Copyright (C) 2009-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor 'install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in "make install-strip", and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +# +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' + +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar <conftest.tar]) + AM_RUN_LOG([cat conftest.dir/file]) + grep GrepMe conftest.dir/file >/dev/null 2>&1 && break + fi + done + rm -rf conftest.dir + + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + diff --git a/libs/ode-0.16.1/ou/bootstrap b/libs/ode-0.16.1/ou/bootstrap new file mode 100755 index 0000000..30e96af --- /dev/null +++ b/libs/ode-0.16.1/ou/bootstrap @@ -0,0 +1,11 @@ +#!/bin/sh + +aclocal || exit 1 +# on Mac libtoolize is called glibtoolize +LIBTOOLIZE=libtoolize +if [ `uname -s` = Darwin ]; then + LIBTOOLIZE=glibtoolize +fi +$LIBTOOLIZE --automake -c || exit 1 +autoconf -f || exit 1 +automake -a -c --foreign || exit 1 diff --git a/libs/ode-0.16.1/ou/build/make/makefile b/libs/ode-0.16.1/ou/build/make/makefile new file mode 100644 index 0000000..bf8a8d6 --- /dev/null +++ b/libs/ode-0.16.1/ou/build/make/makefile @@ -0,0 +1,219 @@ +PRODUCTNAME = ou +MODE ?= DEVELOP +BITS ?= 32 + +include makefile.os + +CXX = gcc +AR = ar +LD = gcc + +CXXFLAGS = -fno-exceptions -fno-rtti -Wall -g +ARFLAGS = -r +LDFLAGS = -fno-exceptions -fno-rtti -g + +ifeq ($(OS_PLATFORM), i386) +ifneq ($(BITS), 64) + +CXXFLAGS += -malign-double + +endif +endif + +ifeq ($(MODE), DEBUG) + +CXXFLAGS += -D_DEBUG +CXXFLAGS += -O0 + +else +ifeq ($(MODE), RELEASE) + +CXXFLAGS += -DNDEBUG +CXXFLAGS += -O3 -funroll-loops + +else + +CXXFLAGS += -O2 + +endif +endif + +ifeq ($(BITS), 64) + +CXXFLAGS += -m64 +LDFLAGS += -m64 + +else + +CXXFLAGS += -m32 +LDFLAGS += -m32 + +endif + + +SRCEXT=.cpp +OBJEXT=$(OS_OBJ_EXT) + +OUTNAME := $(PRODUCTNAME) +OUTDIR = ../../lib/ +OUTEXT=$(OS_LIB_EXT) + +TESTNAME := $(PRODUCTNAME)test +TESTDIR = ../../bin/ +TESTEXT=$(OS_EXE_EXT) + +REFINEDCXX = $(notdir $(CXX)) +OUTINTDIR := ../../intermediate/$(REFINEDCXX)/ +TESTINTDIR := ../../intermediate/$(REFINEDCXX)_$(TESTNAME)/ + + +ifeq ($(MODE), DEBUG) + +OUTINTDIR := $(OUTINTDIR)debug +TESTINTDIR := $(TESTINTDIR)debug + +else +ifeq ($(MODE), RELEASE) + +OUTINTDIR := $(OUTINTDIR)release +TESTINTDIR := $(TESTINTDIR)release + +else + +OUTINTDIR := $(OUTINTDIR)develop +TESTINTDIR := $(TESTINTDIR)develop + +endif +endif + +ifeq ($(BITS), 64) + +OUTINTDIR := $(OUTINTDIR)64 +TESTINTDIR := $(TESTINTDIR)64 + + +OUTNAME := $(OUTNAME)64 +TESTNAME := $(TESTNAME)64 + +endif + +ifeq ($(MODE), DEBUG) + +OUTNAME := $(OUTNAME)_debug +TESTNAME := $(TESTNAME)_debug + +endif + +ifeq ($(MODE), RELEASE) + +OUTNAME := $(OUTNAME)_release +TESTNAME := $(TESTNAME)_release + +endif + +OUTINTDIR := $(OUTINTDIR)/ +TESTINTDIR := $(TESTINTDIR)/ + +OUTPATH = $(OUTDIR)$(OS_LIB_PRE)$(OUTNAME)$(OUTEXT) +TESTPATH = $(TESTDIR)$(TESTNAME)$(TESTEXT) + +ININCDIR = ../../include +INDIR = ../../src/ou/ + +INFILES = \ + atomic \ + customization \ + malloc \ + threadlocalstorage + +INOBJS = $(addprefix $(OUTINTDIR), $(addsuffix $(OBJEXT), $(INFILES))) + + +TESTINCDIR = $(ININCDIR) +TESTLIBDIR = $(OUTDIR) +TESTLIBS = $(OUTNAME) +TESTSRCDIR = ../../test/ + +ifeq ($(OS_TYPE), Linux) +TESTLIBS += pthread +endif + +ifeq ($(OS_TYPE), SUN) +TESTLIBS += pthread c +endif + + +TESTFILES = outest + +TESTOBJS = $(addprefix $(TESTINTDIR), $(addsuffix $(OBJEXT), $(TESTFILES))) + + +.PHONY: develop debug release develop64 debug64 release64 all ou + +all: develop + +develop: + $(MAKE) ou MODE=DEVELOP BITS=32 + +debug: + $(MAKE) ou MODE=DEBUG BITS=32 + +release: + $(MAKE) ou MODE=RELEASE BITS=32 + +develop64: + $(MAKE) ou MODE=DEVELOP BITS=64 + +debug64: + $(MAKE) ou MODE=DEBUG BITS=64 + +release64: + $(MAKE) ou MODE=RELEASE BITS=64 + +ou: $(OUTPATH) $(TESTPATH) + + +.PHONY: mkoutintpath mkoutpath mktestintpath mktestpath + +$(OUTPATH): mkoutintpath mkoutpath $(INOBJS) + $(OS_VP)echo BUILDING $(notdir $(OUTPATH))... + $(OS_VP)$(AR) $(ARFLAGS) $(OUTPATH) $(INOBJS) + +$(TESTPATH): mktestintpath mktestpath $(OUTPATH) $(TESTOBJS) + $(OS_VP)echo LINKING $(notdir $(TESTPATH))... + $(OS_VP)$(LD) $(LDFLAGS) $(LDADDFLAGS) -o $(TESTPATH) \ + $(addprefix -I, $(TESTINCDIR) $(OS_INCLUDE_PATH)) \ + $(addprefix -L, $(TESTLIBDIR) $(OS_LIB_PATH)) \ + $(TESTOBJS) \ + $(addprefix -l, $(TESTLIBS)) + +$(OUTINTDIR)%$(OBJEXT): $(INDIR)%$(SRCEXT) + $(OS_VP)echo Compiling $(notdir $@)... + $(OS_VP)$(CXX) $(CXXFLAGS) $(CXXADDFLAGS) -c -o $@ \ + $(addprefix -I, $(ININCDIR) $(OS_INCLUDE_PATH)) \ + $< + +$(TESTINTDIR)%$(OBJEXT): $(TESTSRCDIR)%$(SRCEXT) + $(OS_VP)echo Compiling $(notdir $@)... + $(OS_VP)$(CXX) $(CXXFLAGS) $(CXXADDFLAGS) -c -o $@ \ + $(addprefix -I, $(TESTINCDIR) $(OS_INCLUDE_PATH)) \ + $< + + +mkoutintpath: + $(call FN_MKDIR, $(OUTINTDIR)) + +mktestintpath: + $(call FN_MKDIR, $(TESTINTDIR)) + +mkoutpath: + $(call FN_MKDIR, $(OUTDIR)) + +mktestpath: + $(call FN_MKDIR, $(TESTDIR)) + + +.PHONY: runtest + +runtest: $(TESTPATH) + $(TESTPATH) diff --git a/libs/ode-0.16.1/ou/build/make/makefile.os b/libs/ode-0.16.1/ou/build/make/makefile.os new file mode 100644 index 0000000..7b7cf13 --- /dev/null +++ b/libs/ode-0.16.1/ou/build/make/makefile.os @@ -0,0 +1,41 @@ +ifeq ($(OS), Windows_NT) + +OS_TYPE = WIN32 +OS_PLATFORM := i386 + +OS_OBJ_EXT = .obj +OS_LIB_EXT = .lib +OS_LIB_PRE = +OS_EXE_EXT = .exe + +FN_CONVERT_PATH = $(subst /,\,$(subst //,/,$(1))) + +FN_RM = $(OS_VP)erase "$(strip $(call FN_CONVERT_PATH, $(1)))" +FN_MKDIR = $(OS_VP)if NOT EXIST "$(strip $(call FN_CONVERT_PATH, $(1)))" mkdir "$(strip $(call FN_CONVERT_PATH, $(1)))" + +OS_INCLUDE_PATH = $(GCC_PATH)/include $(GCC_PATH)/include/win32 +OS_LIB_PATH += $(GCC_PATH)/lib $(GCC_PATH)/lib/win32 +OS_VP=@ + +else + +OS_OBJ_EXT = .o +OS_LIB_EXT = .a +OS_LIB_PRE = lib +OS_EXE_EXT = + +OS_TYPE = $(subst SunOS,SUN,$(shell uname)) +OS_PLATFORM := $(shell uname -p) +OS_PLATFORM := $(subst x86_64,i386,$(OS_PLATFORM)) +OS_PLATFORM := $(subst i586,i386,$(OS_PLATFORM)) +OS_PLATFORM := $(subst i686,i386,$(OS_PLATFORM)) + +FN_RM = $(OS_VP)rm -rf $(1) +FN_MKDIR = $(OS_VP)test -d $(1) || mkdir -p $(patsubst %/,%,$(1)) + +OS_INCLUDE_PATH = /include /usr/include +OS_LIB_PATH = /lib /usr/lib +OS_VP=@ + +endif + diff --git a/libs/ode-0.16.1/ou/build/vs2005/ou.sln b/libs/ode-0.16.1/ou/build/vs2005/ou.sln new file mode 100644 index 0000000..8ae5b79 --- /dev/null +++ b/libs/ode-0.16.1/ou/build/vs2005/ou.sln @@ -0,0 +1,39 @@ +
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ou", "ou.vcproj", "{7DD3E42F-80C8-430D-87B0-2E6B8147F7D7}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "outest", "..\..\test\vs2005\outest.vcproj", "{B2F294B7-F3F0-4876-AD75-6BB24BA020F8}"
+ ProjectSection(ProjectDependencies) = postProject
+ {7DD3E42F-80C8-430D-87B0-2E6B8147F7D7} = {7DD3E42F-80C8-430D-87B0-2E6B8147F7D7}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {7DD3E42F-80C8-430D-87B0-2E6B8147F7D7}.Debug|Win32.ActiveCfg = Debug|Win32
+ {7DD3E42F-80C8-430D-87B0-2E6B8147F7D7}.Debug|Win32.Build.0 = Debug|Win32
+ {7DD3E42F-80C8-430D-87B0-2E6B8147F7D7}.Debug|x64.ActiveCfg = Debug|x64
+ {7DD3E42F-80C8-430D-87B0-2E6B8147F7D7}.Debug|x64.Build.0 = Debug|x64
+ {7DD3E42F-80C8-430D-87B0-2E6B8147F7D7}.Release|Win32.ActiveCfg = Release|Win32
+ {7DD3E42F-80C8-430D-87B0-2E6B8147F7D7}.Release|Win32.Build.0 = Release|Win32
+ {7DD3E42F-80C8-430D-87B0-2E6B8147F7D7}.Release|x64.ActiveCfg = Release|x64
+ {7DD3E42F-80C8-430D-87B0-2E6B8147F7D7}.Release|x64.Build.0 = Release|x64
+ {B2F294B7-F3F0-4876-AD75-6BB24BA020F8}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B2F294B7-F3F0-4876-AD75-6BB24BA020F8}.Debug|Win32.Build.0 = Debug|Win32
+ {B2F294B7-F3F0-4876-AD75-6BB24BA020F8}.Debug|x64.ActiveCfg = Debug|x64
+ {B2F294B7-F3F0-4876-AD75-6BB24BA020F8}.Debug|x64.Build.0 = Debug|x64
+ {B2F294B7-F3F0-4876-AD75-6BB24BA020F8}.Release|Win32.ActiveCfg = Release|Win32
+ {B2F294B7-F3F0-4876-AD75-6BB24BA020F8}.Release|Win32.Build.0 = Release|Win32
+ {B2F294B7-F3F0-4876-AD75-6BB24BA020F8}.Release|x64.ActiveCfg = Release|x64
+ {B2F294B7-F3F0-4876-AD75-6BB24BA020F8}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/libs/ode-0.16.1/ou/build/vs2005/ou.vcproj b/libs/ode-0.16.1/ou/build/vs2005/ou.vcproj new file mode 100644 index 0000000..3883c21 --- /dev/null +++ b/libs/ode-0.16.1/ou/build/vs2005/ou.vcproj @@ -0,0 +1,494 @@ +<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="ou"
+ ProjectGUID="{7DD3E42F-80C8-430D-87B0-2E6B8147F7D7}"
+ RootNamespace="ou"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory=".\..\..\lib"
+ IntermediateDirectory=".\..\..\intermediate\vs2005\Debug"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ MinimalRebuild="true"
+ ExceptionHandling="0"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ BufferSecurityCheck="false"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ CallingConvention="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1058"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)\$(ProjectName)_debug.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="..\..\lib"
+ IntermediateDirectory=".\..\..\intermediate\vs2005\Debug64"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ MinimalRebuild="true"
+ ExceptionHandling="0"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ BufferSecurityCheck="false"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ CallingConvention="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1058"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)\$(ProjectName)64_debug.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory=".\..\..\lib"
+ IntermediateDirectory=".\..\..\intermediate\vs2005\Release"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="true"
+ OmitFramePointers="true"
+ AdditionalIncludeDirectories="..\..\include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ StringPooling="true"
+ ExceptionHandling="0"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ CallingConvention="1"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1058"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory=".\..\..\lib"
+ IntermediateDirectory=".\..\..\intermediate\vs2005\Release64"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="true"
+ OmitFramePointers="true"
+ AdditionalIncludeDirectories="..\..\include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ StringPooling="true"
+ ExceptionHandling="0"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ CallingConvention="1"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1058"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)\$(ProjectName)64.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+ >
+ <File
+ RelativePath="..\..\src\ou\atomic.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\..\src\ou\customization.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\ou\malloc.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\ou\threadlocalstorage.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl"
+ >
+ <File
+ RelativePath="..\..\include\ou\assert.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\ou\atomic.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\ou\atomicflags.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\ou\customization.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\ou\enumarrays.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\ou\flags.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\ou\flagsdefines.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\ou\inttypes.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\ou\macros.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\ou\malloc.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\ou\namespace.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\ou\platform.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\ou\simpleflags.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\ou\templates.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\ou\threadlocalstorage.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\ou\typewrapper.h"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/libs/ode-0.16.1/ou/build/vs6/ou.dsp b/libs/ode-0.16.1/ou/build/vs6/ou.dsp new file mode 100644 index 0000000..33344fc --- /dev/null +++ b/libs/ode-0.16.1/ou/build/vs6/ou.dsp @@ -0,0 +1,172 @@ +# Microsoft Developer Studio Project File - Name="ou" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=ou - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "ou.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "ou.mak" CFG="ou - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "ou - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "ou - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "ou - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\..\intermediate\vs6\Release"
+# PROP Intermediate_Dir "..\..\intermediate\vs6\Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD CPP /nologo /Gr /MD /W3 /Zi /O2 /Ob2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD BASE RSC /l 0x422 /d "NDEBUG"
+# ADD RSC /l 0x422 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\..\lib\ou.lib"
+
+!ELSEIF "$(CFG)" == "ou - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\intermediate\vs6\Debug"
+# PROP Intermediate_Dir "..\..\intermediate\vs6\Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /Gz /MDd /W3 /Gm /ZI /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x422 /d "_DEBUG"
+# ADD RSC /l 0x422 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\..\lib\ou_debug.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "ou - Win32 Release"
+# Name "ou - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\..\src\ou\atomic.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\src\ou\customization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\src\ou\malloc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\src\ou\threadlocalstorage.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\..\include\ou\assert.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\ou\atomic.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\ou\atomicflags.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\ou\customization.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\ou\enumarrays.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\ou\flags.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\ou\flagsdefines.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\ou\inttypes.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\ou\macros.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\ou\malloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\ou\namespace.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\ou\platform.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\ou\simpleflags.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\ou\templates.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\ou\threadlocalstorage.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\ou\typewrapper.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/libs/ode-0.16.1/ou/build/vs6/ou.dsw b/libs/ode-0.16.1/ou/build/vs6/ou.dsw new file mode 100644 index 0000000..ee249b6 --- /dev/null +++ b/libs/ode-0.16.1/ou/build/vs6/ou.dsw @@ -0,0 +1,44 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "ou"=.\ou.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "outest"=..\..\test\vs6\outest.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name ou
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/libs/ode-0.16.1/ou/configure b/libs/ode-0.16.1/ou/configure new file mode 100755 index 0000000..0e3659f --- /dev/null +++ b/libs/ode-0.16.1/ou/configure @@ -0,0 +1,20569 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for ou 0. +# +# Report bugs to <oleh_derevenko@users.sourceforge.net>. +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: oleh_derevenko@users.sourceforge.net about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 </dev/null +exec 6>&1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='ou' +PACKAGE_TARNAME='ou' +PACKAGE_VERSION='0' +PACKAGE_STRING='ou 0' +PACKAGE_BUGREPORT='oleh_derevenko@users.sourceforge.net' +PACKAGE_URL='' + +ac_unique_file="src/ou/atomic.cpp" +# Factoring default headers for most tests. +ac_includes_default="\ +#include <stdio.h> +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#ifdef STDC_HEADERS +# include <stdlib.h> +# include <stddef.h> +#else +# ifdef HAVE_STDLIB_H +# include <stdlib.h> +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include <memory.h> +# endif +# include <string.h> +#endif +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif +#ifdef HAVE_INTTYPES_H +# include <inttypes.h> +#endif +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +OU_FEATURE_SET +OU_NAMESPACE +CXXCPP +LT_SYS_LIBRARY_PATH +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +ac_ct_AR +AR +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +SED +LIBTOOL +OBJDUMP +DLLTOOL +AS +RANLIB +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +ac_ct_CXX +CXXFLAGS +CXX +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +EGREP +GREP +CPP +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +runstatedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_dependency_tracking +enable_silent_rules +enable_shared +enable_static +with_pic +enable_fast_install +with_aix_soname +with_gnu_ld +with_sysroot +enable_libtool_lock +with_namespace +with_feature_set +enable_asserts +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP +CXX +CXXFLAGS +CCC +LT_SYS_LIBRARY_PATH +CXXCPP +OU_NAMESPACE +OU_FEATURE_SET' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir runstatedir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures ou 0 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/ou] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of ou 0:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-shared[=PKGS] build shared libraries [default=yes] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + --disable-asserts disables debug error checking + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use + both] + --with-aix-soname=aix|svr4|both + shared library versioning (aka "SONAME") variant to + provide on AIX, [default=aix]. + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-sysroot[=DIR] Search for dependent libraries within DIR (or the + compiler's sysroot if not specified). + --with-namespace=name sets the namespace for compiled code + --feature-set=_OU_FEATURE_SET_BASICS|_OU_FEATURE_SET_ATOMICS|_OU_FEATURE_SET_TLS|_OU_FEATURE_SET__MAX + sets the feature set to be enabled + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a + nonstandard directory <lib dir> + LIBS libraries to pass to the linker, e.g. -l<library> + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if + you have headers in a nonstandard directory <include dir> + CPP C preprocessor + CXX C++ compiler command + CXXFLAGS C++ compiler flags + LT_SYS_LIBRARY_PATH + User-defined run-time library search path. + CXXCPP C++ preprocessor + OU_NAMESPACE + which namespace OU will be compiled in + OU_FEATURE_SET + feature set to be compiled within the OU + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to <oleh_derevenko@users.sourceforge.net>. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +ou configure 0 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## --------------------------------------------------- ## +## Report this to oleh_derevenko@users.sourceforge.net ## +## --------------------------------------------------- ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case <limits.h> declares $2. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_cxx_try_cpp LINENO +# ------------------------ +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_cpp + +# ac_fn_cxx_try_link LINENO +# ------------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_link + +# ac_fn_cxx_try_run LINENO +# ------------------------ +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_cxx_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_run + +# ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES +# --------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_cxx_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## --------------------------------------------------- ## +## Report this to oleh_derevenko@users.sourceforge.net ## +## --------------------------------------------------- ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_cxx_check_header_mongrel + +# ac_fn_cxx_check_type LINENO TYPE VAR INCLUDES +# --------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_cxx_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_cxx_check_type + +# ac_fn_c_find_intX_t LINENO BITS VAR +# ----------------------------------- +# Finds a signed integer type with width BITS, setting cache variable VAR +# accordingly. +ac_fn_c_find_intX_t () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5 +$as_echo_n "checking for int$2_t... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + # Order is important - never check a type that is potentially smaller + # than half of the expected target width. + for ac_type in int$2_t 'int' 'long int' \ + 'long long int' 'short int' 'signed char'; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default + enum { N = $2 / 2 - 1 }; +int +main () +{ +static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default + enum { N = $2 / 2 - 1 }; +int +main () +{ +static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1) + < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + case $ac_type in #( + int$2_t) : + eval "$3=yes" ;; #( + *) : + eval "$3=\$ac_type" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if eval test \"x\$"$3"\" = x"no"; then : + +else + break +fi + done +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_find_intX_t + +# ac_fn_c_find_uintX_t LINENO BITS VAR +# ------------------------------------ +# Finds an unsigned integer type with width BITS, setting cache variable VAR +# accordingly. +ac_fn_c_find_uintX_t () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5 +$as_echo_n "checking for uint$2_t... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + # Order is important - never check a type that is potentially smaller + # than half of the expected target width. + for ac_type in uint$2_t 'unsigned int' 'unsigned long int' \ + 'unsigned long long int' 'unsigned short int' 'unsigned char'; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !((($ac_type) -1 >> ($2 / 2 - 1)) >> ($2 / 2 - 1) == 3)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + case $ac_type in #( + uint$2_t) : + eval "$3=yes" ;; #( + *) : + eval "$3=\$ac_type" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if eval test \"x\$"$3"\" = x"no"; then : + +else + break +fi + done +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_find_uintX_t + +# ac_fn_cxx_check_func LINENO FUNC VAR +# ------------------------------------ +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_cxx_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case <limits.h> declares $2. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_cxx_check_func +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by ou $as_me 0, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +# AC_CONFIG_HEADER([config.h]) +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdio.h> +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <string.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ctype.h> +#include <stdlib.h> +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" +if test "x$ac_cv_header_minix_config_h" = xyes; then : + MINIX=yes +else + MINIX= +fi + + + if test "$MINIX" = yes; then + +$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h + + +$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h + + +$as_echo "#define _MINIX 1" >>confdefs.h + + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 +$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } +if ${ac_cv_safe_to_define___extensions__+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# define __EXTENSIONS__ 1 + $ac_includes_default +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_safe_to_define___extensions__=yes +else + ac_cv_safe_to_define___extensions__=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 +$as_echo "$ac_cv_safe_to_define___extensions__" >&6; } + test $ac_cv_safe_to_define___extensions__ = yes && + $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h + + $as_echo "#define _ALL_SOURCE 1" >>confdefs.h + + $as_echo "#define _GNU_SOURCE 1" >>confdefs.h + + $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h + + $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h + + +am__api_version='1.15' + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='ou' + VERSION='0' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: <http://www.gnu.org/software/coreutils/>. + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target OS" >&5 +$as_echo_n "checking target OS... " >&6; } +case "$host_os" in + cygwin* | mingw*) + targetos=_OU_TARGET_OS_WINDOWS + CXXFLAGS="-mthreads $CXXFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: win32" >&5 +$as_echo "win32" >&6; } + ;; + *qnx*) + targetos=_OU_TARGET_OS_QNX + { $as_echo "$as_me:${as_lineno-$LINENO}: result: qnx" >&5 +$as_echo "qnx" >&6; } + ;; + *apple* | *darwin*) + targetos=_OU_TARGET_OS_MAC + { $as_echo "$as_me:${as_lineno-$LINENO}: result: darwin" >&5 +$as_echo "darwin" >&6; } + ;; + *sunos*) + targetos=_OU_TARGET_OS_SUNOS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: sunos" >&5 +$as_echo "sunos" >&6; } + ;; + *aix*) + targetos=_OU_TARGET_OS_AIX + { $as_echo "$as_me:${as_lineno-$LINENO}: result: aix" >&5 +$as_echo "aix" >&6; } + ;; + *) + targetos=_OU_TARGET_OS_GENUNIX + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unix" >&5 +$as_echo "unix" >&6; } + ;; +esac + + +#echo "host OS name: $host_os" +#TODO: _OU_TARGET_BITS ? + + + +# Checks for programs. +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CXX_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdio.h> +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + +enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. +set dummy ${ac_tool_prefix}as; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AS+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AS"; then + ac_cv_prog_AS="$AS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AS="${ac_tool_prefix}as" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AS=$ac_cv_prog_AS +if test -n "$AS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 +$as_echo "$AS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AS"; then + ac_ct_AS=$AS + # Extract the first word of "as", so it can be a program name with args. +set dummy as; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AS+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AS"; then + ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AS="as" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AS=$ac_cv_prog_ac_ct_AS +if test -n "$ac_ct_AS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5 +$as_echo "$ac_ct_AS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AS" = x; then + AS="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AS=$ac_ct_AS + fi +else + AS="$ac_cv_prog_AS" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + + ;; +esac + +test -z "$AS" && AS=as + + + + + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4.6' +macro_revision='2.4.6' + + + + + + + + + + + + + +ltmain=$ac_aux_dir/ltmain.sh + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case $ECHO in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_FGREP" || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in + *GNU* | *'with BFD'*) + test no != "$with_gnu_ld" && break + ;; + *) + test yes != "$with_gnu_ld" && break + ;; + esac + fi + done + IFS=$lt_save_ifs +else + lt_cv_path_LD=$LD # Let the user override the test with a path. +fi +fi + +LD=$lt_cv_path_LD +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + lt_cv_prog_gnu_ld=yes + ;; +*) + lt_cv_prog_gnu_ld=no + ;; +esac +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM=$NM +else + lt_nm_to_check=${ac_tool_prefix}nm + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break 2 + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break 2 + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS=$lt_save_ifs + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols -headers" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test : != "$DUMPBIN"; then + NM=$DUMPBIN + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring=ABCD + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test 17 != "$i" # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n "$lt_cv_sys_max_cmd_len"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +$as_echo_n "checking how to convert $build file names to $host format... " >&6; } +if ${lt_cv_to_host_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +$as_echo "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } +if ${lt_cv_to_tool_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +$as_echo "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test yes != "$GCC"; then + reload_cmds=false + fi + ;; + darwin*) + if test yes = "$GCC"; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# 'unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +$as_echo_n "checking how to associate runtime and link libraries... " >&6; } +if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd=$ECHO + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cru} + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +$as_echo_n "checking for archiver @FILE support... " >&6; } +if ${lt_cv_ar_at_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -eq "$ac_status"; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -ne "$ac_status"; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +$as_echo "$lt_cv_ar_at_file" >&6; } + +if test no = "$lt_cv_ar_at_file"; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + bitrig* | openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test ia64 = "$host_cpu"; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS=conftstm.$ac_objext + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test yes = "$pipe_works"; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; +else + with_sysroot=no +fi + + +lt_sysroot= +case $with_sysroot in #( + yes) + if test yes = "$GCC"; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 +$as_echo "$with_sysroot" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +$as_echo "${lt_sysroot:-no}" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 +$as_echo_n "checking for a working dd... " >&6; } +if ${ac_cv_path_lt_DD+:} false; then : + $as_echo_n "(cached) " >&6 +else + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +if test -z "$lt_DD"; then + ac_path_lt_DD_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in dd; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_lt_DD" || continue +if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi + $ac_path_lt_DD_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_lt_DD"; then + : + fi +else + ac_cv_path_lt_DD=$lt_DD +fi + +rm -f conftest.i conftest2.i conftest.out +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 +$as_echo "$ac_cv_path_lt_DD" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 +$as_echo_n "checking how to truncate binary pipes... " >&6; } +if ${lt_cv_truncate_bin+:} false; then : + $as_echo_n "(cached) " >&6 +else + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 +$as_echo "$lt_cv_truncate_bin" >&6; } + + + + + + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test no = "$enable_libtool_lock" || enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE=32 + ;; + *ELF-64*) + HPUX_IA64_MODE=64 + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test yes = "$lt_cv_prog_gnu_ld"; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test yes != "$lt_cv_cc_needs_belf"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS=$SAVE_CFLAGS + fi + ;; +*-*solaris*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*|x86_64-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD=${LD-ld}_sol2 + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks=$enable_libtool_lock + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +$as_echo "$MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if ${lt_cv_path_mainfest_tool+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +$as_echo "$lt_cv_path_mainfest_tool" >&6; } +if test yes != "$lt_cv_path_mainfest_tool"; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "$LT_MULTI_MODULE"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&5 + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if ${lt_cv_ld_force_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&5 + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + 10.[012][,.]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test yes = "$lt_cv_apple_cc_single_mod"; then + _lt_dar_single_mod='$single_module' + fi + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' + fi + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + +func_stripname_cnf () +{ + case $2 in + .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;; + *) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;; + esac +} # func_stripname_cnf + + + + + +# Set options + + + + enable_dlopen=no + + + + # Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_shared=yes +fi + + + + + + + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + pic_mode=default +fi + + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[5-9]*,yes) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 +$as_echo_n "checking which variant of shared library versioning to provide... " >&6; } + +# Check whether --with-aix-soname was given. +if test "${with_aix_soname+set}" = set; then : + withval=$with_aix_soname; case $withval in + aix|svr4|both) + ;; + *) + as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname +else + if ${lt_cv_with_aix_soname+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_with_aix_soname=aix +fi + + with_aix_soname=$lt_cv_with_aix_soname +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 +$as_echo "$with_aix_soname" >&6; } + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS=$ltmain + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld=$lt_cv_prog_gnu_ld + +old_CC=$CC +old_CFLAGS=$CFLAGS + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +func_cc_basename $compiler +cc_basename=$func_cc_basename_result + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/${ac_tool_prefix}file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC=$CC +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test yes = "$GCC"; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test yes = "$GCC"; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + lt_prog_compiler_pic='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +$as_echo "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works"; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works"; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test no = "$hard_links"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test yes != "$GCC"; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd* | bitrig*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test yes = "$with_gnu_ld"; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test yes = "$lt_use_gnu_ld_interface"; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='$wl' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + export_dynamic_flag_spec='$wl--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test ia64 != "$host_cpu"; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='$wl--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test linux-dietlibc = "$host_os"; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test no = "$tmp_diet" + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + tcc*) + export_dynamic_flag_spec='-rdynamic' + ;; + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test no = "$ld_shlibs"; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then + aix_use_runtimelinking=yes + break + fi + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + hardcode_direct=no + hardcode_direct_absolute=no + ;; + esac + + if test yes = "$GCC"; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + export_dynamic_flag_spec='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' $wl-bernotok' + allow_undefined_flag=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test yes = "$GCC"; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='$wl-E' + ;; + + hpux10*) + if test yes,no = "$GCC,$with_gnu_ld"; then + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test yes,no = "$GCC,$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if ${lt_cv_prog_compiler__b+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test yes = "$lt_cv_prog_compiler__b"; then + archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test yes = "$GCC"; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if ${lt_cv_irix_exported_symbol+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_irix_exported_symbol=yes +else + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +$as_echo "$lt_cv_irix_exported_symbol" >&6; } + if test yes = "$lt_cv_irix_exported_symbol"; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' + fi + link_all_deplibs=no + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + ld_shlibs=yes + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + else + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + osf3*) + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test yes = "$GCC"; then + wlarc='$wl' + archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='$wl' + archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. GCC discards it without '$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test yes = "$GCC"; then + whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test sequent = "$host_vendor"; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='$wl-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='$wl-z,text' + allow_undefined_flag='$wl-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test sni = "$host_vendor"; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='$wl-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test no = "$ld_shlibs" && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test yes = "$GCC"; then + case $host_os in + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary... + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo = "/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's|/\([A-Za-z]:\)|\1|g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + + + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib<name>.so + # instead of lib<name>.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a(lib.so.V)' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test yes = "$hardcode_automatic"; then + + # We can hardcode non-existent directories. + if test no != "$hardcode_direct" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && + test no != "$hardcode_minus_L"; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test relink = "$hardcode_action" || + test yes = "$inherit_rpath"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test yes != "$enable_dlopen"; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen=load_add_on + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen=LoadLibrary + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else + + lt_cv_dlopen=dyld + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + lt_cv_dlopen=shl_load +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + lt_cv_dlopen=dlopen +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test no = "$lt_cv_dlopen"; then + enable_dlopen=no + else + enable_dlopen=yes + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS=$LDFLAGS + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS=$LIBS + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test yes = "$lt_cv_dlopen_self"; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP"; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report what library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +CC=$lt_save_CC + + if test -n "$CXX" && ( test no != "$CXX" && + ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || + (test g++ != "$CXX"))); then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if ${ac_cv_prog_CXXCPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +else + _lt_caught_CXX_error=yes +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +compiler_needs_object_CXX=no +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_direct_absolute_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +inherit_rpath_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +reload_flag_CXX=$reload_flag +reload_cmds_CXX=$reload_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_caught_CXX_error"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + + # save warnings/boilerplate of simple test code + ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + + ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + compiler_CXX=$CC + func_cc_basename $compiler +cc_basename=$func_cc_basename_result + + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test yes = "$GXX"; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' + else + lt_prog_compiler_no_builtin_flag_CXX= + fi + + if test yes = "$GXX"; then + # Set up default GNU C++ configuration + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in + *GNU* | *'with BFD'*) + test no != "$with_gnu_ld" && break + ;; + *) + test yes != "$with_gnu_ld" && break + ;; + esac + fi + done + IFS=$lt_save_ifs +else + lt_cv_path_LD=$LD # Let the user override the test with a path. +fi +fi + +LD=$lt_cv_path_LD +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + lt_cv_prog_gnu_ld=yes + ;; +*) + lt_cv_prog_gnu_ld=no + ;; +esac +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test yes = "$with_gnu_ld"; then + archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='$wl' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + ld_shlibs_CXX=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix[4-9]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + file_list_spec_CXX='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + hardcode_direct_CXX=no + hardcode_direct_absolute_CXX=no + ;; + esac + + if test yes = "$GXX"; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag=$shared_flag' $wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + export_dynamic_flag_spec_CXX='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + always_export_symbols_CXX=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + # The "-G" linker flag allows undefined symbols. + no_undefined_flag_CXX='-bernotok' + # Determine the default libpath from the value encoded in an empty + # executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec_CXX='$wl-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' $wl-bernotok' + allow_undefined_flag_CXX=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + fi + archive_cmds_need_lc_CXX=yes + archive_expsym_cmds_CXX='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared + # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_CXX=' ' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=yes + file_list_spec_CXX='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' + enable_shared_with_static_runtimes_CXX=yes + # Don't use ranlib + old_postinstall_cmds_CXX='chmod 644 $oldlib' + postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + export_dynamic_flag_spec_CXX='$wl--export-all-symbols' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + + + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec_CXX='' + fi + link_all_deplibs_CXX=yes + allow_undefined_flag_CXX=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds_CXX="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + if test yes != "$lt_cv_apple_cc_single_mod"; then + archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" + archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" + fi + + else + ld_shlibs_CXX=no + fi + + ;; + + os2*) + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_minus_L_CXX=yes + allow_undefined_flag_CXX=unsupported + shrext_cmds=.dll + archive_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes_CXX=yes + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + ld_shlibs_CXX=no + ;; + + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + + haiku*) + archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + link_all_deplibs_CXX=yes + ;; + + hpux9*) + hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='$wl-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + export_dynamic_flag_spec_CXX='$wl-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + interix[3-9]*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + hardcode_libdir_separator_CXX=: + inherit_rpath_CXX=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [1-5].* | *pgcpp\ [1-5].*) + prelink_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + old_archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='$wl--rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + whole_archive_flag_spec_CXX='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' + hardcode_libdir_flag_spec_CXX='-R$libdir' + whole_archive_flag_spec_CXX='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object_CXX=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + ld_shlibs_CXX=yes + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + hardcode_direct_absolute_CXX=yes + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='$wl-E' + whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + ld_shlibs_CXX=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + case $host in + osf3*) + allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' + archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + ;; + *) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ + $RM $lib.exp' + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + ;; + esac + + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes,no = "$GXX,$with_gnu_ld"; then + allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' + case $host in + osf3*) + archive_cmds_CXX='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + *) + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test yes,no = "$GXX,$with_gnu_ld"; then + no_undefined_flag_CXX=' $wl-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require '-G' NOT '-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir' + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + whole_archive_flag_spec_CXX='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='$wl-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_CXX='$wl-z,text' + allow_undefined_flag_CXX='$wl-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-R,$libdir' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ + '"$old_archive_cmds_CXX" + reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ + '"$reload_cmds_CXX" + ;; + *) + archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } + test no = "$ld_shlibs_CXX" && can_build_shared=no + + GCC_CXX=$GXX + LD_CXX=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + # Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF + + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $prev$p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test x-L = "$p" || + test x-R = "$p"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test no = "$pre_test_object_deps_done"; then + case $prev in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX=$prev$p + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} $prev$p" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX=$prev$p + else + postdeps_CXX="${postdeps_CXX} $prev$p" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test no = "$pre_test_object_deps_done"; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX=$p + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX=$p + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +case $host_os in +interix[3-9]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; +esac + + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + compiler_lib_search_dirs_CXX= +if test -n "${compiler_lib_search_path_CXX}"; then + compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | $SED -e 's! -L! !g' -e 's!^ !!'` +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + + + # C++ specific cases for pic, static, wl, etc. + if test yes = "$GXX"; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + lt_prog_compiler_pic_CXX='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic_CXX='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static_CXX='$wl-static' + ;; + esac + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static_CXX= + ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix[4-9]*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='$wl-a ${wl}archive' + if test ia64 != "$host_cpu"; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='$wl-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64, which still supported -KPIC. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-qpic' + lt_prog_compiler_static_CXX='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } +lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } +if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_CXX=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works_CXX=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_CXX=yes + fi + else + lt_cv_prog_compiler_static_works_CXX=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then + : +else + lt_prog_compiler_static_CXX= +fi + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test no = "$hard_links"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + case $host_os in + aix[4-9]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX=$ltdll_cmds + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + ;; + esac + ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs_CXX=no + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } +test no = "$ld_shlibs_CXX" && can_build_shared=no + +with_gnu_ld_CXX=$with_gnu_ld + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc_CXX=no + else + lt_cv_archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } + archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + + + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib<name>.so + # instead of lib<name>.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a(lib.so.V)' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec_CXX='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || + test -n "$runpath_var_CXX" || + test yes = "$hardcode_automatic_CXX"; then + + # We can hardcode non-existent directories. + if test no != "$hardcode_direct_CXX" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" && + test no != "$hardcode_minus_L_CXX"; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 +$as_echo "$hardcode_action_CXX" >&6; } + +if test relink = "$hardcode_action_CXX" || + test yes = "$inherit_rpath_CXX"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test yes != "$_lt_caught_CXX_error" + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + + + +# Checks for libraries. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lc" >&5 +$as_echo_n "checking for main in -lc... " >&6; } +if ${ac_cv_lib_c_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lc $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + ac_cv_lib_c_main=yes +else + ac_cv_lib_c_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_main" >&5 +$as_echo "$ac_cv_lib_c_main" >&6; } +if test "x$ac_cv_lib_c_main" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBC 1 +_ACEOF + + LIBS="-lc $LIBS" + +fi + # needed for sunos? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lpthread" >&5 +$as_echo_n "checking for main in -lpthread... " >&6; } +if ${ac_cv_lib_pthread_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthread $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + ac_cv_lib_pthread_main=yes +else + ac_cv_lib_pthread_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_main" >&5 +$as_echo "$ac_cv_lib_pthread_main" >&6; } +if test "x$ac_cv_lib_pthread_main" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBPTHREAD 1 +_ACEOF + + LIBS="-lpthread $LIBS" + +fi + + +$as_echo "#define _REENTRANT 1" >>confdefs.h + + + + +# Checks for header files. + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <string.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ctype.h> +#include <stdlib.h> +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_cxx_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +for ac_header in inttypes.h malloc.h stddef.h stdlib.h string.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +# Checks for typedefs, structures, and compiler characteristics. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5 +$as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } +if ${ac_cv_header_stdbool_h+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include <stdbool.h> + #ifndef bool + "error: bool is not defined" + #endif + #ifndef false + "error: false is not defined" + #endif + #if false + "error: false is not 0" + #endif + #ifndef true + "error: true is not defined" + #endif + #if true != 1 + "error: true is not 1" + #endif + #ifndef __bool_true_false_are_defined + "error: __bool_true_false_are_defined is not defined" + #endif + + struct s { _Bool s: 1; _Bool t; } s; + + char a[true == 1 ? 1 : -1]; + char b[false == 0 ? 1 : -1]; + char c[__bool_true_false_are_defined == 1 ? 1 : -1]; + char d[(bool) 0.5 == true ? 1 : -1]; + /* See body of main program for 'e'. */ + char f[(_Bool) 0.0 == false ? 1 : -1]; + char g[true]; + char h[sizeof (_Bool)]; + char i[sizeof s.t]; + enum { j = false, k = true, l = false * true, m = true * 256 }; + /* The following fails for + HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ + _Bool n[m]; + char o[sizeof n == m * sizeof n[0] ? 1 : -1]; + char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; + /* Catch a bug in an HP-UX C compiler. See + http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html + http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html + */ + _Bool q = true; + _Bool *pq = &q; + +int +main () +{ + + bool e = &s; + *pq |= q; + *pq |= ! q; + /* Refer to every declared value, to avoid compiler optimizations. */ + return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l + + !m + !n + !o + !p + !q + !pq); + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_header_stdbool_h=yes +else + ac_cv_header_stdbool_h=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5 +$as_echo "$ac_cv_header_stdbool_h" >&6; } + ac_fn_cxx_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default" +if test "x$ac_cv_type__Bool" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE__BOOL 1 +_ACEOF + + +fi + + +if test $ac_cv_header_stdbool_h = yes; then + +$as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 +$as_echo_n "checking for an ANSI C-conforming const... " >&6; } +if ${ac_cv_c_const+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#ifndef __cplusplus + /* Ultrix mips cc rejects this sort of thing. */ + typedef int charset[2]; + const charset cs = { 0, 0 }; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this sort of thing. */ + char tx; + char *t = &tx; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; } bx; + struct s *b = &bx; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_c_const=yes +else + ac_cv_c_const=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 +$as_echo "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +$as_echo "#define const /**/" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 +$as_echo_n "checking for inline... " >&6; } +if ${ac_cv_c_inline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_c_inline=$ac_kw +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 +$as_echo "$ac_cv_c_inline" >&6; } + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + +ac_fn_c_find_intX_t "$LINENO" "16" "ac_cv_c_int16_t" +case $ac_cv_c_int16_t in #( + no|yes) ;; #( + *) + +cat >>confdefs.h <<_ACEOF +#define int16_t $ac_cv_c_int16_t +_ACEOF +;; +esac + +ac_fn_c_find_intX_t "$LINENO" "32" "ac_cv_c_int32_t" +case $ac_cv_c_int32_t in #( + no|yes) ;; #( + *) + +cat >>confdefs.h <<_ACEOF +#define int32_t $ac_cv_c_int32_t +_ACEOF +;; +esac + +ac_fn_c_find_intX_t "$LINENO" "64" "ac_cv_c_int64_t" +case $ac_cv_c_int64_t in #( + no|yes) ;; #( + *) + +cat >>confdefs.h <<_ACEOF +#define int64_t $ac_cv_c_int64_t +_ACEOF +;; +esac + +ac_fn_c_find_intX_t "$LINENO" "8" "ac_cv_c_int8_t" +case $ac_cv_c_int8_t in #( + no|yes) ;; #( + *) + +cat >>confdefs.h <<_ACEOF +#define int8_t $ac_cv_c_int8_t +_ACEOF +;; +esac + +ac_fn_cxx_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + +ac_fn_c_find_uintX_t "$LINENO" "16" "ac_cv_c_uint16_t" +case $ac_cv_c_uint16_t in #( + no|yes) ;; #( + *) + + +cat >>confdefs.h <<_ACEOF +#define uint16_t $ac_cv_c_uint16_t +_ACEOF +;; + esac + +ac_fn_c_find_uintX_t "$LINENO" "32" "ac_cv_c_uint32_t" +case $ac_cv_c_uint32_t in #( + no|yes) ;; #( + *) + +$as_echo "#define _UINT32_T 1" >>confdefs.h + + +cat >>confdefs.h <<_ACEOF +#define uint32_t $ac_cv_c_uint32_t +_ACEOF +;; + esac + +ac_fn_c_find_uintX_t "$LINENO" "64" "ac_cv_c_uint64_t" +case $ac_cv_c_uint64_t in #( + no|yes) ;; #( + *) + +$as_echo "#define _UINT64_T 1" >>confdefs.h + + +cat >>confdefs.h <<_ACEOF +#define uint64_t $ac_cv_c_uint64_t +_ACEOF +;; + esac + +ac_fn_c_find_uintX_t "$LINENO" "8" "ac_cv_c_uint8_t" +case $ac_cv_c_uint8_t in #( + no|yes) ;; #( + *) + +$as_echo "#define _UINT8_T 1" >>confdefs.h + + +cat >>confdefs.h <<_ACEOF +#define uint8_t $ac_cv_c_uint8_t +_ACEOF +;; + esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working volatile" >&5 +$as_echo_n "checking for working volatile... " >&6; } +if ${ac_cv_c_volatile+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +volatile int x; +int * volatile y = (int *) 0; +return !x && !y; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_c_volatile=yes +else + ac_cv_c_volatile=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_volatile" >&5 +$as_echo "$ac_cv_c_volatile" >&6; } +if test $ac_cv_c_volatile = no; then + +$as_echo "#define volatile /**/" >>confdefs.h + +fi + +ac_fn_cxx_check_type "$LINENO" "ptrdiff_t" "ac_cv_type_ptrdiff_t" "$ac_includes_default" +if test "x$ac_cv_type_ptrdiff_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_PTRDIFF_T 1 +_ACEOF + + +fi + + +# Checks for library functions. +for ac_func in memset +do : + ac_fn_cxx_check_func "$LINENO" "memset" "ac_cv_func_memset" +if test "x$ac_cv_func_memset" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_MEMSET 1 +_ACEOF + +fi +done + + +if test $targetos = _OU_TARGET_OS_MAC +then + MAC_OS_X_VERSION=1000 + ac_fn_cxx_check_func "$LINENO" "OSAtomicAdd32Barrier" "ac_cv_func_OSAtomicAdd32Barrier" +if test "x$ac_cv_func_OSAtomicAdd32Barrier" = xyes; then : + MAC_OS_X_VERSION=1040 +fi + + ac_fn_cxx_check_func "$LINENO" "OSAtomicAnd32OrigBarrier" "ac_cv_func_OSAtomicAnd32OrigBarrier" +if test "x$ac_cv_func_OSAtomicAnd32OrigBarrier" = xyes; then : + MAC_OS_X_VERSION=1050 +fi + + +cat >>confdefs.h <<_ACEOF +#define MAC_OS_X_VERSION $MAC_OS_X_VERSION +_ACEOF + +fi + +if test $targetos = _OU_TARGET_OS_SUNOS +then + ac_fn_cxx_check_func "$LINENO" "atomic_inc_32_nv" "ac_cv_func_atomic_inc_32_nv" +if test "x$ac_cv_func_atomic_inc_32_nv" = xyes; then : + +else + targetos=_OU_TARGET_OS_GENUNIX +fi + +fi + +cat >>confdefs.h <<_ACEOF +#define _OU_TARGET_OS $targetos +_ACEOF + + + + + +# Check whether --with-namespace was given. +if test "${with_namespace+set}" = set; then : + withval=$with_namespace; OU_NAMESPACE=$withval +fi + +if test x$OU_NAMESPACE = xno -o x$OU_NAMESPACE = x +then + OU_NAMESPACE="ou" +fi +CPPFLAGS="$CPPFLAGS -D_OU_NAMESPACE=$OU_NAMESPACE" + + + +# Check whether --with-feature-set was given. +if test "${with_feature_set+set}" = set; then : + withval=$with_feature_set; OU_FEATURE_SET=$withval +fi + +if test x$OU_FEATURE_SET = xno -o x$OU_FEATURE_SET = x +then + OU_NAMESPACE=_OU_FEATURE_SET__MAX +fi +CPPFLAGS="$CPPFLAGS -D_OU_FEATURE_SET=$OU_FEATURE_SET" + +# Check whether --enable-asserts was given. +if test "${enable_asserts+set}" = set; then : + enableval=$enable_asserts; asserts=$enableval +else + asserts=yes +fi + +if test x$asserts = xno +then + CPPFLAGS="$CPPFLAGS -DNDEBUG" +fi + +ac_config_files="$ac_config_files Makefile include/ou/Makefile src/ou/Makefile test/Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +ac_script=' +:mline +/\\$/{ + N + s,\\\n,, + b mline +} +t clear +:clear +s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g +t quote +s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g +t quote +b any +:quote +s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g +s/\[/\\&/g +s/\]/\\&/g +s/\$/$$/g +H +:any +${ + g + s/^\n// + s/\n/ /g + p +} +' +DEFS=`sed -n "$ac_script" confdefs.h` + + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by ou $as_me 0, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Configuration commands: +$config_commands + +Report bugs to <oleh_derevenko@users.sourceforge.net>." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +ou config.status 0 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h | --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' +configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' +predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' +postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' +predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' +postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' +LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' +reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' +reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' +GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' +inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' +link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' +always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' +exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' +predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' +postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' +predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' +postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in AS \ +DLLTOOL \ +OBJDUMP \ +SHELL \ +ECHO \ +PATH_SEPARATOR \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_import \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +lt_cv_nm_interface \ +nm_file_list_spec \ +lt_cv_truncate_bin \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib \ +compiler_lib_search_dirs \ +predep_objects \ +postdep_objects \ +predeps \ +postdeps \ +compiler_lib_search_path \ +LD_CXX \ +reload_flag_CXX \ +compiler_CXX \ +lt_prog_compiler_no_builtin_flag_CXX \ +lt_prog_compiler_pic_CXX \ +lt_prog_compiler_wl_CXX \ +lt_prog_compiler_static_CXX \ +lt_cv_prog_compiler_c_o_CXX \ +export_dynamic_flag_spec_CXX \ +whole_archive_flag_spec_CXX \ +compiler_needs_object_CXX \ +with_gnu_ld_CXX \ +allow_undefined_flag_CXX \ +no_undefined_flag_CXX \ +hardcode_libdir_flag_spec_CXX \ +hardcode_libdir_separator_CXX \ +exclude_expsyms_CXX \ +include_expsyms_CXX \ +file_list_spec_CXX \ +compiler_lib_search_dirs_CXX \ +predep_objects_CXX \ +postdep_objects_CXX \ +predeps_CXX \ +postdeps_CXX \ +compiler_lib_search_path_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +configure_time_dlsearch_path \ +configure_time_lt_sys_library_path \ +reload_cmds_CXX \ +old_archive_cmds_CXX \ +old_archive_from_new_cmds_CXX \ +old_archive_from_expsyms_cmds_CXX \ +archive_cmds_CXX \ +archive_expsym_cmds_CXX \ +module_cmds_CXX \ +module_expsym_cmds_CXX \ +export_symbols_cmds_CXX \ +prelink_cmds_CXX \ +postlink_cmds_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' + +# See if we are running on zsh, and set the options that allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + RM='$RM' + ofile='$ofile' + + + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "include/ou/Makefile") CONFIG_FILES="$CONFIG_FILES include/ou/Makefile" ;; + "src/ou/Makefile") CONFIG_FILES="$CONFIG_FILES src/ou/Makefile" ;; + "test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' <conf$$subs.awk | sed ' +/^[^""]/{ + N + s/\n// +} +' >>$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + + +eval set X " :F $CONFIG_FILES :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options that allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST + fi + + cfgfile=${ofile}T + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL +# Generated automatically by $as_me ($PACKAGE) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + +# Copyright (C) 2014 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool 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 2 of of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 <http://www.gnu.org/licenses/>. + + +# The names of the tagged configurations supported by this script. +available_tags='CXX ' + +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} + +# ### BEGIN LIBTOOL CONFIG + +# Assembler program. +AS=$lt_AS + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Object dumper program. +OBJDUMP=$lt_OBJDUMP + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shared archive member basename,for filename based shared library versioning on AIX. +shared_archive_member_spec=$shared_archive_member_spec + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The PATH separator for the build system. +PATH_SEPARATOR=$lt_PATH_SEPARATOR + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm into a list of symbols to manually relocate. +global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# The name lister interface. +nm_interface=$lt_lt_cv_nm_interface + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and where our libraries should be installed. +lt_sysroot=$lt_sysroot + +# Command to truncate a binary pipe. +lt_truncate_bin=$lt_lt_cv_truncate_bin + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Detected run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path + +# Explicit LT_SYS_LIBRARY_PATH set during ./configure time. +configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects +postdep_objects=$lt_postdep_objects +predeps=$lt_predeps +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + +# ### END LIBTOOL CONFIG + +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + + +# ### END FUNCTIONS SHARED WITH CONFIGURE + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain=$ac_aux_dir/ltmain.sh + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + + cat <<_LT_EOF >> "$ofile" + +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# How to create reloadable object files. +reload_flag=$lt_reload_flag_CXX +reload_cmds=$lt_reload_cmds_CXX + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds_CXX + +# A language specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU compiler? +with_gcc=$GCC_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object_CXX + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld_CXX + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute_CXX + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath_CXX + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds_CXX + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds_CXX + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec_CXX + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects_CXX +postdep_objects=$lt_postdep_objects_CXX +predeps=$lt_predeps_CXX +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_CXX + +# ### END LIBTOOL TAG CONFIG: CXX +_LT_EOF + + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + +echo "OU namespace: $OU_NAMESPACE" +echo "OU feature set: $OU_FEATURE_SET" + diff --git a/libs/ode-0.16.1/ou/configure.ac b/libs/ode-0.16.1/ou/configure.ac new file mode 100644 index 0000000..f78fc1a --- /dev/null +++ b/libs/ode-0.16.1/ou/configure.ac @@ -0,0 +1,145 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.61) +AC_INIT(ou, 0, oleh_derevenko@users.sourceforge.net) +AC_CONFIG_SRCDIR([src/ou/atomic.cpp]) +# AC_CONFIG_HEADER([config.h]) +AC_CANONICAL_HOST +AC_USE_SYSTEM_EXTENSIONS +AM_INIT_AUTOMAKE(foreign) + +AC_LANG([C++]) + +AC_MSG_CHECKING([target OS]) +case "$host_os" in + cygwin* | mingw*) + targetos=_OU_TARGET_OS_WINDOWS + CXXFLAGS="-mthreads $CXXFLAGS" + AC_MSG_RESULT([win32]) + ;; + *qnx*) + targetos=_OU_TARGET_OS_QNX + AC_MSG_RESULT([qnx]) + ;; + *apple* | *darwin*) + targetos=_OU_TARGET_OS_MAC + AC_MSG_RESULT([darwin]) + ;; + *sunos*) + targetos=_OU_TARGET_OS_SUNOS + AC_MSG_RESULT([sunos]) + ;; + *aix*) + targetos=_OU_TARGET_OS_AIX + AC_MSG_RESULT([aix]) + ;; + *) + targetos=_OU_TARGET_OS_GENUNIX + AC_MSG_RESULT([unix]) + ;; +esac + + +#echo "host OS name: $host_os" +#TODO: _OU_TARGET_BITS ? + + + +# Checks for programs. +AC_PROG_CXX +AC_PROG_CC +AC_PROG_AWK +AC_PROG_INSTALL +AC_PROG_RANLIB +AC_PROG_CPP +AC_PROG_MKDIR_P +AC_LIBTOOL_WIN32_DLL +AC_PROG_LIBTOOL + + +# Checks for libraries. +AC_CHECK_LIB([c], main) # needed for sunos? +AC_CHECK_LIB([pthread], [main]) +AC_DEFINE(_REENTRANT,1,[enable thread-safe functions]) + + + +# Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS([inttypes.h malloc.h stddef.h stdlib.h string.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_HEADER_STDBOOL +AC_C_CONST +AC_C_INLINE +AC_TYPE_INT16_T +AC_TYPE_INT32_T +AC_TYPE_INT64_T +AC_TYPE_INT8_T +AC_TYPE_SIZE_T +AC_TYPE_UINT16_T +AC_TYPE_UINT32_T +AC_TYPE_UINT64_T +AC_TYPE_UINT8_T +AC_C_VOLATILE +AC_CHECK_TYPES([ptrdiff_t]) + +# Checks for library functions. +AC_CHECK_FUNCS([memset]) + +if test $targetos = _OU_TARGET_OS_MAC +then + MAC_OS_X_VERSION=1000 + AC_CHECK_FUNC([OSAtomicAdd32Barrier], [MAC_OS_X_VERSION=1040]) + AC_CHECK_FUNC([OSAtomicAnd32OrigBarrier], [MAC_OS_X_VERSION=1050]) + AC_DEFINE_UNQUOTED(MAC_OS_X_VERSION, $MAC_OS_X_VERSION, [Mac OS X version]) +fi + +if test $targetos = _OU_TARGET_OS_SUNOS +then + AC_CHECK_FUNC(atomic_inc_32_nv, [], + [targetos=_OU_TARGET_OS_GENUNIX]) +fi + +AC_DEFINE_UNQUOTED(_OU_TARGET_OS, $targetos) + + +AC_ARG_VAR([OU_NAMESPACE], [which namespace OU will be compiled in]) +AC_ARG_WITH([namespace], + AC_HELP_STRING([--with-namespace=name],[sets the namespace for compiled code]), + [OU_NAMESPACE=$withval]) +if test x$OU_NAMESPACE = xno -o x$OU_NAMESPACE = x +then + OU_NAMESPACE="ou" +fi +CPPFLAGS="$CPPFLAGS -D_OU_NAMESPACE=$OU_NAMESPACE" + +AC_ARG_VAR([OU_FEATURE_SET], [feature set to be compiled within the OU]) +AC_ARG_WITH([feature-set], + AC_HELP_STRING([--feature-set=_OU_FEATURE_SET_BASICS|_OU_FEATURE_SET_ATOMICS|_OU_FEATURE_SET_TLS|_OU_FEATURE_SET__MAX],[sets the feature set to be enabled]), + [OU_FEATURE_SET=$withval]) +if test x$OU_FEATURE_SET = xno -o x$OU_FEATURE_SET = x +then + OU_NAMESPACE=_OU_FEATURE_SET__MAX +fi +CPPFLAGS="$CPPFLAGS -D_OU_FEATURE_SET=$OU_FEATURE_SET" + +AC_ARG_ENABLE([asserts], + AS_HELP_STRING([--disable-asserts], + [disables debug error checking]), + asserts=$enableval,asserts=yes) +if test x$asserts = xno +then + CPPFLAGS="$CPPFLAGS -DNDEBUG" +fi + +AC_CONFIG_FILES([Makefile + include/ou/Makefile + src/ou/Makefile + test/Makefile]) +AC_OUTPUT + +echo "OU namespace: $OU_NAMESPACE" +echo "OU feature set: $OU_FEATURE_SET" + diff --git a/libs/ode-0.16.1/ou/include/ou/Makefile.am b/libs/ode-0.16.1/ou/include/ou/Makefile.am new file mode 100644 index 0000000..fce65c5 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/Makefile.am @@ -0,0 +1,17 @@ +EXTRA_DIST = assert.h \ + atomicflags.h \ + atomic.h \ + customization.h \ + enumarrays.h \ + features.h \ + flagsdefines.h \ + flags.h \ + inttypes.h \ + macros.h \ + malloc.h \ + namespace.h \ + platform.h \ + simpleflags.h \ + templates.h \ + threadlocalstorage.h \ + typewrapper.h diff --git a/libs/ode-0.16.1/ou/include/ou/Makefile.in b/libs/ode-0.16.1/ou/include/ou/Makefile.in new file mode 100644 index 0000000..bd481ec --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/Makefile.in @@ -0,0 +1,457 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = include/ou +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +OU_FEATURE_SET = @OU_FEATURE_SET@ +OU_NAMESPACE = @OU_NAMESPACE@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = assert.h \ + atomicflags.h \ + atomic.h \ + customization.h \ + enumarrays.h \ + features.h \ + flagsdefines.h \ + flags.h \ + inttypes.h \ + macros.h \ + malloc.h \ + namespace.h \ + platform.h \ + simpleflags.h \ + templates.h \ + threadlocalstorage.h \ + typewrapper.h + +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/ou/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign include/ou/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/ou/include/ou/assert.h b/libs/ode-0.16.1/ou/include/ou/assert.h new file mode 100644 index 0000000..d3147b3 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/assert.h @@ -0,0 +1,188 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_ASSERT_H_INCLUDED +#define __OU_ASSERT_H_INCLUDED + + +/** + * \file + * \brief Definitions of assertion checking macros. + * + * This file contains definitions of assertion failure check macros. + * These include \c OU_ASSERT, \c OU_VERIFY and \c OU_CHECK. + * Assertion failure handler is common for all three macros and is customizable. + * If assertion checks are not customized, system \c assert() function is used. + * \see CAssertionCheckCustomization + */ + + +#include <ou/customization.h> +#include <ou/namespace.h> + + +/** + * \def OU_ASSERT + * \brief Defines a regular assertion check macro. + * + * \c OU_ASSERT defines a classic assertion check macro. Normally its expression + * is evaluated and if it is equal to \c false, assertion failure handler is invoked + * with \c AFS_ASSERT parameter. If assertion failure handler is not customized, + * the functionality of system \c assert() call is performed. + * If \c NDEBUG preprocessor symbol is defined, the macro expands to empty operator + * and expression of its argument is \e NOT evaluated. + * \note The expression is evaluated only once even though either custom handler or + * system \c assert() might be chosen to handle failure. + * \par + * \note The macro is designed so that "Condition" text is passed to customized + * handler and "OU__ASSERT_HANDLER(Condition)" is passed to \c assert() if + * handler is not customized. However new versions of GCC (starting from 4.3.0) + * seem to use modified macro expansion schema which formats macro \c OU__ASSERT_HANDLER + * into string after full expansion. + * + * \see OU_VERIFY + * \see OU_CHECK + * \see EASSERTIONFAILURESEVERITY + * \see CAssertionFailedProcedure + * \see CAssertionCheckCustomization + */ + +/** + * \def OU_VERIFY + * \brief Defines an assertion check macro which always evaluates its parameter. + * + * \c OU_VERIFY is similar to \c OU_ASSERT with exception that if \c NDEBUG preprocessor + * symbol is defined it still evaluates its parameter. + * The main purpose of this macro is to prevent "unused variable" compiler warning + * which would otherwise appear with \c OU_ASSERT macro used when \c NDEBUG is defined. + * + * \code + * bool bCallStatus = CallMyFunction(); + * // A compiler warning would be generated with OU_ASSERT if bCallStatus is + * // not used further in the code. + * OU_VERIFY(bCallStatus); + * \endcode + * + * \note It is not recommended to use \c OU_VERIFY with function calls directly + * if function result is not boolean, as otherwise in case of assertion failure + * it will be not possible to retrieve function result. + * \code + * // Incorrect! Call status will not be available in case of failure! + * OU_VERIFY(pthread_mutex_create(&attr) == EOK); + * + * // Correct. Call status can be retrieved from a variable. + * int iMutexCreateStatus = pthread_mutex_create(&attr); + * OU_VERIFY(iMutexCreateStatus == EOK); + * \endcode + * + * \see OU_ASSERT + * \see OU_CHECK + * \see EASSERTIONFAILURESEVERITY + * \see CAssertionFailedProcedure + * \see CAssertionCheckCustomization + */ + +/** + * \def OU_CHECK + * \brief Defines a hard assertion check macro. + * + * \c OU_CHECK evaluates its parameter and if the expression equals to \c false + * it invokes either a custom assertion failure handler with \c AFS_CHECK parameter + * or failure processing of system \c assert() function. The execution is not supposed + * to exit from assertion failure call. If it does (either because custom assertion + * failure handler returns or handler is not customized and \c assert() function has + * no effect because of \c NDEBUG symbol being defined), a write attempt to NULL + * pointer is performed to generate Access Violation exception or SIGSEGV signal. + * \c OU_CHECK is similar to \c OU_VERIFY in that it evaluates its parameter whether + * \c NDEBUG is defined or not. + * \note The expression is evaluated only once even though either custom handler or + * system \c assert() might be chosen to handle failure. + * \par + * \note The macro is designed so that "Condition" text is passed to customized + * handler and "OU__CHECK_HANDLER(Condition)" is passed to \c assert() if + * handler is not customized. However new versions of GCC (starting from 4.3.0) + * seem to use modified macro expansion schema which formats macro \c OU__CHECK_HANDLER + * into string after full expansion. + * + * \see OU_ASSERT + * \see OU_VERIFY + * \see EASSERTIONFAILURESEVERITY + * \see CAssertionFailedProcedure + * \see CAssertionCheckCustomization + */ + + +/* + * Implementation Note: + * 1) Fully qualified names must be used in macros as they might be + * used externally and forwarded from outside of _OU_NAMESPACE. + * 2) false || ... is necessary to suppress C4800 warning in MSVC. + */ + +#if defined(NDEBUG) + +#define OU_ASSERT(Condition) ((void)0) + +#define OU_VERIFY(Condition) ((void)(Condition)) + +#define OU_CHECK(Condition) (void)(false || (Condition) \ + || (!_OU_NAMESPACE::CAssertionCheckCustomization::GetAssertFailureCustomHandler() \ + || (_OU_NAMESPACE::CAssertionCheckCustomization::GetAssertFailureCustomHandler()( \ + _OU_NAMESPACE::AFS_CHECK, #Condition, __FILE__, __LINE__), false)) \ + || (*(volatile int *)0 = 0, false)) + + +#else // #if !defined(NDEBUG) + +#include <assert.h> + + +#define OU__ASSERT_HANDLER(Condition) (false || (Condition) \ + || (_OU_NAMESPACE::CAssertionCheckCustomization::GetAssertFailureCustomHandler() \ + && (_OU_NAMESPACE::CAssertionCheckCustomization::GetAssertFailureCustomHandler()( \ + _OU_NAMESPACE::AFS_ASSERT, #Condition, __FILE__, __LINE__), true))) + +#define OU__CHECK_HANDLER(Condition) (((bConditionValue = false || (Condition)), bConditionValue) \ + || (_OU_NAMESPACE::CAssertionCheckCustomization::GetAssertFailureCustomHandler() \ + && (_OU_NAMESPACE::CAssertionCheckCustomization::GetAssertFailureCustomHandler()( \ + _OU_NAMESPACE::AFS_CHECK, #Condition, __FILE__, __LINE__), true))) + + +#define OU_ASSERT(Condition) assert(OU__ASSERT_HANDLER(Condition)) + +#define OU_VERIFY(Condition) OU_ASSERT(Condition) + +#define OU_CHECK(Condition) { \ + bool bConditionValue; \ + assert(OU__CHECK_HANDLER(Condition)); \ + (void)(bConditionValue || (*(volatile int *)0 = 0, false)); \ +} + + +#endif // #if !defined(NDEBUG) + + +#endif // #ifndef __OU_ASSERT_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/atomic.h b/libs/ode-0.16.1/ou/include/ou/atomic.h new file mode 100644 index 0000000..2f90a70 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/atomic.h @@ -0,0 +1,1835 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_ATOMIC_H_INCLUDED +#define __OU_ATOMIC_H_INCLUDED + + +/** + * \file + * \brief Definitions of atomic (interlocked) API. + * + * Atomic (interlocked) functions are supposed to provide atomic operations on + * variables in multi-threaded environment without bringing synchronization objects in. + * Atomic functions can be used for implementing reliable reference counting, advanced + * synchronization objects, complex techniques of relaxed synchronization with minimum + * or no synchronization obejcts' usage. + * + * All atomic functions are implemented as memory barriers. + * + * On Windows, QNX, MacOS, AIX, SunOS atomic API is implemented via native OS calls. + * If atomic operation function are not provided (or not fully provided) by target OS, + * the missing operations are implemented with aid of other atomic functions or + * via mutex locks if that is not possible. The array of \c _OU_ATOMIC_MUTEX_COUNT + * (8 in current version) mutexes is used to decrease probability of several threads + * being competing for the same mutex lock and resulting necessity to block some + * of them during operation. + * + * All atomic API implementations are inlined, Exceptions are implementations via + * mutex locks for which it is not reasonable to generate inlined code. + * + * Atomic functions' prototypes were selected to to provide maximal possible + * functionality available on all the platforms mentioned above in common. Function + * names were chosen as a mix of Windows and UNIX naming traditions (more closely + * to Windows though). + * + * There are the following groups of API available: + * \li Arithmetic (\c AtomicIncrement, \c AtomicDecrement) + * \li Integer Exchange (\c AtomicExchange, \c AtomicExchangeAdd, \c AtomicCompareExchange) + * \li Bitwise (\c AtomicAnd, \c AtomicOr, \c AtomicXor) + * \li Pointer Exchange (\c AtomicExchangePointer, \c AtomicCompareExchangePointer) + * + * For Arithmetic and Bitwise groups along with \c AtomicExchangeAdd function there + * are "no result" variants available. These are written with \c NoResult suffix + * after function name and may operate faster on some platforms. However they do not + * provide operation results. + * + * Atomic functions of Arithmetic, Integer Exchange and Bitwise groups operate with + * 32-bit values regardless if build target address space is 32 or 64 bits wide. + * Pointer Exchange functions operate with pointer type and their argument can be + * both 32 or 64 bit value depending on build target. + * + * Generic x86 assembler implementation is provided for i486 and later processors. + * However it is never automatically selected. You must explicitly define + * \c _OU_ATOMIC_USE_X86_ASSEMBLER symbol in compiler options to select that + * implementation. The option can only be used if \c _OU_TARGET_OS is equal to + * \c _OU_TARGET_OS_GENUNIX. If the symbol is defined for any other target, + * it is silently ignored. + * \warning + * Never use assembler implementation on systems that provide native atomic API! + * + * Atomic API may require initialization before first use and finalization on program + * exit. The initialization may be necessary when operating system does not provide + * sufficient functionality to implement all the operations via native calls. However, + * to maintain code portability it is recommended that initialization/finalization + * functions are always called. + * + * API initialization and finalization calls use reference counting mechanism and + * thus may be invoked several times from different subsystems. Initialization and + * finalization is \e not \e thread \e safe and should be performed from main thread + * only. + */ + +#include <ou/features.h> + + +#if _OU_FEATURE_SET >= _OU_FEATURE_SET_ATOMICS + +#include <ou/inttypes.h> +#include <ou/namespace.h> +#include <ou/platform.h> + + +/** + * \typedef atomicord32 + * \brief An uniform type for 32-bit values to be used as atomic operations' arguments. + * + * This type is supposed to be used for all the variables that store atomic values. + * The word "int" was by intent avoided in its name to emphasize that the type + * needs not necessary to be a signed integer. It might be either signed or unsigned + * depending on target platform. The only information which could be relied on is + * that the type will always be 32 bit wide, regardless if target platform is a + * 32 or 64-bit one. + * + * Any arithmetic operations should be avoided with type \c atomicord32. + * Instead, the wrapper functions should be used to access the value. The function should + * cast value type to \c atomicord32 in parameters and cast result back to value type. + * \code + * int ExchangeValue(volatile atomicord32 *paoDestination, int iExchange) + * { + * return (int)AtomicExchange(paoDestination, (atomicord32)iExchange); + * } + * \endcode + * \see atomicptr + */ + +/** + * \typedef atomicptr + * \brief An uniform type for pointer values to be used as atomic operations' arguments + * + * The type is to be used for those function which operate with pointers rather + * than integers. The size of \c atomicptr is platform dependent, just like the + * size of the pointer and equals 4 bytes on 32-bit platforms and 8 bytes on 64-bit ones. + * \see atomicord32 + */ + +/** + * \fn atomicord32 _OU_CONVENTION_API AtomicIncrement(volatile atomicord32 *paoDestination) + * \brief Increments the destination and returns its new value. + * \param paoDestination A pointer to a variable to be incremented. + * \return A value of variable pointed to by \a paoDestination after the increment. + * + * The function implements functionality of \c InterlockedIncrement from Win32 API. + * It is most commonly used for reference counting. + * \see AtomicDecrement + */ + +/** + * \fn atomicord32 _OU_CONVENTION_API AtomicDecrement(volatile atomicord32 *paoDestination) + * \brief Decrements the destination and returns its new value. + * \param paoDestination A pointer to a variable to be decremented. + * \return A value of variable pointed to by \a paoDestination after the decrement. + * + * The function implements functionality of \c InterlockedDecrement from Win32 API. + * It is most commonly used for reference counting. + * \see AtomicIncrement + */ + +/** + * \fn void _OU_CONVENTION_API AtomicStore(volatile atomicord32 *paoDestination, atomicord32 aoValue) + * \brief Stores the value in destination. + * \param paoDestination A pointer to a variable the data is to be stored in. + * \param aoValue A value to be stored. + * + * The function performs atomic store of \a aoValue value in the memory location + * pointed to by \a paoDestination. + */ + +/** + * \fn atomicord32 _OU_CONVENTION_API AtomicExchange(volatile atomicord32 *paoDestination, atomicord32 aoExchange) + * \brief Stores new value in destination and returns old value of destination. + * \param paoDestination A pointer to a variable the data is to be exchanged with. + * \param aoExchange A value to be used for exchange. + * \return Previous value of variable pointed to by \a paoDestination. + * + * The function performs atomic exchange of \a aoExchange value with memory location + * pointed to by \a paoDestination. Most common uses are relaxed synchronization + * and shared value extraction. + * \see AtomicCompareExchange + */ + +/** + * \fn atomicord32 _OU_CONVENTION_API AtomicExchangeAdd(volatile atomicord32 *paoDestination, atomicord32 aoAddend) + * \brief Assigns sum of addend and existing destination value to the destination + * and returns original value of destination. + * \param paoDestination A pointer to a variable the value is to be added to. + * \param aoAddend An addend to be used in operation. + * \return Original value of variable pointed to by \a paoDestination. + * + * The function computes sum of \a aoAddend and location pointed to by \a paoDestination + * stores it in the location and returns original value instead. The function is + * close to both exchange and increment groups by semantics but it has been + * put into exchange group because it returns original value of the destination. + * Also, the function was not named \c AtomicAdd to avoid similarity with \c AtomicAnd. + * One of supposed applications is the resource counting. + * \see AtomicIncrement + * \see AtomicDecrement + */ + +/** + * \fn bool _OU_CONVENTION_API AtomicCompareExchange(volatile atomicord32 *paoDestination, atomicord32 aoComparand, atomicord32 aoExchange) + * \brief Compares comparand with destination and stores a new value if comparand + * and destination match; returns if the assignment was performed or not. + * \param paoDestination A pointer to a variable the data is to be compared and assigned to. + * \param aoComparand A value to be used for comparison. + * \param aoExchange A new value to be used for assignment. + * \return \c true if exchange was performed and \c false otherwise. + * + * The function performs comparison of \a aoComparand value with the value pointed + * by \a paoDestination. If the values match an \a aoExchange is assigned to + * destination location. If values do not match, the restination remains unchanged. + * Function returns boolean status whether the match and assignment occurred or not. + * The most common uses are relaxed synchronization and construction of LIFO lists. + * \see AtomicExchange + */ + +/** + * \fn atomicord32 _OU_CONVENTION_API AtomicAnd(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) + * \brief Applies a mask with bitwise AND to the destination and returns original + * value of destination. + * \param paoDestination A pointer to a variable the bitmask is to be applied to. + * \param aoBitMask A bitmask to be used in operation. + * \return Original value of variable pointed to by \a paoDestination. + * + * \c AtomicAnd updates variable pointed to by \a paoDestination with result of + * bitwise AND of \a aoBitMask and existing \a paoDestination target. The result + * is original value that was pointed to by \a paoDestination before the operation + * was performed. Common applications are object state manipulations. + * \see AtomicOr + * \see AtomicXor + */ + +/** + * \fn atomicord32 _OU_CONVENTION_API AtomicOr(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) + * \brief Applies a mask with bitwise OR to the destination and returns original + * value of destination. + * \param paoDestination A pointer to a variable the bitmask is to be applied to. + * \param aoBitMask A bitmask to be used in operation. + * \return Original value of variable pointed to by \a paoDestination. + * + * \c AtomicOr updates variable pointed to by \a paoDestination with result of + * bitwise OR of \a aoBitMask and existing \a paoDestination target. The result + * is original value that was pointed to by \a paoDestination before the operation + * was performed. Common applications are object state manipulations. + * \see AtomicAnd + * \see AtomicXor + */ + +/** + * \fn atomicord32 _OU_CONVENTION_API AtomicXor(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) + * \brief Applies a mask with bitwise XOR to the destination and returns original + * value of destination. + * \param paoDestination A pointer to a variable the bitmask is to be applied to. + * \param aoBitMask A bitmask to be used in operation. + * \return Original value of variable pointed to by \a paoDestination. + * + * \c AtomicXor updates variable pointed to by \a paoDestination with result of + * bitwise XOR of \a aoBitMask and existing \a paoDestination target. The result + * is original value that was pointed to by \a paoDestination before the operation + * was performed. Common applications are object state manipulations. + * \see AtomicAnd + * \see AtomicOr + */ + +/** + * \fn void _OU_CONVENTION_API AtomicStorePointer(volatile atomicptr *papDestination, atomicptr apValue) + * \brief The function is identical to \c AtomicStore except that it operates + * with pointers rather than 32-bit integers. + * \see AtomicStore + */ + +/** + * \fn atomicptr _OU_CONVENTION_API AtomicExchangePointer(volatile atomicptr *papDestination, atomicptr apExchange) + * \brief The function is identical to \c AtomicExchange except that it operates + * with pointers rather than 32-bit integers. + * \see AtomicExchange + */ + +/** + * \fn bool _OU_CONVENTION_API AtomicCompareExchangePointer(volatile atomicptr *papDestination, atomicptr apComparand, atomicptr apExchange) + * \brief The function is identical to \c AtomicCompareExchange except that it operates + * with pointers rather than 32-bit integers. + * \see AtomicCompareExchange + */ + +/** + * \fn void _OU_CONVENTION_API AtomicIncrementNoResult(volatile atomicord32 *paoDestination) + * \brief The function is identical to \c AtomicIncrement but does not return a result. + * + * The function implementation can be faster on some platforms and it is recommended + * to use "NoResult" variants in cases when the result of operation or previous value + * of destination is not used. + * \see AtomicIncrement + */ + +/** + * \fn void _OU_CONVENTION_API AtomicDecrementNoResult(volatile atomicord32 *paoDestination) + * \brief The function is identical to \c AtomicDecrement but does not return a result. + * + * The function implementation can be faster on some platforms and it is recommended + * to use "NoResult" variants in cases when the result of operation or previous value + * of destination is not used. + * \see AtomicDecrement + */ + +/** + * \fn void _OU_CONVENTION_API AtomicExchangeAddNoResult(volatile atomicord32 *paoDestination, atomicord32 aoAddend) + * \brief The function is identical to \c AtomicExchangeAdd but does not return a result. + * + * The function implementation can be faster on some platforms and it is recommended + * to use "NoResult" variants in cases when the result of operation or previous value + * of destination is not used. + * \see AtomicExchangeAdd + */ + +/** + * \fn void _OU_CONVENTION_API AtomicAndNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) + * \brief The function is identical to \c AtomicAnd but does not return a result. + * + * The function implementation can be faster on some platforms and it is recommended + * to use "NoResult" variants in cases when the result of operation or previous value + * of destination is not used. + * \see AtomicAnd + */ + +/** + * \fn void _OU_CONVENTION_API AtomicOrNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) + * \brief The function is identical to \c AtomicOr but does not return a result. + * + * The function implementation can be faster on some platforms and it is recommended + * to use "NoResult" variants in cases when the result of operation or previous value + * of destination is not used. + * \see AtomicOr + */ + +/** + * \fn void _OU_CONVENTION_API AtomicXorNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) + * \brief The function is identical to \c AtomicXor but does not return a result. + * + * The function implementation can be faster on some platforms and it is recommended + * to use "NoResult" variants in cases when the result of operation or previous value + * of destination is not used. + * \see AtomicXor + */ + +/** + * \fn void _OU_CONVENTION_API AtomicReadReorderBarrier() + * \brief The function prevents both the compiler and the processor architecture + * from reordering memory read operations across the barrier call. + */ + + +/** + * \fn bool _OU_CONVENTION_API InitializeAtomicAPI() + * \brief Performs initialization tasks to allow using atomic functions. + * \return Boolean initialization status. + * + * The function is required to be called before first use of atomic functions. + * The initialization uses reference counting, so multiple calls to \c InitializeAtomicAPI + * are allowed. However the counter is not thread safe. Therefore it is recommended + * that the function is always called from main thread on program startup or + * library initialization. + * + * The function returns initialization status. If initialization succeeds, + * \c FinalizeAtomicAPI is to be called for each call to \c InitializeAtomicAPI after + * atomic functions are not needed any more. If \c InitializeAtomicAPI returns + * \c false, the atomic functions may not be used and \c FinalizeAtomicAPI must not be called. + * \see FinalizeAtomicAPI + */ + +/** + * \fn void _OU_CONVENTION_API FinalizeAtomicAPI() + * \brief Finalizes objects and frees the memory that might be used to provide + * functionality of atomic functions. + * + * The function is to be called on program exit or library client detach to + * release resources that might be allocated to support functionality of Atomic... + * functions. The function must be called once for every successful call to + * \c InitializeAtomicAPI. \c FinalizeAtomicAPI can not fail. + * \see InitializeAtomicAPI + */ + + +BEGIN_NAMESPACE_OU(); + + +////////////////////////////////////////////////////////////////////////// +// Windows implementation + +#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + + +END_NAMESPACE_OU(); + + +#include <windows.h> +#include <stddef.h> + + +BEGIN_NAMESPACE_OU(); + + +typedef ULONG atomicord32; +typedef PVOID atomicptr; + + +#if _OU_COMPILER == _OU_COMPILER_MSVC && _OU_COMPILER_VERSION == _OU_COMPILER_VERSION_MSVC1998 + +#define __ou_intlck_value_t LONG +#define __ou_intlck_target_t LPLONG +#define __ou_xchgadd_target_t LPLONG +#define __ou_cmpxchg_value_t PVOID +#define __ou_cmpxchg_target_t PVOID * + + +#elif _OU_COMPILER == _OU_COMPILER_GCC + +#define __ou_intlck_value_t LONG +#define __ou_intlck_target_t LPLONG +#define __ou_xchgadd_target_t LPLONG +#define __ou_cmpxchg_value_t LONG +#define __ou_cmpxchg_target_t LPLONG + + +#else // other compilers + +#define __ou_intlck_value_t LONG +#define __ou_intlck_target_t volatile LONG * +#define __ou_xchgadd_target_t LPLONG +#define __ou_cmpxchg_value_t LONG +#define __ou_cmpxchg_target_t volatile LONG * + + +#endif // #if _OU_COMPILER == _OU_COMPILER_GCC + + +#define __OU_ATOMIC_ORD32_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicIncrement(volatile atomicord32 *paoDestination) +{ + return ::InterlockedIncrement((__ou_intlck_target_t)paoDestination); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicDecrement(volatile atomicord32 *paoDestination) +{ + return ::InterlockedDecrement((__ou_intlck_target_t)paoDestination); +} + + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicExchange(volatile atomicord32 *paoDestination, atomicord32 aoExchange) +{ + return ::InterlockedExchange((__ou_intlck_target_t)paoDestination, aoExchange); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicExchangeAdd(volatile atomicord32 *paoDestination, atomicord32 aoAddend) +{ + return ::InterlockedExchangeAdd((__ou_xchgadd_target_t)paoDestination, aoAddend); +} + +static _OU_ALWAYSINLINE bool _OU_CONVENTION_API +/*bool */AtomicCompareExchange(volatile atomicord32 *paoDestination, atomicord32 aoComparand, atomicord32 aoExchange) +{ + return (aoComparand == (atomicord32)::InterlockedCompareExchange((__ou_cmpxchg_target_t)paoDestination, (__ou_cmpxchg_value_t)aoExchange, (__ou_cmpxchg_value_t)aoComparand)); +} + + +#define __OU_ATOMIC_BIT_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicAnd(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoOldValue = *paoDestination; + + while (true) + { + atomicord32 aoNewValue = (atomicord32)::InterlockedCompareExchange((__ou_cmpxchg_target_t)paoDestination, (__ou_cmpxchg_value_t)(aoOldValue & aoBitMask), (__ou_cmpxchg_value_t)aoOldValue); + + if (aoNewValue == aoOldValue) + { + break; + } + + aoOldValue = aoNewValue; + } + + return aoOldValue; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicOr(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoOldValue = *paoDestination; + + while (true) + { + atomicord32 aoNewValue = (atomicord32)::InterlockedCompareExchange((__ou_cmpxchg_target_t)paoDestination, (__ou_cmpxchg_value_t)(aoOldValue | aoBitMask), (__ou_cmpxchg_value_t)aoOldValue); + + if (aoNewValue == aoOldValue) + { + break; + } + + aoOldValue = aoNewValue; + } + + return aoOldValue; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicXor(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoOldValue = *paoDestination; + + while (true) + { + atomicord32 aoNewValue = (atomicord32)::InterlockedCompareExchange((__ou_cmpxchg_target_t)paoDestination, (__ou_cmpxchg_value_t)(aoOldValue ^ aoBitMask), (__ou_cmpxchg_value_t)aoOldValue); + + if (aoNewValue == aoOldValue) + { + break; + } + + aoOldValue = aoNewValue; + } + + return aoOldValue; +} + + +#define __OU_ATOMIC_PTR_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicptr _OU_CONVENTION_API +/*atomicptr */AtomicExchangePointer(volatile atomicptr *papDestination, atomicptr apExchange) +{ +#if _OU_TARGET_BITS == _OU_TARGET_BITS_32 + + return (atomicptr)(ptrdiff_t)::InterlockedExchange((__ou_intlck_target_t)papDestination, (__ou_intlck_value_t)(ptrdiff_t)apExchange); + + +#else // #if _OU_TARGET_BITS == _OU_TARGET_BITS_64 + + return ::InterlockedExchangePointer(papDestination, apExchange); + + +#endif // #if _OU_TARGET_BITS == ... +} + +static _OU_ALWAYSINLINE bool _OU_CONVENTION_API +/*bool */AtomicCompareExchangePointer(volatile atomicptr *papDestination, atomicptr apComparand, atomicptr apExchange) +{ +#if _OU_TARGET_BITS == _OU_TARGET_BITS_32 + + return (apComparand == (atomicptr)(ptrdiff_t)::InterlockedCompareExchange((__ou_cmpxchg_target_t)papDestination, (__ou_cmpxchg_value_t)(ptrdiff_t)apExchange, (__ou_cmpxchg_value_t)(ptrdiff_t)apComparand)); + + +#else // #if !defined(__OU_ATOMIC_WINDOWS_OLD_STYLE_PARAMS) + + return (apComparand == ::InterlockedCompareExchangePointer(papDestination, apExchange, apComparand)); + + +#endif // #if !defined(__OU_ATOMIC_WINDOWS_OLD_STYLE_PARAMS) +} + + +#if _OU_COMPILER == _OU_COMPILER_MSVC + +#if (_OU_TARGET_ARCH == _OU_TARGET_ARCH_X86 || _OU_TARGET_ARCH == _OU_TARGET_ARCH_X64) + +#define __OU_ATOMIC_READREORDERBARRIER_FUNCTION_DEFINED + +#include <intrin.h> + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicReadReorderBarrier() +{ + _ReadBarrier(); +} + + +#endif // #if (_OU_TARGET_ARCH == _OU_TARGET_ARCH_X86 || _OU_TARGET_ARCH == _OU_TARGET_ARCH_X64) + + +#endif // #if _OU_COMPILER == _OU_COMPILER_MSVC + + +#undef __ou_intlck_value_t +#undef __ou_intlck_target_t +#undef __ou_xchgadd_target_t +#undef __ou_cmpxchg_value_t +#undef __ou_cmpxchg_target_t + + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + + +////////////////////////////////////////////////////////////////////////// +// QNX implementation + +#if _OU_TARGET_OS == _OU_TARGET_OS_QNX + +END_NAMESPACE_OU(); + + +#include <atomic.h> +#include _NTO_CPU_HDR_(smpxchg.h) + + +BEGIN_NAMESPACE_OU(); + +typedef unsigned int atomicord32; +typedef void *atomicptr; + + +#define __OU_ATOMIC_ORD32_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicIncrement(volatile atomicord32 *paoDestination) +{ + return (atomic_add_value(paoDestination, 1U) + 1U); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicDecrement(volatile atomicord32 *paoDestination) +{ + return (atomic_sub_value(paoDestination, 1U) - 1U); +} + + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicExchange(volatile atomicord32 *paoDestination, atomicord32 aoExchange) +{ + return _smp_xchg(paoDestination, aoExchange); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicExchangeAdd(volatile atomicord32 *paoDestination, atomicord32 aoAddend) +{ + return atomic_add_value(paoDestination, aoAddend); +} + +static _OU_ALWAYSINLINE bool _OU_CONVENTION_API +/*bool */AtomicCompareExchange(volatile atomicord32 *paoDestination, atomicord32 aoComparand, atomicord32 aoExchange) +{ + return (aoComparand == (atomicord32)_smp_cmpxchg(paoDestination, aoComparand, aoExchange)); +} + + +#define __OU_ATOMIC_BIT_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicAnd(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + return atomic_clr_value(paoDestination, ~aoBitMask); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicOr(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + return atomic_set_value(paoDestination, aoBitMask); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicXor(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + return atomic_toggle_value(paoDestination, aoBitMask); +} + + +#define __OU_ATOMIC_ORD32_NORESULT_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicIncrementNoResult(volatile atomicord32 *paoDestination) +{ + atomic_add(paoDestination, 1U); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicDecrementNoResult(volatile atomicord32 *paoDestination) +{ + atomic_sub(paoDestination, 1U); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicExchangeAddNoResult(volatile atomicord32 *paoDestination, atomicord32 aoAddend) +{ + atomic_add(paoDestination, aoAddend); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicAndNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomic_clr(paoDestination, ~aoBitMask); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicOrNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomic_set(paoDestination, aoBitMask); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicXorNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomic_toggle(paoDestination, aoBitMask); +} + + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_QNX + + +////////////////////////////////////////////////////////////////////////// +// Mac implementation + +#if _OU_TARGET_OS == _OU_TARGET_OS_MAC || _OU_TARGET_OS == _OU_TARGET_OS_IOS + +#if MAC_OS_X_VERSION >= 1040 + + +END_NAMESPACE_OU(); + + +#include <libkern/OSAtomic.h> + + +BEGIN_NAMESPACE_OU(); + + +typedef uint32_t atomicord32; +typedef void *atomicptr; + + +#define __ou_intlck_target_t volatile int32_t * +#define __ou_xchgadd_target_t volatile int32_t * +#define __ou_cmpxchg_value_t int32_t +#define __ou_cmpxchg_target_t volatile int32_t * +#define __ou_bitmsk_target_t volatile uint32_t * + + +#define __OU_ATOMIC_ORD32_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicIncrement(volatile atomicord32 *paoDestination) +{ + return OSAtomicIncrement32Barrier((__ou_intlck_target_t)paoDestination); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicDecrement(volatile atomicord32 *paoDestination) +{ + return OSAtomicDecrement32Barrier((__ou_intlck_target_t)paoDestination); +} + + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicExchange(volatile atomicord32 *paoDestination, atomicord32 aoExchange) +{ + __ou_cmpxchg_value_t aoOldValue = *paoDestination; + + /* + * Implementation Note: + * It is safe to use compare-and-swap without memory barrier for subsequent attempts + * because current thread had already had a barrier and does not have any additional + * memory access until function exit. On the other hand it is expected that other + * threads will be using this API set for manipulations with paoDestination as well + * and hence will not issue writes after/without memory barrier. + */ + for (bool bSwapExecuted = OSAtomicCompareAndSwap32Barrier(aoOldValue, aoExchange, (__ou_cmpxchg_target_t)paoDestination); + !bSwapExecuted; bSwapExecuted = OSAtomicCompareAndSwap32(aoOldValue, aoExchange, (__ou_cmpxchg_target_t)paoDestination)) + { + aoOldValue = *paoDestination; + } + + return aoOldValue; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicExchangeAdd(volatile atomicord32 *paoDestination, atomicord32 aoAddend) +{ + return (OSAtomicAdd32Barrier(aoAddend, (__ou_xchgadd_target_t)paoDestination) - aoAddend); +} + +static _OU_ALWAYSINLINE bool _OU_CONVENTION_API +/*bool */AtomicCompareExchange(volatile atomicord32 *paoDestination, atomicord32 aoComparand, atomicord32 aoExchange) +{ + return OSAtomicCompareAndSwap32Barrier(aoComparand, aoExchange, (__ou_cmpxchg_target_t)paoDestination); +} + + +#if MAC_OS_X_VERSION >= 1050 + +#define __OU_ATOMIC_BIT_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicAnd(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + return OSAtomicAnd32OrigBarrier(aoBitMask, (__ou_bitmsk_target_t)paoDestination); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicOr(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + return OSAtomicOr32OrigBarrier(aoBitMask, (__ou_bitmsk_target_t)paoDestination); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicXor(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + return OSAtomicXor32OrigBarrier(aoBitMask, (__ou_bitmsk_target_t)paoDestination); +} + + +#else // #if MAC_OS_X_VERSION < 1050 (...&& MAC_OS_X_VERSION >= 1040) + +#define __OU_ATOMIC_BIT_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicAnd(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoOldValue = *paoDestination; + + /* + * Implementation Note: + * It is safe to use compare-and-swap without memory barrier for subsequent attempts + * because current thread had already had a barrier and does not have any additional + * memory access until function exit. On the other hand it is expected that other + * threads will be using this API set for manipulations with paoDestination as well + * and hence will not issue writes after/without memory barrier. + */ + for (bool bSwapExecuted = OSAtomicCompareAndSwap32Barrier(aoOldValue, (aoOldValue & aoBitMask), paoDestination); + !bSwapExecuted; bSwapExecuted = OSAtomicCompareAndSwap32(aoOldValue, (aoOldValue & aoBitMask), paoDestination)) + { + aoOldValue = *paoDestination; + } + + return aoOldValue; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicOr(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoOldValue = *paoDestination; + + /* + * Implementation Note: + * It is safe to use compare-and-swap without memory barrier for subsequent attempts + * because current thread had already had a barrier and does not have any additional + * memory access until function exit. On the other hand it is expected that other + * threads will be using this API set for manipulations with paoDestination as well + * and hence will not issue writes after/without memory barrier. + */ + for (bool bSwapExecuted = OSAtomicCompareAndSwap32Barrier(aoOldValue, (aoOldValue | aoBitMask), paoDestination); + !bSwapExecuted; bSwapExecuted = OSAtomicCompareAndSwap32(aoOldValue, (aoOldValue | aoBitMask), paoDestination)) + { + aoOldValue = *paoDestination; + } + + return aoOldValue; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicXor(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + return (OSAtomicXor32Barrier(aoBitMask, (__ou_bitmsk_target_t)paoDestination) ^ aoBitMask); +} + + +#endif // #if MAC_OS_X_VERSION < 1050 (...&& MAC_OS_X_VERSION >= 1040) + + +#if MAC_OS_X_VERSION >= 1050 + +#define __OU_ATOMIC_PTR_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicptr _OU_CONVENTION_API +/*atomicptr */AtomicExchangePointer(volatile atomicptr *papDestination, atomicptr apExchange) +{ + atomicptr apOldValue = *papDestination; + + /* + * Implementation Note: + * It is safe to use compare-and-swap without memory barrier for subsequent attempts + * because current thread had already had a barrier and does not have any additional + * memory access until function exit. On the other hand it is expected that other + * threads will be using this API set for manipulations with papDestination as well + * and hence will not issue writes after/without memory barrier. + */ + for (bool bSwapExecuted = OSAtomicCompareAndSwapPtrBarrier(apOldValue, apExchange, papDestination); + !bSwapExecuted; bSwapExecuted = OSAtomicCompareAndSwapPtr(apOldValue, apExchange, papDestination)) + { + apOldValue = *papDestination; + } + + return apOldValue; +} + +static _OU_ALWAYSINLINE bool _OU_CONVENTION_API +/*bool */AtomicCompareExchangePointer(volatile atomicptr *papDestination, atomicptr apComparand, atomicptr apExchange) +{ + return OSAtomicCompareAndSwapPtrBarrier(apComparand, apExchange, papDestination); +} + + +#endif // #if MAC_OS_X_VERSION >= 1050 + + +#define __OU_ATOMIC_ORD32_NORESULT_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicIncrementNoResult(volatile atomicord32 *paoDestination) +{ + OSAtomicIncrement32Barrier((__ou_intlck_target_t)paoDestination); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicDecrementNoResult(volatile atomicord32 *paoDestination) +{ + OSAtomicDecrement32Barrier((__ou_intlck_target_t)paoDestination); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicExchangeAddNoResult(volatile atomicord32 *paoDestination, atomicord32 aoAddend) +{ + OSAtomicAdd32Barrier(aoAddend, (__ou_xchgadd_target_t)paoDestination); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicAndNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + OSAtomicAnd32Barrier(aoBitMask, (__ou_bitmsk_target_t)paoDestination); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicOrNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + OSAtomicOr32Barrier(aoBitMask, (__ou_bitmsk_target_t)paoDestination); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicXorNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + OSAtomicXor32Barrier(aoBitMask, (__ou_bitmsk_target_t)paoDestination); +} + + +#endif // #if MAC_OS_X_VERSION >= 1040 + + +#undef __ou_bitmsk_target_t +#undef __ou_cmpxchg_target_t +#undef __ou_cmpxchg_value_t +#undef __ou_xchgadd_target_t +#undef __ou_intlck_target_t + + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_MAC + + +////////////////////////////////////////////////////////////////////////// +// AIX implementation + +#if _OU_TARGET_OS == _OU_TARGET_OS_AIX + + +END_NAMESPACE_OU(); + + +#include <sys/atomic_op.h> + + +BEGIN_NAMESPACE_OU(); + + +typedef unsigned int atomicord32; +typedef void *atomicptr; + +#define __ou_cas_value_t int +#define __ou_caslp_value_t long + + +#define __OU_ATOMIC_ORD32_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicIncrement(volatile atomicord32 *paoDestination) +{ + return (fetch_and_add((atomic_p)paoDestination, 1) + 1); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicDecrement(volatile atomicord32 *paoDestination) +{ + return (fetch_and_add((atomic_p)paoDestination, -1) - 1); +} + + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicExchange(volatile atomicord32 *paoDestination, atomicord32 aoExchange) +{ + __ou_cas_value_t aoOldValue = *paoDestination; + + while (!compare_and_swap((atomic_p)paoDestination, &aoOldValue, aoExchange)) + { + // Do nothing + } + + return aoOldValue; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicExchangeAdd(volatile atomicord32 *paoDestination, atomicord32 aoAddend) +{ + return fetch_and_add((atomic_p)paoDestination, aoAddend); +} + +static _OU_ALWAYSINLINE bool _OU_CONVENTION_API +/*bool */AtomicCompareExchange(volatile atomicord32 *paoDestination, atomicord32 aoComparand, atomicord32 aoExchange) +{ + __ou_cas_value_t aoOldValue = aoComparand; + + return compare_and_swap((atomic_p)paoDestination, &aoOldValue, aoExchange); +} + + +#define __OU_ATOMIC_BIT_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicAnd(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + return fetch_and_and((atomic_p)paoDestination, aoBitMask); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicOr(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + return fetch_and_or((atomic_p)paoDestination, aoBitMask); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicXor(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + volatile __ou_cas_value_t aoOldValue = *paoDestination; + + while (!compare_and_swap((atomic_p)paoDestination, &aoOldValue, aoOldValue ^ aoBitMask)) + { + // Do nothing + } + + return aoOldValue; +} + + +#if _OU_TARGET_BITS == _OU_TARGET_BITS_64 // Otherwise functions will be forwarded to ord32 further in this file + +#define __OU_ATOMIC_PTR_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicptr _OU_CONVENTION_API +/*atomicptr */AtomicExchangePointer(volatile atomicptr *papDestination, atomicptr apExchange) +{ + __ou_caslp_value_t liOldValue = (__ou_caslp_value_t)*papDestination; + + while (!compare_and_swaplp((atomic_l)papDestination, &liOldValue, (__ou_caslp_value_t)apExchange)) + { + // Do nothing + } + + return liOldValue; +} + +static _OU_ALWAYSINLINE bool _OU_CONVENTION_API +/*bool */AtomicCompareExchangePointer(volatile atomicptr *papDestination, atomicptr apComparand, atomicptr apExchange) +{ + __ou_caslp_value_t liOldValue = (__ou_caslp_value_t)apComparand; + + return compare_and_swaplp((atomic_l)papDestination, &liOldValue, (__ou_caslp_value_t)apExchange); +} + + +#endif // #if _OU_TARGET_BITS == _OU_TARGET_BITS_64 + + +#undef __ou_caslp_value_t +#undef __ou_cas_value_t + + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_AIX + + +////////////////////////////////////////////////////////////////////////// +// SunOS implementation + +#if _OU_TARGET_OS == _OU_TARGET_OS_SUNOS + + +END_NAMESPACE_OU(); + + +#include <atomic.h> + + +BEGIN_NAMESPACE_OU(); + + +typedef uint32_t atomicord32; +typedef void *atomicptr; + + +#define __OU_ATOMIC_ORD32_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicIncrement(volatile atomicord32 *paoDestination) +{ + return atomic_inc_32_nv(paoDestination); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicDecrement(volatile atomicord32 *paoDestination) +{ + return atomic_dec_32_nv(paoDestination); +} + + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicExchange(volatile atomicord32 *paoDestination, atomicord32 aoExchange) +{ + return atomic_swap_32(paoDestination, aoExchange); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicExchangeAdd(volatile atomicord32 *paoDestination, atomicord32 aoAddend) +{ + return (atomic_add_32_nv(paoDestination, aoAddend) - aoAddend); +} + +static _OU_ALWAYSINLINE bool _OU_CONVENTION_API +/*bool */AtomicCompareExchange(volatile atomicord32 *paoDestination, atomicord32 aoComparand, atomicord32 aoExchange) +{ + return (aoComparand == atomic_cas_32(paoDestination, aoComparand, aoExchange)); +} + + +#define __OU_ATOMIC_BIT_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicAnd(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoOldValue = *paoDestination; + + while (true) + { + atomicord32 aoNewValue = atomic_cas_32(paoDestination, aoOldValue, aoOldValue & aoBitMask); + + if (aoNewValue == aoOldValue) + { + break; + } + + aoOldValue = aoNewValue; + } + + return aoOldValue; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicOr(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoOldValue = *paoDestination; + + while (true) + { + atomicord32 aoNewValue = atomic_cas_32(paoDestination, aoOldValue, aoOldValue | aoBitMask); + + if (aoNewValue == aoOldValue) + { + break; + } + + aoOldValue = aoNewValue; + } + + return aoOldValue; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicXor(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoOldValue = *paoDestination; + + while (true) + { + atomicord32 aoNewValue = atomic_cas_32(paoDestination, aoOldValue, aoOldValue ^ aoBitMask); + + if (aoNewValue == aoOldValue) + { + break; + } + + aoOldValue = aoNewValue; + } + + return aoOldValue; +} + + +#define __OU_ATOMIC_PTR_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicptr _OU_CONVENTION_API +/*atomicptr */AtomicExchangePointer(volatile atomicptr *papDestination, atomicptr apExchange) +{ + return atomic_swap_ptr(papDestination, apExchange); +} + +static _OU_ALWAYSINLINE bool _OU_CONVENTION_API +/*bool */AtomicCompareExchangePointer(volatile atomicptr *papDestination, atomicptr apComparand, atomicptr apExchange) +{ + return (apComparand == atomic_cas_ptr(papDestination, apComparand, apExchange)); +} + + +#define __OU_ATOMIC_ORD32_NORESULT_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicIncrementNoResult(volatile atomicord32 *paoDestination) +{ + atomic_inc_32(paoDestination); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicDecrementNoResult(volatile atomicord32 *paoDestination) +{ + atomic_dec_32(paoDestination); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicExchangeAddNoResult(volatile atomicord32 *paoDestination, atomicord32 aoAddend) +{ + atomic_add_32(paoDestination, aoAddend); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicAndNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomic_and_32(paoDestination, aoBitMask); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicOrNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomic_or_32(paoDestination, aoBitMask); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicXorNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + AtomicXor(paoDestination, aoBitMask); +} + + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_SUNOS + + +////////////////////////////////////////////////////////////////////////// +// Generic UNIX implementation + +#if _OU_TARGET_OS == _OU_TARGET_OS_GENUNIX + +// No atomic functions for generic UNIX + +#if _OU_COMPILER == _OU_COMPILER_GCC && (_OU_TARGET_ARCH == _OU_TARGET_ARCH_X86 || _OU_TARGET_ARCH == _OU_TARGET_ARCH_X64) + +#define __OU_ATOMIC_X86_ASSEMBLER_USE_AUTOENABLED 1 + + +#endif // Otherwise the x86 assembler implementation must be engaged explicitly + + +#if _OU_ATOMIC_USE_X86_ASSEMBLER || (__OU_ATOMIC_X86_ASSEMBLER_USE_AUTOENABLED && !defined(_OU_ATOMIC_USE_X86_ASSEMBLER)) + +typedef uint32ou atomicord32; +typedef void *atomicptr; + + +struct _ou_atomic_CLargeStruct +{ + unsigned int m_uiData[32]; +}; + + +#define __OU_ATOMIC_ORD32_FUNCTIONS_DEFINED + + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicIncrement(volatile atomicord32 *paoDestination) +{ + atomicord32 aoResult = 1; + + asm volatile ( + "lock; xaddl %2, %0;" + : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination), "=r" (aoResult) + : "1" (aoResult), "m" (*paoDestination) + : "memory", "cc"); + + return aoResult + 1; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicDecrement(volatile atomicord32 *paoDestination) +{ + atomicord32 aoResult = (atomicord32)(-1); + + asm volatile ( + "lock; xaddl %2, %0;" + : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination), "=r" (aoResult) + : "1" (aoResult), "m" (*paoDestination) + : "memory", "cc"); + + return aoResult - 1; +} + + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicExchange(volatile atomicord32 *paoDestination, atomicord32 aoExchange) +{ + atomicord32 aoResult; + + asm volatile ( + "xchgl %2, %0;" + : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination), "=r" (aoResult) + : "1" (aoExchange), "m" (*paoDestination) + : "memory"); + + return aoResult; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicExchangeAdd(volatile atomicord32 *paoDestination, atomicord32 aoAddend) +{ + atomicord32 aoResult; + + asm volatile ( + "lock; xaddl %2, %0;" + : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination), "=r" (aoResult) + : "1" (aoAddend), "m" (*paoDestination) + : "memory", "cc"); + + return aoResult; +} + +static _OU_ALWAYSINLINE bool _OU_CONVENTION_API +/*bool */AtomicCompareExchange(volatile atomicord32 *paoDestination, atomicord32 aoComparand, atomicord32 aoExchange) +{ + bool bResult; + + asm volatile ( + "lock; cmpxchgl %3, %0;" + "setzb %1;" + : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination), "=a" (bResult) + : "a" (aoComparand), "r" (aoExchange), "m" (*paoDestination) + : "memory", "cc"); + + return bResult; +} + + +#define __OU_ATOMIC_BIT_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicAnd(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoResult; + atomicord32 aoExchange; + + asm volatile ( + "0:;" + "movl %4, %2;" + "andl %3, %2;" + "lock; cmpxchgl %2, %0;" + "jnz 0b;" + : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination), "=a" (aoResult), "=&r" (aoExchange) + : "a" (*paoDestination), "g" (aoBitMask), "m" (*paoDestination) + : "memory", "cc"); + + return aoResult; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicOr(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoResult; + atomicord32 aoExchange; + + asm volatile ( + "0:;" + "movl %4, %2;" + "orl %3, %2;" + "lock; cmpxchgl %2, %0;" + "jnz 0b;" + : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination), "=a" (aoResult), "=&r" (aoExchange) + : "a" (*paoDestination), "g" (aoBitMask), "m" (*paoDestination) + : "memory", "cc"); + + return aoResult; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicXor(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoResult; + atomicord32 aoExchange; + + asm volatile ( + "0:;" + "movl %4, %2;" + "xorl %3, %2;" + "lock; cmpxchgl %2, %0;" + "jnz 0b;" + : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination), "=a" (aoResult), "=&r" (aoExchange) + : "a" (*paoDestination), "g" (aoBitMask), "m" (*paoDestination) + : "memory", "cc"); + + return aoResult; +} + + +#define __OU_ATOMIC_ORD32_NORESULT_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicIncrementNoResult(volatile atomicord32 *paoDestination) +{ + asm volatile ( + "lock; incl %0;" + : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination) + : "m" (*paoDestination) + : "memory", "cc"); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicDecrementNoResult(volatile atomicord32 *paoDestination) +{ + asm volatile ( + "lock; decl %0;" + : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination) + : "m" (*paoDestination) + : "memory", "cc"); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicExchangeAddNoResult(volatile atomicord32 *paoDestination, atomicord32 aoAddend) +{ + asm volatile ( + "lock; addl %1, %0;" + : "=m,m,m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination) + : "r,K,i" (aoAddend), "m,m,m" (*paoDestination) + : "memory", "cc"); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicAndNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + asm volatile ( + "lock; andl %1, %0;" + : "=m,m,m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination) + : "r,K,i" (aoBitMask), "m,m,m" (*paoDestination) + : "memory", "cc"); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicOrNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + asm volatile ( + "lock; orl %1, %0;" + : "=m,m,m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination) + : "r,K,i" (aoBitMask), "m,m,m" (*paoDestination) + : "memory", "cc"); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicXorNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + asm volatile ( + "lock; xorl %1, %0;" + : "=m,m,m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination) + : "r,K,i" (aoBitMask), "m,m,m" (*paoDestination) + : "memory", "cc"); +} + + +#define __OU_ATOMIC_PTR_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicptr _OU_CONVENTION_API +/*atomicptr */AtomicExchangePointer(volatile atomicptr *papDestination, atomicptr apExchange) +{ + atomicptr apResult; + + asm volatile ( + "xchg %2, %0;" + : "=m" (*(volatile _ou_atomic_CLargeStruct *)papDestination), "=r" (apResult) + : "1" (apExchange), "m" (*papDestination) + : "memory"); + + return apResult; +} + +static _OU_ALWAYSINLINE bool _OU_CONVENTION_API +/*bool */AtomicCompareExchangePointer(volatile atomicptr *papDestination, atomicptr apComparand, atomicptr apExchange) +{ + bool bResult; + + asm volatile ( + "lock; cmpxchg %3, %0;" + "setzb %1;" + : "=m" (*(volatile _ou_atomic_CLargeStruct *)papDestination), "=a" (bResult) + : "a" (apComparand), "r" (apExchange), "m" (*papDestination) + : "memory", "cc"); + + return bResult; +} + + +#endif // #if defined(_OU_ATOMIC_USE_X86_ASSEMBLER) + + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_GENUNIX + + +////////////////////////////////////////////////////////////////////////// +// BitMask to CompareExchange forwarders + +#if defined(__OU_ATOMIC_ORD32_FUNCTIONS_DEFINED) && !defined(__OU_ATOMIC_BIT_FUNCTIONS_DEFINED) + +#define __OU_ATOMIC_BIT_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicAnd(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoOldValue = *paoDestination; + + while (true) + { + if (AtomicCompareExchange(paoDestination, aoOldValue, (aoOldValue & aoBitMask))) + { + break; + } + + aoOldValue = *paoDestination; + } + + return aoOldValue; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicOr(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoOldValue = *paoDestination; + + while (true) + { + if (AtomicCompareExchange(paoDestination, aoOldValue, (aoOldValue | aoBitMask))) + { + break; + } + + aoOldValue = *paoDestination; + } + + return aoOldValue; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicXor(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoOldValue = *paoDestination; + + while (true) + { + if (AtomicCompareExchange(paoDestination, aoOldValue, (aoOldValue ^ aoBitMask))) + { + break; + } + + aoOldValue = *paoDestination; + } + + return aoOldValue; +} + + +#endif // #if defined(__OU_ATOMIC_ORD32_FUNCTIONS_DEFINED) && !defined(__OU_ATOMIC_BIT_FUNCTIONS_DEFINED) + + +////////////////////////////////////////////////////////////////////////// +// Pointer to ord32 forwarders + +#if defined(__OU_ATOMIC_ORD32_FUNCTIONS_DEFINED) && !defined(__OU_ATOMIC_PTR_FUNCTIONS_DEFINED) && _OU_TARGET_BITS == _OU_TARGET_BITS_32 + +#define __OU_ATOMIC_PTR_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicptr _OU_CONVENTION_API +/*atomicptr */AtomicExchangePointer(volatile atomicptr *papDestination, atomicptr apExchange) +{ + return (atomicptr)AtomicExchange((volatile atomicord32 *)papDestination, (atomicord32)apExchange); +} + +static _OU_ALWAYSINLINE bool _OU_CONVENTION_API +/*bool */AtomicCompareExchangePointer(volatile atomicptr *papDestination, atomicptr apComparand, atomicptr apExchange) +{ + return AtomicCompareExchange((volatile atomicord32 *)papDestination, (atomicord32)apComparand, (atomicord32)apExchange); +} + + +#endif // #if defined(__OU_ATOMIC_ORD32_FUNCTIONS_DEFINED) && !defined(__OU_ATOMIC_PTR_FUNCTIONS_DEFINED) && _OU_TARGET_BITS == _OU_TARGET_BITS_32 + + +////////////////////////////////////////////////////////////////////////// +// Atomic-via-mutex implementations + +#if !defined(__OU_ATOMIC_ORD32_FUNCTIONS_DEFINED) + + +END_NAMESPACE_OU(); + + +#include <stddef.h> + + +BEGIN_NAMESPACE_OU(); + + +typedef uint32_t atomicord32; +typedef void *atomicptr; + + +atomicord32 _OU_CONVENTION_API AtomicIncrement(volatile atomicord32 *paoDestination); +atomicord32 _OU_CONVENTION_API AtomicDecrement(volatile atomicord32 *paoDestination); + +atomicord32 _OU_CONVENTION_API AtomicExchange(volatile atomicord32 *paoDestination, atomicord32 aoExchange); +atomicord32 _OU_CONVENTION_API AtomicExchangeAdd(volatile atomicord32 *paoDestination, atomicord32 aoAddend); +bool _OU_CONVENTION_API AtomicCompareExchange(volatile atomicord32 *paoDestination, atomicord32 aoComparand, atomicord32 aoExchange); + +atomicord32 _OU_CONVENTION_API AtomicAnd(volatile atomicord32 *paoDestination, atomicord32 aoBitMask); +atomicord32 _OU_CONVENTION_API AtomicOr(volatile atomicord32 *paoDestination, atomicord32 aoBitMask); +atomicord32 _OU_CONVENTION_API AtomicXor(volatile atomicord32 *paoDestination, atomicord32 aoBitMask); + + +#if defined(__OU_ATOMIC_BIT_FUNCTIONS_DEFINED) + +#error Internal error (__OU_ATOMIC_BIT_FUNCTIONS_DEFINED must not be defined in this case) + + +#endif // #if defined(__OU_ATOMIC_BIT_FUNCTIONS_DEFINED) + +#if defined(__OU_ATOMIC_PTR_FUNCTIONS_DEFINED) + +#error Internal error (__OU_ATOMIC_PTR_FUNCTIONS_DEFINED must not be defined in this case) + + +#endif // #if defined(__OU_ATOMIC_PTR_FUNCTIONS_DEFINED) + + +#endif // #if !defined(__OU_ATOMIC_ORD32_FUNCTIONS_DEFINED) + + +#if !defined(__OU_ATOMIC_PTR_FUNCTIONS_DEFINED) + +atomicptr _OU_CONVENTION_API AtomicExchangePointer(volatile atomicptr *papDestination, atomicptr apExchange); +bool _OU_CONVENTION_API AtomicCompareExchangePointer(volatile atomicptr *papDestination, atomicptr apComparand, atomicptr apExchange); + + +#if defined(__OU_DOXYGEN__) + +// Doxygen fooling declarations (used for documentation generation only) +void _OU_CONVENTION_API AtomicIncrementNoResult(volatile atomicord32 *paoDestination); +void _OU_CONVENTION_API AtomicDecrementNoResult(volatile atomicord32 *paoDestination); +void _OU_CONVENTION_API AtomicStore(volatile atomicord32 *paoDestination, atomicord32 aoValue); +void _OU_CONVENTION_API AtomicExchangeAddNoResult(volatile atomicord32 *paoDestination, atomicord32 aoAddend); +void _OU_CONVENTION_API AtomicAndNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask); +void _OU_CONVENTION_API AtomicOrNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask); +void _OU_CONVENTION_API AtomicXorNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask); +void _OU_CONVENTION_API AtomicStorePointer(volatile atomicptr *papDestination, atomicptr apValue); +void _OU_CONVENTION_API AtomicReadReorderBarrier(); + +#endif // #if defined(__OU_DOXYGEN__) + + +#define __OU_ATOMIC_OPERATIONS_VIA_MUTEXES +#define __OU_ATOMIC_INITIALIZATION_FUNCTIONS_REQUIRED + +// Initialization must be performed from main thread +bool _OU_CONVENTION_API InitializeAtomicAPI(); +void _OU_CONVENTION_API FinalizeAtomicAPI(); + + +#endif // #if !defined(__OU_ATOMIC_PTR_FUNCTIONS_DEFINED) + + +////////////////////////////////////////////////////////////////////////// +// No-result to result forwarders + +#if !defined(__OU_ATOMIC_ORD32_NORESULT_FUNCTIONS_DEFINED) + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicIncrementNoResult(volatile atomicord32 *paoDestination) +{ + AtomicIncrement(paoDestination); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicDecrementNoResult(volatile atomicord32 *paoDestination) +{ + AtomicDecrement(paoDestination); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicExchangeAddNoResult(volatile atomicord32 *paoDestination, atomicord32 aoAddend) +{ + AtomicExchangeAdd(paoDestination, aoAddend); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicAndNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + AtomicAnd(paoDestination, aoBitMask); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicOrNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + AtomicOr(paoDestination, aoBitMask); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicXorNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + AtomicXor(paoDestination, aoBitMask); +} + + +#endif // #if !defined(__OU_ATOMIC_ORD32_NORESULT_FUNCTIONS_DEFINED) + + +////////////////////////////////////////////////////////////////////////// +// Default Load/Store function implementations + +#if !defined(__OU_ATOMIC_READREORDERBARRIER_FUNCTION_DEFINED) && _OU_COMPILER == _OU_COMPILER_GCC + +// These architectures are known (by me ;-))to retain memory read request order +#if (_OU_TARGET_ARCH == _OU_TARGET_ARCH_X86 || _OU_TARGET_ARCH == _OU_TARGET_ARCH_X64) + +#define __OU_ATOMIC_READREORDERBARRIER_FUNCTION_DEFINED + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicReadReorderBarrier() +{ + // x86/x64 architectures do not reorder memory reads anyway + // it's only necessary to stop compiler from reordering read instructions + asm volatile ( "" : : :"memory" ); +} + + +#endif // #if (_OU_TARGET_ARCH == _OU_TARGET_ARCH_X86 || _OU_TARGET_ARCH == _OU_TARGET_ARCH_X64) + + +#endif // #if !defined(__OU_ATOMIC_READREORDERBARRIER_FUNCTION_DEFINED) && _OU_COMPILER == _OU_COMPILER_GCC + + +#ifndef __OU_ATOMIC_READREORDERBARRIER_FUNCTION_DEFINED + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicReadReorderBarrier() +{ + atomicord32 aoTemporaryValue; + AtomicExchangeAddNoResult(&aoTemporaryValue, 0); +} + + +#endif // #ifndef __OU_ATOMIC_READREORDERBARRIER_FUNCTION_DEFINED + + +#ifndef __OU_ATOMIC_STORE_FUNCTION_DEFINED + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicStore(volatile atomicord32 *paoDestination, atomicord32 aoValue) +{ + AtomicExchange(paoDestination, aoValue); +} + + +#endif // #ifndef __OU_ATOMIC_STORE_FUNCTION_DEFINED + + +#ifndef __OU_ATOMIC_STOREPTR_FUNCTION_DEFINED + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicStorePointer(volatile atomicptr *papDestination, atomicptr apValue) +{ + AtomicExchangePointer(papDestination, apValue); +} + + +#endif // #ifndef __OU_ATOMIC_STOREPTR_FUNCTION_DEFINED + + +////////////////////////////////////////////////////////////////////////// +// Atomic initialization function stubs + +#if !defined(__OU_ATOMIC_INITIALIZATION_FUNCTIONS_REQUIRED) + +// Initialization must be performed from main thread +static _OU_INLINE bool _OU_CONVENTION_API InitializeAtomicAPI() +{ + // Do nothing + + return true; +} + +static _OU_INLINE void _OU_CONVENTION_API FinalizeAtomicAPI() +{ + // Do nothing +} + + +#endif // #if !defined(__OU_ATOMIC_INITIALIZE_FUNCTIONS_DEFINED) + + +END_NAMESPACE_OU(); + + +#endif // #if _OU_FEATURE_SET >= _OU_FEATURE_SET_ATOMICS + + +#endif // #ifndef __OU_ATOMIC_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/atomicflags.h b/libs/ode-0.16.1/ou/include/ou/atomicflags.h new file mode 100644 index 0000000..58517fa --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/atomicflags.h @@ -0,0 +1,367 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_ATOMICFLAGS_H_INCLUDED +#define __OU_ATOMICFLAGS_H_INCLUDED + + +#include <ou/flagsdefines.h> +#include <ou/atomic.h> +#include <ou/assert.h> +#include <ou/namespace.h> + + +BEGIN_NAMESPACE_OU(); + + +/* + * Implementation Note: + * Modification functions are implemented as memory barriers. + * Retrieval functions are implemented as ordinary memory accesses. + * Practice proves that such approach is quite sufficient to provide + * reliable synchronization mechanisms (provided a developer has solid + * knowledge in field, of course). + */ + +class CAtomicFlags +{ +public: + _OU_INLINE _OU_CONVENTION_METHOD CAtomicFlags(): + m_aoFlagsValue(0) + { + } + + _OU_INLINE _OU_CONVENTION_METHOD CAtomicFlags(atomicord32 aoFlagsValue): + m_aoFlagsValue(aoFlagsValue) + { + } + + typedef atomicord32 value_type; + +public: + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */AssignFlagsAllValues(atomicord32 aoFlagsValue) + { + AtomicExchange(&m_aoFlagsValue, aoFlagsValue); + } + + _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_METHOD + /*atomicord32 */QueryFlagsAllValues() const + { + return m_aoFlagsValue; + } + + + // Can operate both on single flag and flag set + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */SetFlagsMaskValue(atomicord32 aoFlagsMask, bool bFlagValue) + { + if (bFlagValue) + { + AtomicOrNoResult(&m_aoFlagsValue, aoFlagsMask); + } + else + { + AtomicAndNoResult(&m_aoFlagsValue, ~aoFlagsMask); + } + } + + // Can operate both on single flag and flag set + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */SignalFlagsMaskValue(atomicord32 aoFlagsMask) + { + AtomicOrNoResult(&m_aoFlagsValue, aoFlagsMask); + } + + // Can operate both on single flag and flag set + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */DropFlagsMaskValue(atomicord32 aoFlagsMask) + { + AtomicAndNoResult(&m_aoFlagsValue, ~aoFlagsMask); + } + + + // Can operate on single flag only + // Returns previous flag value + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */ToggleSingleFlagValue(atomicord32 aoSingleFlag) + { + OU_ASSERT(OU_FLAGS_FLAG_IS_SINGLE(atomicord32, aoSingleFlag)); + + return (AtomicXor(&m_aoFlagsValue, aoSingleFlag) & aoSingleFlag) != (atomicord32)0; + } + + // Can operate on single flag only + // Returns if modification occurred + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */ModifySingleFlagValue(atomicord32 aoSingleFlag, bool bFlagValue) + { + OU_ASSERT(OU_FLAGS_FLAG_IS_SINGLE(atomicord32, aoSingleFlag)); + + return bFlagValue + ? ((AtomicOr(&m_aoFlagsValue, aoSingleFlag) & aoSingleFlag) == (atomicord32)0) + : ((AtomicAnd(&m_aoFlagsValue, ~aoSingleFlag) & aoSingleFlag) != (atomicord32)0); + } + + + // Modifies subset of flags + // Returns previous flags + _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_METHOD + /*atomicord32 */AssignFlagsByMask(atomicord32 aoFlagsMask, atomicord32 aoFlagsValue) + { + atomicord32 aoFlagsOldValue; + + do + { + aoFlagsOldValue = m_aoFlagsValue; + } + while (!AtomicCompareExchange(&m_aoFlagsValue, aoFlagsOldValue, (aoFlagsOldValue & ~aoFlagsMask) | (aoFlagsValue & aoFlagsMask))); + + return aoFlagsOldValue; + } + + // Modifies subset of flags + // Returns if modification occurred + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */AlterFlagsByMask(atomicord32 aoFlagsMask, atomicord32 aoFlagsValue) + { + atomicord32 aoFlagsOldValue; + + do + { + aoFlagsOldValue = m_aoFlagsValue; + } + while (!AtomicCompareExchange(&m_aoFlagsValue, aoFlagsOldValue, (aoFlagsOldValue & ~aoFlagsMask) | (aoFlagsValue & aoFlagsMask))); + + return ((aoFlagsOldValue ^ aoFlagsValue) & aoFlagsMask) != (atomicord32)0; + } + + + // Returns value of flag or tests for any bit in a mask + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */GetFlagsMaskValue(atomicord32 aoFlagsMask) const + { + return (m_aoFlagsValue & aoFlagsMask) != (atomicord32)0; + } + + // Returns subset of flags + _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_METHOD + /*atomicord32 */QueryFlagsByMask(atomicord32 aoFlagsMask) const + { + return (m_aoFlagsValue & aoFlagsMask); + } + +public: + // Signal only flag out of mask + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */OnlySignalSingleFlagOutOfMask(atomicord32 aoFlagsMask, atomicord32 aoSingleFlag) + { + OU_ASSERT(OU_FLAGS_FLAG_IS_SINGLE(atomicord32, aoSingleFlag)); + + bool bResult; + + atomicord32 aoFlagsOldValue; + + do + { + aoFlagsOldValue = m_aoFlagsValue; + + /* + * Implementation Note: + * 1) This function may be not a memory barrier. However that would also mean that + * no modification occurred and result is 'false'. Such behavior should be OK. + * 2) Even though second assignment to bResult is unnecessary it might yield + * better code as compiler does not need to save variable's value for the call + * to AtomicCompareExchange in this case. + */ + } + while ((bResult = !(aoFlagsOldValue & aoFlagsMask)) && !(bResult = AtomicCompareExchange(&m_aoFlagsValue, aoFlagsOldValue, aoFlagsOldValue | aoSingleFlag))); + + return bResult; + } + +public: + // Set value of flag indexed by enum + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */EnumSetEnumeratedFlagValue(atomicord32 aoStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum, bool bFlagValue) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + + SetFlagsMaskValue(aoStartingFlag << uiEnumeratedValue, bFlagValue); + } + + // Signal value of flag indexed by enum + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */EnumSignalEnumeratedFlagValue(atomicord32 aoStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + + SignalFlagsMaskValue(aoStartingFlag << uiEnumeratedValue); + } + + // Drop value of flag indexed by enum + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */EnumDropEnumeratedFlagValue(atomicord32 aoStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + + DropFlagsMaskValue(aoStartingFlag << uiEnumeratedValue); + } + + + // Can operate on single flag only + // Returns previous flag value + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */EnumToggleEnumeratedFlagValue(atomicord32 aoStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + + return ToggleSingleFlagValue(aoStartingFlag << uiEnumeratedValue); + } + + // Can operate on single flag only + // Returns if modification occurred + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */EnumModifyEnumeratedFlagValue(atomicord32 aoStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum, bool bFlagValue) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + + return ModifySingleFlagValue(aoStartingFlag << uiEnumeratedValue, bFlagValue); + } + + + // Returns if this was the first flag signaled + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */EnumSignalFirstEnumeratedFlagValue(atomicord32 aoStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + + return (AssignFlagsByMask(aoStartingFlag << uiEnumeratedValue, aoStartingFlag << uiEnumeratedValue) & OU_FLAGS_ENUMFLAGS_MASK(atomicord32, aoStartingFlag, uiEnumeratedMaximum)) == (atomicord32)0; + } + + // Returns if this was the last flag signaled + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */EnumSignalLastEnumeratedFlagValue(atomicord32 aoStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + + return (AssignFlagsByMask(aoStartingFlag << uiEnumeratedValue, aoStartingFlag << uiEnumeratedValue) & OU_FLAGS_ENUMFLAGS_MASK(atomicord32, aoStartingFlag, uiEnumeratedMaximum)) == (OU_FLAGS_ENUMFLAGS_MASK(atomicord32, aoStartingFlag, uiEnumeratedMaximum) & ~(aoStartingFlag << uiEnumeratedValue)); + } + + + // Retrieve value of flag indexed by enum + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */EnumGetEnumeratedFlagValue(atomicord32 aoStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum) const + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + + return GetFlagsMaskValue(aoStartingFlag << uiEnumeratedValue); + } + + // Find enum value for first flag signaled + _OU_INLINE int _OU_CONVENTION_METHOD + /*int */EnumFindFirstEnumeratedFlag(atomicord32 aoStartingFlag, unsigned int uiEnumeratedMaximum) const + { + OU_ASSERT(OU_FLAGS_ENUMFLAGS_START_VALID(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + + unsigned int uiResult = 0; + + atomicord32 aoFlagsMask = aoStartingFlag; + for (; uiResult < uiEnumeratedMaximum; ++uiResult, aoFlagsMask <<= 1) + { + if (GetFlagsMaskValue(aoFlagsMask)) + { + break; + } + } + + return uiResult; + } + +public: + // Signal all flags indexed by enum + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */EnumAllSignalEnumeratedFlags(atomicord32 aoStartingFlag, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(OU_FLAGS_ENUMFLAGS_START_VALID(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + + SignalFlagsMaskValue(OU_FLAGS_ENUMFLAGS_MASK(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + } + + // Drop all flags indexed by enum + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */EnumAllDropEnumeratedFlags(atomicord32 aoStartingFlag, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(OU_FLAGS_ENUMFLAGS_START_VALID(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + + DropFlagsMaskValue(OU_FLAGS_ENUMFLAGS_MASK(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + } + + + // Query all flags indexed by enum + _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_METHOD + /*atomicord32 */EnumAllQueryEnumeratedFlags(atomicord32 aoStartingFlag, unsigned int uiEnumeratedMaximum) const + { + OU_ASSERT(OU_FLAGS_ENUMFLAGS_START_VALID(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + + return QueryFlagsByMask(OU_FLAGS_ENUMFLAGS_MASK(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + } + + // Get if any flag indexed by enum is set + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */EnumAnyGetEnumeratedFlagValue(atomicord32 aoStartingFlag, unsigned int uiEnumeratedMaximum) const + { + OU_ASSERT(OU_FLAGS_ENUMFLAGS_START_VALID(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + + return GetFlagsMaskValue(OU_FLAGS_ENUMFLAGS_MASK(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + } + +public: + // Store enumerated value in flags + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */StoreFlagsEnumeratedValue(atomicord32 aoEnumeratedValueMask, unsigned int uiEnumeratedValueShift, unsigned int uiEnumeratedValue) + { + OU_ASSERT(OU_FLAGS_STOREENUM_VALUE_IN_MASK(atomicord32, uiEnumeratedValue, aoEnumeratedValueMask)); + + AssignFlagsByMask(aoEnumeratedValueMask << uiEnumeratedValueShift, (atomicord32)uiEnumeratedValue << uiEnumeratedValueShift); + } + + // Retrieve enumerated value from flags + _OU_ALWAYSINLINE unsigned int _OU_CONVENTION_METHOD + /*unsigned int */RetrieveFlagsEnumeratedValue(atomicord32 aoEnumeratedValueMask, unsigned int uiEnumeratedValueShift) const + { + return (unsigned int)((QueryFlagsAllValues() >> uiEnumeratedValueShift) & aoEnumeratedValueMask); + } + +private: + atomicord32 m_aoFlagsValue; +}; + + +END_NAMESPACE_OU(); + + +#endif // #ifndef __OU_ATOMICFLAGS_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/customization.h b/libs/ode-0.16.1/ou/include/ou/customization.h new file mode 100644 index 0000000..17fbeb0 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/customization.h @@ -0,0 +1,149 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_CUSTOMIZATION_H_INCLUDED +#define __OU_CUSTOMIZATION_H_INCLUDED + + +#include <ou/namespace.h> +#include <ou/inttypes.h> +#include <ou/platform.h> + +#include <stddef.h> + + +BEGIN_NAMESPACE_OU(); + + +////////////////////////////////////////////////////////////////////////// +// Some helper definitions for assert macros + +#if !defined(__FILE__) + +// Definition of __FILE__ constant for the case if compiler does not support the macro +extern const char *const __FILE__; + + +#endif // #if !defined(__FILE__) + + +#if !defined(__LINE__) + +// Definition of __LINE__ constant for the case if compiler does not support the macro +extern const unsigned int __LINE__; + + +#endif // #if !defined(__LINE__) + + +////////////////////////////////////////////////////////////////////////// +// Assertion checks customization + +enum EASSERTIONFAILURESEVERITY +{ + AFS__MIN, + + AFS_ASSERT = AFS__MIN, + AFS_CHECK, + + AFS__MAX, +}; + + +typedef void (_OU_CONVENTION_CALLBACK *CAssertionFailedProcedure)(EASSERTIONFAILURESEVERITY fsFailureSeverity, + const char *szAssertionExpression, const char *szAssertionFileName, unsigned int uiAssertionSourceLine); + + +class CAssertionCheckCustomization +{ +public: + static _OU_ALWAYSINLINE CAssertionFailedProcedure _OU_CONVENTION_API + /*CAssertionFailedProcedure */GetAssertFailureCustomHandler() + { + return g_fnAssertFailureHandler; + } + + static _OU_INLINE void _OU_CONVENTION_API CustomizeAssertionChecks(CAssertionFailedProcedure fnAssertionFailureProcedure) + { + g_fnAssertFailureHandler = fnAssertionFailureProcedure; + } + +private: + static CAssertionFailedProcedure g_fnAssertFailureHandler; +}; + + +////////////////////////////////////////////////////////////////////////// +// Memory manager customization + +#define _OU_MEMORY_REQUIRED_ALIGNMENT sizeof(_OU_NAMESPACE::uint64ou) + + +typedef void *(_OU_CONVENTION_CALLBACK *CMemoryAllocationProcedure)(size_t nBlockSize); +typedef void *(_OU_CONVENTION_CALLBACK *CMemoryReallocationProcedure)(void *pv_ExistingBlock, size_t nBlockNewSize); +typedef void (_OU_CONVENTION_CALLBACK *CMemoryDeallocationProcedure)(void *pv_ExistingBlock); + + +class CMemoryManagerCustomization +{ +public: + static _OU_ALWAYSINLINE CMemoryAllocationProcedure _OU_CONVENTION_API + /*CMemoryAllocationProcedure */GetMemoryAllocationCustomProcedure() + { + return g_fnMemoryAllocationProcedure; + } + + static _OU_ALWAYSINLINE CMemoryReallocationProcedure _OU_CONVENTION_API + /*CMemoryReallocationProcedure */GetMemoryReallocationCustomProcedure() + { + return g_fnMemoryReallocationProcedure; + } + + static _OU_ALWAYSINLINE CMemoryDeallocationProcedure _OU_CONVENTION_API + /*CMemoryDeallocationProcedure */GetMemoryDeallocationCustomProcedure() + { + return g_fnMemoryDeallocationProcedure; + } + + static _OU_INLINE void _OU_CONVENTION_API CustomizeMemoryManager(CMemoryAllocationProcedure fnAllocationProcedure, + CMemoryReallocationProcedure fnReallocationProcedure, CMemoryDeallocationProcedure fnDeallocationProcedure) + { + g_fnMemoryAllocationProcedure = fnAllocationProcedure; + g_fnMemoryReallocationProcedure = fnReallocationProcedure; + g_fnMemoryDeallocationProcedure = fnDeallocationProcedure; + } + +private: + static CMemoryAllocationProcedure g_fnMemoryAllocationProcedure; + static CMemoryReallocationProcedure g_fnMemoryReallocationProcedure; + static CMemoryDeallocationProcedure g_fnMemoryDeallocationProcedure; +}; + + +END_NAMESPACE_OU(); + + +#endif // #ifndef __OU_CUSTOMIZATION_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/enumarrays.h b/libs/ode-0.16.1/ou/include/ou/enumarrays.h new file mode 100644 index 0000000..d8ce0c1 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/enumarrays.h @@ -0,0 +1,256 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_ENUMARRAYS_H_INCLUDED +#define __OU_ENUMARRAYS_H_INCLUDED + + +#include <ou/assert.h> +#include <ou/macros.h> +#include <ou/platform.h> +#include <ou/namespace.h> + + +BEGIN_NAMESPACE_OU(); + + +////////////////////////////////////////////////////////////////////////// +// Helper template definitions + +template<typename ElementType> +struct CTypeStandardEqual +{ + _OU_INLINE bool _OU_CONVENTION_METHOD operator ()(const ElementType &etLeftElement, const ElementType &etRightElement) const + { + return etLeftElement == etRightElement; + } +}; + +template<typename ElementType> +struct CTypeStandardLess +{ + _OU_INLINE bool _OU_CONVENTION_METHOD operator ()(const ElementType &etLeftElement, const ElementType &etRightElement) const + { + return etLeftElement < etRightElement; + } +}; + + +////////////////////////////////////////////////////////////////////////// +// CEnumUnsortedElementArray definition + +/* + * Implementation Note: + * The array is intended to store static constant data. + * Therefore CElementEqualType should not ever need a nontrivial constructor + * and it is acceptable to have it as template parameter. + */ + +template<typename EnumType, const EnumType EnumMax, typename ElementType, const int Instance=0, class CElementEqualType=CTypeStandardEqual<ElementType> > +class CEnumUnsortedElementArray +{ +public: + _OU_CONVENTION_METHOD CEnumUnsortedElementArray() + { +#if !defined(NDEBUG) + +#if _OU_COMPILER != _OU_COMPILER_GCC || _OU_COMPILER_VERSION == _OU_COMPILER_VERSION_GCCLT4 + + OU_ASSERT(OU_ARRAY_SIZE(m_aetElementArray) == EnumMax); + + +#endif // #if _OU_COMPILER != _OU_COMPILER_GCC || _OU_COMPILER_VERSION == _OU_COMPILER_VERSION_GCCLT4 + + +#endif // #if !defined(NDEBUG) + } + +public: + static _OU_ALWAYSINLINE const EnumType _OU_CONVENTION_API + /*const EnumType */Decode(const ElementType &etValue) + { + const ElementType *itElementFound = FindValueSequentially(m_aetElementArray, m_aetElementArray + EnumMax, etValue); + + EnumType etResult = (EnumType)(itElementFound - m_aetElementArray); + return etResult; + } + + static _OU_ALWAYSINLINE const ElementType &_OU_CONVENTION_API + /*const ElementType &*/Encode(const EnumType &etValue) + { + OU_ASSERT(sizeof(EnumType) <= sizeof(int)); + OU_ASSERT(OU_IN_INT_RANGE(etValue, 0, EnumMax)); + + return m_aetElementArray[etValue]; + } + + static _OU_ALWAYSINLINE bool _OU_CONVENTION_API + /*bool */IsValidDecode(const EnumType &etValue) + { + return etValue != EnumMax; + } + + static _OU_ALWAYSINLINE const ElementType *_OU_CONVENTION_API + /*const ElementType **/GetStoragePointer() + { + return m_aetElementArray; + } + +private: + static const ElementType *_OU_CONVENTION_API FindValueSequentially(const ElementType *petArrayBegin, const ElementType *petArrayEnd, const ElementType &etValue) + { + const CElementEqualType etElementEqual = CElementEqualType(); + + const ElementType *petCurrentElement = petArrayBegin; + + for (; petCurrentElement != petArrayEnd; ++petCurrentElement) + { + if (etElementEqual(*petCurrentElement, etValue)) + { + break; + } + } + + return petCurrentElement; + } + +private: + static const ElementType m_aetElementArray[]; +}; + + +////////////////////////////////////////////////////////////////////////// +// CEnumSortedElementArray definition + +/* + * Implementation Note: + * The array is intended to store static constant data. + * Therefore CElementLessType and CElementEqualType should not ever need + * a nontrivial constructor and it is acceptable to have them + * as template parameters. + */ + +template<typename EnumType, const EnumType EnumMax, typename ElementType, const int Instance=0, class CElementLessType=CTypeStandardLess<ElementType> > +class CEnumSortedElementArray +{ +public: + _OU_INLINE _OU_CONVENTION_METHOD CEnumSortedElementArray() + { +#if !defined(NDEBUG) + +#if _OU_COMPILER != _OU_COMPILER_GCC || _OU_COMPILER_VERSION == _OU_COMPILER_VERSION_GCCLT4 + + OU_ASSERT(OU_ARRAY_SIZE(m_aetElementArray) == EnumMax); + + +#endif // #if _OU_COMPILER != _OU_COMPILER_GCC || _OU_COMPILER_VERSION == _OU_COMPILER_VERSION_GCCLT4 + + const CElementLessType ltElementLess = CElementLessType(); + + for (unsigned nElementIndex = 1; nElementIndex < EnumMax; ++nElementIndex) + { + OU_ASSERT(ltElementLess(m_aetElementArray[nElementIndex - 1], m_aetElementArray[nElementIndex])); // Element values must be sorted + } + + +#endif // #if !defined(NDEBUG) + } + + static _OU_ALWAYSINLINE const EnumType _OU_CONVENTION_API + /*const EnumType */Decode(const ElementType &etValue) + { + const CElementLessType ltElementLess = CElementLessType(); + + EnumType etResult = EnumMax; + + const ElementType *itElementFound = FindValueLowerBound(m_aetElementArray, m_aetElementArray + EnumMax, etValue); + + if (itElementFound != m_aetElementArray + EnumMax) + { + if (!ltElementLess(etValue, *itElementFound)) + { + etResult = (EnumType)(itElementFound - m_aetElementArray); + } + } + + return etResult; + } + + static _OU_ALWAYSINLINE const ElementType &_OU_CONVENTION_API + /*const ElementType &*/Encode(const EnumType &etValue) + { + OU_ASSERT(sizeof(EnumType) <= sizeof(int)); + OU_ASSERT(OU_IN_INT_RANGE(etValue, 0, EnumMax)); + + return m_aetElementArray[etValue]; + } + + static _OU_ALWAYSINLINE bool _OU_CONVENTION_API + /*bool */IsValidDecode(const EnumType &etValue) + { + return etValue != EnumMax; + } + + static _OU_ALWAYSINLINE const ElementType *_OU_CONVENTION_API + /*const ElementType **/GetStoragePointer() + { + return m_aetElementArray; + } + +private: + static const ElementType *_OU_CONVENTION_API FindValueLowerBound(const ElementType *petArrayBegin, const ElementType *petArrayEnd, const ElementType &etValue) + { + const CElementLessType ltElementLess = CElementLessType(); + + const ElementType *petCurrentRangeBegin = petArrayBegin; + const ElementType *petCurrentRangeEnd = petArrayEnd; + + while (petCurrentRangeBegin != petCurrentRangeEnd) + { + const ElementType *petCurrentRangeMiddle = petCurrentRangeBegin + (petCurrentRangeEnd - petCurrentRangeBegin) / 2; + + if (ltElementLess(*petCurrentRangeMiddle, etValue)) + { + petCurrentRangeBegin = petCurrentRangeMiddle + 1; + } + else + { + petCurrentRangeEnd = petCurrentRangeMiddle; + } + } + + return petCurrentRangeBegin; + } + +private: + static const ElementType m_aetElementArray[]; +}; + + +END_NAMESPACE_OU(); + + +#endif // #ifndef __OU_ENUMARRAYS_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/features.h b/libs/ode-0.16.1/ou/include/ou/features.h new file mode 100644 index 0000000..bf50a57 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/features.h @@ -0,0 +1,51 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_FEATURES_H_INCLUDED +#define __OU_FEATURES_H_INCLUDED + + +////////////////////////////////////////////////////////////////////////// +// Feature set definitions + +#define _OU_FEATURE_SET_BASICS 0 +#define _OU_FEATURE_SET_ATOMICS 1 +#define _OU_FEATURE_SET_TLS 2 + +#define _OU_FEATURE_SET__MAX 3 + + +////////////////////////////////////////////////////////////////////////// + +#if !defined(_OU_FEATURE_SET) + +#define _OU_FEATURE_SET _OU_FEATURE_SET__MAX + + +#endif // #if !defined(_OU_FEATURE_SET) + + +#endif // #ifndef __OU_FEATURES_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/flags.h b/libs/ode-0.16.1/ou/include/ou/flags.h new file mode 100644 index 0000000..781dd6b --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/flags.h @@ -0,0 +1,35 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_FLAGS_H_INCLUDED +#define __OU_FLAGS_H_INCLUDED + + +#include <ou/simpleflags.h> +#include <ou/atomicflags.h> + + +#endif // #ifndef __OU_FLAGS_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/flagsdefines.h b/libs/ode-0.16.1/ou/include/ou/flagsdefines.h new file mode 100644 index 0000000..b294ead --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/flagsdefines.h @@ -0,0 +1,37 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_FLAGSDEFINES_H_INCLUDED +#define __OU_FLAGSDEFINES_H_INCLUDED + + +#define OU_FLAGS_ENUMFLAGS_MASK(Type, StartingFlag, EnumMax) ((Type)((Type)((Type)((Type)(StartingFlag) << ((EnumMax) - 1)) - (Type)(StartingFlag)) | (Type)((Type)(StartingFlag) << ((EnumMax) - 1)))) +#define OU_FLAGS_ENUMFLAGS_START_VALID(Type, StartingFlag, EnumMax) ((Type)((Type)(StartingFlag) << ((EnumMax) - 1)) != 0) +#define OU_FLAGS_STOREENUM_VALUE_IN_MASK(Type, EnumValue, ValueMask) ((Type)(ValueMask) != 0 && ((Type)(EnumValue) & (Type)(~((Type)(ValueMask)))) == 0) +#define OU_FLAGS_FLAG_IS_SINGLE(Type, Flag) ((Type)(Flag) != 0 && ((Type)(Flag) & (Type)((Type)(Flag) - (Type)1)) == 0) + + +#endif // #ifndef __OU_FLAGSDEFINES_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/inttypes.h b/libs/ode-0.16.1/ou/include/ou/inttypes.h new file mode 100644 index 0000000..b69b622 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/inttypes.h @@ -0,0 +1,136 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_INTTYPES_H_INCLUDED +#define __OU_INTTYPES_H_INCLUDED + + +#include <ou/namespace.h> +#include <ou/platform.h> + + +BEGIN_NAMESPACE_OU(); + +/* + * Implementation Note: + * Standard [u]int??_t type names are avoided to prevent possibility + * of conflict with system types which might be the preprocessor defines. + * If you know that all your target platforms do not use defines for + * integer types, you can typedef them to convenient names after inclusion + * of "ou" library. + */ + + +#if _OU_COMPILER == _OU_COMPILER_MSVC + +typedef __int8 int8ou; +typedef unsigned __int8 uint8ou; + +typedef __int16 int16ou; +typedef unsigned __int16 uint16ou; + +typedef __int32 int32ou; +typedef unsigned __int32 uint32ou; + +typedef __int64 int64ou; +typedef unsigned __int64 uint64ou; + + +#else // #if _OU_TARGET_OS != _OU_TARGET_OS_WINDOWS + + +END_NAMESPACE_OU(); + + +#include <inttypes.h> + +typedef int8_t __ou_global_int8; +typedef uint8_t __ou_global_uint8; + +typedef int16_t __ou_global_int16; +typedef uint16_t __ou_global_uint16; + +typedef int32_t __ou_global_int32; +typedef uint32_t __ou_global_uint32; + +typedef int64_t __ou_global_int64; +typedef uint64_t __ou_global_uint64; + + +BEGIN_NAMESPACE_OU(); + + +typedef ::__ou_global_int8 int8ou; +typedef ::__ou_global_uint8 uint8ou; + +typedef ::__ou_global_int16 int16ou; +typedef ::__ou_global_uint16 uint16ou; + +typedef ::__ou_global_int32 int32ou; +typedef ::__ou_global_uint32 uint32ou; + +typedef ::__ou_global_int64 int64ou; +typedef ::__ou_global_uint64 uint64ou; + + +#endif // #if _OU_TARGET_OS == ... + + +#define OU_BITS_IN_BYTE 8U + +#define OU_UINT8_BITS (sizeof(_OU_NAMESPACE::uint8ou) * OU_BITS_IN_BYTE) +#define OU_INT8_BITS (sizeof(_OU_NAMESPACE::int8ou) * OU_BITS_IN_BYTE) +#define OU_UINT8_MAX ((_OU_NAMESPACE::uint8ou)(-1)) +#define OU_UINT8_MIN ((_OU_NAMESPACE::uint8ou)0) +#define OU_INT8_MAX ((_OU_NAMESPACE::int8ou)(OU_UINT8_MAX >> 1)) +#define OU_INT8_MIN ((_OU_NAMESPACE::int8ou)(OU_UINT8_MAX - OU_INT8_MAX)) + +#define OU_UINT16_BITS (sizeof(_OU_NAMESPACE::uint16ou) * OU_BITS_IN_BYTE) +#define OU_INT16_BITS (sizeof(_OU_NAMESPACE::int16ou) * OU_BITS_IN_BYTE) +#define OU_UINT16_MAX ((_OU_NAMESPACE::uint16ou)(-1)) +#define OU_UINT16_MIN ((_OU_NAMESPACE::uint16ou)0) +#define OU_INT16_MAX ((_OU_NAMESPACE::int16ou)(OU_UINT16_MAX >> 1)) +#define OU_INT16_MIN ((_OU_NAMESPACE::int16ou)(OU_UINT16_MAX - OU_INT16_MAX)) + +#define OU_UINT32_BITS (sizeof(_OU_NAMESPACE::uint32ou) * OU_BITS_IN_BYTE) +#define OU_INT32_BITS (sizeof(_OU_NAMESPACE::int32ou) * OU_BITS_IN_BYTE) +#define OU_UINT32_MAX ((_OU_NAMESPACE::uint32ou)(-1)) +#define OU_UINT32_MIN ((_OU_NAMESPACE::uint32ou)0) +#define OU_INT32_MAX ((_OU_NAMESPACE::int32ou)(OU_UINT32_MAX >> 1)) +#define OU_INT32_MIN ((_OU_NAMESPACE::int32ou)(OU_UINT32_MAX - OU_INT32_MAX)) + +#define OU_UINT64_BITS (sizeof(_OU_NAMESPACE::uint64ou) * OU_BITS_IN_BYTE) +#define OU_INT64_BITS (sizeof(_OU_NAMESPACE::int64ou) * OU_BITS_IN_BYTE) +#define OU_UINT64_MAX ((_OU_NAMESPACE::uint64ou)(-1)) +#define OU_UINT64_MIN ((_OU_NAMESPACE::uint64ou)0) +#define OU_INT64_MAX ((_OU_NAMESPACE::int64ou)(OU_UINT64_MAX >> 1)) +#define OU_INT64_MIN ((_OU_NAMESPACE::int64ou)(OU_UINT64_MAX - OU_INT64_MAX)) + + +END_NAMESPACE_OU(); + + +#endif // #ifndef __OU_INTTYPES_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/macros.h b/libs/ode-0.16.1/ou/include/ou/macros.h new file mode 100644 index 0000000..bfbf5d7 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/macros.h @@ -0,0 +1,79 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_MACROS_H_INCLUDED +#define __OU_MACROS_H_INCLUDED + + +#include <stddef.h> + + +////////////////////////////////////////////////////////////////////////// +// offsetof macro redefinition for QNX (to avoid compiler warning) + +#if _OU_TARGET_OS == _OU_TARGET_OS_QNX + + +#undef offsetof +#define offsetof(s, m) ((size_t)&(((s *)8)->m) - (size_t)8) + + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_QNX + + +////////////////////////////////////////////////////////////////////////// +// OU_ALIGNED_SIZE macro + +#define OU_ALIGNED_SIZET(Size, Alignment) (((size_t)(Size) + (size_t)((Alignment) - 1)) & ~((size_t)((Alignment) - 1))) +#define OU_ALIGNED_INT(Size, Alignment) (((unsigned int)(Size) + (unsigned int)((Alignment) - 1)) & ~((unsigned int)((Alignment) - 1))) + +#define OU_ALIGNED_SIZE(Size, Alignment) OU_ALIGNED_SIZET(Size, Alignment) + + +////////////////////////////////////////////////////////////////////////// +// OU_ARRAY_SIZE macro + +#define OU_ARRAY_SIZE(Array) (sizeof(Array) / sizeof((Array)[0])) + + +////////////////////////////////////////////////////////////////////////// +// OU_IN_*_RANGE macros + +/* + * Implementation Note: + * It seems to me "unsigned long long" is not always available. + * Therefore I find _OU_NAMESPACE::uint64ou a more safe choice. + * You have to include <ou/inttypes.h> for it to work. + * I do not include the header automaticaly to keep <macros.h> + * a low-level header. + */ + +#define OU_IN_INT_RANGE(Value, Min, Max) ((unsigned int)((unsigned int)(Value) - (unsigned int)(Min)) < (unsigned int)((unsigned int)(Max) - (unsigned int)(Min))) +#define OU_IN_I64_RANGE(Value, Min, Max) ((_OU_NAMESPACE::uint64ou)((_OU_NAMESPACE::uint64ou)(Value) - (_OU_NAMESPACE::uint64ou)(Min)) < (_OU_NAMESPACE::uint64ou)((_OU_NAMESPACE::uint64ou)(Max) - (_OU_NAMESPACE::uint64ou)(Min))) +#define OU_IN_SIZET_RANGE(Value, Min, Max) ((size_t)((size_t)(Value) - (size_t)(Min)) < (size_t)((size_t)(Max) - (size_t)(Min))) + + +#endif // #ifndef __OU_MACROS_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/malloc.h b/libs/ode-0.16.1/ou/include/ou/malloc.h new file mode 100644 index 0000000..9a758c5 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/malloc.h @@ -0,0 +1,48 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_MALLOC_H_INCLUDED +#define __OU_MALLOC_H_INCLUDED + + +#include <ou/namespace.h> +#include <ou/platform.h> + +#include <stddef.h> + + +BEGIN_NAMESPACE_OU(); + + +void *_OU_CONVENTION_API AllocateMemoryBlock(size_t nBlockSize); +void *_OU_CONVENTION_API ReallocateMemoryBlock(void *pv_ExistingBlock, size_t nNewBlockSize); +void _OU_CONVENTION_API FreeMemoryBlock(void *pv_ExistingBlock); + + +END_NAMESPACE_OU(); + + +#endif // #ifndef __OU_MALLOC_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/namespace.h b/libs/ode-0.16.1/ou/include/ou/namespace.h new file mode 100644 index 0000000..3b57ab1 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/namespace.h @@ -0,0 +1,43 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_NAMESPACE_H_INCLUDED +#define __OU_NAMESPACE_H_INCLUDED + + +#ifndef _OU_NAMESPACE + +#define _OU_NAMESPACE ou + + +#endif // #ifndef _OU_NAMESPACE + + +#define BEGIN_NAMESPACE_OU() namespace _OU_NAMESPACE { +#define END_NAMESPACE_OU() } /* namespace _OU_NAMESPACE */ + + +#endif // #ifndef __OU_NAMESPACE_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/platform.h b/libs/ode-0.16.1/ou/include/ou/platform.h new file mode 100644 index 0000000..ac12132 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/platform.h @@ -0,0 +1,398 @@ +/*************************************************************************
+ * *
+ * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. *
+ * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of EITHER: *
+ * (1) The GNU Lesser General Public License as published by the Free *
+ * Software Foundation; either version 3 of the License, or (at *
+ * your option) any later version. The text of the GNU Lesser *
+ * General Public License is included with this library in the *
+ * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL *
+ * the text of GNU General Public License is also provided for *
+ * your information in file LICENSE.TXT. *
+ * (2) The BSD-style license that is included with this library in *
+ * the file LICENSE-BSD.TXT. *
+ * (3) The zlib/libpng license that is included with this library in *
+ * the file LICENSE-ZLIB.TXT *
+ * *
+ * This library is distributed WITHOUT ANY WARRANTY, including implied *
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
+ * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT *
+ * or LICENSE-ZLIB.TXT for more details. *
+ * *
+ *************************************************************************/
+
+#ifndef __OU_PLATFORM_H_INCLUDED
+#define __OU_PLATFORM_H_INCLUDED
+
+
+//////////////////////////////////////////////////////////////////////////
+// Target definitions
+
+#define _OU_TARGET_OS_GENUNIX 1
+#define _OU_TARGET_OS_WINDOWS 2
+#define _OU_TARGET_OS_QNX 3
+#define _OU_TARGET_OS_MAC 4
+#define _OU_TARGET_OS_AIX 5
+#define _OU_TARGET_OS_SUNOS 6
+#define _OU_TARGET_OS_IOS 7
+
+#define _OU_TARGET_OS__MAX 8
+
+
+#define _OU_TARGET_BITS_32 1
+#define _OU_TARGET_BITS_64 2
+
+#define _OU_TARGET_BITS__MAX 3
+
+
+#define _OU_TARGET_ARCH_OTHER 1
+#define _OU_TARGET_ARCH_X86 2
+#define _OU_TARGET_ARCH_IA64 3
+#define _OU_TARGET_ARCH_X64 4
+#define _OU_TARGET_ARCH_POWERPC 5
+#define _OU_TARGET_ARCH_SPARC 6
+#define _OU_TARGET_ARCH_ARM 7
+#define _OU_TARGET_ARCH_AARCH64 8
+
+#define _OU_TARGET_ARCH__MAX 9
+
+
+//////////////////////////////////////////////////////////////////////////
+
+#if !defined(_OU_TARGET_OS)
+
+
+#if defined(_WINDOWS) || defined(_WIN32)
+
+#define _OU_TARGET_OS _OU_TARGET_OS_WINDOWS
+
+
+#elif defined(__QNX__)
+
+#define _OU_TARGET_OS _OU_TARGET_OS_QNX
+
+
+#elif defined(__APPLE__)
+
+#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+
+#define _OU_TARGET_OS _OU_TARGET_OS_IOS
+
+#if !defined(MAC_OS_X_VERSION)
+#define MAC_OS_X_VERSION 1050
+#endif
+
+
+#elif TARGET_OS_MAC
+
+#define _OU_TARGET_OS _OU_TARGET_OS_MAC
+
+
+#else // An unknown Apple target
+
+#error Build Apple target is not supported
+
+
+#endif // // An unknown Apple target
+
+#elif defined(__aix__)
+
+#define _OU_TARGET_OS _OU_TARGET_OS_AIX
+
+
+#elif defined(__sun__)
+
+#define _OU_TARGET_OS _OU_TARGET_OS_SUNOS
+
+
+#elif defined(__unix__)
+
+#define _OU_TARGET_OS _OU_TARGET_OS_GENUNIX
+
+
+#else // if no known define found
+
+#error Build target is not supported
+
+
+#endif // Target OS definitions
+
+
+#else // #if defined(_OU_TARGET_OS)
+
+#if _OU_TARGET_OS <= 0 || _OU_TARGET_OS >= _OU_TARGET_OS__MAX
+
+#error Please define a valid value for _OU_TARGET_OS
+
+
+#endif // #if _OU_TARGET_OS <= 0 || _OU_TARGET_OS >= _OU_TARGET_OS__MAX
+
+
+#endif // #if defined(_OU_TARGET_OS)
+
+
+#if _OU_TARGET_OS == _OU_TARGET_OS_MAC
+
+#if !defined(MAC_OS_X_VERSION)
+
+#error Please defile preprocessor symbol MAC_OS_X_VERSION in command line (e.g. "-DMAC_OS_X_VERSION=1050" for MacOS 10.5)
+
+
+#endif // #if !defined(MAC_OS_X_VERSION)
+
+
+#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_MAC
+
+
+//////////////////////////////////////////////////////////////////////////
+
+#if !defined(_OU_TARGET_BITS)
+
+
+#if defined(_LP64) || defined(_WIN64)
+
+#define _OU_TARGET_BITS _OU_TARGET_BITS_64
+
+
+#else // #if !defined(_LP64)
+
+#define _OU_TARGET_BITS _OU_TARGET_BITS_32
+
+
+#endif // #if !defined(_LP64)
+
+
+#else // #if defined(_OU_TARGET_BITS)
+
+#if _OU_TARGET_BITS <= 0 || _OU_TARGET_BITS >= _OU_TARGET_BITS__MAX
+
+#error Please define a valid value for _OU_TARGET_BITS
+
+
+#endif // #if _OU_TARGET_BITS <= 0 || _OU_TARGET_BITS >= _OU_TARGET_BITS__MAX
+
+
+#endif // #if defined(_OU_TARGET_BITS)
+
+
+//////////////////////////////////////////////////////////////////////////
+
+#if !defined(_OU_TARGET_ARCH)
+
+
+#if defined(__i386__) || defined(_M_IX86)
+
+#define _OU_TARGET_ARCH _OU_TARGET_ARCH_X86
+
+
+#elif defined(__ia64__) || defined(_M_IA64)
+
+#define _OU_TARGET_ARCH _OU_TARGET_ARCH_IA64
+
+
+#elif defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64)
+
+#define _OU_TARGET_ARCH _OU_TARGET_ARCH_X64
+
+
+#elif defined(__ppc__)
+
+#define _OU_TARGET_ARCH _OU_TARGET_ARCH_POWERPC
+
+
+#elif defined(__sparc__)
+
+#define _OU_TARGET_ARCH _OU_TARGET_ARCH_SPARC
+
+
+#elif defined(__arm__) || defined(_M_ARM) || defined(TARGET_OS_IPHONE)
+
+#define _OU_TARGET_ARCH _OU_TARGET_ARCH_ARM
+
+
+#elif defined(__aarch64__)
+
+#define _OU_TARGET_ARCH _OU_TARGET_ARCH_AARCH64
+
+
+#else // Unknown architecture
+
+#define _OU_TARGET_ARCH _OU_TARGET_ARCH_OTHER
+
+
+#endif // Architecture definitions
+
+
+#else // #if defined(_OU_TARGET_ARCH)
+
+#if _OU_TARGET_ARCH <= 0 || _OU_TARGET_ARCH >= _OU_TARGET_ARCH__MAX
+
+#error Please define a valid value for _OU_TARGET_ARCH
+
+
+#endif // #if _OU_TARGET_ARCH <= 0 || _OU_TARGET_ARCH >= _OU_TARGET_ARCH__MAX
+
+
+#endif // #if defined(_OU_TARGET_ARCH)
+
+
+//////////////////////////////////////////////////////////////////////////
+// Compiler definition
+
+#define _OU_COMPILER__OTHER 1
+#define _OU_COMPILER_GCC 2
+#define _OU_COMPILER_MSVC 3
+
+#define _OU_COMPILER__MAX 4
+
+
+#define _OU_COMPILER_VERSION__OTHER 1
+#define _OU_COMPILER_VERSION_MSVC1998 2
+#define _OU_COMPILER_VERSION_GCCLT4 3
+
+#define _OU_COMPILER_VERSION__MAX 4
+
+
+//////////////////////////////////////////////////////////////////////////
+
+#if !defined(_OU_COMPILER)
+
+#if defined(__GNUC__)
+
+#define _OU_COMPILER _OU_COMPILER_GCC
+
+#if __GNUC__ < 4
+
+#define _OU_COMPILER_VERSION _OU_COMPILER_VERSION_GCCLT4
+
+
+#endif // compiler version
+
+
+#elif defined(_MSC_VER)
+
+#define _OU_COMPILER _OU_COMPILER_MSVC
+
+#if _MSC_VER <= 1200
+
+#define _OU_COMPILER_VERSION _OU_COMPILER_VERSION_MSVC1998
+
+
+#endif // compiler version
+
+
+#else // if no known define found
+
+#define _OU_COMPILER _OU_COMPILER__OTHER
+
+
+#endif // Compiler specific definitions
+
+
+#else // #if defined(_OU_COMPILER)
+
+#if _OU_COMPILER <= 0 || _OU_COMPILER >= _OU_COMPILER__MAX
+
+#error Please define a valid value for _OU_COMPILER
+
+
+#endif // #if _OU_COMPILER <= 0 || _OU_COMPILER >= _OU_COMPILER__MAX
+
+
+#endif // #if defined(_OU_COMPILER)
+
+
+#if !defined(_OU_COMPILER_VERSION)
+
+#define _OU_COMPILER_VERSION _OU_COMPILER_VERSION__OTHER
+
+
+#endif // #if !defined(_OU_COMPILER_VERSION)
+
+
+#if _OU_COMPILER_VERSION <= 0 || _OU_COMPILER_VERSION >= _OU_COMPILER_VERSION__MAX
+
+#error Please define a valid value for _OU_COMPILER_VERSION
+
+
+#endif // #if _OU_COMPILER_VERSION <= 0 || _OU_COMPILER_VERSION >= _OU_COMPILER_VERSION__MAX
+
+
+//////////////////////////////////////////////////////////////////////////
+// Calling convention definition
+
+#if !defined(__OU_CONVENTIONS_DEFINED)
+
+#define __OU_CONVENTIONS_DEFINED
+
+
+#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS
+
+#define _OU_CONVENTION_METHOD
+#define _OU_CONVENTION_API __stdcall
+#define _OU_CONVENTION_CALLBACK __stdcall
+
+
+#else // #if _OU_TARGET_OS != _OU_TARGET_OS_WINDOWS
+
+#define _OU_CONVENTION_METHOD
+#define _OU_CONVENTION_API
+#define _OU_CONVENTION_CALLBACK
+
+
+#endif // #if _OU_TARGET_OS == ...
+
+
+#endif // #if !defined(__OU_CONVENTIONS_DEFINED)
+
+
+//////////////////////////////////////////////////////////////////////////
+// _OU_ALWAYSINLINE/_OU_INLINE definition
+
+#if !defined(__OU_INLINES_DEFINED)
+
+#define __OU_INLINES_DEFINED
+
+
+#if _OU_COMPILER == _OU_COMPILER_GCC
+
+#define _OU_ALWAYSINLINE__DEFINITION inline __attribute__((always_inline))
+
+
+#elif _OU_COMPILER == _OU_COMPILER_MSVC
+
+#define _OU_ALWAYSINLINE__DEFINITION inline __forceinline
+
+
+#else // if _OU_COMPILER == _OU_COMPILER_OTHER
+
+#define _OU_ALWAYSINLINE__DEFINITION inline
+
+
+#endif // #if _OU_COMPILER == ...
+
+
+#if defined(_DEBUG)
+
+#define _OU_ALWAYSINLINE inline
+
+#define _OU_INLINE inline
+
+
+#else // #if !defined(_DEBUG)
+
+#define _OU_ALWAYSINLINE _OU_ALWAYSINLINE__DEFINITION
+
+#define _OU_INLINE inline
+
+
+#endif // #if !defined(_DEBUG)
+
+
+#endif // #if !defined(__OU_INLINES_DEFINED)
+
+
+#endif // #ifndef __OU_PLATFORM_H_INCLUDED
diff --git a/libs/ode-0.16.1/ou/include/ou/simpleflags.h b/libs/ode-0.16.1/ou/include/ou/simpleflags.h new file mode 100644 index 0000000..db26617 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/simpleflags.h @@ -0,0 +1,334 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_SIMPLEFLAGS_H_INCLUDED +#define __OU_SIMPLEFLAGS_H_INCLUDED + + +#include <ou/flagsdefines.h> +#include <ou/assert.h> +#include <ou/inttypes.h> +#include <ou/namespace.h> + +#include <stddef.h> + + +BEGIN_NAMESPACE_OU(); + + +template<typename ContainerType> +class CSimpleFlagsTemplate +{ +public: + _OU_INLINE _OU_CONVENTION_METHOD CSimpleFlagsTemplate(): + m_ctFlagsValue(0) + { + } + + _OU_INLINE _OU_CONVENTION_METHOD CSimpleFlagsTemplate(ContainerType ctFlagsValue): + m_ctFlagsValue(ctFlagsValue) + { + } + + typedef ContainerType value_type; + +public: + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */AssignFlagsAllValues(ContainerType ctFlagsValue) + { + m_ctFlagsValue = ctFlagsValue; + } + + _OU_ALWAYSINLINE ContainerType _OU_CONVENTION_METHOD + /*ContainerType */QueryFlagsAllValues() const + { + return m_ctFlagsValue; + } + + + // Can operate both on single flag and flag set + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */SetFlagsMaskValue(ContainerType ctFlagsMask, bool bFlagValue) + { + m_ctFlagsValue = bFlagValue + ? (m_ctFlagsValue | ctFlagsMask) + : (m_ctFlagsValue & ~ctFlagsMask); + } + + // Can operate both on single flag and flag set + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */SignalFlagsMaskValue(ContainerType ctFlagsMask) + { + m_ctFlagsValue |= ctFlagsMask; + } + + // Can operate both on single flag and flag set + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */DropFlagsMaskValue(ContainerType ctFlagsMask) + { + m_ctFlagsValue &= ~ctFlagsMask; + } + + + // Can operate on single flag only + // Returns previous flag value + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */ToggleSingleFlagValue(ContainerType ctSingleFlag) + { + OU_ASSERT(OU_FLAGS_FLAG_IS_SINGLE(ContainerType, ctSingleFlag)); + + return ((m_ctFlagsValue ^= ctSingleFlag) & ctSingleFlag) == (ContainerType)0; + } + + // Can operate on single flag only + // Returns if modification occurred + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */ModifySingleFlagValue(ContainerType ctSingleFlag, bool bFlagValue) + { + OU_ASSERT(OU_FLAGS_FLAG_IS_SINGLE(ContainerType, ctSingleFlag)); + + return ((m_ctFlagsValue & ctSingleFlag) != (ContainerType)0) != bFlagValue + ? ((m_ctFlagsValue ^= ctSingleFlag), true) + : (false); + } + + + // Modifies subset of flags + // Returns previous flags + _OU_ALWAYSINLINE ContainerType _OU_CONVENTION_METHOD + /*ContainerType */AssignFlagsByMask(ContainerType ctFlagsMask, ContainerType ctFlagsValue) + { + ContainerType ctFlagsOldValue = m_ctFlagsValue; + + m_ctFlagsValue = (ctFlagsOldValue & ~ctFlagsMask) | (ctFlagsValue & ctFlagsMask); + + return ctFlagsOldValue; + } + + // Modifies subset of flags + // Returns if modification occurred + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */AlterFlagsByMask(ContainerType ctFlagsMask, ContainerType ctFlagsValue) + { + ContainerType ctFlagsOldValue = m_ctFlagsValue; + + m_ctFlagsValue = (ctFlagsOldValue & ~ctFlagsMask) | (ctFlagsValue & ctFlagsMask); + + return ((ctFlagsOldValue ^ ctFlagsValue) & ctFlagsMask) != (ContainerType)0; + } + + + // Returns value of flag or tests for any bit in a mask + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */GetFlagsMaskValue(ContainerType ctFlagsMask) const + { + return (m_ctFlagsValue & ctFlagsMask) != (ContainerType)0; + } + + // Returns subset of flags + _OU_ALWAYSINLINE ContainerType _OU_CONVENTION_METHOD + /*ContainerType */QueryFlagsByMask(ContainerType ctFlagsMask) const + { + return (m_ctFlagsValue & ctFlagsMask); + } + +public: + // Signal only flag out of mask + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */OnlySignalSingleFlagOutOfMask(ContainerType ctFlagsMask, ContainerType ctSingleFlag) + { + OU_ASSERT(OU_FLAGS_FLAG_IS_SINGLE(ContainerType, ctSingleFlag)); + + return !(m_ctFlagsValue & ctFlagsMask) + ? (m_ctFlagsValue |= ctSingleFlag, true) + : (false); + } + +public: + // Set value of flag indexed by enum + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */EnumSetEnumeratedFlagValue(ContainerType ctStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum, bool bFlagValue) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + + SetFlagsMaskValue(ctStartingFlag << uiEnumeratedValue, bFlagValue); + } + + // Signal value of flag indexed by enum + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */EnumSignalEnumeratedFlagValue(ContainerType ctStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + + SignalFlagsMaskValue(ctStartingFlag << uiEnumeratedValue); + } + + // Drop value of flag indexed by enum + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */EnumDropEnumeratedFlagValue(ContainerType ctStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + + DropFlagsMaskValue(ctStartingFlag << uiEnumeratedValue); + } + + + // Can operate on single flag only + // Returns previous flag value + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */EnumToggleEnumeratedFlagValue(ContainerType ctStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + + return ToggleSingleFlagValue(ctStartingFlag << uiEnumeratedValue); + } + + // Can operate on single flag only + // Returns if modification occurred + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */EnumModifyEnumeratedFlagValue(ContainerType ctStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum, bool bFlagValue) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + + return ModifySingleFlagValue(ctStartingFlag << uiEnumeratedValue, bFlagValue); + } + + + // Returns if this was the first flag signaled + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */EnumSignalFirstEnumeratedFlagValue(ContainerType ctStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + + return (AssignFlagsByMask(ctStartingFlag << uiEnumeratedValue, ctStartingFlag << uiEnumeratedValue) & OU_FLAGS_ENUMFLAGS_MASK(ContainerType, ctStartingFlag, uiEnumeratedMaximum)) == (ContainerType)0; + } + + // Returns if this was the last flag signaled + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */EnumSignalLastEnumeratedFlagValue(ContainerType ctStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + + return (AssignFlagsByMask(ctStartingFlag << uiEnumeratedValue, ctStartingFlag << uiEnumeratedValue) & OU_FLAGS_ENUMFLAGS_MASK(ContainerType, ctStartingFlag, uiEnumeratedMaximum)) == (OU_FLAGS_ENUMFLAGS_MASK(ContainerType, ctStartingFlag, uiEnumeratedMaximum) & ~(ctStartingFlag << uiEnumeratedValue)); + } + + + // Retrieve value of flag indexed by enum + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */EnumGetEnumeratedFlagValue(ContainerType ctStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum) const + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + + return GetFlagsMaskValue(ctStartingFlag << uiEnumeratedValue); + } + + // Find enum value for first flag signaled + _OU_INLINE unsigned int _OU_CONVENTION_METHOD + /*unsigned int */EnumFindFirstEnumeratedFlag(ContainerType ctStartingFlag, unsigned int uiEnumeratedMaximum) const + { + OU_ASSERT(OU_FLAGS_ENUMFLAGS_START_VALID(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + + unsigned int uiResult = 0; + + ContainerType ctFlagsMask = ctStartingFlag; + for (; uiResult < uiEnumeratedMaximum; ++uiResult, ctFlagsMask <<= 1) + { + if (GetFlagsMaskValue(ctFlagsMask)) + { + break; + } + } + + return uiResult; + } + +public: + // Signal all flags indexed by enum + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */EnumAllSignalEnumeratedFlags(ContainerType ctStartingFlag, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(OU_FLAGS_ENUMFLAGS_START_VALID(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + + SignalFlagsMaskValue(OU_FLAGS_ENUMFLAGS_MASK(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + } + + // Drop all flags indexed by enum + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */EnumAllDropEnumeratedFlags(ContainerType ctStartingFlag, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(OU_FLAGS_ENUMFLAGS_START_VALID(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + + DropFlagsMaskValue(OU_FLAGS_ENUMFLAGS_MASK(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + } + + + // Query all flags indexed by enum + _OU_ALWAYSINLINE ContainerType _OU_CONVENTION_METHOD + /*ContainerType */EnumAllQueryEnumeratedFlags(ContainerType ctStartingFlag, unsigned int uiEnumeratedMaximum) const + { + OU_ASSERT(OU_FLAGS_ENUMFLAGS_START_VALID(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + + return QueryFlagsByMask(OU_FLAGS_ENUMFLAGS_MASK(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + } + + // Get if any flag indexed by enum is set + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */EnumAnyGetEnumeratedFlagValue(ContainerType ctStartingFlag, unsigned int uiEnumeratedMaximum) const + { + OU_ASSERT(OU_FLAGS_ENUMFLAGS_START_VALID(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + + return GetFlagsMaskValue(OU_FLAGS_ENUMFLAGS_MASK(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + } + +public: + // Store enumerated value in flags + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */StoreFlagsEnumeratedValue(ContainerType ctEnumeratedValueMask, unsigned int uiEnumeratedValueShift, unsigned int uiEnumeratedValue) + { + OU_ASSERT(OU_FLAGS_STOREENUM_VALUE_IN_MASK(ContainerType, uiEnumeratedValue, ctEnumeratedValueMask)); + + AssignFlagsByMask(ctEnumeratedValueMask << uiEnumeratedValueShift, (ContainerType)uiEnumeratedValue << uiEnumeratedValueShift); + } + + // Retrieve enumerated value from flags + _OU_ALWAYSINLINE unsigned int _OU_CONVENTION_METHOD + /*unsigned int */RetrieveFlagsEnumeratedValue(ContainerType ctEnumeratedValueMask, unsigned int uiEnumeratedValueShift) const + { + return (unsigned int)((QueryFlagsAllValues() >> uiEnumeratedValueShift) & ctEnumeratedValueMask); + } + +private: + ContainerType m_ctFlagsValue; +}; + + +typedef CSimpleFlagsTemplate<uint32ou> CSimpleFlags; + + +END_NAMESPACE_OU(); + + +#endif // #ifndef __OU_SIMPLEFLAGS_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/templates.h b/libs/ode-0.16.1/ou/include/ou/templates.h new file mode 100644 index 0000000..13fceb3 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/templates.h @@ -0,0 +1,90 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_TEMPLATES_H_INCLUDED +#define __OU_TEMPLATES_H_INCLUDED + + +#include <ou/macros.h> +#include <ou/namespace.h> + + +BEGIN_NAMESPACE_OU(); + + +////////////////////////////////////////////////////////////////////////// +// Enumerated type increment/decrement operator templates + +/* + * Implementation Note: + * __attribute__((always_inline)) seems to be unimplemented for templates in GCC + */ + +template<typename EnumType> +_OU_INLINE EnumType &_OU_CONVENTION_API operator ++(EnumType &Value) +{ + Value = (EnumType)(Value + 1); + return Value; +} + +template<typename EnumType> +_OU_INLINE EnumType _OU_CONVENTION_API operator ++(EnumType &Value, int) +{ + EnumType ValueCopy = Value; + Value = (EnumType)(Value + 1); + return ValueCopy; +} + +template<typename EnumType> +_OU_INLINE EnumType &_OU_CONVENTION_API operator --(EnumType &Value) +{ + Value = (EnumType)(Value - 1); + return Value; +} + +template<typename EnumType> +_OU_INLINE EnumType _OU_CONVENTION_API operator --(EnumType &Value, int) +{ + EnumType ValueCopy = Value; + Value = (EnumType)(Value - 1); + return ValueCopy; +} + + +////////////////////////////////////////////////////////////////////////// +// Empty "signed zero" check template + +template<typename ValueType> +_OU_INLINE bool _OU_CONVENTION_API IsEmptySz(const ValueType *szLine) +{ + return !szLine || !(*szLine); +} + + +END_NAMESPACE_OU(); + + +#endif // #ifndef __OU_TEMPLATES_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/threadlocalstorage.h b/libs/ode-0.16.1/ou/include/ou/threadlocalstorage.h new file mode 100644 index 0000000..2c2fcb5 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/threadlocalstorage.h @@ -0,0 +1,297 @@ +/*************************************************************************
+ * *
+ * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. *
+ * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of EITHER: *
+ * (1) The GNU Lesser General Public License as published by the Free *
+ * Software Foundation; either version 3 of the License, or (at *
+ * your option) any later version. The text of the GNU Lesser *
+ * General Public License is included with this library in the *
+ * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL *
+ * the text of GNU General Public License is also provided for *
+ * your information in file LICENSE.TXT. *
+ * (2) The BSD-style license that is included with this library in *
+ * the file LICENSE-BSD.TXT. *
+ * (3) The zlib/libpng license that is included with this library in *
+ * the file LICENSE-ZLIB.TXT *
+ * *
+ * This library is distributed WITHOUT ANY WARRANTY, including implied *
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
+ * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT *
+ * or LICENSE-ZLIB.TXT for more details. *
+ * *
+ *************************************************************************/
+
+#ifndef _OU_THREADLOCALSTORAGE_H_INCLUDED
+#define _OU_THREADLOCALSTORAGE_H_INCLUDED
+
+
+#include <ou/features.h>
+
+
+#if _OU_FEATURE_SET >= _OU_FEATURE_SET_TLS
+
+#include <ou/typewrapper.h>
+#include <ou/macros.h>
+#include <ou/assert.h>
+#include <ou/platform.h>
+#include <ou/namespace.h>
+
+#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS
+
+#include <windows.h>
+
+
+#else // #if _OU_TARGET_OS != _OU_TARGET_OS_WINDOWS
+
+#include <pthread.h>
+
+
+#endif // #if _OU_TARGET_OS == ...
+
+
+BEGIN_NAMESPACE_OU();
+
+
+//////////////////////////////////////////////////////////////////////////
+// API specific types
+
+typedef CTypeSimpleWrapper<void *, 1> HTLSKEYVALUE;
+typedef CTypeSimpleWrapper<HTLSKEYVALUE *, 0> HTLSKEYSELECTOR;
+typedef HTLSKEYSELECTOR HTLSKEY;
+
+typedef void *tlsvaluetype;
+typedef unsigned int tlsindextype;
+
+typedef void (_OU_CONVENTION_CALLBACK *CTLSValueDestructor)(tlsvaluetype vValueData);
+
+
+#define OU_TLS_VALUE_AS_POINTER(value) (value)
+
+
+//////////////////////////////////////////////////////////////////////////
+// Internal types required for functions to be made inline
+
+struct CTLSStorageArray;
+
+struct CTLSStorageBlock
+{
+/*
+ * Implementation Note:
+ * 1) Value destructors are stored in separate array since those are
+ * rarely accessed values and not intermixing them with data
+ * potentially simplifies data access (well, just theoretically, of course :)).
+ * 2) Destructors are stored with negative offset to allow accessing them
+ * without the knowledge of value count.
+ * 3) Well, intermixing or not intermixing has really minor impact on
+ * implementation characteristics, so why not to choose it after the current mood? :)
+ */
+private:
+ enum
+ {
+ TSB_RESERVEDPOINTER_HOSTARRAY,
+
+ TSB_RESERVEDPOINTER__MAX,
+ };
+
+public:
+ enum
+ {
+ TSB_LARGEST_ALIGNMENT = sizeof(void *) > sizeof(tlsvaluetype) ? sizeof(void *) : sizeof(tlsvaluetype),
+ };
+
+public:
+ static inline size_t GetRequiredSize(tlsindextype iValueCount)
+ {
+ return OU_ALIGNED_SIZE(iValueCount * (sizeof(tlsvaluetype) + sizeof(CTLSValueDestructor)) + TSB_RESERVEDPOINTER__MAX * sizeof(void *), TSB_LARGEST_ALIGNMENT);
+ }
+
+ static inline size_t GetZeroOffset(tlsindextype iValueCount)
+ {
+ // Since pointers and values are stored in different directions,
+ // alignment correction must fall entirely to either side and
+ // required size will not be exceeded.
+ return OU_ALIGNED_SIZE(iValueCount * sizeof(CTLSValueDestructor) + TSB_RESERVEDPOINTER__MAX * sizeof(void *), TSB_LARGEST_ALIGNMENT);
+ }
+
+public:
+ inline void SetValueData(tlsindextype iValueIndex, tlsvaluetype vValueData)
+ {
+ un.m_av_ValueDatas[iValueIndex] = vValueData;
+ }
+
+ inline tlsvaluetype GetValueData(tlsindextype iValueIndex) const
+ {
+ return un.m_av_ValueDatas[iValueIndex];
+ }
+
+ inline void SetHostArray(CTLSStorageArray *psaInstance)
+ {
+ un.m_asaHostArrays[(ptrdiff_t)0 - (1 + TSB_RESERVEDPOINTER_HOSTARRAY)] = psaInstance;
+ }
+
+ inline CTLSStorageArray *GetHostArray() const
+ {
+ return un.m_asaHostArrays[(ptrdiff_t)0 - (1 + TSB_RESERVEDPOINTER_HOSTARRAY)];
+ }
+
+ inline void SetValueDestructor(tlsindextype iValueIndex, CTLSValueDestructor fvValue)
+ {
+ un.m_afnValueDestructors[-((ptrdiff_t)iValueIndex) - (1 + TSB_RESERVEDPOINTER__MAX)] = fvValue;
+ }
+
+ inline CTLSValueDestructor GetValueDestructor(tlsindextype iValueIndex) const
+ {
+ return un.m_afnValueDestructors[-((ptrdiff_t)iValueIndex) - (1 + TSB_RESERVEDPOINTER__MAX)];
+ }
+
+private:
+ union
+ {
+ tlsvaluetype m_av_ValueDatas[1];
+ CTLSValueDestructor m_afnValueDestructors[1];
+ CTLSStorageArray *m_asaHostArrays[1];
+ } un;
+};
+
+
+//////////////////////////////////////////////////////////////////////////
+// API declaration
+
+class CThreadLocalStorage
+{
+public: // Safe methods
+ /*
+ * Implementation Note:
+ * Since the function is potentially slow and should not be frequently
+ * called anyway, there is no sense in creating additional overload without
+ * destructor parameter which would preserve current destructor procedure.
+ */
+ static _OU_ALWAYSINLINE bool _OU_CONVENTION_API
+ /*bool */SetStorageValue(const HTLSKEY &hskStorageKey, tlsindextype iValueIndex, tlsvaluetype vValueData, CTLSValueDestructor fnValueDestructor=NULL)
+ {
+ bool bResult;
+
+ CTLSStorageBlock *psbStorageBlock = GetKeyStorageBlock(hskStorageKey);
+
+ if (psbStorageBlock)
+ {
+ psbStorageBlock->SetValueData(iValueIndex, vValueData);
+ psbStorageBlock->SetValueDestructor(iValueIndex, fnValueDestructor);
+
+ bResult = true;
+ }
+ else
+ {
+ bResult = AllocateAndSetStorageValue(hskStorageKey, iValueIndex, vValueData, fnValueDestructor);
+ }
+
+ return bResult;
+ }
+
+ static _OU_ALWAYSINLINE tlsvaluetype _OU_CONVENTION_API
+ /*tlsvaluetype */GetStorageValue(const HTLSKEY &hskStorageKey, tlsindextype iValueIndex)
+ {
+ tlsvaluetype vValueData = 0;
+
+ CTLSStorageBlock *psbStorageBlock = GetKeyStorageBlock(hskStorageKey);
+
+ if (psbStorageBlock)
+ {
+ vValueData = psbStorageBlock->GetValueData(iValueIndex);
+ }
+
+ return vValueData;
+ }
+
+public: // Unsafe methods
+ static _OU_ALWAYSINLINE void _OU_CONVENTION_API
+ /*void */UnsafeSetStorageValue(const HTLSKEY &hskStorageKey, tlsindextype iValueIndex, tlsvaluetype vValueData)
+ {
+ CTLSStorageBlock *psbStorageBlock = GetKeyStorageBlock(hskStorageKey);
+ psbStorageBlock->SetValueData(iValueIndex, vValueData);
+ }
+
+ static _OU_ALWAYSINLINE tlsvaluetype _OU_CONVENTION_API
+ /*tlsvaluetype */UnsafeGetStorageValue(const HTLSKEY &hskStorageKey, tlsindextype iValueIndex)
+ {
+ CTLSStorageBlock *psbStorageBlock = GetKeyStorageBlock(hskStorageKey);
+ return psbStorageBlock->GetValueData(iValueIndex);
+ }
+
+private:
+ static bool _OU_CONVENTION_API AllocateAndSetStorageValue(const HTLSKEYSELECTOR &hksKeySelector,
+ tlsindextype iValueIndex, tlsvaluetype vValueData, CTLSValueDestructor fnValueDestructor);
+
+private:
+ friend class CTLSInitialization;
+
+ static inline void _OU_CONVENTION_API SetKeyStorageBlock(const HTLSKEYSELECTOR &hskStorageKey, CTLSStorageBlock *psbInstance)
+ {
+#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS
+
+ ::TlsSetValue((DWORD)(size_t)(HTLSKEYVALUE::value_type)(*(HTLSKEYSELECTOR::value_type)hskStorageKey), (LPVOID)psbInstance);
+
+
+#else // #if _OU_TARGET_OS != _OU_TARGET_OS_WINDOWS
+
+ pthread_setspecific((pthread_key_t)(size_t)(HTLSKEYVALUE::value_type)(*(HTLSKEYSELECTOR::value_type)hskStorageKey), (void *)psbInstance);
+
+
+#endif // #if _OU_TARGET_OS == ...
+ }
+
+ static inline CTLSStorageBlock *_OU_CONVENTION_API GetKeyStorageBlock(const HTLSKEYSELECTOR &hskStorageKey)
+ {
+#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS
+
+ CTLSStorageBlock *psbStorageBlock = (CTLSStorageBlock *)::TlsGetValue((DWORD)(size_t)(HTLSKEYVALUE::value_type)(*(HTLSKEYSELECTOR::value_type)hskStorageKey));
+
+
+#else // #if _OU_TARGET_OS != _OU_TARGET_OS_WINDOWS
+
+ CTLSStorageBlock *psbStorageBlock = (CTLSStorageBlock *)pthread_getspecific((pthread_key_t)(size_t)(HTLSKEYVALUE::value_type)(*(HTLSKEYSELECTOR::value_type)hskStorageKey));
+
+
+#endif // #if _OU_TARGET_OS == ...
+
+ return psbStorageBlock;
+ }
+};
+
+
+//////////////////////////////////////////////////////////////////////////
+// Initialization/finalization
+
+class CTLSInitialization
+{
+public:
+ enum EINITIALIZATIONFLAGS
+ {
+ SIF_MANUAL_CLEANUP_ON_THREAD_EXIT = 0x00000001,
+ };
+
+public:
+ // Initialization must be performed from main thread
+ static bool _OU_CONVENTION_API InitializeTLSAPI(HTLSKEY &hskOutStorageKey, tlsindextype iValueCount,
+ unsigned int uiInitializationFlags=0);
+ static void _OU_CONVENTION_API FinalizeTLSAPI();
+
+ static void _OU_CONVENTION_API CleanupOnThreadExit();
+
+private:
+ static bool _OU_CONVENTION_API InitializeTLSAPIValidated(unsigned int uiInstanceKind,
+ tlsindextype iValueCount, unsigned int uiInitializationFlags);
+ static void _OU_CONVENTION_API FinalizeTLSAPIValidated(unsigned int uiInstanceKind);
+};
+
+
+END_NAMESPACE_OU();
+
+
+#endif // #if _OU_FEATURE_SET >= _OU_FEATURE_SET_TLS
+
+
+#endif // #ifndef _OU_THREADLOCALSTORAGE_H_INCLUDED
diff --git a/libs/ode-0.16.1/ou/include/ou/typewrapper.h b/libs/ode-0.16.1/ou/include/ou/typewrapper.h new file mode 100644 index 0000000..59f5cef --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/typewrapper.h @@ -0,0 +1,111 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_TYPEWRAPPER_H_INCLUDED +#define __OU_TYPEWRAPPER_H_INCLUDED + + +#include <ou/platform.h> +#include <ou/namespace.h> + + +BEGIN_NAMESPACE_OU(); + + +template<typename ContainedType, const int Instance=0> +struct CTypeSimpleWrapper +{ +public: + _OU_INLINE CTypeSimpleWrapper(): m_ctValue() {} + _OU_INLINE CTypeSimpleWrapper(const ContainedType &ctValue): m_ctValue(ctValue) {} + // _OU_INLINE CTypeSimpleWrapper(const CTypeSimpleWrapper &twOtherWrapper): m_ctValue(twOtherWrapper.m_ctValue) {} -- do not uncomment!!! in MSVC 6.0 optimization fails with it. :-/ + + typedef ContainedType value_type; + + _OU_INLINE bool operator ==(const CTypeSimpleWrapper &twOtherWrapper) const { return m_ctValue == twOtherWrapper.m_ctValue; } + _OU_INLINE bool operator !=(const CTypeSimpleWrapper &twOtherWrapper) const { return !(operator ==(twOtherWrapper)); } + + _OU_INLINE bool operator <(const CTypeSimpleWrapper &twOtherWrapper) const { return m_ctValue < twOtherWrapper.m_ctValue; } + _OU_INLINE bool operator >(const CTypeSimpleWrapper &twOtherWrapper) const { return twOtherWrapper.operator <(*this); } + _OU_INLINE bool operator <=(const CTypeSimpleWrapper &twOtherWrapper) const { return !(twOtherWrapper.operator <(*this)); } + _OU_INLINE bool operator >=(const CTypeSimpleWrapper &twOtherWrapper) const { return !(operator <(twOtherWrapper)); } + + // _OU_INLINE operator bool() const { return !!m_ctValue; } -- casting to bool is too dangerous - it tends to be used instead of casting to int + _OU_INLINE bool operator !() const { return !m_ctValue; } + + _OU_INLINE CTypeSimpleWrapper &operator =(const ContainedType &ctValue) { m_ctValue = ctValue; return *this; } + _OU_INLINE CTypeSimpleWrapper &operator =(const CTypeSimpleWrapper &twOtherWrapper) { m_ctValue = twOtherWrapper.m_ctValue; return *this; } + + _OU_INLINE operator const ContainedType &() const { return m_ctValue; } + _OU_INLINE operator ContainedType &() { return m_ctValue; } + +private: + ContainedType m_ctValue; +}; + + +template<typename ContainedType, const int Instance> +_OU_INLINE bool _OU_CONVENTION_API operator ==(const CTypeSimpleWrapper<ContainedType, Instance> &twLeftWrapper, const ContainedType &ctRightValue) { return (const ContainedType &)twLeftWrapper == ctRightValue; } + +template<typename ContainedType, const int Instance> +_OU_INLINE bool _OU_CONVENTION_API operator ==(const ContainedType &ctLeftValue, const CTypeSimpleWrapper<ContainedType, Instance> &twRightWrapper) { return ctLeftValue == (const ContainedType &)twRightWrapper; } + +template<typename ContainedType, const int Instance> +_OU_INLINE bool _OU_CONVENTION_API operator !=(const CTypeSimpleWrapper<ContainedType, Instance> &twLeftWrapper, const ContainedType &ctRightValue) { return !(twLeftWrapper == ctRightValue); } + +template<typename ContainedType, const int Instance> +_OU_INLINE bool _OU_CONVENTION_API operator !=(const ContainedType &ctLeftValue, const CTypeSimpleWrapper<ContainedType, Instance> &twRightWrapper) { return !(ctLeftValue == twRightWrapper); } + + +template<typename ContainedType, const int Instance> +_OU_INLINE bool _OU_CONVENTION_API operator <(const CTypeSimpleWrapper<ContainedType, Instance> &twLeftWrapper, const ContainedType &ctRightValue) { return (const ContainedType &)twLeftWrapper < ctRightValue; } + +template<typename ContainedType, const int Instance> +_OU_INLINE bool _OU_CONVENTION_API operator <(const ContainedType &ctLeftValue, const CTypeSimpleWrapper<ContainedType, Instance> &twRightWrapper) { return ctLeftValue < (const ContainedType &)twRightWrapper; } + +template<typename ContainedType, const int Instance> +_OU_INLINE bool _OU_CONVENTION_API operator >(const CTypeSimpleWrapper<ContainedType, Instance> &twLeftWrapper, const ContainedType &ctRightValue) { return ctRightValue < twLeftWrapper; } + +template<typename ContainedType, const int Instance> +_OU_INLINE bool _OU_CONVENTION_API operator >(const ContainedType &ctLeftValue, const CTypeSimpleWrapper<ContainedType, Instance> &twRightWrapper) { return twRightWrapper < ctLeftValue; } + +template<typename ContainedType, const int Instance> +_OU_INLINE bool _OU_CONVENTION_API operator <=(const CTypeSimpleWrapper<ContainedType, Instance> &twLeftWrapper, const ContainedType &ctRightValue) { return !(ctRightValue < twLeftWrapper); } + +template<typename ContainedType, const int Instance> +_OU_INLINE bool _OU_CONVENTION_API operator <=(const ContainedType &ctLeftValue, const CTypeSimpleWrapper<ContainedType, Instance> &twRightWrapper) { return !(twRightWrapper < ctLeftValue); } + +template<typename ContainedType, const int Instance> +_OU_INLINE bool _OU_CONVENTION_API operator >=(const CTypeSimpleWrapper<ContainedType, Instance> &twLeftWrapper, const ContainedType &ctRightValue) { return !(twLeftWrapper < ctRightValue); } + +template<typename ContainedType, const int Instance> +_OU_INLINE bool _OU_CONVENTION_API operator >=(const ContainedType &ctLeftValue, const CTypeSimpleWrapper<ContainedType, Instance> &twRightWrapper) { return !(ctLeftValue < twRightWrapper); } + + +END_NAMESPACE_OU(); + + +#endif // #ifndef __OU_TYPEWRAPPER_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/src/ou/Makefile.am b/libs/ode-0.16.1/ou/src/ou/Makefile.am new file mode 100644 index 0000000..12a40cd --- /dev/null +++ b/libs/ode-0.16.1/ou/src/ou/Makefile.am @@ -0,0 +1,13 @@ +AM_CPPFLAGS = -I$(top_srcdir)/include + +AM_CXXFLAGS = -fno-exceptions -fno-rtti +AM_LDFLAGS = -fno-exceptions -fno-rtti + +noinst_LTLIBRARIES = libou.la + +libou_la_SOURCES = atomic.cpp \ + customization.cpp \ + malloc.cpp \ + threadlocalstorage.cpp + + diff --git a/libs/ode-0.16.1/ou/src/ou/Makefile.in b/libs/ode-0.16.1/ou/src/ou/Makefile.in new file mode 100644 index 0000000..b2d755b --- /dev/null +++ b/libs/ode-0.16.1/ou/src/ou/Makefile.in @@ -0,0 +1,598 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/ou +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libou_la_LIBADD = +am_libou_la_OBJECTS = atomic.lo customization.lo malloc.lo \ + threadlocalstorage.lo +libou_la_OBJECTS = $(am_libou_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/../depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +SOURCES = $(libou_la_SOURCES) +DIST_SOURCES = $(libou_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/../depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +OU_FEATURE_SET = @OU_FEATURE_SET@ +OU_NAMESPACE = @OU_NAMESPACE@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = -I$(top_srcdir)/include +AM_CXXFLAGS = -fno-exceptions -fno-rtti +AM_LDFLAGS = -fno-exceptions -fno-rtti +noinst_LTLIBRARIES = libou.la +libou_la_SOURCES = atomic.cpp \ + customization.cpp \ + malloc.cpp \ + threadlocalstorage.cpp + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/ou/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/ou/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libou.la: $(libou_la_OBJECTS) $(libou_la_DEPENDENCIES) $(EXTRA_libou_la_DEPENDENCIES) + $(AM_V_CXXLD)$(CXXLINK) $(libou_la_OBJECTS) $(libou_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atomic.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/customization.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/malloc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/threadlocalstorage.Plo@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/ou/src/ou/atomic.cpp b/libs/ode-0.16.1/ou/src/ou/atomic.cpp new file mode 100644 index 0000000..609cf41 --- /dev/null +++ b/libs/ode-0.16.1/ou/src/ou/atomic.cpp @@ -0,0 +1,445 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#include <ou/features.h> + + +#if _OU_FEATURE_SET >= _OU_FEATURE_SET_ATOMICS + +#include <ou/atomic.h> +#include <ou/assert.h> +#include <ou/namespace.h> + + +BEGIN_NAMESPACE_OU(); + + +#if !defined(__OU_ATOMIC_PTR_FUNCTIONS_DEFINED) + +////////////////////////////////////////////////////////////////////////// +// Implementation via mutex locks + +#if !defined(__OU_ATOMIC_INITIALIZATION_FUNCTIONS_REQUIRED) + +#error Internal error (Atomic-via-mutex implementations can not appear without initialization) + + +#endif // #if !defined(__OU_ATOMIC_INITIALIZATION_FUNCTIONS_DEFINED) + + +END_NAMESPACE_OU(); + + +#include <pthread.h> +#include <errno.h> + +#if !defined(EOK) + +#define EOK 0 + + +#endif + + +BEGIN_NAMESPACE_OU(); + + +static unsigned int g_uiAtomicAPIInitializationCount = 0; + + +#define _OU_ATOMIC_MUTEX_COUNT 8 +#define _OU_ATOMIC_MUTES_INDEX_SHIFT 3 // Shift by 3 bits as 8 bytes is a common memory alignment +#define _OU_ATOMIC_MUTEX_INDEX_MASK (_OU_ATOMIC_MUTEX_COUNT - 1) + + +// Mutexes array is used to distribute load over multiple mutexes +static pthread_mutex_t g_apmAtomicMutexes[_OU_ATOMIC_MUTEX_COUNT]; + + +static inline unsigned int DeriveAtomicMutexIndex(void *pv_Destination) +{ + return ((unsigned int)(size_t)pv_Destination >> _OU_ATOMIC_MUTES_INDEX_SHIFT) & _OU_ATOMIC_MUTEX_INDEX_MASK; +} + + +////////////////////////////////////////////////////////////////////////// +// Atomic ord32 functions implementation + +#if !defined(__OU_ATOMIC_ORD32_FUNCTIONS_DEFINED) + +/*extern*/ atomicord32 AtomicIncrement(volatile atomicord32 *paoDestination) +{ + const unsigned int uiMutexIndex = DeriveAtomicMutexIndex((void *)paoDestination); + pthread_mutex_t *ptmMutexToBeUsed = g_apmAtomicMutexes + uiMutexIndex; + + int iLockResult = pthread_mutex_lock(ptmMutexToBeUsed); + OU_CHECK(iLockResult == EOK); + + const atomicord32 aoNewValue = ++(*paoDestination); + + int iUnlockResult = pthread_mutex_unlock(ptmMutexToBeUsed); + OU_CHECK(iUnlockResult == EOK); + + atomicord32 aoResult = aoNewValue; + return aoResult; +} + +/*extern*/ atomicord32 AtomicDecrement(volatile atomicord32 *paoDestination) +{ + const unsigned int uiMutexIndex = DeriveAtomicMutexIndex((void *)paoDestination); + pthread_mutex_t *ptmMutexToBeUsed = g_apmAtomicMutexes + uiMutexIndex; + + int iLockResult = pthread_mutex_lock(ptmMutexToBeUsed); + OU_CHECK(iLockResult == EOK); + + const atomicord32 aoNewValue = --(*paoDestination); + + int iUnlockResult = pthread_mutex_unlock(ptmMutexToBeUsed); + OU_CHECK(iUnlockResult == EOK); + + atomicord32 aoResult = aoNewValue; + return aoResult; +} + + +/*extern*/ atomicord32 AtomicExchange(volatile atomicord32 *paoDestination, atomicord32 aoExchange) +{ + const unsigned int uiMutexIndex = DeriveAtomicMutexIndex((void *)paoDestination); + pthread_mutex_t *ptmMutexToBeUsed = g_apmAtomicMutexes + uiMutexIndex; + + int iLockResult = pthread_mutex_lock(ptmMutexToBeUsed); + OU_CHECK(iLockResult == EOK); + + const atomicord32 aoOldValue = *paoDestination; + + *paoDestination = aoExchange; + + int iUnlockResult = pthread_mutex_unlock(ptmMutexToBeUsed); + OU_CHECK(iUnlockResult == EOK); + + atomicord32 aoResult = aoOldValue; + return aoResult; +} + +/*extern*/ atomicord32 AtomicExchangeAdd(volatile atomicord32 *paoDestination, atomicord32 aoAddend) +{ + const unsigned int uiMutexIndex = DeriveAtomicMutexIndex((void *)paoDestination); + pthread_mutex_t *ptmMutexToBeUsed = g_apmAtomicMutexes + uiMutexIndex; + + int iLockResult = pthread_mutex_lock(ptmMutexToBeUsed); + OU_CHECK(iLockResult == EOK); + + const atomicord32 aoOldValue = *paoDestination; + + *paoDestination += aoAddend; + + int iUnlockResult = pthread_mutex_unlock(ptmMutexToBeUsed); + OU_CHECK(iUnlockResult == EOK); + + atomicord32 aoResult = aoOldValue; + return aoResult; +} + +/*extern*/ bool AtomicCompareExchange(volatile atomicord32 *paoDestination, atomicord32 aoComparand, atomicord32 aoExchange) +{ + bool bResult = false; + + const unsigned int uiMutexIndex = DeriveAtomicMutexIndex((void *)paoDestination); + pthread_mutex_t *ptmMutexToBeUsed = g_apmAtomicMutexes + uiMutexIndex; + + int iLockResult = pthread_mutex_lock(ptmMutexToBeUsed); + OU_CHECK(iLockResult == EOK); + + const atomicord32 aoOldValue = *paoDestination; + + if (aoOldValue == aoComparand) + { + *paoDestination = aoExchange; + + bResult = true; + } + + int iUnlockResult = pthread_mutex_unlock(ptmMutexToBeUsed); + OU_CHECK(iUnlockResult == EOK); + + return bResult; +} + + +/*extern*/ atomicord32 AtomicAnd(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + const unsigned int uiMutexIndex = DeriveAtomicMutexIndex((void *)paoDestination); + pthread_mutex_t *ptmMutexToBeUsed = g_apmAtomicMutexes + uiMutexIndex; + + int iLockResult = pthread_mutex_lock(ptmMutexToBeUsed); + OU_CHECK(iLockResult == EOK); + + const atomicord32 aoOldValue = *paoDestination; + + *paoDestination &= aoBitMask; + + int iUnlockResult = pthread_mutex_unlock(ptmMutexToBeUsed); + OU_CHECK(iUnlockResult == EOK); + + atomicord32 aoResult = aoOldValue; + return aoResult; +} + +/*extern*/ atomicord32 AtomicOr(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + const unsigned int uiMutexIndex = DeriveAtomicMutexIndex((void *)paoDestination); + pthread_mutex_t *ptmMutexToBeUsed = g_apmAtomicMutexes + uiMutexIndex; + + int iLockResult = pthread_mutex_lock(ptmMutexToBeUsed); + OU_CHECK(iLockResult == EOK); + + const atomicord32 aoOldValue = *paoDestination; + + *paoDestination |= aoBitMask; + + int iUnlockResult = pthread_mutex_unlock(ptmMutexToBeUsed); + OU_CHECK(iUnlockResult == EOK); + + atomicord32 aoResult = aoOldValue; + return aoResult; +} + +/*extern*/ atomicord32 AtomicXor(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + const unsigned int uiMutexIndex = DeriveAtomicMutexIndex((void *)paoDestination); + pthread_mutex_t *ptmMutexToBeUsed = g_apmAtomicMutexes + uiMutexIndex; + + int iLockResult = pthread_mutex_lock(ptmMutexToBeUsed); + OU_CHECK(iLockResult == EOK); + + const atomicord32 aoOldValue = *paoDestination; + + *paoDestination ^= aoBitMask; + + int iUnlockResult = pthread_mutex_unlock(ptmMutexToBeUsed); + OU_CHECK(iUnlockResult == EOK); + + atomicord32 aoResult = aoOldValue; + return aoResult; +} + + +#endif // #if !defined(__OU_ATOMIC_ORD32_FUNCTIONS_DEFINED) + + +////////////////////////////////////////////////////////////////////////// +// Atomic pointer functions implementation + +/*extern*/ atomicptr AtomicExchangePointer(volatile atomicptr *papDestination, atomicptr apExchange) +{ + const unsigned int uiMutexIndex = DeriveAtomicMutexIndex((void *)papDestination); + pthread_mutex_t *ptmMutexToBeUsed = g_apmAtomicMutexes + uiMutexIndex; + + int iLockResult = pthread_mutex_lock(ptmMutexToBeUsed); + OU_CHECK(iLockResult == EOK); + + const atomicptr apOldValue = *papDestination; + + *papDestination = apExchange; + + int iUnlockResult = pthread_mutex_unlock(ptmMutexToBeUsed); + OU_CHECK(iUnlockResult == EOK); + + atomicptr apResult = apOldValue; + return apResult; +} + +/*extern*/ bool AtomicCompareExchangePointer(volatile atomicptr *papDestination, atomicptr apComparand, atomicptr apExchange) +{ + bool bResult = false; + + const unsigned int uiMutexIndex = DeriveAtomicMutexIndex((void *)papDestination); + pthread_mutex_t *ptmMutexToBeUsed = g_apmAtomicMutexes + uiMutexIndex; + + int iLockResult = pthread_mutex_lock(ptmMutexToBeUsed); + OU_CHECK(iLockResult == EOK); + + const atomicptr apOldValue = *papDestination; + + if (apOldValue == apComparand) + { + *papDestination = apExchange; + + bResult = true; + } + + int iUnlockResult = pthread_mutex_unlock(ptmMutexToBeUsed); + OU_CHECK(iUnlockResult == EOK); + + return bResult; +} + + +////////////////////////////////////////////////////////////////////////// +// Atomic initialization functions implementation + +static void FreeAtomicMutexes(unsigned int nLastMutexIndex=0) +{ + const unsigned int nMutexCount = nLastMutexIndex == 0 ? _OU_ATOMIC_MUTEX_COUNT : nLastMutexIndex; + + for (unsigned int nMutexIndex = 0; nMutexIndex != nMutexCount; ++nMutexIndex) + { + int iMutexDestroyResult = pthread_mutex_destroy(g_apmAtomicMutexes + nMutexIndex); + OU_VERIFY(iMutexDestroyResult == EOK); // Ignore the error + } +} + +static bool CreateAtomicMutexesWithAttributes(pthread_mutexattr_t *pmaMutexAttributes) +{ + const unsigned int nMutexCount = _OU_ATOMIC_MUTEX_COUNT; + + unsigned int nMutexIndex = 0; + + for (; nMutexIndex != nMutexCount; ++nMutexIndex) + { + int iMutexInitResult = pthread_mutex_init(g_apmAtomicMutexes + nMutexIndex, pmaMutexAttributes); + + if (iMutexInitResult != EOK) + { + if (nMutexIndex != 0) + { + FreeAtomicMutexes(nMutexIndex); + } + + break; + } + } + + bool bResult = nMutexIndex == nMutexCount; + return bResult; +} + +static bool CreateAtomicMutexes() +{ + bool bResult = false; + + pthread_mutexattr_t maMutexAttributes; + + int iAttrInitResult = pthread_mutexattr_init(&maMutexAttributes); + + if (iAttrInitResult == EOK) + { + bResult = CreateAtomicMutexesWithAttributes(&maMutexAttributes); + + int iAttrDestroyResult = pthread_mutexattr_destroy(&maMutexAttributes); + OU_VERIFY(iAttrDestroyResult == EOK); // Ignore error + } + + return bResult; +} + + +static bool InitializeAtomicAPIValidated() +{ + bool bResult = false; + + do + { + if (!CreateAtomicMutexes()) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +static void FinalizeAtomicAPIValidated() +{ + FreeAtomicMutexes(); +} + + +/*extern*/ bool InitializeAtomicAPI() +{ + OU_ASSERT(g_uiAtomicAPIInitializationCount != 0U - 1U); + + bool bResult = false; + + do + { + if (g_uiAtomicAPIInitializationCount == 0) // Initialization/finalization must be called from main thread + { + if (!InitializeAtomicAPIValidated()) + { + break; + } + } + + ++g_uiAtomicAPIInitializationCount; + + bResult = true; + } + while (false); + + return bResult; +} + +/*extern*/ void FinalizeAtomicAPI() +{ + OU_ASSERT(g_uiAtomicAPIInitializationCount != 0U); + + if (--g_uiAtomicAPIInitializationCount == 0) // Initialization/finalization must be called from main thread + { + FinalizeAtomicAPIValidated(); + } +} + + +#else // #if defined(__OU_ATOMIC_PTR_FUNCTIONS_DEFINED) + +#if !defined(__OU_ATOMIC_ORD32_FUNCTIONS_DEFINED) + +#error Internal error (Atomic ord32 functions can not be undefined while pointer functions are defined) + + +#endif // #if !defined(__OU_ATOMIC_ORD32_FUNCTIONS_DEFINED) + + +#if defined(__OU_ATOMIC_INITIALIZATION_FUNCTIONS_REQUIRED) + +#error Internal error (Atomic initialization can not be required while atomic functions are defined) + + +#endif // #if defined(__OU_ATOMIC_INITIALIZATION_FUNCTIONS_REQUIRED) + + +#endif // #if !defined(__OU_ATOMIC_PTR_FUNCTIONS_DEFINED) + + +END_NAMESPACE_OU(); + + +#endif // #if _OU_FEATURE_SET >= _OU_FEATURE_SET_ATOMICS + diff --git a/libs/ode-0.16.1/ou/src/ou/customization.cpp b/libs/ode-0.16.1/ou/src/ou/customization.cpp new file mode 100644 index 0000000..31f1342 --- /dev/null +++ b/libs/ode-0.16.1/ou/src/ou/customization.cpp @@ -0,0 +1,64 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#include <ou/customization.h> + + +BEGIN_NAMESPACE_OU(); + + +#if !defined(__FILE__) + +// Definition of __FILE__ constant for the case if compiler does not support the macro +/*extern*/ const char *const __FILE__ = "<filename unavailable>"; + + +#endif // #if !defined(__FILE__) + + +#if !defined(__LINE__) + +// Definition of __LINE__ constant for the case if compiler does not support the macro +extern const unsigned int __LINE__ = 0; + + +#endif // #if !defined(__LINE__) + + +////////////////////////////////////////////////////////////////////////// + +/*extern*/ CAssertionFailedProcedure CAssertionCheckCustomization::g_fnAssertFailureHandler = NULL; + + +////////////////////////////////////////////////////////////////////////// + +/*extern*/ CMemoryAllocationProcedure CMemoryManagerCustomization::g_fnMemoryAllocationProcedure = NULL; +/*extern*/ CMemoryReallocationProcedure CMemoryManagerCustomization::g_fnMemoryReallocationProcedure = NULL; +/*extern*/ CMemoryDeallocationProcedure CMemoryManagerCustomization::g_fnMemoryDeallocationProcedure = NULL; + + +END_NAMESPACE_OU(); + diff --git a/libs/ode-0.16.1/ou/src/ou/malloc.cpp b/libs/ode-0.16.1/ou/src/ou/malloc.cpp new file mode 100644 index 0000000..de6d8f5 --- /dev/null +++ b/libs/ode-0.16.1/ou/src/ou/malloc.cpp @@ -0,0 +1,106 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#include <ou/malloc.h> +#include <ou/assert.h> +#include <ou/customization.h> +#include <ou/macros.h> + +#if _OU_TARGET_OS == _OU_TARGET_OS_MAC || _OU_TARGET_OS == _OU_TARGET_OS_IOS + +#include <stdlib.h> + + +#else // #if _OU_TARGET_OS != _OU_TARGET_OS_MAC && _OU_TARGET_OS != _OU_TARGET_OS_IOS + +#include <malloc.h> + + +#endif // #if _OU_TARGET_OS != _OU_TARGET_OS_MAC && _OU_TARGET_OS != _OU_TARGET_OS_IOS + + +BEGIN_NAMESPACE_OU(); + + +/*extern*/ void *_OU_CONVENTION_API AllocateMemoryBlock(size_t nBlockSize) +{ + void *pv_NewBlock; + + CMemoryAllocationProcedure fnMemoryAllocationProcedure = CMemoryManagerCustomization::GetMemoryAllocationCustomProcedure(); + + if (fnMemoryAllocationProcedure) + { + pv_NewBlock = fnMemoryAllocationProcedure(nBlockSize); + OU_ASSERT(OU_ALIGNED_SIZE((size_t)pv_NewBlock, _OU_MEMORY_REQUIRED_ALIGNMENT) == (size_t)pv_NewBlock); // Memory must be aligned + } + else + { + pv_NewBlock = malloc(nBlockSize); + } + + return pv_NewBlock; +} + +/*extern*/ void *_OU_CONVENTION_API ReallocateMemoryBlock(void *pv_ExistingBlock, size_t nNewBlockSize) +{ + OU_ASSERT(OU_ALIGNED_SIZE((size_t)pv_ExistingBlock, _OU_MEMORY_REQUIRED_ALIGNMENT) == (size_t)pv_ExistingBlock); // Memory must be aligned + + void *pv_NewBlock; + + CMemoryReallocationProcedure fnMemoryReallocationProcedure = CMemoryManagerCustomization::GetMemoryReallocationCustomProcedure(); + + if (fnMemoryReallocationProcedure) + { + pv_NewBlock = fnMemoryReallocationProcedure(pv_ExistingBlock, nNewBlockSize); + OU_ASSERT(OU_ALIGNED_SIZE((size_t)pv_NewBlock, _OU_MEMORY_REQUIRED_ALIGNMENT) == (size_t)pv_NewBlock); // Memory must be aligned + } + else + { + pv_NewBlock = realloc(pv_ExistingBlock, nNewBlockSize); + } + + return pv_NewBlock; +} + +/*extern*/ void _OU_CONVENTION_API FreeMemoryBlock(void *pv_ExistingBlock) +{ + OU_ASSERT(OU_ALIGNED_SIZE((size_t)pv_ExistingBlock, _OU_MEMORY_REQUIRED_ALIGNMENT) == (size_t)pv_ExistingBlock); // Memory must be aligned + + CMemoryDeallocationProcedure fnMemoryDeallocationProcedure = CMemoryManagerCustomization::GetMemoryDeallocationCustomProcedure(); + + if (fnMemoryDeallocationProcedure) + { + fnMemoryDeallocationProcedure(pv_ExistingBlock); + } + else + { + free(pv_ExistingBlock); + } +} + + +END_NAMESPACE_OU(); + diff --git a/libs/ode-0.16.1/ou/src/ou/threadlocalstorage.cpp b/libs/ode-0.16.1/ou/src/ou/threadlocalstorage.cpp new file mode 100644 index 0000000..49d033a --- /dev/null +++ b/libs/ode-0.16.1/ou/src/ou/threadlocalstorage.cpp @@ -0,0 +1,1336 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#include <ou/features.h> + + +#if _OU_FEATURE_SET >= _OU_FEATURE_SET_TLS + +#include <ou/threadlocalstorage.h> +#include <ou/atomicflags.h> +#include <ou/atomic.h> +#include <ou/simpleflags.h> +#include <ou/malloc.h> +#include <ou/templates.h> +#include <ou/inttypes.h> + +#include <string.h> +#include <errno.h> +#include <new> + +#if !defined(EOK) + +#define EOK 0 + + +#endif + + +#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + +#include <windows.h> + + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + + +BEGIN_NAMESPACE_OU(); + + +class CTLSStorageInstance; + +enum ESTORAGEINSTANCEKIND +{ + SIK__MIN, + + SIK_AUTOCLEANUP = SIK__MIN, + SIK_MANUALCLEANUP, + + SIK__MAX, +}; + + +static unsigned int g_uiThreadLocalStorageInitializationCount = 0; +static CTLSStorageInstance *g_apsiStorageGlobalInstances[SIK__MAX] = { NULL }; +static HTLSKEYVALUE g_ahkvStorageGlobalKeyValues[SIK__MAX] = { NULL }; + + +static inline size_t DecodeInstanceKindFromKeySelector(const HTLSKEYSELECTOR &hksKeySelector) +{ + return (HTLSKEYSELECTOR::value_type)hksKeySelector - g_ahkvStorageGlobalKeyValues; +} + +static inline HTLSKEYSELECTOR EncodeKeySelectorFromStorageKind(ESTORAGEINSTANCEKIND ikInstanceKind) +{ + return g_ahkvStorageGlobalKeyValues + ikInstanceKind; +} + + +#if !defined(_OU_TLS_ARRAY_ELEMENT_COUNT) + +// Default TLS array element count +#define _OU_TLS_ARRAY_ELEMENT_COUNT 8 + + +#endif // #if !defined(_OU_TLS_ARRAY_ELEMENT_COUNT) + + +// Few bits must be reserved for additional purposes (currently 1) +#if (_OU_TLS_ARRAY_ELEMENT_COUNT < 1) || (_OU_TLS_ARRAY_ELEMENT_COUNT > 30) + +#error Please specify TLS array element count in range from 1 to 30 + + +#endif // #if (_OU_TLS_ARRAY_ELEMENT_COUNT < 1) || (_OU_TLS_ARRAY_ELEMENT_COUNT > 30) + + +enum +{ + TLS_ARRAY_ELEMENT__MAX = _OU_TLS_ARRAY_ELEMENT_COUNT, // 16 threads with 8 values each using 4 + 4 bytes is ~1 kb of memory +}; + + +struct CTLSStorageArray +{ +private: +#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + + typedef HANDLE CClientHandleArray[TLS_ARRAY_ELEMENT__MAX]; + typedef unsigned int CHandleTranslationMap[TLS_ARRAY_ELEMENT__MAX]; + + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + +public: + static inline size_t GetHeaderSize() { return OU_ALIGNED_SIZE(sizeof(CTLSStorageArray), CTLSStorageBlock::TSB_LARGEST_ALIGNMENT); } + +public: + static CTLSStorageArray *AllocateInstance(tlsindextype iValueCount); + void FreeInstance(tlsindextype iValueCount); + +protected: + inline CTLSStorageArray(); // Use AllocateInstance() + inline ~CTLSStorageArray(); // Use FreeInstance() + +public: + void FreeStorageBlockOnThreadExit(CTLSStorageBlock *psbStorageBlock, tlsindextype iValueCount); + +public: + bool FindFreeStorageBlock(CTLSStorageBlock *&psbOutFreeStorageBlock, + tlsindextype iValueCount, bool bIsManualCleanup); + +private: + bool FindFreeStorageBlockIndex(unsigned int &nOutFreeBlockIndex, tlsindextype iValueCount, bool bIsManualCleanup); + bool FindFreeStorageBlockIndexWithPossibilityVerified(unsigned int &nOutFreeBlockIndex, bool bIsManualCleanup); +#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + + bool FindAbandonedStorageBlockIndex(unsigned int &nOutFreeBlockIndex, tlsindextype iValueCount); + unsigned int TranslateClientHandles(CClientHandleArray haTranslatedHandlesStorage, CHandleTranslationMap tmTranslationMapStorage, + const HANDLE *&ph_OutTranslatedHandles, const unsigned int *&puiOutTranslationMap) const; + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + +private: + void FreeStorageAllBlocks(tlsindextype iValueCount); + void ReinitializeStorageSingleBlock(CTLSStorageBlock *psbStorageBlock, tlsindextype iValueCount); + static void FinalizeStorageSingleBlock(CTLSStorageBlock *psbStorageBlock, tlsindextype iValueCount); + + void AssignAllBlocksHostArray(tlsindextype iValueCount); + inline void AssignSingleBlockHostArray(CTLSStorageBlock *psbStorageBlock); + +private: + inline CTLSStorageBlock *GetStorageBlockPointer(unsigned int nBlockIndex, tlsindextype iValueCount) const; + inline unsigned int GetStorageBlockIndex(CTLSStorageBlock *psbStorageBlock, tlsindextype iValueCount) const; + inline static void ZeroStorageBlockMemory(CTLSStorageBlock *psbStorageBlock, tlsindextype iValueCount); + +private: +#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + + void AllocateBlockThreadHandle(unsigned int nBlockIndex); + void FreeStorageThreadHandle(unsigned int nBlockIndex); + + void AssignAllBlocksInvalidThreads(); + bool CheckIfAllBlocksHaveInvalidThreads(); + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + +private: +#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + + inline void SetBlockThreadHandle(unsigned int nBlockIndex, HANDLE hValue) + { + m_haBlockThreads[nBlockIndex] = hValue; + } + + inline HANDLE GetBlockThreadHandle(unsigned int nBlockIndex) const + { + return m_haBlockThreads[nBlockIndex]; + } + + inline const HANDLE *GetBlockThreadHandlesStorage() const + { + return m_haBlockThreads; + } + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + +public: + inline void SetNextArray(CTLSStorageArray *psaInstance) + { + m_psaNextArray = (atomicptr)psaInstance; + } + + inline CTLSStorageArray *GetNextArray() const + { + return (CTLSStorageArray *)m_psaNextArray; + } + +private: + enum + { + FL_OCCUPANCY_FLAGS__START = 0x00000001, + FL_OCCUPANCY_FLAGS__END = FL_OCCUPANCY_FLAGS__START << TLS_ARRAY_ELEMENT__MAX, + + FL_ARRAY_LOCKED = FL_OCCUPANCY_FLAGS__END, + }; + + inline bool GetAreAllBlocksOccupied() const + { + return m_afOccupancyFlags.EnumAllQueryEnumeratedFlags(FL_OCCUPANCY_FLAGS__START, TLS_ARRAY_ELEMENT__MAX) == OU_FLAGS_ENUMFLAGS_MASK(COccupancyFlagsType::value_type, FL_OCCUPANCY_FLAGS__START, TLS_ARRAY_ELEMENT__MAX); + } + + inline bool GetIsAnyBlockOccupied() const + { + return m_afOccupancyFlags.EnumAnyGetEnumeratedFlagValue(FL_OCCUPANCY_FLAGS__START, TLS_ARRAY_ELEMENT__MAX); + } + + inline bool SetBlockOccupiedFlag(unsigned int nBlockIndex) + { + return m_afOccupancyFlags.EnumModifyEnumeratedFlagValue(FL_OCCUPANCY_FLAGS__START, nBlockIndex, TLS_ARRAY_ELEMENT__MAX, true); + } + + inline void ResetBlockOccupiedFlag(unsigned int nBlockIndex) + { + m_afOccupancyFlags.EnumDropEnumeratedFlagValue(FL_OCCUPANCY_FLAGS__START, nBlockIndex, TLS_ARRAY_ELEMENT__MAX); + } + + inline bool GetBlockOccupiedFlag(unsigned int nBlockIndex) const + { + return m_afOccupancyFlags.EnumGetEnumeratedFlagValue(FL_OCCUPANCY_FLAGS__START, nBlockIndex, TLS_ARRAY_ELEMENT__MAX); + } + + inline bool SetArrayLockedFlag() + { + return m_afOccupancyFlags.ModifySingleFlagValue(FL_ARRAY_LOCKED, true); + } + + inline void ResetArrayLockedFlag() + { + m_afOccupancyFlags.DropFlagsMaskValue(FL_ARRAY_LOCKED); + } + +private: + typedef CAtomicFlags COccupancyFlagsType; + + volatile atomicptr m_psaNextArray; // CTLSStorageArray * + COccupancyFlagsType m_afOccupancyFlags; + +#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + + CClientHandleArray m_haBlockThreads; + + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + + // CTLSStorageBlock m_asbStorageBlocks[]; +}; + +class CTLSStorageInstance +{ +public: + static CTLSStorageInstance *AllocateInstance(tlsindextype iValueCount, unsigned int uiInitializationFlags); + void FreeInstance(); + +protected: + CTLSStorageInstance(tlsindextype iValueCount, unsigned int uiInitializationFlags); + ~CTLSStorageInstance(); + +public: + bool Init(ESTORAGEINSTANCEKIND ikInstanceKind); + +private: + void Finit(); + +public: + inline const HTLSKEYVALUE &RetrieveStorageKey() const { return GetStorageKey(); } + inline tlsindextype RetrieveValueCount() const { return GetValueCount(); } + inline unsigned int RetrieveInitializationFlags() const { return GetInitializationFlags(); } + + inline bool GetIsThreadManualCleanup() const { return GetThreadManualCleanupFlag(); } + +public: + void FreeStorageBlockOnThreadExit(CTLSStorageBlock *psbStorageBlock); + +public: + bool FindFreeStorageBlock(CTLSStorageBlock *&psbOutStorageBlock); + +private: + bool FindFreeStorageBlockInArrayList(CTLSStorageBlock *&psbOutStorageBlock); + bool FindFreeStorageBlockInArrayListSegment(CTLSStorageBlock *&psbOutStorageBlock, + CTLSStorageArray *psaListSegmentBegin, CTLSStorageArray *psaListSegmentEnd); + bool FindFreeStorageBlockFromArray(CTLSStorageBlock *&psbOutStorageBlock, + CTLSStorageArray *psaArrayInstance); + + void AddStorageArrayToArrayList(CTLSStorageArray *psaStorageArray); + +private: + static bool AllocateStorageKey(HTLSKEYVALUE &hkvOutStorageKey, ESTORAGEINSTANCEKIND ikInstanceKind); + static void FreeStorageKey(const HTLSKEYVALUE &hkvStorageKey); + +#if _OU_TARGET_OS != _OU_TARGET_OS_WINDOWS + + static void FreeStorageBlock_Callback_Automatic(void *pv_DataValue); + static void FreeStorageBlock_Callback_Manual(void *pv_DataValue); + + +#endif // #if _OU_TARGET_OS != _OU_TARGET_OS_WINDOWS + + void FreeStorageBlock(CTLSStorageBlock *psbStorageBlock); + + CTLSStorageArray *AllocateStorageArray(); + void FreeStorageArrayList(CTLSStorageArray *psaStorageArrayList); + +private: + inline bool TrySettingStorageArrayList(CTLSStorageArray *psaInstance, CTLSStorageArray *psaCurrentList) + { + return AtomicCompareExchangePointer(&m_psaStorageList, (atomicptr)psaCurrentList, (atomicptr)psaInstance); + } + + inline CTLSStorageArray *GetStorageArrayList() const + { + return (CTLSStorageArray *)m_psaStorageList; + } + + inline void SetStorageKey(const HTLSKEYVALUE &hskValue) { m_hskStorageKey = hskValue; } + inline const HTLSKEYVALUE &GetStorageKey() const { return m_hskStorageKey; } + + inline tlsindextype GetValueCount() const { return m_iValueCount; } + +private: + enum + { + FL_STORAGE_KEY_VALID = 0x00000001, + + FLM_INITIALIZATION_FLAGS_MASK = 0x0000FFFF, + FLS_INITIALIZATION_FLAGS_SHIFT = 16, + + FL_INITIALIZATION_THREAD_MANUAL_CLEANUP = CTLSInitialization::SIF_MANUAL_CLEANUP_ON_THREAD_EXIT << FLS_INITIALIZATION_FLAGS_SHIFT, + }; + + inline void SetStorageKeyValidFlag() { m_sfInstanceFlags.SignalFlagsMaskValue(FL_STORAGE_KEY_VALID); } + inline void ResetStorageKeyValidFlag() { m_sfInstanceFlags.DropFlagsMaskValue(FL_STORAGE_KEY_VALID); } + inline bool GetStorageKeyValidFlag() const { return m_sfInstanceFlags.GetFlagsMaskValue(FL_STORAGE_KEY_VALID); } + + inline void SetInitializationFlags(unsigned int uiValue) { m_sfInstanceFlags.StoreFlagsEnumeratedValue(FLM_INITIALIZATION_FLAGS_MASK, FLS_INITIALIZATION_FLAGS_SHIFT, uiValue); } + inline unsigned int GetInitializationFlags() const { return m_sfInstanceFlags.RetrieveFlagsEnumeratedValue(FLM_INITIALIZATION_FLAGS_MASK, FLS_INITIALIZATION_FLAGS_SHIFT); } + + inline bool GetThreadManualCleanupFlag() const { return m_sfInstanceFlags.GetFlagsMaskValue(FL_INITIALIZATION_THREAD_MANUAL_CLEANUP); } + +private: + volatile atomicptr m_psaStorageList; // CTLSStorageArray * + HTLSKEYVALUE m_hskStorageKey; + CSimpleFlags m_sfInstanceFlags; + tlsindextype m_iValueCount; +}; + + +////////////////////////////////////////////////////////////////////////// +// CTLSStorageArray methods + +CTLSStorageArray *CTLSStorageArray::AllocateInstance(tlsindextype iValueCount) +{ + const size_t nHeaderSize = CTLSStorageArray::GetHeaderSize(); + const size_t nBlockSize = CTLSStorageBlock::GetRequiredSize(iValueCount); + size_t nRequiredSize = nHeaderSize + nBlockSize * TLS_ARRAY_ELEMENT__MAX; + + CTLSStorageArray *psaNewInstance = (CTLSStorageArray *)AllocateMemoryBlock(nRequiredSize); + + if (psaNewInstance) + { + memset(psaNewInstance, 0, nRequiredSize); + new((CTLSStorageArray *)psaNewInstance) CTLSStorageArray(); + + psaNewInstance->AssignAllBlocksHostArray(iValueCount); + } + + return psaNewInstance; +} + +void CTLSStorageArray::FreeInstance(tlsindextype iValueCount) +{ + if (GetIsAnyBlockOccupied()) + { + FreeStorageAllBlocks(iValueCount); + } + + this->CTLSStorageArray::~CTLSStorageArray(); + FreeMemoryBlock((void *)this); +} + +CTLSStorageArray::CTLSStorageArray() +{ +#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + + AssignAllBlocksInvalidThreads(); + + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS +} + +CTLSStorageArray::~CTLSStorageArray() +{ +#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + + OU_ASSERT(CheckIfAllBlocksHaveInvalidThreads()); + + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS +} + + +void CTLSStorageArray::FreeStorageBlockOnThreadExit(CTLSStorageBlock *psbStorageBlock, tlsindextype iValueCount) +{ + ReinitializeStorageSingleBlock(psbStorageBlock, iValueCount); + // OU_ASSERT(GetBlockThreadHandle(nBlockIndex) == INVALID_HANDLE_VALUE) -- assertion further in the code + + unsigned int nBlockIndex = GetStorageBlockIndex(psbStorageBlock, iValueCount); + OU_ASSERT(GetBlockOccupiedFlag(nBlockIndex)); +#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + + OU_ASSERT(GetBlockThreadHandle(nBlockIndex) == INVALID_HANDLE_VALUE); // The method is not to be called if automatic cleanup is enabled + + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + + ResetBlockOccupiedFlag(nBlockIndex); +} + + +bool CTLSStorageArray::FindFreeStorageBlock(CTLSStorageBlock *&psbOutFreeStorageBlock, + tlsindextype iValueCount, bool bIsManualCleanup) +{ + bool bResult = false; + + unsigned int nFreeBlockIndex; + + if (FindFreeStorageBlockIndex(nFreeBlockIndex, iValueCount, bIsManualCleanup)) + { + CTLSStorageBlock *psbFreeStorageBlock = GetStorageBlockPointer(nFreeBlockIndex, iValueCount); + + psbOutFreeStorageBlock = psbFreeStorageBlock; + bResult = true; + } + + return bResult; +} + + +bool CTLSStorageArray::FindFreeStorageBlockIndex(unsigned int &nOutFreeBlockIndex, + tlsindextype iValueCount, bool bIsManualCleanup) +{ + bool bResult = false; + + if (!GetAreAllBlocksOccupied() && FindFreeStorageBlockIndexWithPossibilityVerified(nOutFreeBlockIndex, bIsManualCleanup)) + { + bResult = true; + } +#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + + else if (!bIsManualCleanup) + { + // Execution gets here is all slots were already occupied or + // they become occupied during search (otherwise why + // FindFreeStorageBlockIndexWithPossibilityVerified call failed???). + // In Automatic cleanup mode a block can't become free by itself - + // it is just re-allocated for new thread and remains busy. + OU_ASSERT(GetAreAllBlocksOccupied()); + + // The locking is performed to avoid more than one threads checking + // for abandoned handles simultaneously. + // If locking fails, execution just proceeds to next array in the chain + if (SetArrayLockedFlag()) + { + bResult = FindAbandonedStorageBlockIndex(nOutFreeBlockIndex, iValueCount); + + ResetArrayLockedFlag(); + } + } + + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + + return bResult; +} + +bool CTLSStorageArray::FindFreeStorageBlockIndexWithPossibilityVerified(unsigned int &nOutFreeBlockIndex, + bool bIsManualCleanup) +{ + unsigned int nBlockIndex = 0; + + for (; nBlockIndex != TLS_ARRAY_ELEMENT__MAX; ++nBlockIndex) + { + if (SetBlockOccupiedFlag(nBlockIndex)) + { +#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + + if (!bIsManualCleanup) + { + AllocateBlockThreadHandle(nBlockIndex); + } + + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + + nOutFreeBlockIndex = nBlockIndex; + break; + } + } + + bool bResult = nBlockIndex != TLS_ARRAY_ELEMENT__MAX; + return bResult; +} + + +#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + +bool CTLSStorageArray::FindAbandonedStorageBlockIndex(unsigned int &nOutFreeBlockIndex, + tlsindextype iValueCount) +{ + bool bResult = false; + + do + { + CClientHandleArray haTranslatedHandlesStorage; + CHandleTranslationMap tmTranslationMapStorage; + + const HANDLE *ph_TranslatedHandles; + const unsigned int *puiTranslationMap; + + // Translate handles into array for the case if there are invalids + unsigned int nHandleCount = TranslateClientHandles(haTranslatedHandlesStorage, tmTranslationMapStorage, + ph_TranslatedHandles, puiTranslationMap); + OU_ASSERT(OU_IN_INT_RANGE(nHandleCount, 0, MAXIMUM_WAIT_OBJECTS + 1)); + + if (nHandleCount == 0) + { + break; + } + + // Since allocating a new storage block is a relatively slow operation + // it is acceptable to enter kernel for checking for exited threads. + DWORD dwWaitResult = ::WaitForMultipleObjects(nHandleCount, ph_TranslatedHandles, FALSE, 0); + + if (!OU_IN_INT_RANGE(dwWaitResult - WAIT_OBJECT_0, 0, nHandleCount)) + { + // Wait should not normally fail. If it does it's in most cases an indication + // of invalid handle passed as parameter. However it may fail because of other + // reasons as well. If this assertion fails too often and you are sure all the + // handles are valid, it is safe to comment it. + OU_ASSERT(dwWaitResult != WAIT_FAILED); + + break; + } + + unsigned int nTranslatedBlockIndex = (unsigned int)(dwWaitResult - WAIT_OBJECT_0); + unsigned int nBlockIndex = !puiTranslationMap ? nTranslatedBlockIndex : puiTranslationMap[nTranslatedBlockIndex]; + + CTLSStorageBlock *psbStorageBlock = GetStorageBlockPointer(nBlockIndex, iValueCount); + ReinitializeStorageSingleBlock(psbStorageBlock, iValueCount); + + // Close old handle and make a duplicate of current thread handle + FreeStorageThreadHandle(nBlockIndex); + AllocateBlockThreadHandle(nBlockIndex); + + nOutFreeBlockIndex = nBlockIndex; + bResult = true; + } + while (false); + + return bResult; +} + +unsigned int CTLSStorageArray::TranslateClientHandles(CClientHandleArray haTranslatedHandlesStorage, CHandleTranslationMap tmTranslationMapStorage, + const HANDLE *&ph_OutTranslatedHandles, const unsigned int *&puiOutTranslationMap) const +{ + ph_OutTranslatedHandles = haTranslatedHandlesStorage; + puiOutTranslationMap = tmTranslationMapStorage; + + unsigned int nTargetStartIndex = 0; + unsigned int nSourceStartIndex = 0, nSourceCurrentIndex = 0; + + while (true) + { + if (GetBlockThreadHandle(nSourceCurrentIndex) == INVALID_HANDLE_VALUE) + { + const HANDLE *ph_BlockThreadHandles = GetBlockThreadHandlesStorage(); + + unsigned int nTargetIncrement = nSourceCurrentIndex - nSourceStartIndex; + + memcpy(&haTranslatedHandlesStorage[nTargetStartIndex], &ph_BlockThreadHandles[nSourceStartIndex], nTargetIncrement * sizeof(HANDLE)); + for (; nTargetIncrement != 0; ++nTargetStartIndex, ++nSourceStartIndex, --nTargetIncrement) { tmTranslationMapStorage[nTargetStartIndex] = nSourceStartIndex; } + + // Skip invalid handle (at this point nSourceStartIndex is equal to nSourceCurrentIndex) + ++nSourceStartIndex; + } + + ++nSourceCurrentIndex; + + if (nSourceCurrentIndex == TLS_ARRAY_ELEMENT__MAX) + { + // Start indice can be equal if and only if no invalid handles have been found + if (nSourceStartIndex != nTargetStartIndex) + { + const HANDLE *ph_BlockThreadHandles = GetBlockThreadHandlesStorage(); + + unsigned int nTargetIncrement = nSourceCurrentIndex - nSourceStartIndex; + + memcpy(&haTranslatedHandlesStorage[nTargetStartIndex], &ph_BlockThreadHandles[nSourceStartIndex], nTargetIncrement * sizeof(HANDLE)); + for (; nTargetIncrement != 0; ++nTargetStartIndex, ++nSourceStartIndex, --nTargetIncrement) { tmTranslationMapStorage[nTargetStartIndex] = nSourceStartIndex; } + } + + break; + } + } + + // If all the handles are valid... + if (nTargetStartIndex == 0) + { + // ...just return original handle array as no copying was performed + ph_OutTranslatedHandles = GetBlockThreadHandlesStorage(); + puiOutTranslationMap = NULL; + } + + return nTargetStartIndex; +} + + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + + +void CTLSStorageArray::FreeStorageAllBlocks(tlsindextype iValueCount) +{ + for (unsigned int nBlockIndex = 0; nBlockIndex != TLS_ARRAY_ELEMENT__MAX; ++nBlockIndex) + { + if (GetBlockOccupiedFlag(nBlockIndex)) + { + CTLSStorageBlock *psbStorageBlock = GetStorageBlockPointer(nBlockIndex, iValueCount); + + FinalizeStorageSingleBlock(psbStorageBlock, iValueCount); +#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + + FreeStorageThreadHandle(nBlockIndex); + + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + } + else + { +#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + + OU_ASSERT(GetBlockThreadHandle(nBlockIndex) == INVALID_HANDLE_VALUE); // Where did the handle come from if block is not occupied? + + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + } + } +} + +void CTLSStorageArray::ReinitializeStorageSingleBlock(CTLSStorageBlock *psbStorageBlock, tlsindextype iValueCount) +{ + FinalizeStorageSingleBlock(psbStorageBlock, iValueCount); + + ZeroStorageBlockMemory(psbStorageBlock, iValueCount); + AssignSingleBlockHostArray(psbStorageBlock); +} + +void CTLSStorageArray::FinalizeStorageSingleBlock(CTLSStorageBlock *psbStorageBlock, tlsindextype iValueCount) +{ + for (tlsindextype iValueIndex = 0; iValueIndex != iValueCount; ++iValueIndex) + { + tlsvaluetype vValueData = psbStorageBlock->GetValueData(iValueIndex); + + if (vValueData) + { + CTLSValueDestructor fnValueDestructor = psbStorageBlock->GetValueDestructor(iValueIndex); + + if (fnValueDestructor) + { + fnValueDestructor(vValueData); + } + } + } +} + + +void CTLSStorageArray::AssignAllBlocksHostArray(tlsindextype iValueCount) +{ + for (unsigned int nBlockIndex = 0; nBlockIndex != TLS_ARRAY_ELEMENT__MAX; ++nBlockIndex) + { + CTLSStorageBlock *psbStorageBlock = GetStorageBlockPointer(nBlockIndex, iValueCount); + + AssignSingleBlockHostArray(psbStorageBlock); + } +} + +void CTLSStorageArray::AssignSingleBlockHostArray(CTLSStorageBlock *psbStorageBlock) +{ + psbStorageBlock->SetHostArray(this); +} + + +CTLSStorageBlock *CTLSStorageArray::GetStorageBlockPointer(unsigned int nBlockIndex, tlsindextype iValueCount) const +{ + OU_ASSERT(OU_IN_INT_RANGE(nBlockIndex, 0, TLS_ARRAY_ELEMENT__MAX)); + + const size_t nHeaderSize = CTLSStorageArray::GetHeaderSize(); + const size_t nBlockSize = CTLSStorageBlock::GetRequiredSize(iValueCount); + const size_t nBlockZeroOffset = CTLSStorageBlock::GetZeroOffset(iValueCount); + + CTLSStorageBlock *psbStorageBlock = (CTLSStorageBlock *)(((int8ou *)this) + nHeaderSize + nBlockIndex * nBlockSize + nBlockZeroOffset); + return psbStorageBlock; +} + +unsigned int CTLSStorageArray::GetStorageBlockIndex(CTLSStorageBlock *psbStorageBlock, tlsindextype iValueCount) const +{ + const size_t nHeaderSize = CTLSStorageArray::GetHeaderSize(); + const size_t nBlockSize = CTLSStorageBlock::GetRequiredSize(iValueCount); + const size_t nBlockZeroOffset = CTLSStorageBlock::GetZeroOffset(iValueCount); + + unsigned int uiBlockIndex = (unsigned int)((((int8ou *)psbStorageBlock) - nBlockZeroOffset - nHeaderSize - ((int8ou *)this)) / nBlockSize); + OU_ASSERT((((int8ou *)psbStorageBlock) - nBlockZeroOffset - nHeaderSize - ((int8ou *)this)) % nBlockSize == 0); + OU_ASSERT(OU_IN_INT_RANGE(uiBlockIndex, 0, TLS_ARRAY_ELEMENT__MAX)); + + return uiBlockIndex; +} + +void CTLSStorageArray::ZeroStorageBlockMemory(CTLSStorageBlock *psbStorageBlock, tlsindextype iValueCount) +{ + const size_t nBlockSize = CTLSStorageBlock::GetRequiredSize(iValueCount); + const size_t nBlockZeroOffset = CTLSStorageBlock::GetZeroOffset(iValueCount); + + memset(((int8ou *)psbStorageBlock) - nBlockZeroOffset, 0, nBlockSize); +} + + +#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + +void CTLSStorageArray::AllocateBlockThreadHandle(unsigned int nBlockIndex) +{ + OU_ASSERT(GetBlockThreadHandle(nBlockIndex) == INVALID_HANDLE_VALUE); + + HANDLE hCurrentThreadDuplicate; + + HANDLE hCurrentProcess = ::GetCurrentProcess(); + HANDLE hCurrentThread = ::GetCurrentThread(); + if (!::DuplicateHandle(hCurrentProcess, hCurrentThread, hCurrentProcess, &hCurrentThreadDuplicate, SYNCHRONIZE, FALSE, 0)) + { + // Handle duplication should not normally fail. + // Thread and process pseudo-handles have full access allowed. + // The duplication may only fail in case of kernel internal problems + // (like lack of the resources or resource limit hits). + // Well, in this case thread data will remain in memory until + // CTLSInitialization::FinalizeTLSAPI() is called. + hCurrentThreadDuplicate = INVALID_HANDLE_VALUE; + } + + SetBlockThreadHandle(nBlockIndex, hCurrentThreadDuplicate); +} + +void CTLSStorageArray::FreeStorageThreadHandle(unsigned int nBlockIndex) +{ + HANDLE hExistingThreadHandle = GetBlockThreadHandle(nBlockIndex); + + if (hExistingThreadHandle != INVALID_HANDLE_VALUE) + { + BOOL bHandleCloseResult = ::CloseHandle(hExistingThreadHandle); + OU_VERIFY(bHandleCloseResult); // Closing handle should normally succeed + + SetBlockThreadHandle(nBlockIndex, INVALID_HANDLE_VALUE); + } +} + + +void CTLSStorageArray::AssignAllBlocksInvalidThreads() +{ + for (unsigned int nBlockIndex = 0; nBlockIndex != TLS_ARRAY_ELEMENT__MAX; ++nBlockIndex) + { + SetBlockThreadHandle(nBlockIndex, INVALID_HANDLE_VALUE); + } +} + +bool CTLSStorageArray::CheckIfAllBlocksHaveInvalidThreads() +{ + unsigned nBlockIndex = 0; + + for (; nBlockIndex != TLS_ARRAY_ELEMENT__MAX; ++nBlockIndex) + { + if (GetBlockThreadHandle(nBlockIndex) != INVALID_HANDLE_VALUE) + { + break; + } + } + + bool bResult = nBlockIndex == TLS_ARRAY_ELEMENT__MAX; + return bResult; +} + + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + + +////////////////////////////////////////////////////////////////////////// +// CTLSStorageInstance methods + +CTLSStorageInstance *CTLSStorageInstance::AllocateInstance(tlsindextype iValueCount, unsigned int uiInitializationFlags) +{ + size_t nSizeRequired = sizeof(CTLSStorageInstance); + + CTLSStorageInstance *psiNewInstance = (CTLSStorageInstance *)AllocateMemoryBlock(nSizeRequired); + + if (psiNewInstance) + { + new(psiNewInstance) CTLSStorageInstance(iValueCount, uiInitializationFlags); + } + + return psiNewInstance; +} + +void CTLSStorageInstance::FreeInstance() +{ + this->CTLSStorageInstance::~CTLSStorageInstance(); + FreeMemoryBlock(this); +} + + +CTLSStorageInstance::CTLSStorageInstance(tlsindextype iValueCount, unsigned int uiInitializationFlags): + m_psaStorageList((atomicptr)0), + m_hskStorageKey((HTLSKEYVALUE::value_type)0), + m_iValueCount(iValueCount) +{ + SetInitializationFlags(uiInitializationFlags); +} + +CTLSStorageInstance::~CTLSStorageInstance() +{ + Finit(); +} + + +bool CTLSStorageInstance::Init(ESTORAGEINSTANCEKIND ikInstanceKind) +{ + bool bResult = false; + + bool bKeyAllocationResult = false; + HTLSKEYVALUE hkvStorageKey; + + do + { + if (!AllocateStorageKey(hkvStorageKey, ikInstanceKind)) + { + break; + } + + bKeyAllocationResult = true; + + CTLSStorageArray *psaFirstStorageArray = AllocateStorageArray(); + + if (!psaFirstStorageArray) + { + break; + } + + SetStorageKey(hkvStorageKey); + SetStorageKeyValidFlag(); + AddStorageArrayToArrayList(psaFirstStorageArray); + + bResult = true; + } + while (false); + + if (!bResult) + { + if (bKeyAllocationResult) + { + FreeStorageKey(hkvStorageKey); + } + } + + return bResult; +} + +void CTLSStorageInstance::Finit() +{ + CTLSStorageArray *psaStorageArrayList = GetStorageArrayList(); + + if (psaStorageArrayList) + { + FreeStorageArrayList(psaStorageArrayList); + + bool bListClearingResult = TrySettingStorageArrayList(NULL, psaStorageArrayList); // It could be assigned directly, but I just do not want to add an extra method + OU_VERIFY(bListClearingResult); + } + + if (GetStorageKeyValidFlag()) + { + const HTLSKEYVALUE &hkvStorageKey = GetStorageKey(); + FreeStorageKey(hkvStorageKey); + + ResetStorageKeyValidFlag(); + } +} + + +void CTLSStorageInstance::FreeStorageBlockOnThreadExit(CTLSStorageBlock *psbStorageBlock) +{ + FreeStorageBlock(psbStorageBlock); +} + + +bool CTLSStorageInstance::FindFreeStorageBlock(CTLSStorageBlock *&psbOutStorageBlock) +{ + bool bResult = false; + + do + { + if (!FindFreeStorageBlockInArrayList(psbOutStorageBlock)) + { + CTLSStorageArray *psaStorageArray = AllocateStorageArray(); + + if (!psaStorageArray) + { + break; + } + + FindFreeStorageBlockFromArray(psbOutStorageBlock, psaStorageArray); // Must always succeed as array is not added to list yet + + AddStorageArrayToArrayList(psaStorageArray); + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool CTLSStorageInstance::FindFreeStorageBlockInArrayList(CTLSStorageBlock *&psbOutStorageBlock) +{ + bool bResult; + + CTLSStorageArray *psaListOldHead = NULL; + CTLSStorageArray *psaListCurrentHead = GetStorageArrayList(); + + while (true) + { + if (FindFreeStorageBlockInArrayListSegment(psbOutStorageBlock, psaListCurrentHead, psaListOldHead)) + { + bResult = true; + break; + } + + psaListOldHead = psaListCurrentHead; + psaListCurrentHead = GetStorageArrayList(); + + if (psaListOldHead == psaListCurrentHead) + { + bResult = false; + break; + } + } + + return bResult; +} + +bool CTLSStorageInstance::FindFreeStorageBlockInArrayListSegment(CTLSStorageBlock *&psbOutStorageBlock, + CTLSStorageArray *psaListSegmentBegin, CTLSStorageArray *psaListSegmentEnd) +{ + OU_ASSERT(psaListSegmentBegin != psaListSegmentEnd); + + bool bResult; + + CTLSStorageArray *psaListSegmentCurrent = psaListSegmentBegin; + + while (true) + { + if (FindFreeStorageBlockFromArray(psbOutStorageBlock, psaListSegmentCurrent)) + { + bResult = true; + break; + } + + psaListSegmentCurrent = psaListSegmentCurrent->GetNextArray(); + + if (psaListSegmentCurrent == psaListSegmentEnd) + { + bResult = false; + break; + } + } + + return bResult; +} + +bool CTLSStorageInstance::FindFreeStorageBlockFromArray(CTLSStorageBlock *&psbOutStorageBlock, + CTLSStorageArray *psaArrayInstance) +{ + tlsindextype iValueCount = GetValueCount(); + bool bIsManualCleanup = GetThreadManualCleanupFlag(); + + return psaArrayInstance->FindFreeStorageBlock(psbOutStorageBlock, iValueCount, bIsManualCleanup); +} + + +void CTLSStorageInstance::AddStorageArrayToArrayList(CTLSStorageArray *psaStorageArray) +{ + while (true) + { + CTLSStorageArray *psaListCurrentHead = GetStorageArrayList(); + psaStorageArray->SetNextArray(psaListCurrentHead); + + if (TrySettingStorageArrayList(psaStorageArray, psaListCurrentHead)) + { + break; + } + } +} + + +bool CTLSStorageInstance::AllocateStorageKey(HTLSKEYVALUE &hkvOutStorageKey, ESTORAGEINSTANCEKIND ikInstanceKind) +{ + bool bResult = false; + +#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + + DWORD dwTlsIndex = ::TlsAlloc(); + + if (dwTlsIndex != TLS_OUT_OF_INDEXES) + { + hkvOutStorageKey = (HTLSKEYVALUE)(HTLSKEYVALUE::value_type)(size_t)dwTlsIndex; + bResult = true; + } + + +#else // #if _OU_TARGET_OS != _OU_TARGET_OS_WINDOWS + + pthread_key_t pkThreadKey; + + int iKeyCreationResult = pthread_key_create(&pkThreadKey, + (ikInstanceKind == SIK_AUTOCLEANUP) ? &CTLSStorageInstance::FreeStorageBlock_Callback_Automatic : &CTLSStorageInstance::FreeStorageBlock_Callback_Manual); + if (iKeyCreationResult == EOK) + { + hkvOutStorageKey = (HTLSKEYVALUE)(HTLSKEYVALUE::value_type)(size_t)pkThreadKey; + bResult = true; + } + + +#endif // #if _OU_TARGET_OS == ... + + return bResult; +} + +void CTLSStorageInstance::FreeStorageKey(const HTLSKEYVALUE &hkvStorageKey) +{ +#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + + DWORD dwTlsIndex = (DWORD)(size_t)(HTLSKEYVALUE::value_type)hkvStorageKey; + OU_ASSERT(dwTlsIndex != TLS_OUT_OF_INDEXES); + + BOOL bIndexFreeingResult = ::TlsFree(dwTlsIndex); + OU_VERIFY(bIndexFreeingResult); + + +#else // #if _OU_TARGET_OS != _OU_TARGET_OS_WINDOWS + + pthread_key_t pkThreadKey = (pthread_key_t)(size_t)(HTLSKEYVALUE::value_type)hkvStorageKey; + + int iKeyDeletionResult = pthread_key_delete(pkThreadKey); + OU_VERIFY(iKeyDeletionResult == EOK); + + +#endif // #if _OU_TARGET_OS == ... +} + + +#if _OU_TARGET_OS != _OU_TARGET_OS_WINDOWS + +void CTLSStorageInstance::FreeStorageBlock_Callback_Automatic(void *pv_DataValue) +{ + if (pv_DataValue) // Just a precaution + { + CTLSStorageBlock *psbStorageBlock = (CTLSStorageBlock *)pv_DataValue; + + g_apsiStorageGlobalInstances[SIK_AUTOCLEANUP]->FreeStorageBlock(psbStorageBlock); + } +} + +void CTLSStorageInstance::FreeStorageBlock_Callback_Manual(void *pv_DataValue) +{ + if (pv_DataValue) // Just a precaution + { + CTLSStorageBlock *psbStorageBlock = (CTLSStorageBlock *)pv_DataValue; + + g_apsiStorageGlobalInstances[SIK_MANUALCLEANUP]->FreeStorageBlock(psbStorageBlock); + } +} + + +#endif // #if _OU_TARGET_OS != _OU_TARGET_OS_WINDOWS + + +void CTLSStorageInstance::FreeStorageBlock(CTLSStorageBlock *psbStorageBlock) +{ + const int iValueCount = GetValueCount(); + + CTLSStorageArray *psaArrayInstance = psbStorageBlock->GetHostArray(); + psaArrayInstance->FreeStorageBlockOnThreadExit(psbStorageBlock, iValueCount); +} + + +CTLSStorageArray *CTLSStorageInstance::AllocateStorageArray() +{ + const tlsindextype iValueCount = GetValueCount(); + + return CTLSStorageArray::AllocateInstance(iValueCount); +} + +void CTLSStorageInstance::FreeStorageArrayList(CTLSStorageArray *psaStorageArrayList) +{ + const tlsindextype iValueCount = GetValueCount(); + + while (psaStorageArrayList) + { + CTLSStorageArray *psaStorageNextArray = psaStorageArrayList->GetNextArray(); + + psaStorageArrayList->FreeInstance(iValueCount); + + psaStorageArrayList = psaStorageNextArray; + } +} + + +////////////////////////////////////////////////////////////////////////// +// CThreadLocalStorage methods + +bool CThreadLocalStorage::AllocateAndSetStorageValue(const HTLSKEYSELECTOR &hksKeySelector, + tlsindextype iValueIndex, tlsvaluetype vValueData, CTLSValueDestructor fnValueDestructor) +{ + OU_ASSERT(OU_IN_SIZET_RANGE(DecodeInstanceKindFromKeySelector(hksKeySelector), SIK__MIN, SIK__MAX)); + + bool bResult = false; + + do + { + ESTORAGEINSTANCEKIND ikInstanceKind = (ESTORAGEINSTANCEKIND)DecodeInstanceKindFromKeySelector(hksKeySelector); + CTLSStorageInstance *psiStorageInstance = g_apsiStorageGlobalInstances[ikInstanceKind]; + + CTLSStorageBlock *psbStorageBlock; + + if (!psiStorageInstance->FindFreeStorageBlock(psbStorageBlock)) + { + break; + } + + SetKeyStorageBlock(hksKeySelector, psbStorageBlock); + + psbStorageBlock->SetValueData(iValueIndex, vValueData); + psbStorageBlock->SetValueDestructor(iValueIndex, fnValueDestructor); + + bResult = true; + } + while (false); + + return bResult; +} + + +////////////////////////////////////////////////////////////////////////// +// CTLSInitialization methods + +bool CTLSInitialization::InitializeTLSAPI(HTLSKEY &hskOutStorageKey, tlsindextype iValueCount, + unsigned int uiInitializationFlags/*=0*/) +{ + OU_ASSERT(g_uiThreadLocalStorageInitializationCount != 0U - 1U); + + bool bResult = false; + + bool bAtomicAPIInitialized = false; + + do + { + const ESTORAGEINSTANCEKIND ikInstanceKind = (uiInitializationFlags & SIF_MANUAL_CLEANUP_ON_THREAD_EXIT) ? SIK_MANUALCLEANUP : SIK_AUTOCLEANUP; + + if (g_apsiStorageGlobalInstances[ikInstanceKind] == NULL) // Initialization/finalization must be called from main thread + { + if (!InitializeAtomicAPI()) + { + break; + } + + bAtomicAPIInitialized = true; + + if (!InitializeTLSAPIValidated(ikInstanceKind, iValueCount, uiInitializationFlags)) + { + break; + } + + const HTLSKEYVALUE &hkvStorageKey = g_apsiStorageGlobalInstances[ikInstanceKind]->RetrieveStorageKey(); + g_ahkvStorageGlobalKeyValues[ikInstanceKind] = hkvStorageKey; + } + + ++g_uiThreadLocalStorageInitializationCount; + + hskOutStorageKey = EncodeKeySelectorFromStorageKind(ikInstanceKind); + OU_ASSERT(iValueCount == g_apsiStorageGlobalInstances[ikInstanceKind]->RetrieveValueCount()); + OU_ASSERT(uiInitializationFlags == g_apsiStorageGlobalInstances[ikInstanceKind]->RetrieveInitializationFlags()); + + bResult = true; + } + while (false); + + if (!bResult) + { + if (bAtomicAPIInitialized) + { + FinalizeAtomicAPI(); + } + } + + return bResult; +} + +void CTLSInitialization::FinalizeTLSAPI() +{ + OU_ASSERT(g_uiThreadLocalStorageInitializationCount != 0U); + + ESTORAGEINSTANCEKIND ikInstanceKind = + (--g_uiThreadLocalStorageInitializationCount == 0U) ? SIK__MIN : SIK__MAX; // Initialization/finalization must be called from main thread + for (; ikInstanceKind != SIK__MAX; ++ikInstanceKind) + { + if (g_apsiStorageGlobalInstances[ikInstanceKind]) + { + g_ahkvStorageGlobalKeyValues[ikInstanceKind] = 0; + + FinalizeTLSAPIValidated(ikInstanceKind); + + FinalizeAtomicAPI(); + } + } +} + + +void CTLSInitialization::CleanupOnThreadExit() +{ + const ESTORAGEINSTANCEKIND ikInstanceKind = SIK_MANUALCLEANUP; + CTLSStorageInstance *psiStorageInstance = g_apsiStorageGlobalInstances[ikInstanceKind]; + + if (psiStorageInstance != NULL) + { + OU_ASSERT(psiStorageInstance->GetIsThreadManualCleanup()); + + const HTLSKEYSELECTOR &hksKeySelector = EncodeKeySelectorFromStorageKind(ikInstanceKind); + CTLSStorageBlock *psbStorageBlock = CThreadLocalStorage::GetKeyStorageBlock(hksKeySelector); + + if (psbStorageBlock) + { + psiStorageInstance->FreeStorageBlockOnThreadExit(psbStorageBlock); + + CThreadLocalStorage::SetKeyStorageBlock(hksKeySelector, NULL); + } + } + else + { + OU_ASSERT(false); // The method is not supposed to be called if manual cleanup was not requested on initialization + } +} + + +bool CTLSInitialization::InitializeTLSAPIValidated(unsigned int uiInstanceKind, + tlsindextype iValueCount, unsigned int uiInitializationFlags) +{ + OU_ASSERT(g_apsiStorageGlobalInstances[uiInstanceKind] == NULL); + + bool bResult = false; + + CTLSStorageInstance *psiStorageInstance; + + do + { + // Use static methods instead of constructor/destructor + // to avoid overloading operators new/delete and for + // uniformity with CTLSStorageArray class + psiStorageInstance = CTLSStorageInstance::AllocateInstance(iValueCount, uiInitializationFlags); + + if (!psiStorageInstance) + { + break; + } + + if (!psiStorageInstance->Init((ESTORAGEINSTANCEKIND)uiInstanceKind)) + { + break; + } + + g_apsiStorageGlobalInstances[uiInstanceKind] = psiStorageInstance; + + bResult = true; + } + while (false); + + if (!bResult) + { + if (psiStorageInstance) + { + psiStorageInstance->FreeInstance(); + } + } + + return bResult; +} + +void CTLSInitialization::FinalizeTLSAPIValidated(unsigned int uiInstanceKind) +{ + OU_ASSERT(g_apsiStorageGlobalInstances[uiInstanceKind] != NULL); + + g_apsiStorageGlobalInstances[uiInstanceKind]->FreeInstance(); + g_apsiStorageGlobalInstances[uiInstanceKind] = NULL; +} + + +END_NAMESPACE_OU(); + + +#endif // #if _OU_FEATURE_SET >= _OU_FEATURE_SET_TLS + diff --git a/libs/ode-0.16.1/ou/test/Makefile.am b/libs/ode-0.16.1/ou/test/Makefile.am new file mode 100644 index 0000000..c0f973f --- /dev/null +++ b/libs/ode-0.16.1/ou/test/Makefile.am @@ -0,0 +1,10 @@ +AM_CPPFLAGS = -I$(top_srcdir)/include +AM_CXXFLAGS = -fno-exceptions -fno-rtti +AM_LDFLAGS = -fno-exceptions -fno-rtti + +check_PROGRAMS = outest + +outest_SOURCES = outest.cpp + +outest_LDADD = $(top_builddir)/src/ou/libou.la + diff --git a/libs/ode-0.16.1/ou/test/Makefile.in b/libs/ode-0.16.1/ou/test/Makefile.in new file mode 100644 index 0000000..0c299c5 --- /dev/null +++ b/libs/ode-0.16.1/ou/test/Makefile.in @@ -0,0 +1,589 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +check_PROGRAMS = outest$(EXEEXT) +subdir = test +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am_outest_OBJECTS = outest.$(OBJEXT) +outest_OBJECTS = $(am_outest_OBJECTS) +outest_DEPENDENCIES = $(top_builddir)/src/ou/libou.la +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/../depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +SOURCES = $(outest_SOURCES) +DIST_SOURCES = $(outest_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/../depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +OU_FEATURE_SET = @OU_FEATURE_SET@ +OU_NAMESPACE = @OU_NAMESPACE@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = -I$(top_srcdir)/include +AM_CXXFLAGS = -fno-exceptions -fno-rtti +AM_LDFLAGS = -fno-exceptions -fno-rtti +outest_SOURCES = outest.cpp +outest_LDADD = $(top_builddir)/src/ou/libou.la +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign test/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +outest$(EXEEXT): $(outest_OBJECTS) $(outest_DEPENDENCIES) $(EXTRA_outest_DEPENDENCIES) + @rm -f outest$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(outest_OBJECTS) $(outest_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/outest.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/ou/test/outest.cpp b/libs/ode-0.16.1/ou/test/outest.cpp new file mode 100644 index 0000000..2ddfdef --- /dev/null +++ b/libs/ode-0.16.1/ou/test/outest.cpp @@ -0,0 +1,9027 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#include <ou/features.h> +#include <ou/platform.h> + +#if _OU_COMPILER == _OU_COMPILER_MSVC + +#pragma warning(disable:4786) + + +#endif + +#if _OU_FEATURE_SET >= _OU_FEATURE_SET_TLS +#include <ou/threadlocalstorage.h> +#endif +#if _OU_FEATURE_SET >= _OU_FEATURE_SET_ATOMICS +#include <ou/atomic.h> +#endif +#if _OU_FEATURE_SET >= _OU_FEATURE_SET_ATOMICS +#include <ou/atomicflags.h> +#endif +#include <ou/simpleflags.h> +#include <ou/flagsdefines.h> +#include <ou/enumarrays.h> +#include <ou/templates.h> +#include <ou/typewrapper.h> +#include <ou/customization.h> +#include <ou/inttypes.h> +#include <ou/macros.h> +#include <ou/malloc.h> + +#include <ou/namespace.h> +using namespace _OU_NAMESPACE; + +#include <stdio.h> +#include <string.h> + + +////////////////////////////////////////////////////////////////////////// + +typedef bool (*CFeatureTestProcedure)(); + + +bool TestSubsystem(unsigned int &nOutSuccessCount, unsigned int &nOutTestCount, + const unsigned int uiFeatureMax, const char *const *aszFeatureNames, CFeatureTestProcedure const *afnFeatureTests) +{ + unsigned int nSuccessCount = 0; + + for (unsigned int uiSubsystemFeature = 0; uiSubsystemFeature != uiFeatureMax; ++uiSubsystemFeature) + { + const char *szFeatureName = aszFeatureNames[uiSubsystemFeature]; + printf("Testing %34s: ", szFeatureName); + + CFeatureTestProcedure fnTestProcedure = afnFeatureTests[uiSubsystemFeature]; + bool bTestResult = fnTestProcedure(); + printf("%s\n", bTestResult ? "success" : "*** failure ***"); + + if (bTestResult) + { + nSuccessCount += 1; + } + } + + nOutSuccessCount = nSuccessCount; + nOutTestCount = uiFeatureMax; + return nSuccessCount == uiFeatureMax; +} + + + +////////////////////////////////////////////////////////////////////////// + +#if _OU_FEATURE_SET >= _OU_FEATURE_SET_TLS + +bool g_bTestTLSAPIInitialized = false; +HTLSKEY g_htkTestTLSKey; + +enum ETESTTLSVALUES +{ + TTV_FIRSTVALUE, + TTV_SECONDVALUE, + + TTV__MAX, +}; + +unsigned int g_uiTestTLSDestructorCallCount = 0; +unsigned int g_uiTestTLSDestructorSuccessCount = 0; + +void _OU_CONVENTION_CALLBACK TestTlsSecondValueDestructor(void *pv_Value) +{ + g_uiTestTLSDestructorCallCount += 1; + + if (pv_Value == (void *)(&TestTlsSecondValueDestructor)) + { + g_uiTestTLSDestructorSuccessCount += 1; + } +} + + +bool TestTls_Initialization() +{ + bool bResult = false; + + do + { + if (!CTLSInitialization::InitializeTLSAPI(g_htkTestTLSKey, 1, 0)) + { + break; + } + + CTLSInitialization::FinalizeTLSAPI(); + + if (!CTLSInitialization::InitializeTLSAPI(g_htkTestTLSKey, TTV__MAX, CTLSInitialization::SIF_MANUAL_CLEANUP_ON_THREAD_EXIT)) + { + break; + } + + g_bTestTLSAPIInitialized = true; + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestTls_GetSetValue() +{ + bool bResult = false; + + do + { + tlsvaluetype vtFirstValue = CThreadLocalStorage::GetStorageValue(g_htkTestTLSKey, TTV_FIRSTVALUE); + + if (vtFirstValue != 0) + { + break; + } + + tlsvaluetype vtSecondValue = CThreadLocalStorage::GetStorageValue(g_htkTestTLSKey, TTV_SECONDVALUE); + + if (vtSecondValue != 0) + { + break; + } + + if (!CThreadLocalStorage::SetStorageValue(g_htkTestTLSKey, TTV_FIRSTVALUE, (tlsvaluetype)&TestTls_GetSetValue)) + { + break; + } + + if (!CThreadLocalStorage::SetStorageValue(g_htkTestTLSKey, TTV_SECONDVALUE, (tlsvaluetype)&TestTlsSecondValueDestructor, &TestTlsSecondValueDestructor)) + { + break; + } + + vtFirstValue = CThreadLocalStorage::GetStorageValue(g_htkTestTLSKey, TTV_FIRSTVALUE); + + if ((void *)vtFirstValue != &TestTls_GetSetValue) + { + break; + } + + vtSecondValue = CThreadLocalStorage::GetStorageValue(g_htkTestTLSKey, TTV_SECONDVALUE); + + if ((void *)vtSecondValue != &TestTlsSecondValueDestructor) + { + break; + } + + if (!CThreadLocalStorage::SetStorageValue(g_htkTestTLSKey, TTV_SECONDVALUE, 0, &TestTlsSecondValueDestructor)) + { + break; + } + + vtSecondValue = CThreadLocalStorage::GetStorageValue(g_htkTestTLSKey, TTV_SECONDVALUE); + + if (vtSecondValue != 0) + { + break; + } + + if (!CThreadLocalStorage::SetStorageValue(g_htkTestTLSKey, TTV_SECONDVALUE, (tlsvaluetype)&TestTlsSecondValueDestructor, &TestTlsSecondValueDestructor)) + { + break; + } + + if (g_uiTestTLSDestructorCallCount != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestTls_UnsafeGetSetValue() +{ + bool bResult = false; + + do + { + tlsvaluetype vtFirstValue = CThreadLocalStorage::UnsafeGetStorageValue(g_htkTestTLSKey, TTV_FIRSTVALUE); + + if ((void *)vtFirstValue != &TestTls_GetSetValue) + { + break; + } + + tlsvaluetype vtSecondValue = CThreadLocalStorage::UnsafeGetStorageValue(g_htkTestTLSKey, TTV_SECONDVALUE); + + if ((void *)vtSecondValue != &TestTlsSecondValueDestructor) + { + break; + } + + CThreadLocalStorage::UnsafeSetStorageValue(g_htkTestTLSKey, TTV_FIRSTVALUE, (tlsvaluetype)(size_t)(-1)); + CThreadLocalStorage::UnsafeSetStorageValue(g_htkTestTLSKey, TTV_SECONDVALUE, (tlsvaluetype)(size_t)(-1)); + + vtFirstValue = CThreadLocalStorage::UnsafeGetStorageValue(g_htkTestTLSKey, TTV_FIRSTVALUE); + + if ((size_t)vtFirstValue != (size_t)(-1)) + { + break; + } + + vtSecondValue = CThreadLocalStorage::UnsafeGetStorageValue(g_htkTestTLSKey, TTV_SECONDVALUE); + + if ((size_t)vtSecondValue != (size_t)(-1)) + { + break; + } + + // Safe function used by intent !!! + vtFirstValue = CThreadLocalStorage::GetStorageValue(g_htkTestTLSKey, TTV_FIRSTVALUE); + + if ((size_t)vtFirstValue != (size_t)(-1)) + { + break; + } + + // Safe function used by intent !!! + vtSecondValue = CThreadLocalStorage::GetStorageValue(g_htkTestTLSKey, TTV_SECONDVALUE); + + if ((size_t)vtSecondValue != (size_t)(-1)) + { + break; + } + + CThreadLocalStorage::UnsafeSetStorageValue(g_htkTestTLSKey, TTV_SECONDVALUE, (tlsvaluetype)(&TestTlsSecondValueDestructor)); + + if (g_uiTestTLSDestructorCallCount != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestTls_CleanupDestructor() +{ + bool bResult = false; + + do + { + CTLSInitialization::CleanupOnThreadExit(); + + if (g_uiTestTLSDestructorCallCount != 1 || g_uiTestTLSDestructorSuccessCount != 1) + { + break; + } + + tlsvaluetype vtFirstValue = CThreadLocalStorage::GetStorageValue(g_htkTestTLSKey, TTV_FIRSTVALUE); + + if (vtFirstValue != 0) + { + break; + } + + // Safe function used by intent !!! + tlsvaluetype vtSecondValue = CThreadLocalStorage::GetStorageValue(g_htkTestTLSKey, TTV_SECONDVALUE); + + if (vtSecondValue != 0) + { + break; + } + + g_uiTestTLSDestructorCallCount = 0; + g_uiTestTLSDestructorSuccessCount = 0; + + CTLSInitialization::CleanupOnThreadExit(); + + if (g_uiTestTLSDestructorCallCount != 0) + { + break; + } + + if (!CThreadLocalStorage::SetStorageValue(g_htkTestTLSKey, TTV_SECONDVALUE, 0, &TestTlsSecondValueDestructor)) + { + break; + } + + CTLSInitialization::CleanupOnThreadExit(); + + if (g_uiTestTLSDestructorCallCount != 0) + { + break; + } + + if (!CThreadLocalStorage::SetStorageValue(g_htkTestTLSKey, TTV_SECONDVALUE, (tlsvaluetype)(size_t)(-1), &TestTlsSecondValueDestructor)) + { + break; + } + + if (g_uiTestTLSDestructorCallCount != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestTls_Finalization() +{ + OU_ASSERT(g_bTestTLSAPIInitialized); + + bool bResult = false; + + do + { + CTLSInitialization::FinalizeTLSAPI(); + + g_bTestTLSAPIInitialized = false; + + if (g_uiTestTLSDestructorCallCount != 1 || g_uiTestTLSDestructorSuccessCount != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + + +enum EOUTLSFEATURE +{ + OHF__MIN, + + OHF_INITIALIZATION = OHF__MIN, + OHF_GETSETVALUE, + OHF_UNSAFEGETSETVALUE, + OHF_CLEANUPDESTRUCTOR, + OHF_FINALIZATION, + + OHF__MAX, +}; + +template<> +CFeatureTestProcedure const CEnumUnsortedElementArray<EOUTLSFEATURE, OHF__MAX, CFeatureTestProcedure>::m_aetElementArray[] = +{ + &TestTls_Initialization, // OHF_INITIALIZATION + &TestTls_GetSetValue, // OHF_GETSETVALUE, + &TestTls_UnsafeGetSetValue, // OHF_UNSAFEGETSETVALUE, + &TestTls_CleanupDestructor, // OHF_CLEANUPDESTRUCTOR, + &TestTls_Finalization, // OHF_FINALIZATION, +}; +static const CEnumUnsortedElementArray<EOUTLSFEATURE, OHF__MAX, CFeatureTestProcedure> g_afnTlsFeatureTestProcedures; + +template<> +const char *const CEnumUnsortedElementArray<EOUTLSFEATURE, OHF__MAX, const char *>::m_aetElementArray[] = +{ + "API Initialization", // OHF_INITIALIZATION + "Get.../SetStorageValue", // OHF_GETSETVALUE, + "UnsafeGet.../UnsafeSetStorageValue", // OHF_UNSAFEGETSETVALUE, + "Storage Cleanup/Value Destructors", // OHF_CLEANUPDESTRUCTOR, + "API Finalization", // OHF_FINALIZATION, +}; +static const CEnumUnsortedElementArray<EOUTLSFEATURE, OHF__MAX, const char *> g_aszTlsFeatureTestNames; + + +bool TestTLS(unsigned int &nOutSuccessCount, unsigned int &nOutTestCount) +{ + bool bResult = TestSubsystem(nOutSuccessCount, nOutTestCount, OHF__MAX, g_aszTlsFeatureTestNames.GetStoragePointer(), g_afnTlsFeatureTestProcedures.GetStoragePointer()); + + if (g_bTestTLSAPIInitialized) + { + CTLSInitialization::FinalizeTLSAPI(); + } + + return bResult; +} + + +#endif // #if _OU_FEATURE_SET >= _OU_FEATURE_SET_TLS + + +////////////////////////////////////////////////////////////////////////// + +#if _OU_FEATURE_SET >= _OU_FEATURE_SET_ATOMICS + +bool TestAtomic_Increment() +{ + bool bResult = false; + + do + { + volatile atomicord32 aoStorage = (atomicord32)(-1); + + // Putting function inside of conditional operator causes + // incorrect code generation by GCC 4.0.1 on MacOS X Leopard 64 bit. + atomicord32 aoIncrementFirstResult = AtomicIncrement(&aoStorage); + if (aoIncrementFirstResult != 0 || aoStorage != (atomicord32)0) + { + break; + } + + if (AtomicIncrement(&aoStorage) != (atomicord32)1 || aoStorage != (atomicord32)1) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomic_Decrement() +{ + bool bResult = false; + + do + { + volatile atomicord32 aoStorage = (atomicord32)1; + + // Putting function inside of conditional operator causes + // incorrect code generation by GCC 4.0.1 on MacOS X Leopard 64 bit. + atomicord32 aoDecrementFirstResult = AtomicDecrement(&aoStorage); + if (aoDecrementFirstResult != (atomicord32)0 || aoStorage != (atomicord32)0) + { + break; + } + + if (AtomicDecrement(&aoStorage) != (atomicord32)(-1) || aoStorage != (atomicord32)(-1)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomic_IncrementNoResult() +{ + bool bResult = false; + + do + { + volatile atomicord32 aoStorage = (atomicord32)(-1); + + AtomicIncrementNoResult(&aoStorage); + + if (aoStorage != (atomicord32)0) + { + break; + } + + AtomicIncrementNoResult(&aoStorage); + + if (aoStorage != (atomicord32)1) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomic_DecrementNoResult() +{ + bool bResult = false; + + do + { + volatile atomicord32 aoStorage = (atomicord32)1; + + AtomicDecrementNoResult(&aoStorage); + + if (aoStorage != (atomicord32)0) + { + break; + } + + AtomicDecrementNoResult(&aoStorage); + + if (aoStorage != (atomicord32)(-1)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomic_Exchange() +{ + bool bResult = false; + + do + { + volatile atomicord32 aoStorage = 0; + + if (AtomicExchange(&aoStorage, (atomicord32)1) != 0 || aoStorage != (atomicord32)1) + { + break; + } + + if (AtomicExchange(&aoStorage, (atomicord32)(-1)) != (atomicord32)1 || aoStorage != (atomicord32)(-1)) + { + break; + } + + if (AtomicExchange(&aoStorage, 0) != (atomicord32)(-1) || aoStorage != 0) + { + break; + } + + if (AtomicExchange(&aoStorage, 0) != 0 || aoStorage != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; + +} + +bool TestAtomic_ExchangeAdd() +{ + bool bResult = false; + + do + { + volatile atomicord32 aoStorage = 0; + + if (AtomicExchangeAdd(&aoStorage, (atomicord32)1) != 0 || aoStorage != (atomicord32)1) + { + break; + } + + if (AtomicExchangeAdd(&aoStorage, (atomicord32)(-2)) != 1 || aoStorage != (atomicord32)(-1)) + { + break; + } + + if (AtomicExchangeAdd(&aoStorage, (atomicord32)1) != (atomicord32)(-1) || aoStorage != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomic_ExchangeAddNoResult() +{ + bool bResult = false; + + do + { + volatile atomicord32 aoStorage = 0; + + AtomicExchangeAddNoResult(&aoStorage, (atomicord32)1); + + if (aoStorage != (atomicord32)1) + { + break; + } + + AtomicExchangeAddNoResult(&aoStorage, (atomicord32)(-2)); + + if (aoStorage != (atomicord32)(-1)) + { + break; + } + + AtomicExchangeAddNoResult(&aoStorage, (atomicord32)1); + + if (aoStorage != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomic_CompareExchange() +{ + bool bResult = false; + + do + { + volatile atomicord32 aoStorage = 0; + + if (AtomicCompareExchange(&aoStorage, 1, 1) || aoStorage != 0) + { + break; + } + + if (!AtomicCompareExchange(&aoStorage, 0, 1) || aoStorage != 1) + { + break; + } + + if (!AtomicCompareExchange(&aoStorage, 1, 1) || aoStorage != 1) + { + break; + } + + if (!AtomicCompareExchange(&aoStorage, 1, (atomicord32)(-1)) || aoStorage != (atomicord32)(-1)) + { + break; + } + + if (AtomicCompareExchange(&aoStorage, 1, (atomicord32)(-1)) || aoStorage != (atomicord32)(-1)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +const atomicord32 g_aoBitmask = (atomicord32)(OU_INT32_MIN + 1); + +bool TestAtomic_And() +{ + bool bResult = false; + + do + { + volatile atomicord32 aoStorage = (atomicord32)OU_UINT32_MAX; + + if (AtomicAnd(&aoStorage, g_aoBitmask) != (atomicord32)OU_UINT32_MAX || aoStorage != g_aoBitmask) + { + break; + } + + if (AtomicAnd(&aoStorage, 0) != g_aoBitmask || aoStorage != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomic_Or() +{ + bool bResult = false; + + do + { + volatile atomicord32 aoStorage = 0; + + if (AtomicOr(&aoStorage, g_aoBitmask) != 0 || aoStorage != g_aoBitmask) + { + break; + } + + if (AtomicOr(&aoStorage, (atomicord32)OU_UINT32_MAX) != g_aoBitmask || aoStorage != (atomicord32)OU_UINT32_MAX) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomic_Xor() +{ + bool bResult = false; + + do + { + volatile atomicord32 aoStorage = 0; + + if (AtomicXor(&aoStorage, g_aoBitmask) != 0 || aoStorage != g_aoBitmask) + { + break; + } + + if (AtomicXor(&aoStorage, (atomicord32)OU_UINT32_MAX) != g_aoBitmask || aoStorage != (atomicord32)(OU_UINT32_MAX ^ g_aoBitmask)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomic_AndNoResult() +{ + bool bResult = false; + + do + { + volatile atomicord32 aoStorage = (atomicord32)OU_UINT32_MAX; + + AtomicAndNoResult(&aoStorage, g_aoBitmask); + + if (aoStorage != g_aoBitmask) + { + break; + } + + AtomicAndNoResult(&aoStorage, 0); + + if (aoStorage != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomic_OrNoResult() +{ + bool bResult = false; + + do + { + volatile atomicord32 aoStorage = 0; + + AtomicOrNoResult(&aoStorage, g_aoBitmask); + + if (aoStorage != g_aoBitmask) + { + break; + } + + AtomicOrNoResult(&aoStorage, (atomicord32)OU_UINT32_MAX); + + if (aoStorage != (atomicord32)OU_UINT32_MAX) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomic_XorNoResult() +{ + bool bResult = false; + + do + { + volatile atomicord32 aoStorage = 0; + + AtomicXorNoResult(&aoStorage, g_aoBitmask); + + if (aoStorage != g_aoBitmask) + { + break; + } + + AtomicXorNoResult(&aoStorage, (atomicord32)OU_UINT32_MAX); + + if (aoStorage != (atomicord32)(OU_UINT32_MAX ^ g_aoBitmask)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomic_ExchangePointer() +{ + bool bResult = false; + + do + { + volatile atomicptr apStorage = NULL; + + if (AtomicExchangePointer(&apStorage, (atomicptr)(&TestAtomic_ExchangePointer)) != NULL || apStorage != (atomicptr)(&TestAtomic_ExchangePointer)) + { + break; + } + + if (AtomicExchangePointer(&apStorage, (atomicptr)(&apStorage)) != (atomicptr)(&TestAtomic_ExchangePointer) || apStorage != (atomicptr)(&apStorage)) + { + break; + } + + if (AtomicExchangePointer(&apStorage, NULL) != (atomicptr)(&apStorage) || apStorage != NULL) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomic_CompareExchangePointer() +{ + bool bResult = false; + + do + { + volatile atomicptr apStorage = NULL; + + if (AtomicCompareExchangePointer(&apStorage, (atomicptr)(&TestAtomic_CompareExchangePointer), (atomicptr)(&TestAtomic_CompareExchangePointer)) || apStorage != NULL) + { + break; + } + + if (!AtomicCompareExchangePointer(&apStorage, NULL, (atomicptr)(&TestAtomic_CompareExchangePointer)) || apStorage != (atomicptr)(&TestAtomic_CompareExchangePointer)) + { + break; + } + + if (!AtomicCompareExchangePointer(&apStorage, (atomicptr)(&TestAtomic_CompareExchangePointer), (atomicptr)(&apStorage)) || apStorage != (atomicptr)(&apStorage)) + { + break; + } + + if (!AtomicCompareExchangePointer(&apStorage, (atomicptr)(&apStorage), (atomicptr)(&apStorage)) || apStorage != (atomicptr)(&apStorage)) + { + break; + } + + if (AtomicCompareExchangePointer(&apStorage, NULL, NULL) || apStorage != (atomicptr)(&apStorage)) + { + break; + } + + if (!AtomicCompareExchangePointer(&apStorage, (atomicptr)(&apStorage), NULL) || apStorage != NULL) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + + +enum EOUATOMICFEATURE +{ + OOF__MIN, + + OOF_INCREMENT = OOF__MIN, + OOF_DECREMENT, + OOF_INCREMENTNORESULT, + OOF_DECREMENTNORESULT, + OOF_EXCHANGE, + OOF_EXCHANGEADD, + OOF_EXCHANGEADDNORESULT, + OOF_COMPAREEXCHANGE, + OOF_AND, + OOF_OR, + OOF_XOR, + OOF_ANDNORESULT, + OOF_ORNORESULT, + OOF_XORNORESULT, + OOF_EXCHANGEPOINTER, + OOF_COMPAREEXCHANGEPOINTER, + + OOF__MAX, +}; + +template<> +CFeatureTestProcedure const CEnumUnsortedElementArray<EOUATOMICFEATURE, OOF__MAX, CFeatureTestProcedure>::m_aetElementArray[] = +{ + &TestAtomic_Increment, // OOF_INCREMENT, + &TestAtomic_Decrement, // OOF_DECREMENT, + &TestAtomic_IncrementNoResult, // OOF_INCREMENTNORESULT, + &TestAtomic_DecrementNoResult, // OOF_DECREMENTNORESULT, + &TestAtomic_Exchange, // OOF_EXCHANGE, + &TestAtomic_ExchangeAdd, // OOF_EXCHANGEADD, + &TestAtomic_ExchangeAddNoResult, // OOF_EXCHANGEADDNORESULT, + &TestAtomic_CompareExchange, // OOF_COMPAREEXCHANGE, + &TestAtomic_And, // OOF_AND, + &TestAtomic_Or, // OOF_OR, + &TestAtomic_Xor, // OOF_XOR, + &TestAtomic_AndNoResult, // OOF_ANDNORESULT, + &TestAtomic_OrNoResult, // OOF_ORNORESULT, + &TestAtomic_XorNoResult, // OOF_XORNORESULT, + &TestAtomic_ExchangePointer, // OOF_EXCHANGEPOINTER, + &TestAtomic_CompareExchangePointer, // OOF_COMPAREEXCHANGEPOINTER, +}; +static const CEnumUnsortedElementArray<EOUATOMICFEATURE, OOF__MAX, CFeatureTestProcedure> g_afnAtomicFeatureTestProcedures; + +template<> +const char *const CEnumUnsortedElementArray<EOUATOMICFEATURE, OOF__MAX, const char *>::m_aetElementArray[] = +{ + "AtomicIncrement", // OOF_INCREMENT, + "AtomicDecrement", // OOF_DECREMENT, + "AtomicIncrementNoResult", // OOF_INCREMENTNORESULT, + "AtomicDecrementNoResult", // OOF_DECREMENTNORESULT, + "AtomicExchange", // OOF_EXCHANGE, + "AtomicExchangeAdd", // OOF_EXCHANGEADD, + "AtomicExchangeAddNoResult", // OOF_EXCHANGEADDNORESULT, + "AtomicCompareExchange", // OOF_COMPAREEXCHANGE, + "AtomicAnd", // OOF_AND, + "AtomicOr", // OOF_OR, + "AtomicXor", // OOF_XOR, + "AtomicAndNoResult", // OOF_ANDNORESULT, + "AtomicOrNoResult", // OOF_ORNORESULT, + "AtomicXorNoResult", // OOF_XORNORESULT, + "AtomicExchangePointer", // OOF_EXCHANGEPOINTER, + "AtomicCompareExchangePointer", // OOF_COMPAREEXCHANGEPOINTER, +}; +static const CEnumUnsortedElementArray<EOUATOMICFEATURE, OOF__MAX, const char *> g_aszAtomicFeatureTestNames; + + +bool TestAtomic(unsigned int &nOutSuccessCount, unsigned int &nOutTestCount) +{ + bool bResult = false; + nOutSuccessCount = 0; + nOutTestCount = OOF__MAX; + + bool bAPIInitialized = false; + + do + { + if (!InitializeAtomicAPI()) + { + break; + } + + bAPIInitialized = true; + + if (!TestSubsystem(nOutSuccessCount, nOutTestCount, OOF__MAX, g_aszAtomicFeatureTestNames.GetStoragePointer(), g_afnAtomicFeatureTestProcedures.GetStoragePointer())) + { + break; + } + + bResult = true; + } + while (false); + + if (bAPIInitialized) + { + FinalizeAtomicAPI(); + } + + return bResult; +} + + +#endif // #if _OU_FEATURE_SET >= _OU_FEATURE_SET_ATOMICS + + +////////////////////////////////////////////////////////////////////////// + +#if _OU_FEATURE_SET >= _OU_FEATURE_SET_ATOMICS + +const atomicord32 g_aoTestValue32 = (atomicord32)0xA5A5A5A5; +const atomicord32 g_aoTestMask32 = (atomicord32)0xC6C6C6C6; +const atomicord32 g_aoTestBit32 = (atomicord32)OU_INT32_MIN; +const atomicord32 g_aoTestAnotherBit32 = (atomicord32)((uint32ou)OU_INT32_MIN >> 1); + + +bool TestAtomicFlags_Constructors() +{ + bool bResult = false; + + do + { + if (sizeof(CAtomicFlags::value_type) != sizeof(atomicord32)) + { + break; + } + + CAtomicFlags afEmptyFlags; + + if (afEmptyFlags.QueryFlagsAllValues()) + { + break; + } + + CAtomicFlags afFullFlags(OU_UINT32_MAX); + + if (afFullFlags.QueryFlagsAllValues() != (atomicord32)OU_UINT32_MAX) + { + break; + } + + CAtomicFlags afCopyOfFullFlags(afFullFlags); + + if (afCopyOfFullFlags.QueryFlagsAllValues() != (atomicord32)OU_UINT32_MAX) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomicFlags_AssignFlagsAllValues() +{ + bool bResult = false; + + do + { + CAtomicFlags afTestFlags; + + afTestFlags.AssignFlagsAllValues(OU_UINT32_MAX); + + if (afTestFlags.QueryFlagsAllValues() != (atomicord32)OU_UINT32_MAX) + { + break; + } + + afTestFlags.AssignFlagsAllValues(0); + + if (afTestFlags.QueryFlagsAllValues() != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomicFlags_QueryFlagsAllValues() +{ + bool bResult = false; + + do + { + CAtomicFlags afTestFlags(g_aoTestValue32); + + if (afTestFlags.QueryFlagsAllValues() != g_aoTestValue32) + { + break; + } + + // Double check to be sure ;-) + if (afTestFlags.QueryFlagsAllValues() != g_aoTestValue32) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomicFlags_SetFlagsMaskValue() +{ + bool bResult = false; + + do + { + CAtomicFlags afTestFlags(g_aoTestValue32); + + afTestFlags.SetFlagsMaskValue(g_aoTestMask32, true); + + if (afTestFlags.QueryFlagsAllValues() != (atomicord32)(g_aoTestValue32 | g_aoTestMask32)) + { + break; + } + + afTestFlags.SetFlagsMaskValue(g_aoTestValue32, false); + + if (afTestFlags.QueryFlagsAllValues() != (atomicord32)(~g_aoTestValue32 & g_aoTestMask32)) + { + break; + } + + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomicFlags_SignalFlagsMaskValue() +{ + bool bResult = false; + + do + { + CAtomicFlags afTestFlags(g_aoTestValue32); + + afTestFlags.SignalFlagsMaskValue(g_aoTestMask32); + + if (afTestFlags.QueryFlagsAllValues() != (atomicord32)(g_aoTestValue32 | g_aoTestMask32)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomicFlags_DropFlagsMaskValue() +{ + bool bResult = false; + + do + { + CAtomicFlags afTestFlags(g_aoTestValue32); + + afTestFlags.DropFlagsMaskValue(g_aoTestMask32); + + if (afTestFlags.QueryFlagsAllValues() != (atomicord32)(g_aoTestValue32 & ~g_aoTestMask32)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomicFlags_ToggleSingleFlagValue() +{ + bool bResult = false; + + do + { + CAtomicFlags afTestFlags(g_aoTestValue32); + + bool bPreviousValue = afTestFlags.ToggleSingleFlagValue(g_aoTestBit32); + + if (bPreviousValue != ((g_aoTestValue32 & g_aoTestBit32) != 0) || afTestFlags.QueryFlagsAllValues() != (atomicord32)(g_aoTestValue32 ^ g_aoTestBit32)) + { + break; + } + + bool bAnotherPreviousValue = afTestFlags.ToggleSingleFlagValue(g_aoTestBit32); + + if (bAnotherPreviousValue == bPreviousValue || afTestFlags.QueryFlagsAllValues() != g_aoTestValue32) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomicFlags_ModifySingleFlagValue() +{ + bool bResult = false; + + do + { + CAtomicFlags afTestFlags(g_aoTestValue32); + + bool bFirstModification = afTestFlags.ModifySingleFlagValue(g_aoTestBit32, true); + + if (bFirstModification != ((g_aoTestValue32 & g_aoTestBit32) != g_aoTestBit32) || afTestFlags.QueryFlagsAllValues() != (atomicord32)(g_aoTestValue32 | g_aoTestBit32)) + { + break; + } + + bool bAnotherModification = afTestFlags.ModifySingleFlagValue(g_aoTestBit32, bFirstModification); + + if (bAnotherModification == bFirstModification || afTestFlags.QueryFlagsAllValues() != (bFirstModification ? (atomicord32)(g_aoTestValue32 | g_aoTestBit32) : (atomicord32)(g_aoTestValue32 & ~g_aoTestBit32))) + { + break; + } + + bool bYetAnotherModification = afTestFlags.ModifySingleFlagValue(g_aoTestBit32, bAnotherModification); + + if (bYetAnotherModification != bAnotherModification || afTestFlags.QueryFlagsAllValues() != (bAnotherModification ? (atomicord32)(g_aoTestValue32 | g_aoTestBit32) : (atomicord32)(g_aoTestValue32 & ~g_aoTestBit32))) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomicFlags_AssignFlagsByMask() +{ + bool bResult = false; + + do + { + CAtomicFlags afTestFlags(g_aoTestValue32); + + atomicord32 aoPreviousFlags = afTestFlags.AssignFlagsByMask(g_aoTestMask32, g_aoTestMask32); + + const atomicord32 aoNewFlags = (g_aoTestValue32 & ~g_aoTestMask32) | g_aoTestMask32; + + if (aoPreviousFlags != g_aoTestValue32 || afTestFlags.QueryFlagsAllValues() != aoNewFlags) + { + break; + } + + atomicord32 aoAnotherPreviousFlags = afTestFlags.AssignFlagsByMask(g_aoTestValue32, 0); + + const atomicord32 aoAnotherNewFlags = aoNewFlags & ~g_aoTestValue32; + + if (aoAnotherPreviousFlags != aoNewFlags || afTestFlags.QueryFlagsAllValues() != aoAnotherNewFlags) + { + break; + } + + atomicord32 aoYetAnotherPreviousFlags = afTestFlags.AssignFlagsByMask(g_aoTestMask32, g_aoTestMask32 & g_aoTestValue32); + OU_ASSERT((g_aoTestMask32 & g_aoTestValue32) != 0); // Test degeneration + + const atomicord32 aoYetAnotherNewFlags = (aoAnotherNewFlags & ~g_aoTestMask32) | (g_aoTestMask32 & g_aoTestValue32); + OU_ASSERT(aoYetAnotherNewFlags != (atomicord32)OU_UINT32_MAX); // Test degeneration + + if (aoYetAnotherPreviousFlags != aoAnotherNewFlags || afTestFlags.QueryFlagsAllValues() != aoYetAnotherNewFlags) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomicFlags_AlterFlagsByMask() +{ + bool bResult = false; + + do + { + CAtomicFlags afTestFlags(g_aoTestValue32); + + bool bWasModification = afTestFlags.AlterFlagsByMask(g_aoTestMask32, g_aoTestMask32); + + const atomicord32 aoNewFlags = (g_aoTestValue32 & ~g_aoTestMask32) | g_aoTestMask32; + + if (bWasModification != ((g_aoTestValue32 & g_aoTestMask32) != g_aoTestMask32) || afTestFlags.QueryFlagsAllValues() != aoNewFlags) + { + break; + } + + bool bWasAnotherModification = afTestFlags.AlterFlagsByMask(g_aoTestValue32, 0); + + const atomicord32 aoAnotherNewFlags = aoNewFlags & ~g_aoTestValue32; + + if (bWasAnotherModification != ((aoNewFlags & g_aoTestValue32) != 0) || afTestFlags.QueryFlagsAllValues() != aoAnotherNewFlags) + { + break; + } + + bool bWasAnotherModificationRepeated = afTestFlags.AlterFlagsByMask(g_aoTestValue32, 0); + + if (bWasAnotherModificationRepeated || afTestFlags.QueryFlagsAllValues() != aoAnotherNewFlags) + { + break; + } + + bool bWasYetAnotherModification = afTestFlags.AlterFlagsByMask(g_aoTestMask32, g_aoTestMask32 & g_aoTestValue32); + OU_ASSERT((g_aoTestMask32 & g_aoTestValue32) != 0); // Test degeneration + + const atomicord32 aoYetAnotherNewFlags = (aoAnotherNewFlags & ~g_aoTestMask32) | (g_aoTestMask32 & g_aoTestValue32); + OU_ASSERT(aoYetAnotherNewFlags != (atomicord32)OU_UINT32_MAX); // Test degeneration + + if (bWasYetAnotherModification != ((aoAnotherNewFlags & g_aoTestMask32) != (g_aoTestMask32 & g_aoTestValue32)) || afTestFlags.QueryFlagsAllValues() != aoYetAnotherNewFlags) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomicFlags_GetFlagsMaskValue() +{ + bool bResult = false; + + do + { + CAtomicFlags afTestFlags(g_aoTestValue32); + + if (afTestFlags.GetFlagsMaskValue(g_aoTestMask32) != ((g_aoTestValue32 & g_aoTestMask32) != 0)) + { + break; + } + + if (afTestFlags.GetFlagsMaskValue(~g_aoTestValue32)) + { + break; + } + + if (!afTestFlags.GetFlagsMaskValue(OU_UINT32_MAX)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomicFlags_QueryFlagsByMask() +{ + bool bResult = false; + + do + { + CAtomicFlags afTestFlags(g_aoTestValue32); + + if (afTestFlags.QueryFlagsByMask(g_aoTestMask32) != (atomicord32)(g_aoTestValue32 & g_aoTestMask32)) + { + break; + } + + if (afTestFlags.QueryFlagsByMask(0)) + { + break; + } + + if (afTestFlags.QueryFlagsByMask(OU_UINT32_MAX) != g_aoTestValue32) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomicFlags_OnlySignalSingleFlagOutOfMask() +{ + bool bResult = false; + + do + { + CAtomicFlags afTestFlags(g_aoTestValue32); + OU_ASSERT(g_aoTestValue32 != 0); // Test degeneration + + if (afTestFlags.OnlySignalSingleFlagOutOfMask(OU_UINT32_MAX, g_aoTestBit32)) + { + break; + } + + if (afTestFlags.QueryFlagsAllValues() != g_aoTestValue32) + { + break; + } + + afTestFlags.AssignFlagsAllValues(0); + + if (!afTestFlags.OnlySignalSingleFlagOutOfMask(g_aoTestBit32, g_aoTestBit32)) + { + break; + } + + if (afTestFlags.QueryFlagsAllValues() != g_aoTestBit32) + { + break; + } + + if (afTestFlags.OnlySignalSingleFlagOutOfMask(g_aoTestBit32, g_aoTestBit32)) + { + break; + } + + if (afTestFlags.QueryFlagsAllValues() != g_aoTestBit32) + { + break; + } + + if (afTestFlags.OnlySignalSingleFlagOutOfMask(OU_UINT32_MAX, g_aoTestAnotherBit32)) + { + break; + } + + if (afTestFlags.QueryFlagsAllValues() != g_aoTestBit32) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomicFlags_EnumSetEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CAtomicFlags afTestFlags; + + afTestFlags.EnumSetEnumeratedFlagValue(1, 0, OU_UINT32_BITS, true); + + if (afTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + afTestFlags.EnumSetEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS, true); + + if (afTestFlags.QueryFlagsAllValues() != (atomicord32)(OU_INT32_MIN + 1)) + { + break; + } + + afTestFlags.EnumSetEnumeratedFlagValue(1, 0, OU_UINT32_BITS, false); + + if (afTestFlags.QueryFlagsAllValues() != (atomicord32)OU_INT32_MIN) + { + break; + } + + afTestFlags.EnumSetEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS, false); + + if (afTestFlags.QueryFlagsAllValues() != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomicFlags_EnumSignalEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CAtomicFlags afTestFlags; + + afTestFlags.EnumSignalEnumeratedFlagValue(1, 0, OU_UINT32_BITS); + + if (afTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + afTestFlags.EnumSignalEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS); + + if (afTestFlags.QueryFlagsAllValues() != (atomicord32)(OU_INT32_MIN + 1)) + { + break; + } + + afTestFlags.EnumSignalEnumeratedFlagValue(1, 0, OU_UINT32_BITS); + + if (afTestFlags.QueryFlagsAllValues() != (atomicord32)(OU_INT32_MIN + 1)) + { + break; + } + + afTestFlags.EnumSignalEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS); + + if (afTestFlags.QueryFlagsAllValues() != (atomicord32)(OU_INT32_MIN + 1)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomicFlags_EnumDropEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CAtomicFlags afTestFlags(OU_UINT32_MAX); + + afTestFlags.EnumDropEnumeratedFlagValue(1, 0, OU_UINT32_BITS); + + if (afTestFlags.QueryFlagsAllValues() != (atomicord32)(OU_UINT32_MAX ^ 1)) + { + break; + } + + afTestFlags.EnumDropEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS); + + if (afTestFlags.QueryFlagsAllValues() != (atomicord32)~(OU_INT32_MIN + 1)) + { + break; + } + + afTestFlags.EnumDropEnumeratedFlagValue(1, 0, OU_UINT32_BITS); + + if (afTestFlags.QueryFlagsAllValues() != (atomicord32)~(OU_INT32_MIN + 1)) + { + break; + } + + afTestFlags.EnumDropEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS); + + if (afTestFlags.QueryFlagsAllValues() != (atomicord32)~(OU_INT32_MIN + 1)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomicFlags_EnumToggleEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CAtomicFlags afTestFlags; + + bool bToggleFirstResult = afTestFlags.EnumToggleEnumeratedFlagValue(1, 0, OU_UINT32_BITS); + + if (bToggleFirstResult || afTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bToggleSecondResult = afTestFlags.EnumToggleEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS); + + if (bToggleSecondResult || afTestFlags.QueryFlagsAllValues() != (atomicord32)(OU_INT32_MIN + 1)) + { + break; + } + + bool bToggleThirdResult = afTestFlags.EnumToggleEnumeratedFlagValue(1, 0, OU_UINT32_BITS); + + if (!bToggleThirdResult || afTestFlags.QueryFlagsAllValues() != (atomicord32)OU_INT32_MIN) + { + break; + } + + bool bToggleFourthResult = afTestFlags.EnumToggleEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS); + + if (!bToggleFourthResult || afTestFlags.QueryFlagsAllValues() != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomicFlags_EnumModifyEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CAtomicFlags afTestFlags; + + bool bModifyFirstResult = afTestFlags.EnumModifyEnumeratedFlagValue(1, 0, OU_UINT32_BITS, true); + + if (!bModifyFirstResult || afTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bModifySecondResult = afTestFlags.EnumModifyEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS, true); + + if (!bModifySecondResult || afTestFlags.QueryFlagsAllValues() != (atomicord32)(OU_INT32_MIN + 1)) + { + break; + } + + bool bModifyThirdResult = afTestFlags.EnumModifyEnumeratedFlagValue(1, 0, OU_UINT32_BITS, true); + + if (bModifyThirdResult || afTestFlags.QueryFlagsAllValues() != (atomicord32)(OU_INT32_MIN + 1)) + { + break; + } + + bool bModifyFourthResult = afTestFlags.EnumModifyEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS, true); + + if (bModifyFourthResult || afTestFlags.QueryFlagsAllValues() != (atomicord32)(OU_INT32_MIN + 1)) + { + break; + } + + bool bModifyFifthResult = afTestFlags.EnumModifyEnumeratedFlagValue(1, 0, OU_UINT32_BITS, false); + + if (!bModifyFifthResult || afTestFlags.QueryFlagsAllValues() != (atomicord32)OU_INT32_MIN) + { + break; + } + + bool bModifySixthResult = afTestFlags.EnumModifyEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS, false); + + if (!bModifySixthResult || afTestFlags.QueryFlagsAllValues() != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomicFlags_EnumSignalFirstEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CAtomicFlags afTestFlags; + + bool bFirstResult = afTestFlags.EnumSignalFirstEnumeratedFlagValue(1, 0, OU_UINT32_BITS); + + if (!bFirstResult || afTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bSecondResult = afTestFlags.EnumSignalFirstEnumeratedFlagValue(1, 0, OU_UINT32_BITS); + + if (bSecondResult || afTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bThirdResult = afTestFlags.EnumSignalFirstEnumeratedFlagValue(2, 0, OU_UINT32_BITS - 1); + + if (!bThirdResult || afTestFlags.QueryFlagsAllValues() != 3) + { + break; + } + + bool bFourthResult = afTestFlags.EnumSignalFirstEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS); + + if (bFourthResult || afTestFlags.QueryFlagsAllValues() != (atomicord32)(OU_INT32_MIN + 3)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomicFlags_EnumSignalLastEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CAtomicFlags afTestFlags; + + bool bFirstResult = afTestFlags.EnumSignalLastEnumeratedFlagValue(1, 0, 1); + + if (!bFirstResult || afTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bSecondResult = afTestFlags.EnumSignalLastEnumeratedFlagValue(1, 0, 1); + + if (bSecondResult || afTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bThirdResult = afTestFlags.EnumSignalLastEnumeratedFlagValue(1, 1, 2); + + if (!bThirdResult || afTestFlags.QueryFlagsAllValues() != 3) + { + break; + } + + bool bFourthResult = afTestFlags.EnumSignalLastEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS); + + if (bFourthResult || afTestFlags.QueryFlagsAllValues() != (atomicord32)(OU_INT32_MIN + 3)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomicFlags_EnumGetEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CAtomicFlags afTestFlags((atomicord32)(OU_INT32_MIN + 1)); + + if (!afTestFlags.EnumGetEnumeratedFlagValue(1, 0, OU_UINT32_BITS)) + { + break; + } + + if (afTestFlags.EnumGetEnumeratedFlagValue(2, 0, OU_UINT32_BITS - 1)) + { + break; + } + + if (afTestFlags.EnumGetEnumeratedFlagValue(1, 1, OU_UINT32_BITS - 1)) + { + break; + } + + if (!afTestFlags.EnumGetEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomicFlags_EnumFindFirstEnumeratedFlag() +{ + bool bResult = false; + + do + { + CAtomicFlags afTestFlags((atomicord32)(OU_INT32_MIN + 1)); + + unsigned int uiFirstResult = afTestFlags.EnumFindFirstEnumeratedFlag(1, OU_UINT32_BITS); + if (uiFirstResult != 0) + { + break; + } + + unsigned int uiSecondResult = afTestFlags.EnumFindFirstEnumeratedFlag(2, OU_UINT32_BITS - 1); + if (uiSecondResult != OU_UINT32_BITS - 2) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomicFlags_EnumAllSignalEnumeratedFlags() +{ + bool bResult = false; + + do + { + CAtomicFlags afTestFlags; + + afTestFlags.EnumAllSignalEnumeratedFlags(1, 1); + + if (afTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + afTestFlags.EnumAllSignalEnumeratedFlags(4, OU_UINT32_BITS - 2); + + if (afTestFlags.QueryFlagsAllValues() != (atomicord32)(OU_UINT32_MAX ^ 2)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomicFlags_EnumAllDropEnumeratedFlags() +{ + bool bResult = false; + + do + { + CAtomicFlags afTestFlags(OU_UINT32_MAX); + + afTestFlags.EnumAllDropEnumeratedFlags(1, 1); + + if (afTestFlags.QueryFlagsAllValues() != (atomicord32)(OU_UINT32_MAX ^ 1)) + { + break; + } + + afTestFlags.EnumAllDropEnumeratedFlags(4, OU_UINT32_BITS - 2); + + if (afTestFlags.QueryFlagsAllValues() != 2) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomicFlags_EnumAllQueryEnumeratedFlags() +{ + bool bResult = false; + + do + { + CAtomicFlags afTestFlags((atomicord32)(OU_INT32_MIN + 1)); + + atomicord32 aoFirstResult = afTestFlags.EnumAllQueryEnumeratedFlags(1, OU_UINT32_BITS); + if (aoFirstResult != (atomicord32)(OU_INT32_MIN + 1)) + { + break; + } + + atomicord32 aoSecondResult = afTestFlags.EnumAllQueryEnumeratedFlags(2, OU_UINT32_BITS - 1); + if (aoSecondResult != (atomicord32)(OU_INT32_MIN)) + { + break; + } + + atomicord32 aoThirdResult = afTestFlags.EnumAllQueryEnumeratedFlags(2, OU_UINT32_BITS - 2); + if (aoThirdResult != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomicFlags_EnumAnyGetEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CAtomicFlags afTestFlags((atomicord32)(OU_INT32_MIN + 1)); + + bool bFirstResult = afTestFlags.EnumAnyGetEnumeratedFlagValue(1, OU_UINT32_BITS); + if (!bFirstResult) + { + break; + } + + bool bSecondResult = afTestFlags.EnumAnyGetEnumeratedFlagValue(2, OU_UINT32_BITS - 1); + if (!bSecondResult) + { + break; + } + + bool bThirdResult = afTestFlags.EnumAnyGetEnumeratedFlagValue(2, OU_UINT32_BITS - 2); + if (bThirdResult) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomicFlags_StoreFlagsEnumeratedValue() +{ + bool bResult = false; + + do + { + CAtomicFlags afTestFlags; + + afTestFlags.StoreFlagsEnumeratedValue(0x03, 1, 2); + + if (afTestFlags.QueryFlagsAllValues() != (atomicord32)(2 << 1)) + { + break; + } + + afTestFlags.StoreFlagsEnumeratedValue(0x03, OU_UINT32_BITS - 2, 3); + + if (afTestFlags.QueryFlagsAllValues() != ((atomicord32)(2 << 1) | (atomicord32)(OU_INT32_MIN | (OU_INT32_MIN >> 1)))) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestAtomicFlags_RetrieveFlagsEnumeratedValue() +{ + bool bResult = false; + + do + { + CAtomicFlags afTestFlags((atomicord32)(OU_INT32_MIN + 1)); + + unsigned int aoFirstResult = afTestFlags.RetrieveFlagsEnumeratedValue(0x3, 1); + if (aoFirstResult != 0) + { + break; + } + + unsigned int aoSecondResult = afTestFlags.RetrieveFlagsEnumeratedValue(0x3, OU_UINT32_BITS - 2); + if (aoSecondResult != 2) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + + +enum EOUATOMICFLAGSFEATURE +{ + OAF__MIN, + + OAF_CONSTRUCTORS = OAF__MIN, + OAF_ASSIGNFLAGSALLVALUES, + OAF_QUERYFLAGSALLVALUES, + OAF_SETFLAGSMASKVALUE, + OAF_SIGNALFLAGSMASKVALUE, + OAF_DROPFLAGSMASKVALUE, + OAF_TOGGLESINGLEFLAGVALUE, + OAF_MODIFYSINGLEFLAGVALUE, + OAF_ASSIGNFLAGSBYMASK, + OAF_ALTERFLAGSBYMASK, + OAF_GETFLAGSMASKVALUE, + OAF_QUERYFLAGSBYMASK, + OAF_ONLYSIGNALSINGLEFLAGOUTOFMASK, + OAF_ENUMSETENUMERATEDFLAGVALUE, + OAF_ENUMSIGNALENUMERATEDFLAGVALUE, + OAF_ENUMDROPENUMERATEDFLAGVALUE, + OAF_ENUMTOGGLEENUMERATEDFLAGVALUE, + OAF_ENUMMODIFYENUMERATEDFLAGVALUE, + OAF_ENUMSIGNALFIRSTENUMERATEDFLAGVALUE, + OAF_ENUMSIGNALLASTENUMERATEDFLAGVALUE, + OAF_ENUMGETENUMERATEDFLAGVALUE, + OAF_ENUMFINDFIRSTENUMERATEDFLAG, + OAF_ENUMALLSIGNALENUMERATEDFLAGS, + OAF_ENUMALLDROPENUMERATEDFLAGS, + OAF_ENUMALLQUERYENUMERATEDFLAGS, + OAF_ENUMANYGETENUMERATEDFLAGVALUE, + OAF_STOREFLAGSENUMERATEDVALUE, + OAF_RETRIEVEFLAGSENUMERATEDVALUE, + + OAF__MAX, +}; + +template<> +CFeatureTestProcedure const CEnumUnsortedElementArray<EOUATOMICFLAGSFEATURE, OAF__MAX, CFeatureTestProcedure>::m_aetElementArray[] = +{ + &TestAtomicFlags_Constructors, // OAF_CONSTRUCTORS + &TestAtomicFlags_AssignFlagsAllValues, // OAF_ASSIGNFLAGSALLVALUES, + &TestAtomicFlags_QueryFlagsAllValues, // OAF_QUERYFLAGSALLVALUES, + &TestAtomicFlags_SetFlagsMaskValue, // OAF_SETFLAGSMASKVALUE, + &TestAtomicFlags_SignalFlagsMaskValue, // OAF_SIGNALFLAGSMASKVALUE, + &TestAtomicFlags_DropFlagsMaskValue, // OAF_DROPFLAGSMASKVALUE, + &TestAtomicFlags_ToggleSingleFlagValue, // OAF_TOGGLESINGLEFLAGVALUE, + &TestAtomicFlags_ModifySingleFlagValue, // OAF_MODIFYSINGLEFLAGVALUE, + &TestAtomicFlags_AssignFlagsByMask, // OAF_ASSIGNFLAGSBYMASK, + &TestAtomicFlags_AlterFlagsByMask, // OAF_ALTERFLAGSBYMASK, + &TestAtomicFlags_GetFlagsMaskValue, // OAF_GETFLAGSMASKVALUE, + &TestAtomicFlags_QueryFlagsByMask, // OAF_QUERYFLAGSBYMASK, + &TestAtomicFlags_OnlySignalSingleFlagOutOfMask, // OAF_ONLYSIGNALSINGLEFLAGOUTOFMASK, + &TestAtomicFlags_EnumSetEnumeratedFlagValue, // OAF_ENUMSETENUMERATEDFLAGVALUE, + &TestAtomicFlags_EnumSignalEnumeratedFlagValue, // OAF_ENUMSIGNALENUMERATEDFLAGVALUE, + &TestAtomicFlags_EnumDropEnumeratedFlagValue, // OAF_ENUMDROPENUMERATEDFLAGVALUE, + &TestAtomicFlags_EnumToggleEnumeratedFlagValue, // OAF_ENUMTOGGLEENUMERATEDFLAGVALUE, + &TestAtomicFlags_EnumModifyEnumeratedFlagValue, // OAF_ENUMMODIFYENUMERATEDFLAGVALUE, + &TestAtomicFlags_EnumSignalFirstEnumeratedFlagValue, // OAF_ENUMSIGNALFIRSTENUMERATEDFLAGVALUE, + &TestAtomicFlags_EnumSignalLastEnumeratedFlagValue, // OAF_ENUMSIGNALLASTENUMERATEDFLAGVALUE, + &TestAtomicFlags_EnumGetEnumeratedFlagValue, // OAF_ENUMGETENUMERATEDFLAGVALUE, + &TestAtomicFlags_EnumFindFirstEnumeratedFlag, // OAF_ENUMFINDFIRSTENUMERATEDFLAG, + &TestAtomicFlags_EnumAllSignalEnumeratedFlags, // OAF_ENUMALLSIGNALENUMERATEDFLAGS, + &TestAtomicFlags_EnumAllDropEnumeratedFlags, // OAF_ENUMALLDROPENUMERATEDFLAGS, + &TestAtomicFlags_EnumAllQueryEnumeratedFlags, // OAF_ENUMALLQUERYENUMERATEDFLAGS, + &TestAtomicFlags_EnumAnyGetEnumeratedFlagValue, // OAF_ENUMANYGETENUMERATEDFLAGVALUE, + &TestAtomicFlags_StoreFlagsEnumeratedValue, // OAF_STOREFLAGSENUMERATEDVALUE, + &TestAtomicFlags_RetrieveFlagsEnumeratedValue, // OAF_RETRIEVEFLAGSENUMERATEDVALUE, +}; +static const CEnumUnsortedElementArray<EOUATOMICFLAGSFEATURE, OAF__MAX, CFeatureTestProcedure> g_afnAtomicFlagsFeatureTestProcedures; + +template<> +const char *const CEnumUnsortedElementArray<EOUATOMICFLAGSFEATURE, OAF__MAX, const char *>::m_aetElementArray[] = +{ + "Constructors", // OAF_CONSTRUCTORS + "AssignFlagsAllValues", // OAF_ASSIGNFLAGSALLVALUES, + "QueryFlagsAllValues", // OAF_QUERYFLAGSALLVALUES, + "SetFlagsMaskValue", // OAF_SETFLAGSMASKVALUE, + "SignalFlagsMaskValue", // OAF_SIGNALFLAGSMASKVALUE, + "DropFlagsMaskValue", // OAF_DROPFLAGSMASKVALUE, + "ToggleSingleFlagValue", // OAF_TOGGLESINGLEFLAGVALUE, + "ModifySingleFlagValue", // OAF_MODIFYSINGLEFLAGVALUE, + "AssignFlagsByMask", // OAF_ASSIGNFLAGSBYMASK, + "AlterFlagsByMask", // OAF_ALTERFLAGSBYMASK, + "GetFlagsMaskValue", // OAF_GETFLAGSMASKVALUE, + "QueryFlagsByMask", // OAF_QUERYFLAGSBYMASK, + "OnlySignalSingleFlagOutOfMask", // OAF_ONLYSIGNALSINGLEFLAGOUTOFMASK, + "EnumSetEnumeratedFlagValue", // OAF_ENUMSETENUMERATEDFLAGVALUE, + "EnumSignalEnumeratedFlagValue", // OAF_ENUMSIGNALENUMERATEDFLAGVALUE, + "EnumDropEnumeratedFlagValue", // OAF_ENUMDROPENUMERATEDFLAGVALUE, + "EnumToggleEnumeratedFlagValue", // OAF_ENUMTOGGLEENUMERATEDFLAGVALUE, + "EnumModifyEnumeratedFlagValue", // OAF_ENUMMODIFYENUMERATEDFLAGVALUE, + "EnumSignalFirstEnumeratedFlagValue", // OAF_ENUMSIGNALFIRSTENUMERATEDFLAGVALUE, + "EnumSignalLastEnumeratedFlagValue", // OAF_ENUMSIGNALLASTENUMERATEDFLAGVALUE, + "EnumGetEnumeratedFlagValue", // OAF_ENUMGETENUMERATEDFLAGVALUE, + "EnumFindFirstEnumeratedFlag", // OAF_ENUMFINDFIRSTENUMERATEDFLAG, + "EnumAllSignalEnumeratedFlags", // OAF_ENUMALLSIGNALENUMERATEDFLAGS, + "EnumAllDropEnumeratedFlags", // OAF_ENUMALLDROPENUMERATEDFLAGS, + "EnumAllQueryEnumeratedFlags", // OAF_ENUMALLQUERYENUMERATEDFLAGS, + "EnumAnyGetEnumeratedFlagValue", // OAF_ENUMANYGETENUMERATEDFLAGVALUE, + "StoreFlagsEnumeratedValue", // OAF_STOREFLAGSENUMERATEDVALUE, + "RetrieveFlagsEnumeratedValue", // OAF_RETRIEVEFLAGSENUMERATEDVALUE, +}; +static const CEnumUnsortedElementArray<EOUATOMICFLAGSFEATURE, OAF__MAX, const char *> g_aszAtomicFlagsFeatureTestNames; + + +bool TestAtomicFlags(unsigned int &nOutSuccessCount, unsigned int &nOutTestCount) +{ + bool bResult = false; + nOutSuccessCount = 0; + nOutTestCount = OAF__MAX; + + bool bAPIInitialized = false; + + do + { + if (!InitializeAtomicAPI()) + { + break; + } + + bAPIInitialized = true; + + if (!TestSubsystem(nOutSuccessCount, nOutTestCount, OAF__MAX, g_aszAtomicFlagsFeatureTestNames.GetStoragePointer(), g_afnAtomicFlagsFeatureTestProcedures.GetStoragePointer())) + { + break; + } + + bResult = true; + } + while (false); + + if (bAPIInitialized) + { + FinalizeAtomicAPI(); + } + + return bResult; +} + + +#endif // #if _OU_FEATURE_SET >= _OU_FEATURE_SET_ATOMICS + + +////////////////////////////////////////////////////////////////////////// + +typedef CSimpleFlagsTemplate<uint64ou> CSimpleFlags64; + +const uint64ou g_uiTestValue64 = ((uint64ou)0xA5A5A5A5 << 32) | 0xA5A5A5A5; +const uint64ou g_uiTestMask64 = ((uint64ou)0xC6C6C6C6 << 32) | 0xC6C6C6C6; +const uint64ou g_uiTestBit64 = (uint64ou)OU_INT64_MIN; +const uint64ou g_uiTestAnotherBit64 = (uint64ou)((uint64ou)OU_INT64_MIN >> 1); + + +bool TestSimpleFlags64_Constructors() +{ + bool bResult = false; + + do + { + if (sizeof(CSimpleFlags64::value_type) != sizeof(uint64ou) || sizeof(CSimpleFlags64) != sizeof(uint64ou)) + { + break; + } + + CSimpleFlags64 sfEmptyFlags; + + if (sfEmptyFlags.QueryFlagsAllValues()) + { + break; + } + + CSimpleFlags64 sfFullFlags(OU_UINT64_MAX); + + if (sfFullFlags.QueryFlagsAllValues() != OU_UINT64_MAX) + { + break; + } + + CSimpleFlags64 sfCopyOfFullFlags(sfFullFlags); + + if (sfCopyOfFullFlags.QueryFlagsAllValues() != OU_UINT64_MAX) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags64_AssignFlagsAllValues() +{ + bool bResult = false; + + do + { + CSimpleFlags64 sfTestFlags; + + sfTestFlags.AssignFlagsAllValues(OU_UINT64_MAX); + + if (sfTestFlags.QueryFlagsAllValues() != OU_UINT64_MAX) + { + break; + } + + sfTestFlags.AssignFlagsAllValues(0); + + if (sfTestFlags.QueryFlagsAllValues() != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags64_QueryFlagsAllValues() +{ + bool bResult = false; + + do + { + CSimpleFlags64 sfTestFlags(g_uiTestValue64); + + if (sfTestFlags.QueryFlagsAllValues() != g_uiTestValue64) + { + break; + } + + // Double check to be sure ;-) + if (sfTestFlags.QueryFlagsAllValues() != g_uiTestValue64) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags64_SetFlagsMaskValue() +{ + bool bResult = false; + + do + { + CSimpleFlags64 sfTestFlags(g_uiTestValue64); + + sfTestFlags.SetFlagsMaskValue(g_uiTestMask64, true); + + if (sfTestFlags.QueryFlagsAllValues() != (uint64ou)(g_uiTestValue64 | g_uiTestMask64)) + { + break; + } + + sfTestFlags.SetFlagsMaskValue(g_uiTestValue64, false); + + if (sfTestFlags.QueryFlagsAllValues() != (uint64ou)(~g_uiTestValue64 & g_uiTestMask64)) + { + break; + } + + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags64_SignalFlagsMaskValue() +{ + bool bResult = false; + + do + { + CSimpleFlags64 sfTestFlags(g_uiTestValue64); + + sfTestFlags.SignalFlagsMaskValue(g_uiTestMask64); + + if (sfTestFlags.QueryFlagsAllValues() != (uint64ou)(g_uiTestValue64 | g_uiTestMask64)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags64_DropFlagsMaskValue() +{ + bool bResult = false; + + do + { + CSimpleFlags64 sfTestFlags(g_uiTestValue64); + + sfTestFlags.DropFlagsMaskValue(g_uiTestMask64); + + if (sfTestFlags.QueryFlagsAllValues() != (uint64ou)(g_uiTestValue64 & ~g_uiTestMask64)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags64_ToggleSingleFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags64 sfTestFlags(g_uiTestValue64); + + bool bPreviousValue = sfTestFlags.ToggleSingleFlagValue(g_uiTestBit64); + + if (bPreviousValue != ((g_uiTestValue64 & g_uiTestBit64) != 0) || sfTestFlags.QueryFlagsAllValues() != (uint64ou)(g_uiTestValue64 ^ g_uiTestBit64)) + { + break; + } + + bool bAnotherPreviousValue = sfTestFlags.ToggleSingleFlagValue(g_uiTestBit64); + + if (bAnotherPreviousValue == bPreviousValue || sfTestFlags.QueryFlagsAllValues() != g_uiTestValue64) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags64_ModifySingleFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags64 sfTestFlags(g_uiTestValue64); + + bool bFirstModification = sfTestFlags.ModifySingleFlagValue(g_uiTestBit64, true); + + if (bFirstModification != ((g_uiTestValue64 & g_uiTestBit64) != g_uiTestBit64) || sfTestFlags.QueryFlagsAllValues() != (uint64ou)(g_uiTestValue64 | g_uiTestBit64)) + { + break; + } + + bool bAnotherModification = sfTestFlags.ModifySingleFlagValue(g_uiTestBit64, bFirstModification); + + if (bAnotherModification == bFirstModification || sfTestFlags.QueryFlagsAllValues() != (bFirstModification ? (uint64ou)(g_uiTestValue64 | g_uiTestBit64) : (uint64ou)(g_uiTestValue64 & ~g_uiTestBit64))) + { + break; + } + + bool bYetAnotherModification = sfTestFlags.ModifySingleFlagValue(g_uiTestBit64, bAnotherModification); + + if (bYetAnotherModification != bAnotherModification || sfTestFlags.QueryFlagsAllValues() != (bAnotherModification ? (uint64ou)(g_uiTestValue64 | g_uiTestBit64) : (uint64ou)(g_uiTestValue64 & ~g_uiTestBit64))) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags64_AssignFlagsByMask() +{ + bool bResult = false; + + do + { + CSimpleFlags64 sfTestFlags(g_uiTestValue64); + + uint64ou uiPreviousFlags = sfTestFlags.AssignFlagsByMask(g_uiTestMask64, g_uiTestMask64); + + const uint64ou uiNewFlags = (g_uiTestValue64 & ~g_uiTestMask64) | g_uiTestMask64; + + if (uiPreviousFlags != g_uiTestValue64 || sfTestFlags.QueryFlagsAllValues() != uiNewFlags) + { + break; + } + + uint64ou uiAnotherPreviousFlags = sfTestFlags.AssignFlagsByMask(g_uiTestValue64, 0); + + const uint64ou uiAnotherNewFlags = uiNewFlags & ~g_uiTestValue64; + + if (uiAnotherPreviousFlags != uiNewFlags || sfTestFlags.QueryFlagsAllValues() != uiAnotherNewFlags) + { + break; + } + + uint64ou uiYetAnotherPreviousFlags = sfTestFlags.AssignFlagsByMask(g_uiTestMask64, g_uiTestMask64 & g_uiTestValue64); + OU_ASSERT((g_uiTestMask64 & g_uiTestValue64) != 0); // Test degeneration + + const uint64ou uiYetAnotherNewFlags = (uiAnotherNewFlags & ~g_uiTestMask64) | (g_uiTestMask64 & g_uiTestValue64); + OU_ASSERT(uiYetAnotherNewFlags != OU_UINT64_MAX); // Test degeneration + + if (uiYetAnotherPreviousFlags != uiAnotherNewFlags || sfTestFlags.QueryFlagsAllValues() != uiYetAnotherNewFlags) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags64_AlterFlagsByMask() +{ + bool bResult = false; + + do + { + CSimpleFlags64 sfTestFlags(g_uiTestValue64); + + bool bWasModification = sfTestFlags.AlterFlagsByMask(g_uiTestMask64, g_uiTestMask64); + + const uint64ou uiNewFlags = (g_uiTestValue64 & ~g_uiTestMask64) | g_uiTestMask64; + + if (bWasModification != ((g_uiTestValue64 & g_uiTestMask64) != g_uiTestMask64) || sfTestFlags.QueryFlagsAllValues() != uiNewFlags) + { + break; + } + + bool bWasAnotherModification = sfTestFlags.AlterFlagsByMask(g_uiTestValue64, 0); + + const uint64ou uiAnotherNewFlags = uiNewFlags & ~g_uiTestValue64; + + if (bWasAnotherModification != ((uiNewFlags & g_uiTestValue64) != 0) || sfTestFlags.QueryFlagsAllValues() != uiAnotherNewFlags) + { + break; + } + + bool bWasAnotherModificationRepeated = sfTestFlags.AlterFlagsByMask(g_uiTestValue64, 0); + + if (bWasAnotherModificationRepeated || sfTestFlags.QueryFlagsAllValues() != uiAnotherNewFlags) + { + break; + } + + bool bWasYetAnotherModification = sfTestFlags.AlterFlagsByMask(g_uiTestMask64, g_uiTestMask64 & g_uiTestValue64); + OU_ASSERT((g_uiTestMask64 & g_uiTestValue64) != 0); // Test degeneration + + const uint64ou uiYetAnotherNewFlags = (uiAnotherNewFlags & ~g_uiTestMask64) | (g_uiTestMask64 & g_uiTestValue64); + OU_ASSERT(uiYetAnotherNewFlags != OU_UINT64_MAX); // Test degeneration + + if (bWasYetAnotherModification != ((uiAnotherNewFlags & g_uiTestMask64) != (g_uiTestMask64 & g_uiTestValue64)) || sfTestFlags.QueryFlagsAllValues() != uiYetAnotherNewFlags) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags64_GetFlagsMaskValue() +{ + bool bResult = false; + + do + { + CSimpleFlags64 sfTestFlags(g_uiTestValue64); + + if (sfTestFlags.GetFlagsMaskValue(g_uiTestMask64) != ((g_uiTestValue64 & g_uiTestMask64) != 0)) + { + break; + } + + if (sfTestFlags.GetFlagsMaskValue(~g_uiTestValue64)) + { + break; + } + + if (!sfTestFlags.GetFlagsMaskValue(OU_UINT64_MAX)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags64_QueryFlagsByMask() +{ + bool bResult = false; + + do + { + CSimpleFlags64 sfTestFlags(g_uiTestValue64); + + if (sfTestFlags.QueryFlagsByMask(g_uiTestMask64) != (uint64ou)(g_uiTestValue64 & g_uiTestMask64)) + { + break; + } + + if (sfTestFlags.QueryFlagsByMask(0)) + { + break; + } + + if (sfTestFlags.QueryFlagsByMask(OU_UINT64_MAX) != g_uiTestValue64) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags64_OnlySignalSingleFlagOutOfMask() +{ + bool bResult = false; + + do + { + CSimpleFlags64 sfTestFlags(g_uiTestValue64); + OU_ASSERT(g_uiTestValue64 != 0); // Test degeneration + + if (sfTestFlags.OnlySignalSingleFlagOutOfMask(OU_UINT64_MAX, g_uiTestBit64)) + { + break; + } + + if (sfTestFlags.QueryFlagsAllValues() != g_uiTestValue64) + { + break; + } + + sfTestFlags.AssignFlagsAllValues(0); + + if (!sfTestFlags.OnlySignalSingleFlagOutOfMask(g_uiTestBit64, g_uiTestBit64)) + { + break; + } + + if (sfTestFlags.QueryFlagsAllValues() != g_uiTestBit64) + { + break; + } + + if (sfTestFlags.OnlySignalSingleFlagOutOfMask(g_uiTestBit64, g_uiTestBit64)) + { + break; + } + + if (sfTestFlags.QueryFlagsAllValues() != g_uiTestBit64) + { + break; + } + + if (sfTestFlags.OnlySignalSingleFlagOutOfMask(OU_UINT64_MAX, g_uiTestAnotherBit64)) + { + break; + } + + if (sfTestFlags.QueryFlagsAllValues() != g_uiTestBit64) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags64_EnumSetEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags64 sfTestFlags; + + sfTestFlags.EnumSetEnumeratedFlagValue(1, 0, OU_UINT64_BITS, true); + + if (sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + sfTestFlags.EnumSetEnumeratedFlagValue(1, OU_UINT64_BITS - 1, OU_UINT64_BITS, true); + + if (sfTestFlags.QueryFlagsAllValues() != (uint64ou)(OU_INT64_MIN + 1)) + { + break; + } + + sfTestFlags.EnumSetEnumeratedFlagValue(1, 0, OU_UINT64_BITS, false); + + if (sfTestFlags.QueryFlagsAllValues() != (uint64ou)OU_INT64_MIN) + { + break; + } + + sfTestFlags.EnumSetEnumeratedFlagValue(1, OU_UINT64_BITS - 1, OU_UINT64_BITS, false); + + if (sfTestFlags.QueryFlagsAllValues() != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags64_EnumSignalEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags64 sfTestFlags; + + sfTestFlags.EnumSignalEnumeratedFlagValue(1, 0, OU_UINT64_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + sfTestFlags.EnumSignalEnumeratedFlagValue(1, OU_UINT64_BITS - 1, OU_UINT64_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (uint64ou)(OU_INT64_MIN + 1)) + { + break; + } + + sfTestFlags.EnumSignalEnumeratedFlagValue(1, 0, OU_UINT64_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (uint64ou)(OU_INT64_MIN + 1)) + { + break; + } + + sfTestFlags.EnumSignalEnumeratedFlagValue(1, OU_UINT64_BITS - 1, OU_UINT64_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (uint64ou)(OU_INT64_MIN + 1)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags64_EnumDropEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags64 sfTestFlags(OU_UINT64_MAX); + + sfTestFlags.EnumDropEnumeratedFlagValue(1, 0, OU_UINT64_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (OU_UINT64_MAX ^ 1)) + { + break; + } + + sfTestFlags.EnumDropEnumeratedFlagValue(1, OU_UINT64_BITS - 1, OU_UINT64_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (uint64ou)~(OU_INT64_MIN + 1)) + { + break; + } + + sfTestFlags.EnumDropEnumeratedFlagValue(1, 0, OU_UINT64_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (uint64ou)~(OU_INT64_MIN + 1)) + { + break; + } + + sfTestFlags.EnumDropEnumeratedFlagValue(1, OU_UINT64_BITS - 1, OU_UINT64_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (uint64ou)~(OU_INT64_MIN + 1)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags64_EnumToggleEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags64 sfTestFlags; + + bool bToggleFirstResult = sfTestFlags.EnumToggleEnumeratedFlagValue(1, 0, OU_UINT64_BITS); + + if (bToggleFirstResult || sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bToggleSecondResult = sfTestFlags.EnumToggleEnumeratedFlagValue(1, OU_UINT64_BITS - 1, OU_UINT64_BITS); + + if (bToggleSecondResult || sfTestFlags.QueryFlagsAllValues() != (uint64ou)(OU_INT64_MIN + 1)) + { + break; + } + + bool bToggleThirdResult = sfTestFlags.EnumToggleEnumeratedFlagValue(1, 0, OU_UINT64_BITS); + + if (!bToggleThirdResult || sfTestFlags.QueryFlagsAllValues() != (uint64ou)OU_INT64_MIN) + { + break; + } + + bool bToggleFourthResult = sfTestFlags.EnumToggleEnumeratedFlagValue(1, OU_UINT64_BITS - 1, OU_UINT64_BITS); + + if (!bToggleFourthResult || sfTestFlags.QueryFlagsAllValues() != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags64_EnumModifyEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags64 sfTestFlags; + + bool bModifyFirstResult = sfTestFlags.EnumModifyEnumeratedFlagValue(1, 0, OU_UINT64_BITS, true); + + if (!bModifyFirstResult || sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bModifySecondResult = sfTestFlags.EnumModifyEnumeratedFlagValue(1, OU_UINT64_BITS - 1, OU_UINT64_BITS, true); + + if (!bModifySecondResult || sfTestFlags.QueryFlagsAllValues() != (uint64ou)(OU_INT64_MIN + 1)) + { + break; + } + + bool bModifyThirdResult = sfTestFlags.EnumModifyEnumeratedFlagValue(1, 0, OU_UINT64_BITS, true); + + if (bModifyThirdResult || sfTestFlags.QueryFlagsAllValues() != (uint64ou)(OU_INT64_MIN + 1)) + { + break; + } + + bool bModifyFourthResult = sfTestFlags.EnumModifyEnumeratedFlagValue(1, OU_UINT64_BITS - 1, OU_UINT64_BITS, true); + + if (bModifyFourthResult || sfTestFlags.QueryFlagsAllValues() != (uint64ou)(OU_INT64_MIN + 1)) + { + break; + } + + bool bModifyFifthResult = sfTestFlags.EnumModifyEnumeratedFlagValue(1, 0, OU_UINT64_BITS, false); + + if (!bModifyFifthResult || sfTestFlags.QueryFlagsAllValues() != (uint64ou)OU_INT64_MIN) + { + break; + } + + bool bModifySixthResult = sfTestFlags.EnumModifyEnumeratedFlagValue(1, OU_UINT64_BITS - 1, OU_UINT64_BITS, false); + + if (!bModifySixthResult || sfTestFlags.QueryFlagsAllValues() != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags64_EnumSignalFirstEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags64 sfTestFlags; + + bool bFirstResult = sfTestFlags.EnumSignalFirstEnumeratedFlagValue(1, 0, OU_UINT64_BITS); + + if (!bFirstResult || sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bSecondResult = sfTestFlags.EnumSignalFirstEnumeratedFlagValue(1, 0, OU_UINT64_BITS); + + if (bSecondResult || sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bThirdResult = sfTestFlags.EnumSignalFirstEnumeratedFlagValue(2, 0, OU_UINT64_BITS - 1); + + if (!bThirdResult || sfTestFlags.QueryFlagsAllValues() != 3) + { + break; + } + + bool bFourthResult = sfTestFlags.EnumSignalFirstEnumeratedFlagValue(1, OU_UINT64_BITS - 1, OU_UINT64_BITS); + + if (bFourthResult || sfTestFlags.QueryFlagsAllValues() != (uint64ou)(OU_INT64_MIN + 3)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags64_EnumSignalLastEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags64 sfTestFlags; + + bool bFirstResult = sfTestFlags.EnumSignalLastEnumeratedFlagValue(1, 0, 1); + + if (!bFirstResult || sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bSecondResult = sfTestFlags.EnumSignalLastEnumeratedFlagValue(1, 0, 1); + + if (bSecondResult || sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bThirdResult = sfTestFlags.EnumSignalLastEnumeratedFlagValue(1, 1, 2); + + if (!bThirdResult || sfTestFlags.QueryFlagsAllValues() != 3) + { + break; + } + + bool bFourthResult = sfTestFlags.EnumSignalLastEnumeratedFlagValue(1, OU_UINT64_BITS - 1, OU_UINT64_BITS); + + if (bFourthResult || sfTestFlags.QueryFlagsAllValues() != (uint64ou)(OU_INT64_MIN + 3)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags64_EnumGetEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags64 sfTestFlags((uint64ou)(OU_INT64_MIN + 1)); + + if (!sfTestFlags.EnumGetEnumeratedFlagValue(1, 0, OU_UINT64_BITS)) + { + break; + } + + if (sfTestFlags.EnumGetEnumeratedFlagValue(2, 0, OU_UINT64_BITS - 1)) + { + break; + } + + if (sfTestFlags.EnumGetEnumeratedFlagValue(1, 1, OU_UINT64_BITS - 1)) + { + break; + } + + if (!sfTestFlags.EnumGetEnumeratedFlagValue(1, OU_UINT64_BITS - 1, OU_UINT64_BITS)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags64_EnumFindFirstEnumeratedFlag() +{ + bool bResult = false; + + do + { + CSimpleFlags64 sfTestFlags((uint64ou)(OU_INT64_MIN + 1)); + + unsigned int uiFirstResult = sfTestFlags.EnumFindFirstEnumeratedFlag(1, OU_UINT64_BITS); + if (uiFirstResult != 0) + { + break; + } + + unsigned int uiSecondResult = sfTestFlags.EnumFindFirstEnumeratedFlag(2, OU_UINT64_BITS - 1); + if (uiSecondResult != OU_UINT64_BITS - 2) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags64_EnumAllSignalEnumeratedFlags() +{ + bool bResult = false; + + do + { + CSimpleFlags64 sfTestFlags; + + sfTestFlags.EnumAllSignalEnumeratedFlags(1, 1); + + if (sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + sfTestFlags.EnumAllSignalEnumeratedFlags(4, OU_UINT64_BITS - 2); + + if (sfTestFlags.QueryFlagsAllValues() != (uint64ou)(OU_UINT64_MAX ^ 2)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags64_EnumAllDropEnumeratedFlags() +{ + bool bResult = false; + + do + { + CSimpleFlags64 sfTestFlags(OU_UINT64_MAX); + + sfTestFlags.EnumAllDropEnumeratedFlags(1, 1); + + if (sfTestFlags.QueryFlagsAllValues() != (uint64ou)(OU_UINT64_MAX ^ 1)) + { + break; + } + + sfTestFlags.EnumAllDropEnumeratedFlags(4, OU_UINT64_BITS - 2); + + if (sfTestFlags.QueryFlagsAllValues() != 2) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags64_EnumAllQueryEnumeratedFlags() +{ + bool bResult = false; + + do + { + CSimpleFlags64 sfTestFlags((uint64ou)(OU_INT64_MIN + 1)); + + uint64ou uiFirstResult = sfTestFlags.EnumAllQueryEnumeratedFlags(1, OU_UINT64_BITS); + if (uiFirstResult != (uint64ou)(OU_INT64_MIN + 1)) + { + break; + } + + uint64ou uiSecondResult = sfTestFlags.EnumAllQueryEnumeratedFlags(2, OU_UINT64_BITS - 1); + if (uiSecondResult != (uint64ou)(OU_INT64_MIN)) + { + break; + } + + uint64ou uiThirdResult = sfTestFlags.EnumAllQueryEnumeratedFlags(2, OU_UINT64_BITS - 2); + if (uiThirdResult != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags64_EnumAnyGetEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags64 sfTestFlags((uint64ou)(OU_INT64_MIN + 1)); + + bool bFirstResult = sfTestFlags.EnumAnyGetEnumeratedFlagValue(1, OU_UINT64_BITS); + if (!bFirstResult) + { + break; + } + + bool bSecondResult = sfTestFlags.EnumAnyGetEnumeratedFlagValue(2, OU_UINT64_BITS - 1); + if (!bSecondResult) + { + break; + } + + bool bThirdResult = sfTestFlags.EnumAnyGetEnumeratedFlagValue(2, OU_UINT64_BITS - 2); + if (bThirdResult) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags64_StoreFlagsEnumeratedValue() +{ + bool bResult = false; + + do + { + CSimpleFlags64 sfTestFlags; + + sfTestFlags.StoreFlagsEnumeratedValue(0x03, 1, 2); + + if (sfTestFlags.QueryFlagsAllValues() != (uint64ou)(2 << 1)) + { + break; + } + + sfTestFlags.StoreFlagsEnumeratedValue(0x03, OU_UINT64_BITS - 2, 3); + + if (sfTestFlags.QueryFlagsAllValues() != ((uint64ou)(2 << 1) | (uint64ou)(OU_INT64_MIN | (OU_INT64_MIN >> 1)))) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags64_RetrieveFlagsEnumeratedValue() +{ + bool bResult = false; + + do + { + CSimpleFlags64 sfTestFlags((uint64ou)(OU_INT64_MIN + 1)); + + unsigned int uiFirstResult = sfTestFlags.RetrieveFlagsEnumeratedValue(0x3, 1); + if (uiFirstResult != 0) + { + break; + } + + unsigned int uiSecondResult = sfTestFlags.RetrieveFlagsEnumeratedValue(0x3, OU_UINT64_BITS - 2); + if (uiSecondResult != 2) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + + +enum EOUSIMPLEFLAGSFEATURE64 +{ + OSF64__MIN, + + OSF64_CONSTRUCTORS = OSF64__MIN, + OSF64_ASSIGNFLAGSALLVALUES, + OSF64_QUERYFLAGSALLVALUES, + OSF64_SETFLAGSMASKVALUE, + OSF64_SIGNALFLAGSMASKVALUE, + OSF64_DROPFLAGSMASKVALUE, + OSF64_TOGGLESINGLEFLAGVALUE, + OSF64_MODIFYSINGLEFLAGVALUE, + OSF64_ASSIGNFLAGSBYMASK, + OSF64_ALTERFLAGSBYMASK, + OSF64_GETFLAGSMASKVALUE, + OSF64_QUERYFLAGSBYMASK, + OSF64_ONLYSIGNALSINGLEFLAGOUTOFMASK, + OSF64_ENUMSETENUMERATEDFLAGVALUE, + OSF64_ENUMSIGNALENUMERATEDFLAGVALUE, + OSF64_ENUMDROPENUMERATEDFLAGVALUE, + OSF64_ENUMTOGGLEENUMERATEDFLAGVALUE, + OSF64_ENUMMODIFYENUMERATEDFLAGVALUE, + OSF64_ENUMSIGNALFIRSTENUMERATEDFLAGVALUE, + OSF64_ENUMSIGNALLASTENUMERATEDFLAGVALUE, + OSF64_ENUMGETENUMERATEDFLAGVALUE, + OSF64_ENUMFINDFIRSTENUMERATEDFLAG, + OSF64_ENUMALLSIGNALENUMERATEDFLAGS, + OSF64_ENUMALLDROPENUMERATEDFLAGS, + OSF64_ENUMALLQUERYENUMERATEDFLAGS, + OSF64_ENUMANYGETENUMERATEDFLAGVALUE, + OSF64_STOREFLAGSENUMERATEDVALUE, + OSF64_RETRIEVEFLAGSENUMERATEDVALUE, + + OSF64__MAX, +}; + +template<> +CFeatureTestProcedure const CEnumUnsortedElementArray<EOUSIMPLEFLAGSFEATURE64, OSF64__MAX, CFeatureTestProcedure>::m_aetElementArray[] = +{ + &TestSimpleFlags64_Constructors, // OSF64_CONSTRUCTORS + &TestSimpleFlags64_AssignFlagsAllValues, // OSF64_ASSIGNFLAGSALLVALUES, + &TestSimpleFlags64_QueryFlagsAllValues, // OSF64_QUERYFLAGSALLVALUES, + &TestSimpleFlags64_SetFlagsMaskValue, // OSF64_SETFLAGSMASKVALUE, + &TestSimpleFlags64_SignalFlagsMaskValue, // OSF64_SIGNALFLAGSMASKVALUE, + &TestSimpleFlags64_DropFlagsMaskValue, // OSF64_DROPFLAGSMASKVALUE, + &TestSimpleFlags64_ToggleSingleFlagValue, // OSF64_TOGGLESINGLEFLAGVALUE, + &TestSimpleFlags64_ModifySingleFlagValue, // OSF64_MODIFYSINGLEFLAGVALUE, + &TestSimpleFlags64_AssignFlagsByMask, // OSF64_ASSIGNFLAGSBYMASK, + &TestSimpleFlags64_AlterFlagsByMask, // OSF64_ALTERFLAGSBYMASK, + &TestSimpleFlags64_GetFlagsMaskValue, // OSF64_GETFLAGSMASKVALUE, + &TestSimpleFlags64_QueryFlagsByMask, // OSF64_QUERYFLAGSBYMASK, + &TestSimpleFlags64_OnlySignalSingleFlagOutOfMask, // OSF64_ONLYSIGNALSINGLEFLAGOUTOFMASK, + &TestSimpleFlags64_EnumSetEnumeratedFlagValue, // OSF64_ENUMSETENUMERATEDFLAGVALUE, + &TestSimpleFlags64_EnumSignalEnumeratedFlagValue, // OSF64_ENUMSIGNALENUMERATEDFLAGVALUE, + &TestSimpleFlags64_EnumDropEnumeratedFlagValue, // OSF64_ENUMDROPENUMERATEDFLAGVALUE, + &TestSimpleFlags64_EnumToggleEnumeratedFlagValue, // OSF64_ENUMTOGGLEENUMERATEDFLAGVALUE, + &TestSimpleFlags64_EnumModifyEnumeratedFlagValue, // OSF64_ENUMMODIFYENUMERATEDFLAGVALUE, + &TestSimpleFlags64_EnumSignalFirstEnumeratedFlagValue, // OSF64_ENUMSIGNALFIRSTENUMERATEDFLAGVALUE, + &TestSimpleFlags64_EnumSignalLastEnumeratedFlagValue, // OSF64_ENUMSIGNALLASTENUMERATEDFLAGVALUE, + &TestSimpleFlags64_EnumGetEnumeratedFlagValue, // OSF64_ENUMGETENUMERATEDFLAGVALUE, + &TestSimpleFlags64_EnumFindFirstEnumeratedFlag, // OSF64_ENUMFINDFIRSTENUMERATEDFLAG, + &TestSimpleFlags64_EnumAllSignalEnumeratedFlags, // OSF64_ENUMALLSIGNALENUMERATEDFLAGS, + &TestSimpleFlags64_EnumAllDropEnumeratedFlags, // OSF64_ENUMALLDROPENUMERATEDFLAGS, + &TestSimpleFlags64_EnumAllQueryEnumeratedFlags, // OSF64_ENUMALLQUERYENUMERATEDFLAGS, + &TestSimpleFlags64_EnumAnyGetEnumeratedFlagValue, // OSF64_ENUMANYGETENUMERATEDFLAGVALUE, + &TestSimpleFlags64_StoreFlagsEnumeratedValue, // OSF64_STOREFLAGSENUMERATEDVALUE, + &TestSimpleFlags64_RetrieveFlagsEnumeratedValue, // OSF64_RETRIEVEFLAGSENUMERATEDVALUE, +}; +static const CEnumUnsortedElementArray<EOUSIMPLEFLAGSFEATURE64, OSF64__MAX, CFeatureTestProcedure> g_afnSimpleFlags64FeatureTestProcedures; + +template<> +const char *const CEnumUnsortedElementArray<EOUSIMPLEFLAGSFEATURE64, OSF64__MAX, const char *>::m_aetElementArray[] = +{ + "Constructors", // OSF64_CONSTRUCTORS + "AssignFlagsAllValues", // OSF64_ASSIGNFLAGSALLVALUES, + "QueryFlagsAllValues", // OSF64_QUERYFLAGSALLVALUES, + "SetFlagsMaskValue", // OSF64_SETFLAGSMASKVALUE, + "SignalFlagsMaskValue", // OSF64_SIGNALFLAGSMASKVALUE, + "DropFlagsMaskValue", // OSF64_DROPFLAGSMASKVALUE, + "ToggleSingleFlagValue", // OSF64_TOGGLESINGLEFLAGVALUE, + "ModifySingleFlagValue", // OSF64_MODIFYSINGLEFLAGVALUE, + "AssignFlagsByMask", // OSF64_ASSIGNFLAGSBYMASK, + "AlterFlagsByMask", // OSF64_ALTERFLAGSBYMASK, + "GetFlagsMaskValue", // OSF64_GETFLAGSMASKVALUE, + "QueryFlagsByMask", // OSF64_QUERYFLAGSBYMASK, + "OnlySignalSingleFlagOutOfMask", // OSF64_ONLYSIGNALSINGLEFLAGOUTOFMASK, + "EnumSetEnumeratedFlagValue", // OSF64_ENUMSETENUMERATEDFLAGVALUE, + "EnumSignalEnumeratedFlagValue", // OSF64_ENUMSIGNALENUMERATEDFLAGVALUE, + "EnumDropEnumeratedFlagValue", // OSF64_ENUMDROPENUMERATEDFLAGVALUE, + "EnumToggleEnumeratedFlagValue", // OSF64_ENUMTOGGLEENUMERATEDFLAGVALUE, + "EnumModifyEnumeratedFlagValue", // OSF64_ENUMMODIFYENUMERATEDFLAGVALUE, + "EnumSignalFirstEnumeratedFlagValue", // OSF64_ENUMSIGNALFIRSTENUMERATEDFLAGVALUE, + "EnumSignalLastEnumeratedFlagValue", // OSF64_ENUMSIGNALLASTENUMERATEDFLAGVALUE, + "EnumGetEnumeratedFlagValue", // OSF64_ENUMGETENUMERATEDFLAGVALUE, + "EnumFindFirstEnumeratedFlag", // OSF64_ENUMFINDFIRSTENUMERATEDFLAG, + "EnumAllSignalEnumeratedFlags", // OSF64_ENUMALLSIGNALENUMERATEDFLAGS, + "EnumAllDropEnumeratedFlags", // OSF64_ENUMALLDROPENUMERATEDFLAGS, + "EnumAllQueryEnumeratedFlags", // OSF64_ENUMALLQUERYENUMERATEDFLAGS, + "EnumAnyGetEnumeratedFlagValue", // OSF64_ENUMANYGETENUMERATEDFLAGVALUE, + "StoreFlagsEnumeratedValue", // OSF64_STOREFLAGSENUMERATEDVALUE, + "RetrieveFlagsEnumeratedValue", // OSF64_RETRIEVEFLAGSENUMERATEDVALUE, +}; +static const CEnumUnsortedElementArray<EOUSIMPLEFLAGSFEATURE64, OSF64__MAX, const char *> g_aszSimpleFlags64FeatureTestNames; + + +bool TestSimpleFlags64(unsigned int &nOutSuccessCount, unsigned int &nOutTestCount) +{ + return TestSubsystem(nOutSuccessCount, nOutTestCount, OSF64__MAX, g_aszSimpleFlags64FeatureTestNames.GetStoragePointer(), g_afnSimpleFlags64FeatureTestProcedures.GetStoragePointer()); +} + + +////////////////////////////////////////////////////////////////////////// + +typedef CSimpleFlags CSimpleFlags32; + +const uint32ou g_uiTestValue32 = (uint32ou)0xA5A5A5A5; +const uint32ou g_uiTestMask32 = (uint32ou)0xC6C6C6C6; +const uint32ou g_uiTestBit32 = (uint32ou)OU_INT32_MIN; +const uint32ou g_uiTestAnotherBit32 = (uint32ou)((uint32ou)OU_INT32_MIN >> 1); + + +bool TestSimpleFlags32_Constructors() +{ + bool bResult = false; + + do + { + if (sizeof(CSimpleFlags32::value_type) != sizeof(uint32ou) || sizeof(CSimpleFlags32) != sizeof(uint32ou)) + { + break; + } + + CSimpleFlags32 sfEmptyFlags; + + if (sfEmptyFlags.QueryFlagsAllValues()) + { + break; + } + + CSimpleFlags32 sfFullFlags(OU_UINT32_MAX); + + if (sfFullFlags.QueryFlagsAllValues() != OU_UINT32_MAX) + { + break; + } + + CSimpleFlags32 sfCopyOfFullFlags(sfFullFlags); + + if (sfCopyOfFullFlags.QueryFlagsAllValues() != OU_UINT32_MAX) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags32_AssignFlagsAllValues() +{ + bool bResult = false; + + do + { + CSimpleFlags32 sfTestFlags; + + sfTestFlags.AssignFlagsAllValues(OU_UINT32_MAX); + + if (sfTestFlags.QueryFlagsAllValues() != OU_UINT32_MAX) + { + break; + } + + sfTestFlags.AssignFlagsAllValues(0); + + if (sfTestFlags.QueryFlagsAllValues() != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags32_QueryFlagsAllValues() +{ + bool bResult = false; + + do + { + CSimpleFlags32 sfTestFlags(g_uiTestValue32); + + if (sfTestFlags.QueryFlagsAllValues() != g_uiTestValue32) + { + break; + } + + // Double check to be sure ;-) + if (sfTestFlags.QueryFlagsAllValues() != g_uiTestValue32) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags32_SetFlagsMaskValue() +{ + bool bResult = false; + + do + { + CSimpleFlags32 sfTestFlags(g_uiTestValue32); + + sfTestFlags.SetFlagsMaskValue(g_uiTestMask32, true); + + if (sfTestFlags.QueryFlagsAllValues() != (uint32ou)(g_uiTestValue32 | g_uiTestMask32)) + { + break; + } + + sfTestFlags.SetFlagsMaskValue(g_uiTestValue32, false); + + if (sfTestFlags.QueryFlagsAllValues() != (uint32ou)(~g_uiTestValue32 & g_uiTestMask32)) + { + break; + } + + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags32_SignalFlagsMaskValue() +{ + bool bResult = false; + + do + { + CSimpleFlags32 sfTestFlags(g_uiTestValue32); + + sfTestFlags.SignalFlagsMaskValue(g_uiTestMask32); + + if (sfTestFlags.QueryFlagsAllValues() != (uint32ou)(g_uiTestValue32 | g_uiTestMask32)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags32_DropFlagsMaskValue() +{ + bool bResult = false; + + do + { + CSimpleFlags32 sfTestFlags(g_uiTestValue32); + + sfTestFlags.DropFlagsMaskValue(g_uiTestMask32); + + if (sfTestFlags.QueryFlagsAllValues() != (uint32ou)(g_uiTestValue32 & ~g_uiTestMask32)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags32_ToggleSingleFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags32 sfTestFlags(g_uiTestValue32); + + bool bPreviousValue = sfTestFlags.ToggleSingleFlagValue(g_uiTestBit32); + + if (bPreviousValue != ((g_uiTestValue32 & g_uiTestBit32) != 0) || sfTestFlags.QueryFlagsAllValues() != (uint32ou)(g_uiTestValue32 ^ g_uiTestBit32)) + { + break; + } + + bool bAnotherPreviousValue = sfTestFlags.ToggleSingleFlagValue(g_uiTestBit32); + + if (bAnotherPreviousValue == bPreviousValue || sfTestFlags.QueryFlagsAllValues() != g_uiTestValue32) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags32_ModifySingleFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags32 sfTestFlags(g_uiTestValue32); + + bool bFirstModification = sfTestFlags.ModifySingleFlagValue(g_uiTestBit32, true); + + if (bFirstModification != ((g_uiTestValue32 & g_uiTestBit32) != g_uiTestBit32) || sfTestFlags.QueryFlagsAllValues() != (uint32ou)(g_uiTestValue32 | g_uiTestBit32)) + { + break; + } + + bool bAnotherModification = sfTestFlags.ModifySingleFlagValue(g_uiTestBit32, bFirstModification); + + if (bAnotherModification == bFirstModification || sfTestFlags.QueryFlagsAllValues() != (bFirstModification ? (uint32ou)(g_uiTestValue32 | g_uiTestBit32) : (uint32ou)(g_uiTestValue32 & ~g_uiTestBit32))) + { + break; + } + + bool bYetAnotherModification = sfTestFlags.ModifySingleFlagValue(g_uiTestBit32, bAnotherModification); + + if (bYetAnotherModification != bAnotherModification || sfTestFlags.QueryFlagsAllValues() != (bAnotherModification ? (uint32ou)(g_uiTestValue32 | g_uiTestBit32) : (uint32ou)(g_uiTestValue32 & ~g_uiTestBit32))) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags32_AssignFlagsByMask() +{ + bool bResult = false; + + do + { + CSimpleFlags32 sfTestFlags(g_uiTestValue32); + + uint32ou uiPreviousFlags = sfTestFlags.AssignFlagsByMask(g_uiTestMask32, g_uiTestMask32); + + const uint32ou uiNewFlags = (g_uiTestValue32 & ~g_uiTestMask32) | g_uiTestMask32; + + if (uiPreviousFlags != g_uiTestValue32 || sfTestFlags.QueryFlagsAllValues() != uiNewFlags) + { + break; + } + + uint32ou uiAnotherPreviousFlags = sfTestFlags.AssignFlagsByMask(g_uiTestValue32, 0); + + const uint32ou uiAnotherNewFlags = uiNewFlags & ~g_uiTestValue32; + + if (uiAnotherPreviousFlags != uiNewFlags || sfTestFlags.QueryFlagsAllValues() != uiAnotherNewFlags) + { + break; + } + + uint32ou uiYetAnotherPreviousFlags = sfTestFlags.AssignFlagsByMask(g_uiTestMask32, g_uiTestMask32 & g_uiTestValue32); + OU_ASSERT((g_uiTestMask32 & g_uiTestValue32) != 0); // Test degeneration + + const uint32ou uiYetAnotherNewFlags = (uiAnotherNewFlags & ~g_uiTestMask32) | (g_uiTestMask32 & g_uiTestValue32); + OU_ASSERT(uiYetAnotherNewFlags != OU_UINT32_MAX); // Test degeneration + + if (uiYetAnotherPreviousFlags != uiAnotherNewFlags || sfTestFlags.QueryFlagsAllValues() != uiYetAnotherNewFlags) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags32_AlterFlagsByMask() +{ + bool bResult = false; + + do + { + CSimpleFlags32 sfTestFlags(g_uiTestValue32); + + bool bWasModification = sfTestFlags.AlterFlagsByMask(g_uiTestMask32, g_uiTestMask32); + + const uint32ou uiNewFlags = (g_uiTestValue32 & ~g_uiTestMask32) | g_uiTestMask32; + + if (bWasModification != ((g_uiTestValue32 & g_uiTestMask32) != g_uiTestMask32) || sfTestFlags.QueryFlagsAllValues() != uiNewFlags) + { + break; + } + + bool bWasAnotherModification = sfTestFlags.AlterFlagsByMask(g_uiTestValue32, 0); + + const uint32ou uiAnotherNewFlags = uiNewFlags & ~g_uiTestValue32; + + if (bWasAnotherModification != ((uiNewFlags & g_uiTestValue32) != 0) || sfTestFlags.QueryFlagsAllValues() != uiAnotherNewFlags) + { + break; + } + + bool bWasAnotherModificationRepeated = sfTestFlags.AlterFlagsByMask(g_uiTestValue32, 0); + + if (bWasAnotherModificationRepeated || sfTestFlags.QueryFlagsAllValues() != uiAnotherNewFlags) + { + break; + } + + bool bWasYetAnotherModification = sfTestFlags.AlterFlagsByMask(g_uiTestMask32, g_uiTestMask32 & g_uiTestValue32); + OU_ASSERT((g_uiTestMask32 & g_uiTestValue32) != 0); // Test degeneration + + const uint32ou uiYetAnotherNewFlags = (uiAnotherNewFlags & ~g_uiTestMask32) | (g_uiTestMask32 & g_uiTestValue32); + OU_ASSERT(uiYetAnotherNewFlags != OU_UINT32_MAX); // Test degeneration + + if (bWasYetAnotherModification != ((uiAnotherNewFlags & g_uiTestMask32) != (g_uiTestMask32 & g_uiTestValue32)) || sfTestFlags.QueryFlagsAllValues() != uiYetAnotherNewFlags) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags32_GetFlagsMaskValue() +{ + bool bResult = false; + + do + { + CSimpleFlags32 sfTestFlags(g_uiTestValue32); + + if (sfTestFlags.GetFlagsMaskValue(g_uiTestMask32) != ((g_uiTestValue32 & g_uiTestMask32) != 0)) + { + break; + } + + if (sfTestFlags.GetFlagsMaskValue(~g_uiTestValue32)) + { + break; + } + + if (!sfTestFlags.GetFlagsMaskValue(OU_UINT32_MAX)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags32_QueryFlagsByMask() +{ + bool bResult = false; + + do + { + CSimpleFlags32 sfTestFlags(g_uiTestValue32); + + if (sfTestFlags.QueryFlagsByMask(g_uiTestMask32) != (uint32ou)(g_uiTestValue32 & g_uiTestMask32)) + { + break; + } + + if (sfTestFlags.QueryFlagsByMask(0)) + { + break; + } + + if (sfTestFlags.QueryFlagsByMask(OU_UINT32_MAX) != g_uiTestValue32) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags32_OnlySignalSingleFlagOutOfMask() +{ + bool bResult = false; + + do + { + CSimpleFlags32 sfTestFlags(g_uiTestValue32); + OU_ASSERT(g_uiTestValue32 != 0); // Test degeneration + + if (sfTestFlags.OnlySignalSingleFlagOutOfMask(OU_UINT32_MAX, g_uiTestBit32)) + { + break; + } + + if (sfTestFlags.QueryFlagsAllValues() != g_uiTestValue32) + { + break; + } + + sfTestFlags.AssignFlagsAllValues(0); + + if (!sfTestFlags.OnlySignalSingleFlagOutOfMask(g_uiTestBit32, g_uiTestBit32)) + { + break; + } + + if (sfTestFlags.QueryFlagsAllValues() != g_uiTestBit32) + { + break; + } + + if (sfTestFlags.OnlySignalSingleFlagOutOfMask(g_uiTestBit32, g_uiTestBit32)) + { + break; + } + + if (sfTestFlags.QueryFlagsAllValues() != g_uiTestBit32) + { + break; + } + + if (sfTestFlags.OnlySignalSingleFlagOutOfMask(OU_UINT32_MAX, g_uiTestAnotherBit32)) + { + break; + } + + if (sfTestFlags.QueryFlagsAllValues() != g_uiTestBit32) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags32_EnumSetEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags32 sfTestFlags; + + sfTestFlags.EnumSetEnumeratedFlagValue(1, 0, OU_UINT32_BITS, true); + + if (sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + sfTestFlags.EnumSetEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS, true); + + if (sfTestFlags.QueryFlagsAllValues() != (uint32ou)(OU_INT32_MIN + 1)) + { + break; + } + + sfTestFlags.EnumSetEnumeratedFlagValue(1, 0, OU_UINT32_BITS, false); + + if (sfTestFlags.QueryFlagsAllValues() != (uint32ou)OU_INT32_MIN) + { + break; + } + + sfTestFlags.EnumSetEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS, false); + + if (sfTestFlags.QueryFlagsAllValues() != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags32_EnumSignalEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags32 sfTestFlags; + + sfTestFlags.EnumSignalEnumeratedFlagValue(1, 0, OU_UINT32_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + sfTestFlags.EnumSignalEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (uint32ou)(OU_INT32_MIN + 1)) + { + break; + } + + sfTestFlags.EnumSignalEnumeratedFlagValue(1, 0, OU_UINT32_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (uint32ou)(OU_INT32_MIN + 1)) + { + break; + } + + sfTestFlags.EnumSignalEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (uint32ou)(OU_INT32_MIN + 1)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags32_EnumDropEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags32 sfTestFlags(OU_UINT32_MAX); + + sfTestFlags.EnumDropEnumeratedFlagValue(1, 0, OU_UINT32_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (OU_UINT32_MAX ^ 1)) + { + break; + } + + sfTestFlags.EnumDropEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (uint32ou)~(OU_INT32_MIN + 1)) + { + break; + } + + sfTestFlags.EnumDropEnumeratedFlagValue(1, 0, OU_UINT32_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (uint32ou)~(OU_INT32_MIN + 1)) + { + break; + } + + sfTestFlags.EnumDropEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (uint32ou)~(OU_INT32_MIN + 1)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags32_EnumToggleEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags32 sfTestFlags; + + bool bToggleFirstResult = sfTestFlags.EnumToggleEnumeratedFlagValue(1, 0, OU_UINT32_BITS); + + if (bToggleFirstResult || sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bToggleSecondResult = sfTestFlags.EnumToggleEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS); + + if (bToggleSecondResult || sfTestFlags.QueryFlagsAllValues() != (uint32ou)(OU_INT32_MIN + 1)) + { + break; + } + + bool bToggleThirdResult = sfTestFlags.EnumToggleEnumeratedFlagValue(1, 0, OU_UINT32_BITS); + + if (!bToggleThirdResult || sfTestFlags.QueryFlagsAllValues() != (uint32ou)OU_INT32_MIN) + { + break; + } + + bool bToggleFourthResult = sfTestFlags.EnumToggleEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS); + + if (!bToggleFourthResult || sfTestFlags.QueryFlagsAllValues() != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags32_EnumModifyEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags32 sfTestFlags; + + bool bModifyFirstResult = sfTestFlags.EnumModifyEnumeratedFlagValue(1, 0, OU_UINT32_BITS, true); + + if (!bModifyFirstResult || sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bModifySecondResult = sfTestFlags.EnumModifyEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS, true); + + if (!bModifySecondResult || sfTestFlags.QueryFlagsAllValues() != (uint32ou)(OU_INT32_MIN + 1)) + { + break; + } + + bool bModifyThirdResult = sfTestFlags.EnumModifyEnumeratedFlagValue(1, 0, OU_UINT32_BITS, true); + + if (bModifyThirdResult || sfTestFlags.QueryFlagsAllValues() != (uint32ou)(OU_INT32_MIN + 1)) + { + break; + } + + bool bModifyFourthResult = sfTestFlags.EnumModifyEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS, true); + + if (bModifyFourthResult || sfTestFlags.QueryFlagsAllValues() != (uint32ou)(OU_INT32_MIN + 1)) + { + break; + } + + bool bModifyFifthResult = sfTestFlags.EnumModifyEnumeratedFlagValue(1, 0, OU_UINT32_BITS, false); + + if (!bModifyFifthResult || sfTestFlags.QueryFlagsAllValues() != (uint32ou)OU_INT32_MIN) + { + break; + } + + bool bModifySixthResult = sfTestFlags.EnumModifyEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS, false); + + if (!bModifySixthResult || sfTestFlags.QueryFlagsAllValues() != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags32_EnumSignalFirstEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags32 sfTestFlags; + + bool bFirstResult = sfTestFlags.EnumSignalFirstEnumeratedFlagValue(1, 0, OU_UINT32_BITS); + + if (!bFirstResult || sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bSecondResult = sfTestFlags.EnumSignalFirstEnumeratedFlagValue(1, 0, OU_UINT32_BITS); + + if (bSecondResult || sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bThirdResult = sfTestFlags.EnumSignalFirstEnumeratedFlagValue(2, 0, OU_UINT32_BITS - 1); + + if (!bThirdResult || sfTestFlags.QueryFlagsAllValues() != 3) + { + break; + } + + bool bFourthResult = sfTestFlags.EnumSignalFirstEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS); + + if (bFourthResult || sfTestFlags.QueryFlagsAllValues() != (uint32ou)(OU_INT32_MIN + 3)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags32_EnumSignalLastEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags32 sfTestFlags; + + bool bFirstResult = sfTestFlags.EnumSignalLastEnumeratedFlagValue(1, 0, 1); + + if (!bFirstResult || sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bSecondResult = sfTestFlags.EnumSignalLastEnumeratedFlagValue(1, 0, 1); + + if (bSecondResult || sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bThirdResult = sfTestFlags.EnumSignalLastEnumeratedFlagValue(1, 1, 2); + + if (!bThirdResult || sfTestFlags.QueryFlagsAllValues() != 3) + { + break; + } + + bool bFourthResult = sfTestFlags.EnumSignalLastEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS); + + if (bFourthResult || sfTestFlags.QueryFlagsAllValues() != (uint32ou)(OU_INT32_MIN + 3)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags32_EnumGetEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags32 sfTestFlags((uint32ou)(OU_INT32_MIN + 1)); + + if (!sfTestFlags.EnumGetEnumeratedFlagValue(1, 0, OU_UINT32_BITS)) + { + break; + } + + if (sfTestFlags.EnumGetEnumeratedFlagValue(2, 0, OU_UINT32_BITS - 1)) + { + break; + } + + if (sfTestFlags.EnumGetEnumeratedFlagValue(1, 1, OU_UINT32_BITS - 1)) + { + break; + } + + if (!sfTestFlags.EnumGetEnumeratedFlagValue(1, OU_UINT32_BITS - 1, OU_UINT32_BITS)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags32_EnumFindFirstEnumeratedFlag() +{ + bool bResult = false; + + do + { + CSimpleFlags32 sfTestFlags((uint32ou)(OU_INT32_MIN + 1)); + + unsigned int uiFirstResult = sfTestFlags.EnumFindFirstEnumeratedFlag(1, OU_UINT32_BITS); + if (uiFirstResult != 0) + { + break; + } + + unsigned int uiSecondResult = sfTestFlags.EnumFindFirstEnumeratedFlag(2, OU_UINT32_BITS - 1); + if (uiSecondResult != OU_UINT32_BITS - 2) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags32_EnumAllSignalEnumeratedFlags() +{ + bool bResult = false; + + do + { + CSimpleFlags32 sfTestFlags; + + sfTestFlags.EnumAllSignalEnumeratedFlags(1, 1); + + if (sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + sfTestFlags.EnumAllSignalEnumeratedFlags(4, OU_UINT32_BITS - 2); + + if (sfTestFlags.QueryFlagsAllValues() != (uint32ou)(OU_UINT32_MAX ^ 2)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags32_EnumAllDropEnumeratedFlags() +{ + bool bResult = false; + + do + { + CSimpleFlags32 sfTestFlags(OU_UINT32_MAX); + + sfTestFlags.EnumAllDropEnumeratedFlags(1, 1); + + if (sfTestFlags.QueryFlagsAllValues() != (uint32ou)(OU_UINT32_MAX ^ 1)) + { + break; + } + + sfTestFlags.EnumAllDropEnumeratedFlags(4, OU_UINT32_BITS - 2); + + if (sfTestFlags.QueryFlagsAllValues() != 2) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags32_EnumAllQueryEnumeratedFlags() +{ + bool bResult = false; + + do + { + CSimpleFlags32 sfTestFlags((uint32ou)(OU_INT32_MIN + 1)); + + uint32ou uiFirstResult = sfTestFlags.EnumAllQueryEnumeratedFlags(1, OU_UINT32_BITS); + if (uiFirstResult != (uint32ou)(OU_INT32_MIN + 1)) + { + break; + } + + uint32ou uiSecondResult = sfTestFlags.EnumAllQueryEnumeratedFlags(2, OU_UINT32_BITS - 1); + if (uiSecondResult != (uint32ou)(OU_INT32_MIN)) + { + break; + } + + uint32ou uiThirdResult = sfTestFlags.EnumAllQueryEnumeratedFlags(2, OU_UINT32_BITS - 2); + if (uiThirdResult != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags32_EnumAnyGetEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags32 sfTestFlags((uint32ou)(OU_INT32_MIN + 1)); + + bool bFirstResult = sfTestFlags.EnumAnyGetEnumeratedFlagValue(1, OU_UINT32_BITS); + if (!bFirstResult) + { + break; + } + + bool bSecondResult = sfTestFlags.EnumAnyGetEnumeratedFlagValue(2, OU_UINT32_BITS - 1); + if (!bSecondResult) + { + break; + } + + bool bThirdResult = sfTestFlags.EnumAnyGetEnumeratedFlagValue(2, OU_UINT32_BITS - 2); + if (bThirdResult) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags32_StoreFlagsEnumeratedValue() +{ + bool bResult = false; + + do + { + CSimpleFlags32 sfTestFlags; + + sfTestFlags.StoreFlagsEnumeratedValue(0x03, 1, 2); + + if (sfTestFlags.QueryFlagsAllValues() != (uint32ou)(2 << 1)) + { + break; + } + + sfTestFlags.StoreFlagsEnumeratedValue(0x03, OU_UINT32_BITS - 2, 3); + + if (sfTestFlags.QueryFlagsAllValues() != ((uint32ou)(2 << 1) | (uint32ou)(OU_INT32_MIN | (OU_INT32_MIN >> 1)))) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags32_RetrieveFlagsEnumeratedValue() +{ + bool bResult = false; + + do + { + CSimpleFlags32 sfTestFlags((uint32ou)(OU_INT32_MIN + 1)); + + unsigned int uiFirstResult = sfTestFlags.RetrieveFlagsEnumeratedValue(0x3, 1); + if (uiFirstResult != 0) + { + break; + } + + unsigned int uiSecondResult = sfTestFlags.RetrieveFlagsEnumeratedValue(0x3, OU_UINT32_BITS - 2); + if (uiSecondResult != 2) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + + +enum EOUSIMPLEFLAGSFEATURE32 +{ + OSF32__MIN, + + OSF32_CONSTRUCTORS = OSF32__MIN, + OSF32_ASSIGNFLAGSALLVALUES, + OSF32_QUERYFLAGSALLVALUES, + OSF32_SETFLAGSMASKVALUE, + OSF32_SIGNALFLAGSMASKVALUE, + OSF32_DROPFLAGSMASKVALUE, + OSF32_TOGGLESINGLEFLAGVALUE, + OSF32_MODIFYSINGLEFLAGVALUE, + OSF32_ASSIGNFLAGSBYMASK, + OSF32_ALTERFLAGSBYMASK, + OSF32_GETFLAGSMASKVALUE, + OSF32_QUERYFLAGSBYMASK, + OSF32_ONLYSIGNALSINGLEFLAGOUTOFMASK, + OSF32_ENUMSETENUMERATEDFLAGVALUE, + OSF32_ENUMSIGNALENUMERATEDFLAGVALUE, + OSF32_ENUMDROPENUMERATEDFLAGVALUE, + OSF32_ENUMTOGGLEENUMERATEDFLAGVALUE, + OSF32_ENUMMODIFYENUMERATEDFLAGVALUE, + OSF32_ENUMSIGNALFIRSTENUMERATEDFLAGVALUE, + OSF32_ENUMSIGNALLASTENUMERATEDFLAGVALUE, + OSF32_ENUMGETENUMERATEDFLAGVALUE, + OSF32_ENUMFINDFIRSTENUMERATEDFLAG, + OSF32_ENUMALLSIGNALENUMERATEDFLAGS, + OSF32_ENUMALLDROPENUMERATEDFLAGS, + OSF32_ENUMALLQUERYENUMERATEDFLAGS, + OSF32_ENUMANYGETENUMERATEDFLAGVALUE, + OSF32_STOREFLAGSENUMERATEDVALUE, + OSF32_RETRIEVEFLAGSENUMERATEDVALUE, + + OSF32__MAX, +}; + +template<> +CFeatureTestProcedure const CEnumUnsortedElementArray<EOUSIMPLEFLAGSFEATURE32, OSF32__MAX, CFeatureTestProcedure>::m_aetElementArray[] = +{ + &TestSimpleFlags32_Constructors, // OSF32_CONSTRUCTORS + &TestSimpleFlags32_AssignFlagsAllValues, // OSF32_ASSIGNFLAGSALLVALUES, + &TestSimpleFlags32_QueryFlagsAllValues, // OSF32_QUERYFLAGSALLVALUES, + &TestSimpleFlags32_SetFlagsMaskValue, // OSF32_SETFLAGSMASKVALUE, + &TestSimpleFlags32_SignalFlagsMaskValue, // OSF32_SIGNALFLAGSMASKVALUE, + &TestSimpleFlags32_DropFlagsMaskValue, // OSF32_DROPFLAGSMASKVALUE, + &TestSimpleFlags32_ToggleSingleFlagValue, // OSF32_TOGGLESINGLEFLAGVALUE, + &TestSimpleFlags32_ModifySingleFlagValue, // OSF32_MODIFYSINGLEFLAGVALUE, + &TestSimpleFlags32_AssignFlagsByMask, // OSF32_ASSIGNFLAGSBYMASK, + &TestSimpleFlags32_AlterFlagsByMask, // OSF32_ALTERFLAGSBYMASK, + &TestSimpleFlags32_GetFlagsMaskValue, // OSF32_GETFLAGSMASKVALUE, + &TestSimpleFlags32_QueryFlagsByMask, // OSF32_QUERYFLAGSBYMASK, + &TestSimpleFlags32_OnlySignalSingleFlagOutOfMask, // OSF32_ONLYSIGNALSINGLEFLAGOUTOFMASK, + &TestSimpleFlags32_EnumSetEnumeratedFlagValue, // OSF32_ENUMSETENUMERATEDFLAGVALUE, + &TestSimpleFlags32_EnumSignalEnumeratedFlagValue, // OSF32_ENUMSIGNALENUMERATEDFLAGVALUE, + &TestSimpleFlags32_EnumDropEnumeratedFlagValue, // OSF32_ENUMDROPENUMERATEDFLAGVALUE, + &TestSimpleFlags32_EnumToggleEnumeratedFlagValue, // OSF32_ENUMTOGGLEENUMERATEDFLAGVALUE, + &TestSimpleFlags32_EnumModifyEnumeratedFlagValue, // OSF32_ENUMMODIFYENUMERATEDFLAGVALUE, + &TestSimpleFlags32_EnumSignalFirstEnumeratedFlagValue, // OSF32_ENUMSIGNALFIRSTENUMERATEDFLAGVALUE, + &TestSimpleFlags32_EnumSignalLastEnumeratedFlagValue, // OSF32_ENUMSIGNALLASTENUMERATEDFLAGVALUE, + &TestSimpleFlags32_EnumGetEnumeratedFlagValue, // OSF32_ENUMGETENUMERATEDFLAGVALUE, + &TestSimpleFlags32_EnumFindFirstEnumeratedFlag, // OSF32_ENUMFINDFIRSTENUMERATEDFLAG, + &TestSimpleFlags32_EnumAllSignalEnumeratedFlags, // OSF32_ENUMALLSIGNALENUMERATEDFLAGS, + &TestSimpleFlags32_EnumAllDropEnumeratedFlags, // OSF32_ENUMALLDROPENUMERATEDFLAGS, + &TestSimpleFlags32_EnumAllQueryEnumeratedFlags, // OSF32_ENUMALLQUERYENUMERATEDFLAGS, + &TestSimpleFlags32_EnumAnyGetEnumeratedFlagValue, // OSF32_ENUMANYGETENUMERATEDFLAGVALUE, + &TestSimpleFlags32_StoreFlagsEnumeratedValue, // OSF32_STOREFLAGSENUMERATEDVALUE, + &TestSimpleFlags32_RetrieveFlagsEnumeratedValue, // OSF32_RETRIEVEFLAGSENUMERATEDVALUE, +}; +static const CEnumUnsortedElementArray<EOUSIMPLEFLAGSFEATURE32, OSF32__MAX, CFeatureTestProcedure> g_afnSimpleFlags32FeatureTestProcedures; + +template<> +const char *const CEnumUnsortedElementArray<EOUSIMPLEFLAGSFEATURE32, OSF32__MAX, const char *>::m_aetElementArray[] = +{ + "Constructors", // OSF32_CONSTRUCTORS + "AssignFlagsAllValues", // OSF32_ASSIGNFLAGSALLVALUES, + "QueryFlagsAllValues", // OSF32_QUERYFLAGSALLVALUES, + "SetFlagsMaskValue", // OSF32_SETFLAGSMASKVALUE, + "SignalFlagsMaskValue", // OSF32_SIGNALFLAGSMASKVALUE, + "DropFlagsMaskValue", // OSF32_DROPFLAGSMASKVALUE, + "ToggleSingleFlagValue", // OSF32_TOGGLESINGLEFLAGVALUE, + "ModifySingleFlagValue", // OSF32_MODIFYSINGLEFLAGVALUE, + "AssignFlagsByMask", // OSF32_ASSIGNFLAGSBYMASK, + "AlterFlagsByMask", // OSF32_ALTERFLAGSBYMASK, + "GetFlagsMaskValue", // OSF32_GETFLAGSMASKVALUE, + "QueryFlagsByMask", // OSF32_QUERYFLAGSBYMASK, + "OnlySignalSingleFlagOutOfMask", // OSF32_ONLYSIGNALSINGLEFLAGOUTOFMASK, + "EnumSetEnumeratedFlagValue", // OSF32_ENUMSETENUMERATEDFLAGVALUE, + "EnumSignalEnumeratedFlagValue", // OSF32_ENUMSIGNALENUMERATEDFLAGVALUE, + "EnumDropEnumeratedFlagValue", // OSF32_ENUMDROPENUMERATEDFLAGVALUE, + "EnumToggleEnumeratedFlagValue", // OSF32_ENUMTOGGLEENUMERATEDFLAGVALUE, + "EnumModifyEnumeratedFlagValue", // OSF32_ENUMMODIFYENUMERATEDFLAGVALUE, + "EnumSignalFirstEnumeratedFlagValue", // OSF32_ENUMSIGNALFIRSTENUMERATEDFLAGVALUE, + "EnumSignalLastEnumeratedFlagValue", // OSF32_ENUMSIGNALLASTENUMERATEDFLAGVALUE, + "EnumGetEnumeratedFlagValue", // OSF32_ENUMGETENUMERATEDFLAGVALUE, + "EnumFindFirstEnumeratedFlag", // OSF32_ENUMFINDFIRSTENUMERATEDFLAG, + "EnumAllSignalEnumeratedFlags", // OSF32_ENUMALLSIGNALENUMERATEDFLAGS, + "EnumAllDropEnumeratedFlags", // OSF32_ENUMALLDROPENUMERATEDFLAGS, + "EnumAllQueryEnumeratedFlags", // OSF32_ENUMALLQUERYENUMERATEDFLAGS, + "EnumAnyGetEnumeratedFlagValue", // OSF32_ENUMANYGETENUMERATEDFLAGVALUE, + "StoreFlagsEnumeratedValue", // OSF32_STOREFLAGSENUMERATEDVALUE, + "RetrieveFlagsEnumeratedValue", // OSF32_RETRIEVEFLAGSENUMERATEDVALUE, +}; +static const CEnumUnsortedElementArray<EOUSIMPLEFLAGSFEATURE32, OSF32__MAX, const char *> g_aszSimpleFlags32FeatureTestNames; + + +bool TestSimpleFlags32(unsigned int &nOutSuccessCount, unsigned int &nOutTestCount) +{ + return TestSubsystem(nOutSuccessCount, nOutTestCount, OSF32__MAX, g_aszSimpleFlags32FeatureTestNames.GetStoragePointer(), g_afnSimpleFlags32FeatureTestProcedures.GetStoragePointer()); +} + + +////////////////////////////////////////////////////////////////////////// + +typedef CSimpleFlagsTemplate<uint16ou> CSimpleFlags16; + +const uint16ou g_uiTestValue16 = (uint16ou)0xA5A5; +const uint16ou g_uiTestMask16 = (uint16ou)0xC6C6; +const uint16ou g_uiTestBit16 = (uint16ou)OU_INT16_MIN; +const uint16ou g_uiTestAnotherBit16 = (uint16ou)((uint16ou)OU_INT16_MIN >> 1); + + +bool TestSimpleFlags16_Constructors() +{ + bool bResult = false; + + do + { + if (sizeof(CSimpleFlags16::value_type) != sizeof(uint16ou) || sizeof(CSimpleFlags16) != sizeof(uint16ou)) + { + break; + } + + CSimpleFlags16 sfEmptyFlags; + + if (sfEmptyFlags.QueryFlagsAllValues()) + { + break; + } + + CSimpleFlags16 sfFullFlags(OU_UINT16_MAX); + + if (sfFullFlags.QueryFlagsAllValues() != OU_UINT16_MAX) + { + break; + } + + CSimpleFlags16 sfCopyOfFullFlags(sfFullFlags); + + if (sfCopyOfFullFlags.QueryFlagsAllValues() != OU_UINT16_MAX) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags16_AssignFlagsAllValues() +{ + bool bResult = false; + + do + { + CSimpleFlags16 sfTestFlags; + + sfTestFlags.AssignFlagsAllValues(OU_UINT16_MAX); + + if (sfTestFlags.QueryFlagsAllValues() != OU_UINT16_MAX) + { + break; + } + + sfTestFlags.AssignFlagsAllValues(0); + + if (sfTestFlags.QueryFlagsAllValues() != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags16_QueryFlagsAllValues() +{ + bool bResult = false; + + do + { + CSimpleFlags16 sfTestFlags(g_uiTestValue16); + + if (sfTestFlags.QueryFlagsAllValues() != g_uiTestValue16) + { + break; + } + + // Double check to be sure ;-) + if (sfTestFlags.QueryFlagsAllValues() != g_uiTestValue16) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags16_SetFlagsMaskValue() +{ + bool bResult = false; + + do + { + CSimpleFlags16 sfTestFlags(g_uiTestValue16); + + sfTestFlags.SetFlagsMaskValue(g_uiTestMask16, true); + + if (sfTestFlags.QueryFlagsAllValues() != (uint16ou)(g_uiTestValue16 | g_uiTestMask16)) + { + break; + } + + sfTestFlags.SetFlagsMaskValue(g_uiTestValue16, false); + + if (sfTestFlags.QueryFlagsAllValues() != (uint16ou)(~g_uiTestValue16 & g_uiTestMask16)) + { + break; + } + + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags16_SignalFlagsMaskValue() +{ + bool bResult = false; + + do + { + CSimpleFlags16 sfTestFlags(g_uiTestValue16); + + sfTestFlags.SignalFlagsMaskValue(g_uiTestMask16); + + if (sfTestFlags.QueryFlagsAllValues() != (uint16ou)(g_uiTestValue16 | g_uiTestMask16)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags16_DropFlagsMaskValue() +{ + bool bResult = false; + + do + { + CSimpleFlags16 sfTestFlags(g_uiTestValue16); + + sfTestFlags.DropFlagsMaskValue(g_uiTestMask16); + + if (sfTestFlags.QueryFlagsAllValues() != (uint16ou)(g_uiTestValue16 & ~g_uiTestMask16)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags16_ToggleSingleFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags16 sfTestFlags(g_uiTestValue16); + + bool bPreviousValue = sfTestFlags.ToggleSingleFlagValue(g_uiTestBit16); + + if (bPreviousValue != ((g_uiTestValue16 & g_uiTestBit16) != 0) || sfTestFlags.QueryFlagsAllValues() != (uint16ou)(g_uiTestValue16 ^ g_uiTestBit16)) + { + break; + } + + bool bAnotherPreviousValue = sfTestFlags.ToggleSingleFlagValue(g_uiTestBit16); + + if (bAnotherPreviousValue == bPreviousValue || sfTestFlags.QueryFlagsAllValues() != g_uiTestValue16) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags16_ModifySingleFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags16 sfTestFlags(g_uiTestValue16); + + bool bFirstModification = sfTestFlags.ModifySingleFlagValue(g_uiTestBit16, true); + + if (bFirstModification != ((g_uiTestValue16 & g_uiTestBit16) != g_uiTestBit16) || sfTestFlags.QueryFlagsAllValues() != (uint16ou)(g_uiTestValue16 | g_uiTestBit16)) + { + break; + } + + bool bAnotherModification = sfTestFlags.ModifySingleFlagValue(g_uiTestBit16, bFirstModification); + + if (bAnotherModification == bFirstModification || sfTestFlags.QueryFlagsAllValues() != (bFirstModification ? (uint16ou)(g_uiTestValue16 | g_uiTestBit16) : (uint16ou)(g_uiTestValue16 & ~g_uiTestBit16))) + { + break; + } + + bool bYetAnotherModification = sfTestFlags.ModifySingleFlagValue(g_uiTestBit16, bAnotherModification); + + if (bYetAnotherModification != bAnotherModification || sfTestFlags.QueryFlagsAllValues() != (bAnotherModification ? (uint16ou)(g_uiTestValue16 | g_uiTestBit16) : (uint16ou)(g_uiTestValue16 & ~g_uiTestBit16))) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags16_AssignFlagsByMask() +{ + bool bResult = false; + + do + { + CSimpleFlags16 sfTestFlags(g_uiTestValue16); + + uint16ou uiPreviousFlags = sfTestFlags.AssignFlagsByMask(g_uiTestMask16, g_uiTestMask16); + + const uint16ou uiNewFlags = (g_uiTestValue16 & ~g_uiTestMask16) | g_uiTestMask16; + + if (uiPreviousFlags != g_uiTestValue16 || sfTestFlags.QueryFlagsAllValues() != uiNewFlags) + { + break; + } + + uint16ou uiAnotherPreviousFlags = sfTestFlags.AssignFlagsByMask(g_uiTestValue16, 0); + + const uint16ou uiAnotherNewFlags = uiNewFlags & ~g_uiTestValue16; + + if (uiAnotherPreviousFlags != uiNewFlags || sfTestFlags.QueryFlagsAllValues() != uiAnotherNewFlags) + { + break; + } + + uint16ou uiYetAnotherPreviousFlags = sfTestFlags.AssignFlagsByMask(g_uiTestMask16, g_uiTestMask16 & g_uiTestValue16); + OU_ASSERT((g_uiTestMask16 & g_uiTestValue16) != 0); // Test degeneration + + const uint16ou uiYetAnotherNewFlags = (uiAnotherNewFlags & ~g_uiTestMask16) | (g_uiTestMask16 & g_uiTestValue16); + OU_ASSERT(uiYetAnotherNewFlags != OU_UINT16_MAX); // Test degeneration + + if (uiYetAnotherPreviousFlags != uiAnotherNewFlags || sfTestFlags.QueryFlagsAllValues() != uiYetAnotherNewFlags) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags16_AlterFlagsByMask() +{ + bool bResult = false; + + do + { + CSimpleFlags16 sfTestFlags(g_uiTestValue16); + + bool bWasModification = sfTestFlags.AlterFlagsByMask(g_uiTestMask16, g_uiTestMask16); + + const uint16ou uiNewFlags = (g_uiTestValue16 & ~g_uiTestMask16) | g_uiTestMask16; + + if (bWasModification != ((g_uiTestValue16 & g_uiTestMask16) != g_uiTestMask16) || sfTestFlags.QueryFlagsAllValues() != uiNewFlags) + { + break; + } + + bool bWasAnotherModification = sfTestFlags.AlterFlagsByMask(g_uiTestValue16, 0); + + const uint16ou uiAnotherNewFlags = uiNewFlags & ~g_uiTestValue16; + + if (bWasAnotherModification != ((uiNewFlags & g_uiTestValue16) != 0) || sfTestFlags.QueryFlagsAllValues() != uiAnotherNewFlags) + { + break; + } + + bool bWasAnotherModificationRepeated = sfTestFlags.AlterFlagsByMask(g_uiTestValue16, 0); + + if (bWasAnotherModificationRepeated || sfTestFlags.QueryFlagsAllValues() != uiAnotherNewFlags) + { + break; + } + + bool bWasYetAnotherModification = sfTestFlags.AlterFlagsByMask(g_uiTestMask16, g_uiTestMask16 & g_uiTestValue16); + OU_ASSERT((g_uiTestMask16 & g_uiTestValue16) != 0); // Test degeneration + + const uint16ou uiYetAnotherNewFlags = (uiAnotherNewFlags & ~g_uiTestMask16) | (g_uiTestMask16 & g_uiTestValue16); + OU_ASSERT(uiYetAnotherNewFlags != OU_UINT16_MAX); // Test degeneration + + if (bWasYetAnotherModification != ((uiAnotherNewFlags & g_uiTestMask16) != (g_uiTestMask16 & g_uiTestValue16)) || sfTestFlags.QueryFlagsAllValues() != uiYetAnotherNewFlags) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags16_GetFlagsMaskValue() +{ + bool bResult = false; + + do + { + CSimpleFlags16 sfTestFlags(g_uiTestValue16); + + if (sfTestFlags.GetFlagsMaskValue(g_uiTestMask16) != ((g_uiTestValue16 & g_uiTestMask16) != 0)) + { + break; + } + + if (sfTestFlags.GetFlagsMaskValue((uint16ou)(~g_uiTestValue16))) + { + break; + } + + if (!sfTestFlags.GetFlagsMaskValue(OU_UINT16_MAX)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags16_QueryFlagsByMask() +{ + bool bResult = false; + + do + { + CSimpleFlags16 sfTestFlags(g_uiTestValue16); + + if (sfTestFlags.QueryFlagsByMask(g_uiTestMask16) != (uint16ou)(g_uiTestValue16 & g_uiTestMask16)) + { + break; + } + + if (sfTestFlags.QueryFlagsByMask(0)) + { + break; + } + + if (sfTestFlags.QueryFlagsByMask(OU_UINT16_MAX) != g_uiTestValue16) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags16_OnlySignalSingleFlagOutOfMask() +{ + bool bResult = false; + + do + { + CSimpleFlags16 sfTestFlags(g_uiTestValue16); + OU_ASSERT(g_uiTestValue16 != 0); // Test degeneration + + if (sfTestFlags.OnlySignalSingleFlagOutOfMask(OU_UINT16_MAX, g_uiTestBit16)) + { + break; + } + + if (sfTestFlags.QueryFlagsAllValues() != g_uiTestValue16) + { + break; + } + + sfTestFlags.AssignFlagsAllValues(0); + + if (!sfTestFlags.OnlySignalSingleFlagOutOfMask(g_uiTestBit16, g_uiTestBit16)) + { + break; + } + + if (sfTestFlags.QueryFlagsAllValues() != g_uiTestBit16) + { + break; + } + + if (sfTestFlags.OnlySignalSingleFlagOutOfMask(g_uiTestBit16, g_uiTestBit16)) + { + break; + } + + if (sfTestFlags.QueryFlagsAllValues() != g_uiTestBit16) + { + break; + } + + if (sfTestFlags.OnlySignalSingleFlagOutOfMask(OU_UINT16_MAX, g_uiTestAnotherBit16)) + { + break; + } + + if (sfTestFlags.QueryFlagsAllValues() != g_uiTestBit16) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags16_EnumSetEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags16 sfTestFlags; + + sfTestFlags.EnumSetEnumeratedFlagValue(1, 0, OU_UINT16_BITS, true); + + if (sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + sfTestFlags.EnumSetEnumeratedFlagValue(1, OU_UINT16_BITS - 1, OU_UINT16_BITS, true); + + if (sfTestFlags.QueryFlagsAllValues() != (uint16ou)(OU_INT16_MIN + 1)) + { + break; + } + + sfTestFlags.EnumSetEnumeratedFlagValue(1, 0, OU_UINT16_BITS, false); + + if (sfTestFlags.QueryFlagsAllValues() != (uint16ou)OU_INT16_MIN) + { + break; + } + + sfTestFlags.EnumSetEnumeratedFlagValue(1, OU_UINT16_BITS - 1, OU_UINT16_BITS, false); + + if (sfTestFlags.QueryFlagsAllValues() != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags16_EnumSignalEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags16 sfTestFlags; + + sfTestFlags.EnumSignalEnumeratedFlagValue(1, 0, OU_UINT16_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + sfTestFlags.EnumSignalEnumeratedFlagValue(1, OU_UINT16_BITS - 1, OU_UINT16_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (uint16ou)(OU_INT16_MIN + 1)) + { + break; + } + + sfTestFlags.EnumSignalEnumeratedFlagValue(1, 0, OU_UINT16_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (uint16ou)(OU_INT16_MIN + 1)) + { + break; + } + + sfTestFlags.EnumSignalEnumeratedFlagValue(1, OU_UINT16_BITS - 1, OU_UINT16_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (uint16ou)(OU_INT16_MIN + 1)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags16_EnumDropEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags16 sfTestFlags(OU_UINT16_MAX); + + sfTestFlags.EnumDropEnumeratedFlagValue(1, 0, OU_UINT16_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (OU_UINT16_MAX ^ 1)) + { + break; + } + + sfTestFlags.EnumDropEnumeratedFlagValue(1, OU_UINT16_BITS - 1, OU_UINT16_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (uint16ou)~(OU_INT16_MIN + 1)) + { + break; + } + + sfTestFlags.EnumDropEnumeratedFlagValue(1, 0, OU_UINT16_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (uint16ou)~(OU_INT16_MIN + 1)) + { + break; + } + + sfTestFlags.EnumDropEnumeratedFlagValue(1, OU_UINT16_BITS - 1, OU_UINT16_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (uint16ou)~(OU_INT16_MIN + 1)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags16_EnumToggleEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags16 sfTestFlags; + + bool bToggleFirstResult = sfTestFlags.EnumToggleEnumeratedFlagValue(1, 0, OU_UINT16_BITS); + + if (bToggleFirstResult || sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bToggleSecondResult = sfTestFlags.EnumToggleEnumeratedFlagValue(1, OU_UINT16_BITS - 1, OU_UINT16_BITS); + + if (bToggleSecondResult || sfTestFlags.QueryFlagsAllValues() != (uint16ou)(OU_INT16_MIN + 1)) + { + break; + } + + bool bToggleThirdResult = sfTestFlags.EnumToggleEnumeratedFlagValue(1, 0, OU_UINT16_BITS); + + if (!bToggleThirdResult || sfTestFlags.QueryFlagsAllValues() != (uint16ou)OU_INT16_MIN) + { + break; + } + + bool bToggleFourthResult = sfTestFlags.EnumToggleEnumeratedFlagValue(1, OU_UINT16_BITS - 1, OU_UINT16_BITS); + + if (!bToggleFourthResult || sfTestFlags.QueryFlagsAllValues() != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags16_EnumModifyEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags16 sfTestFlags; + + bool bModifyFirstResult = sfTestFlags.EnumModifyEnumeratedFlagValue(1, 0, OU_UINT16_BITS, true); + + if (!bModifyFirstResult || sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bModifySecondResult = sfTestFlags.EnumModifyEnumeratedFlagValue(1, OU_UINT16_BITS - 1, OU_UINT16_BITS, true); + + if (!bModifySecondResult || sfTestFlags.QueryFlagsAllValues() != (uint16ou)(OU_INT16_MIN + 1)) + { + break; + } + + bool bModifyThirdResult = sfTestFlags.EnumModifyEnumeratedFlagValue(1, 0, OU_UINT16_BITS, true); + + if (bModifyThirdResult || sfTestFlags.QueryFlagsAllValues() != (uint16ou)(OU_INT16_MIN + 1)) + { + break; + } + + bool bModifyFourthResult = sfTestFlags.EnumModifyEnumeratedFlagValue(1, OU_UINT16_BITS - 1, OU_UINT16_BITS, true); + + if (bModifyFourthResult || sfTestFlags.QueryFlagsAllValues() != (uint16ou)(OU_INT16_MIN + 1)) + { + break; + } + + bool bModifyFifthResult = sfTestFlags.EnumModifyEnumeratedFlagValue(1, 0, OU_UINT16_BITS, false); + + if (!bModifyFifthResult || sfTestFlags.QueryFlagsAllValues() != (uint16ou)OU_INT16_MIN) + { + break; + } + + bool bModifySixthResult = sfTestFlags.EnumModifyEnumeratedFlagValue(1, OU_UINT16_BITS - 1, OU_UINT16_BITS, false); + + if (!bModifySixthResult || sfTestFlags.QueryFlagsAllValues() != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags16_EnumSignalFirstEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags16 sfTestFlags; + + bool bFirstResult = sfTestFlags.EnumSignalFirstEnumeratedFlagValue(1, 0, OU_UINT16_BITS); + + if (!bFirstResult || sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bSecondResult = sfTestFlags.EnumSignalFirstEnumeratedFlagValue(1, 0, OU_UINT16_BITS); + + if (bSecondResult || sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bThirdResult = sfTestFlags.EnumSignalFirstEnumeratedFlagValue(2, 0, OU_UINT16_BITS - 1); + + if (!bThirdResult || sfTestFlags.QueryFlagsAllValues() != 3) + { + break; + } + + bool bFourthResult = sfTestFlags.EnumSignalFirstEnumeratedFlagValue(1, OU_UINT16_BITS - 1, OU_UINT16_BITS); + + if (bFourthResult || sfTestFlags.QueryFlagsAllValues() != (uint16ou)(OU_INT16_MIN + 3)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags16_EnumSignalLastEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags16 sfTestFlags; + + bool bFirstResult = sfTestFlags.EnumSignalLastEnumeratedFlagValue(1, 0, 1); + + if (!bFirstResult || sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bSecondResult = sfTestFlags.EnumSignalLastEnumeratedFlagValue(1, 0, 1); + + if (bSecondResult || sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bThirdResult = sfTestFlags.EnumSignalLastEnumeratedFlagValue(1, 1, 2); + + if (!bThirdResult || sfTestFlags.QueryFlagsAllValues() != 3) + { + break; + } + + bool bFourthResult = sfTestFlags.EnumSignalLastEnumeratedFlagValue(1, OU_UINT16_BITS - 1, OU_UINT16_BITS); + + if (bFourthResult || sfTestFlags.QueryFlagsAllValues() != (uint16ou)(OU_INT16_MIN + 3)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags16_EnumGetEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags16 sfTestFlags((uint16ou)(OU_INT16_MIN + 1)); + + if (!sfTestFlags.EnumGetEnumeratedFlagValue(1, 0, OU_UINT16_BITS)) + { + break; + } + + if (sfTestFlags.EnumGetEnumeratedFlagValue(2, 0, OU_UINT16_BITS - 1)) + { + break; + } + + if (sfTestFlags.EnumGetEnumeratedFlagValue(1, 1, OU_UINT16_BITS - 1)) + { + break; + } + + if (!sfTestFlags.EnumGetEnumeratedFlagValue(1, OU_UINT16_BITS - 1, OU_UINT16_BITS)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags16_EnumFindFirstEnumeratedFlag() +{ + bool bResult = false; + + do + { + CSimpleFlags16 sfTestFlags((uint16ou)(OU_INT16_MIN + 1)); + + unsigned int uiFirstResult = sfTestFlags.EnumFindFirstEnumeratedFlag(1, OU_UINT16_BITS); + if (uiFirstResult != 0) + { + break; + } + + unsigned int uiSecondResult = sfTestFlags.EnumFindFirstEnumeratedFlag(2, OU_UINT16_BITS - 1); + if (uiSecondResult != OU_UINT16_BITS - 2) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags16_EnumAllSignalEnumeratedFlags() +{ + bool bResult = false; + + do + { + CSimpleFlags16 sfTestFlags; + + sfTestFlags.EnumAllSignalEnumeratedFlags(1, 1); + + if (sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + sfTestFlags.EnumAllSignalEnumeratedFlags(4, OU_UINT16_BITS - 2); + + if (sfTestFlags.QueryFlagsAllValues() != (uint16ou)(OU_UINT16_MAX ^ 2)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags16_EnumAllDropEnumeratedFlags() +{ + bool bResult = false; + + do + { + CSimpleFlags16 sfTestFlags(OU_UINT16_MAX); + + sfTestFlags.EnumAllDropEnumeratedFlags(1, 1); + + if (sfTestFlags.QueryFlagsAllValues() != (uint16ou)(OU_UINT16_MAX ^ 1)) + { + break; + } + + sfTestFlags.EnumAllDropEnumeratedFlags(4, OU_UINT16_BITS - 2); + + if (sfTestFlags.QueryFlagsAllValues() != 2) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags16_EnumAllQueryEnumeratedFlags() +{ + bool bResult = false; + + do + { + CSimpleFlags16 sfTestFlags((uint16ou)(OU_INT16_MIN + 1)); + + uint16ou uiFirstResult = sfTestFlags.EnumAllQueryEnumeratedFlags(1, OU_UINT16_BITS); + if (uiFirstResult != (uint16ou)(OU_INT16_MIN + 1)) + { + break; + } + + uint16ou uiSecondResult = sfTestFlags.EnumAllQueryEnumeratedFlags(2, OU_UINT16_BITS - 1); + if (uiSecondResult != (uint16ou)(OU_INT16_MIN)) + { + break; + } + + uint16ou uiThirdResult = sfTestFlags.EnumAllQueryEnumeratedFlags(2, OU_UINT16_BITS - 2); + if (uiThirdResult != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags16_EnumAnyGetEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags16 sfTestFlags((uint16ou)(OU_INT16_MIN + 1)); + + bool bFirstResult = sfTestFlags.EnumAnyGetEnumeratedFlagValue(1, OU_UINT16_BITS); + if (!bFirstResult) + { + break; + } + + bool bSecondResult = sfTestFlags.EnumAnyGetEnumeratedFlagValue(2, OU_UINT16_BITS - 1); + if (!bSecondResult) + { + break; + } + + bool bThirdResult = sfTestFlags.EnumAnyGetEnumeratedFlagValue(2, OU_UINT16_BITS - 2); + if (bThirdResult) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags16_StoreFlagsEnumeratedValue() +{ + bool bResult = false; + + do + { + CSimpleFlags16 sfTestFlags; + + sfTestFlags.StoreFlagsEnumeratedValue(0x03, 1, 2); + + if (sfTestFlags.QueryFlagsAllValues() != (uint16ou)(2 << 1)) + { + break; + } + + sfTestFlags.StoreFlagsEnumeratedValue(0x03, OU_UINT16_BITS - 2, 3); + + if (sfTestFlags.QueryFlagsAllValues() != ((uint16ou)(2 << 1) | (uint16ou)(OU_INT16_MIN | (OU_INT16_MIN >> 1)))) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags16_RetrieveFlagsEnumeratedValue() +{ + bool bResult = false; + + do + { + CSimpleFlags16 sfTestFlags((uint16ou)(OU_INT16_MIN + 1)); + + unsigned int uiFirstResult = sfTestFlags.RetrieveFlagsEnumeratedValue(0x3, 1); + if (uiFirstResult != 0) + { + break; + } + + unsigned int uiSecondResult = sfTestFlags.RetrieveFlagsEnumeratedValue(0x3, OU_UINT16_BITS - 2); + if (uiSecondResult != 2) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + + +enum EOUSIMPLEFLAGSFEATURE16 +{ + OSF16__MIN, + + OSF16_CONSTRUCTORS = OSF16__MIN, + OSF16_ASSIGNFLAGSALLVALUES, + OSF16_QUERYFLAGSALLVALUES, + OSF16_SETFLAGSMASKVALUE, + OSF16_SIGNALFLAGSMASKVALUE, + OSF16_DROPFLAGSMASKVALUE, + OSF16_TOGGLESINGLEFLAGVALUE, + OSF16_MODIFYSINGLEFLAGVALUE, + OSF16_ASSIGNFLAGSBYMASK, + OSF16_ALTERFLAGSBYMASK, + OSF16_GETFLAGSMASKVALUE, + OSF16_QUERYFLAGSBYMASK, + OSF16_ONLYSIGNALSINGLEFLAGOUTOFMASK, + OSF16_ENUMSETENUMERATEDFLAGVALUE, + OSF16_ENUMSIGNALENUMERATEDFLAGVALUE, + OSF16_ENUMDROPENUMERATEDFLAGVALUE, + OSF16_ENUMTOGGLEENUMERATEDFLAGVALUE, + OSF16_ENUMMODIFYENUMERATEDFLAGVALUE, + OSF16_ENUMSIGNALFIRSTENUMERATEDFLAGVALUE, + OSF16_ENUMSIGNALLASTENUMERATEDFLAGVALUE, + OSF16_ENUMGETENUMERATEDFLAGVALUE, + OSF16_ENUMFINDFIRSTENUMERATEDFLAG, + OSF16_ENUMALLSIGNALENUMERATEDFLAGS, + OSF16_ENUMALLDROPENUMERATEDFLAGS, + OSF16_ENUMALLQUERYENUMERATEDFLAGS, + OSF16_ENUMANYGETENUMERATEDFLAGVALUE, + OSF16_STOREFLAGSENUMERATEDVALUE, + OSF16_RETRIEVEFLAGSENUMERATEDVALUE, + + OSF16__MAX, +}; + +template<> +CFeatureTestProcedure const CEnumUnsortedElementArray<EOUSIMPLEFLAGSFEATURE16, OSF16__MAX, CFeatureTestProcedure>::m_aetElementArray[] = +{ + &TestSimpleFlags16_Constructors, // OSF16_CONSTRUCTORS + &TestSimpleFlags16_AssignFlagsAllValues, // OSF16_ASSIGNFLAGSALLVALUES, + &TestSimpleFlags16_QueryFlagsAllValues, // OSF16_QUERYFLAGSALLVALUES, + &TestSimpleFlags16_SetFlagsMaskValue, // OSF16_SETFLAGSMASKVALUE, + &TestSimpleFlags16_SignalFlagsMaskValue, // OSF16_SIGNALFLAGSMASKVALUE, + &TestSimpleFlags16_DropFlagsMaskValue, // OSF16_DROPFLAGSMASKVALUE, + &TestSimpleFlags16_ToggleSingleFlagValue, // OSF16_TOGGLESINGLEFLAGVALUE, + &TestSimpleFlags16_ModifySingleFlagValue, // OSF16_MODIFYSINGLEFLAGVALUE, + &TestSimpleFlags16_AssignFlagsByMask, // OSF16_ASSIGNFLAGSBYMASK, + &TestSimpleFlags16_AlterFlagsByMask, // OSF16_ALTERFLAGSBYMASK, + &TestSimpleFlags16_GetFlagsMaskValue, // OSF16_GETFLAGSMASKVALUE, + &TestSimpleFlags16_QueryFlagsByMask, // OSF16_QUERYFLAGSBYMASK, + &TestSimpleFlags16_OnlySignalSingleFlagOutOfMask, // OSF16_ONLYSIGNALSINGLEFLAGOUTOFMASK, + &TestSimpleFlags16_EnumSetEnumeratedFlagValue, // OSF16_ENUMSETENUMERATEDFLAGVALUE, + &TestSimpleFlags16_EnumSignalEnumeratedFlagValue, // OSF16_ENUMSIGNALENUMERATEDFLAGVALUE, + &TestSimpleFlags16_EnumDropEnumeratedFlagValue, // OSF16_ENUMDROPENUMERATEDFLAGVALUE, + &TestSimpleFlags16_EnumToggleEnumeratedFlagValue, // OSF16_ENUMTOGGLEENUMERATEDFLAGVALUE, + &TestSimpleFlags16_EnumModifyEnumeratedFlagValue, // OSF16_ENUMMODIFYENUMERATEDFLAGVALUE, + &TestSimpleFlags16_EnumSignalFirstEnumeratedFlagValue, // OSF16_ENUMSIGNALFIRSTENUMERATEDFLAGVALUE, + &TestSimpleFlags16_EnumSignalLastEnumeratedFlagValue, // OSF16_ENUMSIGNALLASTENUMERATEDFLAGVALUE, + &TestSimpleFlags16_EnumGetEnumeratedFlagValue, // OSF16_ENUMGETENUMERATEDFLAGVALUE, + &TestSimpleFlags16_EnumFindFirstEnumeratedFlag, // OSF16_ENUMFINDFIRSTENUMERATEDFLAG, + &TestSimpleFlags16_EnumAllSignalEnumeratedFlags, // OSF16_ENUMALLSIGNALENUMERATEDFLAGS, + &TestSimpleFlags16_EnumAllDropEnumeratedFlags, // OSF16_ENUMALLDROPENUMERATEDFLAGS, + &TestSimpleFlags16_EnumAllQueryEnumeratedFlags, // OSF16_ENUMALLQUERYENUMERATEDFLAGS, + &TestSimpleFlags16_EnumAnyGetEnumeratedFlagValue, // OSF16_ENUMANYGETENUMERATEDFLAGVALUE, + &TestSimpleFlags16_StoreFlagsEnumeratedValue, // OSF16_STOREFLAGSENUMERATEDVALUE, + &TestSimpleFlags16_RetrieveFlagsEnumeratedValue, // OSF16_RETRIEVEFLAGSENUMERATEDVALUE, +}; +static const CEnumUnsortedElementArray<EOUSIMPLEFLAGSFEATURE16, OSF16__MAX, CFeatureTestProcedure> g_afnSimpleFlags16FeatureTestProcedures; + +template<> +const char *const CEnumUnsortedElementArray<EOUSIMPLEFLAGSFEATURE16, OSF16__MAX, const char *>::m_aetElementArray[] = +{ + "Constructors", // OSF16_CONSTRUCTORS + "AssignFlagsAllValues", // OSF16_ASSIGNFLAGSALLVALUES, + "QueryFlagsAllValues", // OSF16_QUERYFLAGSALLVALUES, + "SetFlagsMaskValue", // OSF16_SETFLAGSMASKVALUE, + "SignalFlagsMaskValue", // OSF16_SIGNALFLAGSMASKVALUE, + "DropFlagsMaskValue", // OSF16_DROPFLAGSMASKVALUE, + "ToggleSingleFlagValue", // OSF16_TOGGLESINGLEFLAGVALUE, + "ModifySingleFlagValue", // OSF16_MODIFYSINGLEFLAGVALUE, + "AssignFlagsByMask", // OSF16_ASSIGNFLAGSBYMASK, + "AlterFlagsByMask", // OSF16_ALTERFLAGSBYMASK, + "GetFlagsMaskValue", // OSF16_GETFLAGSMASKVALUE, + "QueryFlagsByMask", // OSF16_QUERYFLAGSBYMASK, + "OnlySignalSingleFlagOutOfMask", // OSF16_ONLYSIGNALSINGLEFLAGOUTOFMASK, + "EnumSetEnumeratedFlagValue", // OSF16_ENUMSETENUMERATEDFLAGVALUE, + "EnumSignalEnumeratedFlagValue", // OSF16_ENUMSIGNALENUMERATEDFLAGVALUE, + "EnumDropEnumeratedFlagValue", // OSF16_ENUMDROPENUMERATEDFLAGVALUE, + "EnumToggleEnumeratedFlagValue", // OSF16_ENUMTOGGLEENUMERATEDFLAGVALUE, + "EnumModifyEnumeratedFlagValue", // OSF16_ENUMMODIFYENUMERATEDFLAGVALUE, + "EnumSignalFirstEnumeratedFlagValue", // OSF16_ENUMSIGNALFIRSTENUMERATEDFLAGVALUE, + "EnumSignalLastEnumeratedFlagValue", // OSF16_ENUMSIGNALLASTENUMERATEDFLAGVALUE, + "EnumGetEnumeratedFlagValue", // OSF16_ENUMGETENUMERATEDFLAGVALUE, + "EnumFindFirstEnumeratedFlag", // OSF16_ENUMFINDFIRSTENUMERATEDFLAG, + "EnumAllSignalEnumeratedFlags", // OSF16_ENUMALLSIGNALENUMERATEDFLAGS, + "EnumAllDropEnumeratedFlags", // OSF16_ENUMALLDROPENUMERATEDFLAGS, + "EnumAllQueryEnumeratedFlags", // OSF16_ENUMALLQUERYENUMERATEDFLAGS, + "EnumAnyGetEnumeratedFlagValue", // OSF16_ENUMANYGETENUMERATEDFLAGVALUE, + "StoreFlagsEnumeratedValue", // OSF16_STOREFLAGSENUMERATEDVALUE, + "RetrieveFlagsEnumeratedValue", // OSF16_RETRIEVEFLAGSENUMERATEDVALUE, +}; +static const CEnumUnsortedElementArray<EOUSIMPLEFLAGSFEATURE16, OSF16__MAX, const char *> g_aszSimpleFlags16FeatureTestNames; + + +bool TestSimpleFlags16(unsigned int &nOutSuccessCount, unsigned int &nOutTestCount) +{ + return TestSubsystem(nOutSuccessCount, nOutTestCount, OSF16__MAX, g_aszSimpleFlags16FeatureTestNames.GetStoragePointer(), g_afnSimpleFlags16FeatureTestProcedures.GetStoragePointer()); +} + + +////////////////////////////////////////////////////////////////////////// + +typedef CSimpleFlagsTemplate<uint8ou> CSimpleFlags8; + +const uint8ou g_uiTestValue8 = (uint8ou)0xA5; +const uint8ou g_uiTestMask8 = (uint8ou)0xC6; +const uint8ou g_uiTestBit8 = (uint8ou)OU_INT8_MIN; +const uint8ou g_uiTestAnotherBit8 = (uint8ou)((uint8ou)OU_INT8_MIN >> 1); + + +bool TestSimpleFlags8_Constructors() +{ + bool bResult = false; + + do + { + if (sizeof(CSimpleFlags8::value_type) != sizeof(uint8ou) || sizeof(CSimpleFlags8) != sizeof(uint8ou)) + { + break; + } + + CSimpleFlags8 sfEmptyFlags; + + if (sfEmptyFlags.QueryFlagsAllValues()) + { + break; + } + + CSimpleFlags8 sfFullFlags(OU_UINT8_MAX); + + if (sfFullFlags.QueryFlagsAllValues() != OU_UINT8_MAX) + { + break; + } + + CSimpleFlags8 sfCopyOfFullFlags(sfFullFlags); + + if (sfCopyOfFullFlags.QueryFlagsAllValues() != OU_UINT8_MAX) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags8_AssignFlagsAllValues() +{ + bool bResult = false; + + do + { + CSimpleFlags8 sfTestFlags; + + sfTestFlags.AssignFlagsAllValues(OU_UINT8_MAX); + + if (sfTestFlags.QueryFlagsAllValues() != OU_UINT8_MAX) + { + break; + } + + sfTestFlags.AssignFlagsAllValues(0); + + if (sfTestFlags.QueryFlagsAllValues() != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags8_QueryFlagsAllValues() +{ + bool bResult = false; + + do + { + CSimpleFlags8 sfTestFlags(g_uiTestValue8); + + if (sfTestFlags.QueryFlagsAllValues() != g_uiTestValue8) + { + break; + } + + // Double check to be sure ;-) + if (sfTestFlags.QueryFlagsAllValues() != g_uiTestValue8) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags8_SetFlagsMaskValue() +{ + bool bResult = false; + + do + { + CSimpleFlags8 sfTestFlags(g_uiTestValue8); + + sfTestFlags.SetFlagsMaskValue(g_uiTestMask8, true); + + if (sfTestFlags.QueryFlagsAllValues() != (uint8ou)(g_uiTestValue8 | g_uiTestMask8)) + { + break; + } + + sfTestFlags.SetFlagsMaskValue(g_uiTestValue8, false); + + if (sfTestFlags.QueryFlagsAllValues() != (uint8ou)(~g_uiTestValue8 & g_uiTestMask8)) + { + break; + } + + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags8_SignalFlagsMaskValue() +{ + bool bResult = false; + + do + { + CSimpleFlags8 sfTestFlags(g_uiTestValue8); + + sfTestFlags.SignalFlagsMaskValue(g_uiTestMask8); + + if (sfTestFlags.QueryFlagsAllValues() != (uint8ou)(g_uiTestValue8 | g_uiTestMask8)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags8_DropFlagsMaskValue() +{ + bool bResult = false; + + do + { + CSimpleFlags8 sfTestFlags(g_uiTestValue8); + + sfTestFlags.DropFlagsMaskValue(g_uiTestMask8); + + if (sfTestFlags.QueryFlagsAllValues() != (uint8ou)(g_uiTestValue8 & ~g_uiTestMask8)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags8_ToggleSingleFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags8 sfTestFlags(g_uiTestValue8); + + bool bPreviousValue = sfTestFlags.ToggleSingleFlagValue(g_uiTestBit8); + + if (bPreviousValue != ((g_uiTestValue8 & g_uiTestBit8) != 0) || sfTestFlags.QueryFlagsAllValues() != (uint8ou)(g_uiTestValue8 ^ g_uiTestBit8)) + { + break; + } + + bool bAnotherPreviousValue = sfTestFlags.ToggleSingleFlagValue(g_uiTestBit8); + + if (bAnotherPreviousValue == bPreviousValue || sfTestFlags.QueryFlagsAllValues() != g_uiTestValue8) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags8_ModifySingleFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags8 sfTestFlags(g_uiTestValue8); + + bool bFirstModification = sfTestFlags.ModifySingleFlagValue(g_uiTestBit8, true); + + if (bFirstModification != ((g_uiTestValue8 & g_uiTestBit8) != g_uiTestBit8) || sfTestFlags.QueryFlagsAllValues() != (uint8ou)(g_uiTestValue8 | g_uiTestBit8)) + { + break; + } + + bool bAnotherModification = sfTestFlags.ModifySingleFlagValue(g_uiTestBit8, bFirstModification); + + if (bAnotherModification == bFirstModification || sfTestFlags.QueryFlagsAllValues() != (bFirstModification ? (uint8ou)(g_uiTestValue8 | g_uiTestBit8) : (uint8ou)(g_uiTestValue8 & ~g_uiTestBit8))) + { + break; + } + + bool bYetAnotherModification = sfTestFlags.ModifySingleFlagValue(g_uiTestBit8, bAnotherModification); + + if (bYetAnotherModification != bAnotherModification || sfTestFlags.QueryFlagsAllValues() != (bAnotherModification ? (uint8ou)(g_uiTestValue8 | g_uiTestBit8) : (uint8ou)(g_uiTestValue8 & ~g_uiTestBit8))) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags8_AssignFlagsByMask() +{ + bool bResult = false; + + do + { + CSimpleFlags8 sfTestFlags(g_uiTestValue8); + + uint8ou uiPreviousFlags = sfTestFlags.AssignFlagsByMask(g_uiTestMask8, g_uiTestMask8); + + const uint8ou uiNewFlags = (g_uiTestValue8 & ~g_uiTestMask8) | g_uiTestMask8; + + if (uiPreviousFlags != g_uiTestValue8 || sfTestFlags.QueryFlagsAllValues() != uiNewFlags) + { + break; + } + + uint8ou uiAnotherPreviousFlags = sfTestFlags.AssignFlagsByMask(g_uiTestValue8, 0); + + const uint8ou uiAnotherNewFlags = uiNewFlags & ~g_uiTestValue8; + + if (uiAnotherPreviousFlags != uiNewFlags || sfTestFlags.QueryFlagsAllValues() != uiAnotherNewFlags) + { + break; + } + + uint8ou uiYetAnotherPreviousFlags = sfTestFlags.AssignFlagsByMask(g_uiTestMask8, g_uiTestMask8 & g_uiTestValue8); + OU_ASSERT((g_uiTestMask8 & g_uiTestValue8) != 0); // Test degeneration + + const uint8ou uiYetAnotherNewFlags = (uiAnotherNewFlags & ~g_uiTestMask8) | (g_uiTestMask8 & g_uiTestValue8); + OU_ASSERT(uiYetAnotherNewFlags != OU_UINT8_MAX); // Test degeneration + + if (uiYetAnotherPreviousFlags != uiAnotherNewFlags || sfTestFlags.QueryFlagsAllValues() != uiYetAnotherNewFlags) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags8_AlterFlagsByMask() +{ + bool bResult = false; + + do + { + CSimpleFlags8 sfTestFlags(g_uiTestValue8); + + bool bWasModification = sfTestFlags.AlterFlagsByMask(g_uiTestMask8, g_uiTestMask8); + + const uint8ou uiNewFlags = (g_uiTestValue8 & ~g_uiTestMask8) | g_uiTestMask8; + + if (bWasModification != ((g_uiTestValue8 & g_uiTestMask8) != g_uiTestMask8) || sfTestFlags.QueryFlagsAllValues() != uiNewFlags) + { + break; + } + + bool bWasAnotherModification = sfTestFlags.AlterFlagsByMask(g_uiTestValue8, 0); + + const uint8ou uiAnotherNewFlags = uiNewFlags & ~g_uiTestValue8; + + if (bWasAnotherModification != ((uiNewFlags & g_uiTestValue8) != 0) || sfTestFlags.QueryFlagsAllValues() != uiAnotherNewFlags) + { + break; + } + + bool bWasAnotherModificationRepeated = sfTestFlags.AlterFlagsByMask(g_uiTestValue8, 0); + + if (bWasAnotherModificationRepeated || sfTestFlags.QueryFlagsAllValues() != uiAnotherNewFlags) + { + break; + } + + bool bWasYetAnotherModification = sfTestFlags.AlterFlagsByMask(g_uiTestMask8, g_uiTestMask8 & g_uiTestValue8); + OU_ASSERT((g_uiTestMask8 & g_uiTestValue8) != 0); // Test degeneration + + const uint8ou uiYetAnotherNewFlags = (uiAnotherNewFlags & ~g_uiTestMask8) | (g_uiTestMask8 & g_uiTestValue8); + OU_ASSERT(uiYetAnotherNewFlags != OU_UINT8_MAX); // Test degeneration + + if (bWasYetAnotherModification != ((uiAnotherNewFlags & g_uiTestMask8) != (g_uiTestMask8 & g_uiTestValue8)) || sfTestFlags.QueryFlagsAllValues() != uiYetAnotherNewFlags) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags8_GetFlagsMaskValue() +{ + bool bResult = false; + + do + { + CSimpleFlags8 sfTestFlags(g_uiTestValue8); + + if (sfTestFlags.GetFlagsMaskValue(g_uiTestMask8) != ((g_uiTestValue8 & g_uiTestMask8) != 0)) + { + break; + } + + if (sfTestFlags.GetFlagsMaskValue((uint8ou)(~g_uiTestValue8))) + { + break; + } + + if (!sfTestFlags.GetFlagsMaskValue(OU_UINT8_MAX)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags8_QueryFlagsByMask() +{ + bool bResult = false; + + do + { + CSimpleFlags8 sfTestFlags(g_uiTestValue8); + + if (sfTestFlags.QueryFlagsByMask(g_uiTestMask8) != (uint8ou)(g_uiTestValue8 & g_uiTestMask8)) + { + break; + } + + if (sfTestFlags.QueryFlagsByMask(0)) + { + break; + } + + if (sfTestFlags.QueryFlagsByMask(OU_UINT8_MAX) != g_uiTestValue8) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags8_OnlySignalSingleFlagOutOfMask() +{ + bool bResult = false; + + do + { + CSimpleFlags8 sfTestFlags(g_uiTestValue8); + OU_ASSERT(g_uiTestValue8 != 0); // Test degeneration + + if (sfTestFlags.OnlySignalSingleFlagOutOfMask(OU_UINT8_MAX, g_uiTestBit8)) + { + break; + } + + if (sfTestFlags.QueryFlagsAllValues() != g_uiTestValue8) + { + break; + } + + sfTestFlags.AssignFlagsAllValues(0); + + if (!sfTestFlags.OnlySignalSingleFlagOutOfMask(g_uiTestBit8, g_uiTestBit8)) + { + break; + } + + if (sfTestFlags.QueryFlagsAllValues() != g_uiTestBit8) + { + break; + } + + if (sfTestFlags.OnlySignalSingleFlagOutOfMask(g_uiTestBit8, g_uiTestBit8)) + { + break; + } + + if (sfTestFlags.QueryFlagsAllValues() != g_uiTestBit8) + { + break; + } + + if (sfTestFlags.OnlySignalSingleFlagOutOfMask(OU_UINT8_MAX, g_uiTestAnotherBit8)) + { + break; + } + + if (sfTestFlags.QueryFlagsAllValues() != g_uiTestBit8) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags8_EnumSetEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags8 sfTestFlags; + + sfTestFlags.EnumSetEnumeratedFlagValue(1, 0, OU_UINT8_BITS, true); + + if (sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + sfTestFlags.EnumSetEnumeratedFlagValue(1, OU_UINT8_BITS - 1, OU_UINT8_BITS, true); + + if (sfTestFlags.QueryFlagsAllValues() != (uint8ou)(OU_INT8_MIN + 1)) + { + break; + } + + sfTestFlags.EnumSetEnumeratedFlagValue(1, 0, OU_UINT8_BITS, false); + + if (sfTestFlags.QueryFlagsAllValues() != (uint8ou)OU_INT8_MIN) + { + break; + } + + sfTestFlags.EnumSetEnumeratedFlagValue(1, OU_UINT8_BITS - 1, OU_UINT8_BITS, false); + + if (sfTestFlags.QueryFlagsAllValues() != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags8_EnumSignalEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags8 sfTestFlags; + + sfTestFlags.EnumSignalEnumeratedFlagValue(1, 0, OU_UINT8_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + sfTestFlags.EnumSignalEnumeratedFlagValue(1, OU_UINT8_BITS - 1, OU_UINT8_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (uint8ou)(OU_INT8_MIN + 1)) + { + break; + } + + sfTestFlags.EnumSignalEnumeratedFlagValue(1, 0, OU_UINT8_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (uint8ou)(OU_INT8_MIN + 1)) + { + break; + } + + sfTestFlags.EnumSignalEnumeratedFlagValue(1, OU_UINT8_BITS - 1, OU_UINT8_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (uint8ou)(OU_INT8_MIN + 1)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags8_EnumDropEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags8 sfTestFlags(OU_UINT8_MAX); + + sfTestFlags.EnumDropEnumeratedFlagValue(1, 0, OU_UINT8_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (OU_UINT8_MAX ^ 1)) + { + break; + } + + sfTestFlags.EnumDropEnumeratedFlagValue(1, OU_UINT8_BITS - 1, OU_UINT8_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (uint8ou)~(OU_INT8_MIN + 1)) + { + break; + } + + sfTestFlags.EnumDropEnumeratedFlagValue(1, 0, OU_UINT8_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (uint8ou)~(OU_INT8_MIN + 1)) + { + break; + } + + sfTestFlags.EnumDropEnumeratedFlagValue(1, OU_UINT8_BITS - 1, OU_UINT8_BITS); + + if (sfTestFlags.QueryFlagsAllValues() != (uint8ou)~(OU_INT8_MIN + 1)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags8_EnumToggleEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags8 sfTestFlags; + + bool bToggleFirstResult = sfTestFlags.EnumToggleEnumeratedFlagValue(1, 0, OU_UINT8_BITS); + + if (bToggleFirstResult || sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bToggleSecondResult = sfTestFlags.EnumToggleEnumeratedFlagValue(1, OU_UINT8_BITS - 1, OU_UINT8_BITS); + + if (bToggleSecondResult || sfTestFlags.QueryFlagsAllValues() != (uint8ou)(OU_INT8_MIN + 1)) + { + break; + } + + bool bToggleThirdResult = sfTestFlags.EnumToggleEnumeratedFlagValue(1, 0, OU_UINT8_BITS); + + if (!bToggleThirdResult || sfTestFlags.QueryFlagsAllValues() != (uint8ou)OU_INT8_MIN) + { + break; + } + + bool bToggleFourthResult = sfTestFlags.EnumToggleEnumeratedFlagValue(1, OU_UINT8_BITS - 1, OU_UINT8_BITS); + + if (!bToggleFourthResult || sfTestFlags.QueryFlagsAllValues() != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags8_EnumModifyEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags8 sfTestFlags; + + bool bModifyFirstResult = sfTestFlags.EnumModifyEnumeratedFlagValue(1, 0, OU_UINT8_BITS, true); + + if (!bModifyFirstResult || sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bModifySecondResult = sfTestFlags.EnumModifyEnumeratedFlagValue(1, OU_UINT8_BITS - 1, OU_UINT8_BITS, true); + + if (!bModifySecondResult || sfTestFlags.QueryFlagsAllValues() != (uint8ou)(OU_INT8_MIN + 1)) + { + break; + } + + bool bModifyThirdResult = sfTestFlags.EnumModifyEnumeratedFlagValue(1, 0, OU_UINT8_BITS, true); + + if (bModifyThirdResult || sfTestFlags.QueryFlagsAllValues() != (uint8ou)(OU_INT8_MIN + 1)) + { + break; + } + + bool bModifyFourthResult = sfTestFlags.EnumModifyEnumeratedFlagValue(1, OU_UINT8_BITS - 1, OU_UINT8_BITS, true); + + if (bModifyFourthResult || sfTestFlags.QueryFlagsAllValues() != (uint8ou)(OU_INT8_MIN + 1)) + { + break; + } + + bool bModifyFifthResult = sfTestFlags.EnumModifyEnumeratedFlagValue(1, 0, OU_UINT8_BITS, false); + + if (!bModifyFifthResult || sfTestFlags.QueryFlagsAllValues() != (uint8ou)OU_INT8_MIN) + { + break; + } + + bool bModifySixthResult = sfTestFlags.EnumModifyEnumeratedFlagValue(1, OU_UINT8_BITS - 1, OU_UINT8_BITS, false); + + if (!bModifySixthResult || sfTestFlags.QueryFlagsAllValues() != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags8_EnumSignalFirstEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags8 sfTestFlags; + + bool bFirstResult = sfTestFlags.EnumSignalFirstEnumeratedFlagValue(1, 0, OU_UINT8_BITS); + + if (!bFirstResult || sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bSecondResult = sfTestFlags.EnumSignalFirstEnumeratedFlagValue(1, 0, OU_UINT8_BITS); + + if (bSecondResult || sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bThirdResult = sfTestFlags.EnumSignalFirstEnumeratedFlagValue(2, 0, OU_UINT8_BITS - 1); + + if (!bThirdResult || sfTestFlags.QueryFlagsAllValues() != 3) + { + break; + } + + bool bFourthResult = sfTestFlags.EnumSignalFirstEnumeratedFlagValue(1, OU_UINT8_BITS - 1, OU_UINT8_BITS); + + if (bFourthResult || sfTestFlags.QueryFlagsAllValues() != (uint8ou)(OU_INT8_MIN + 3)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags8_EnumSignalLastEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags8 sfTestFlags; + + bool bFirstResult = sfTestFlags.EnumSignalLastEnumeratedFlagValue(1, 0, 1); + + if (!bFirstResult || sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bSecondResult = sfTestFlags.EnumSignalLastEnumeratedFlagValue(1, 0, 1); + + if (bSecondResult || sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + bool bThirdResult = sfTestFlags.EnumSignalLastEnumeratedFlagValue(1, 1, 2); + + if (!bThirdResult || sfTestFlags.QueryFlagsAllValues() != 3) + { + break; + } + + bool bFourthResult = sfTestFlags.EnumSignalLastEnumeratedFlagValue(1, OU_UINT8_BITS - 1, OU_UINT8_BITS); + + if (bFourthResult || sfTestFlags.QueryFlagsAllValues() != (uint8ou)(OU_INT8_MIN + 3)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags8_EnumGetEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags8 sfTestFlags((uint8ou)(OU_INT8_MIN + 1)); + + if (!sfTestFlags.EnumGetEnumeratedFlagValue(1, 0, OU_UINT8_BITS)) + { + break; + } + + if (sfTestFlags.EnumGetEnumeratedFlagValue(2, 0, OU_UINT8_BITS - 1)) + { + break; + } + + if (sfTestFlags.EnumGetEnumeratedFlagValue(1, 1, OU_UINT8_BITS - 1)) + { + break; + } + + if (!sfTestFlags.EnumGetEnumeratedFlagValue(1, OU_UINT8_BITS - 1, OU_UINT8_BITS)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags8_EnumFindFirstEnumeratedFlag() +{ + bool bResult = false; + + do + { + CSimpleFlags8 sfTestFlags((uint8ou)(OU_INT8_MIN + 1)); + + unsigned int uiFirstResult = sfTestFlags.EnumFindFirstEnumeratedFlag(1, OU_UINT8_BITS); + if (uiFirstResult != 0) + { + break; + } + + unsigned int uiSecondResult = sfTestFlags.EnumFindFirstEnumeratedFlag(2, OU_UINT8_BITS - 1); + if (uiSecondResult != OU_UINT8_BITS - 2) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags8_EnumAllSignalEnumeratedFlags() +{ + bool bResult = false; + + do + { + CSimpleFlags8 sfTestFlags; + + sfTestFlags.EnumAllSignalEnumeratedFlags(1, 1); + + if (sfTestFlags.QueryFlagsAllValues() != 1) + { + break; + } + + sfTestFlags.EnumAllSignalEnumeratedFlags(4, OU_UINT8_BITS - 2); + + if (sfTestFlags.QueryFlagsAllValues() != (uint8ou)(OU_UINT8_MAX ^ 2)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags8_EnumAllDropEnumeratedFlags() +{ + bool bResult = false; + + do + { + CSimpleFlags8 sfTestFlags(OU_UINT8_MAX); + + sfTestFlags.EnumAllDropEnumeratedFlags(1, 1); + + if (sfTestFlags.QueryFlagsAllValues() != (uint8ou)(OU_UINT8_MAX ^ 1)) + { + break; + } + + sfTestFlags.EnumAllDropEnumeratedFlags(4, OU_UINT8_BITS - 2); + + if (sfTestFlags.QueryFlagsAllValues() != 2) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags8_EnumAllQueryEnumeratedFlags() +{ + bool bResult = false; + + do + { + CSimpleFlags8 sfTestFlags((uint8ou)(OU_INT8_MIN + 1)); + + uint8ou uiFirstResult = sfTestFlags.EnumAllQueryEnumeratedFlags(1, OU_UINT8_BITS); + if (uiFirstResult != (uint8ou)(OU_INT8_MIN + 1)) + { + break; + } + + uint8ou uiSecondResult = sfTestFlags.EnumAllQueryEnumeratedFlags(2, OU_UINT8_BITS - 1); + if (uiSecondResult != (uint8ou)(OU_INT8_MIN)) + { + break; + } + + uint8ou uiThirdResult = sfTestFlags.EnumAllQueryEnumeratedFlags(2, OU_UINT8_BITS - 2); + if (uiThirdResult != 0) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags8_EnumAnyGetEnumeratedFlagValue() +{ + bool bResult = false; + + do + { + CSimpleFlags8 sfTestFlags((uint8ou)(OU_INT8_MIN + 1)); + + bool bFirstResult = sfTestFlags.EnumAnyGetEnumeratedFlagValue(1, OU_UINT8_BITS); + if (!bFirstResult) + { + break; + } + + bool bSecondResult = sfTestFlags.EnumAnyGetEnumeratedFlagValue(2, OU_UINT8_BITS - 1); + if (!bSecondResult) + { + break; + } + + bool bThirdResult = sfTestFlags.EnumAnyGetEnumeratedFlagValue(2, OU_UINT8_BITS - 2); + if (bThirdResult) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags8_StoreFlagsEnumeratedValue() +{ + bool bResult = false; + + do + { + CSimpleFlags8 sfTestFlags; + + sfTestFlags.StoreFlagsEnumeratedValue(0x03, 1, 2); + + if (sfTestFlags.QueryFlagsAllValues() != (uint8ou)(2 << 1)) + { + break; + } + + sfTestFlags.StoreFlagsEnumeratedValue(0x03, OU_UINT8_BITS - 2, 3); + + if (sfTestFlags.QueryFlagsAllValues() != ((uint8ou)(2 << 1) | (uint8ou)(OU_INT8_MIN | (OU_INT8_MIN >> 1)))) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestSimpleFlags8_RetrieveFlagsEnumeratedValue() +{ + bool bResult = false; + + do + { + CSimpleFlags8 sfTestFlags((uint8ou)(OU_INT8_MIN + 1)); + + unsigned int uiFirstResult = sfTestFlags.RetrieveFlagsEnumeratedValue(0x3, 1); + if (uiFirstResult != 0) + { + break; + } + + unsigned int uiSecondResult = sfTestFlags.RetrieveFlagsEnumeratedValue(0x3, OU_UINT8_BITS - 2); + if (uiSecondResult != 2) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + + +enum EOUSIMPLEFLAGSFEATURE8 +{ + OSF8__MIN, + + OSF8_CONSTRUCTORS = OSF8__MIN, + OSF8_ASSIGNFLAGSALLVALUES, + OSF8_QUERYFLAGSALLVALUES, + OSF8_SETFLAGSMASKVALUE, + OSF8_SIGNALFLAGSMASKVALUE, + OSF8_DROPFLAGSMASKVALUE, + OSF8_TOGGLESINGLEFLAGVALUE, + OSF8_MODIFYSINGLEFLAGVALUE, + OSF8_ASSIGNFLAGSBYMASK, + OSF8_ALTERFLAGSBYMASK, + OSF8_GETFLAGSMASKVALUE, + OSF8_QUERYFLAGSBYMASK, + OSF8_ONLYSIGNALSINGLEFLAGOUTOFMASK, + OSF8_ENUMSETENUMERATEDFLAGVALUE, + OSF8_ENUMSIGNALENUMERATEDFLAGVALUE, + OSF8_ENUMDROPENUMERATEDFLAGVALUE, + OSF8_ENUMTOGGLEENUMERATEDFLAGVALUE, + OSF8_ENUMMODIFYENUMERATEDFLAGVALUE, + OSF8_ENUMSIGNALFIRSTENUMERATEDFLAGVALUE, + OSF8_ENUMSIGNALLASTENUMERATEDFLAGVALUE, + OSF8_ENUMGETENUMERATEDFLAGVALUE, + OSF8_ENUMFINDFIRSTENUMERATEDFLAG, + OSF8_ENUMALLSIGNALENUMERATEDFLAGS, + OSF8_ENUMALLDROPENUMERATEDFLAGS, + OSF8_ENUMALLQUERYENUMERATEDFLAGS, + OSF8_ENUMANYGETENUMERATEDFLAGVALUE, + OSF8_STOREFLAGSENUMERATEDVALUE, + OSF8_RETRIEVEFLAGSENUMERATEDVALUE, + + OSF8__MAX, +}; + +template<> +CFeatureTestProcedure const CEnumUnsortedElementArray<EOUSIMPLEFLAGSFEATURE8, OSF8__MAX, CFeatureTestProcedure>::m_aetElementArray[] = +{ + &TestSimpleFlags8_Constructors, // OSF8_CONSTRUCTORS + &TestSimpleFlags8_AssignFlagsAllValues, // OSF8_ASSIGNFLAGSALLVALUES, + &TestSimpleFlags8_QueryFlagsAllValues, // OSF8_QUERYFLAGSALLVALUES, + &TestSimpleFlags8_SetFlagsMaskValue, // OSF8_SETFLAGSMASKVALUE, + &TestSimpleFlags8_SignalFlagsMaskValue, // OSF8_SIGNALFLAGSMASKVALUE, + &TestSimpleFlags8_DropFlagsMaskValue, // OSF8_DROPFLAGSMASKVALUE, + &TestSimpleFlags8_ToggleSingleFlagValue, // OSF8_TOGGLESINGLEFLAGVALUE, + &TestSimpleFlags8_ModifySingleFlagValue, // OSF8_MODIFYSINGLEFLAGVALUE, + &TestSimpleFlags8_AssignFlagsByMask, // OSF8_ASSIGNFLAGSBYMASK, + &TestSimpleFlags8_AlterFlagsByMask, // OSF8_ALTERFLAGSBYMASK, + &TestSimpleFlags8_GetFlagsMaskValue, // OSF8_GETFLAGSMASKVALUE, + &TestSimpleFlags8_QueryFlagsByMask, // OSF8_QUERYFLAGSBYMASK, + &TestSimpleFlags8_OnlySignalSingleFlagOutOfMask, // OSF8_ONLYSIGNALSINGLEFLAGOUTOFMASK, + &TestSimpleFlags8_EnumSetEnumeratedFlagValue, // OSF8_ENUMSETENUMERATEDFLAGVALUE, + &TestSimpleFlags8_EnumSignalEnumeratedFlagValue, // OSF8_ENUMSIGNALENUMERATEDFLAGVALUE, + &TestSimpleFlags8_EnumDropEnumeratedFlagValue, // OSF8_ENUMDROPENUMERATEDFLAGVALUE, + &TestSimpleFlags8_EnumToggleEnumeratedFlagValue, // OSF8_ENUMTOGGLEENUMERATEDFLAGVALUE, + &TestSimpleFlags8_EnumModifyEnumeratedFlagValue, // OSF8_ENUMMODIFYENUMERATEDFLAGVALUE, + &TestSimpleFlags8_EnumSignalFirstEnumeratedFlagValue, // OSF8_ENUMSIGNALFIRSTENUMERATEDFLAGVALUE, + &TestSimpleFlags8_EnumSignalLastEnumeratedFlagValue, // OSF8_ENUMSIGNALLASTENUMERATEDFLAGVALUE, + &TestSimpleFlags8_EnumGetEnumeratedFlagValue, // OSF8_ENUMGETENUMERATEDFLAGVALUE, + &TestSimpleFlags8_EnumFindFirstEnumeratedFlag, // OSF8_ENUMFINDFIRSTENUMERATEDFLAG, + &TestSimpleFlags8_EnumAllSignalEnumeratedFlags, // OSF8_ENUMALLSIGNALENUMERATEDFLAGS, + &TestSimpleFlags8_EnumAllDropEnumeratedFlags, // OSF8_ENUMALLDROPENUMERATEDFLAGS, + &TestSimpleFlags8_EnumAllQueryEnumeratedFlags, // OSF8_ENUMALLQUERYENUMERATEDFLAGS, + &TestSimpleFlags8_EnumAnyGetEnumeratedFlagValue, // OSF8_ENUMANYGETENUMERATEDFLAGVALUE, + &TestSimpleFlags8_StoreFlagsEnumeratedValue, // OSF8_STOREFLAGSENUMERATEDVALUE, + &TestSimpleFlags8_RetrieveFlagsEnumeratedValue, // OSF8_RETRIEVEFLAGSENUMERATEDVALUE, +}; +static const CEnumUnsortedElementArray<EOUSIMPLEFLAGSFEATURE8, OSF8__MAX, CFeatureTestProcedure> g_afnSimpleFlags8FeatureTestProcedures; + +template<> +const char *const CEnumUnsortedElementArray<EOUSIMPLEFLAGSFEATURE8, OSF8__MAX, const char *>::m_aetElementArray[] = +{ + "Constructors", // OSF8_CONSTRUCTORS + "AssignFlagsAllValues", // OSF8_ASSIGNFLAGSALLVALUES, + "QueryFlagsAllValues", // OSF8_QUERYFLAGSALLVALUES, + "SetFlagsMaskValue", // OSF8_SETFLAGSMASKVALUE, + "SignalFlagsMaskValue", // OSF8_SIGNALFLAGSMASKVALUE, + "DropFlagsMaskValue", // OSF8_DROPFLAGSMASKVALUE, + "ToggleSingleFlagValue", // OSF8_TOGGLESINGLEFLAGVALUE, + "ModifySingleFlagValue", // OSF8_MODIFYSINGLEFLAGVALUE, + "AssignFlagsByMask", // OSF8_ASSIGNFLAGSBYMASK, + "AlterFlagsByMask", // OSF8_ALTERFLAGSBYMASK, + "GetFlagsMaskValue", // OSF8_GETFLAGSMASKVALUE, + "QueryFlagsByMask", // OSF8_QUERYFLAGSBYMASK, + "OnlySignalSingleFlagOutOfMask", // OSF8_ONLYSIGNALSINGLEFLAGOUTOFMASK, + "EnumSetEnumeratedFlagValue", // OSF8_ENUMSETENUMERATEDFLAGVALUE, + "EnumSignalEnumeratedFlagValue", // OSF8_ENUMSIGNALENUMERATEDFLAGVALUE, + "EnumDropEnumeratedFlagValue", // OSF8_ENUMDROPENUMERATEDFLAGVALUE, + "EnumToggleEnumeratedFlagValue", // OSF8_ENUMTOGGLEENUMERATEDFLAGVALUE, + "EnumModifyEnumeratedFlagValue", // OSF8_ENUMMODIFYENUMERATEDFLAGVALUE, + "EnumSignalFirstEnumeratedFlagValue", // OSF8_ENUMSIGNALFIRSTENUMERATEDFLAGVALUE, + "EnumSignalLastEnumeratedFlagValue", // OSF8_ENUMSIGNALLASTENUMERATEDFLAGVALUE, + "EnumGetEnumeratedFlagValue", // OSF8_ENUMGETENUMERATEDFLAGVALUE, + "EnumFindFirstEnumeratedFlag", // OSF8_ENUMFINDFIRSTENUMERATEDFLAG, + "EnumAllSignalEnumeratedFlags", // OSF8_ENUMALLSIGNALENUMERATEDFLAGS, + "EnumAllDropEnumeratedFlags", // OSF8_ENUMALLDROPENUMERATEDFLAGS, + "EnumAllQueryEnumeratedFlags", // OSF8_ENUMALLQUERYENUMERATEDFLAGS, + "EnumAnyGetEnumeratedFlagValue", // OSF8_ENUMANYGETENUMERATEDFLAGVALUE, + "StoreFlagsEnumeratedValue", // OSF8_STOREFLAGSENUMERATEDVALUE, + "RetrieveFlagsEnumeratedValue", // OSF8_RETRIEVEFLAGSENUMERATEDVALUE, +}; +static const CEnumUnsortedElementArray<EOUSIMPLEFLAGSFEATURE8, OSF8__MAX, const char *> g_aszSimpleFlags8FeatureTestNames; + + +bool TestSimpleFlags8(unsigned int &nOutSuccessCount, unsigned int &nOutTestCount) +{ + return TestSubsystem(nOutSuccessCount, nOutTestCount, OSF8__MAX, g_aszSimpleFlags8FeatureTestNames.GetStoragePointer(), g_afnSimpleFlags8FeatureTestProcedures.GetStoragePointer()); +} + + +////////////////////////////////////////////////////////////////////////// + +bool TestFlagsDefines_EnumFlagsMask() +{ + bool bResult = false; + + do + { + int64ou iMask; + + iMask = OU_FLAGS_ENUMFLAGS_MASK(uint8ou, 1, 1); + if (iMask - 1 != 0) + { + break; + } + + iMask = OU_FLAGS_ENUMFLAGS_MASK(uint8ou, 1, OU_UINT8_BITS); + if (iMask ^ OU_UINT8_MAX) + { + break; + } + + iMask = OU_FLAGS_ENUMFLAGS_MASK(uint16ou, 1, 1); + if (iMask - 1 != 0) + { + break; + } + + iMask = OU_FLAGS_ENUMFLAGS_MASK(uint16ou, 1, OU_UINT16_BITS); + if (iMask ^ OU_UINT16_MAX) + { + break; + } + + iMask = OU_FLAGS_ENUMFLAGS_MASK(uint32ou, 1, 1); + if (iMask - 1 != 0) + { + break; + } + + iMask = OU_FLAGS_ENUMFLAGS_MASK(uint32ou, 1, OU_UINT32_BITS); + if (iMask ^ OU_UINT32_MAX) + { + break; + } + + iMask = OU_FLAGS_ENUMFLAGS_MASK(uint64ou, 1, 1); + if (iMask - 1 != 0) + { + break; + } + + iMask = OU_FLAGS_ENUMFLAGS_MASK(uint64ou, 1, OU_UINT64_BITS); + if (iMask ^ OU_UINT64_MAX) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestFlagsDefines_EnumFlagsStartValid() +{ + bool bResult = false; + + do + { + if (!OU_FLAGS_ENUMFLAGS_START_VALID(uint8ou, 1, OU_UINT8_BITS)) + { + break; + } +/* + if (OU_FLAGS_ENUMFLAGS_START_VALID(uint8ou, 1, OU_UINT8_BITS + 1)) + { + break; + } +*/ + if (!OU_FLAGS_ENUMFLAGS_START_VALID(uint16ou, 1, OU_UINT16_BITS)) + { + break; + } +/* + if (OU_FLAGS_ENUMFLAGS_START_VALID(uint16ou, 1, OU_UINT16_BITS + 1)) + { + break; + } +*/ + if (!OU_FLAGS_ENUMFLAGS_START_VALID(uint32ou, 1, OU_UINT32_BITS)) + { + break; + } +/* + if (OU_FLAGS_ENUMFLAGS_START_VALID(uint32ou, 1, OU_UINT32_BITS + 1)) + { + break; + } +*/ + if (!OU_FLAGS_ENUMFLAGS_START_VALID(uint64ou, 1, OU_UINT64_BITS)) + { + break; + } +/* + if (OU_FLAGS_ENUMFLAGS_START_VALID(uint64ou, 1, OU_UINT64_BITS + 1)) + { + break; + } +*/ + bResult = true; + } + while (false); + + return bResult; +} + +bool TestFlagsDefines_StoreEnumValueInMask() +{ + bool bResult = false; + + do + { + if (!OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint8ou, 0, 1) || !OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint8ou, 1, 1)) + { + break; + } + + if (!OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint8ou, 0, OU_UINT8_MAX) || !OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint8ou, OU_UINT8_MAX, OU_UINT8_MAX)) + { + break; + } + + if (OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint8ou, 1, 2) || OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint8ou, 2, 1)) + { + break; + } + + if (OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint8ou, 0, 0) || OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint8ou, 1, 0)) + { + break; + } + + if (!OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint16ou, 0, 1) || !OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint16ou, 1, 1)) + { + break; + } + + if (!OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint16ou, 0, OU_UINT16_MAX) || !OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint16ou, OU_UINT16_MAX, OU_UINT16_MAX)) + { + break; + } + + if (OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint16ou, 1, 2) || OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint16ou, 2, 1)) + { + break; + } + + if (OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint16ou, 0, 0) || OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint16ou, 1, 0)) + { + break; + } + + if (!OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint32ou, 0, 1) || !OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint32ou, 1, 1)) + { + break; + } + + if (!OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint32ou, 0, OU_UINT32_MAX) || !OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint32ou, OU_UINT32_MAX, OU_UINT32_MAX)) + { + break; + } + + if (OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint32ou, 1, 2) || OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint32ou, 2, 1)) + { + break; + } + + if (OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint32ou, 0, 0) || OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint32ou, 1, 0)) + { + break; + } + + if (!OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint64ou, 0, 1) || !OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint64ou, 1, 1)) + { + break; + } + + if (!OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint64ou, 0, OU_UINT64_MAX) || !OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint64ou, OU_UINT64_MAX, OU_UINT64_MAX)) + { + break; + } + + if (OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint64ou, 1, 2) || OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint64ou, 2, 1)) + { + break; + } + + if (OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint64ou, 0, 0) || OU_FLAGS_STOREENUM_VALUE_IN_MASK(uint64ou, 1, 0)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestFlagsDefines_FlagIsSingle() +{ + bool bResult = false; + + do + { + if (!OU_FLAGS_FLAG_IS_SINGLE(uint8ou, 1) || !OU_FLAGS_FLAG_IS_SINGLE(uint8ou, OU_INT8_MIN)) + { + break; + } + + if (OU_FLAGS_FLAG_IS_SINGLE(uint8ou, 0) || OU_FLAGS_FLAG_IS_SINGLE(uint8ou, 3) || OU_FLAGS_FLAG_IS_SINGLE(uint8ou, OU_INT8_MIN + 1)) + { + break; + } + + if (!OU_FLAGS_FLAG_IS_SINGLE(uint16ou, 1) || !OU_FLAGS_FLAG_IS_SINGLE(uint16ou, OU_INT16_MIN)) + { + break; + } + + if (OU_FLAGS_FLAG_IS_SINGLE(uint16ou, 0) || OU_FLAGS_FLAG_IS_SINGLE(uint16ou, 3) || OU_FLAGS_FLAG_IS_SINGLE(uint16ou, OU_INT16_MIN + 1)) + { + break; + } + + if (!OU_FLAGS_FLAG_IS_SINGLE(uint32ou, 1) || !OU_FLAGS_FLAG_IS_SINGLE(uint32ou, OU_INT32_MIN)) + { + break; + } + + if (OU_FLAGS_FLAG_IS_SINGLE(uint32ou, 0) || OU_FLAGS_FLAG_IS_SINGLE(uint32ou, 3) || OU_FLAGS_FLAG_IS_SINGLE(uint32ou, OU_INT32_MIN + 1)) + { + break; + } + + if (!OU_FLAGS_FLAG_IS_SINGLE(uint64ou, 1) || !OU_FLAGS_FLAG_IS_SINGLE(uint64ou, OU_INT64_MIN)) + { + break; + } + + if (OU_FLAGS_FLAG_IS_SINGLE(uint64ou, 0) || OU_FLAGS_FLAG_IS_SINGLE(uint64ou, 3) || OU_FLAGS_FLAG_IS_SINGLE(uint64ou, OU_INT64_MIN + 1)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + + +enum EOUFLAGSDEFINESFEATURE +{ + OFF__MIN, + + OFF_ENUMFLAGS_MASK = OFF__MIN, + OFF_ENUMFLAGS_START_VALID, + OFF_STOREENUM_VALUE_IN_MASK, + OFF_FLAG_IS_SINGLE, + + OFF__MAX, +}; + +template<> +CFeatureTestProcedure const CEnumUnsortedElementArray<EOUFLAGSDEFINESFEATURE, OFF__MAX, CFeatureTestProcedure>::m_aetElementArray[] = +{ + &TestFlagsDefines_EnumFlagsMask, // OFF_ENUMFLAGS_MASK, + &TestFlagsDefines_EnumFlagsStartValid, // OFF_ENUMFLAGS_START_VALID, + &TestFlagsDefines_StoreEnumValueInMask, // OFF_STOREENUM_VALUE_IN_MASK, + &TestFlagsDefines_FlagIsSingle, // OFF_FLAG_IS_SINGLE, +}; +static const CEnumUnsortedElementArray<EOUFLAGSDEFINESFEATURE, OFF__MAX, CFeatureTestProcedure> g_afnFlagsDefineFeatureTestProcedures; + +template<>const char *const CEnumUnsortedElementArray<EOUFLAGSDEFINESFEATURE, OFF__MAX, const char *>::m_aetElementArray[] = +{ + "ENUMFLAGS_MASK", // OFF_ENUMFLAGS_MASK = OFF__MIN, + "ENUMFLAGS_START_VALID", // OFF_ENUMFLAGS_START_VALID, + "STOREENUM_VALUE_IN_MASK", // OFF_STOREENUM_VALUE_IN_MASK, + "FLAG_IS_SINGLE", // OFF_FLAG_IS_SINGLE, +}; +static const CEnumUnsortedElementArray<EOUFLAGSDEFINESFEATURE, OFF__MAX, const char *> g_aszFlagsDefineFeatureTestNames; + + +bool TestFlagsDefines(unsigned int &nOutSuccessCount, unsigned int &nOutTestCount) +{ + return TestSubsystem(nOutSuccessCount, nOutTestCount, OFF__MAX, g_aszFlagsDefineFeatureTestNames.GetStoragePointer(), g_afnFlagsDefineFeatureTestProcedures.GetStoragePointer()); +} + + +////////////////////////////////////////////////////////////////////////// + +enum EENUMARRAYTESTENUM +{ + ATE__MIN, + + ATE_FIRSTELEMENT = ATE__MIN, + ATE_SECONDELEMENT, + ATE_THIRDELEMENT, + + ATE__MAX, +}; + +template<> +const int CEnumUnsortedElementArray<EENUMARRAYTESTENUM, ATE__MAX, int>::m_aetElementArray[] = +{ + 1, // ATE_FIRSTELEMENT, + 3, // ATE_SECONDELEMENT, + 2, // ATE_THIRDELEMENT, +}; +static const CEnumUnsortedElementArray<EENUMARRAYTESTENUM, ATE__MAX, int> g_ai_IntUnsortedArray; + +template<> +const int CEnumSortedElementArray<EENUMARRAYTESTENUM, ATE__MAX, int>::m_aetElementArray[] = +{ + 1, // ATE_FIRSTELEMENT, + 2, // ATE_SECONDELEMENT, + 3, // ATE_THIRDELEMENT, +}; +static const CEnumSortedElementArray<EENUMARRAYTESTENUM, ATE__MAX, int> g_ai_IntSortedArray; + +struct ConstCharPtrEq +{ + bool operator ()(const char *szLeftValue, const char *szRightValue) const + { + return strcmp(szLeftValue, szRightValue) == 0; + } +}; + +struct ConstCharPtrLess +{ + bool operator ()(const char *szLeftValue, const char *szRightValue) const + { + return strcmp(szLeftValue, szRightValue) < 0; + } +}; + +template<> +const char *const CEnumUnsortedElementArray<EENUMARRAYTESTENUM, ATE__MAX, const char *, 0, ConstCharPtrEq>::m_aetElementArray[] = +{ + "first", + "third", + "second", +}; +static const CEnumUnsortedElementArray<EENUMARRAYTESTENUM, ATE__MAX, const char *, 0, ConstCharPtrEq> g_aszStringUnsortedArray; + +template<> +const char *const CEnumSortedElementArray<EENUMARRAYTESTENUM, ATE__MAX, const char *, 0, ConstCharPtrLess>::m_aetElementArray[] = +{ + "first", + "second", + "third", +}; +static const CEnumSortedElementArray<EENUMARRAYTESTENUM, ATE__MAX, const char *, 0, ConstCharPtrLess> g_aszStringSortedArray; + + +bool TestEnumArrays_UnsortedArray() +{ + EENUMARRAYTESTENUM teEnumCurrent = ATE__MIN; + + for (; teEnumCurrent != ATE__MAX; ++teEnumCurrent) + { + int iCurrentValue = g_ai_IntUnsortedArray.Encode(teEnumCurrent); + EENUMARRAYTESTENUM teIntDecodeCheck = g_ai_IntUnsortedArray.Decode(iCurrentValue); + + if (!g_ai_IntUnsortedArray.IsValidDecode(teIntDecodeCheck) || teIntDecodeCheck != teEnumCurrent) + { + break; + } + + if (g_ai_IntUnsortedArray.GetStoragePointer()[teEnumCurrent] != iCurrentValue) + { + break; + } + + const char *szCurrentString = g_aszStringUnsortedArray.Encode(teEnumCurrent); + EENUMARRAYTESTENUM teStringDecodeCheck = g_aszStringUnsortedArray.Decode(szCurrentString); + + if (!g_aszStringUnsortedArray.IsValidDecode(teStringDecodeCheck) || teStringDecodeCheck != teEnumCurrent) + { + break; + } + + if (strcmp(g_aszStringUnsortedArray.GetStoragePointer()[teEnumCurrent], szCurrentString) != 0) + { + break; + } + + EENUMARRAYTESTENUM teInvalidDecodeCheck = g_aszStringUnsortedArray.Decode(szCurrentString + 1); + if (teInvalidDecodeCheck != ATE__MAX || g_aszStringUnsortedArray.IsValidDecode(teInvalidDecodeCheck)) + { + break; + } + } + + bool bResult = teEnumCurrent == ATE__MAX; + return bResult; +} + +bool TestEnumArrays_SortedArray() +{ + EENUMARRAYTESTENUM teEnumCurrent = ATE__MIN; + + for (; teEnumCurrent != ATE__MAX; ++teEnumCurrent) + { + int iCurrentValue = g_ai_IntSortedArray.Encode(teEnumCurrent); + EENUMARRAYTESTENUM teIntDecodeCheck = g_ai_IntSortedArray.Decode(iCurrentValue); + + if (!g_ai_IntSortedArray.IsValidDecode(teIntDecodeCheck) || teIntDecodeCheck != teEnumCurrent) + { + break; + } + + if (g_ai_IntSortedArray.GetStoragePointer()[teEnumCurrent] != iCurrentValue) + { + break; + } + + const char *szCurrentString = g_aszStringSortedArray.Encode(teEnumCurrent); + EENUMARRAYTESTENUM teStringDecodeCheck = g_aszStringSortedArray.Decode(szCurrentString); + + if (!g_aszStringSortedArray.IsValidDecode(teStringDecodeCheck) || teStringDecodeCheck != teEnumCurrent) + { + break; + } + + if (strcmp(g_aszStringSortedArray.GetStoragePointer()[teEnumCurrent], szCurrentString) != 0) + { + break; + } + + EENUMARRAYTESTENUM teInvalidDecodeCheck = g_aszStringSortedArray.Decode(szCurrentString + 1); + if (teInvalidDecodeCheck != ATE__MAX || g_aszStringSortedArray.IsValidDecode(teInvalidDecodeCheck)) + { + break; + } + } + + bool bResult = teEnumCurrent == ATE__MAX; + return bResult; +} + + +enum EOUENUMARRAYSFEATURE +{ + ORF__MIN, + + ORF_UNSORTEDARRAY = ORF__MIN, + ORF_SORTEDARRAY, + + ORF__MAX, +}; + +template<> +CFeatureTestProcedure const CEnumUnsortedElementArray<EOUENUMARRAYSFEATURE, ORF__MAX, CFeatureTestProcedure>::m_aetElementArray[] = +{ + &TestEnumArrays_UnsortedArray, // ORF_UNSORTEDARRAY, + &TestEnumArrays_SortedArray, // ORF_SORTEDARRAY, +}; +static const CEnumUnsortedElementArray<EOUENUMARRAYSFEATURE, ORF__MAX, CFeatureTestProcedure> g_afnEnumArrayFeatureTestProcedures; + +template<> +const char *const CEnumUnsortedElementArray<EOUENUMARRAYSFEATURE, ORF__MAX, const char *>::m_aetElementArray[] = +{ + "Unsorted Array", // ORF_UNSORTEDARRAY, + "Sorted Array", // ORF_SORTEDARRAY, +}; +static const CEnumUnsortedElementArray<EOUENUMARRAYSFEATURE, ORF__MAX, const char *> g_aszEnumArrayFeatureTestNames; + + +bool TestEnumArrays(unsigned int &nOutSuccessCount, unsigned int &nOutTestCount) +{ + return TestSubsystem(nOutSuccessCount, nOutTestCount, ORF__MAX, g_aszEnumArrayFeatureTestNames.GetStoragePointer(), g_afnEnumArrayFeatureTestProcedures.GetStoragePointer()); +} + + +////////////////////////////////////////////////////////////////////////// + +enum ETESTTEMPLATES8 +{ + TT8_ONE, + TT8_TWO, +}; + +enum ETESTTEMPLATES16 +{ + TT16_ONE = 1000, + TT16_TWO, +}; + +enum ETESTTEMPLATES32 +{ + TT32_ONE = 100000, + TT32_TWO, +}; + + +bool TestTemplates_PrefixIncrement() +{ + bool bResult = false; + + do + { + ETESTTEMPLATES8 t8Test = TT8_ONE; + ETESTTEMPLATES16 t16Test = TT16_ONE; + ETESTTEMPLATES32 t32Test = TT32_ONE; + + if (++t8Test != TT8_TWO || t8Test != TT8_TWO) + { + break; + } + + ++t8Test = TT8_ONE; + if (t8Test != TT8_ONE) + { + break; + } + + if (++t16Test != TT16_TWO || t16Test != TT16_TWO) + { + break; + } + + ++t16Test = TT16_ONE; + if (t16Test != TT16_ONE) + { + break; + } + + if (++t32Test != TT32_TWO || t32Test != TT32_TWO) + { + break; + } + + ++t32Test = TT32_ONE; + if (t32Test != TT32_ONE) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestTemplates_PostfixIncrement() +{ + bool bResult = false; + + do + { + ETESTTEMPLATES8 t8Test = TT8_ONE; + ETESTTEMPLATES16 t16Test = TT16_ONE; + ETESTTEMPLATES32 t32Test = TT32_ONE; + + if (t8Test++ != TT8_ONE || t8Test != TT8_TWO) + { + break; + } + + if (t16Test++ != TT16_ONE || t16Test != TT16_TWO) + { + break; + } + + if (t32Test++ != TT32_ONE || t32Test != TT32_TWO) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestTemplates_PrefixDecrement() +{ + bool bResult = false; + + do + { + ETESTTEMPLATES8 t8Test = TT8_TWO; + ETESTTEMPLATES16 t16Test = TT16_TWO; + ETESTTEMPLATES32 t32Test = TT32_TWO; + + if (--t8Test != TT8_ONE || t8Test != TT8_ONE) + { + break; + } + + --t8Test = TT8_TWO; + if (t8Test != TT8_TWO) + { + break; + } + + if (--t16Test != TT16_ONE || t16Test != TT16_ONE) + { + break; + } + + --t16Test = TT16_TWO; + if (t16Test != TT16_TWO) + { + break; + } + + if (--t32Test != TT32_ONE || t32Test != TT32_ONE) + { + break; + } + + --t32Test = TT32_TWO; + if (t32Test != TT32_TWO) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestTemplates_PostfixDecrement() +{ + bool bResult = false; + + do + { + ETESTTEMPLATES8 t8Test = TT8_TWO; + ETESTTEMPLATES16 t16Test = TT16_TWO; + ETESTTEMPLATES32 t32Test = TT32_TWO; + + if (t8Test-- != TT8_TWO || t8Test != TT8_ONE) + { + break; + } + + if (t16Test-- != TT16_TWO || t16Test != TT16_ONE) + { + break; + } + + if (t32Test-- != TT32_TWO || t32Test != TT32_ONE) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestTemplates_IsEmptySz() +{ + bool bResult = false; + + do + { + const char *szData = "a"; + const char *szEmpty = ""; + const char *szNull = NULL; + + if (IsEmptySz(szData) || !IsEmptySz(szEmpty) || !IsEmptySz(szNull)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + + +enum EOUTEMPLATESFEATURE +{ + OTF__MIN, + + OTF_PREFIXINCREMENT = OTF__MIN, + OTF_POSTFIXINCREMENT, + OTF_PREFIXDECREMENT, + OTF_POSTFIXDECREMENT, + OTF_ISEMPTYSZ, + + OTF__MAX, +}; + +template<> +CFeatureTestProcedure const CEnumUnsortedElementArray<EOUTEMPLATESFEATURE, OTF__MAX, CFeatureTestProcedure>::m_aetElementArray[] = +{ + &TestTemplates_PrefixIncrement, // OTF_PREFIXINCREMENT, + &TestTemplates_PostfixIncrement, // OTF_POSTFIXINCREMENT, + &TestTemplates_PrefixDecrement, // OTF_PREFIXDECREMENT, + &TestTemplates_PostfixDecrement, // OTF_POSTFIXDECREMENT, + &TestTemplates_IsEmptySz, // OTF_ISEMPTYSZ, +}; +static const CEnumUnsortedElementArray<EOUTEMPLATESFEATURE, OTF__MAX, CFeatureTestProcedure> g_afnTemplateFeatureTestProcedures; + +template<> +const char *const CEnumUnsortedElementArray<EOUTEMPLATESFEATURE, OTF__MAX, const char *>::m_aetElementArray[] = +{ + "Prefix Increment", // OTF_PREFIXINCREMENT, + "Postfix Increment", // OTF_POSTFIXINCREMENT, + "Prefix Decrement", // OTF_PREFIXDECREMENT, + "Postfix Decrement", // OTF_POSTFIXDECREMENT, + "IsEmptySz", // OTF_ISEMPTYSZ, +}; +static const CEnumUnsortedElementArray<EOUTEMPLATESFEATURE, OTF__MAX, const char *> g_aszTemplateFeatureTestNames; + + +bool TestTemplates(unsigned int &nOutSuccessCount, unsigned int &nOutTestCount) +{ + return TestSubsystem(nOutSuccessCount, nOutTestCount, OTF__MAX, g_aszTemplateFeatureTestNames.GetStoragePointer(), g_afnTemplateFeatureTestProcedures.GetStoragePointer()); +} + + +////////////////////////////////////////////////////////////////////////// + +typedef CTypeSimpleWrapper<int> CTestWrapper; + +bool TestTypeWrappers_Constructors() +{ + CTestWrapper twEmptyWrapper; + CTestWrapper twZeroWrapper(0); + CTestWrapper twCopyWrapper(twZeroWrapper); + + return true; +} + +bool TestTypeWrappers_Comparison() +{ + bool bResult = false; + + do + { + CTestWrapper twOneWrapper(1); + CTestWrapper twTwoWrapper(2); + + if (!(twTwoWrapper == twTwoWrapper) || twOneWrapper == twTwoWrapper) + { + break; + } + + if (twTwoWrapper != twTwoWrapper || !(twOneWrapper != twTwoWrapper)) + { + break; + } + + if (!(twOneWrapper < twTwoWrapper) || twTwoWrapper < twTwoWrapper || twTwoWrapper < twOneWrapper) + { + break; + } + + if (twOneWrapper > twTwoWrapper || twTwoWrapper > twTwoWrapper || !(twTwoWrapper > twOneWrapper)) + { + break; + } + + if (!(twOneWrapper <= twTwoWrapper) || !(twTwoWrapper <= twTwoWrapper) || twTwoWrapper <= twOneWrapper) + { + break; + } + + if (twOneWrapper >= twTwoWrapper || !(twTwoWrapper >= twTwoWrapper) || !(twTwoWrapper >= twOneWrapper)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestTypeWrappers_BoolCasts() +{ + bool bResult = false; + + do + { + CTestWrapper twZeroWrapper(0); + CTestWrapper twOneWrapper(1); +/* -- cast to bool is commented in definition + if (twZeroWrapper || !(false || twOneWrapper)) + { + break; + } +*/ + if (!(!twZeroWrapper) || !twOneWrapper) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestTypeWrappers_Assignment() +{ + bool bResult = false; + + do + { + CTestWrapper twZeroWrapper(0); + CTestWrapper twOneWrapper(1); + + CTestWrapper twTestWrapper; + + CTestWrapper &twFirstAssignmentReference = (twTestWrapper = (CTestWrapper::value_type)1); + + if (twTestWrapper != twOneWrapper || &twFirstAssignmentReference != &twTestWrapper) + { + break; + } + + CTestWrapper &twSecondAssignmentReference = (twTestWrapper = twZeroWrapper); + + if (twTestWrapper != twZeroWrapper || &twSecondAssignmentReference != &twTestWrapper) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestTypeWrappers_DataCast() +{ + bool bResult = false; + + do + { + const CTestWrapper twZeroWrapper(0); + CTestWrapper twOneWrapper(1); + + const CTestWrapper::value_type &wtZeroValue = (const CTestWrapper::value_type &)twZeroWrapper; + CTestWrapper::value_type &wtOneValue = (CTestWrapper::value_type &)twOneWrapper; + + if (wtZeroValue != 0 || wtOneValue != 1) + { + break; + } + + wtOneValue = 0; + + if (twOneWrapper != twZeroWrapper) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestTypeWrappers_DataComparison() +{ + bool bResult = false; + + do + { + const CTestWrapper twZeroWrapper(0); + const CTestWrapper twOneWrapper(1); + + const CTestWrapper::value_type &wtZeroValue = twZeroWrapper; + const CTestWrapper::value_type &wtOneValue = twOneWrapper; + + if (!(twZeroWrapper == wtZeroValue) || (twZeroWrapper == wtOneValue)) + { + break; + } + + if (!(wtZeroValue == twZeroWrapper) || (wtOneValue == twZeroWrapper)) + { + break; + } + + if ((twZeroWrapper != wtZeroValue) || !(twZeroWrapper != wtOneValue)) + { + break; + } + + if ((wtZeroValue != twZeroWrapper) || !(wtOneValue != twZeroWrapper)) + { + break; + } + + if ((twZeroWrapper < wtZeroValue) || !(twZeroWrapper < wtOneValue) || (twOneWrapper < wtZeroValue)) + { + break; + } + + if ((wtZeroValue < twZeroWrapper) || (wtOneValue < twZeroWrapper) || !(wtZeroValue < twOneWrapper)) + { + break; + } + + if ((twZeroWrapper > wtZeroValue) || (twZeroWrapper > wtOneValue) || !(twOneWrapper > wtZeroValue)) + { + break; + } + + if ((wtZeroValue > twZeroWrapper) || !(wtOneValue > twZeroWrapper) || (wtZeroValue > twOneWrapper)) + { + break; + } + + if (!(twZeroWrapper <= wtZeroValue) || !(twZeroWrapper <= wtOneValue) || (twOneWrapper <= wtZeroValue)) + { + break; + } + + if (!(wtZeroValue <= twZeroWrapper) || (wtOneValue <= twZeroWrapper) || !(wtZeroValue <= twOneWrapper)) + { + break; + } + + if (!(twZeroWrapper >= wtZeroValue) || (twZeroWrapper >= wtOneValue) || !(twOneWrapper >= wtZeroValue)) + { + break; + } + + if (!(wtZeroValue >= twZeroWrapper) || !(wtOneValue >= twZeroWrapper) || (wtZeroValue >= twOneWrapper)) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + + +enum EOUTYPEWRAPPERFEATURE +{ + OWF__MIN, + + OWF_CONSTRUCTORS = OWF__MIN, + OWF_COMPARISON, + OWF_BOOLCASTS, + OWF_ASSIGNMENT, + OWF_DATACAST, + OWF_DATACOMPARISON, + + OWF__MAX, +}; + +template<> +CFeatureTestProcedure const CEnumUnsortedElementArray<EOUTYPEWRAPPERFEATURE, OWF__MAX, CFeatureTestProcedure>::m_aetElementArray[] = +{ + &TestTypeWrappers_Constructors, // OWF_CONSTRUCTORS, + &TestTypeWrappers_Comparison, // OWF_COMPARISON, + &TestTypeWrappers_BoolCasts, // OWF_BOOLCASTS, + &TestTypeWrappers_Assignment, // OWF_ASSIGNMENT, + &TestTypeWrappers_DataCast, // OWF_DATACAST, + &TestTypeWrappers_DataComparison, // OWF_DATACOMPARISON, +}; +static const CEnumUnsortedElementArray<EOUTYPEWRAPPERFEATURE, OWF__MAX, CFeatureTestProcedure> g_afnTypeWrapperFeatureTestProcedures; + +template<> +const char *const CEnumUnsortedElementArray<EOUTYPEWRAPPERFEATURE, OWF__MAX, const char *>::m_aetElementArray[] = +{ + "Constructors", // OWF_CONSTRUCTORS, + "Comparison Operators", // OWF_COMPARISON, + "Boolean Casts", // OWF_BOOLCASTS, + "Assignment Operators", // OWF_ASSIGNMENT, + "Data Cast", // OWF_DATACAST, + "Data Comparisons", // OWF_DATACOMPARISON, +}; +static const CEnumUnsortedElementArray<EOUTYPEWRAPPERFEATURE, OWF__MAX, const char *> g_aszTypeWrapperFeatureTestNames; + + +bool TestTypeWrapper(unsigned int &nOutSuccessCount, unsigned int &nOutTestCount) +{ + return TestSubsystem(nOutSuccessCount, nOutTestCount, OWF__MAX, g_aszTypeWrapperFeatureTestNames.GetStoragePointer(), g_afnTypeWrapperFeatureTestProcedures.GetStoragePointer()); +} + + +////////////////////////////////////////////////////////////////////////// + +struct CTestCustomizations_Asserts_FailureInfo +{ + EASSERTIONFAILURESEVERITY m_fsFailureSeverity; + const char *m_szAssertionExpression; + const char *m_szAssertionFileName; + unsigned int m_uiAssertionSourceLine; +}; + +static const CTestCustomizations_Asserts_FailureInfo g_fiAssertInvalidInfo = { AFS__MAX, NULL, NULL, 0 }; +static CTestCustomizations_Asserts_FailureInfo g_fiAssertLastInfo; + +void _OU_CONVENTION_CALLBACK TestCustomizations_Asserts_AssertionFailure(EASSERTIONFAILURESEVERITY fsFailureSeverity, + const char *szAssertionExpression, const char *szAssertionFileName, unsigned int uiAssertionSourceLine) +{ + g_fiAssertLastInfo.m_fsFailureSeverity = fsFailureSeverity; + g_fiAssertLastInfo.m_szAssertionExpression = szAssertionExpression; + g_fiAssertLastInfo.m_szAssertionFileName = szAssertionFileName; + g_fiAssertLastInfo.m_uiAssertionSourceLine = uiAssertionSourceLine; +} + + +bool TestCustomizations_Asserts() +{ + bool bResult = false; + + CAssertionFailedProcedure fnAssertOldHandler = CAssertionCheckCustomization::GetAssertFailureCustomHandler(); + CAssertionCheckCustomization::CustomizeAssertionChecks(&TestCustomizations_Asserts_AssertionFailure); + + do + { +#if !defined(NDEBUG) + // Only callback invocation is checked here. + // Availability of functionality depending on preprocessor defines + // is verified in OST_ASSERT subsystem. + + OU_ASSERT(false); // const unsigned int uiAssertToVerifyLines = 14; -- see further in code + + if (g_fiAssertLastInfo.m_fsFailureSeverity != AFS_ASSERT + || g_fiAssertLastInfo.m_szAssertionExpression == NULL + || g_fiAssertLastInfo.m_szAssertionFileName == NULL + || strcmp(g_fiAssertLastInfo.m_szAssertionFileName, __FILE__) != 0 + || g_fiAssertLastInfo.m_uiAssertionSourceLine == 0) + { + break; + } + + CTestCustomizations_Asserts_FailureInfo fiAssertFailureInfoSave = g_fiAssertLastInfo; + g_fiAssertLastInfo = g_fiAssertInvalidInfo; + + OU_VERIFY(false); const unsigned int uiAssertToVerifyLines = 14; + + if (g_fiAssertLastInfo.m_fsFailureSeverity != AFS_ASSERT + || g_fiAssertLastInfo.m_szAssertionExpression == NULL + || strcmp(g_fiAssertLastInfo.m_szAssertionExpression, fiAssertFailureInfoSave.m_szAssertionExpression) != 0 + || g_fiAssertLastInfo.m_szAssertionFileName == NULL + || strcmp(g_fiAssertLastInfo.m_szAssertionFileName, __FILE__) != 0 + || g_fiAssertLastInfo.m_uiAssertionSourceLine != fiAssertFailureInfoSave.m_uiAssertionSourceLine + uiAssertToVerifyLines) + { + break; + } + + g_fiAssertLastInfo = g_fiAssertInvalidInfo; + + +#endif // #if !defined(NDEBUG) + +/* -- can't verify OU_CHECK() as it crashes the application on failure + OU_CHECK(false); + + if (g_fiAssertLastInfo.m_fsFailureSeverity != AFS_CHECK + || g_fiAssertLastInfo.m_szAssertionExpression == NULL + || g_fiAssertLastInfo.m_szAssertionFileName == NULL + || strcmp(g_fiAssertLastInfo.m_szAssertionFileName, __FILE__) != 0 + || g_fiAssertLastInfo.m_uiAssertionSourceLine == 0) + { + break; + } +*/ + bResult = true; + } + while (false); + + CAssertionCheckCustomization::CustomizeAssertionChecks(fnAssertOldHandler); + + return bResult; +} + +void *const g_pv_MallocResult = (void *)(size_t)0x12345678; +bool g_bMallocInvocation = false, g_bReallocInvocation = false; +bool g_bFreeInvocation = false, g_bFreeSuccess = false; + +void *_OU_CONVENTION_CALLBACK TestCustomizations_MemMgr_Alloc(size_t nBlockSize) +{ + g_bMallocInvocation = true; + return (void *)((ptrdiff_t)g_pv_MallocResult + nBlockSize); +} + +void *_OU_CONVENTION_CALLBACK TestCustomizations_MemMgr_Realloc(void *pv_OldBlock, size_t nBlockNewSize) +{ + g_bReallocInvocation = true; + return (void *)((ptrdiff_t)pv_OldBlock - nBlockNewSize); +} + +void _OU_CONVENTION_CALLBACK TestCustomizations_MemMgr_Free(void *pv_OldBlock) +{ + g_bFreeInvocation = true; + g_bFreeSuccess = pv_OldBlock == g_pv_MallocResult; +} + + +bool TestCustomizations_MemMgr() +{ + bool bResult = false; + + CMemoryAllocationProcedure fnAllocationOldProcedure = CMemoryManagerCustomization::GetMemoryAllocationCustomProcedure(); + CMemoryReallocationProcedure fnReallocationOldProcedure = CMemoryManagerCustomization::GetMemoryReallocationCustomProcedure(); + CMemoryDeallocationProcedure fnDeallocationOldProcedure = CMemoryManagerCustomization::GetMemoryDeallocationCustomProcedure(); + CMemoryManagerCustomization::CustomizeMemoryManager(&TestCustomizations_MemMgr_Alloc, &TestCustomizations_MemMgr_Realloc, &TestCustomizations_MemMgr_Free); + + do + { + const size_t nBlockSize = 0x1000; + + void *pv_BlockAllocated = AllocateMemoryBlock(nBlockSize); + + if (!g_bMallocInvocation + || pv_BlockAllocated != (void *)((size_t)g_pv_MallocResult + nBlockSize)) + { + break; + } + + void *pv_BlockReallocated = ReallocateMemoryBlock(pv_BlockAllocated, 2 * nBlockSize); + + if (!g_bReallocInvocation + || pv_BlockReallocated != (void *)((size_t)g_pv_MallocResult - nBlockSize)) + { + break; + } + + FreeMemoryBlock(g_pv_MallocResult); + + if (!g_bFreeInvocation || !g_bFreeSuccess) + { + break; + } + + bResult = true; + } + while (false); + + CMemoryManagerCustomization::CustomizeMemoryManager(fnAllocationOldProcedure, fnReallocationOldProcedure, fnDeallocationOldProcedure); + + return bResult; +} + + +enum EOUCUSTOMIZATIONFEATURE +{ + OCF__MIN, + + OCF_ASSERTS = OCF__MIN, + OCF_MEMMGR, + + OCF__MAX, +}; + +template<> +CFeatureTestProcedure const CEnumUnsortedElementArray<EOUCUSTOMIZATIONFEATURE, OCF__MAX, CFeatureTestProcedure>::m_aetElementArray[] = +{ + &TestCustomizations_Asserts, // OCF_ASSERTS, + &TestCustomizations_MemMgr, // OCF_MEMMGR, +}; +static const CEnumUnsortedElementArray<EOUCUSTOMIZATIONFEATURE, OCF__MAX, CFeatureTestProcedure> g_afnCustomizationFeatureTestProcedures; + +template<> +const char *const CEnumUnsortedElementArray<EOUCUSTOMIZATIONFEATURE, OCF__MAX, const char *>::m_aetElementArray[] = +{ + "Asserts", // OCF_ASSERTS, + "Memory Manager", // OCF_MEMMGR, +}; +static const CEnumUnsortedElementArray<EOUCUSTOMIZATIONFEATURE, OCF__MAX, const char *> g_aszCustomizationFeatureTestNames; + + +bool TestCustomization(unsigned int &nOutSuccessCount, unsigned int &nOutTestCount) +{ + return TestSubsystem(nOutSuccessCount, nOutTestCount, OCF__MAX, g_aszCustomizationFeatureTestNames.GetStoragePointer(), g_afnCustomizationFeatureTestProcedures.GetStoragePointer()); +} + + +////////////////////////////////////////////////////////////////////////// + +static const size_t g_nTestMallocBlockInitialSize = 1001; +static const size_t g_nTestMallocBlockNextSize = 65501; +static const uint8ou g_uiTestMallocToken = 0xAA; +static void *g_pv_MemoryBlock = NULL; + +bool TestMallocs_Allocate() +{ + bool bResult = false; + + do + { + g_pv_MemoryBlock = AllocateMemoryBlock(g_nTestMallocBlockInitialSize); + + if (g_pv_MemoryBlock == NULL || OU_ALIGNED_SIZE((size_t)g_pv_MemoryBlock, _OU_MEMORY_REQUIRED_ALIGNMENT) != (size_t)g_pv_MemoryBlock) + { + break; + } + + *((uint8ou *)g_pv_MemoryBlock + g_nTestMallocBlockInitialSize - 1) = g_uiTestMallocToken; + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestMallocs_Reallocate() +{ + OU_ASSERT(g_nTestMallocBlockNextSize > g_nTestMallocBlockInitialSize); + + bool bResult = false; + + do + { + void *pv_OldMemoryBlock = g_pv_MemoryBlock; + g_pv_MemoryBlock = ReallocateMemoryBlock(pv_OldMemoryBlock, g_nTestMallocBlockNextSize); + + if (g_pv_MemoryBlock == NULL || OU_ALIGNED_SIZE((size_t)g_pv_MemoryBlock, _OU_MEMORY_REQUIRED_ALIGNMENT) != (size_t)g_pv_MemoryBlock) + { + break; + } + + if (*((uint8ou *)g_pv_MemoryBlock + g_nTestMallocBlockInitialSize - 1) != g_uiTestMallocToken) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +bool TestMallocs_Deallocate() +{ + FreeMemoryBlock(g_pv_MemoryBlock); + + FreeMemoryBlock(NULL); // Free must survive NULL-pointer + + return true; +} + + +enum EOUMALLOCFEATURE +{ + OLF__MIN, + + OLF_ALLOCATE = OLF__MIN, + OLF_REALLOCATE, + OLF_DEALLOCATE, + + OLF__MAX, +}; + +template<> +CFeatureTestProcedure const CEnumUnsortedElementArray<EOUMALLOCFEATURE, OLF__MAX, CFeatureTestProcedure>::m_aetElementArray[] = +{ + &TestMallocs_Allocate, // OLF_ALLOCATE, + &TestMallocs_Reallocate, // OLF_REALLOCATE, + &TestMallocs_Deallocate, // OLF_DEALLOCATE, +}; +static const CEnumUnsortedElementArray<EOUMALLOCFEATURE, OLF__MAX, CFeatureTestProcedure> g_afnMallocFeatureTestProcedures; + +template<> +const char *const CEnumUnsortedElementArray<EOUMALLOCFEATURE, OLF__MAX, const char *>::m_aetElementArray[] = +{ + "AllocateMemoryBlock", // OLF_ALLOCATE, + "ReallocateMemoryBlock", // OLF_REALLOCATE, + "FreeMemoryBlock", // OLF_DEALLOCATE, +}; +static const CEnumUnsortedElementArray<EOUMALLOCFEATURE, OLF__MAX, const char *> g_aszMallocFeatureTestNames; + + +bool TestMalloc(unsigned int &nOutSuccessCount, unsigned int &nOutTestCount) +{ + return TestSubsystem(nOutSuccessCount, nOutTestCount, OLF__MAX, g_aszMallocFeatureTestNames.GetStoragePointer(), g_afnMallocFeatureTestProcedures.GetStoragePointer()); +} + + +////////////////////////////////////////////////////////////////////////// + +bool TestAsserts_FalseFunction(bool &bVarInvocation) +{ + bool bResult = true; + bVarInvocation = !bVarInvocation; + + bool *pv_Pointer = &bResult; + if (pv_Pointer) + { + bResult = false; + } + + return bResult; +} + +bool TestAsserts_TrueFunction(bool &bVarInvocation) +{ + bool bResult = false; + bVarInvocation = !bVarInvocation; + + bool *pv_Pointer = &bResult; + if (pv_Pointer) + { + bResult = true; + } + + return bResult; +} + +bool TestAsserts_Assert() +{ + bool bNDebugInvocation = false, bOrdinaryInvocation = false; + +#if defined(NDEBUG) + + OU_ASSERT(TestAsserts_FalseFunction(bNDebugInvocation)); + + bOrdinaryInvocation = true; + +#endif // #if defined(NDEBUG) + + OU_ASSERT(TestAsserts_TrueFunction(bOrdinaryInvocation)); + + return !bNDebugInvocation && bOrdinaryInvocation; +} + +bool TestAsserts_Verify() +{ + bool bNDebugInvocation = false, bOrdinaryInvocation = false; + +#if defined(NDEBUG) + + OU_VERIFY(TestAsserts_FalseFunction(bNDebugInvocation)); + + +#else // #if !defined(NDEBUG) + + bNDebugInvocation = true; + + +#endif // #if !defined(NDEBUG) + + OU_VERIFY(TestAsserts_TrueFunction(bOrdinaryInvocation)); + + return bNDebugInvocation && bOrdinaryInvocation; +} + +bool TestAsserts_Check() +{ + bool bOrdinaryInvocation = false; + + OU_CHECK(TestAsserts_TrueFunction(bOrdinaryInvocation)); + + return bOrdinaryInvocation; +} + + +enum EOUASSERTFEATURE +{ + OEF__MIN, + + OEF_ASSERT = OEF__MIN, + OEF_VERIFY, + OEF_CHECK, + + OEF__MAX, +}; + +template<> +CFeatureTestProcedure const CEnumUnsortedElementArray<EOUASSERTFEATURE, OEF__MAX, CFeatureTestProcedure>::m_aetElementArray[] = +{ + &TestAsserts_Assert, // OEF_ASSERT, + &TestAsserts_Verify, // OEF_VERIFY, + &TestAsserts_Check, // OEF_CHECK, + +}; +static const CEnumUnsortedElementArray<EOUASSERTFEATURE, OEF__MAX, CFeatureTestProcedure> g_afnAssertFeatureTestProcedures; + +template<> +const char *const CEnumUnsortedElementArray<EOUASSERTFEATURE, OEF__MAX, const char *>::m_aetElementArray[] = +{ + "OU_ASSERT", // OEF_ASSERT, + "OU_VERIFY", // OEF_VERIFY, + "OU_CHECK", // OEF_CHECK, +}; +static const CEnumUnsortedElementArray<EOUASSERTFEATURE, OEF__MAX, const char *> g_aszAssertFeatureTestNames; + + +bool TestAssert(unsigned int &nOutSuccessCount, unsigned int &nOutTestCount) +{ + return TestSubsystem(nOutSuccessCount, nOutTestCount, OEF__MAX, g_aszAssertFeatureTestNames.GetStoragePointer(), g_afnAssertFeatureTestProcedures.GetStoragePointer()); +} + + +////////////////////////////////////////////////////////////////////////// + +struct CTestIntTypes_int8 +{ + int8ou m_iPad; + int8ou m_iValue; +}; + +bool TestIntTypes_Int8() +{ + bool bResult = false; + + do + { + if (sizeof(int8ou) != 1 || offsetof(CTestIntTypes_int8, m_iValue) != 1) + { + break; + } + + if (OU_INT8_BITS != sizeof(int8ou) * OU_BITS_IN_BYTE ) + { + break; + } + + if ((int8ou)OU_INT8_MIN == 0 || (int8ou)(OU_INT8_MIN << 1) != 0) + { + break; + } + + if (~OU_INT8_MIN != OU_INT8_MAX || ~OU_INT8_MAX != OU_INT8_MIN) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +struct CTestIntTypes_uint8 +{ + int8ou m_iPad; + uint8ou m_iValue; +}; + +bool TestIntTypes_UInt8() +{ + bool bResult = false; + + do + { + if (sizeof(uint8ou) != 1 || offsetof(CTestIntTypes_uint8, m_iValue) != 1) + { + break; + } + + if (OU_UINT8_BITS != sizeof(uint8ou) * OU_BITS_IN_BYTE) + { + break; + } + + if (OU_UINT8_MIN != 0) + { + break; + } + + if (!(OU_UINT8_MAX & (uint8ou)1) || (OU_UINT8_MAX >> 1) != (uint8ou)OU_INT8_MAX) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +struct CTestIntTypes_int16 +{ + int8ou m_iPad; + int16ou m_iValue; +}; + +bool TestIntTypes_Int16() +{ + bool bResult = false; + + do + { + if (sizeof(int16ou) != 2 || offsetof(CTestIntTypes_int16, m_iValue) != 2) + { + break; + } + + if (OU_INT16_BITS != sizeof(int16ou) * OU_BITS_IN_BYTE ) + { + break; + } + + if ((int16ou)OU_INT16_MIN == 0 || (int16ou)(OU_INT16_MIN << 1) != 0) + { + break; + } + + if (~OU_INT16_MIN != OU_INT16_MAX || ~OU_INT16_MAX != OU_INT16_MIN) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +struct CTestIntTypes_uint16 +{ + int8ou m_iPad; + uint16ou m_iValue; +}; + +bool TestIntTypes_UInt16() +{ + bool bResult = false; + + do + { + if (sizeof(uint16ou) != 2 || offsetof(CTestIntTypes_uint16, m_iValue) != 2) + { + break; + } + + if (OU_UINT16_BITS != sizeof(uint16ou) * OU_BITS_IN_BYTE) + { + break; + } + + if (OU_UINT16_MIN != 0) + { + break; + } + + if (!(OU_UINT16_MAX & (uint16ou)1) || (OU_UINT16_MAX >> 1) != (uint16ou)OU_INT16_MAX) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +struct CTestIntTypes_int32 +{ + int8ou m_iPad; + int32ou m_iValue; +}; + +bool TestIntTypes_Int32() +{ + bool bResult = false; + + do + { + if (sizeof(int32ou) != 4 || offsetof(CTestIntTypes_int32, m_iValue) != 4) + { + break; + } + + if (OU_INT32_BITS != sizeof(int32ou) * OU_BITS_IN_BYTE ) + { + break; + } + + if ((int32ou)OU_INT32_MIN == 0 || (int32ou)(OU_INT32_MIN << 1) != 0) + { + break; + } + + if (~OU_INT32_MIN != OU_INT32_MAX || ~OU_INT32_MAX != OU_INT32_MIN) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +struct CTestIntTypes_uint32 +{ + int8ou m_iPad; + uint32ou m_iValue; +}; + +bool TestIntTypes_UInt32() +{ + bool bResult = false; + + do + { + if (sizeof(uint32ou) != 4 || offsetof(CTestIntTypes_uint32, m_iValue) != 4) + { + break; + } + + if (OU_UINT32_BITS != sizeof(uint32ou) * OU_BITS_IN_BYTE) + { + break; + } + + if (OU_UINT32_MIN != 0) + { + break; + } + + if (!(OU_UINT32_MAX & (uint32ou)1) || (OU_UINT32_MAX >> 1) != (uint32ou)OU_INT32_MAX) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +struct CTestIntTypes_int64 +{ + int8ou m_iPad; + int64ou m_iValue; +}; + +bool TestIntTypes_Int64() +{ + bool bResult = false; + + do + { + if (sizeof(int64ou) != 8) + { + break; + } + +#if _OU_TARGET_ARCH == _OU_TARGET_ARCH_X86 && _OU_TARGET_OS != _OU_TARGET_OS_MAC + + if (offsetof(CTestIntTypes_int64, m_iValue) != 8) + { + break; + } + + +#endif + + if (OU_INT64_BITS != sizeof(int64ou) * OU_BITS_IN_BYTE ) + { + break; + } + + if ((int64ou)OU_INT64_MIN == 0 || (int64ou)(OU_INT64_MIN << 1) != 0) + { + break; + } + + if (~OU_INT64_MIN != OU_INT64_MAX || ~OU_INT64_MAX != OU_INT64_MIN) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + +struct CTestIntTypes_uint64 +{ + int8ou m_iPad; + uint64ou m_iValue; +}; + +bool TestIntTypes_UInt64() +{ + bool bResult = false; + + do + { + if (sizeof(uint64ou) != 8) + { + break; + } + +#if _OU_TARGET_ARCH == _OU_TARGET_ARCH_X86 && _OU_TARGET_OS != _OU_TARGET_OS_MAC + + if (offsetof(CTestIntTypes_uint64, m_iValue) != 8) + { + break; + } + + +#endif + + if (OU_UINT64_BITS != sizeof(uint64ou) * OU_BITS_IN_BYTE) + { + break; + } + + if (OU_UINT64_MIN != 0) + { + break; + } + + if (!(OU_UINT64_MAX & (uint64ou)1) || (OU_UINT64_MAX >> 1) != (uint64ou)OU_INT64_MAX) + { + break; + } + + bResult = true; + } + while (false); + + return bResult; +} + + +enum EOUINTTYPEFEATURE +{ + OIF__MIN, + + OIF_INT8 = OIF__MIN, + OIF_UINT8, + OIF_INT16, + OIF_UINT16, + OIF_INT32, + OIF_UINT32, + OIF_INT64, + OIF_UINT64, + + OIF__MAX, +}; + +template<> +CFeatureTestProcedure const CEnumUnsortedElementArray<EOUINTTYPEFEATURE, OIF__MAX, CFeatureTestProcedure>::m_aetElementArray[] = +{ + &TestIntTypes_Int8, // OIF_INT8, + &TestIntTypes_UInt8, // OIF_UINT8, + &TestIntTypes_Int16, // OIF_INT16, + &TestIntTypes_UInt16, // OIF_UINT16, + &TestIntTypes_Int32, // OIF_INT32, + &TestIntTypes_UInt32, // OIF_UINT32, + &TestIntTypes_Int64, // OIF_INT64, + &TestIntTypes_UInt64, // OIF_UINT64, + +}; +static const CEnumUnsortedElementArray<EOUINTTYPEFEATURE, OIF__MAX, CFeatureTestProcedure> g_afnIntTypeFeatureTestProcedures; + +template<> +const char *const CEnumUnsortedElementArray<EOUINTTYPEFEATURE, OIF__MAX, const char *>::m_aetElementArray[] = +{ + "int8ou", // OIF_INT8, + "uint8ou", // OIF_UINT8, + "int16ou", // OIF_INT16, + "uint16ou", // OIF_UINT16, + "int32ou", // OIF_INT32, + "uint32ou", // OIF_UINT32, + "int64ou", // OIF_INT64, + "uint64ou", // OIF_UINT64, +}; +static const CEnumUnsortedElementArray<EOUINTTYPEFEATURE, OIF__MAX, const char *> g_aszIntTypeFeatureTestNames; + + +bool TestIntTypes(unsigned int &nOutSuccessCount, unsigned int &nOutTestCount) +{ + return TestSubsystem(nOutSuccessCount, nOutTestCount, OIF__MAX, g_aszIntTypeFeatureTestNames.GetStoragePointer(), g_afnIntTypeFeatureTestProcedures.GetStoragePointer()); +} + + +////////////////////////////////////////////////////////////////////////// + +struct CTestMacros_OffsetStruct +{ + int8ou m_i8a; + int16ou m_i16a; + int32ou m_i32a; + int64ou m_i64; + int32ou m_i32b; + int16ou m_i16b; + int8ou m_i8b; +}; + +bool TestMacros_OffsetOf() +{ + size_t sOffset_i8a = offsetof(CTestMacros_OffsetStruct, m_i8a); + size_t sOffset_i16a = offsetof(CTestMacros_OffsetStruct, m_i16a); + size_t sOffset_i32a = offsetof(CTestMacros_OffsetStruct, m_i32a); + size_t sOffset_i64 = offsetof(CTestMacros_OffsetStruct, m_i64); + size_t sOffset_i32b = offsetof(CTestMacros_OffsetStruct, m_i32b); + size_t sOffset_i16b = offsetof(CTestMacros_OffsetStruct, m_i16b); + size_t sOffset_i8b = offsetof(CTestMacros_OffsetStruct, m_i8b); + size_t sStructSize = sizeof(CTestMacros_OffsetStruct); + + return true + && sOffset_i8a == 0 + && sOffset_i16a == 2 + && sOffset_i32a == 4 + && sOffset_i64 == 8 + && sOffset_i32b == 16 + && sOffset_i16b == 20 + && sOffset_i8b == 22 + && sStructSize == 24; +} + +bool TestMacros_AlignedSize() +{ + return true + && OU_ALIGNED_SIZE(0, sizeof(int8ou)) == 0 + && OU_ALIGNED_SIZE(0, sizeof(int16ou)) == 0 + && OU_ALIGNED_SIZE(0, sizeof(int32ou)) == 0 + && OU_ALIGNED_SIZE(0, sizeof(int64ou)) == 0 + && OU_ALIGNED_SIZE(sizeof(int8ou), sizeof(int8ou)) == sizeof(int8ou) + && OU_ALIGNED_SIZE(sizeof(int8ou), sizeof(int16ou)) == sizeof(int16ou) + && OU_ALIGNED_SIZE(sizeof(int8ou), sizeof(int32ou)) == sizeof(int32ou) + && OU_ALIGNED_SIZE(sizeof(int8ou), sizeof(int64ou)) == sizeof(int64ou) + && OU_ALIGNED_SIZE(sizeof(int16ou), sizeof(int8ou)) == sizeof(int16ou) + && OU_ALIGNED_SIZE(sizeof(int16ou), sizeof(int16ou)) == sizeof(int16ou) + && OU_ALIGNED_SIZE(sizeof(int16ou), sizeof(int32ou)) == sizeof(int32ou) + && OU_ALIGNED_SIZE(sizeof(int16ou), sizeof(int64ou)) == sizeof(int64ou) + && OU_ALIGNED_SIZE(sizeof(int32ou), sizeof(int8ou)) == sizeof(int32ou) + && OU_ALIGNED_SIZE(sizeof(int32ou), sizeof(int16ou)) == sizeof(int32ou) + && OU_ALIGNED_SIZE(sizeof(int32ou), sizeof(int32ou)) == sizeof(int32ou) + && OU_ALIGNED_SIZE(sizeof(int32ou), sizeof(int64ou)) == sizeof(int64ou) + && OU_ALIGNED_SIZE(sizeof(int64ou), sizeof(int8ou)) == sizeof(int64ou) + && OU_ALIGNED_SIZE(sizeof(int64ou), sizeof(int16ou)) == sizeof(int64ou) + && OU_ALIGNED_SIZE(sizeof(int64ou), sizeof(int32ou)) == sizeof(int64ou) + && OU_ALIGNED_SIZE(sizeof(int64ou), sizeof(int64ou)) == sizeof(int64ou); +} + +bool TestMacros_ArraySize() +{ + static int m_ai_Array1[1]; + static int m_aai_Array11[1][1]; + static int m_ai_Array2[2]; + static int m_aai_Array21[2][1]; + static int m_aai_Array12[1][2]; + + return true + && OU_ARRAY_SIZE(m_ai_Array1) == 1 + && OU_ARRAY_SIZE(m_aai_Array11[0]) == 1 + && OU_ARRAY_SIZE(m_aai_Array11) == 1 + && OU_ARRAY_SIZE(m_ai_Array2) == 2 + && OU_ARRAY_SIZE(m_aai_Array21[0]) == 1 + && OU_ARRAY_SIZE(m_aai_Array21) == 2 + && OU_ARRAY_SIZE(m_aai_Array12[0]) == 2 + && OU_ARRAY_SIZE(m_aai_Array12) == 1; +} + +bool TestMacros_InIntRange() +{ + char iZero = 0; + char iOne = 1; + char iMinusOne = -1; + unsigned int uiTen = 10; + unsigned int uiNotZero = ~0U; + + return true + && !OU_IN_INT_RANGE(iZero, 0, 0) + && !OU_IN_INT_RANGE(iOne, 0, 0) + && !OU_IN_INT_RANGE(iMinusOne, 0, 0) + && !OU_IN_INT_RANGE(uiTen, 0, 0) + && !OU_IN_INT_RANGE(uiNotZero, 0, 0) + + && OU_IN_INT_RANGE(iZero, 0, 1) + && !OU_IN_INT_RANGE(iOne, 0, 1) + && !OU_IN_INT_RANGE(iMinusOne, 0, 1) + && !OU_IN_INT_RANGE(uiTen, 0, 1) + && !OU_IN_INT_RANGE(uiNotZero, 0, 1) + + && !OU_IN_INT_RANGE(iZero, 1, 2) + && OU_IN_INT_RANGE(iOne, 1, 2) + && !OU_IN_INT_RANGE(iMinusOne, 1, 2) + && !OU_IN_INT_RANGE(uiTen, 1, 2) + && !OU_IN_INT_RANGE(uiNotZero, 1, 2) + + && OU_IN_INT_RANGE(iZero, -1, 1) + && !OU_IN_INT_RANGE(iOne, -1, 1) + && OU_IN_INT_RANGE(iMinusOne, -1, 1) + && !OU_IN_INT_RANGE(uiTen, -1, 1) + && OU_IN_INT_RANGE(uiNotZero, -1, 1) + + && !OU_IN_INT_RANGE(iZero, 1, -1) + && OU_IN_INT_RANGE(iOne, 1, -1) + && !OU_IN_INT_RANGE(iMinusOne, 1, -1) + && OU_IN_INT_RANGE(uiTen, 1, -1) + && !OU_IN_INT_RANGE(uiNotZero, 1, -1); +} + +bool TestMacros_InI64Range() +{ + char iZero = 0; + char iOne = 1; + char iMinusOne = -1; + unsigned int uiTen = 10; + unsigned int uiNotZero = ~0U; + + return true + && !OU_IN_I64_RANGE(iZero, 0, 0) + && !OU_IN_I64_RANGE(iOne, 0, 0) + && !OU_IN_I64_RANGE(iMinusOne, 0, 0) + && !OU_IN_I64_RANGE(uiTen, 0, 0) + && !OU_IN_I64_RANGE(uiNotZero, 0, 0) + + && OU_IN_I64_RANGE(iZero, 0, 1) + && !OU_IN_I64_RANGE(iOne, 0, 1) + && !OU_IN_I64_RANGE(iMinusOne, 0, 1) + && !OU_IN_I64_RANGE(uiTen, 0, 1) + && !OU_IN_I64_RANGE(uiNotZero, 0, 1) + + && !OU_IN_I64_RANGE(iZero, 1, 2) + && OU_IN_I64_RANGE(iOne, 1, 2) + && !OU_IN_I64_RANGE(iMinusOne, 1, 2) + && !OU_IN_I64_RANGE(uiTen, 1, 2) + && !OU_IN_I64_RANGE(uiNotZero, 1, 2) + + && OU_IN_I64_RANGE(iZero, -1, 1) + && !OU_IN_I64_RANGE(iOne, -1, 1) + && OU_IN_I64_RANGE(iMinusOne, -1, 1) + && !OU_IN_I64_RANGE(uiTen, -1, 1) + && !OU_IN_I64_RANGE(uiNotZero, -1, 1) + + && !OU_IN_I64_RANGE(iZero, 1, -1) + && OU_IN_I64_RANGE(iOne, 1, -1) + && !OU_IN_I64_RANGE(iMinusOne, 1, -1) + && OU_IN_I64_RANGE(uiTen, 1, -1) + && OU_IN_I64_RANGE(uiNotZero, 1, -1); +} + +bool TestMacros_InSizetRange() +{ + char iZero = 0; + char iOne = 1; + char iMinusOne = -1; + unsigned int uiTen = 10; + unsigned int uiNotZero = ~0U; + + return true + && !OU_IN_SIZET_RANGE(iZero, 0, 0) + && !OU_IN_SIZET_RANGE(iOne, 0, 0) + && !OU_IN_SIZET_RANGE(iMinusOne, 0, 0) + && !OU_IN_SIZET_RANGE(uiTen, 0, 0) + && !OU_IN_SIZET_RANGE(uiNotZero, 0, 0) + + && OU_IN_SIZET_RANGE(iZero, 0, 1) + && !OU_IN_SIZET_RANGE(iOne, 0, 1) + && !OU_IN_SIZET_RANGE(iMinusOne, 0, 1) + && !OU_IN_SIZET_RANGE(uiTen, 0, 1) + && !OU_IN_SIZET_RANGE(uiNotZero, 0, 1) + + && !OU_IN_SIZET_RANGE(iZero, 1, 2) + && OU_IN_SIZET_RANGE(iOne, 1, 2) + && !OU_IN_SIZET_RANGE(iMinusOne, 1, 2) + && !OU_IN_SIZET_RANGE(uiTen, 1, 2) + && !OU_IN_SIZET_RANGE(uiNotZero, 1, 2) + + && OU_IN_SIZET_RANGE(iZero, -1, 1) + && !OU_IN_SIZET_RANGE(iOne, -1, 1) + && OU_IN_SIZET_RANGE(iMinusOne, -1, 1) + && !OU_IN_SIZET_RANGE(uiTen, -1, 1) + && OU_IN_SIZET_RANGE(uiNotZero, -1, 1) == (sizeof(size_t) == sizeof(unsigned int)) + + && !OU_IN_SIZET_RANGE(iZero, 1, -1) + && OU_IN_SIZET_RANGE(iOne, 1, -1) + && !OU_IN_SIZET_RANGE(iMinusOne, 1, -1) + && OU_IN_SIZET_RANGE(uiTen, 1, -1) + && OU_IN_SIZET_RANGE(uiNotZero, 1, -1) != (sizeof(size_t) == sizeof(unsigned int)); +} + + +enum EOUMACROFEATURE +{ + OMF__MIN, + + OMF_OFFSETOF = OMF__MIN, + OMF_ALIGNEDSIZE, + OMF_ARRAYSIZE, + OMF_ININTRANGE, + OMF_INI64RANGE, + OMF_INSIZETRANGE, + + OMF__MAX, +}; + +template<> +CFeatureTestProcedure const CEnumUnsortedElementArray<EOUMACROFEATURE, OMF__MAX, CFeatureTestProcedure>::m_aetElementArray[] = +{ + &TestMacros_OffsetOf, // OMF_OFFSETOF, + &TestMacros_AlignedSize, // OMF_ALIGNEDSIZE, + &TestMacros_ArraySize, // OMF_ARRAYSIZE, + &TestMacros_InIntRange, // OMF_ININTRANGE, + &TestMacros_InI64Range, // OMF_INI64RANGE, + &TestMacros_InSizetRange, // OMF_INSIZETRANGE, +}; +static const CEnumUnsortedElementArray<EOUMACROFEATURE, OMF__MAX, CFeatureTestProcedure> g_afnMacroFeatureTestProcedures; + +template<> +const char *const CEnumUnsortedElementArray<EOUMACROFEATURE, OMF__MAX, const char *>::m_aetElementArray[] = +{ + "offsetof", // OMF_OFFSETOF, + "OU_ALIGNED_SIZE", // OMF_ALIGNEDSIZE, + "OU_ARRAY_SIZE", // OMF_ARRAYSIZE, + "OU_IN_INT_RANGE", // OMF_ININTRANGE, + "OU_IN_I64_RANGE", // OMF_INI64RANGE, + "OU_IN_SIZET_RANGE", // OMF_INSIZETRANGE, +}; +static const CEnumUnsortedElementArray<EOUMACROFEATURE, OMF__MAX, const char *> g_aszMacroFeatureTestNames; + + +bool TestMacros(unsigned int &nOutSuccessCount, unsigned int &nOutTestCount) +{ + return TestSubsystem(nOutSuccessCount, nOutTestCount, OMF__MAX, g_aszMacroFeatureTestNames.GetStoragePointer(), g_afnMacroFeatureTestProcedures.GetStoragePointer()); +} + + +////////////////////////////////////////////////////////////////////////// + +// Verifies that target order is not changed +template<> +int const CEnumSortedElementArray<int, _OU_TARGET_OS__MAX - 1, int, 100>::m_aetElementArray[] = +{ + _OU_TARGET_OS_GENUNIX, // _OU_TARGET_OS_GENUNIX + _OU_TARGET_OS_WINDOWS, // _OU_TARGET_OS_WINDOWS + _OU_TARGET_OS_QNX, // _OU_TARGET_OS_QNX + _OU_TARGET_OS_MAC, // _OU_TARGET_OS_MAC + _OU_TARGET_OS_AIX, // _OU_TARGET_OS_AIX + _OU_TARGET_OS_SUNOS, // _OU_TARGET_OS_SUNOS + _OU_TARGET_OS_IOS, // _OU_TARGET_OS_IOS +}; +static const CEnumSortedElementArray<int, _OU_TARGET_OS__MAX - 1, int, 100> g_ai_TargetOrderCheck; + +template<> +const char *const CEnumUnsortedElementArray<int, _OU_TARGET_OS__MAX - 1, const char *, 100>::m_aetElementArray[] = +{ + "GENERIC UNIX", // _OU_TARGET_OS_GENUNIX + "WINDOWS", // _OU_TARGET_OS_WINDOWS + "QNX", // _OU_TARGET_OS_QNX + "MAC", // _OU_TARGET_OS_MAC + "AIX", // _OU_TARGET_OS_AIX + "SunOS", // _OU_TARGET_OS_SUNOS + "iOS", // _OU_TARGET_OS_IOS +}; +static const CEnumUnsortedElementArray<int, _OU_TARGET_OS__MAX - 1, const char *, 100> g_aszOSNames; + +// Verifies that bits order is not changed +template<> +int const CEnumSortedElementArray<int, _OU_TARGET_BITS__MAX - 1, int, 101>::m_aetElementArray[] = +{ + _OU_TARGET_BITS_32, // _OU_TARGET_BITS_32 + _OU_TARGET_BITS_64, // _OU_TARGET_BITS_64 +}; +static const CEnumSortedElementArray<int, _OU_TARGET_BITS__MAX - 1, int, 101> g_ai_BitsOrderCheck; + +template<> +const char *const CEnumUnsortedElementArray<int, _OU_TARGET_BITS__MAX - 1, const char *, 101>::m_aetElementArray[] = +{ + "32", // _OU_TARGET_BITS_32 + "64", // _OU_TARGET_BITS_64 +}; +static const CEnumUnsortedElementArray<int, _OU_TARGET_BITS__MAX - 1, const char *, 101> g_aszBitsNames; + +// Verifies that architectures order is not changed +template<> +int const CEnumSortedElementArray<int, _OU_TARGET_ARCH__MAX - 1, int, 102>::m_aetElementArray[] = +{ + _OU_TARGET_ARCH_OTHER, // _OU_TARGET_ARCH_OTHER + _OU_TARGET_ARCH_X86, // _OU_TARGET_ARCH_X86 + _OU_TARGET_ARCH_IA64, // _OU_TARGET_ARCH_IA64 + _OU_TARGET_ARCH_X64, // _OU_TARGET_ARCH_X64 + _OU_TARGET_ARCH_POWERPC, // _OU_TARGET_ARCH_POWERPC + _OU_TARGET_ARCH_SPARC, // _OU_TARGET_ARCH_SPARC + _OU_TARGET_ARCH_ARM, // _OU_TARGET_ARCH_ARM +}; +static const CEnumSortedElementArray<int, _OU_TARGET_ARCH__MAX - 1, int, 102> g_ai_ArchitecturesOrderCheck; + +template<> +const char *const CEnumUnsortedElementArray<int, _OU_TARGET_ARCH__MAX - 1, const char *, 102>::m_aetElementArray[] = +{ + "OTHER", // _OU_TARGET_ARCH_OTHER + "x86", // _OU_TARGET_ARCH_X86 + "Itanium", // _OU_TARGET_ARCH_IA64 + "x64", // _OU_TARGET_ARCH_X64 + "PowerPC", // _OU_TARGET_ARCH_POWERPC + "Sparc", // _OU_TARGET_ARCH_SPARC + "ARM", // _OU_TARGET_ARCH_ARM +}; +static const CEnumUnsortedElementArray<int, _OU_TARGET_ARCH__MAX - 1, const char *, 102> g_aszArchitecturesNames; + +// Verifies that compilers order is not changed +template<> +int const CEnumSortedElementArray<int, _OU_COMPILER__MAX - 1, int, 103>::m_aetElementArray[] = +{ + _OU_COMPILER__OTHER, // _OU_COMPILER__OTHER, + _OU_COMPILER_GCC, // _OU_COMPILER_GCC, + _OU_COMPILER_MSVC, // _OU_COMPILER_MSVC, +}; +static const CEnumSortedElementArray<int, _OU_COMPILER__MAX - 1, int, 103> g_ai_CompilersOrderCheck; + +template<> +const char *const CEnumUnsortedElementArray<int, _OU_COMPILER__MAX - 1, const char *, 103>::m_aetElementArray[] = +{ + "UNKNOWN", // _OU_COMPILER__OTHER, + "GCC", // _OU_COMPILER_GCC, + "MSVC", // _OU_COMPILER_MSVC, +}; +static const CEnumUnsortedElementArray<int, _OU_COMPILER__MAX - 1, const char *, 103> g_aszCompilersNames; + +// Verifies that compiler versions order is not changed +template<> +int const CEnumSortedElementArray<int, _OU_COMPILER_VERSION__MAX - 1, int, 104>::m_aetElementArray[] = +{ + _OU_COMPILER_VERSION__OTHER, // _OU_COMPILER_VERSION__OTHER, + _OU_COMPILER_VERSION_MSVC1998, // _OU_COMPILER_VERSION_MSVC1998, + _OU_COMPILER_VERSION_GCCLT4, // _OU_COMPILER_VERSION_GCCLT4, +}; +static const CEnumSortedElementArray<int, _OU_COMPILER_VERSION__MAX - 1, int, 104> g_ai_CompilersVersionOrderCheck; + +template<> +const char *const CEnumUnsortedElementArray<int, _OU_COMPILER_VERSION__MAX - 1, const char *, 104>::m_aetElementArray[] = +{ + "OTHER", // _OU_COMPILER_VERSION__OTHER, + "MSVC1998", // _OU_COMPILER_VERSION_MSVC1998, + "GCC LESS THAN 4.0", // _OU_COMPILER_VERSION_GCCLT4, +}; +static const CEnumUnsortedElementArray<int, _OU_COMPILER_VERSION__MAX - 1, const char *, 104> g_aszCompilerVersionNames; + + +#define _TESTPLATFORM_DEFINITION_TEXT(Definition) #Definition +#define TESTPLATFORM_TEFINITION_TEXT(Definition) _TESTPLATFORM_DEFINITION_TEXT(Definition) + +bool TestPlatform(unsigned int &nOutSuccessCount, unsigned int &nOutTestCount) +{ + const char *szOSName = g_aszOSNames.Encode(_OU_TARGET_OS - 1); + const char *szBitsName = g_aszBitsNames.Encode(_OU_TARGET_BITS - 1); + const char *szArchitectureName = g_aszArchitecturesNames.Encode(_OU_TARGET_ARCH - 1); + const char *szCompilerName = g_aszCompilersNames.Encode(_OU_COMPILER - 1); + const char *szCompilerVersion = g_aszCompilerVersionNames.Encode(_OU_COMPILER_VERSION - 1); + + printf("Target OS: %s\n", szOSName); + printf("Target Bits: %s\n", szBitsName); + printf("Target Architecture %s\n", szArchitectureName); + printf("Compiler Name: %s\n", szCompilerName); + printf("Compiler Version: %s\n", szCompilerVersion); + printf("Method Convention: %s\n", TESTPLATFORM_TEFINITION_TEXT(=_OU_CONVENTION_METHOD)); + printf("Function Convention: %s\n", TESTPLATFORM_TEFINITION_TEXT(=_OU_CONVENTION_API)); + printf("Callback Convention: %s\n", TESTPLATFORM_TEFINITION_TEXT(=_OU_CONVENTION_CALLBACK)); + printf("Alwaysinline definition: %s\n", TESTPLATFORM_TEFINITION_TEXT(=_OU_ALWAYSINLINE)); + printf("Inline definition: %s\n", TESTPLATFORM_TEFINITION_TEXT(=_OU_INLINE)); + + nOutSuccessCount = 0; + nOutTestCount = 0; + return true; +} + + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +enum EOUSUBSYSTEMTEST +{ + OST__MIN, + + OST_INTTYPES = OST__MIN, + OST_MACROS, + OST_TEMPLATES, + OST_TYPEWRAPPER, + OST_ASSERT, + OST_MALLOC, + OST_CUSTOMIZATION, + OST_ENUMARRAYS, +#if _OU_FEATURE_SET >= _OU_FEATURE_SET_ATOMICS + OST_ATOMIC, +#endif + OST_FLAGSDEFINES, +#if _OU_FEATURE_SET >= _OU_FEATURE_SET_ATOMICS + OST_ATOMICFLAGS, +#endif + OST_SIMPLEFLAGS64, + OST_SIMPLEFLAGS32, + OST_SIMPLEFLAGS16, + OST_SIMPLEFLAGS8, +#if _OU_FEATURE_SET >= _OU_FEATURE_SET_TLS + OST_TLS, +#endif + OST_PLATFORM, + + OST__MAX, +}; + +typedef bool (*COUSubsystemTestProcedure)(unsigned int &nOutSuccessCount, unsigned int &nOutTestCount); + +template<> +COUSubsystemTestProcedure const CEnumUnsortedElementArray<EOUSUBSYSTEMTEST, OST__MAX, COUSubsystemTestProcedure>::m_aetElementArray[] = +{ + &TestIntTypes, // OST_INTTYPES, + &TestMacros, // OST_MACROS, + &TestTemplates, // OST_TEMPLATES, + &TestTypeWrapper, // OST_TYPEWRAPPER, + &TestAssert, // OST_ASSERT, + &TestMalloc, // OST_MALLOC, + &TestCustomization, // OST_CUSTOMIZATION, + &TestEnumArrays, // OST_ENUMARRAYS, +#if _OU_FEATURE_SET >= _OU_FEATURE_SET_ATOMICS + &TestAtomic, // OST_ATOMIC, +#endif + &TestFlagsDefines, // OST_FLAGSDEFINES, +#if _OU_FEATURE_SET >= _OU_FEATURE_SET_ATOMICS + &TestAtomicFlags, // OST_ATOMICFLAGS, +#endif + &TestSimpleFlags64, // OST_SIMPLEFLAGS64, + &TestSimpleFlags32, // OST_SIMPLEFLAGS32, + &TestSimpleFlags16, // OST_SIMPLEFLAGS16, + &TestSimpleFlags8, // OST_SIMPLEFLAGS8, +#if _OU_FEATURE_SET >= _OU_FEATURE_SET_TLS + &TestTLS, // OST_TLS, +#endif + &TestPlatform, // OST_PLATFORM, +}; +static const CEnumUnsortedElementArray<EOUSUBSYSTEMTEST, OST__MAX, COUSubsystemTestProcedure> g_afnOUSubsystemTestProcedures; + +template<> +const char *const CEnumUnsortedElementArray<EOUSUBSYSTEMTEST, OST__MAX, const char *>::m_aetElementArray[] = +{ + "IntTypes", // OST_INTTYPES, + "Macros", // OST_MACROS, + "Templates", // OST_TEMPLATES, + "TypeWrapper", // OST_TYPEWRAPPER, + "Assert", // OST_ASSERT, + "Malloc", // OST_MALLOC, + "Customization", // OST_CUSTOMIZATION, + "EnumArrays", // OST_ENUMARRAYS, +#if _OU_FEATURE_SET >= _OU_FEATURE_SET_ATOMICS + "Atomic", // OST_ATOMIC, +#endif + "FlagsDefines", // OST_FLAGSDEFINES, +#if _OU_FEATURE_SET >= _OU_FEATURE_SET_ATOMICS + "AtomicFlags", // OST_ATOMICFLAGS, +#endif + "SimpleFlags64", // OST_SIMPLEFLAGS64, + "SimpleFlags32", // OST_SIMPLEFLAGS32, + "SimpleFlags16", // OST_SIMPLEFLAGS16, + "SimpleFlags8", // OST_SIMPLEFLAGS8, +#if _OU_FEATURE_SET >= _OU_FEATURE_SET_TLS + "TLS", // OST_TLS, +#endif + "Platform", // OST_PLATFORM, +}; +static const CEnumUnsortedElementArray<EOUSUBSYSTEMTEST, OST__MAX, const char *> g_aszOUSubsystemNames; + + +bool ProcessOUCoverageTests(unsigned int &nOutFailureCount) +{ + unsigned int nSuccessCount = 0; + + for (EOUSUBSYSTEMTEST stSubsystemTest = OST__MIN; stSubsystemTest != OST__MAX; ++stSubsystemTest) + { + const char *szSubsystemName = g_aszOUSubsystemNames.Encode(stSubsystemTest); + printf("\nTesting subsystem \"%s\"\n", szSubsystemName); + printf("---------------------------------------------------\n"); + + unsigned int nSubsysytemSuccessCount = 0, nSubsystemTestCount = 1; + + COUSubsystemTestProcedure fnTestProcedure = g_afnOUSubsystemTestProcedures.Encode(stSubsystemTest); + if (fnTestProcedure(nSubsysytemSuccessCount, nSubsystemTestCount) && nSubsysytemSuccessCount == nSubsystemTestCount) + { + nSuccessCount += 1; + } + + unsigned int nSubsysytemFailureCount = nSubsystemTestCount - nSubsysytemSuccessCount; + printf("---------------------------------------------------\n"); + printf("Feature tests failed: %3u out of %3u\n", nSubsysytemFailureCount, nSubsystemTestCount); + } + + unsigned int nFailureCount = OST__MAX - nSuccessCount; + + printf("\n===================================================\n"); + printf("Subsystem tests failed: %3u out of %3u\n", nFailureCount, (unsigned int)OST__MAX); + + nOutFailureCount = nFailureCount; + return nSuccessCount == OST__MAX; +} + +int main(int argc, char* argv[]) +{ + unsigned int nFailureCount; + ProcessOUCoverageTests(nFailureCount); + + return nFailureCount; +} + diff --git a/libs/ode-0.16.1/test-driver b/libs/ode-0.16.1/test-driver new file mode 100755 index 0000000..8e575b0 --- /dev/null +++ b/libs/ode-0.16.1/test-driver @@ -0,0 +1,148 @@ +#! /bin/sh +# test-driver - basic testsuite driver script. + +scriptversion=2013-07-13.22; # UTC + +# Copyright (C) 2011-2014 Free Software Foundation, Inc. +# +# 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 2, 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 <http://www.gnu.org/licenses/>. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to <bug-automake@gnu.org> or send patches to +# <automake-patches@gnu.org>. + +# Make unconditional expansion of undefined variables an error. This +# helps a lot in preventing typo-related bugs. +set -u + +usage_error () +{ + echo "$0: $*" >&2 + print_usage >&2 + exit 2 +} + +print_usage () +{ + cat <<END +Usage: + test-driver --test-name=NAME --log-file=PATH --trs-file=PATH + [--expect-failure={yes|no}] [--color-tests={yes|no}] + [--enable-hard-errors={yes|no}] [--] + TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS] +The '--test-name', '--log-file' and '--trs-file' options are mandatory. +END +} + +test_name= # Used for reporting. +log_file= # Where to save the output of the test script. +trs_file= # Where to save the metadata of the test run. +expect_failure=no +color_tests=no +enable_hard_errors=yes +while test $# -gt 0; do + case $1 in + --help) print_usage; exit $?;; + --version) echo "test-driver $scriptversion"; exit $?;; + --test-name) test_name=$2; shift;; + --log-file) log_file=$2; shift;; + --trs-file) trs_file=$2; shift;; + --color-tests) color_tests=$2; shift;; + --expect-failure) expect_failure=$2; shift;; + --enable-hard-errors) enable_hard_errors=$2; shift;; + --) shift; break;; + -*) usage_error "invalid option: '$1'";; + *) break;; + esac + shift +done + +missing_opts= +test x"$test_name" = x && missing_opts="$missing_opts --test-name" +test x"$log_file" = x && missing_opts="$missing_opts --log-file" +test x"$trs_file" = x && missing_opts="$missing_opts --trs-file" +if test x"$missing_opts" != x; then + usage_error "the following mandatory options are missing:$missing_opts" +fi + +if test $# -eq 0; then + usage_error "missing argument" +fi + +if test $color_tests = yes; then + # Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'. + red='[0;31m' # Red. + grn='[0;32m' # Green. + lgn='[1;32m' # Light green. + blu='[1;34m' # Blue. + mgn='[0;35m' # Magenta. + std='[m' # No color. +else + red= grn= lgn= blu= mgn= std= +fi + +do_exit='rm -f $log_file $trs_file; (exit $st); exit $st' +trap "st=129; $do_exit" 1 +trap "st=130; $do_exit" 2 +trap "st=141; $do_exit" 13 +trap "st=143; $do_exit" 15 + +# Test script is run here. +"$@" >$log_file 2>&1 +estatus=$? + +if test $enable_hard_errors = no && test $estatus -eq 99; then + tweaked_estatus=1 +else + tweaked_estatus=$estatus +fi + +case $tweaked_estatus:$expect_failure in + 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; + 0:*) col=$grn res=PASS recheck=no gcopy=no;; + 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; + 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; + *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; + *:*) col=$red res=FAIL recheck=yes gcopy=yes;; +esac + +# Report the test outcome and exit status in the logs, so that one can +# know whether the test passed or failed simply by looking at the '.log' +# file, without the need of also peaking into the corresponding '.trs' +# file (automake bug#11814). +echo "$res $test_name (exit status: $estatus)" >>$log_file + +# Report outcome to console. +echo "${col}${res}${std}: $test_name" + +# Register the test result, and other relevant metadata. +echo ":test-result: $res" > $trs_file +echo ":global-test-result: $res" >> $trs_file +echo ":recheck: $recheck" >> $trs_file +echo ":copy-in-global-log: $gcopy" >> $trs_file + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/libs/ode-0.16.1/tests/Makefile.am b/libs/ode-0.16.1/tests/Makefile.am new file mode 100644 index 0000000..7ed8620 --- /dev/null +++ b/libs/ode-0.16.1/tests/Makefile.am @@ -0,0 +1,30 @@ +SUBDIRS = joints UnitTest++ + +AM_CPPFLAGS = -I$(srcdir)/UnitTest++/src \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/ode/src + +if GIMPACT + AM_CPPFLAGS += -DdTRIMESH_ENABLED -DdTRIMESH_GIMPACT +endif +if OPCODE + AM_CPPFLAGS += -DdTRIMESH_ENABLED -DdTRIMESH_OPCODE +endif + + +check_PROGRAMS = tests + +TESTS = tests + +tests_SOURCES = \ + collision.cpp \ + friction.cpp \ + joint.cpp \ + main.cpp \ + odemath.cpp + +tests_LDADD = \ + $(top_builddir)/ode/src/libode.la \ + joints/*.o \ + UnitTest++/src/libunittestpp.la diff --git a/libs/ode-0.16.1/tests/Makefile.in b/libs/ode-0.16.1/tests/Makefile.in new file mode 100644 index 0000000..a5fb17b --- /dev/null +++ b/libs/ode-0.16.1/tests/Makefile.in @@ -0,0 +1,1116 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@GIMPACT_TRUE@am__append_1 = -DdTRIMESH_ENABLED -DdTRIMESH_GIMPACT +@OPCODE_TRUE@am__append_2 = -DdTRIMESH_ENABLED -DdTRIMESH_OPCODE +check_PROGRAMS = tests$(EXEEXT) +TESTS = tests$(EXEEXT) +subdir = tests +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ode/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am_tests_OBJECTS = collision.$(OBJEXT) friction.$(OBJEXT) \ + joint.$(OBJEXT) main.$(OBJEXT) odemath.$(OBJEXT) +tests_OBJECTS = $(am_tests_OBJECTS) +tests_DEPENDENCIES = $(top_builddir)/ode/src/libode.la joints/*.o \ + UnitTest++/src/libunittestpp.la +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +SOURCES = $(tests_SOURCES) +DIST_SOURCES = $(tests_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + check recheck distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red='[0;31m'; \ + grn='[0;32m'; \ + lgn='[1;32m'; \ + blu='[1;34m'; \ + mgn='[0;35m'; \ + brg='[1m'; \ + std='[m'; \ + fi; \ +} +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +RECHECK_LOGS = $(TEST_LOGS) +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ + $(top_srcdir)/test-driver +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_CFLAGS = @CCD_CFLAGS@ +CCD_LIBS = @CCD_LIBS@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSTDCXX = @LIBSTDCXX@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ODE_PRECISION = @ODE_PRECISION@ +ODE_VERSION = @ODE_VERSION@ +ODE_VERSION_INFO = @ODE_VERSION_INFO@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = joints UnitTest++ +AM_CPPFLAGS = -I$(srcdir)/UnitTest++/src -I$(top_srcdir)/include \ + -I$(top_builddir)/include -I$(top_srcdir)/ode/src \ + $(am__append_1) $(am__append_2) +tests_SOURCES = \ + collision.cpp \ + friction.cpp \ + joint.cpp \ + main.cpp \ + odemath.cpp + +tests_LDADD = \ + $(top_builddir)/ode/src/libode.la \ + joints/*.o \ + UnitTest++/src/libunittestpp.la + +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .cpp .lo .log .o .obj .test .test$(EXEEXT) .trs +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +tests$(EXEEXT): $(tests_OBJECTS) $(tests_DEPENDENCIES) $(EXTRA_tests_DEPENDENCIES) + @rm -f tests$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(tests_OBJECTS) $(tests_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/friction.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/joint.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odemath.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + elif test -n "$$redo_logs"; then \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all $(check_PROGRAMS) + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +tests.log: tests$(EXEEXT) + @p='tests$(EXEEXT)'; \ + b='tests'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) check-am install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-TESTS check-am clean clean-checkPROGRAMS clean-generic \ + clean-libtool cscopelist-am ctags ctags-am distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am recheck tags tags-am \ + uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/tests/UnitTest++/COPYING b/libs/ode-0.16.1/tests/UnitTest++/COPYING new file mode 100644 index 0000000..9f96308 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/COPYING @@ -0,0 +1,20 @@ +Copyright (c) 2006 Noel Llopis and Charles Nicholson + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/libs/ode-0.16.1/tests/UnitTest++/Makefile.am b/libs/ode-0.16.1/tests/UnitTest++/Makefile.am new file mode 100644 index 0000000..000d8e4 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/Makefile.am @@ -0,0 +1,6 @@ +# Makefile.am for UnitTest++ + +SUBDIRS = src + +EXTRA_DIST = docs + diff --git a/libs/ode-0.16.1/tests/UnitTest++/Makefile.in b/libs/ode-0.16.1/tests/UnitTest++/Makefile.in new file mode 100644 index 0000000..0bc32c9 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/Makefile.in @@ -0,0 +1,643 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Makefile.am for UnitTest++ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = tests/UnitTest++ +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ode/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in COPYING README +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_CFLAGS = @CCD_CFLAGS@ +CCD_LIBS = @CCD_LIBS@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSTDCXX = @LIBSTDCXX@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ODE_PRECISION = @ODE_PRECISION@ +ODE_VERSION = @ODE_VERSION@ +ODE_VERSION_INFO = @ODE_VERSION_INFO@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = src +EXTRA_DIST = docs +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/UnitTest++/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/UnitTest++/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/tests/UnitTest++/README b/libs/ode-0.16.1/tests/UnitTest++/README new file mode 100644 index 0000000..b32ff5f --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/README @@ -0,0 +1,62 @@ +UnitTest++ README +Version: v1.3 +Last update: 2007-4-22 + + +UnitTest++ is free software. You may copy, distribute, and modify it under +the terms of the License contained in the file COPYING distributed +with this package. This license is the same as the MIT/X Consortium +license. + +See src/tests/TestUnitTest++.cpp for usage. + +Authors: +Noel Llopis (llopis@convexhull.com) +Charles Nicholson (cn@cnicholson.net) + +Contributors: +Jim Tilander (jim.tilander@gmail.com) +Kim Grasman (kim@mvps.org) +Jonathan Jansson (lilliemarck@users.sourceforge.net) +Dirck Blaskey (listtarget2@danbala.com) +Rory Driscoll (rorydriscoll@gmail.com) +Dan Lind (podcat@gmail.com) +Matt Kimmel (mattkimmel@gmail.com) -- Submitted with permission from Blue Fang Games +Anthony Moralez (anthony.moralez@gmail.com) +Jeff Dixon <bodisafa@helixe.com> + + +Release notes +-------------- +Version 1.3 (2007-4-22) +- Removed dynamic memory allocations (other than streams) +- MinGW support +- Consistent (native) line endings +- Minor bug fixing + +Version 1.2 (2006-10-29) +- First pass at documentation. +- More detailed error crash catching in fixtures. +- Standard streams used for printing objects under check. This should allow the + use of standard class types such as std::string or other custom classes with + stream operators to ostream. +- Standard streams can be optionally compiled off by defining UNITTEST_USE_CUSTOM_STREAMS + in Config.h +- Added named test suites +- Added CHECK_ARRAY2D_CLOSE +- Posix library name is libUnitTest++.a now +- Floating point numbers are postfixed with f in the failure reports + +Version 1.1 (2006-04-18) +- CHECK macros do not have side effects even if one of the parameters changes state +- Removed CHECK_ARRAY_EQUAL (too similar to CHECK_ARRAY_CLOSE) +- Added local and global time constraints +- Removed dependencies on strstream +- Improved Posix signal to exception translator +- Failing tests are added to Visual Studio's error list +- Fixed Visual Studio projects to work with spaces in directories + + +Version 1.0 (2006-03-15) +- Initial release + diff --git a/libs/ode-0.16.1/tests/UnitTest++/docs/UnitTest++.html b/libs/ode-0.16.1/tests/UnitTest++/docs/UnitTest++.html new file mode 100644 index 0000000..cd40400 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/docs/UnitTest++.html @@ -0,0 +1,260 @@ +<html> +<head> + <title>UnitTest++ in brief</title> +</head> +<body> +<h1>UnitTest++ in brief</h1> +<h2>Introduction</h2> +<p>This little document serves as bare-bones documentation for UnitTest++.</p> + +<p>For background, goals and license details, see:</p> + +<ul> + <li><a href="http://unittest-cpp.sourceforge.net/">The UnitTest++ home page</a></li> + <li><a href="http://www.gamesfromwithin.com/articles/0603/000108.html">Noel Llopis' announcement</a></li> +</ul> + +<p>The documentation, while sparse, aims to be practical, so it should give you enough info to get started using UnitTest++ as fast as possible.</p> + +<h2>Building UnitTest++</h2> +<p>Building UnitTest++ will be specific to each platform and build environment, but it should be straightforward.</p> + +<h3>Building with Visual Studio</h3> +<p>If you are using Visual Studio, go for either of the provided .sln files, depending on version. There are no prefabricated solutions for versions earlier than VS.NET 2003, but we have had reports of people building UnitTest++ with at least VS.NET 2002.</p> + +<h3>Building with Make</h3> +<p>The bundled makefile is written to build with g++. It also needs <code>sed</code> installed in the path, and to be able to use the <code>mv</code> and <code>rm</code> shell commands. The makefile should be usable on most Posix-like platforms.</p> + +<p>Do "make all" to generate a library and test executable. A final build step runs all unit tests to make sure that the result works as expected.</p> + +<h3>Packaging</h3> +<p>You'll probably want to keep the generated library in a shared space in source control, so you can reuse it for multiple test projects. A redistributable package of UnitTest++ would consist of the generated library file, and all of the header files in <code>UnitTest++/src/</code> and its per-platform subfolders. The <code>tests</code> directory only contains the unit tests for the library, and need not be included.</p> + +<h2>Using UnitTest++</h2> +<p>The source code for UnitTest++ comes with a full test suite written <em>using</em> UnitTest++. This is a great place to learn techniques for testing. There is one sample .cpp file: <code>UnitTest++/src/tests/TestUnitTest++.cpp</code>. It covers most of UnitTest++'s features in an easy-to-grasp context, so start there if you want a quick overview of typical usage.</p> + +<h3>Getting started</h3> +<p>Listed below is a minimal C++ program to run a failing test through UnitTest++.</p> + +<pre> + // test.cpp + #include <UnitTest++.h> + + TEST(FailSpectacularly) + { + CHECK(false); + } + + int main() + { + return UnitTest::RunAllTests(); + } +</pre> + +<p><code>UnitTest++.h</code> is a facade header for UnitTest++, so including that should get you all features of the library. All classes and free functions are placed in namespace <code>UnitTest</code>, so you need to either qualify their full names (as with <code>RunAllTests()</code> in the example) or add a <code>using namespace UnitTest;</code> statement in your .cpp files. Note that any mention of UnitTest++ functions and classes in this document assume that the <code>UnitTest</code> namespace has been opened.</p> + +<p>Compiling and linking this program with UnitTest++'s static library into an executable, and running it, will produce the following output (details may vary):</p> + +<pre> + .\test.cpp(5): error: Failure in FailSpectacularly: false + FAILED: 1 out of 1 tests failed (1 failures). + Test time: 0.00 seconds. +</pre> + +<p>UnitTest++ attempts to report every failure in an IDE-friendly format, depending on platform (e.g. you can double-click it in Visual Studio's error list.) The exit code will be the number of failed tests, so that a failed test run always returns a non-zero exit code.</p> + +<h3>Test macros</h3> +<p>To add a test, simply put the following code in a .cpp file of your choice:</p> + +<pre> + TEST(YourTestName) + { + } +</pre> + +<p>The <code>TEST</code> macro contains enough machinery to turn this slightly odd-looking syntax into legal C++, and automatically register the test in a global list. This test list forms the basis of what is executed by <code>RunAllTests()</code>.</p> + +<p>If you want to re-use a set of test data for more than one test, or provide setup/teardown for tests, you can use the <code>TEST_FIXTURE</code> macro instead. The macro requires that you pass it a class name that it will instantiate, so any setup and teardown code should be in its constructor and destructor.</p> + +<pre> + struct SomeFixture + { + SomeFixture() { /* some setup */ } + ~SomeFixture() { /* some teardown */ } + + int testData; + }; + + TEST_FIXTURE(SomeFixture, YourTestName) + { + int temp = testData; + } +</pre> + +<p>Note how members of the fixture are used as if they are a part of the test, since the macro-generated test class derives from the provided fixture class.</p> + +<h3>Suite macros</h3> +<p>Tests can be grouped into suites, using the <code>SUITE</code> macro. A suite serves as a namespace for test names, so that the same test name can be used in two difference contexts.</p> + +<pre> + SUITE(YourSuiteName) + { + TEST(YourTestName) + { + } + + TEST(YourOtherTestName) + { + } + } +</pre> + +<p>This will place the tests into a C++ namespace called <code>YourSuiteName</code>, and make the suite name available to UnitTest++. <code>RunAllTests()</code> can be called for a specific suite name, so you can use this to build named groups of tests to be run together.</p> + +<h3>Simple check macros</h3> +<p>In test cases, we want to check the results of our system under test. UnitTest++ provides a number of check macros that handle comparison and proper failure reporting.</p> + +<p>The most basic variety is the boolean <code>CHECK</code> macro:</p> + +<pre> + CHECK(false); // fails +</pre> + +<p>It will fail if the boolean expression evaluates to false.</p> + +<p>For equality checks, it's generally better to use <code>CHECK_EQUAL</code>:</p> + +<pre> + CHECK_EQUAL(10, 20); // fails + CHECK_EQUAL("foo", "bar"); // fails +</pre> + +<p>Note how <code>CHECK_EQUAL</code> is overloaded for C strings, so you don't have to resort to <code>strcmp</code> or similar. There is no facility for case-insensitive comparison or string searches, so you may have to drop down to a plain boolean <code>CHECK</code> with help from the CRT:</p> + +<pre> + CHECK(std::strstr("zaza", "az") != 0); // succeeds +</pre> + +<p>For floating-point comparison, equality <a href="http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm">isn't necessarily well-defined</a>, so you should prefer the <code>CHECK_CLOSE</code> macro:</p> + +<pre> + CHECK_CLOSE(3.14, 3.1415, 0.01); // succeeds +</pre> + +<p>All of the macros are tailored to avoid unintended side-effects, for example:</p> + +<pre> + TEST(CheckMacrosHaveNoSideEffects) + { + int i = 4; + CHECK_EQUAL(5, ++i); // succeeds + CHECK_EQUAL(5, i); // succeeds + } +</pre> + +<p>The check macros guarantee that the <code>++i</code> expression isn't repeated internally, as demonstrated above.</p> + +<h3>Array check macros</h3> +<p>There is a set of check macros for array comparison as well:</p> + +<pre> + const float oned[2] = { 10, 20 }; + CHECK_ARRAY_EQUAL(oned, oned, 2); // succeeds + CHECK_ARRAY_CLOSE(oned, oned, 2, 0.00); // succeeds + + const float twod[2][3] = { {0, 1, 2}, {2, 3, 4} }; + CHECK_ARRAY2D_CLOSE(twod, twod, 2, 3, 0.00); // succeeds +</pre> + +<p>The array equal macro compares elements using <code>operator==</code>, so <code>CHECK_ARRAY_EQUAL</code> won't work for an array of C strings, for example.</p> + +<p>The array close macros are similar to the regular CHECK_CLOSE macro, and are really only useful for scalar types, that can be compared in terms of a difference between two array elements.</p> + +<p>Note that the one-dimensional array macros work for <code>std::vector</code> as well, as it can be indexed just as a C array.</p> + +<h3>Exception check macros</h3> +<p>Finally, there's a <code>CHECK_THROW</code> macro, which asserts that its enclosed expression throws the specified type:</p> + +<pre> + struct TestException {}; + CHECK_THROW(throw TestException(), TestException); // succeeds +</pre> + +<p>UnitTest++ natively catches exceptions if your test code doesn't. So if your code under test throws any exception UnitTest++ will fail the test and report either using the <code>what()</code> method for <code>std::exception</code> derivatives or just a plain message for unknown exception types.</p> + +<p>Should your test or code raise an irrecoverable error (an Access Violation on Win32, for example, or a signal on Linux), UnitTest++ will attempt to map them to an exception and fail the test, just as for other unhandled exceptions.</p> + +<h3>Time constraints</h3> +<p>UnitTest++ can fail a test if it takes too long to complete, using so-called time constraints.</p> + +<p>They come in two flavors; <em>local</em> and <em>global</em> time constraints.</p> + +<p>Local time constraints are limited to the current scope, like so:</p> + +<pre> + TEST(YourTimedTest) + { + // Lengthy setup... + + { + UNITTEST_TIME_CONSTRAINT(50); + + // Do time-critical stuff + } + + // Lengthy teardown... + } +</pre> + +<p>The test will fail if the "Do time-critical stuff" block takes longer than 50 ms to complete. The time-consuming setup and teardown are not measured, since the time constraint is scope-bound. It's perfectly valid to have multiple local time constraints in the same test, as long as there is only one per block.</p> + +<p>A global time constraint, on the other hand, requires that all of the tests in a test run are faster than a specified amount of time. This allows you, when you run a suite of tests, to ask UnitTest++ to fail it entirely if any test exceeds the global constraint. The max time is passed as a parameter to an overload of <code>RunAllTests()</code>.</p> + +<p>If you want to use a global time constraint, but have one test that is notoriously slow, you can exempt it from inspection by using the <code>UNITTEST_TIME_CONSTRAINT_EXEMPT</code> macro anywhere inside the test body.</p> + +<pre> + TEST(NotoriouslySlowTest) + { + UNITTEST_TIME_CONSTRAINT_EXEMPT(); + + // Oh boy, this is going to take a while + ... + } +</pre> + +<h3>Test runners</h3> +<p>The <code>RunAllTests()</code> function has an overload that lets you customize the behavior of the runner, such as global time constraints, custom reporters, which suite to run, etc.</p> + +<pre> + int RunAllTests(TestReporter& reporter, TestList const& list, char const* suiteName, int const maxTestTimeInMs); +</pre> + +<p>If you attempt to pass custom parameters to <code>RunAllTests()</code>, note that the <code>list</code> parameter should have the value <code>Test::GetTestList()</code>.</p> + +<p>The parameterless <code>RunAllTests()</code> is a simple wrapper for this one, with sensible defaults.</p> + +<h3>Example setup</h3> +<p>How to create a new test project varies depending on your environment, but here are some directions on common file structure and usage.</p> + +<p>The general idea is that you keep one <code>Main.cpp</code> file with the entry-point which calls <code>RunAllTests()</code>.</p> + +<p>Then you can simply compile and link new .cpp files at will, typically one per test suite.</p> + +<pre> + + ShaverTests/ + | + +- Main.cpp + | + +- TestBrush.cpp + +- TestEngine.cpp + +- TestRazor.cpp +</pre> + +<p>Each of the <code>Test*.cpp</code> files will contain one or more <code>TEST</code> macro incantations with the associated test code. There are no source-level dependencies between <code>Main.cpp</code> and <code>Test*.cpp</code>, as the <code>TEST</code> macro handles the registration and setup necessary for <code>RunAllTests()</code> to find all tests compiled into the same final executable.</p> + +<p>UnitTest++ does not require this structure, even if this is how the library itself does it. As long as your test project contains one or more <code>TESTs</code> and calls <code>RunAllTests()</code> at one point or another, it will be handled by UnitTest++.</p> + +<p>It's common to make the generated executable start as a post-build step, so that merely building your test project will run the tests as well. Since the exit code is the count of failures, a failed test will generally break the build, as most build engines will fail a build if any step returns a non-zero exit code.</p> + +</body> +</html>
\ No newline at end of file diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/AssertException.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/AssertException.cpp new file mode 100644 index 0000000..49f7ba7 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/AssertException.cpp @@ -0,0 +1,32 @@ +#include "AssertException.h" +#include <cstring> + +namespace UnitTest { + +AssertException::AssertException(char const* description, char const* filename, int const lineNumber) + : m_lineNumber(lineNumber) +{ + std::strcpy(m_description, description); + std::strcpy(m_filename, filename); +} + +AssertException::~AssertException() throw() +{ +} + +char const* AssertException::what() const throw() +{ + return m_description; +} + +char const* AssertException::Filename() const +{ + return m_filename; +} + +int AssertException::LineNumber() const +{ + return m_lineNumber; +} + +} diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/AssertException.h b/libs/ode-0.16.1/tests/UnitTest++/src/AssertException.h new file mode 100644 index 0000000..e04d450 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/AssertException.h @@ -0,0 +1,28 @@ +#ifndef UNITTEST_ASSERTEXCEPTION_H +#define UNITTEST_ASSERTEXCEPTION_H + +#include <exception> + + +namespace UnitTest { + +class AssertException : public std::exception +{ +public: + AssertException(char const* description, char const* filename, int lineNumber); + virtual ~AssertException() throw(); + + virtual char const* what() const throw(); + + char const* Filename() const; + int LineNumber() const; + +private: + char m_description[512]; + char m_filename[256]; + int m_lineNumber; +}; + +} + +#endif diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/CheckMacros.h b/libs/ode-0.16.1/tests/UnitTest++/src/CheckMacros.h new file mode 100644 index 0000000..2d499cc --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/CheckMacros.h @@ -0,0 +1,102 @@ +#ifndef UNITTEST_CHECKMACROS_H +#define UNITTEST_CHECKMACROS_H + +#include "Checks.h" +#include "AssertException.h" +#include "MemoryOutStream.h" +#include "TestDetails.h" + +#ifdef CHECK + #error UnitTest++ redefines CHECK +#endif + + +#define CHECK(value) \ + do \ + { \ + try { \ + if (!UnitTest::Check(value)) \ + testResults_.OnTestFailure( UnitTest::TestDetails(m_details, __LINE__), #value); \ + } \ + catch (...) { \ + testResults_.OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \ + "Unhandled exception in CHECK(" #value ")"); \ + } \ + } while (0) + +#define CHECK_EQUAL(expected, actual) \ + do \ + { \ + try { \ + UnitTest::CheckEqual(testResults_, expected, actual, UnitTest::TestDetails(m_details, __LINE__)); \ + } \ + catch (...) { \ + testResults_.OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \ + "Unhandled exception in CHECK_EQUAL(" #expected ", " #actual ")"); \ + } \ + } while (0) + +#define CHECK_CLOSE(expected, actual, tolerance) \ + do \ + { \ + try { \ + UnitTest::CheckClose(testResults_, expected, actual, tolerance, UnitTest::TestDetails(m_details, __LINE__)); \ + } \ + catch (...) { \ + testResults_.OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \ + "Unhandled exception in CHECK_CLOSE(" #expected ", " #actual ")"); \ + } \ + } while (0) + +#define CHECK_ARRAY_EQUAL(expected, actual, count) \ + do \ + { \ + try { \ + UnitTest::CheckArrayEqual(testResults_, expected, actual, count, UnitTest::TestDetails(m_details, __LINE__)); \ + } \ + catch (...) { \ + testResults_.OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \ + "Unhandled exception in CHECK_ARRAY_EQUAL(" #expected ", " #actual ")"); \ + } \ + } while (0) + +#define CHECK_ARRAY_CLOSE(expected, actual, count, tolerance) \ + do \ + { \ + try { \ + UnitTest::CheckArrayClose(testResults_, expected, actual, count, tolerance, UnitTest::TestDetails(m_details, __LINE__)); \ + } \ + catch (...) { \ + testResults_.OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \ + "Unhandled exception in CHECK_ARRAY_CLOSE(" #expected ", " #actual ")"); \ + } \ + } while (0) + +#define CHECK_ARRAY2D_CLOSE(expected, actual, rows, columns, tolerance) \ + do \ + { \ + try { \ + UnitTest::CheckArray2DClose(testResults_, expected, actual, rows, columns, tolerance, UnitTest::TestDetails(m_details, __LINE__)); \ + } \ + catch (...) { \ + testResults_.OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \ + "Unhandled exception in CHECK_ARRAY_CLOSE(" #expected ", " #actual ")"); \ + } \ + } while (0) + + +#define CHECK_THROW(expression, ExpectedExceptionType) \ + do \ + { \ + bool caught_ = false; \ + try { expression; } \ + catch (ExpectedExceptionType const&) { caught_ = true; } \ + catch (...) {} \ + if (!caught_) \ + testResults_.OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), "Expected exception: \"" #ExpectedExceptionType "\" not thrown"); \ + } while(0) + +#define CHECK_ASSERT(expression) \ + CHECK_THROW(expression, UnitTest::AssertException); + +#endif diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Checks.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/Checks.cpp new file mode 100644 index 0000000..36db997 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/Checks.cpp @@ -0,0 +1,48 @@ +#include "Checks.h" +#include <cstring> + +namespace UnitTest { + +namespace { + +void CheckStringsEqual(TestResults& results, char const* expected, char const* actual, + TestDetails const& details) +{ + if (std::strcmp(expected, actual)) + { + UnitTest::MemoryOutStream stream; + stream << "Expected " << expected << " but was " << actual; + + results.OnTestFailure(details, stream.GetText()); + } +} + +} + + +void CheckEqual(TestResults& results, char const* expected, char const* actual, + TestDetails const& details) +{ + CheckStringsEqual(results, expected, actual, details); +} + +void CheckEqual(TestResults& results, char* expected, char* actual, + TestDetails const& details) +{ + CheckStringsEqual(results, expected, actual, details); +} + +void CheckEqual(TestResults& results, char* expected, char const* actual, + TestDetails const& details) +{ + CheckStringsEqual(results, expected, actual, details); +} + +void CheckEqual(TestResults& results, char const* expected, char* actual, + TestDetails const& details) +{ + CheckStringsEqual(results, expected, actual, details); +} + + +} diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Checks.h b/libs/ode-0.16.1/tests/UnitTest++/src/Checks.h new file mode 100644 index 0000000..b470b62 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/Checks.h @@ -0,0 +1,146 @@ +#ifndef UNITTEST_CHECKS_H +#define UNITTEST_CHECKS_H + +#include "Config.h" +#include "TestResults.h" +#include "MemoryOutStream.h" + +namespace UnitTest { + + +template< typename Value > +bool Check(Value const value) +{ + return !!value; // doing double negative to avoid silly VS warnings +} + + +template< typename Expected, typename Actual > +void CheckEqual(TestResults& results, Expected const expected, Actual const actual, TestDetails const& details) +{ + if (!(expected == actual)) + { + UnitTest::MemoryOutStream stream; + stream << "Expected " << expected << " but was " << actual; + + results.OnTestFailure(details, stream.GetText()); + } +} + +void CheckEqual(TestResults& results, char const* expected, char const* actual, TestDetails const& details); + +void CheckEqual(TestResults& results, char* expected, char* actual, TestDetails const& details); + +void CheckEqual(TestResults& results, char* expected, char const* actual, TestDetails const& details); + +void CheckEqual(TestResults& results, char const* expected, char* actual, TestDetails const& details); + +template< typename Expected, typename Actual, typename Tolerance > +bool AreClose(Expected const expected, Actual const actual, Tolerance const tolerance) +{ + return (actual >= (expected - tolerance)) && (actual <= (expected + tolerance)); +} + +template< typename Expected, typename Actual, typename Tolerance > +void CheckClose(TestResults& results, Expected const expected, Actual const actual, Tolerance const tolerance, + TestDetails const& details) +{ + if (!AreClose(expected, actual, tolerance)) + { + UnitTest::MemoryOutStream stream; + stream << "Expected " << expected << " +/- " << tolerance << " but was " << actual; + + results.OnTestFailure(details, stream.GetText()); + } +} + + +template< typename Expected, typename Actual > +void CheckArrayEqual(TestResults& results, Expected const expected, Actual const actual, + int const count, TestDetails const& details) +{ + bool equal = true; + for (int i = 0; i < count; ++i) + equal &= (expected[i] == actual[i]); + + if (!equal) + { + UnitTest::MemoryOutStream stream; + stream << "Expected [ "; + for (int i = 0; i < count; ++i) + stream << expected[i] << " "; + stream << "] but was [ "; + for (int i = 0; i < count; ++i) + stream << actual[i] << " "; + stream << "]"; + + results.OnTestFailure(details, stream.GetText()); + } +} + +template< typename Expected, typename Actual, typename Tolerance > +bool ArrayAreClose(Expected const expected, Actual const actual, int const count, Tolerance const tolerance) +{ + bool equal = true; + for (int i = 0; i < count; ++i) + equal &= AreClose(expected[i], actual[i], tolerance); + return equal; +} + +template< typename Expected, typename Actual, typename Tolerance > +void CheckArrayClose(TestResults& results, Expected const expected, Actual const actual, + int const count, Tolerance const tolerance, TestDetails const& details) +{ + bool equal = ArrayAreClose(expected, actual, count, tolerance); + + if (!equal) + { + UnitTest::MemoryOutStream stream; + stream << "Expected [ "; + for (int i = 0; i < count; ++i) + stream << expected[i] << " "; + stream << "] +/- " << tolerance << " but was [ "; + for (int i = 0; i < count; ++i) + stream << actual[i] << " "; + stream << "]"; + + results.OnTestFailure(details, stream.GetText()); + } +} + +template< typename Expected, typename Actual, typename Tolerance > +void CheckArray2DClose(TestResults& results, Expected const expected, Actual const actual, + int const rows, int const columns, Tolerance const tolerance, TestDetails const& details) +{ + bool equal = true; + for (int i = 0; i < rows; ++i) + equal &= ArrayAreClose(expected[i], actual[i], columns, tolerance); + + if (!equal) + { + UnitTest::MemoryOutStream stream; + stream << "Expected [ "; + for (int i = 0; i < rows; ++i) + { + stream << "[ "; + for (int j = 0; j < columns; ++j) + stream << expected[i][j] << " "; + stream << "] "; + } + stream << "] +/- " << tolerance << " but was [ "; + for (int i = 0; i < rows; ++i) + { + stream << "[ "; + for (int j = 0; j < columns; ++j) + stream << actual[i][j] << " "; + stream << "] "; + } + stream << "]"; + + results.OnTestFailure(details, stream.GetText()); + } +} + +} + +#endif diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Config.h b/libs/ode-0.16.1/tests/UnitTest++/src/Config.h new file mode 100644 index 0000000..db423d4 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/Config.h @@ -0,0 +1,25 @@ +#ifndef UNITTEST_CONFIG_H +#define UNITTEST_CONFIG_H + +// Standard defines documented here: http://predef.sourceforge.net + +#if defined _MSC_VER + #pragma warning(disable:4127) // conditional expression is constant + #pragma warning(disable:4702) // unreachable code + #pragma warning(disable:4722) // destructor never returns, potential memory leak +#endif + +#if defined(unix) || defined(__unix__) || defined(__unix) || defined(linux) || \ + defined(__APPLE__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__FreeBSD__) + #define UNITTEST_POSIX +#endif + +#if defined (__MINGW32__) + #define UNITTEST_MINGW +#endif + +// by default, MemoryOutStream is implemented in terms of std::ostringstream. +// uncomment this line to use the custom MemoryOutStream (no deps on std::ostringstream). +//#define UNITTEST_USE_CUSTOM_STREAMS + +#endif diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestReporter.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestReporter.cpp new file mode 100644 index 0000000..05e8055 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestReporter.cpp @@ -0,0 +1,28 @@ +#include "DeferredTestReporter.h" +#include "TestDetails.h" + +using namespace UnitTest; + +void DeferredTestReporter::ReportTestStart(TestDetails const& details) +{ + m_results.push_back(DeferredTestResult(details.suiteName, details.testName)); +} + +void DeferredTestReporter::ReportFailure(TestDetails const& details, char const* failure) +{ + DeferredTestResult& r = m_results.back(); + r.failed = true; + r.failures.push_back(DeferredTestResult::Failure(details.lineNumber, failure)); + r.failureFile = details.filename; +} + +void DeferredTestReporter::ReportTestFinish(TestDetails const&, float const secondsElapsed) +{ + DeferredTestResult& r = m_results.back(); + r.timeElapsed = secondsElapsed; +} + +DeferredTestReporter::DeferredTestResultList& DeferredTestReporter::GetResults() +{ + return m_results; +} diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestReporter.h b/libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestReporter.h new file mode 100644 index 0000000..026ed05 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestReporter.h @@ -0,0 +1,28 @@ +#ifndef UNITTEST_DEFERREDTESTREPORTER_H +#define UNITTEST_DEFERREDTESTREPORTER_H + +#include "TestReporter.h" +#include "DeferredTestResult.h" + +#include <vector> + +namespace UnitTest +{ + +class DeferredTestReporter : public TestReporter +{ +public: + virtual void ReportTestStart(TestDetails const& details); + virtual void ReportFailure(TestDetails const& details, char const* failure); + virtual void ReportTestFinish(TestDetails const& details, float secondsElapsed); + + typedef std::vector< DeferredTestResult > DeferredTestResultList; + DeferredTestResultList& GetResults(); + +private: + DeferredTestResultList m_results; +}; + +} + +#endif diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestResult.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestResult.cpp new file mode 100644 index 0000000..6e35f86 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestResult.cpp @@ -0,0 +1,26 @@ +#include "DeferredTestResult.h" + +#include <cstdlib> + +namespace UnitTest +{ + +DeferredTestResult::DeferredTestResult() + : suiteName("") + , testName("") + , failureFile("") + , timeElapsed(0.0f) + , failed(false) +{ +} + +DeferredTestResult::DeferredTestResult(char const* suite, char const* test) + : suiteName(suite) + , testName(test) + , failureFile("") + , timeElapsed(0.0f) + , failed(false) +{ +} + +} diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestResult.h b/libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestResult.h new file mode 100644 index 0000000..6cca77c --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/DeferredTestResult.h @@ -0,0 +1,29 @@ +#ifndef UNITTEST_DEFERREDTESTRESULT_H +#define UNITTEST_DEFERREDTESTRESULT_H + +#include <string> +#include <vector> + +namespace UnitTest +{ + +struct DeferredTestResult +{ + DeferredTestResult(); + DeferredTestResult(char const* suite, char const* test); + + std::string suiteName; + std::string testName; + std::string failureFile; + + typedef std::pair< int, std::string > Failure; + typedef std::vector< Failure > FailureVec; + FailureVec failures; + + float timeElapsed; + bool failed; +}; + +} + +#endif //UNITTEST_DEFERREDTESTRESULT_H diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Makefile.am b/libs/ode-0.16.1/tests/UnitTest++/src/Makefile.am new file mode 100644 index 0000000..c17c4b1 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/Makefile.am @@ -0,0 +1,33 @@ +if WIN32 +SUBDIRS = Win32 +else +SUBDIRS = Posix +endif + + +check_LTLIBRARIES = libunittestpp.la + +libunittestpp_la_SOURCES = AssertException.cpp AssertException.h \ + CheckMacros.h Checks.cpp \ + Checks.h Config.h \ + DeferredTestReporter.cpp DeferredTestReporter.h \ + DeferredTestResult.cpp DeferredTestResult.h \ + MemoryOutStream.cpp MemoryOutStream.h \ + ReportAssert.cpp ReportAssert.h \ + Test.cpp TestDetails.cpp \ + TestDetails.h Test.h \ + TestList.cpp TestList.h \ + TestMacros.h TestReporter.cpp \ + TestReporter.h TestReporterStdout.cpp \ + TestReporterStdout.h TestResults.cpp \ + TestResults.h TestRunner.cpp \ + TestRunner.h TestSuite.h \ + TimeConstraint.cpp TimeConstraint.h \ + TimeHelpers.h UnitTest++.h \ + XmlTestReporter.cpp XmlTestReporter.h +if WIN32 +libunittestpp_la_LIBADD = $(builddir)/Win32/libhelper.la +else +libunittestpp_la_LIBADD = $(builddir)/Posix/libhelper.la +endif + diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Makefile.in b/libs/ode-0.16.1/tests/UnitTest++/src/Makefile.in new file mode 100644 index 0000000..a0707bd --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/Makefile.in @@ -0,0 +1,784 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = tests/UnitTest++/src +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ode/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +@WIN32_FALSE@libunittestpp_la_DEPENDENCIES = \ +@WIN32_FALSE@ $(builddir)/Posix/libhelper.la +@WIN32_TRUE@libunittestpp_la_DEPENDENCIES = \ +@WIN32_TRUE@ $(builddir)/Win32/libhelper.la +am_libunittestpp_la_OBJECTS = AssertException.lo Checks.lo \ + DeferredTestReporter.lo DeferredTestResult.lo \ + MemoryOutStream.lo ReportAssert.lo Test.lo TestDetails.lo \ + TestList.lo TestReporter.lo TestReporterStdout.lo \ + TestResults.lo TestRunner.lo TimeConstraint.lo \ + XmlTestReporter.lo +libunittestpp_la_OBJECTS = $(am_libunittestpp_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libunittestpp_la_SOURCES) +DIST_SOURCES = $(libunittestpp_la_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = Posix Win32 +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_CFLAGS = @CCD_CFLAGS@ +CCD_LIBS = @CCD_LIBS@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSTDCXX = @LIBSTDCXX@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ODE_PRECISION = @ODE_PRECISION@ +ODE_VERSION = @ODE_VERSION@ +ODE_VERSION_INFO = @ODE_VERSION_INFO@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +@WIN32_FALSE@SUBDIRS = Posix +@WIN32_TRUE@SUBDIRS = Win32 +check_LTLIBRARIES = libunittestpp.la +libunittestpp_la_SOURCES = AssertException.cpp AssertException.h \ + CheckMacros.h Checks.cpp \ + Checks.h Config.h \ + DeferredTestReporter.cpp DeferredTestReporter.h \ + DeferredTestResult.cpp DeferredTestResult.h \ + MemoryOutStream.cpp MemoryOutStream.h \ + ReportAssert.cpp ReportAssert.h \ + Test.cpp TestDetails.cpp \ + TestDetails.h Test.h \ + TestList.cpp TestList.h \ + TestMacros.h TestReporter.cpp \ + TestReporter.h TestReporterStdout.cpp \ + TestReporterStdout.h TestResults.cpp \ + TestResults.h TestRunner.cpp \ + TestRunner.h TestSuite.h \ + TimeConstraint.cpp TimeConstraint.h \ + TimeHelpers.h UnitTest++.h \ + XmlTestReporter.cpp XmlTestReporter.h + +@WIN32_FALSE@libunittestpp_la_LIBADD = $(builddir)/Posix/libhelper.la +@WIN32_TRUE@libunittestpp_la_LIBADD = $(builddir)/Win32/libhelper.la +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/UnitTest++/src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/UnitTest++/src/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkLTLIBRARIES: + -test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES) + @list='$(check_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libunittestpp.la: $(libunittestpp_la_OBJECTS) $(libunittestpp_la_DEPENDENCIES) $(EXTRA_libunittestpp_la_DEPENDENCIES) + $(AM_V_CXXLD)$(CXXLINK) $(libunittestpp_la_OBJECTS) $(libunittestpp_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AssertException.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Checks.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DeferredTestReporter.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DeferredTestResult.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MemoryOutStream.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ReportAssert.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Test.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TestDetails.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TestList.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TestReporter.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TestReporterStdout.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TestResults.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TestRunner.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeConstraint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XmlTestReporter.Plo@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_LTLIBRARIES) +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-checkLTLIBRARIES clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) check-am install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-checkLTLIBRARIES clean-generic \ + clean-libtool cscopelist-am ctags ctags-am distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/MemoryOutStream.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/MemoryOutStream.cpp new file mode 100644 index 0000000..04d4082 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/MemoryOutStream.cpp @@ -0,0 +1,143 @@ +#include "MemoryOutStream.h" + +#ifndef UNITTEST_USE_CUSTOM_STREAMS + + +namespace UnitTest { + +char const* MemoryOutStream::GetText() const +{ + m_text = this->str(); + return m_text.c_str(); +} + + +} + + +#else + + +#include <cstring> +#include <cstdio> + +namespace UnitTest { + +namespace { + +template<typename ValueType> +void FormatToStream(MemoryOutStream& stream, char const* format, ValueType const& value) +{ + char txt[32]; + std::sprintf(txt, format, value); + stream << txt; +} + +int RoundUpToMultipleOfPow2Number (int n, int pow2Number) +{ + return (n + (pow2Number - 1)) & ~(pow2Number - 1); +} + +} + + +MemoryOutStream::MemoryOutStream(int const size) + : m_capacity (0) + , m_buffer (0) + +{ + GrowBuffer(size); +} + +MemoryOutStream::~MemoryOutStream() +{ + delete [] m_buffer; +} + +char const* MemoryOutStream::GetText() const +{ + return m_buffer; +} + +MemoryOutStream& MemoryOutStream::operator << (char const* txt) +{ + int const bytesLeft = m_capacity - (int)std::strlen(m_buffer); + int const bytesRequired = (int)std::strlen(txt) + 1; + + if (bytesRequired > bytesLeft) + { + int const requiredCapacity = bytesRequired + m_capacity - bytesLeft; + GrowBuffer(requiredCapacity); + } + + std::strcat(m_buffer, txt); + return *this; +} + +MemoryOutStream& MemoryOutStream::operator << (int const n) +{ + FormatToStream(*this, "%i", n); + return *this; +} + +MemoryOutStream& MemoryOutStream::operator << (long const n) +{ + FormatToStream(*this, "%li", n); + return *this; +} + +MemoryOutStream& MemoryOutStream::operator << (unsigned long const n) +{ + FormatToStream(*this, "%lu", n); + return *this; +} + +MemoryOutStream& MemoryOutStream::operator << (float const f) +{ + FormatToStream(*this, "%ff", f); + return *this; +} + +MemoryOutStream& MemoryOutStream::operator << (void const* p) +{ + FormatToStream(*this, "%p", p); + return *this; +} + +MemoryOutStream& MemoryOutStream::operator << (unsigned int const s) +{ + FormatToStream(*this, "%u", s); + return *this; +} + +MemoryOutStream& MemoryOutStream::operator <<(double const d) +{ + FormatToStream(*this, "%f", d); + return *this; +} + +int MemoryOutStream::GetCapacity() const +{ + return m_capacity; +} + + +void MemoryOutStream::GrowBuffer(int const desiredCapacity) +{ + int const newCapacity = RoundUpToMultipleOfPow2Number(desiredCapacity, GROW_CHUNK_SIZE); + + char* buffer = new char[newCapacity]; + if (m_buffer) + std::strcpy(buffer, m_buffer); + else + std::strcpy(buffer, ""); + + delete [] m_buffer; + m_buffer = buffer; + m_capacity = newCapacity; +} + +} + + +#endif diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/MemoryOutStream.h b/libs/ode-0.16.1/tests/UnitTest++/src/MemoryOutStream.h new file mode 100644 index 0000000..e03227e --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/MemoryOutStream.h @@ -0,0 +1,67 @@ +#ifndef UNITTEST_MEMORYOUTSTREAM_H +#define UNITTEST_MEMORYOUTSTREAM_H + +#include "Config.h" + +#ifndef UNITTEST_USE_CUSTOM_STREAMS + +#include <sstream> + +namespace UnitTest +{ + +class MemoryOutStream : public std::ostringstream +{ +public: + MemoryOutStream() {} + char const* GetText() const; + +private: + MemoryOutStream(MemoryOutStream const&); + void operator =(MemoryOutStream const&); + + mutable std::string m_text; +}; + +} + +#else + +#include <cstddef> + +namespace UnitTest +{ + +class MemoryOutStream +{ +public: + explicit MemoryOutStream(int const size = 256); + ~MemoryOutStream(); + + char const* GetText() const; + + MemoryOutStream& operator << (char const* txt); + MemoryOutStream& operator << (int n); + MemoryOutStream& operator << (long n); + MemoryOutStream& operator << (unsigned long n); + MemoryOutStream& operator << (float f); + MemoryOutStream& operator << (double d); + MemoryOutStream& operator << (void const* p); + MemoryOutStream& operator << (unsigned int s); + + enum { GROW_CHUNK_SIZE = 32 }; + int GetCapacity() const; + +private: + void operator= (MemoryOutStream const&); + void GrowBuffer(int capacity); + + int m_capacity; + char* m_buffer; +}; + +} + +#endif + +#endif diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Posix/Makefile.am b/libs/ode-0.16.1/tests/UnitTest++/src/Posix/Makefile.am new file mode 100644 index 0000000..349b3c0 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/Posix/Makefile.am @@ -0,0 +1,5 @@ +check_LTLIBRARIES = libhelper.la + +libhelper_la_SOURCES = SignalTranslator.cpp SignalTranslator.h \ + TimeHelpers.cpp TimeHelpers.h + diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Posix/Makefile.in b/libs/ode-0.16.1/tests/UnitTest++/src/Posix/Makefile.in new file mode 100644 index 0000000..8f69c7f --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/Posix/Makefile.in @@ -0,0 +1,627 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = tests/UnitTest++/src/Posix +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ode/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +libhelper_la_LIBADD = +am_libhelper_la_OBJECTS = SignalTranslator.lo TimeHelpers.lo +libhelper_la_OBJECTS = $(am_libhelper_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libhelper_la_SOURCES) +DIST_SOURCES = $(libhelper_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_CFLAGS = @CCD_CFLAGS@ +CCD_LIBS = @CCD_LIBS@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSTDCXX = @LIBSTDCXX@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ODE_PRECISION = @ODE_PRECISION@ +ODE_VERSION = @ODE_VERSION@ +ODE_VERSION_INFO = @ODE_VERSION_INFO@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +check_LTLIBRARIES = libhelper.la +libhelper_la_SOURCES = SignalTranslator.cpp SignalTranslator.h \ + TimeHelpers.cpp TimeHelpers.h + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/UnitTest++/src/Posix/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/UnitTest++/src/Posix/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkLTLIBRARIES: + -test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES) + @list='$(check_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libhelper.la: $(libhelper_la_OBJECTS) $(libhelper_la_DEPENDENCIES) $(EXTRA_libhelper_la_DEPENDENCIES) + $(AM_V_CXXLD)$(CXXLINK) $(libhelper_la_OBJECTS) $(libhelper_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SignalTranslator.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeHelpers.Plo@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_LTLIBRARIES) +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkLTLIBRARIES clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ + clean-checkLTLIBRARIES clean-generic clean-libtool \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Posix/SignalTranslator.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/Posix/SignalTranslator.cpp new file mode 100644 index 0000000..a31cb25 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/Posix/SignalTranslator.cpp @@ -0,0 +1,46 @@ +#include "SignalTranslator.h" + +namespace UnitTest { + +sigjmp_buf* SignalTranslator::s_jumpTarget = 0; + +namespace { + +void SignalHandler (int sig) +{ + siglongjmp(*SignalTranslator::s_jumpTarget, sig ); +} + +} + + +SignalTranslator::SignalTranslator () +{ + m_oldJumpTarget = s_jumpTarget; + s_jumpTarget = &m_currentJumpTarget; + + struct sigaction action; + action.sa_flags = 0; + action.sa_handler = SignalHandler; + sigemptyset( &action.sa_mask ); + + sigaction( SIGSEGV, &action, &m_old_SIGSEGV_action ); + sigaction( SIGFPE , &action, &m_old_SIGFPE_action ); + sigaction( SIGTRAP, &action, &m_old_SIGTRAP_action ); + sigaction( SIGBUS , &action, &m_old_SIGBUS_action ); + sigaction( SIGILL , &action, &m_old_SIGBUS_action ); +} + +SignalTranslator::~SignalTranslator() +{ + sigaction( SIGILL , &m_old_SIGBUS_action , 0 ); + sigaction( SIGBUS , &m_old_SIGBUS_action , 0 ); + sigaction( SIGTRAP, &m_old_SIGTRAP_action, 0 ); + sigaction( SIGFPE , &m_old_SIGFPE_action , 0 ); + sigaction( SIGSEGV, &m_old_SIGSEGV_action, 0 ); + + s_jumpTarget = m_oldJumpTarget; +} + + +} diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Posix/SignalTranslator.h b/libs/ode-0.16.1/tests/UnitTest++/src/Posix/SignalTranslator.h new file mode 100644 index 0000000..dfa0d11 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/Posix/SignalTranslator.h @@ -0,0 +1,42 @@ +#ifndef UNITTEST_SIGNALTRANSLATOR_H +#define UNITTEST_SIGNALTRANSLATOR_H + +#include <setjmp.h> +#include <signal.h> + +namespace UnitTest { + +class SignalTranslator +{ +public: + SignalTranslator(); + ~SignalTranslator(); + + static sigjmp_buf* s_jumpTarget; + +private: + sigjmp_buf m_currentJumpTarget; + sigjmp_buf* m_oldJumpTarget; + + struct sigaction m_old_SIGFPE_action; + struct sigaction m_old_SIGTRAP_action; + struct sigaction m_old_SIGSEGV_action; + struct sigaction m_old_SIGBUS_action; + struct sigaction m_old_SIGABRT_action; + struct sigaction m_old_SIGALRM_action; +}; + +#ifdef SOLARIS + #define UNITTEST_EXTENSION +#else + #define UNITTEST_EXTENSION __extension__ +#endif + +#define UNITTEST_THROW_SIGNALS \ + UnitTest::SignalTranslator sig; \ + if (UNITTEST_EXTENSION sigsetjmp(*UnitTest::SignalTranslator::s_jumpTarget, 1) != 0) \ + throw ("Unhandled system exception"); + +} + +#endif diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Posix/TimeHelpers.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/Posix/TimeHelpers.cpp new file mode 100644 index 0000000..bfd23c0 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/Posix/TimeHelpers.cpp @@ -0,0 +1,33 @@ +#include "TimeHelpers.h" +#include <unistd.h> + +namespace UnitTest { + +Timer::Timer() +{ + m_startTime.tv_sec = 0; + m_startTime.tv_usec = 0; +} + +void Timer::Start() +{ + gettimeofday(&m_startTime, 0); +} + + +int Timer::GetTimeInMs() const +{ + struct timeval currentTime; + gettimeofday(¤tTime, 0); + int const dsecs = currentTime.tv_sec - m_startTime.tv_sec; + int const dus = currentTime.tv_usec - m_startTime.tv_usec; + return dsecs*1000 + dus/1000; +} + + +void TimeHelpers::SleepMs (int ms) +{ + usleep(ms * 1000); +} + +} diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Posix/TimeHelpers.h b/libs/ode-0.16.1/tests/UnitTest++/src/Posix/TimeHelpers.h new file mode 100644 index 0000000..fdc8428 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/Posix/TimeHelpers.h @@ -0,0 +1,28 @@ +#ifndef UNITTEST_TIMEHELPERS_H +#define UNITTEST_TIMEHELPERS_H + +#include <sys/time.h> + +namespace UnitTest { + +class Timer +{ +public: + Timer(); + void Start(); + int GetTimeInMs() const; + +private: + struct timeval m_startTime; +}; + + +namespace TimeHelpers +{ +void SleepMs (int ms); +} + + +} + +#endif diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/ReportAssert.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/ReportAssert.cpp new file mode 100644 index 0000000..6c7db58 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/ReportAssert.cpp @@ -0,0 +1,10 @@ +#include "AssertException.h" + +namespace UnitTest { + +void ReportAssert(char const* description, char const* filename, int const lineNumber) +{ + throw AssertException(description, filename, lineNumber); +} + +} diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/ReportAssert.h b/libs/ode-0.16.1/tests/UnitTest++/src/ReportAssert.h new file mode 100644 index 0000000..d4dd864 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/ReportAssert.h @@ -0,0 +1,10 @@ +#ifndef UNITTEST_ASSERT_H +#define UNITTEST_ASSERT_H + +namespace UnitTest { + +void ReportAssert(char const* description, char const* filename, int lineNumber); + +} + +#endif diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Test.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/Test.cpp new file mode 100644 index 0000000..943fced --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/Test.cpp @@ -0,0 +1,62 @@ +#include "Config.h" +#include "Test.h" +#include "TestList.h" +#include "TestResults.h" +#include "AssertException.h" +#include "MemoryOutStream.h" + +#ifdef UNITTEST_POSIX + #include "Posix/SignalTranslator.h" +#endif + +namespace UnitTest { + +TestList& Test::GetTestList() +{ + static TestList s_list; + return s_list; +} + +Test::Test(char const* testName, char const* suiteName, char const* filename, int const lineNumber) + : m_details(testName, suiteName, filename, lineNumber) + , next(0) + , m_timeConstraintExempt(false) +{ +} + +Test::~Test() +{ +} + +void Test::Run(TestResults& testResults) const +{ + try + { +#ifdef UNITTEST_POSIX + UNITTEST_THROW_SIGNALS +#endif + RunImpl(testResults); + } + catch (AssertException const& e) + { + testResults.OnTestFailure( TestDetails(m_details.testName, m_details.suiteName, e.Filename(), e.LineNumber()), e.what()); + } + catch (std::exception const& e) + { + MemoryOutStream stream; + stream << "Unhandled exception: " << e.what(); + testResults.OnTestFailure(m_details, stream.GetText()); + } + catch (...) + { + testResults.OnTestFailure(m_details, "Unhandled exception: Crash!"); + } +} + + +void Test::RunImpl(TestResults&) const +{ +} + + +} diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Test.h b/libs/ode-0.16.1/tests/UnitTest++/src/Test.h new file mode 100644 index 0000000..458c75c --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/Test.h @@ -0,0 +1,34 @@ +#ifndef UNITTEST_TEST_H +#define UNITTEST_TEST_H + +#include "TestDetails.h" + +namespace UnitTest { + +class TestResults; +class TestList; + +class Test +{ +public: + Test(char const* testName, char const* suiteName = "DefaultSuite", char const* filename = "", int lineNumber = 0); + virtual ~Test(); + void Run(TestResults& testResults) const; + + TestDetails const m_details; + Test* next; + mutable bool m_timeConstraintExempt; + + static TestList& GetTestList(); + +private: + virtual void RunImpl(TestResults& testResults_) const; + + Test(Test const&); + Test& operator =(Test const&); +}; + + +} + +#endif diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestDetails.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/TestDetails.cpp new file mode 100644 index 0000000..a13a168 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestDetails.cpp @@ -0,0 +1,22 @@ +#include "TestDetails.h" + +namespace UnitTest { + +TestDetails::TestDetails(char const* testName_, char const* suiteName_, char const* filename_, int lineNumber_) + : suiteName(suiteName_) + , testName(testName_) + , filename(filename_) + , lineNumber(lineNumber_) +{ +} + +TestDetails::TestDetails(const TestDetails& details, int lineNumber_) + : suiteName(details.suiteName) + , testName(details.testName) + , filename(details.filename) + , lineNumber(lineNumber_) +{ +} + + +} diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestDetails.h b/libs/ode-0.16.1/tests/UnitTest++/src/TestDetails.h new file mode 100644 index 0000000..eae0e71 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestDetails.h @@ -0,0 +1,24 @@ +#ifndef UNITTEST_TESTDETAILS_H +#define UNITTEST_TESTDETAILS_H + +namespace UnitTest { + +class TestDetails +{ +public: + TestDetails(char const* testName, char const* suiteName, char const* filename, int lineNumber); + TestDetails(const TestDetails& details, int lineNumber); + + char const* const suiteName; + char const* const testName; + char const* const filename; + int const lineNumber; + + TestDetails(TestDetails const&); // Why is it public? --> http://gcc.gnu.org/bugs.html#cxx_rvalbind +private: + TestDetails& operator=(TestDetails const&); +}; + +} + +#endif diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestList.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/TestList.cpp new file mode 100644 index 0000000..d11965c --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestList.cpp @@ -0,0 +1,39 @@ +#include "TestList.h" +#include "Test.h" + +#include <cassert> + +namespace UnitTest { + +TestList::TestList() + : m_head(0) + , m_tail(0) +{ +} + +void TestList::Add(Test* test) +{ + if (m_tail == 0) + { + assert(m_head == 0); + m_head = test; + m_tail = test; + } + else + { + m_tail->next = test; + m_tail = test; + } +} + +const Test* TestList::GetHead() const +{ + return m_head; +} + +ListAdder::ListAdder(TestList& list, Test* test) +{ + list.Add(test); +} + +} diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestList.h b/libs/ode-0.16.1/tests/UnitTest++/src/TestList.h new file mode 100644 index 0000000..14b978a --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestList.h @@ -0,0 +1,32 @@ +#ifndef UNITTEST_TESTLIST_H +#define UNITTEST_TESTLIST_H + + +namespace UnitTest { + +class Test; + +class TestList +{ +public: + TestList(); + void Add (Test* test); + + const Test* GetHead() const; + +private: + Test* m_head; + Test* m_tail; +}; + + +class ListAdder +{ +public: + ListAdder(TestList& list, Test* test); +}; + +} + + +#endif diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestMacros.h b/libs/ode-0.16.1/tests/UnitTest++/src/TestMacros.h new file mode 100644 index 0000000..09ecc6b --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestMacros.h @@ -0,0 +1,99 @@ +#ifndef UNITTEST_TESTMACROS_H +#define UNITTEST_TESTMACROS_H + +#include "Config.h" + +#ifndef UNITTEST_POSIX + #define UNITTEST_THROW_SIGNALS +#else + #include "Posix/SignalTranslator.h" +#endif + +#ifdef TEST + #error UnitTest++ redefines TEST +#endif + +#define SUITE(Name) \ + namespace Name { \ + namespace UnitTestSuite { \ + inline char const* GetSuiteName () { \ + return #Name ; \ + } \ + } \ + } \ + namespace Name + +#define TEST_EX(Name, List) \ + class Test##Name : public UnitTest::Test \ + { \ + public: \ + Test##Name() : Test(#Name, UnitTestSuite::GetSuiteName(), __FILE__, __LINE__) {} \ + private: \ + virtual void RunImpl(UnitTest::TestResults& testResults_) const; \ + } test##Name##Instance; \ + \ + UnitTest::ListAdder adder##Name (List, &test##Name##Instance); \ + \ + void Test##Name::RunImpl(UnitTest::TestResults& testResults_) const + + +#define TEST(Name) TEST_EX(Name, UnitTest::Test::GetTestList()) + + +#define TEST_FIXTURE_EX(Fixture, Name, List) \ + class Fixture##Name##Helper : public Fixture \ + { \ + public: \ + Fixture##Name##Helper(UnitTest::TestDetails const& details) : m_details(details) {} \ + void RunTest(UnitTest::TestResults& testResults_); \ + UnitTest::TestDetails const& m_details; \ + private: \ + Fixture##Name##Helper(Fixture##Name##Helper const&); \ + Fixture##Name##Helper& operator =(Fixture##Name##Helper const&); \ + }; \ + \ + class Test##Fixture##Name : public UnitTest::Test \ + { \ + public: \ + Test##Fixture##Name() : Test(#Name, UnitTestSuite::GetSuiteName(), __FILE__, __LINE__) {} \ + private: \ + virtual void RunImpl(UnitTest::TestResults& testResults_) const; \ + } test##Fixture##Name##Instance; \ + \ + UnitTest::ListAdder adder##Fixture##Name (List, &test##Fixture##Name##Instance); \ + \ + void Test##Fixture##Name::RunImpl(UnitTest::TestResults& testResults_) const \ + { \ + bool ctorOk = false; \ + try { \ + Fixture##Name##Helper fixtureHelper(m_details); \ + ctorOk = true; \ + try { \ + UNITTEST_THROW_SIGNALS; \ + fixtureHelper.RunTest(testResults_); \ + } catch (UnitTest::AssertException const& e) { \ + testResults_.OnTestFailure(UnitTest::TestDetails(m_details.testName, m_details.suiteName, e.Filename(), e.LineNumber()), e.what()); \ + } catch (std::exception const& e) { \ + UnitTest::MemoryOutStream stream; \ + stream << "Unhandled exception: " << e.what(); \ + testResults_.OnTestFailure(m_details, stream.GetText()); \ + } catch (...) { testResults_.OnTestFailure(m_details, "Unhandled exception: Crash!"); } \ + } \ + catch (...) { \ + if (ctorOk) \ + { \ + testResults_.OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \ + "Unhandled exception while destroying fixture " #Fixture); \ + } \ + else \ + { \ + testResults_.OnTestFailure(UnitTest::TestDetails(m_details, __LINE__), \ + "Unhandled exception while constructing fixture " #Fixture); \ + } \ + } \ + } \ + void Fixture##Name##Helper::RunTest(UnitTest::TestResults& testResults_) + +#define TEST_FIXTURE(Fixture,Name) TEST_FIXTURE_EX(Fixture, Name, UnitTest::Test::GetTestList()) + +#endif diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestReporter.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/TestReporter.cpp new file mode 100644 index 0000000..608d3c6 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestReporter.cpp @@ -0,0 +1,10 @@ +#include "TestReporter.h" + +namespace UnitTest { + + +TestReporter::~TestReporter() +{ +} + +} diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestReporter.h b/libs/ode-0.16.1/tests/UnitTest++/src/TestReporter.h new file mode 100644 index 0000000..5a2f404 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestReporter.h @@ -0,0 +1,20 @@ +#ifndef UNITTEST_TESTREPORTER_H +#define UNITTEST_TESTREPORTER_H + +namespace UnitTest { + +class TestDetails; + +class TestReporter +{ +public: + virtual ~TestReporter(); + + virtual void ReportTestStart(TestDetails const& test) = 0; + virtual void ReportFailure(TestDetails const& test, char const* failure) = 0; + virtual void ReportTestFinish(TestDetails const& test, float secondsElapsed) = 0; + virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed) = 0; +}; + +} +#endif diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestReporterStdout.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/TestReporterStdout.cpp new file mode 100644 index 0000000..133e6fa --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestReporterStdout.cpp @@ -0,0 +1,36 @@ +#include "TestReporterStdout.h" +#include <cstdio> + +#include "TestDetails.h" + +namespace UnitTest { + +void TestReporterStdout::ReportFailure(TestDetails const& details, char const* failure) +{ +#ifdef __APPLE__ + char const* const errorFormat = "%s:%d: error: Failure in %s: %s\n"; +#else + char const* const errorFormat = "%s(%d): error: Failure in %s: %s\n"; +#endif + std::printf(errorFormat, details.filename, details.lineNumber, details.testName, failure); +} + +void TestReporterStdout::ReportTestStart(TestDetails const& /*test*/) +{ +} + +void TestReporterStdout::ReportTestFinish(TestDetails const& /*test*/, float) +{ +} + +void TestReporterStdout::ReportSummary(int const totalTestCount, int const failedTestCount, + int const failureCount, float secondsElapsed) +{ + if (failureCount > 0) + std::printf("FAILURE: %d out of %d tests failed (%d failures).\n", failedTestCount, totalTestCount, failureCount); + else + std::printf("Success: %d tests passed.\n", totalTestCount); + std::printf("Test time: %.2f seconds.\n", secondsElapsed); +} + +} diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestReporterStdout.h b/libs/ode-0.16.1/tests/UnitTest++/src/TestReporterStdout.h new file mode 100644 index 0000000..eacbba3 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestReporterStdout.h @@ -0,0 +1,19 @@ +#ifndef UNITTEST_TESTREPORTERSTDOUT_H +#define UNITTEST_TESTREPORTERSTDOUT_H + +#include "TestReporter.h" + +namespace UnitTest { + +class TestReporterStdout : public TestReporter +{ +private: + virtual void ReportTestStart(TestDetails const& test); + virtual void ReportFailure(TestDetails const& test, char const* failure); + virtual void ReportTestFinish(TestDetails const& test, float secondsElapsed); + virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed); +}; + +} + +#endif diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestResults.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/TestResults.cpp new file mode 100644 index 0000000..b3b67c0 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestResults.cpp @@ -0,0 +1,60 @@ +#include "TestResults.h" +#include "TestReporter.h" + +#include "TestDetails.h" + +namespace UnitTest { + +TestResults::TestResults(TestReporter* testReporter) + : m_testReporter(testReporter) + , m_totalTestCount(0) + , m_failedTestCount(0) + , m_failureCount(0) + , m_currentTestFailed(false) +{ +} + +void TestResults::OnTestStart(TestDetails const& test) +{ + ++m_totalTestCount; + m_currentTestFailed = false; + if (m_testReporter) + m_testReporter->ReportTestStart(test); +} + +void TestResults::OnTestFailure(TestDetails const& test, char const* failure) +{ + ++m_failureCount; + if (!m_currentTestFailed) + { + ++m_failedTestCount; + m_currentTestFailed = true; + } + + if (m_testReporter) + m_testReporter->ReportFailure(test, failure); +} + +void TestResults::OnTestFinish(TestDetails const& test, float secondsElapsed) +{ + if (m_testReporter) + m_testReporter->ReportTestFinish(test, secondsElapsed); +} + +int TestResults::GetTotalTestCount() const +{ + return m_totalTestCount; +} + +int TestResults::GetFailedTestCount() const +{ + return m_failedTestCount; +} + +int TestResults::GetFailureCount() const +{ + return m_failureCount; +} + + +} diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestResults.h b/libs/ode-0.16.1/tests/UnitTest++/src/TestResults.h new file mode 100644 index 0000000..8ef7fda --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestResults.h @@ -0,0 +1,36 @@ +#ifndef UNITTEST_TESTRESULTS_H +#define UNITTEST_TESTRESULTS_H + +namespace UnitTest { + +class TestReporter; +class TestDetails; + +class TestResults +{ +public: + explicit TestResults(TestReporter* reporter = 0); + + void OnTestStart(TestDetails const& test); + void OnTestFailure(TestDetails const& test, char const* failure); + void OnTestFinish(TestDetails const& test, float secondsElapsed); + + int GetTotalTestCount() const; + int GetFailedTestCount() const; + int GetFailureCount() const; + +private: + TestReporter* m_testReporter; + int m_totalTestCount; + int m_failedTestCount; + int m_failureCount; + + bool m_currentTestFailed; + + TestResults(TestResults const&); + TestResults& operator =(TestResults const&); +}; + +} + +#endif diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestRunner.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/TestRunner.cpp new file mode 100644 index 0000000..5780d91 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestRunner.cpp @@ -0,0 +1,60 @@ +#include "TestRunner.h" +#include "TestResults.h" +#include "Test.h" +#include "TestList.h" +#include "TestReporter.h" +#include "TestReporterStdout.h" +#include "TimeHelpers.h" +#include "MemoryOutStream.h" +#include <cstring> + + +namespace UnitTest { + + +int RunAllTests(TestReporter& reporter, TestList const& list, char const* suiteName, int const maxTestTimeInMs ) +{ + TestResults result(&reporter); + + Timer overallTimer; + overallTimer.Start(); + + Test const* curTest = list.GetHead(); + while (curTest != 0) + { + if (suiteName == 0 || !std::strcmp(curTest->m_details.suiteName, suiteName)) + { + Timer testTimer; + testTimer.Start(); + result.OnTestStart(curTest->m_details); + + curTest->Run(result); + + int const testTimeInMs = testTimer.GetTimeInMs(); + if (maxTestTimeInMs > 0 && testTimeInMs > maxTestTimeInMs && !curTest->m_timeConstraintExempt) + { + MemoryOutStream stream; + stream << "Global time constraint failed. Expected under " << maxTestTimeInMs << + "ms but took " << testTimeInMs << "ms."; + result.OnTestFailure(curTest->m_details, stream.GetText()); + } + result.OnTestFinish(curTest->m_details, testTimeInMs/1000.0f); + } + + curTest = curTest->next; + } + + float const secondsElapsed = overallTimer.GetTimeInMs() / 1000.0f; + reporter.ReportSummary(result.GetTotalTestCount(), result.GetFailedTestCount(), result.GetFailureCount(), secondsElapsed); + + return result.GetFailureCount(); +} + + +int RunAllTests() +{ + TestReporterStdout reporter; + return RunAllTests(reporter, Test::GetTestList(), 0); +} + +} diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestRunner.h b/libs/ode-0.16.1/tests/UnitTest++/src/TestRunner.h new file mode 100644 index 0000000..8b9934a --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestRunner.h @@ -0,0 +1,17 @@ +#ifndef UNITTEST_TESTRUNNER_H +#define UNITTEST_TESTRUNNER_H + + +namespace UnitTest { + +class TestReporter; +class TestList; + + +int RunAllTests(); +int RunAllTests(TestReporter& reporter, TestList const& list, char const* suiteName, int maxTestTimeInMs = 0); + +} + + +#endif diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TestSuite.h b/libs/ode-0.16.1/tests/UnitTest++/src/TestSuite.h new file mode 100644 index 0000000..dd3717e --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/TestSuite.h @@ -0,0 +1,14 @@ +#ifndef UNITTEST_TESTSUITE_H +#define UNITTEST_TESTSUITE_H + +namespace UnitTestSuite { + + inline char const* GetSuiteName () + { + return "DefaultSuite"; + } + +} + +#endif + diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TimeConstraint.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/TimeConstraint.cpp new file mode 100644 index 0000000..451c2b3 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/TimeConstraint.cpp @@ -0,0 +1,28 @@ +#include "TimeConstraint.h" +#include "TestResults.h" +#include "MemoryOutStream.h" + +namespace UnitTest { + + +TimeConstraint::TimeConstraint(int ms, TestResults& result, TestDetails const& details) + : m_result(result) + , m_details(details) + , m_maxMs(ms) +{ + m_timer.Start(); +} + +TimeConstraint::~TimeConstraint() +{ + int const totalTimeInMs = m_timer.GetTimeInMs(); + if (totalTimeInMs > m_maxMs) + { + MemoryOutStream stream; + stream << "Time constraint failed. Expected to run test under " << m_maxMs << + "ms but took " << totalTimeInMs << "ms."; + m_result.OnTestFailure(m_details, stream.GetText()); + } +} + +} diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TimeConstraint.h b/libs/ode-0.16.1/tests/UnitTest++/src/TimeConstraint.h new file mode 100644 index 0000000..8451c66 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/TimeConstraint.h @@ -0,0 +1,34 @@ +#ifndef UNITTEST_TIMECONSTRAINT_H +#define UNITTEST_TIMECONSTRAINT_H + +#include "TimeHelpers.h" + +namespace UnitTest { + +class TestResults; +class TestDetails; + +class TimeConstraint +{ +public: + TimeConstraint(int ms, TestResults& result, TestDetails const& details); + ~TimeConstraint(); + +private: + void operator=(TimeConstraint const&); + TimeConstraint(TimeConstraint const&); + + Timer m_timer; + TestResults& m_result; + TestDetails const& m_details; + int const m_maxMs; +}; + +#define UNITTEST_TIME_CONSTRAINT(ms) \ + UnitTest::TimeConstraint unitTest__timeConstraint__(ms, testResults_, UnitTest::TestDetails(m_details, __LINE__)) + +#define UNITTEST_TIME_CONSTRAINT_EXEMPT() do { m_timeConstraintExempt = true; } while (0) + +} + +#endif diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/TimeHelpers.h b/libs/ode-0.16.1/tests/UnitTest++/src/TimeHelpers.h new file mode 100644 index 0000000..f34ed00 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/TimeHelpers.h @@ -0,0 +1,7 @@ +#include "Config.h" + +#if defined UNITTEST_POSIX + #include "Posix/TimeHelpers.h" +#else + #include "Win32/TimeHelpers.h" +#endif diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/UnitTest++.h b/libs/ode-0.16.1/tests/UnitTest++/src/UnitTest++.h new file mode 100644 index 0000000..019f80a --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/UnitTest++.h @@ -0,0 +1,17 @@ +#ifndef UNITTESTCPP_H +#define UNITTESTCPP_H + +#include "Config.h" +#include "Test.h" +#include "TestList.h" +#include "TestSuite.h" +#include "TestResults.h" + +#include <new> +#include "TestMacros.h" + +#include "CheckMacros.h" +#include "TestRunner.h" +#include "TimeConstraint.h" + +#endif diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Win32/Makefile.am b/libs/ode-0.16.1/tests/UnitTest++/src/Win32/Makefile.am new file mode 100644 index 0000000..faa35b8 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/Win32/Makefile.am @@ -0,0 +1,4 @@ +check_LTLIBRARIES = libhelper.la + +libhelper_la_SOURCES = TimeHelpers.cpp TimeHelpers.h + diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Win32/Makefile.in b/libs/ode-0.16.1/tests/UnitTest++/src/Win32/Makefile.in new file mode 100644 index 0000000..0595763 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/Win32/Makefile.in @@ -0,0 +1,624 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = tests/UnitTest++/src/Win32 +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ode/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +libhelper_la_LIBADD = +am_libhelper_la_OBJECTS = TimeHelpers.lo +libhelper_la_OBJECTS = $(am_libhelper_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libhelper_la_SOURCES) +DIST_SOURCES = $(libhelper_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_CFLAGS = @CCD_CFLAGS@ +CCD_LIBS = @CCD_LIBS@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSTDCXX = @LIBSTDCXX@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ODE_PRECISION = @ODE_PRECISION@ +ODE_VERSION = @ODE_VERSION@ +ODE_VERSION_INFO = @ODE_VERSION_INFO@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +check_LTLIBRARIES = libhelper.la +libhelper_la_SOURCES = TimeHelpers.cpp TimeHelpers.h +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/UnitTest++/src/Win32/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/UnitTest++/src/Win32/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkLTLIBRARIES: + -test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES) + @list='$(check_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libhelper.la: $(libhelper_la_OBJECTS) $(libhelper_la_DEPENDENCIES) $(EXTRA_libhelper_la_DEPENDENCIES) + $(AM_V_CXXLD)$(CXXLINK) $(libhelper_la_OBJECTS) $(libhelper_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeHelpers.Plo@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_LTLIBRARIES) +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkLTLIBRARIES clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ + clean-checkLTLIBRARIES clean-generic clean-libtool \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Win32/TimeHelpers.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/Win32/TimeHelpers.cpp new file mode 100644 index 0000000..7c3dae8 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/Win32/TimeHelpers.cpp @@ -0,0 +1,46 @@ +#include "TimeHelpers.h" +#include <windows.h> + +namespace UnitTest { + +Timer::Timer() + : m_startTime(0) +{ + m_threadId = ::GetCurrentThread(); + DWORD_PTR systemMask; + ::GetProcessAffinityMask(GetCurrentProcess(), &m_processAffinityMask, &systemMask); + + ::SetThreadAffinityMask(m_threadId, 1); + ::QueryPerformanceFrequency(reinterpret_cast< LARGE_INTEGER* >(&m_frequency)); + ::SetThreadAffinityMask(m_threadId, m_processAffinityMask); +} + +void Timer::Start() +{ + m_startTime = GetTime(); +} + +int Timer::GetTimeInMs() const +{ + __int64 const elapsedTime = GetTime() - m_startTime; + double const seconds = double(elapsedTime) / double(m_frequency); + return int(seconds * 1000.0f); +} + +__int64 Timer::GetTime() const +{ + LARGE_INTEGER curTime; + ::SetThreadAffinityMask(m_threadId, 1); + ::QueryPerformanceCounter(&curTime); + ::SetThreadAffinityMask(m_threadId, m_processAffinityMask); + return curTime.QuadPart; +} + + + +void TimeHelpers::SleepMs(int const ms) +{ + ::Sleep(ms); +} + +} diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/Win32/TimeHelpers.h b/libs/ode-0.16.1/tests/UnitTest++/src/Win32/TimeHelpers.h new file mode 100644 index 0000000..56e30d5 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/Win32/TimeHelpers.h @@ -0,0 +1,48 @@ +#ifndef UNITTEST_TIMEHELPERS_H +#define UNITTEST_TIMEHELPERS_H + +#include "../Config.h" + + +#ifdef UNITTEST_MINGW + #ifndef __int64 + #define __int64 long long + #endif +#endif + +namespace UnitTest { + +class Timer +{ +public: + Timer(); + void Start(); + int GetTimeInMs() const; + +private: + __int64 GetTime() const; + + void* m_threadId; + +#if defined(_WIN64) + unsigned __int64 m_processAffinityMask; +#else + unsigned long m_processAffinityMask; +#endif + + __int64 m_startTime; + __int64 m_frequency; +}; + + +namespace TimeHelpers +{ +void SleepMs (int ms); +} + + +} + + + +#endif diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/XmlTestReporter.cpp b/libs/ode-0.16.1/tests/UnitTest++/src/XmlTestReporter.cpp new file mode 100644 index 0000000..0895e37 --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/XmlTestReporter.cpp @@ -0,0 +1,126 @@ +#include "XmlTestReporter.h" + +#include <iostream> +#include <sstream> +#include <string> + +using std::string; +using std::ostringstream; +using std::ostream; + +namespace { + +void ReplaceChar(string& str, char const c, string const& replacement) +{ + for (size_t pos = str.find(c); pos != string::npos; pos = str.find(c, pos + 1)) + str.replace(pos, 1, replacement); +} + +string XmlEscape(string const& value) +{ + string escaped = value; + + ReplaceChar(escaped, '&', "&"); + ReplaceChar(escaped, '<', "<"); + ReplaceChar(escaped, '>', ">"); + ReplaceChar(escaped, '\'', "'"); + ReplaceChar(escaped, '\"', """); + + return escaped; +} + +string BuildFailureMessage(string const& file, int const line, string const& message) +{ + ostringstream failureMessage; + failureMessage << file << "(" << line << ") : " << message; + return failureMessage.str(); +} + +} + +namespace UnitTest { + +XmlTestReporter::XmlTestReporter(ostream& ostream) + : m_ostream(ostream) +{ +} + +void XmlTestReporter::ReportSummary(int const totalTestCount, int const failedTestCount, + int const failureCount, float const secondsElapsed) +{ + AddXmlElement(m_ostream, NULL); + + BeginResults(m_ostream, totalTestCount, failedTestCount, failureCount, secondsElapsed); + + DeferredTestResultList const& results = GetResults(); + for (DeferredTestResultList::const_iterator i = results.begin(); i != results.end(); ++i) + { + BeginTest(m_ostream, *i); + + if (i->failed) + AddFailure(m_ostream, *i); + + EndTest(m_ostream, *i); + } + + EndResults(m_ostream); +} + +void XmlTestReporter::AddXmlElement(ostream& os, char const* encoding) +{ + os << "<?xml version=\"1.0\""; + + if (encoding != NULL) + os << " encoding=\"" << encoding << "\""; + + os << "?>"; +} + +void XmlTestReporter::BeginResults(std::ostream& os, int const totalTestCount, int const failedTestCount, + int const failureCount, float const secondsElapsed) +{ + os << "<unittest-results" + << " tests=\"" << totalTestCount << "\"" + << " failedtests=\"" << failedTestCount << "\"" + << " failures=\"" << failureCount << "\"" + << " time=\"" << secondsElapsed << "\"" + << ">"; +} + +void XmlTestReporter::EndResults(std::ostream& os) +{ + os << "</unittest-results>"; +} + +void XmlTestReporter::BeginTest(std::ostream& os, DeferredTestResult const& result) +{ + os << "<test" + << " suite=\"" << result.suiteName << "\"" + << " name=\"" << result.testName << "\"" + << " time=\"" << result.timeElapsed << "\""; +} + +void XmlTestReporter::EndTest(std::ostream& os, DeferredTestResult const& result) +{ + if (result.failed) + os << "</test>"; + else + os << "/>"; +} + +void XmlTestReporter::AddFailure(std::ostream& os, DeferredTestResult const& result) +{ + os << ">"; // close <test> element + + for (DeferredTestResult::FailureVec::const_iterator it = result.failures.begin(); + it != result.failures.end(); + ++it) + { + string const escapedMessage = XmlEscape(it->second); + string const message = BuildFailureMessage(result.failureFile, it->first, escapedMessage); + + os << "<failure" << " message=\"" << message << "\"" << "/>"; + } +} + +} diff --git a/libs/ode-0.16.1/tests/UnitTest++/src/XmlTestReporter.h b/libs/ode-0.16.1/tests/UnitTest++/src/XmlTestReporter.h new file mode 100644 index 0000000..884123b --- /dev/null +++ b/libs/ode-0.16.1/tests/UnitTest++/src/XmlTestReporter.h @@ -0,0 +1,34 @@ +#ifndef UNITTEST_XMLTESTREPORTER_H +#define UNITTEST_XMLTESTREPORTER_H + +#include "DeferredTestReporter.h" + +#include <iosfwd> + +namespace UnitTest +{ + +class XmlTestReporter : public DeferredTestReporter +{ +public: + explicit XmlTestReporter(std::ostream& ostream); + + virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed); + +private: + XmlTestReporter(XmlTestReporter const&); + XmlTestReporter& operator=(XmlTestReporter const&); + + void AddXmlElement(std::ostream& os, char const* encoding); + void BeginResults(std::ostream& os, int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed); + void EndResults(std::ostream& os); + void BeginTest(std::ostream& os, DeferredTestResult const& result); + void AddFailure(std::ostream& os, DeferredTestResult const& result); + void EndTest(std::ostream& os, DeferredTestResult const& result); + + std::ostream& m_ostream; +}; + +} + +#endif diff --git a/libs/ode-0.16.1/tests/collision.cpp b/libs/ode-0.16.1/tests/collision.cpp new file mode 100644 index 0000000..6eef4cf --- /dev/null +++ b/libs/ode-0.16.1/tests/collision.cpp @@ -0,0 +1,224 @@ +#include <UnitTest++.h> +#include <ode/ode.h> +#include "common.h" + +TEST(test_collision_trimesh_sphere_exact) +{ + /* + * This tests some extreme cases, where a sphere barely touches some triangles + * with zero depth. + */ + + #ifdef dTRIMESH_GIMPACT + /* + * Although GIMPACT is algorithmically able to handle this extreme case, + * the numerical approximation used for the square root produces inexact results. + */ + return; + #endif + + { + const int VertexCount = 4; + const int IndexCount = 2*3; + // this is a square on the XY plane + /* + 3 2 + +----+ + | /| + | / | + | / | + |/ | + +----+ + 0 1 + */ + float vertices[VertexCount * 3] = { + -1,-1,0, + 1,-1,0, + 1,1,0, + -1,1,0 + }; + dTriIndex indices[IndexCount] = { + 0,1,2, + 0,2,3 + }; + + dTriMeshDataID data = dGeomTriMeshDataCreate(); + dGeomTriMeshDataBuildSingle(data, + vertices, + 3 * sizeof(float), + VertexCount, + indices, + IndexCount, + 3 * sizeof(dTriIndex)); + dGeomID trimesh = dCreateTriMesh(0, data, 0, 0, 0); + const dReal radius = 4; + dGeomID sphere = dCreateSphere(0, radius); + dContactGeom cg[4]; + int nc; + dVector3 trinormal = { 0, 0, -1 }; + + // Test case: sphere touches the diagonal edge + dGeomSetPosition(sphere, 0,0,radius); + nc = dCollide(trimesh, sphere, 4, &cg[0], sizeof cg[0]); + CHECK_EQUAL(2, nc); + for (int i=0; i<nc; ++i) { + CHECK_EQUAL(0, cg[i].depth); + CHECK_ARRAY_EQUAL(trinormal, cg[i].normal, 3); + } + + // now translate both geoms + dGeomSetPosition(trimesh, 10,30,40); + dGeomSetPosition(sphere, 10,30,40+radius); + // check extreme case, again + nc = dCollide(trimesh, sphere, 4, &cg[0], sizeof cg[0]); + CHECK_EQUAL(2, nc); + for (int i=0; i<nc; ++i) { + CHECK_EQUAL(0, cg[i].depth); + CHECK_ARRAY_EQUAL(trinormal, cg[i].normal, 3); + } + + // and now, let's rotate the trimesh, 90 degrees on X + dMatrix3 rot = { 1, 0, 0, 0, + 0, 0, -1, 0, + 0, 1, 0, 0 }; + dGeomSetPosition(trimesh, 10,30,40); + dGeomSetRotation(trimesh, rot); + + dGeomSetPosition(sphere, 10,30-radius,40); + // check extreme case, again + nc = dCollide(trimesh, sphere, 4, &cg[0], sizeof cg[0]); + CHECK_EQUAL(2, nc); + dVector3 rtrinormal = { 0, 1, 0 }; + for (int i=0; i<nc; ++i) { + CHECK_EQUAL(0, cg[i].depth); + CHECK_ARRAY_EQUAL(rtrinormal, cg[i].normal, 3); + } + } +} + + + +TEST(test_collision_heightfield_ray_fail) +{ + /* + * This test demonstrated a bug in the AABB handling of the + * heightfield. + */ + { + // Create quick heightfield with dummy data + dHeightfieldDataID heightfieldData = dGeomHeightfieldDataCreate(); + unsigned char dataBuffer[16+1] = "1234567890123456"; + dGeomHeightfieldDataBuildByte(heightfieldData, dataBuffer, 0, 4, 4, 4, 4, 1, 0, 0, 0); + dGeomHeightfieldDataSetBounds(heightfieldData, '0', '9'); + dGeomID height = dCreateHeightfield(0, heightfieldData, 1); + + // Create ray outside bounds + dGeomID ray = dCreateRay(0, 20); + dGeomRaySet(ray, 5, 10, 1, 0, -1, 0); + dContact contactBuf[10]; + + // Make sure it does not crash! + dCollide(ray, height, 10, &(contactBuf[0].geom), sizeof(dContact)); + + dGeomDestroy(height); + dGeomDestroy(ray); + dGeomHeightfieldDataDestroy(heightfieldData); + } +} + +#include "../ode/demo/convex_prism.h" + +TEST(test_collision_ray_convex) +{ + /* + * Issue 55: ray vs convex collider does not consider the position of the convex geometry. + */ + { + dContact contact; + + // Create convex + dGeomID convex = dCreateConvex(0, + prism_planes, + prism_planecount, + prism_points, + prism_pointcount, + prism_polygons); + dGeomSetPosition(convex,0,0,0); + + // Create ray + dGeomID ray = dCreateRay(0, 20); + + dGeomRaySet(ray, 0, -10, 0, 0, 1, 0); + + int count = dCollide(ray, convex, 1, &contact.geom, sizeof(dContact)); + + CHECK_EQUAL(1,count); + CHECK_CLOSE(0.0,contact.geom.pos[0], dEpsilon); + CHECK_CLOSE(-1.0,contact.geom.pos[1], dEpsilon); + CHECK_CLOSE(0.0,contact.geom.pos[2], dEpsilon); + CHECK_CLOSE(0.0, contact.geom.normal[0], dEpsilon); + CHECK_CLOSE(-1.0, contact.geom.normal[1], dEpsilon); + CHECK_CLOSE(0.0, contact.geom.normal[2], dEpsilon); + CHECK_CLOSE(9.0, contact.geom.depth, dEpsilon); + + // Move Ray + dGeomRaySet(ray, 5, -10, 0, 0, 1, 0); + + count = dCollide(ray, convex, 1, &contact.geom, sizeof(dContact)); + + CHECK_EQUAL(1,count); + CHECK_CLOSE(5.0, contact.geom.pos[0], dEpsilon); + CHECK_CLOSE(-1.0, contact.geom.pos[1], dEpsilon); + CHECK_CLOSE(0.0, contact.geom.pos[2], dEpsilon); + CHECK_CLOSE(0.0, contact.geom.normal[0], dEpsilon); + CHECK_CLOSE(-1.0, contact.geom.normal[1], dEpsilon); + CHECK_CLOSE(0.0, contact.geom.normal[2], dEpsilon); + CHECK_CLOSE(9.0, contact.geom.depth, dEpsilon); + + // Rotate Convex + dMatrix3 rotate90z = + { + 0,-1,0,0, + 1,0,0,0, + 0,0,1,0 + }; + dGeomSetRotation(convex, rotate90z); + + count = dCollide(ray, convex, 1, &contact.geom, sizeof(dContact)); + + CHECK_EQUAL(0,count); + + // Move Ray + dGeomRaySet(ray, 10, 0, 0, -1, 0, 0); + count = dCollide(ray, convex, 1, &contact.geom, sizeof(dContact)); + + CHECK_EQUAL(1,count); + CHECK_CLOSE(1.0, contact.geom.pos[0], dEpsilon); + CHECK_CLOSE(0.0, contact.geom.pos[1], dEpsilon); + CHECK_CLOSE(0.0, contact.geom.pos[2], dEpsilon); + CHECK_CLOSE(1.0, contact.geom.normal[0], dEpsilon); + CHECK_CLOSE(0.0, contact.geom.normal[1], dEpsilon); + CHECK_CLOSE(0.0, contact.geom.normal[2], dEpsilon); + CHECK_CLOSE(9.0,contact.geom.depth, dEpsilon); + + + // Move Ray + dGeomRaySet(ray, 10, 1000, 1000, -1, 0, 0); + // Move Geom + dGeomSetPosition(convex, 0, 1000, 1000); + + count = dCollide(ray, convex, 1, &contact.geom, sizeof(dContact)); + + CHECK_EQUAL(1, count); + CHECK_CLOSE(1.0, contact.geom.pos[0], dEpsilon); + CHECK_CLOSE(1000.0, contact.geom.pos[1], dEpsilon); + CHECK_CLOSE(1000.0, contact.geom.pos[2], dEpsilon); + CHECK_CLOSE(1.0, contact.geom.normal[0], dEpsilon); + CHECK_CLOSE(0.0, contact.geom.normal[1], dEpsilon); + CHECK_CLOSE(0.0, contact.geom.normal[2], dEpsilon); + CHECK_CLOSE(9.0, contact.geom.depth, dEpsilon); + + dGeomDestroy(convex); + dGeomDestroy(ray); + } +} diff --git a/libs/ode-0.16.1/tests/friction.cpp b/libs/ode-0.16.1/tests/friction.cpp new file mode 100644 index 0000000..c082e85 --- /dev/null +++ b/libs/ode-0.16.1/tests/friction.cpp @@ -0,0 +1,176 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ +//234567890123456789012345678901234567890123456789012345678901234567890123456789 +// 1 2 3 4 5 6 7 + +//////////////////////////////////////////////////////////////////////////////// +// This file create unit test for some of the functions found in: +// ode/src/joint.cpp +// +// +//////////////////////////////////////////////////////////////////////////////// +#include <algorithm> +#include <UnitTest++.h> +#include <ode/ode.h> +#include "../ode/src/config.h" +#include "../ode/src/joints/joints.h" + + +/* + * Tests for contact friction + */ + +SUITE(JointContact) +{ + struct ContactSetup + { + dWorldID world; + dBodyID body1; + dBodyID body2; + dJointID joint; + + ContactSetup() + { + world = dWorldCreate(); + body1 = dBodyCreate(world); + body2 = dBodyCreate(world); + + dBodySetPosition(body1, -1, 0, 0); + dBodySetPosition(body2, 1, 0, 0); + } + + ~ContactSetup() + { + dBodyDestroy(body1); + dBodyDestroy(body2); + dWorldDestroy(world); + } + }; + + TEST_FIXTURE(ContactSetup, + test_ZeroMu) + { + dxJoint::Info1 info1; + dReal dummy_J[3][16] = {{0}}; + int dummy_findex[3]; + + dReal info2_fps = 100; + dReal info2_erp = 0; + dReal *J1 = dummy_J[0]; + dReal *J2 = dummy_J[0] + 8; + dReal *rhscfm = dummy_J[0] + 6; + dReal *lohi = dummy_J[0] + 14; + unsigned rowskip = 16; + int *findex = dummy_findex; + +#define ZERO_ALL do { \ + memset(dummy_J, 0, sizeof dummy_J); \ + std::fill(dummy_findex, dummy_findex+3, -1); \ + } \ + while (0) + + dContact contact; + contact.surface.mode = dContactMu2 | dContactFDir1 | dContactApprox1; + + contact.geom.pos[0] = 0; + contact.geom.pos[1] = 0; + contact.geom.pos[2] = 0; + + // normal points into body1 + contact.geom.normal[0] = -1; + contact.geom.normal[1] = 0; + contact.geom.normal[2] = 0; + + contact.geom.depth = 0; + + contact.geom.g1 = 0; + contact.geom.g2 = 0; + + // we ask for fdir1 = +Y, so fdir2 = normal x fdir1 = -Z + contact.fdir1[0] = 0; + contact.fdir1[1] = 1; + contact.fdir1[2] = 0; + + /* + * First, test with mu = 0, mu2 = 1 + * Because there is no friction on the first direction (+Y) the body + * is allowed to translate in the Y axis and rotate around the Z axis. + * + * That is, the only constraint will be for the second dir (-Z): + * so J[1] = [ 0 0 -1 0 1 0 0 0 1 0 1 0 ] + */ + contact.surface.mu = 0; + contact.surface.mu2 = 1; + joint = dJointCreateContact(world, 0, &contact); + dJointAttach(joint, body1, body2); + joint->getInfo1(&info1); + CHECK_EQUAL(2, (int)info1.m); + ZERO_ALL; + joint->getInfo2(info2_fps, info2_erp, rowskip, J1, J2, + rowskip, rhscfm, lohi, findex); + CHECK_CLOSE(0, dummy_J[1][0], 1e-6); + CHECK_CLOSE(0, dummy_J[1][1], 1e-6); + CHECK_CLOSE(-1, dummy_J[1][2], 1e-6); + CHECK_CLOSE(0, dummy_J[1][3], 1e-6); + CHECK_CLOSE(1, dummy_J[1][4], 1e-6); + CHECK_CLOSE(0, dummy_J[1][5], 1e-6); + CHECK_CLOSE(0, dummy_J[1][8], 1e-6); + CHECK_CLOSE(0, dummy_J[1][9], 1e-6); + CHECK_CLOSE(1, dummy_J[1][10], 1e-6); + CHECK_CLOSE(0, dummy_J[1][11], 1e-6); + CHECK_CLOSE(1, dummy_J[1][12], 1e-6); + CHECK_CLOSE(0, dummy_J[1][13], 1e-6); + CHECK_EQUAL(0, dummy_findex[1]); // because of dContactApprox1 + dJointDestroy(joint); + + + /* + * Now try with no frictino in the second direction. The Jacobian should look like: + * J[1] = [ 0 1 0 0 0 1 0 -1 0 0 0 1 ] + */ + // try again, with zero mu2 + contact.surface.mu = 1; + contact.surface.mu2 = 0; + joint = dJointCreateContact(world, 0, &contact); + dJointAttach(joint, body1, body2); + joint->getInfo1(&info1); + CHECK_EQUAL(2, (int)info1.m); + ZERO_ALL; + joint->getInfo2(info2_fps, info2_erp, rowskip, J1, J2, + rowskip, rhscfm, lohi, findex); + CHECK_CLOSE(0, dummy_J[1][0], 1e-6); + CHECK_CLOSE(1, dummy_J[1][1], 1e-6); + CHECK_CLOSE(0, dummy_J[1][2], 1e-6); + CHECK_CLOSE(0, dummy_J[1][3], 1e-6); + CHECK_CLOSE(0, dummy_J[1][4], 1e-6); + CHECK_CLOSE(1, dummy_J[1][5], 1e-6); + CHECK_CLOSE(0, dummy_J[1][8], 1e-6); + CHECK_CLOSE(-1, dummy_J[1][9], 1e-6); + CHECK_CLOSE(0, dummy_J[1][10], 1e-6); + CHECK_CLOSE(0, dummy_J[1][11], 1e-6); + CHECK_CLOSE(0, dummy_J[1][12], 1e-6); + CHECK_CLOSE(1, dummy_J[1][13], 1e-6); + CHECK_EQUAL(0, dummy_findex[1]); // because of dContactApprox1 + dJointDestroy(joint); + } + +} diff --git a/libs/ode-0.16.1/tests/joint.cpp b/libs/ode-0.16.1/tests/joint.cpp new file mode 100644 index 0000000..465fb1b --- /dev/null +++ b/libs/ode-0.16.1/tests/joint.cpp @@ -0,0 +1,3054 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ +//234567890123456789012345678901234567890123456789012345678901234567890123456789 +// 1 2 3 4 5 6 7 + +//////////////////////////////////////////////////////////////////////////////// +// This file create unit test for some of the functions found in: +// ode/src/joint.cpp +// +// +//////////////////////////////////////////////////////////////////////////////// +#include <UnitTest++.h> +#include <ode/ode.h> +#include "../ode/src/config.h" +#include "../ode/src/joints/joints.h" + + +//////////////////////////////////////////////////////////////////////////////// +// Testing the Hinge2 Joint +// +SUITE(JointHinge2) +{ + + struct Hinge2GetInfo1_Fixture_1 + { + Hinge2GetInfo1_Fixture_1() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate(wId); + dBodySetPosition(bId1, 0, -1, 0); + + bId2 = dBodyCreate(wId); + dBodySetPosition(bId2, 0, 1, 0); + + + jId = dJointCreateHinge2(wId, 0); + joint = (dxJointHinge2*)jId; + + dJointAttach(jId, bId1, bId2); + + dJointSetHinge2Anchor (jId, REAL(0.0), REAL(0.0), REAL(0.0)); + } + + ~Hinge2GetInfo1_Fixture_1() + { + dWorldDestroy(wId); + } + + dJointID jId; + dxJointHinge2* joint; + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + dxJoint::Info1 info; + }; + + TEST_FIXTURE(Hinge2GetInfo1_Fixture_1, test_hinge2GetInfo1) + { + /* + // ^Y + // |---| HiStop + // | | ^Y / + // |B_2| | / + // |---| | / + // | ----- | / + // Z <-- * Z<--|B_2|--* + // / | \ ----- | \ + // /|---|\ |---| \ + // / | | \ | | \ + // / |B_1| \ |B_1| \ + // / |---| \ |---| \ + //LoStop HiStop LoStop + // + // + // + // + */ + dMatrix3 R; + + dJointSetHinge2Param(jId, dParamLoStop, -M_PI/4.0); + dJointSetHinge2Param(jId, dParamHiStop, M_PI/4.0); + + dxJoint::Info1 info; + + + dxJointHinge2* joint = (dxJointHinge2*)jId; + + // Original position inside the limits + joint->getInfo1(&info); + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(4, info.m); + + // Move the body outside the Lo limits + dBodySetPosition (bId2, 0, 0, 1); + dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0); + dBodySetRotation (bId2, R); + joint->getInfo1(&info); + CHECK_EQUAL(1, joint->limot1.limit); + CHECK_EQUAL(5, info.m); + + + // Return to original position + // Keep the limits + dBodySetPosition (bId2, 0, 1, 0); + dRFromAxisAndAngle (R, 1, REAL(0.0), REAL(0.0), REAL(0.0)); + dBodySetRotation (bId2, R); + joint->getInfo1(&info); + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(4, info.m); + + + // Move the body outside the Lo limits + dBodySetPosition (bId2, 0, 0, 1); + dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0); + dBodySetRotation (bId2, R); + joint->getInfo1(&info); + CHECK_EQUAL(1, joint->limot1.limit); + CHECK_EQUAL(5, info.m); + + + + // Return to original position + // and remove the limits + dBodySetPosition (bId2, 0, 1, 0); + dRFromAxisAndAngle (R, 1, REAL(0.0), REAL(0.0), REAL(0.0)); + dBodySetRotation (bId2, R); + dJointSetHinge2Param(jId, dParamLoStop, -2*M_PI); + dJointSetHinge2Param(jId, dParamHiStop, 2*M_PI); + joint->getInfo1(&info); + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(4, info.m); + + + // Set the limits + // Move pass the Hi limits + dJointSetHinge2Param(jId, dParamLoStop, -M_PI/4.0); + dJointSetHinge2Param(jId, dParamHiStop, M_PI/4.0); + dBodySetPosition (bId2, 0, 0, 1); + dRFromAxisAndAngle (R, 1, 0, 0, -M_PI/2.0); + dBodySetRotation (bId2, R); + joint->getInfo1(&info); + CHECK_EQUAL(2, joint->limot1.limit); + CHECK_EQUAL(5, info.m); + + + // Return to original position + // Keep the limits + dBodySetPosition (bId2, 0, 1, 0); + dRFromAxisAndAngle (R, 1, REAL(0.0), REAL(0.0), REAL(0.0)); + dBodySetRotation (bId2, R); + joint->getInfo1(&info); + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(4, info.m); + + + // Move the pass the Hi limit + dBodySetPosition (bId2, 0, 0, 1); + dRFromAxisAndAngle (R, 1, 0, 0, -M_PI/2.0); + dBodySetRotation (bId2, R); + joint->getInfo1(&info); + CHECK_EQUAL(2, joint->limot1.limit); + CHECK_EQUAL(5, info.m); + + + // Return to original position + // and remove the limits + dBodySetPosition (bId2, 0, 1, 0); + dRFromAxisAndAngle (R, 1, 0, 0, -M_PI/2.0); + dBodySetRotation (bId2, R); + dJointSetHinge2Param(jId, dParamLoStop, -2*M_PI); + dJointSetHinge2Param(jId, dParamHiStop, 2*M_PI); + joint->getInfo1(&info); + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(4, info.m); + + + /// Motorize the first joint angle + dJointSetHinge2Param(jId, dParamFMax, 2); + joint->getInfo1(&info); + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(5, info.m); + + + /// Motorize the second joint angle + dJointSetHinge2Param(jId, dParamFMax2, 2); + joint->getInfo1(&info); + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(6, info.m); + + /// Unmotorize the first joint angle + dJointSetHinge2Param(jId, dParamFMax, 0); + joint->getInfo1(&info); + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(5, info.m); + } +} // End of SUITE(JointHinge2) + + +//////////////////////////////////////////////////////////////////////////////// +// Testing the Universal Joint +// +SUITE(JointUniversal) +{ + + struct UniversalGetInfo1_Fixture_1 + { + UniversalGetInfo1_Fixture_1() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate(wId); + dBodySetPosition(bId1, 0, -1, 0); + + bId2 = dBodyCreate(wId); + dBodySetPosition(bId2, 0, 1, 0); + + + jId = dJointCreateUniversal(wId, 0); + joint = (dxJointUniversal*)jId; + + dJointAttach(jId, bId1, bId2); + + dJointSetUniversalAnchor (jId, REAL(0.0), REAL(0.0), REAL(0.0)); + } + + ~UniversalGetInfo1_Fixture_1() + { + dWorldDestroy(wId); + } + + dJointID jId; + dxJointUniversal* joint; + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + dxJoint::Info1 info; + }; + + TEST_FIXTURE(UniversalGetInfo1_Fixture_1, test_hinge2GetInfo1_RotAroundX) + { + /* + // ^Y + // |---| HiStop + // | | ^Y / + // |B_2| | / + // |---| | / + // | ----- | / + // Z <-- * Z<--|B_2|--* + // / | \ ----- | \ + // /|---|\ |---| \ + // / | | \ | | \ + // / |B_1| \ |B_1| \ + // / |---| \ |---| \ + //LoStop HiStop LoStop + // + // + // + // + */ + dMatrix3 R; + + dJointSetUniversalParam(jId, dParamLoStop, -M_PI/4.0); + dJointSetUniversalParam(jId, dParamHiStop, M_PI/4.0); + dJointSetUniversalParam(jId, dParamLoStop2, -M_PI/4.0); + dJointSetUniversalParam(jId, dParamHiStop2, M_PI/4.0); + + dxJoint::Info1 info; + + + dxJointUniversal* joint = (dxJointUniversal*)jId; + + // Original position inside the limits + joint->getInfo1(&info); + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(4, info.m); + + // Move the body outside the Lo limits + dBodySetPosition (bId2, 0, 0, 1); + dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0); + dBodySetRotation (bId2, R); + joint->getInfo1(&info); + CHECK_EQUAL(1, joint->limot1.limit); + CHECK_EQUAL(5, info.m); + + + // Return to original position + // Keep the limits + dBodySetPosition (bId2, 0, 1, 0); + dRFromAxisAndAngle (R, 1, REAL(0.0), REAL(0.0), REAL(0.0)); + dBodySetRotation (bId2, R); + joint->getInfo1(&info); + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(4, info.m); + + + // Move the body outside the Lo limits + dBodySetPosition (bId2, 0, 0, 1); + dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0); + dBodySetRotation (bId2, R); + joint->getInfo1(&info); + CHECK_EQUAL(1, joint->limot1.limit); + CHECK_EQUAL(5, info.m); + + + + // Return to original position + // and remove the limits + dBodySetPosition (bId2, 0, 1, 0); + dRFromAxisAndAngle (R, 1, REAL(0.0), REAL(0.0), REAL(0.0)); + dBodySetRotation (bId2, R); + dJointSetUniversalParam(jId, dParamLoStop, -2*M_PI); + dJointSetUniversalParam(jId, dParamHiStop, 2*M_PI); + joint->getInfo1(&info); + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(4, info.m); + + + // Set the limits + // Move pass the Hi limits + dJointSetUniversalParam(jId, dParamLoStop, -M_PI/4.0); + dJointSetUniversalParam(jId, dParamHiStop, M_PI/4.0); + dBodySetPosition (bId2, 0, 0, 1); + dRFromAxisAndAngle (R, 1, 0, 0, -M_PI/2.0); + dBodySetRotation (bId2, R); + joint->getInfo1(&info); + CHECK_EQUAL(2, joint->limot1.limit); + CHECK_EQUAL(5, info.m); + + + // Return to original position + // Keep the limits + dBodySetPosition (bId2, 0, 1, 0); + dRFromAxisAndAngle (R, 1, REAL(0.0), REAL(0.0), REAL(0.0)); + dBodySetRotation (bId2, R); + joint->getInfo1(&info); + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(4, info.m); + + + // Move the pass the Hi limit + dBodySetPosition (bId2, 0, 0, 1); + dRFromAxisAndAngle (R, 1, 0, 0, -M_PI/2.0); + dBodySetRotation (bId2, R); + joint->getInfo1(&info); + CHECK_EQUAL(2, joint->limot1.limit); + CHECK_EQUAL(5, info.m); + + + // Return to original position + // and remove the limits + dBodySetPosition (bId2, 0, 1, 0); + dRFromAxisAndAngle (R, 1, 0, 0, -M_PI/2.0); + dBodySetRotation (bId2, R); + dJointSetUniversalParam(jId, dParamLoStop, -2*M_PI); + dJointSetUniversalParam(jId, dParamHiStop, 2*M_PI); + joint->getInfo1(&info); + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(4, info.m); + + + /// Motorize the first joint angle + dJointSetUniversalParam(jId, dParamFMax, 2); + joint->getInfo1(&info); + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(5, info.m); + + + /// Motorize the second joint angle + dJointSetUniversalParam(jId, dParamFMax2, 2); + joint->getInfo1(&info); + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(6, info.m); + + /// Unmotorize the first joint angle + dJointSetUniversalParam(jId, dParamFMax, 0); + joint->getInfo1(&info); + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(5, info.m); + } + + TEST_FIXTURE(UniversalGetInfo1_Fixture_1, test_hinge2GetInfo1_RotAroundY) + { + /* + // ^Y + // |---| HiStop + // | | ^Y / + // |B_2| | / + // |---| | / + // | ----- | / + // Z <-- * Z<--|B_2|--* + // / | \ ----- | \ + // /|---|\ |---| \ + // / | | \ | | \ + // / |B_1| \ |B_1| \ + // / |---| \ |---| \ + //LoStop HiStop LoStop + // + // + // + // + */ + dMatrix3 R; + + dJointSetUniversalParam(jId, dParamLoStop, -M_PI/4.0); + dJointSetUniversalParam(jId, dParamHiStop, M_PI/4.0); + dJointSetUniversalParam(jId, dParamLoStop2, -M_PI/4.0); + dJointSetUniversalParam(jId, dParamHiStop2, M_PI/4.0); + + dxJoint::Info1 info; + + + dxJointUniversal* joint = (dxJointUniversal*)jId; + + // Original position inside the limits + joint->getInfo1(&info); + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(4, info.m); + + // Move the body outside the Lo limits + dBodySetPosition (bId2, 0, 0, 1); + dRFromAxisAndAngle (R, 0, 1, 0, M_PI/2.0); + dBodySetRotation (bId2, R); + joint->getInfo1(&info); + CHECK_EQUAL(1, joint->limot2.limit); + CHECK_EQUAL(5, info.m); + + + // Return to original position + // Keep the limits + dBodySetPosition (bId2, 0, 1, 0); + dRFromAxisAndAngle (R, 0, 1, 0, 0); + dBodySetRotation (bId2, R); + joint->getInfo1(&info); + CHECK_EQUAL(0, joint->limot2.limit); + CHECK_EQUAL(4, info.m); + + + // Move the body outside the Lo limits + dBodySetPosition (bId2, 0, 0, 1); + dRFromAxisAndAngle (R, 0, 1, 0, M_PI/2.0); + dBodySetRotation (bId2, R); + joint->getInfo1(&info); + CHECK_EQUAL(1, joint->limot2.limit); + CHECK_EQUAL(5, info.m); + + + + // Return to original position + // and remove the limits + dBodySetPosition (bId2, 0, 1, 0); + dRFromAxisAndAngle (R, 0, 1, 0, 0); + dBodySetRotation (bId2, R); + dJointSetUniversalParam(jId, dParamLoStop2, -2*M_PI); + dJointSetUniversalParam(jId, dParamHiStop2, 2*M_PI); + joint->getInfo1(&info); + CHECK_EQUAL(0, joint->limot2.limit); + CHECK_EQUAL(4, info.m); + + + // Set the limits + // Move pass the Hi limits + dJointSetUniversalParam(jId, dParamLoStop2, -M_PI/4.0); + dJointSetUniversalParam(jId, dParamHiStop2, M_PI/4.0); + dBodySetPosition (bId2, 0, 0, 1); + dRFromAxisAndAngle (R, 0, 1, 0, -M_PI/2.0); + dBodySetRotation (bId2, R); + joint->getInfo1(&info); + CHECK_EQUAL(2, joint->limot2.limit); + CHECK_EQUAL(5, info.m); + + + // Return to original position + // Keep the limits + dBodySetPosition (bId2, 0, 1, 0); + dRFromAxisAndAngle (R, 0, 1, 0, 0); + dBodySetRotation (bId2, R); + joint->getInfo1(&info); + CHECK_EQUAL(0, joint->limot2.limit); + CHECK_EQUAL(4, info.m); + + + // Move the pass the Hi limit + dBodySetPosition (bId2, 0, 0, 1); + dRFromAxisAndAngle (R, 0, 1, 0, -M_PI/2.0); + dBodySetRotation (bId2, R); + joint->getInfo1(&info); + CHECK_EQUAL(2, joint->limot2.limit); + CHECK_EQUAL(5, info.m); + + + // Return to original position + // and remove the limits + dBodySetPosition (bId2, 0, 1, 0); + dRFromAxisAndAngle (R, 0, 1, 0, -M_PI/2.0); + dBodySetRotation (bId2, R); + dJointSetUniversalParam(jId, dParamLoStop2, -2*M_PI); + dJointSetUniversalParam(jId, dParamHiStop2, 2*M_PI); + joint->getInfo1(&info); + CHECK_EQUAL(0, joint->limot2.limit); + CHECK_EQUAL(4, info.m); + + + /// Motorize the first joint angle + dJointSetUniversalParam(jId, dParamFMax, 2); + joint->getInfo1(&info); + CHECK_EQUAL(0, joint->limot2.limit); + CHECK_EQUAL(5, info.m); + + + /// Motorize the second joint angle + dJointSetUniversalParam(jId, dParamFMax2, 2); + joint->getInfo1(&info); + CHECK_EQUAL(0, joint->limot2.limit); + CHECK_EQUAL(6, info.m); + + /// Unmotorize the first joint angle + dJointSetUniversalParam(jId, dParamFMax, 0); + joint->getInfo1(&info); + CHECK_EQUAL(0, joint->limot2.limit); + CHECK_EQUAL(5, info.m); + } +} // End of SUITE(JointUniversal) + + + +// // // +// Testing the PR Joint +// +SUITE(JointPR) +{ + struct PRGetInfo1_Fixture_1 + { + PRGetInfo1_Fixture_1() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate(wId); + dBodySetPosition(bId1, 0, -1, 0); + + bId2 = dBodyCreate(wId); + dBodySetPosition(bId2, 0, 1, 0); + + + jId = dJointCreatePR(wId, 0); + joint = (dxJointPR*)jId; + + dJointAttach(jId, bId1, bId2); + + dJointSetPRAnchor (jId, REAL(0.0), REAL(0.0), REAL(0.0)); + } + + ~PRGetInfo1_Fixture_1() + { + dWorldDestroy(wId); + } + + dJointID jId; + dxJointPR* joint; + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + dxJoint::Info1 info; + }; + + +//////////////////////////////////////////////////////////////////////////////// +// Test when there is no limits. +// The 2 bodies stay aligned. +// +// Default value for axisR1 = 1,0,0 +// Default value for axisP1 = 0,1,0 +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PRGetInfo1_Fixture_1, test1_PRGetInfo1_) + { + dJointSetPRParam(jId, dParamLoStop, -dInfinity); + dJointSetPRParam(jId, dParamHiStop, dInfinity); + dJointSetPRParam(jId, dParamLoStop2, -M_PI); + dJointSetPRParam(jId, dParamHiStop2, M_PI); + + joint->getInfo1(&info); + + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(0, joint->limotR.limit); + CHECK_EQUAL(4, info.m); + } + + +//////////////////////////////////////////////////////////////////////////////// +// Test when there is limits for the prismatic at -10 and 10 +// The Body 2 is moved -100 unit then at 100 +// +// Default value for axisR1 = 1,0,0 +// Default value for axisP1 = 0,1,0 +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PRGetInfo1_Fixture_1, test2_PRGetInfo1) + { + dJointSetPRParam(jId, dParamLoStop, -10); + dJointSetPRParam(jId, dParamHiStop, 10); + dJointSetPRParam(jId, dParamLoStop2, -M_PI); + dJointSetPRParam(jId, dParamHiStop2, M_PI); + + + dBodySetPosition(bId2, 0, -100, 0); + + joint->getInfo1(&info); + + CHECK_EQUAL(2, joint->limotP.limit); + CHECK_EQUAL(0, joint->limotR.limit); + CHECK_EQUAL(5, info.m); + + + dBodySetPosition(bId2, 0, 100, 0); + + joint->getInfo1(&info); + + CHECK_EQUAL(1, joint->limotP.limit); + CHECK_EQUAL(0, joint->limotR.limit); + CHECK_EQUAL(5, info.m); + + // Reset Position and test + dBodySetPosition(bId2, 0, 1, 0); + dMatrix3 R_final = { 1,0,0,0, + 0,1,0,0, + 0,0,1,0 + }; + dBodySetRotation (bId2, R_final); + + joint->getInfo1(&info); + + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(0, joint->limotR.limit); + CHECK_EQUAL(4, info.m); + } + +//////////////////////////////////////////////////////////////////////////////// +// Test when there is limits for the prismatic at -10 and 10 +// and for the rotoide at -45deg and 45deg. +// The Body 2 is only rotated by 90deg since the rotoide limits are not +// used this should not change the limit value. +// +// Default value for axisR1 = 1,0,0 +// Default value for axisP1 = 0,1,0 +// +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PRGetInfo1_Fixture_1, test3_PRGetInfo1) + { + dJointSetPRParam(jId, dParamLoStop, -10); + dJointSetPRParam(jId, dParamHiStop, 10); + dJointSetPRParam(jId, dParamLoStop2, -M_PI/4.0); + dJointSetPRParam(jId, dParamHiStop2, M_PI/4.0); + + + dMatrix3 R; + dBodySetPosition (bId2, 0, 0, 1); + dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0); + dBodySetRotation (bId2, R); + + joint->getInfo1(&info); + + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(1, joint->limotR.limit); + CHECK_EQUAL(5, info.m); + + // Reset Position and test + dBodySetPosition(bId2, 0, 1, 0); + dMatrix3 R_final = { 1,0,0,0, + 0,1,0,0, + 0,0,1,0 + }; + dBodySetRotation (bId2, R_final); + + joint->getInfo1(&info); + + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(0, joint->limotR.limit); + CHECK_EQUAL(4, info.m); + } + + +// The joint is now powered. (i.e. info->fmax > 0 + struct PRGetInfo1_Fixture_2 + { + PRGetInfo1_Fixture_2() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate(wId); + dBodySetPosition(bId1, 0, -1, 0); + + bId2 = dBodyCreate(wId); + dBodySetPosition(bId2, 0, 1, 0); + + + jId = dJointCreatePR(wId, 0); + joint = (dxJointPR*)jId; + + dJointAttach(jId, bId1, bId2); + dJointSetPRAnchor (jId, REAL(0.0), REAL(0.0), REAL(0.0)); + + joint->limotP.fmax = 1; + } + + ~PRGetInfo1_Fixture_2() + { + dWorldDestroy(wId); + } + + dJointID jId; + dxJointPR* joint; + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + dxJoint::Info1 info; + }; + + + +//////////////////////////////////////////////////////////////////////////////// +// Test when there is no limits. +// The 2 bodies stay align. +// +// Default value for axisR1 = 1,0,0 +// Default value for axisP1 = 0,1,0 +// +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PRGetInfo1_Fixture_2, test1_PRGetInfo1) + { + dJointSetPRParam(jId, dParamLoStop, -dInfinity); + dJointSetPRParam(jId, dParamHiStop, dInfinity); + dJointSetPRParam(jId, dParamLoStop2, -M_PI); + dJointSetPRParam(jId, dParamHiStop2, M_PI); + + joint->getInfo1(&info); + + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(0, joint->limotR.limit); + CHECK_EQUAL(5, info.m); + } + + +//////////////////////////////////////////////////////////////////////////////// +// Test when there is limits for the prismatic at -10 and 10 +// The Body 2 is moved -100 unit then at 100 +// +// Default value for axisR1 = 1,0,0 +// Default value for axisP1 = 0,1,0 +// +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PRGetInfo1_Fixture_2, test2_PRGetInfo1) + { + + dJointSetPRParam(jId, dParamLoStop, -10); + dJointSetPRParam(jId, dParamHiStop, 10); + dJointSetPRParam(jId, dParamLoStop2, -M_PI); + dJointSetPRParam(jId, dParamHiStop2, M_PI); + + + dBodySetPosition(bId2, 0, -100, 0); + + joint->getInfo1(&info); + + CHECK_EQUAL(2, joint->limotP.limit); + CHECK_EQUAL(0, joint->limotR.limit); + CHECK_EQUAL(5, info.m); + + + dBodySetPosition(bId2, 0, 100, 0); + + joint->getInfo1(&info); + + CHECK_EQUAL(1, joint->limotP.limit); + CHECK_EQUAL(0, joint->limotR.limit); + CHECK_EQUAL(5, info.m); + + // Reset Position and test + dBodySetPosition(bId2, 0, 1, 0); + dMatrix3 R_final = { 1,0,0,0, + 0,1,0,0, + 0,0,1,0 + }; + dBodySetRotation (bId2, R_final); + + joint->getInfo1(&info); + + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(0, joint->limotR.limit); + CHECK_EQUAL(5, info.m); + } + +//////////////////////////////////////////////////////////////////////////////// +// Test when there is limits for the prismatic at -10 and 10 +// and for the rotoide at -45deg and 45deg +// The Body 2 is only rotated by 90deg since the rotoide limits are not +// used this should not change the limit value. +// +// Default value for axisR1 = 1,0,0 +// Default value for axisP1 = 0,1,0 +// +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PRGetInfo1_Fixture_2, test3_PRGetInfo1) + { + + dJointSetPRParam(jId, dParamLoStop, -10); + dJointSetPRParam(jId, dParamHiStop, 10); + dJointSetPRParam(jId, dParamLoStop2, -M_PI/4.0); + dJointSetPRParam(jId, dParamHiStop2, M_PI/4.0); + + + dMatrix3 R; + dBodySetPosition (bId2, 0, 0, 100); + dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0); + dBodySetRotation (bId2, R); + + joint->getInfo1(&info); + + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(1, joint->limotR.limit); + CHECK_EQUAL(6, info.m); + + // Reset Position and test + dBodySetPosition(bId2, 0, 1, 0); + dMatrix3 R_final = { 1,0,0,0, + 0,1,0,0, + 0,0,1,0 + }; + dBodySetRotation (bId2, R_final); + + joint->getInfo1(&info); + + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(0, joint->limotR.limit); + CHECK_EQUAL(5, info.m); + } + + +//////////////////////////////////////////////////////////////////////////////// +// Test the setting and getting of parameters +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PRGetInfo1_Fixture_1, test_SetPRParam) + { + dJointSetPRParam(jId, dParamHiStop, REAL(5.0) ); + CHECK_EQUAL(REAL(5.0), joint->limotP.histop); + + dJointSetPRParam(jId, dParamVel, REAL(7.0) ); + CHECK_EQUAL(REAL(7.0), joint->limotP.vel); + +#ifdef dParamFudgeFactor1 + dJointSetPRParam(jId, dParamFudgeFactor1, REAL(5.5) ); + CHECK_EQUAL(REAL(5.5), joint->limotP.dParamFudgeFactor); +#endif + + dJointSetPRParam(jId, dParamCFM2, REAL(9.0) ); + CHECK_EQUAL(REAL(9.0), joint->limotR.normal_cfm); + + dJointSetPRParam(jId, dParamStopERP2, REAL(11.0) ); + CHECK_EQUAL(REAL(11.0), joint->limotR.stop_erp); + } + + TEST_FIXTURE(PRGetInfo1_Fixture_1, test_GetPRParam) + { + joint->limotP.histop = REAL(5.0); + CHECK_EQUAL(joint->limotP.histop, + dJointGetPRParam(jId, dParamHiStop) ); + + joint->limotP.vel = REAL(7.0); + + CHECK_EQUAL(joint->limotP.vel, + dJointGetPRParam(jId, dParamVel) ); + +#ifdef dParamFudgeFactor1 + joint->limotP.dParamFudgeFactor = REAL(5.5); + + CHECK_EQUAL(joint->limotP.dParamFudgeFactor, + dJointGetPRParam(jId, dParamFudgeFactor1) ); +#endif + + joint->limotR.normal_cfm = REAL(9.0); + CHECK_EQUAL(joint->limotR.normal_cfm, + dJointGetPRParam(jId, dParamCFM2) ); + + joint->limotR.stop_erp = REAL(11.0); + CHECK_EQUAL(joint->limotR.stop_erp, + dJointGetPRParam(jId, dParamStopERP2) ); + } + + + +//////////////////////////////////////////////////////////////////////////////// +// Fixture for testing the PositionRate +// +// Default Position +// ^Z +// | +// | +// +// Body2 R Body1 +// +---------+ _ - +-----------+ +// | |--------(_)----|-----| | ----->Y +// +---------+ - +-----------+ +// +// N.B. X is comming out of the page +//////////////////////////////////////////////////////////////////////////////// + struct PRGetInfo1_Fixture_3 + { + PRGetInfo1_Fixture_3() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate(wId); + dBodySetPosition(bId1, 0, 1, 0); + + bId2 = dBodyCreate(wId); + dBodySetPosition(bId2, 0, -1, 0); + + + jId = dJointCreatePR(wId, 0); + joint = (dxJointPR*)jId; + + dJointAttach(jId, bId1, bId2); + dJointSetPRAnchor (jId, REAL(0.0), REAL(0.0), REAL(0.0)); + + dBodySetLinearVel (bId1, REAL(0.0), REAL(0.0), REAL(0.0)); + dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0)); + + dBodySetLinearVel (bId2, REAL(0.0), REAL(0.0), REAL(0.0)); + dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0)); + + } + + ~PRGetInfo1_Fixture_3() + { + dWorldDestroy(wId); + } + + dJointID jId; + dxJointPR* joint; + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + dxJoint::Info1 info; + }; + +//////////////////////////////////////////////////////////////////////////////// +// Position Body1 [0, 1, 0] +// Position Body2 [0, -1, 0] +// Axis of the prismatic [0, 1, 0] +// Axis of the rotoide [1, 0, ]0 +// +// Move at the same speed +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PRGetInfo1_Fixture_3, test_GetPRPositionRate_1) + { + // They move with the same linear speed + // Angular speed == 0 + dBodySetLinearVel(bId1, REAL(0.0), REAL(3.33), REAL(0.0)); + dBodySetLinearVel(bId2, REAL(0.0), REAL(3.33), REAL(0.0)); + CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) ); + + dBodySetLinearVel(bId1, REAL(1.11), REAL(3.33), REAL(0.0)); + dBodySetLinearVel(bId2, REAL(1.11), REAL(3.33), REAL(0.0)); + CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) ); + + dBodySetLinearVel(bId1, REAL(1.11), REAL(3.33), REAL(2.22)); + dBodySetLinearVel(bId2, REAL(1.11), REAL(3.33), REAL(2.22)); + CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) ); + + + // Reset for the next set of test. + dBodySetLinearVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0)); + dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0)); + + dBodySetLinearVel(bId2, REAL(0.0), REAL(0.0), REAL(0.0)); + dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0)); + + + // They move with the same angular speed + // linear speed == 0 + + dBodySetAngularVel(bId1, REAL(1.22), REAL(0.0), REAL(0.0)); + dBodySetAngularVel(bId2, REAL(1.22), REAL(0.0), REAL(0.0)); + CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) ); + + dBodySetAngularVel(bId1, REAL(1.22), REAL(2.33), REAL(0.0)); + dBodySetAngularVel(bId2, REAL(1.22), REAL(2.33), REAL(0.0)); + CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) ); + + dBodySetAngularVel(bId1, REAL(1.22), REAL(2.33), REAL(3.44)); + dBodySetAngularVel(bId2, REAL(1.22), REAL(2.33), REAL(3.44)); + CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) ); + } + + +//////////////////////////////////////////////////////////////////////////////// +// Position Body1 [0, 1, 0] +// Position Body2 [0, -1, 0] +// Axis of the prismatic [0, 1, 0] +// Axis of the rotoide [1, 0, ]0 +// +// Only the first body moves +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PRGetInfo1_Fixture_3, GetPRPositionRate_Bodies_in_line_B1_moves) + { + dBodySetLinearVel(bId1, REAL(3.33), REAL(0.0), REAL(0.0)); // This is impossible but ... + CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) ); + + dBodySetLinearVel(bId1, REAL(0.0), REAL(3.33), REAL(0.0)); + CHECK_EQUAL(REAL(3.33), dJointGetPRPositionRate (jId) ); + + dBodySetLinearVel(bId1, REAL(0.0), REAL(0.0), REAL(3.33)); // This is impossible but ... + CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) ); + + + // Only the first body as angular velocity + dBodySetAngularVel(bId1, REAL(1.22), REAL(0.0), REAL(0.0)); + CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) ); + + dBodySetAngularVel(bId1, REAL(0.0), REAL(2.33), REAL(0.0)); + CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) ); + + dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(5.55)); + CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) ); + } + +//////////////////////////////////////////////////////////////////////////////// +// Position Body1 [0, 1, 0] +// Position Body2 [0, -1, 0] +// Axis of the prismatic [0, 1, 0] +// Axis of the rotoide [1, 0, ]0 +// +// Only the second body moves +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PRGetInfo1_Fixture_3, GetPRPositionRate_Bodies_in_line_B2_moves) + { + dBodySetLinearVel(bId2, REAL(3.33), REAL(0.0), REAL(0.0)); // This is impossible but ... + CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) ); + + // The length was at zero and this will give an negative length + dBodySetLinearVel(bId2, REAL(0.0), REAL(3.33), REAL(0.0)); + CHECK_EQUAL(REAL(-3.33), dJointGetPRPositionRate (jId) ); + + dBodySetLinearVel(bId2, REAL(0.0), REAL(0.0), REAL(3.33)); // This is impossible but ... + CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) ); + + + // Only angular velocity + dBodySetAngularVel(bId2, REAL(1.22), REAL(0.0), REAL(0.0)); + CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) ); + + dBodySetAngularVel(bId2, REAL(0.0), REAL(2.33), REAL(0.0)); + CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) ); + + dBodySetAngularVel(bId2, REAL(0.0), REAL(0.0), REAL(5.55)); + CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) ); + } + + +//////////////////////////////////////////////////////////////////////////////// +// Fixture for testing the PositionRate +// +// The second body is at 90deg w.r.t. the first body +// +// +// Default Position +// ^Z +// | +// | +// +// +---+ +// | |Body2 +// | | +// | | +// +---+ +// | +// | +// | +// | Body1 +// R _ - +-----------+ +// (_)----|-----| | ----->Y +// - +-----------+ +// +// N.B. X is comming out of the page +//////////////////////////////////////////////////////////////////////////////// + struct PRGetInfo1_Fixture_4 + { + PRGetInfo1_Fixture_4() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate(wId); + dBodySetPosition(bId1, 0, 1, 0); + + bId2 = dBodyCreate(wId); + dBodySetPosition(bId2, 0, 0, 1); + + dMatrix3 R; + dRFromAxisAndAngle (R, 1, 0, 0, -M_PI/2.0); + dBodySetRotation (bId2, R); + + + jId = dJointCreatePR(wId, 0); + joint = (dxJointPR*)jId; + + dJointAttach(jId, bId1, bId2); + dJointSetPRAnchor (jId, REAL(0.0), REAL(0.0), REAL(0.0)); + + dBodySetLinearVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0)); + dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0)); + + dBodySetLinearVel(bId2, REAL(0.0), REAL(0.0), REAL(0.0)); + dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0)); + + } + + ~PRGetInfo1_Fixture_4() + { + dWorldDestroy(wId); + } + + dJointID jId; + dxJointPR* joint; + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + dxJoint::Info1 info; + }; + + +//////////////////////////////////////////////////////////////////////////////// +// Position Body1 [0, 1, 0] +// Position Body2 [0, 0, 1] +// Axis of the prismatic [0, 1, 0] +// Axis of the rotoide [1, 0, 0] +// +// Only the first body moves +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PRGetInfo1_Fixture_4, GetPRPositionRate_Bodies_at90deg_B1_moves) + { + dBodySetLinearVel(bId1, REAL(3.33), REAL(0.0), REAL(0.0)); // This is impossible but ... + CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) ); + + // The length was at zero and this will give an negative length + dBodySetLinearVel(bId1, REAL(0.0), REAL(3.33), REAL(0.0)); + CHECK_EQUAL(REAL(3.33), dJointGetPRPositionRate (jId) ); + + dBodySetLinearVel(bId1, REAL(0.0), REAL(0.0), REAL(3.33)); // This is impossible but ... + CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) ); + + + // Only angular velocity + dBodySetAngularVel(bId1, REAL(1.22), REAL(0.0), REAL(0.0)); + CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) ); + + dBodySetAngularVel(bId1, REAL(0.0), REAL(2.33), REAL(0.0)); + CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) ); + + dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(5.55)); + CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) ); + } + +//////////////////////////////////////////////////////////////////////////////// +// Position Body1 [0, 1, 0] +// Position Body2 [0, 0, 1] +// Axis of the prismatic [0, 1, 0] +// Axis of the rotoide [1, 0, 0] +// +// Only the second body moves +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PRGetInfo1_Fixture_4, GetPRPositionRate_Bodies_at90deg_B2_moves) + { + dBodySetLinearVel(bId2, REAL(3.33), REAL(0.0), REAL(0.0)); // This is impossible but ... + CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) ); + + dBodySetLinearVel(bId2, REAL(0.0), REAL(3.33), REAL(0.0)); + CHECK_EQUAL(REAL(-3.33), dJointGetPRPositionRate (jId) ); + + dBodySetLinearVel(bId2, REAL(0.0), REAL(0.0), REAL(3.33)); // This is impossible but ... + CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) ); + + + // Only angular velocity + dBodySetAngularVel(bId2, REAL(1.22), REAL(0.0), REAL(0.0)); + CHECK_EQUAL(REAL(-1.0*1.22), dJointGetPRPositionRate (jId) ); + + dBodySetAngularVel(bId2, REAL(0.0), REAL(2.33), REAL(0.0)); + CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) ); + + dBodySetAngularVel(bId2, REAL(0.0), REAL(0.0), REAL(5.55)); + CHECK_EQUAL(REAL(0.0), dJointGetPRPositionRate (jId) ); + } + +} // End of SUITE(JointPR) + + + + + +// // // +// Testing the PU Joint +// +// // +//////////////////////////////////////////////////////////////////////////////// +// Default Position: +// Position Body1 (3, 0, 0) +// Position Body2 (1, 0, 0) +// Angchor (2, 0, 0) +// Axis1 (0, 1, 0) +// Axis2 (0, 0, 1) +// AxisP1 (1, 0, 0) +// +// Y ^ Axis2 +// ^ | +// / | ^ Axis1 +// Z^ / | / +// | / Body 2 | / Body 1 +// | / +---------+ | / +-----------+ +// | / / /| | / / /| +// | / / / + _/ - / / + +// | / / /-/--------(_)----|--- /-----------/-------> AxisP +// | / +---------+ / - +-----------+ / +// | / | |/ | |/ +// | / +---------+ +-----------+ +// |/ +// .-----------------------------------------> X +// |-----------------> +// Anchor2 <--------------| +// Anchor1 +// +//////////////////////////////////////////////////////////////////////////////// +SUITE(JointPU) +{ + struct PUGetInfo1_Fixture_1 + { + PUGetInfo1_Fixture_1() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate(wId); + dBodySetPosition(bId1, 3, 0, 0); + + bId2 = dBodyCreate(wId); + dBodySetPosition(bId2, 1, 0, 0); + + + jId = dJointCreatePU(wId, 0); + joint = (dxJointPU*)jId; + + dJointAttach(jId, bId1, bId2); + + dJointSetPUAnchor (jId, 2, 0, 0); + } + + ~PUGetInfo1_Fixture_1() + { + dWorldDestroy(wId); + } + + dJointID jId; + dxJointPU* joint; + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + dxJoint::Info1 info; + }; + + +//////////////////////////////////////////////////////////////////////////////// +// Test when there is no limits. +// The 2 bodies stay aligned. +// +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PUGetInfo1_Fixture_1, test1_SetPUParam) + { + dJointSetPUParam(jId, dParamLoStop1, -M_PI); + dJointSetPUParam(jId, dParamHiStop1 , M_PI); + dJointSetPUParam(jId, dParamLoStop2, -M_PI); + dJointSetPUParam(jId, dParamHiStop2, M_PI); + dJointSetPUParam(jId, dParamLoStop3, -dInfinity); + dJointSetPUParam(jId, dParamHiStop3, dInfinity); + + joint->getInfo1(&info); + + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(0, joint->limot2.limit); + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(3, info.m); + } + + +//////////////////////////////////////////////////////////////////////////////// +// Test when there is limits for the prismatic at -10 and 10 +// The Body 2 is moved -100 unit then at 100 +// +// Default value for axisR1 = 1,0,0 +// Default value for axisP1 = 0,1,0 +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PUGetInfo1_Fixture_1, test1_GetPUParam) + { + dJointSetPUParam(jId, dParamLoStop3, -10); + dJointSetPUParam(jId, dParamHiStop3, 10); + + dBodySetPosition(bId2, REAL(-100.0), REAL(0.0), REAL(0.0)); + + joint->getInfo1(&info); + + + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(0, joint->limot2.limit); + CHECK_EQUAL(2, joint->limotP.limit); + CHECK_EQUAL(4, info.m); + + + dBodySetPosition(bId2, REAL(100.0), REAL(0.0), REAL(0.0)); + + joint->getInfo1(&info); + + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(0, joint->limot2.limit); + CHECK_EQUAL(1, joint->limotP.limit); + CHECK_EQUAL(4, info.m); + + // Reset Position and test + dBodySetPosition(bId2, 1, 0, 0); + dMatrix3 R_final = { 1,0,0,0, + 0,1,0,0, + 0,0,1,0 + }; + dBodySetRotation (bId2, R_final); + + joint->getInfo1(&info); + + + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(0, joint->limot2.limit); + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(3, info.m); + } + +//////////////////////////////////////////////////////////////////////////////// +// Test when there is limits for the prismatic at -10 and 10 +// and for Axis1 and Axis2 at -45deg and 45deg. +// The Body 2 is rotated by 90deg around Axis1 +// +// +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PUGetInfo1_Fixture_1, test2_PUGetInfo1) + { + dJointSetPUParam(jId, dParamLoStop1, -M_PI/4.0); + dJointSetPUParam(jId, dParamHiStop1, M_PI/4.0); + dJointSetPUParam(jId, dParamLoStop2, -M_PI/4.0); + dJointSetPUParam(jId, dParamHiStop2, M_PI/4.0); + dJointSetPUParam(jId, dParamLoStop3, -10); + dJointSetPUParam(jId, dParamHiStop3, 10); + + + dMatrix3 R; + dBodySetPosition (bId2, 0, 0, 1); + dRFromAxisAndAngle (R, 0, 1, 0, M_PI/2.0); + dBodySetRotation (bId2, R); + + joint->getInfo1(&info); + + CHECK_EQUAL(1, joint->limot1.limit); + CHECK_EQUAL(0, joint->limot2.limit); + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(4, info.m); + + // Reset Position and test + dBodySetPosition(bId2, 1, 0, 0); + dMatrix3 R_final = { 1,0,0,0, + 0,1,0,0, + 0,0,1,0 + }; + dBodySetRotation (bId2, R_final); + + joint->getInfo1(&info); + + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(0, joint->limot2.limit); + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(3, info.m); + } + +//////////////////////////////////////////////////////////////////////////////// +// Test when there is limits for the prismatic at -10 and 10 +// and for Axis1 and Axis2 at -45deg and 45deg. +// The Body 2 is rotated by 90deg around Axis1 and +// Body1 is moved at X=100 +// +// +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PUGetInfo1_Fixture_1, test3_PUGetInfo1) + { + dJointSetPUParam(jId, dParamLoStop1, -M_PI/4.0); + dJointSetPUParam(jId, dParamHiStop1, M_PI/4.0); + dJointSetPUParam(jId, dParamLoStop2, -M_PI/4.0); + dJointSetPUParam(jId, dParamHiStop2, M_PI/4.0); + dJointSetPUParam(jId, dParamLoStop3, -10); + dJointSetPUParam(jId, dParamHiStop3, 10); + + + dBodySetPosition (bId1, REAL(100.0), REAL(0.0), REAL(0.0)); + + dMatrix3 R; + dBodySetPosition (bId2, 0, 0, 1); + dRFromAxisAndAngle (R, 0, 1, 0, M_PI/2.0); + dBodySetRotation (bId2, R); + + joint->getInfo1(&info); + + CHECK_EQUAL(1, joint->limot1.limit); + CHECK_EQUAL(0, joint->limot2.limit); + CHECK_EQUAL(2, joint->limotP.limit); + CHECK_EQUAL(5, info.m); + + // Reset Position and test + dBodySetPosition(bId1, 3, 0, 0); + + dBodySetPosition(bId2, 1, 0, 0); + dMatrix3 R_final = { 1,0,0,0, + 0,1,0,0, + 0,0,1,0 + }; + dBodySetRotation (bId2, R_final); + + joint->getInfo1(&info); + + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(0, joint->limot2.limit); + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(3, info.m); + } + + +//////////////////////////////////////////////////////////////////////////////// +// Default Position: +// Position Body1 (3, 0, 0) +// Position Body2 (1, 0, 0) +// Angchor (2, 0, 0) +// Axis1 (0, 1, 0) +// Axis2 (0, 0, 1) +// AxisP1 (1, 0, 0) +// +// The motor on axis1 is now powered. (i.e. joint->limot1->fmax > 0 +// +// Y ^ Axis2 +// ^ | +// / | ^ Axis1 +// Z^ / | / +// | / Body 2 | / Body 1 +// | / +---------+ | / +-----------+ +// | / / /| | / / /| +// | / / / + _/ - / / + +// | / / /-/--------(_)----|--- /-----------/-------> AxisP +// | / +---------+ / - +-----------+ / +// | / | |/ | |/ +// | / +---------+ +-----------+ +// |/ +// .-----------------------------------------> X +// |-----------------> +// Anchor2 <--------------| +// Anchor1 +// +//////////////////////////////////////////////////////////////////////////////// + struct PUGetInfo1_Fixture_2 + { + PUGetInfo1_Fixture_2() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate(wId); + dBodySetPosition(bId1, 3, 0, 0); + + bId2 = dBodyCreate(wId); + dBodySetPosition(bId2, 1, 0, 0); + + + jId = dJointCreatePU(wId, 0); + joint = (dxJointPU*)jId; + + dJointAttach(jId, bId1, bId2); + + dJointSetPUAnchor (jId, 2, 0, 0); + + joint->limot1.fmax = 1; + } + + ~PUGetInfo1_Fixture_2() + { + dWorldDestroy(wId); + } + + dJointID jId; + dxJointPU* joint; + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + dxJoint::Info1 info; + }; + + + +//////////////////////////////////////////////////////////////////////////////// +// Test when there is no limits. +// The 2 bodies stay aligned. +// +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PUGetInfo1_Fixture_2, test0_PUGetInfo1) + { + dJointSetPUParam(jId, dParamLoStop1, -M_PI); + dJointSetPUParam(jId, dParamHiStop1 , M_PI); + dJointSetPUParam(jId, dParamLoStop2, -M_PI); + dJointSetPUParam(jId, dParamHiStop2, M_PI); + dJointSetPUParam(jId, dParamLoStop3, -dInfinity); + dJointSetPUParam(jId, dParamHiStop3, dInfinity); + + joint->getInfo1(&info); + + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(0, joint->limot2.limit); + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(4, info.m); + } + + +//////////////////////////////////////////////////////////////////////////////// +// Test when there is limits for the prismatic at -10 and 10 +// The Body 2 is moved -100 unit then at 100 +// +// Default value for axisR1 = 1,0,0 +// Default value for axisP1 = 0,1,0 +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PUGetInfo1_Fixture_2, test1_PUGetInfo1) + { + dJointSetPUParam(jId, dParamLoStop3, -10); + dJointSetPUParam(jId, dParamHiStop3, 10); + + dBodySetPosition(bId2, REAL(-100.0), REAL(0.0), REAL(0.0)); + + joint->getInfo1(&info); + + + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(0, joint->limot2.limit); + CHECK_EQUAL(2, joint->limotP.limit); + CHECK_EQUAL(5, info.m); + + + dBodySetPosition(bId2, REAL(100.0), REAL(0.0), REAL(0.0)); + + joint->getInfo1(&info); + + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(0, joint->limot2.limit); + CHECK_EQUAL(1, joint->limotP.limit); + CHECK_EQUAL(5, info.m); + + // Reset Position and test + dBodySetPosition(bId2, 1, 0, 0); + dMatrix3 R_final = { 1,0,0,0, + 0,1,0,0, + 0,0,1,0 + }; + dBodySetRotation (bId2, R_final); + + joint->getInfo1(&info); + + + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(0, joint->limot2.limit); + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(4, info.m); + } + +//////////////////////////////////////////////////////////////////////////////// +// Test when there is limits for the prismatic at -10 and 10 +// and for Axis1 and Axis2 at -45deg and 45deg. +// The Body 2 is rotated by 90deg around Axis1 +// +// +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PUGetInfo1_Fixture_2, test2_PUGetInfo1) + { + dJointSetPUParam(jId, dParamLoStop1, -M_PI/4.0); + dJointSetPUParam(jId, dParamHiStop1, M_PI/4.0); + dJointSetPUParam(jId, dParamLoStop2, -M_PI/4.0); + dJointSetPUParam(jId, dParamHiStop2, M_PI/4.0); + dJointSetPUParam(jId, dParamLoStop3, -10); + dJointSetPUParam(jId, dParamHiStop3, 10); + + + dMatrix3 R; + dBodySetPosition (bId2, 0, 0, 1); + dRFromAxisAndAngle (R, 0, 1, 0, M_PI/2.0); + dBodySetRotation (bId2, R); + + joint->getInfo1(&info); + + CHECK_EQUAL(1, joint->limot1.limit); + CHECK_EQUAL(0, joint->limot2.limit); + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(4, info.m); + + // Reset Position and test + dBodySetPosition(bId2, 1, 0, 0); + dMatrix3 R_final = { 1,0,0,0, + 0,1,0,0, + 0,0,1,0 + }; + dBodySetRotation (bId2, R_final); + + joint->getInfo1(&info); + + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(0, joint->limot2.limit); + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(4, info.m); + } + +//////////////////////////////////////////////////////////////////////////////// +// Test when there is limits for the prismatic at -10 and 10 +// and for Axis1 and Axis2 at -45deg and 45deg. +// The Body 2 is rotated by 90deg around Axis1 and +// Body1 is moved at X=100 +// +// +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PUGetInfo1_Fixture_2, test3_PUGetInfo1) + { + dJointSetPUParam(jId, dParamLoStop1, -M_PI/4.0); + dJointSetPUParam(jId, dParamHiStop1, M_PI/4.0); + dJointSetPUParam(jId, dParamLoStop2, -M_PI/4.0); + dJointSetPUParam(jId, dParamHiStop2, M_PI/4.0); + dJointSetPUParam(jId, dParamLoStop3, -10); + dJointSetPUParam(jId, dParamHiStop3, 10); + + + dBodySetPosition (bId1, REAL(100.0), REAL(0.0), REAL(0.0)); + + dMatrix3 R; + dBodySetPosition (bId2, 0, 0, 1); + dRFromAxisAndAngle (R, 0, 1, 0, M_PI/2.0); + dBodySetRotation (bId2, R); + + joint->getInfo1(&info); + + CHECK_EQUAL(1, joint->limot1.limit); + CHECK_EQUAL(0, joint->limot2.limit); + CHECK_EQUAL(2, joint->limotP.limit); + CHECK_EQUAL(5, info.m); + + // Reset Position and test + dBodySetPosition(bId1, 3, 0, 0); + + dBodySetPosition(bId2, 1, 0, 0); + dMatrix3 R_final = { 1,0,0,0, + 0,1,0,0, + 0,0,1,0 + }; + dBodySetRotation (bId2, R_final); + + joint->getInfo1(&info); + + CHECK_EQUAL(0, joint->limot1.limit); + CHECK_EQUAL(0, joint->limot2.limit); + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(4, info.m); + } + + + + TEST_FIXTURE(PUGetInfo1_Fixture_2, test_SetPUParam) + { + dJointSetPUParam(jId, dParamHiStop, REAL(5.0) ); + CHECK_EQUAL(REAL(5.0), joint->limot1.histop); + + dJointSetPUParam(jId, dParamVel, REAL(7.0) ); + CHECK_EQUAL(REAL(7.0), joint->limot1.vel); + +#ifdef dParamFudgeFactor1 + dJointSetPUParam(jId, dParamFudgeFactor1, REAL(5.5) ); + CHECK_EQUAL(REAL(5.5), joint->limot1.dParamFudgeFactor); +#endif + + dJointSetPUParam(jId, dParamCFM2, REAL(9.0) ); + CHECK_EQUAL(REAL(9.0), joint->limot2.normal_cfm); + + dJointSetPUParam(jId, dParamStopERP2, REAL(11.0) ); + CHECK_EQUAL(REAL(11.0), joint->limot2.stop_erp); + + + dJointSetPUParam(jId, dParamBounce3, REAL(13.0) ); + CHECK_EQUAL(REAL(13.0), joint->limotP.bounce); + } + + + + TEST_FIXTURE(PUGetInfo1_Fixture_1, test_GetPUParam) + { + joint->limotP.histop = REAL(5.0); + CHECK_EQUAL(joint->limot1.histop, + dJointGetPUParam(jId, dParamHiStop) ); + + joint->limotP.vel = REAL(7.0); + + CHECK_EQUAL(joint->limot1.vel, + dJointGetPUParam(jId, dParamVel) ); + +#ifdef dParamFudgeFactor1 + joint->limotP.dParamFudgeFactor = REAL(5.5); + + CHECK_EQUAL(joint->limot1.dParamFudgeFactor, + dJointGetPUParam(jId, dParamFudgeFactor1) ); +#endif + + joint->limot2.normal_cfm = REAL(9.0); + CHECK_EQUAL(joint->limot2.normal_cfm, + dJointGetPUParam(jId, dParamCFM2) ); + + joint->limot2.stop_erp = REAL(11.0); + CHECK_EQUAL(joint->limot2.stop_erp, + dJointGetPUParam(jId, dParamStopERP2) ); + + joint->limotP.bounce = REAL(13.0); + CHECK_EQUAL(joint->limotP.bounce, + dJointGetPUParam(jId, dParamBounce3) ); + } + + + +//////////////////////////////////////////////////////////////////////////////// +// Texture for testing the PositionRate +// +// Default Position: +// Position Body1 (3, 0, 0) +// Position Body2 (1, 0, 0) +// Angchor (2, 0, 0) +// Axis1 (0, 1, 0) +// Axis2 (0, 0, 1) +// AxisP1 (1, 0, 0) +// +// Default velocity: +// Body 1 lvel=( 0, 0, 0) avel=( 0, 0, 0) +// Body 2 lvel=( 0, 0, 0) avel=( 0, 0, 0) +// +// +// Y ^ Axis2 +// ^ | +// / | ^ Axis1 +// Z^ / | / +// | / Body 2 | / Body 1 +// | / +---------+ | / +-----------+ +// | / / /| | / / /| +// | / / / + _/ - / / + +// | / / /-/--------(_)----|--- /-----------/-------> AxisP +// | / +---------+ / - +-----------+ / +// | / | |/ | |/ +// | / +---------+ +-----------+ +// |/ +// .-----------------------------------------> X +// |-----------------> +// Anchor2 <--------------| +// Anchor1 +// +//////////////////////////////////////////////////////////////////////////////// + struct PUGetInfo1_Fixture_3 + { + PUGetInfo1_Fixture_3() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate(wId); + dBodySetPosition(bId1, 3, 0, 0); + + bId2 = dBodyCreate(wId); + dBodySetPosition(bId2, 1, 0, 0); + + + jId = dJointCreatePU(wId, 0); + joint = (dxJointPU*)jId; + + dJointAttach(jId, bId1, bId2); + dJointSetPUAnchor (jId, 2, 0, 0); + + dBodySetLinearVel (bId1, REAL(0.0), REAL(0.0), REAL(0.0)); + dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0)); + + dBodySetLinearVel (bId2, REAL(0.0), REAL(0.0), REAL(0.0)); + dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0)); + + } + + ~PUGetInfo1_Fixture_3() + { + dWorldDestroy(wId); + } + + dJointID jId; + dxJointPU* joint; + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + dxJoint::Info1 info; + }; + +//////////////////////////////////////////////////////////////////////////////// +// Position Body1 [3, 0, 0] +// Position Body2 [1, 0, 0] +// Axis of the prismatic [1, 0, 0] +// Axis1 [0, 1, 0] +// Axis2 [0, 0, 1] +// +// Move at the same speed +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PUGetInfo1_Fixture_3, test1_GetPUPositionRate) + { + // They move with the same linear speed + // Angular speed == 0 + dBodySetLinearVel(bId1, REAL(0.0), REAL(3.33), REAL(0.0)); + dBodySetLinearVel(bId2, REAL(0.0), REAL(3.33), REAL(0.0)); + CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) ); + + dBodySetLinearVel(bId1, REAL(1.11), REAL(3.33), REAL(0.0)); + dBodySetLinearVel(bId2, REAL(1.11), REAL(3.33), REAL(0.0)); + CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) ); + + dBodySetLinearVel(bId1, REAL(1.11), REAL(3.33), REAL(2.22)); + dBodySetLinearVel(bId2, REAL(1.11), REAL(3.33), REAL(2.22)); + CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) ); + + + // Reset for the next set of test. + dBodySetLinearVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0)); + dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0)); + + dBodySetLinearVel(bId2, REAL(0.0), REAL(0.0), REAL(0.0)); + dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0)); + + + // They move with the same angular speed + // linear speed == 0 + + dBodySetAngularVel(bId1, REAL(1.22), REAL(0.0), REAL(0.0)); + dBodySetAngularVel(bId2, REAL(1.22), REAL(0.0), REAL(0.0)); + CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) ); + + dBodySetAngularVel(bId1, REAL(1.22), REAL(2.33), REAL(0.0)); + dBodySetAngularVel(bId2, REAL(1.22), REAL(2.33), REAL(0.0)); + CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) ); + + dBodySetAngularVel(bId1, REAL(1.22), REAL(2.33), REAL(3.44)); + dBodySetAngularVel(bId2, REAL(1.22), REAL(2.33), REAL(3.44)); + CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) ); + } + + +//////////////////////////////////////////////////////////////////////////////// +// Position Body1 [3, 0, 0] +// Position Body2 [1, 0, 0] +// Axis of the prismatic [1, 0, 0] +// Axis1 [0, 1, 0] +// Axis2 [0, 0, 1] +// +// Only the first body moves +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PUGetInfo1_Fixture_3, GetPUPositionRate_Bodies_in_line_B1_moves) + { + dBodySetLinearVel(bId1, REAL(3.33), REAL(0.0), REAL(0.0)); // This is impossible but ... + CHECK_EQUAL(REAL(3.33), dJointGetPUPositionRate (jId) ); + + dBodySetLinearVel(bId1, REAL(0.0), REAL(3.33), REAL(0.0)); + CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) ); + + dBodySetLinearVel(bId1, REAL(0.0), REAL(0.0), REAL(3.33)); // This is impossible but ... + CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) ); + + + // Only the first body as angular velocity + dBodySetAngularVel(bId1, REAL(1.22), REAL(0.0), REAL(0.0)); + CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) ); + + dBodySetAngularVel(bId1, REAL(0.0), REAL(2.33), REAL(0.0)); + CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) ); + + dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(5.55)); + CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) ); + } + +//////////////////////////////////////////////////////////////////////////////// +// Position Body1 [3, 0, 0] +// Position Body2 [1, 0, 0] +// Axis of the prismatic [1, 0, 0] +// Axis1 [0, 1, 0] +// Axis2 [0, 0, 1] +// +// Only the second body moves +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PUGetInfo1_Fixture_3, GetPUPositionRate_Bodies_in_line_B2_moves) + { + // The length was at zero and this will give an negative length + dBodySetLinearVel(bId2, REAL(3.33), REAL(0.0), REAL(0.0)); + CHECK_EQUAL(REAL(-3.33), dJointGetPUPositionRate (jId) ); + + dBodySetLinearVel(bId2, REAL(0.0), REAL(3.33), REAL(0.0)); // This is impossible but ... + CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) ); + + dBodySetLinearVel(bId2, REAL(0.0), REAL(0.0), REAL(3.33)); // This is impossible but ... + CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) ); + + + // Only angular velocity + dBodySetAngularVel(bId2, REAL(1.22), REAL(0.0), REAL(0.0)); + CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) ); + + dBodySetAngularVel(bId2, REAL(0.0), REAL(2.33), REAL(0.0)); + CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) ); + + dBodySetAngularVel(bId2, REAL(0.0), REAL(0.0), REAL(5.55)); + CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) ); + } + + +//////////////////////////////////////////////////////////////////////////////// +// Fixture for testing the PositionRate +// +// Default Position: +// Position Body1 (3, 0, 0) +// Position Body2 (0, 0, 1) +// Angchor (2, 0, 0) +// Axis1 (0, 1, 0) +// Axis2 (1, 0, 0) +// AxisP (1, 0, 0) +// +// The second body is at 90deg w.r.t. the first body +// +// +// Default Position +// ^Z +// | +// | +// +// +---+ +// | |Body2 +// | | +// | | +// +---+ +// | ^ Axis1 +// | / +// | / +// | / Body1 +// R _ - +-----------+ +// (_)----|-----| | ----->X AxisP, Axis2 +// - +-----------+ +// +// N.B. Y is going into the page +//////////////////////////////////////////////////////////////////////////////// + struct PUGetInfo1_Fixture_4 + { + PUGetInfo1_Fixture_4() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate(wId); + dBodySetPosition(bId1, 3, 0, 0); + + bId2 = dBodyCreate(wId); + dBodySetPosition(bId2, 0, 0, 1); + + dMatrix3 R; + dRFromAxisAndAngle (R, 1, 0, 0, -M_PI/2.0); + dBodySetRotation (bId2, R); + + + jId = dJointCreatePU(wId, 0); + joint = (dxJointPU*)jId; + + dJointAttach(jId, bId1, bId2); + dJointSetPUAnchor (jId, 2, 0, 0); + dJointSetPUAxis1 (jId, 0, 1, 0); + dJointSetPUAxis2 (jId, 1, 0, 0); + dJointSetPUAxisP (jId, 1, 0, 0); + + + dBodySetLinearVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0)); + dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0)); + + dBodySetLinearVel(bId2, REAL(0.0), REAL(0.0), REAL(0.0)); + dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0)); + + } + + ~PUGetInfo1_Fixture_4() + { + dWorldDestroy(wId); + } + + dJointID jId; + dxJointPU* joint; + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + dxJoint::Info1 info; + }; + + +//////////////////////////////////////////////////////////////////////////////// +// Position Body1 (3, 0, 0) +// Position Body2 (1, 0, 0) +// Angchor (2, 0, 0) +// Axis1 (0, 1, 0) +// Axis2 (0, 0, 1) +// AxisP1 (1, 0, 0) +// +// Only the first body moves +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PUGetInfo1_Fixture_4, GetPUPositionRate_Bodies_at90deg_B1_moves) + { + dBodySetLinearVel(bId1, REAL(3.33), REAL(0.0), REAL(0.0)); // This is impossible but ... + CHECK_EQUAL(REAL(3.33), dJointGetPUPositionRate (jId) ); + + dBodySetLinearVel(bId1, REAL(0.0), REAL(3.33), REAL(0.0)); + CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) ); + + dBodySetLinearVel(bId1, REAL(0.0), REAL(0.0), REAL(3.33)); // This is impossible but ... + CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) ); + + + // Only angular velocity + dBodySetAngularVel(bId1, REAL(1.22), REAL(0.0), REAL(0.0)); + CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) ); + + dBodySetAngularVel(bId1, REAL(0.0), REAL(2.33), REAL(0.0)); + CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) ); + + dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(5.55)); + CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) ); + } + +//////////////////////////////////////////////////////////////////////////////// +// Position Body1 (3, 0, 0) +// Position Body2 (1, 0, 0) +// Angchor (2, 0, 0) +// Axis1 (0, 1, 0) +// Axis2 (0, 0, 1) +// AxisP1 (1, 0, 0) +// +// Only the second body moves +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PUGetInfo1_Fixture_4, GetPUPositionRate_Bodies_at90deg_B2_moves) + { + // The length was at zero and this will give an negative length + dBodySetLinearVel(bId2, REAL(3.33), REAL(0.0), REAL(0.0)); + CHECK_EQUAL(REAL(-3.33), dJointGetPUPositionRate (jId) ); + + dBodySetLinearVel(bId2, REAL(0.0), REAL(3.33), REAL(0.0)); // This is impossible but ... + CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) ); + + dBodySetLinearVel(bId2, REAL(0.0), REAL(0.0), REAL(3.33)); // This is impossible but ... + CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) ); + + + // Only angular velocity + dBodySetAngularVel(bId2, REAL(1.22), REAL(0.0), REAL(0.0)); + CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) ); + + dBodySetAngularVel(bId2, REAL(0.0), REAL(2.33), REAL(0.0)); + CHECK_EQUAL(REAL(-1.0*2.330), dJointGetPUPositionRate (jId) ); + + dBodySetAngularVel(bId2, REAL(0.0), REAL(0.0), REAL(5.55)); + CHECK_EQUAL(REAL(0.0), dJointGetPUPositionRate (jId) ); + } + +} // End of SUITE(JointPU) + + +// ============================================================================= +// ============================================================================= +// +// Testing the Piston Joint +// +// ============================================================================= +// ============================================================================= + +//////////////////////////////////////////////////////////////////////////////// +// Default Position: +// Position Body1 (1, 0, 0) +// Position Body2 (3, 0, 0) +// Angchor (2, 0, 0) +// AxisR (0, 1, 0) +// Axis2 (0, 0, 1) +// AxisP1 (1, 0, 0) +// +/// <PRE> +///^Z |- Anchor point +/// | Body_1 | Body_2 +/// | +---------------+ V +------------------+ +/// | / /| / /| +/// | / / + |-- ______ / / + +/// .- / x /./........x.......(_____()..../ x /.......> axis +/// +---------------+ / |-- +------------------+ / X +/// | |/ | |/ +/// +---------------+ +------------------+ +/// | | +/// | | +/// |------------------> <----------------------------| +/// anchor1 anchor2 +/// +/// +/// Axis Y is going into the page +//////////////////////////////////////////////////////////////////////////////// +SUITE(JointPiston) +{ + struct PistonGetInfo1_Fixture_1 + { + PistonGetInfo1_Fixture_1() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate(wId); + dBodySetPosition(bId1, 1, 0, 0); + + bId2 = dBodyCreate(wId); + dBodySetPosition(bId2, 3, 0, 0); + + + jId = dJointCreatePiston(wId, 0); + joint = (dxJointPiston*)jId; + + dJointAttach(jId, bId1, bId2); + + dJointSetPistonAnchor (jId, 2, 0, 0); + } + + ~PistonGetInfo1_Fixture_1() + { + dWorldDestroy(wId); + } + + dJointID jId; + dxJointPiston* joint; + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + dxJoint::Info1 info; + }; + + +//////////////////////////////////////////////////////////////////////////////// +// Test when there is no limits. +// The 2 bodies stay aligned. +// +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PistonGetInfo1_Fixture_1, test1_SetPistonParam) + { + dJointSetPistonParam(jId, dParamLoStop1, -dInfinity); + dJointSetPistonParam(jId, dParamHiStop1, dInfinity); + dJointSetPistonParam(jId, dParamLoStop2, -M_PI); + dJointSetPistonParam(jId, dParamHiStop2 , M_PI); + + joint->getInfo1(&info); + + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(0, joint->limotR.limit); + CHECK_EQUAL(4, info.m); + } + + +//////////////////////////////////////////////////////////////////////////////// +// Test when there is limits for the prismatic at -10 and 10 +// The Body 2 is moved -100 unit then at 100 +// +// Default value for axisR1 = 1,0,0 +// Default value for axisP1 = 0,1,0 +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PistonGetInfo1_Fixture_1, test1_GetPistonParam) + { + dJointSetPistonParam(jId, dParamLoStop1, -10); + dJointSetPistonParam(jId, dParamHiStop1, 10); + + dBodySetPosition(bId2, REAL(-100.0), REAL(0.0), REAL(0.0)); + + joint->getInfo1(&info); + + CHECK_EQUAL(2, joint->limotP.limit); + CHECK_EQUAL(0, joint->limotR.limit); + CHECK_EQUAL(5, info.m); + + + dBodySetPosition(bId2, REAL(100.0), REAL(0.0), REAL(0.0)); + + joint->getInfo1(&info); + + CHECK_EQUAL(0, joint->limotR.limit); + CHECK_EQUAL(1, joint->limotP.limit); + CHECK_EQUAL(5, info.m); + + // Reset Position and test + dBodySetPosition(bId2, 1, 0, 0); + dMatrix3 R_final = { 1,0,0,0, + 0,1,0,0, + 0,0,1,0 + }; + dBodySetRotation (bId2, R_final); + + joint->getInfo1(&info); + + + CHECK_EQUAL(0, joint->limotR.limit); + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(4, info.m); + } + +//////////////////////////////////////////////////////////////////////////////// +// Test when there is limits for the prismatic at -10 and 10 +// and the rotoide at -45deg and 45deg. +// The Body 2 is rotated by 90deg around the axis +// +// +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PistonGetInfo1_Fixture_1, test2_PistonGetInfo1) + { + dJointSetPistonParam(jId, dParamLoStop1, -10); + dJointSetPistonParam(jId, dParamHiStop1, 10); + dJointSetPistonParam(jId, dParamLoStop2, -M_PI/4.0); + dJointSetPistonParam(jId, dParamHiStop2, M_PI/4.0); + + dMatrix3 R; + dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0); + dBodySetRotation (bId2, R); + + joint->getInfo1(&info); + + CHECK_EQUAL(1, joint->limotR.limit); + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(5, info.m); + + // Reset Position and test + dMatrix3 R_final = { 1,0,0,0, + 0,1,0,0, + 0,0,1,0 + }; + dBodySetRotation (bId2, R_final); + + joint->getInfo1(&info); + + CHECK_EQUAL(0, joint->limotR.limit); + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(4, info.m); + } + +//////////////////////////////////////////////////////////////////////////////// +// Test when there is limits for the prismatic at -10 and 10 +// and for rotoide at -45deg and 45deg. +// The Body 2 is rotated by 90deg around the axis +// Body1 is moved at X=100 +// +// +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PistonGetInfo1_Fixture_1, test3_PistonGetInfo1) + { + dJointSetPistonParam(jId, dParamLoStop1, -10); + dJointSetPistonParam(jId, dParamHiStop1, 10); + dJointSetPistonParam(jId, dParamLoStop2, -M_PI/4.0); + dJointSetPistonParam(jId, dParamHiStop2, M_PI/4.0); + + + dBodySetPosition (bId1, REAL(100.0), REAL(0.0), REAL(0.0)); + + dMatrix3 R; + dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0); + dBodySetRotation (bId2, R); + + joint->getInfo1(&info); + + CHECK_EQUAL(2, joint->limotP.limit); + CHECK_EQUAL(1, joint->limotR.limit); + + CHECK_EQUAL(6, info.m); + + // Reset Position and test + dBodySetPosition(bId1, 1, 0, 0); + + dMatrix3 R_final = { 1,0,0,0, + 0,1,0,0, + 0,0,1,0 + }; + dBodySetRotation (bId2, R_final); + + joint->getInfo1(&info); + + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(0, joint->limotR.limit); + CHECK_EQUAL(4, info.m); + } + + +//////////////////////////////////////////////////////////////////////////////// +// Default Position: +// Position Body1 (1, 0, 0) +// Position Body2 (3, 0, 0) +// Angchor (2, 0, 0) +// AxisR (0, 1, 0) +// Axis2 (0, 0, 1) +// AxisP1 (1, 0, 0) +// +// The motor on axis1 is now powered. (i.e. joint->limot1->fmax > 0 +// +/// <PRE> +///^Z |- Anchor point +/// | Body_1 | Body_2 +/// | +---------------+ V +------------------+ +/// | / /| / /| +/// | / / + |-- ______ / / + +/// .- / x /./........x.......(_____()..../ x /.......> axis +/// +---------------+ / |-- +------------------+ / X +/// | |/ | |/ +/// +---------------+ +------------------+ +/// | | +/// | | +/// |------------------> <----------------------------| +/// anchor1 anchor2 +/// +/// +/// Axis Y is going into the page +//////////////////////////////////////////////////////////////////////////////// + struct PistonGetInfo1_Fixture_2 + { + PistonGetInfo1_Fixture_2() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate(wId); + dBodySetPosition(bId1, 1, 0, 0); + + bId2 = dBodyCreate(wId); + dBodySetPosition(bId2, 3, 0, 0); + + + jId = dJointCreatePiston(wId, 0); + joint = (dxJointPiston*)jId; + + dJointAttach(jId, bId1, bId2); + + dJointSetPistonAnchor (jId, 2, 0, 0); + + joint->limotP.fmax = 1; + } + + ~PistonGetInfo1_Fixture_2() + { + dWorldDestroy(wId); + } + + dJointID jId; + dxJointPiston* joint; + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + dxJoint::Info1 info; + }; + + + +//////////////////////////////////////////////////////////////////////////////// +// Test when there is no limits. +// The 2 bodies stay aligned. +// +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PistonGetInfo1_Fixture_2, test0_PistonGetInfo1) + { + dJointSetPistonParam(jId, dParamLoStop1, -dInfinity); + dJointSetPistonParam(jId, dParamHiStop1, dInfinity); + dJointSetPistonParam(jId, dParamLoStop2, -M_PI); + dJointSetPistonParam(jId, dParamHiStop2, M_PI); + + + joint->getInfo1(&info); + + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(0, joint->limotR.limit); + CHECK_EQUAL(5, info.m); + } + + +//////////////////////////////////////////////////////////////////////////////// +// Test when there is limits for the prismatic at -10 and 10 +// The Body 2 is moved -100 unit then at 100 +// +// Default value for axis = 1,0,0 +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PistonGetInfo1_Fixture_2, test1_PistonGetInfo1) + { + dJointSetPistonParam(jId, dParamLoStop1, -10); + dJointSetPistonParam(jId, dParamHiStop1, 10); + + dBodySetPosition(bId2, REAL(-100.0), REAL(0.0), REAL(0.0)); + + joint->getInfo1(&info); + + CHECK_EQUAL(2, joint->limotP.limit); + CHECK_EQUAL(0, joint->limotR.limit); + CHECK_EQUAL(5, info.m); + + + dBodySetPosition(bId2, REAL(100.0), REAL(0.0), REAL(0.0)); + + joint->getInfo1(&info); + + CHECK_EQUAL(1, joint->limotP.limit); + CHECK_EQUAL(0, joint->limotR.limit); + CHECK_EQUAL(5, info.m); + + // Reset Position and test + dBodySetPosition(bId2, 3, 0, 0); + dMatrix3 R_final = { 1,0,0,0, + 0,1,0,0, + 0,0,1,0 + }; + dBodySetRotation (bId2, R_final); + + joint->getInfo1(&info); + + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(0, joint->limotR.limit); + CHECK_EQUAL(5, info.m); + } + +//////////////////////////////////////////////////////////////////////////////// +// Test when there is limits for the prismatic at -10 and 10 +// and for the rotoide at -45deg and 45deg. +// The Body 2 is rotated by 90deg around the axis +// +// +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PistonGetInfo1_Fixture_2, test2_PistonGetInfo1) + { + dJointSetPistonParam(jId, dParamLoStop1, -10); + dJointSetPistonParam(jId, dParamHiStop1, 10); + dJointSetPistonParam(jId, dParamLoStop2, -M_PI/4.0); + dJointSetPistonParam(jId, dParamHiStop2, M_PI/4.0); + + dMatrix3 R; + dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0); + dBodySetRotation (bId2, R); + + joint->getInfo1(&info); + + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(1, joint->limotR.limit); + CHECK_EQUAL(6, info.m); + + // Reset Position and test + dMatrix3 R_final = { 1,0,0,0, + 0,1,0,0, + 0,0,1,0 + }; + dBodySetRotation (bId2, R_final); + + joint->getInfo1(&info); + + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(0, joint->limotR.limit); + CHECK_EQUAL(5, info.m); + } + +//////////////////////////////////////////////////////////////////////////////// +// Test when there is limits for the prismatic at -10 and 10 +// and for the rotoide axuis at -45deg and 45deg. +// The Body 2 is rotated by 90deg around the axis and +// Body1 is moved at X=100 +// +// +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PistonGetInfo1_Fixture_2, test3_PistonGetInfo1) + { + dJointSetPistonParam(jId, dParamLoStop1, -10); + dJointSetPistonParam(jId, dParamHiStop1, 10); + dJointSetPistonParam(jId, dParamLoStop2, -M_PI/4.0); + dJointSetPistonParam(jId, dParamHiStop2, M_PI/4.0); + + + + dBodySetPosition (bId1, REAL(100.0), REAL(0.0), REAL(0.0)); + + dMatrix3 R; + dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0); + dBodySetRotation (bId2, R); + + joint->getInfo1(&info); + + CHECK_EQUAL(2, joint->limotP.limit); + CHECK_EQUAL(1, joint->limotR.limit); + CHECK_EQUAL(6, info.m); + + // Reset Position and test + dBodySetPosition(bId1, 1, 0, 0); + + dBodySetPosition(bId2, 3, 0, 0); + dMatrix3 R_final = { 1,0,0,0, + 0,1,0,0, + 0,0,1,0 + }; + dBodySetRotation (bId2, R_final); + + joint->getInfo1(&info); + + CHECK_EQUAL(0, joint->limotP.limit); + CHECK_EQUAL(0, joint->limotR.limit); + CHECK_EQUAL(5, info.m); + } + + + + TEST_FIXTURE(PistonGetInfo1_Fixture_2, test_SetPistonParam) + { + dJointSetPistonParam(jId, dParamHiStop, REAL(5.0) ); + CHECK_EQUAL(REAL(5.0), joint->limotP.histop); + + dJointSetPistonParam(jId, dParamVel, REAL(7.0) ); + CHECK_EQUAL(REAL(7.0), joint->limotP.vel); + +#ifdef dParamFudgeFactor1 + dJointSetPistonParam(jId, dParamFudgeFactor1, REAL(5.5) ); + CHECK_EQUAL(REAL(5.5), joint->limotP.dParamFudgeFactor); +#endif + + dJointSetPistonParam(jId, dParamCFM2, REAL(9.0) ); + CHECK_EQUAL(REAL(9.0), joint->limotR.normal_cfm); + + dJointSetPistonParam(jId, dParamStopERP2, REAL(11.0) ); + CHECK_EQUAL(REAL(11.0), joint->limotR.stop_erp); + } + + + + TEST_FIXTURE(PistonGetInfo1_Fixture_1, test_GetPistonParam) + { + joint->limotP.histop = REAL(5.0); + CHECK_EQUAL(joint->limotP.histop, + dJointGetPistonParam(jId, dParamHiStop) ); + + joint->limotP.vel = REAL(7.0); + + CHECK_EQUAL(joint->limotP.vel, + dJointGetPistonParam(jId, dParamVel) ); + +#ifdef dParamFudgeFactor1 + joint->limotP.dParamFudgeFactor = REAL(5.5); + + CHECK_EQUAL(joint->limotP.dParamFudgeFactor, + dJointGetPistonParam(jId, dParamFudgeFactor1) ); +#endif + + joint->limotR.normal_cfm = REAL(9.0); + CHECK_EQUAL(joint->limotR.normal_cfm, + dJointGetPistonParam(jId, dParamCFM2) ); + + joint->limotR.stop_erp = REAL(11.0); + CHECK_EQUAL(joint->limotR.stop_erp, + dJointGetPistonParam(jId, dParamStopERP2) ); + } + + + +//////////////////////////////////////////////////////////////////////////////// +// Texture for testing the PositionRate +// +// Default Position: +// Position Body1 (3, 0, 0) +// Position Body2 (1, 0, 0) +// Angchor (2, 0, 0) +// Axis1 (0, 1, 0) +// Axis2 (0, 0, 1) +// AxisP1 (1, 0, 0) +// +// Default velocity: +// Body 1 lvel=( 0, 0, 0) avel=( 0, 0, 0) +// Body 2 lvel=( 0, 0, 0) avel=( 0, 0, 0) +// +// +// Y ^ Axis2 +// ^ | +// / | ^ Axis1 +// Z^ / | / +// | / Body 2 | / Body 1 +// | / +---------+ | / +-----------+ +// | / / /| | / / /| +// | / / / + _/ - / / + +// | / / /-/--------(_)----|--- /-----------/-------> AxisP +// | / +---------+ / - +-----------+ / +// | / | |/ | |/ +// | / +---------+ +-----------+ +// |/ +// .-----------------------------------------> X +// |-----------------> +// Anchor2 <--------------| +// Anchor1 +// +//////////////////////////////////////////////////////////////////////////////// + struct PistonGetInfo1_Fixture_3 + { + PistonGetInfo1_Fixture_3() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate(wId); + dBodySetPosition(bId1, 3, 0, 0); + + bId2 = dBodyCreate(wId); + dBodySetPosition(bId2, 1, 0, 0); + + + jId = dJointCreatePiston(wId, 0); + joint = (dxJointPiston*)jId; + + dJointAttach(jId, bId1, bId2); + dJointSetPistonAnchor (jId, 2, 0, 0); + + dBodySetLinearVel (bId1, REAL(0.0), REAL(0.0), REAL(0.0)); + dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0)); + + dBodySetLinearVel (bId2, REAL(0.0), REAL(0.0), REAL(0.0)); + dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0)); + + } + + ~PistonGetInfo1_Fixture_3() + { + dWorldDestroy(wId); + } + + dJointID jId; + dxJointPiston* joint; + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + dxJoint::Info1 info; + }; + +//////////////////////////////////////////////////////////////////////////////// +// Position Body1 [3, 0, 0] +// Position Body2 [1, 0, 0] +// Axis of the prismatic [1, 0, 0] +// Axis1 [0, 1, 0] +// Axis2 [0, 0, 1] +// +// Move at the same speed +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PistonGetInfo1_Fixture_3, test1_GetPistonPositionRate) + { + // They move with the same linear speed + // Angular speed == 0 + dBodySetLinearVel(bId1, 0, REAL(3.33), 0); + dBodySetLinearVel(bId2, 0, REAL(3.33), 0); + CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) ); + + dBodySetLinearVel(bId1, REAL(1.11), REAL(3.33), 0); + dBodySetLinearVel(bId2, REAL(1.11), REAL(3.33), 0); + CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) ); + + dBodySetLinearVel(bId1, REAL(1.11), REAL(3.33), REAL(2.22)); + dBodySetLinearVel(bId2, REAL(1.11), REAL(3.33), REAL(2.22)); + CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) ); + + + // Reset for the next set of test. + dBodySetLinearVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0)); + dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0)); + + dBodySetLinearVel(bId2, REAL(0.0), REAL(0.0), REAL(0.0)); + dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0)); + + + // They move with the same angular speed + // linear speed == 0 + + dBodySetAngularVel(bId1, REAL(1.22), 0.0, 0.0); + dBodySetAngularVel(bId2, REAL(1.22), 0.0, 0.0); + CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) ); + + dBodySetAngularVel(bId1, REAL(1.22), REAL(2.33), 0.0); + dBodySetAngularVel(bId2, REAL(1.22), REAL(2.33), 0.0); + CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) ); + + dBodySetAngularVel(bId1, REAL(1.22), REAL(2.33), REAL(3.44)); + dBodySetAngularVel(bId2, REAL(1.22), REAL(2.33), REAL(3.44)); + CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) ); + } + + +//////////////////////////////////////////////////////////////////////////////// +// Position Body1 [3, 0, 0] +// Position Body2 [1, 0, 0] +// Axis of the prismatic [1, 0, 0] +// Axis1 [0, 1, 0] +// Axis2 [0, 0, 1] +// +// Only the first body moves +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PistonGetInfo1_Fixture_3, GetPistonPositionRate_Bodies_in_line_B1_moves) + { + dBodySetLinearVel(bId1, REAL(3.33), 0.0, 0.0); // This is impossible but ... + CHECK_EQUAL(REAL(3.33), dJointGetPistonPositionRate (jId) ); + + dBodySetLinearVel(bId1, 0, REAL(3.33), 0); + CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) ); + + dBodySetLinearVel(bId1, 0, 0, REAL(3.33)); // This is impossible but ... + CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) ); + + + // Only the first body as angular velocity + dBodySetAngularVel(bId1, REAL(1.22), 0.0, 0.0); + CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) ); + + dBodySetAngularVel(bId1, 0.0, REAL(2.33), 0.0); + CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) ); + + dBodySetAngularVel(bId1, 0.0, 0.0, REAL(5.55)); + CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) ); + } + +//////////////////////////////////////////////////////////////////////////////// +// Position Body1 [3, 0, 0] +// Position Body2 [1, 0, 0] +// Axis of the prismatic [1, 0, 0] +// Axis1 [0, 1, 0] +// Axis2 [0, 0, 1] +// +// Only the second body moves +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PistonGetInfo1_Fixture_3, GetPistonPositionRate_Bodies_in_line_B2_moves) + { + // The length was at zero and this will give an negative length + dBodySetLinearVel(bId2, REAL(3.33), 0.0, 0.0); + CHECK_EQUAL(REAL(-3.33), dJointGetPistonPositionRate (jId) ); + + dBodySetLinearVel(bId2, 0, REAL(3.33), 0); // This is impossible but ... + CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) ); + + dBodySetLinearVel(bId2, 0, 0, REAL(3.33)); // This is impossible but ... + CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) ); + + + // Only angular velocity + dBodySetAngularVel(bId2, REAL(1.22), 0.0, 0.0); + CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) ); + + dBodySetAngularVel(bId2, 0.0, REAL(2.33), 0.0); + CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) ); + + dBodySetAngularVel(bId2, 0.0, 0.0, REAL(5.55)); + CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) ); + } + + +//////////////////////////////////////////////////////////////////////////////// +// Fixture for testing the PositionRate +// +// Default Position: +// Position Body1 (3, 0, 0) +// Position Body2 (0, 0, 1) +// Angchor (2, 0, 0) +// Axis1 (0, 1, 0) +// Axis2 (1, 0, 0) +// AxisP (1, 0, 0) +// +// The second body is at 90deg w.r.t. the first body +// From +// +// Y ^ Axis2 +// ^ | +// / | ^ Axis1 +// Z^ / | / +// | / Body 2 | / Body 1 +// | / +---------+ | / +-----------+ +// | / / /| | / / /| +// | / / / + _/ - / / + +// | / / /-/--------(_)----|--- /-----------/-------> AxisP +// | / +---------+ / - +-----------+ / +// | / | |/ | |/ +// | / +---------+ +-----------+ +// |/ +// .-----------------------------------------> X +// |-----------------> +// Anchor2 <--------------| +// Anchor1 +// To +// +// Y ^ Axis2 +// ^ | +// / Body 2 | ^ Axis1 +// Z^ +----------+ | / +// | // /| | / Body 1 +// | /+----------+ | | / +-----------+ +// | / | | | | / / /| +// | / | | | _/ - / / + +// | / | |-|------(_)----|--- /-----------/-------> AxisP +// | / | | | - +-----------+ / +// | / | | | | |/ +// | / | | + +-----------+ +// |/ | |/ +// .--------+----------+--------------------> X +// |----------------> +// Anchor2 <--------------| +// Anchor1 +// Default Position +// +// N.B. Y is going into the page +//////////////////////////////////////////////////////////////////////////////// + struct PistonGetInfo1_Fixture_4 + { + PistonGetInfo1_Fixture_4() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate(wId); + dBodySetPosition(bId1, 3, 0, 0); + + bId2 = dBodyCreate(wId); + dBodySetPosition(bId2, 0, 0, 1); + + dMatrix3 R; + dRFromAxisAndAngle (R, 1, 0, 0, -M_PI/2.0); + dBodySetRotation (bId2, R); + + + jId = dJointCreatePiston(wId, 0); + joint = (dxJointPiston*)jId; + + dJointAttach(jId, bId1, bId2); + dJointSetPistonAnchor (jId, 2, 0, 0); + + + dBodySetLinearVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0)); + dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0)); + + dBodySetLinearVel(bId2, REAL(0.0), REAL(0.0), REAL(0.0)); + dBodySetAngularVel(bId1, REAL(0.0), REAL(0.0), REAL(0.0)); + + } + + ~PistonGetInfo1_Fixture_4() + { + dWorldDestroy(wId); + } + + dJointID jId; + dxJointPiston* joint; + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + dxJoint::Info1 info; + }; + + +//////////////////////////////////////////////////////////////////////////////// +// Position Body1 (3, 0, 0) +// Position Body2 (1, 0, 0) +// Angchor (2, 0, 0) +// Axis1 (0, 1, 0) +// Axis2 (0, 0, 1) +// AxisP1 (1, 0, 0) +// +// Only the first body moves +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PistonGetInfo1_Fixture_4, GetPistonPositionRate_Bodies_at90deg_B1_moves) + { + dBodySetLinearVel(bId1, REAL(3.33), 0.0, 0.0); // This is impossible but ... + CHECK_EQUAL(REAL(3.33), dJointGetPistonPositionRate (jId) ); + + dBodySetLinearVel(bId1, 0, REAL(3.33), 0); + CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) ); + + dBodySetLinearVel(bId1, 0, 0, REAL(3.33)); // This is impossible but ... + CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) ); + + + // Only angular velocity + dBodySetAngularVel(bId1, REAL(1.22), 0.0, 0.0); + CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) ); + + dBodySetAngularVel(bId1, 0.0, REAL(2.33), 0.0); + CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) ); + + dBodySetAngularVel(bId1, 0.0, 0.0, REAL(5.55)); + CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) ); + } + +//////////////////////////////////////////////////////////////////////////////// +// Position Body1 (3, 0, 0) +// Position Body2 (1, 0, 0) +// Angchor (2, 0, 0) +// Axis1 (0, 1, 0) +// Axis2 (0, 0, 1) +// AxisP1 (1, 0, 0) +// +// Only the second body moves +//////////////////////////////////////////////////////////////////////////////// + TEST_FIXTURE(PistonGetInfo1_Fixture_4, GetPistonPositionRate_Bodies_at90deg_B2_moves) + { + // The length was at zero and this will give an negative length + dBodySetLinearVel(bId2, REAL(3.33), 0.0, 0.0); + CHECK_EQUAL(REAL(-3.33), dJointGetPistonPositionRate (jId) ); + + dBodySetLinearVel(bId2, 0, REAL(3.33), 0); // This is impossible but ... + CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) ); + + dBodySetLinearVel(bId2, 0, 0, REAL(3.33)); // This is impossible but ... + CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) ); + + + // Only angular velocity + dBodySetAngularVel(bId2, REAL(1.22), 0.0, 0.0); + CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) ); + + dBodySetAngularVel(bId2, 0.0, REAL(2.33), 0.0); + CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) ); + + dBodySetAngularVel(bId2, 0.0, 0.0, REAL(5.55)); + CHECK_EQUAL(REAL(0.0), dJointGetPistonPositionRate (jId) ); + } + + + + struct Fixture_Simple_Hinge + { + Fixture_Simple_Hinge () + { + wId = dWorldCreate(); + + bId1 = dBodyCreate(wId); + dBodySetPosition(bId1, 0, -1, 0); + + bId2 = dBodyCreate(wId); + dBodySetPosition(bId2, 0, 1, 0); + + + jId = dJointCreateHinge(wId, 0); + + dJointAttach(jId, bId1, bId2); + } + + ~Fixture_Simple_Hinge() + { + dWorldDestroy(wId); + } + + dJointID jId; + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + }; + + // Test that it is possible to have joint without a body + TEST_FIXTURE(Fixture_Simple_Hinge, test_dJointAttach) + { + bool only_body1_OK = true; + try { + dJointAttach(jId, bId1, 0); + dWorldStep (wId, 1); + } + catch (...) { + only_body1_OK = false; + } + CHECK_EQUAL(true, only_body1_OK); + + bool only_body2_OK = true; + try { + dJointAttach(jId, 0, bId2); + dWorldStep (wId, 1); + } + catch (...) { + only_body2_OK = false; + } + CHECK_EQUAL(true, only_body2_OK); + + bool no_body_OK = true; + try { + dJointAttach(jId, 0, 0); + dWorldStep (wId, 1); + } + catch (...) { + no_body_OK = false; + } + CHECK_EQUAL(true, no_body_OK); + } + + + +} // End of SUITE(JointPiston) diff --git a/libs/ode-0.16.1/tests/joints/Makefile.am b/libs/ode-0.16.1/tests/joints/Makefile.am new file mode 100644 index 0000000..5b8f743 --- /dev/null +++ b/libs/ode-0.16.1/tests/joints/Makefile.am @@ -0,0 +1,21 @@ +AM_CPPFLAGS = -I$(srcdir)/../UnitTest++/src \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/ode/src + +check_LTLIBRARIES = libjoints.la + +libjoints_la_LDFLAGS = -static + +libjoints_la_SOURCES = \ + amotor.cpp \ + ball.cpp \ + dball.cpp \ + fixed.cpp \ + hinge.cpp \ + hinge2.cpp \ + piston.cpp \ + pr.cpp \ + pu.cpp \ + slider.cpp \ + universal.cpp diff --git a/libs/ode-0.16.1/tests/joints/Makefile.in b/libs/ode-0.16.1/tests/joints/Makefile.in new file mode 100644 index 0000000..edbb187 --- /dev/null +++ b/libs/ode-0.16.1/tests/joints/Makefile.in @@ -0,0 +1,638 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = tests/joints +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/ode/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +libjoints_la_LIBADD = +am_libjoints_la_OBJECTS = amotor.lo ball.lo dball.lo fixed.lo hinge.lo \ + hinge2.lo piston.lo pr.lo pu.lo slider.lo universal.lo +libjoints_la_OBJECTS = $(am_libjoints_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libjoints_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(libjoints_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +SOURCES = $(libjoints_la_SOURCES) +DIST_SOURCES = $(libjoints_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CCD_CFLAGS = @CCD_CFLAGS@ +CCD_LIBS = @CCD_LIBS@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBTOOL_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ +FGREP = @FGREP@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSTDCXX = @LIBSTDCXX@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ODE_PRECISION = @ODE_PRECISION@ +ODE_VERSION = @ODE_VERSION@ +ODE_VERSION_INFO = @ODE_VERSION_INFO@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WINDRES = @WINDRES@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = -I$(srcdir)/../UnitTest++/src \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/ode/src + +check_LTLIBRARIES = libjoints.la +libjoints_la_LDFLAGS = -static +libjoints_la_SOURCES = \ + amotor.cpp \ + ball.cpp \ + dball.cpp \ + fixed.cpp \ + hinge.cpp \ + hinge2.cpp \ + piston.cpp \ + pr.cpp \ + pu.cpp \ + slider.cpp \ + universal.cpp + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/joints/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/joints/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkLTLIBRARIES: + -test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES) + @list='$(check_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libjoints.la: $(libjoints_la_OBJECTS) $(libjoints_la_DEPENDENCIES) $(EXTRA_libjoints_la_DEPENDENCIES) + $(AM_V_CXXLD)$(libjoints_la_LINK) $(libjoints_la_OBJECTS) $(libjoints_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amotor.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ball.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dball.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fixed.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hinge.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hinge2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/piston.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pu.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slider.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/universal.Plo@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_LTLIBRARIES) +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkLTLIBRARIES clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ + clean-checkLTLIBRARIES clean-generic clean-libtool \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/tests/joints/amotor.cpp b/libs/ode-0.16.1/tests/joints/amotor.cpp new file mode 100644 index 0000000..0dc1c2d --- /dev/null +++ b/libs/ode-0.16.1/tests/joints/amotor.cpp @@ -0,0 +1,324 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ +//234567890123456789012345678901234567890123456789012345678901234567890123456789 +// 1 2 3 4 5 6 7 + +//////////////////////////////////////////////////////////////////////////////// +// This file create unit test for some of the functions found in: +// ode/src/joinst/fixed.cpp +// +// +//////////////////////////////////////////////////////////////////////////////// + +#include <UnitTest++.h> +#include <ode/ode.h> + +#include "config.h" +#include "../../ode/src/joints/amotor.h" + +const dReal tol = 1e-5; + +SUITE (TestdxJointAMotor) +{ + struct FixtureBase { + dWorldID world; + dBodyID body; + dJointID joint; + + FixtureBase() + { + world = dWorldCreate(); + body = dBodyCreate(world); + joint = dJointCreateAMotor(world, 0); + } + + ~FixtureBase() + { + dJointDestroy(joint); + dBodyDestroy(body); + dWorldDestroy(world); + } + }; + + + struct FixtureXUser: FixtureBase { + FixtureXUser() + { + // body only allowed to rotate around X axis + dBodySetFiniteRotationMode(body, 1); + dBodySetFiniteRotationAxis(body, 1, 0, 0); + dJointAttach(joint, body, 0); + dJointSetAMotorNumAxes(joint, 2); + dJointSetAMotorAxis(joint, 0, 2, 0, 1, 0); + dJointSetAMotorAxis(joint, 1, 2, 0, 0, 1); + dJointSetAMotorParam(joint, dParamVel, 0); + dJointSetAMotorParam(joint, dParamFMax, dInfinity); + dJointSetAMotorParam(joint, dParamVel2, 0); + dJointSetAMotorParam(joint, dParamFMax2, dInfinity); + } + }; + + TEST_FIXTURE(FixtureXUser, rotate_x) + { + const dReal h = 1; + const dReal v = 1; + dMatrix3 identity = {1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0}; + dBodySetRotation(body, identity); + dBodySetAngularVel(body, v, 0, 0); + dWorldQuickStep(world, h); + const dReal* rot = dBodyGetRotation(body); + CHECK_CLOSE(1, rot[0], tol); + CHECK_CLOSE(0, rot[4], tol); + CHECK_CLOSE(0, rot[8], tol); + + CHECK_CLOSE(0, rot[1], tol); + CHECK_CLOSE(dCos(v*h), rot[5], tol); + CHECK_CLOSE(dSin(v*h), rot[9], tol); + + CHECK_CLOSE(0, rot[2], tol); + CHECK_CLOSE(-dSin(v*h), rot[6], tol); + CHECK_CLOSE( dCos(v*h), rot[10], tol); + } + + TEST_FIXTURE(FixtureXUser, rotate_yz) + { + const dReal h = 1; + const dReal v = 1; + dMatrix3 identity = {1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0}; + dBodySetRotation(body, identity); + + dVector3 axis_y; + dJointGetAMotorAxis(joint, 0, axis_y); + CHECK_CLOSE(0, axis_y[0], tol); + CHECK_CLOSE(1, axis_y[1], tol); + CHECK_CLOSE(0, axis_y[2], tol); + + dVector3 axis_z; + dJointGetAMotorAxis(joint, 1, axis_z); + CHECK_CLOSE(0, axis_z[0], tol); + CHECK_CLOSE(0, axis_z[1], tol); + CHECK_CLOSE(1, axis_z[2], tol); + + dBodySetAngularVel(body, 0, v, v); + dWorldStep(world, h); + const dReal* rot = dBodyGetRotation(body); + CHECK_CLOSE(1, rot[0], tol); + CHECK_CLOSE(0, rot[4], tol); + CHECK_CLOSE(0, rot[8], tol); + + CHECK_CLOSE(0, rot[1], tol); + CHECK_CLOSE(1, rot[5], tol); + CHECK_CLOSE(0, rot[9], tol); + + CHECK_CLOSE(0, rot[2], tol); + CHECK_CLOSE(0, rot[6], tol); + CHECK_CLOSE(1, rot[10], tol); + } + + + TEST_FIXTURE(FixtureBase, sanity_check) + { + dMatrix3 R; + dRFromAxisAndAngle(R, 1, 1, 1, 10*M_PI/180); + dBodySetRotation(body, R); + + dVector3 res; + + dJointAttach(joint, body, 0); + dJointSetAMotorNumAxes(joint, 3); + CHECK_EQUAL(3, dJointGetAMotorNumAxes(joint)); + + // axes relative to world + dJointSetAMotorAxis(joint, 0, 0, 1, 0, 0); + dJointGetAMotorAxis(joint, 0, res); + CHECK_EQUAL(0, dJointGetAMotorAxisRel(joint, 0)); + CHECK_CLOSE(1, res[0], tol); + CHECK_CLOSE(0, res[1], tol); + CHECK_CLOSE(0, res[2], tol); + + dJointSetAMotorAxis(joint, 1, 0, 0, 1, 0); + dJointGetAMotorAxis(joint, 1, res); + CHECK_EQUAL(0, dJointGetAMotorAxisRel(joint, 1)); + CHECK_CLOSE(0, res[0], tol); + CHECK_CLOSE(1, res[1], tol); + CHECK_CLOSE(0, res[2], tol); + + dJointSetAMotorAxis(joint, 2, 0, 0, 0, 1); + dJointGetAMotorAxis(joint, 2, res); + CHECK_EQUAL(0, dJointGetAMotorAxisRel(joint, 2)); + CHECK_CLOSE(0, res[0], tol); + CHECK_CLOSE(0, res[1], tol); + CHECK_CLOSE(1, res[2], tol); + + // axes relative to body1 + dJointSetAMotorAxis(joint, 0, 1, 1, 0, 0); + dJointGetAMotorAxis(joint, 0, res); + CHECK_EQUAL(1, dJointGetAMotorAxisRel(joint, 0)); + CHECK_CLOSE(1, res[0], tol); + CHECK_CLOSE(0, res[1], tol); + CHECK_CLOSE(0, res[2], tol); + + dJointSetAMotorAxis(joint, 1, 1, 0, 1, 0); + dJointGetAMotorAxis(joint, 1, res); + CHECK_EQUAL(1, dJointGetAMotorAxisRel(joint, 1)); + CHECK_CLOSE(0, res[0], tol); + CHECK_CLOSE(1, res[1], tol); + CHECK_CLOSE(0, res[2], tol); + + dJointSetAMotorAxis(joint, 2, 1, 0, 0, 1); + dJointGetAMotorAxis(joint, 2, res); + CHECK_EQUAL(1, dJointGetAMotorAxisRel(joint, 2)); + CHECK_CLOSE(0, res[0], tol); + CHECK_CLOSE(0, res[1], tol); + CHECK_CLOSE(1, res[2], tol); + + // axes relative to body2 + dJointSetAMotorAxis(joint, 0, 2, 1, 0, 0); + dJointGetAMotorAxis(joint, 0, res); + CHECK_EQUAL(2, dJointGetAMotorAxisRel(joint, 0)); + CHECK_CLOSE(1, res[0], tol); + CHECK_CLOSE(0, res[1], tol); + CHECK_CLOSE(0, res[2], tol); + + dJointSetAMotorAxis(joint, 1, 2, 0, 1, 0); + dJointGetAMotorAxis(joint, 1, res); + CHECK_EQUAL(2, dJointGetAMotorAxisRel(joint, 1)); + CHECK_CLOSE(0, res[0], tol); + CHECK_CLOSE(1, res[1], tol); + CHECK_CLOSE(0, res[2], tol); + + dJointSetAMotorAxis(joint, 2, 2, 0, 0, 1); + dJointGetAMotorAxis(joint, 2, res); + CHECK_EQUAL(2, dJointGetAMotorAxisRel(joint, 2)); + CHECK_CLOSE(0, res[0], tol); + CHECK_CLOSE(0, res[1], tol); + CHECK_CLOSE(1, res[2], tol); + + // reverse attachment to force internal reversal + dJointAttach(joint, 0, body); + // axes relative to world + dJointSetAMotorAxis(joint, 0, 0, 1, 0, 0); + dJointGetAMotorAxis(joint, 0, res); + CHECK_EQUAL(0, dJointGetAMotorAxisRel(joint, 0)); + CHECK_CLOSE(1, res[0], tol); + CHECK_CLOSE(0, res[1], tol); + CHECK_CLOSE(0, res[2], tol); + + dJointSetAMotorAxis(joint, 1, 0, 0, 1, 0); + dJointGetAMotorAxis(joint, 1, res); + CHECK_EQUAL(0, dJointGetAMotorAxisRel(joint, 1)); + CHECK_CLOSE(0, res[0], tol); + CHECK_CLOSE(1, res[1], tol); + CHECK_CLOSE(0, res[2], tol); + + dJointSetAMotorAxis(joint, 2, 0, 0, 0, 1); + dJointGetAMotorAxis(joint, 2, res); + CHECK_EQUAL(0, dJointGetAMotorAxisRel(joint, 2)); + CHECK_CLOSE(0, res[0], tol); + CHECK_CLOSE(0, res[1], tol); + CHECK_CLOSE(1, res[2], tol); + + // axes relative to body1 + dJointSetAMotorAxis(joint, 0, 1, 1, 0, 0); + dJointGetAMotorAxis(joint, 0, res); + CHECK_EQUAL(1, dJointGetAMotorAxisRel(joint, 0)); + CHECK_CLOSE(1, res[0], tol); + CHECK_CLOSE(0, res[1], tol); + CHECK_CLOSE(0, res[2], tol); + + dJointSetAMotorAxis(joint, 1, 1, 0, 1, 0); + dJointGetAMotorAxis(joint, 1, res); + CHECK_EQUAL(1, dJointGetAMotorAxisRel(joint, 1)); + CHECK_CLOSE(0, res[0], tol); + CHECK_CLOSE(1, res[1], tol); + CHECK_CLOSE(0, res[2], tol); + + dJointSetAMotorAxis(joint, 2, 1, 0, 0, 1); + dJointGetAMotorAxis(joint, 2, res); + CHECK_EQUAL(1, dJointGetAMotorAxisRel(joint, 2)); + CHECK_CLOSE(0, res[0], tol); + CHECK_CLOSE(0, res[1], tol); + CHECK_CLOSE(1, res[2], tol); + + // axes relative to body2 + dJointSetAMotorAxis(joint, 0, 2, 1, 0, 0); + dJointGetAMotorAxis(joint, 0, res); + CHECK_EQUAL(2, dJointGetAMotorAxisRel(joint, 0)); + CHECK_CLOSE(1, res[0], tol); + CHECK_CLOSE(0, res[1], tol); + CHECK_CLOSE(0, res[2], tol); + + dJointSetAMotorAxis(joint, 1, 2, 0, 1, 0); + dJointGetAMotorAxis(joint, 1, res); + CHECK_EQUAL(2, dJointGetAMotorAxisRel(joint, 1)); + CHECK_CLOSE(0, res[0], tol); + CHECK_CLOSE(1, res[1], tol); + CHECK_CLOSE(0, res[2], tol); + + dJointSetAMotorAxis(joint, 2, 2, 0, 0, 1); + dJointGetAMotorAxis(joint, 2, res); + CHECK_EQUAL(2, dJointGetAMotorAxisRel(joint, 2)); + CHECK_CLOSE(0, res[0], tol); + CHECK_CLOSE(0, res[1], tol); + CHECK_CLOSE(1, res[2], tol); + } + + + struct FixtureXEuler : FixtureBase { + FixtureXEuler() + { + // body only allowed to rotate around X axis + dJointAttach(joint, 0, body); + dJointSetAMotorMode(joint, dAMotorEuler); + dJointSetAMotorAxis(joint, 0, 0, 1, 0, 0); + dJointSetAMotorAxis(joint, 2, 0, 0, 0, 1); + } + }; + + + TEST_FIXTURE(FixtureXEuler, check_axes) + { + // test patch #181 bug fix + dVector3 axis_x; + dJointGetAMotorAxis(joint, 0, axis_x); + CHECK_CLOSE(1, axis_x[0], tol); + CHECK_CLOSE(0, axis_x[1], tol); + CHECK_CLOSE(0, axis_x[2], tol); + + dVector3 axis_y; + dJointGetAMotorAxis(joint, 1, axis_y); + CHECK_CLOSE(0, axis_y[0], tol); + CHECK_CLOSE(1, axis_y[1], tol); + CHECK_CLOSE(0, axis_y[2], tol); + + dVector3 axis_z; + dJointGetAMotorAxis(joint, 2, axis_z); + CHECK_CLOSE(0, axis_z[0], tol); + CHECK_CLOSE(0, axis_z[1], tol); + CHECK_CLOSE(1, axis_z[2], tol); + } + +} // End of SUITE TestdxJointAMotor diff --git a/libs/ode-0.16.1/tests/joints/ball.cpp b/libs/ode-0.16.1/tests/joints/ball.cpp new file mode 100644 index 0000000..edbb243 --- /dev/null +++ b/libs/ode-0.16.1/tests/joints/ball.cpp @@ -0,0 +1,160 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ +//234567890123456789012345678901234567890123456789012345678901234567890123456789 +// 1 2 3 4 5 6 7 + +//////////////////////////////////////////////////////////////////////////////// +// This file create unit test for some of the functions found in: +// ode/src/joinst/ball.cpp +// +// +//////////////////////////////////////////////////////////////////////////////// + +#include <UnitTest++.h> +#include <ode/ode.h> + +#include "../../ode/src/config.h" +#include "../../ode/src/joints/ball.h" + + +using namespace std; + +SUITE (TestdxJointBall) +{ + // The 2 bodies are positionned at (-1, -2, -3), and (11, 22, 33) + // The bodis have rotation of 27deg around some axis. + // The joint is a Ball Joint + // Axis is along the X axis + // Anchor at (0, 0, 0) + struct dxJointBall_Fixture_B1_and_B2_At_Zero_Axis_Along_X { + dxJointBall_Fixture_B1_and_B2_At_Zero_Axis_Along_X() + { + wId = dWorldCreate(); + + for (int j=0; j<2; ++j) { + bId[j][0] = dBodyCreate (wId); + dBodySetPosition (bId[j][0], -1, -2, -3); + + bId[j][1] = dBodyCreate (wId); + dBodySetPosition (bId[j][1], 11, 22, 33); + + + dMatrix3 R; + dVector3 axis; // Random axis + + axis[0] = REAL(0.53); + axis[1] = -REAL(0.71); + axis[2] = REAL(0.43); + dNormalize3(axis); + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], + REAL(0.47123)); // 27deg + dBodySetRotation (bId[j][0], R); + + + axis[0] = REAL(1.2); + axis[1] = REAL(0.87); + axis[2] = -REAL(0.33); + dNormalize3(axis); + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], + REAL(0.47123)); // 27deg + dBodySetRotation (bId[j][1], R); + + jId[j] = dJointCreateBall (wId, 0); + dJointAttach (jId[j], bId[j][0], bId[j][1]); + } + } + + ~dxJointBall_Fixture_B1_and_B2_At_Zero_Axis_Along_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId[2][2]; + + + dJointID jId[2]; + }; + + // Rotate 2nd body 90deg around X then back to original position + // + // ^ ^ ^ + // | | => | <--- + // | | | + // B1 B2 B1 B2 + // + // Start with a Delta of 90deg + // ^ ^ ^ + // | <--- => | | + // | | | + // B1 B2 B1 B2 + TEST_FIXTURE (dxJointBall_Fixture_B1_and_B2_At_Zero_Axis_Along_X, + test_dJointSetBallAxisOffset_B2_90deg) { + + dVector3 anchor; + dJointGetBallAnchor(jId[1], anchor); + dJointSetBallAnchor(jId[1], anchor[0], anchor[1], anchor[2]); + + + for (int b=0; b<2; ++b) { + // Compare body b of the first joint with its equivalent on the + // second joint + const dReal *qA = dBodyGetQuaternion(bId[0][b]); + const dReal *qB = dBodyGetQuaternion(bId[1][b]); + CHECK_CLOSE (qA[0], qB[0], 1e-4); + CHECK_CLOSE (qA[1], qB[1], 1e-4); + CHECK_CLOSE (qA[2], qB[2], 1e-4); + CHECK_CLOSE (qA[3], qB[3], 1e-4); + } + + dWorldStep (wId,0.5); + dWorldStep (wId,0.5); + dWorldStep (wId,0.5); + dWorldStep (wId,0.5); + + for (int b=0; b<2; ++b) { + // Compare body b of the first joint with its equivalent on the + // second joint + const dReal *qA = dBodyGetQuaternion(bId[0][b]); + const dReal *qB = dBodyGetQuaternion(bId[1][b]); + CHECK_CLOSE (qA[0], qB[0], 1e-4); + CHECK_CLOSE (qA[1], qB[1], 1e-4); + CHECK_CLOSE (qA[2], qB[2], 1e-4); + CHECK_CLOSE (qA[3], qB[3], 1e-4); + + + const dReal *posA = dBodyGetPosition(bId[0][b]); + const dReal *posB = dBodyGetPosition(bId[1][b]); + CHECK_CLOSE (posA[0], posB[0], 1e-4); + CHECK_CLOSE (posA[1], posB[1], 1e-4); + CHECK_CLOSE (posA[2], posB[2], 1e-4); + CHECK_CLOSE (posA[3], posB[3], 1e-4); + } + } + + + + +} // End of SUITE TestdxJointBall + + diff --git a/libs/ode-0.16.1/tests/joints/dball.cpp b/libs/ode-0.16.1/tests/joints/dball.cpp new file mode 100644 index 0000000..0e82c8d --- /dev/null +++ b/libs/ode-0.16.1/tests/joints/dball.cpp @@ -0,0 +1,81 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ +//234567890123456789012345678901234567890123456789012345678901234567890123456789 +// 1 2 3 4 5 6 7 + +//////////////////////////////////////////////////////////////////////////////// +// This file create unit test for some of the functions found in: +// ode/src/joinst/dball.cpp +// +// +//////////////////////////////////////////////////////////////////////////////// + +#include <UnitTest++.h> +#include <ode/ode.h> + +#include "../../ode/src/config.h" + + +using namespace std; + +SUITE (TestdxJointDBall) +{ + struct SimpleFixture { + dWorldID w; + dBodyID b1, b2; + dJointID j; + + SimpleFixture() : + w(dWorldCreate()), + b1(dBodyCreate(w)), + b2(dBodyCreate(w)), + j(dJointCreateDBall(w, 0)) + { + dJointAttach(j, b1, b2); + } + + ~SimpleFixture() + { + dJointDestroy(j); + dBodyDestroy(b1); + dBodyDestroy(b2); + dWorldDestroy(w); + } + }; + + TEST_FIXTURE(SimpleFixture, testTargetDistance) + { + dBodySetPosition(b1, -1, -2, -3); + dBodySetPosition(b2, 3, 5, 7); + dJointAttach(j, b1, b2); // this recomputes the deduced target distance + CHECK_CLOSE(dJointGetDBallDistance(j), dSqrt(REAL(165.0)), 1e-4); + + // moving body should not change target distance + dBodySetPosition(b1, 2,3,4); + CHECK_CLOSE(dJointGetDBallDistance(j), dSqrt(REAL(165.0)), 1e-4); + + // setting target distance manually should override the deduced one + dJointSetDBallDistance(j, REAL(6.0)); + CHECK_EQUAL(dJointGetDBallDistance(j), REAL(6.0)); + } + +} diff --git a/libs/ode-0.16.1/tests/joints/fixed.cpp b/libs/ode-0.16.1/tests/joints/fixed.cpp new file mode 100644 index 0000000..c069073 --- /dev/null +++ b/libs/ode-0.16.1/tests/joints/fixed.cpp @@ -0,0 +1,149 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ +//234567890123456789012345678901234567890123456789012345678901234567890123456789 +// 1 2 3 4 5 6 7 + +//////////////////////////////////////////////////////////////////////////////// +// This file create unit test for some of the functions found in: +// ode/src/joinst/fixed.cpp +// +// +//////////////////////////////////////////////////////////////////////////////// + +#include <UnitTest++.h> +#include <ode/ode.h> + +#include "../../ode/src/config.h" +#include "../../ode/src/joints/fixed.h" + +SUITE (TestdxJointFixed) +{ + struct dxJointFixed_Fixture_1 + { + dxJointFixed_Fixture_1() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate (wId); + dBodySetPosition (bId1, 0, -1, 0); + + bId2 = dBodyCreate (wId); + dBodySetPosition (bId2, 0, 1, 0); + + jId = dJointCreateFixed (wId, 0); + joint = (dxJointFixed*) jId; + + + dJointAttach (jId, bId1, bId2); + } + + ~dxJointFixed_Fixture_1() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + + dJointID jId; + dxJointFixed* joint; + }; + + TEST_FIXTURE (dxJointFixed_Fixture_1, test_dJointSetFixed) + { + // the 2 bodies are align + dJointSetFixed (jId); + CHECK_CLOSE (joint->qrel[0], 1.0, 1e-4); + CHECK_CLOSE (joint->qrel[1], 0.0, 1e-4); + CHECK_CLOSE (joint->qrel[2], 0.0, 1e-4); + CHECK_CLOSE (joint->qrel[3], 0.0, 1e-4); + + dMatrix3 R; + // Rotate 2nd body 90deg around X + dBodySetPosition (bId2, 0, 0, 1); + dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0); + dBodySetRotation (bId2, R); + + dJointSetFixed (jId); + CHECK_CLOSE (joint->qrel[0], 0.70710678118654757, 1e-4); + CHECK_CLOSE (joint->qrel[1], 0.70710678118654757, 1e-4); + CHECK_CLOSE (joint->qrel[2], 0.0, 1e-4); + CHECK_CLOSE (joint->qrel[3], 0.0, 1e-4); + + + // Rotate 2nd body -90deg around X + dBodySetPosition (bId2, 0, 0, -1); + dRFromAxisAndAngle (R, 1, 0, 0, -M_PI/2.0); + dBodySetRotation (bId2, R); + + dJointSetFixed (jId); + CHECK_CLOSE (joint->qrel[0], 0.70710678118654757, 1e-4); + CHECK_CLOSE (joint->qrel[1], -0.70710678118654757, 1e-4); + CHECK_CLOSE (joint->qrel[2], 0.0, 1e-4); + CHECK_CLOSE (joint->qrel[3], 0.0, 1e-4); + + + // Rotate 2nd body 90deg around Z + dBodySetPosition (bId2, 0, 1, 0); + dRFromAxisAndAngle (R, 0, 0, 1, M_PI/2.0); + dBodySetRotation (bId2, R); + + dJointSetFixed (jId); + CHECK_CLOSE (joint->qrel[0], 0.70710678118654757, 1e-4); + CHECK_CLOSE (joint->qrel[1], 0.0, 1e-4); + CHECK_CLOSE (joint->qrel[2], 0.0, 1e-4); + CHECK_CLOSE (joint->qrel[3], 0.70710678118654757, 1e-4); + + + // Rotate 2nd body 45deg around Y + dBodySetPosition (bId2, 0, 1, 0); + dRFromAxisAndAngle (R, 0, 1, 0, M_PI/4.0); + dBodySetRotation (bId2, R); + + dJointSetFixed (jId); + CHECK_CLOSE (joint->qrel[0], 0.92387953251128674, 1e-4); + CHECK_CLOSE (joint->qrel[1], 0.0, 1e-4); + CHECK_CLOSE (joint->qrel[2], 0.38268343236508984, 1e-4); + CHECK_CLOSE (joint->qrel[3], 0.0, 1e-4); + + // Rotate in a strange manner + // Both bodies at origin + dRFromEulerAngles (R, REAL(0.23), REAL(3.1), REAL(-0.73)); + dBodySetPosition (bId1, 0, 0, 0); + dBodySetRotation (bId1, R); + + dRFromEulerAngles (R, REAL(-0.57), REAL(1.49), REAL(0.81)); + dBodySetPosition (bId2, 0, 0, 0); + dBodySetRotation (bId2, R); + + dJointSetFixed (jId); + CHECK_CLOSE (joint->qrel[0], -0.25526036263124319, 1e-4); + CHECK_CLOSE (joint->qrel[1], 0.28434861188441968, 1e-4); + CHECK_CLOSE (joint->qrel[2], -0.65308047160141625, 1e-4); + CHECK_CLOSE (joint->qrel[3], 0.65381489108282143, 1e-4); + } + + +} // End of SUITE TestdxJointFixed diff --git a/libs/ode-0.16.1/tests/joints/hinge.cpp b/libs/ode-0.16.1/tests/joints/hinge.cpp new file mode 100644 index 0000000..f715a6e --- /dev/null +++ b/libs/ode-0.16.1/tests/joints/hinge.cpp @@ -0,0 +1,928 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ +//234567890123456789012345678901234567890123456789012345678901234567890123456789 +// 1 2 3 4 5 6 7 + +//////////////////////////////////////////////////////////////////////////////// +// This file create unit test for some of the functions found in: +// ode/src/joinst/hinge.cpp +// +// +//////////////////////////////////////////////////////////////////////////////// + +#include <UnitTest++.h> +#include <ode/ode.h> + +#include "../../ode/src/config.h" +#include "../../ode/src/joints/hinge.h" + +SUITE (TestdxJointHinge) +{ + // The 2 bodies are positionned at (0, 0, 0), with no rotation + // The joint is an Hinge Joint + // Axis is along the X axis + // Anchor at (0, 0, 0) + // ^Y + // | + // | + // | + // | + // | + // Z <---- . (X going out of the page) + struct dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Along_X { + dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Along_X() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate (wId); + dBodySetPosition (bId1, 0, 0, 0); + + bId2 = dBodyCreate (wId); + dBodySetPosition (bId2, 0, 0, 0); + + jId = dJointCreateHinge (wId, 0); + joint = (dxJointHinge*) jId; + + + dJointAttach (jId, bId1, bId2); + dJointSetHingeAnchor (jId, 0, 0, 0); + + axis[0] = 1; + axis[1] = 0; + axis[2] = 0; + } + + ~dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Along_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + + dJointID jId; + dxJointHinge* joint; + + dVector3 axis; + }; + + // Rotate 2nd body 90deg around X then back to original position + // + // ^ ^ ^ + // | | => | <--- + // | | | + // B1 B2 B1 B2 + // + // Start with a Delta of 90deg + // ^ ^ ^ + // | <--- => | | + // | | | + // B1 B2 B1 B2 + TEST_FIXTURE (dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Along_X, + test_dJointSetHingeAxisOffset_B2_90deg) { + dMatrix3 R; + + CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0); + dBodySetRotation (bId2, R); + + CHECK_CLOSE (-M_PI/2.0, dJointGetHingeAngle (jId), 1e-4); + + dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], -M_PI/2.0); + CHECK_CLOSE (-M_PI/2.0, dJointGetHingeAngle (jId), 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, 0); + dBodySetRotation (bId2, R); + + CHECK_CLOSE (0.0, dJointGetHingeAngle (jId), 1e-4); + } + + + // Rotate 2nd body -90deg around X then back to original position + // + // ^ ^ ^ + // | | => | ---> + // | | | + // B1 B2 B1 B2 + // + // Start with a Delta of 90deg + // ^ ^ ^ + // | ---> => | | + // | | | + // B1 B2 B1 B2 + TEST_FIXTURE (dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Along_X, + test_dJointSetHingeAxisOffset_B2_Minus90deg) { + dMatrix3 R; + + dJointSetHingeAxis (jId, axis[0], axis[1], axis[2]); + + CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, -M_PI/2.0); + dBodySetRotation (bId2, R); + + CHECK_CLOSE (M_PI/2.0, dJointGetHingeAngle (jId), 1e-4); + + dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], M_PI/2.0); + CHECK_CLOSE (M_PI/2.0, dJointGetHingeAngle (jId), 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, 0); + dBodySetRotation (bId2, R); + + CHECK_CLOSE (0.0, dJointGetHingeAngle (jId), 1e-4); + } + + + // Rotate 1st body 0.23rad around X then back to original position + // + // ^ ^ ^ ^ + // | | => \ | + // | | \ | + // B1 B2 B1 B2 + // + // Start with a Delta of 0.23rad + // ^ ^ ^ ^ + // \ | => | | + // \ | | | + // B1 B2 B1 B2 + TEST_FIXTURE (dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Along_X, + test_dJointSetHingeAxisOffset_B1_0_23rad) { + dMatrix3 R; + + dJointSetHingeAxis (jId, axis[0], axis[1], axis[2]); + + CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, REAL(0.23) ); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (REAL(0.23), dJointGetHingeAngle (jId), 1e-4); + + dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], REAL(0.23)); + CHECK_CLOSE (REAL(0.23), dJointGetHingeAngle (jId), 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, 0); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (0.0, dJointGetHingeAngle (jId), 1e-4); + } + + + // Rotate 1st body -0.23rad around Z then back to original position + // + // ^ ^ ^ ^ + // | | => / | + // | | / | + // B1 B2 B1 B2 + // + // Start with a Delta of 0.23rad + // ^ ^ ^ ^ + // / | => | | + // / | | | + // B1 B2 B1 B2 + TEST_FIXTURE (dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Along_X, + test_dJointSetHingeAxisOffset_B1_Minus0_23rad) { + dMatrix3 R; + + dJointSetHingeAxis (jId, axis[0], axis[1], axis[2]); + + CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, -REAL(0.23)); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (-REAL(0.23), dJointGetHingeAngle (jId), 1e-4); + + dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], -REAL(0.23)); + CHECK_CLOSE (-REAL(0.23), dJointGetHingeAngle (jId), 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, 0); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (0.0, dJointGetHingeAngle (jId), 1e-4); + } + + + // The 2 bodies are positionned at (0, 0, 0), with no rotation + // The joint is an Hinge Joint. + // Axis in the inverse direction of the X axis + // Anchor at (0, 0, 0) + // ^Y + // | + // | + // | + // | + // | + // Z <---- x (X going out of the page) + struct dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Inverse_of_X { + dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Inverse_of_X() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate (wId); + dBodySetPosition (bId1, 0, -1, 0); + + bId2 = dBodyCreate (wId); + dBodySetPosition (bId2, 0, 1, 0); + + jId = dJointCreateHinge (wId, 0); + joint = (dxJointHinge*) jId; + + + dJointAttach (jId, bId1, bId2); + dJointSetHingeAnchor (jId, 0, 0, 0); + + axis[0] = -1; + axis[1] = 0; + axis[2] = 0; + } + + ~dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Inverse_of_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + + dJointID jId; + dxJointHinge* joint; + + dVector3 axis; + }; + + // Rotate 2nd body 90deg around X then back to original position + // + // ^ ^ ^ + // | | => | <--- + // | | | + // B1 B2 B1 B2 + // + // Start with a Delta of 90deg + // ^ ^ ^ + // | <--- => | | + // | | | + // B1 B2 B1 B2 + TEST_FIXTURE (dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetHingeAxisOffset_B2_90Deg) { + dMatrix3 R; + + dJointSetHingeAxis (jId, axis[0], axis[1], axis[2]); + + CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0); + dBodySetRotation (bId2, R); + + CHECK_CLOSE (M_PI/2.0, dJointGetHingeAngle (jId), 1e-4); + + dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], M_PI/2.0); + CHECK_CLOSE (M_PI/2.0, dJointGetHingeAngle (jId), 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, 0); + dBodySetRotation (bId2, R); + + CHECK_CLOSE (0.0, dJointGetHingeAngle (jId), 1e-4); + } + + + // Rotate 2nd body -90deg around X then back to original position + // + // ^ ^ ^ + // | | => | ---> + // | | | + // B1 B2 B1 B2 + // + // Start with a Delta of 90deg + // ^ ^ ^ + // | ---> => | | + // | | | + // B1 B2 B1 B2 + TEST_FIXTURE (dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetHingeAxisOffset_B2_Minus90Deg) { + dMatrix3 R; + + dJointSetHingeAxis (jId, axis[0], axis[1], axis[2]); + + CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, -M_PI/2.0); + dBodySetRotation (bId2, R); + + CHECK_CLOSE (-M_PI/2.0, dJointGetHingeAngle (jId), 1e-4); + + dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], -M_PI/2.0); + CHECK_CLOSE (-M_PI/2.0, dJointGetHingeAngle (jId), 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, 0); + dBodySetRotation (bId2, R); + + CHECK_CLOSE (0.0, dJointGetHingeAngle (jId), 1e-4); + } + + + // Rotate 1st body 0.23rad around X then back to original position + // + // ^ ^ ^ ^ + // | | => \ | + // | | \ | + // B1 B2 B1 B2 + // + // Start with a Delta of 0.23rad + // ^ ^ ^ ^ + // \ | => | | + // \ | | | + // B1 B2 B1 B2 + TEST_FIXTURE (dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetHingeAxisOffset_B1_0_23rad) { + dMatrix3 R; + + dJointSetHingeAxis (jId, axis[0], axis[1], axis[2]); + + CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, REAL(0.23)); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (-REAL(0.23), dJointGetHingeAngle (jId), 1e-4); + + dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], -REAL(0.23)); + CHECK_CLOSE (-REAL(0.23), dJointGetHingeAngle (jId), 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, 0); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (0.0, dJointGetHingeAngle (jId), 1e-4); + } + + + // Rotate 2nd body -0.23rad around Z then back to original position + // + // ^ ^ ^ ^ + // | | => / | + // | | / | + // B1 B2 B1 B2 + // + // Start with a Delta of 0.23rad + // ^ ^ ^ ^ + // / | => | | + // / | | | + // B1 B2 B1 B2 + TEST_FIXTURE (dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetHingeAxisOffset_B1_Minus0_23rad) { + dMatrix3 R; + + dJointSetHingeAxis (jId, axis[0], axis[1], axis[2]); + + CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, -REAL(0.23)); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (REAL(0.23), dJointGetHingeAngle (jId), 1e-4); + + dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], REAL(0.23)); + CHECK_CLOSE (REAL(0.23), dJointGetHingeAngle (jId), 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, 0); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (0.0, dJointGetHingeAngle (jId), 1e-4); + } + + + // Only one body body1 at (0,0,0) + // The joint is an Hinge Joint. + // Axis is along the X axis + // Anchor at (0, 0, 0) + // + // ^Y + // | + // | + // | + // | + // | + // Z <-- X + struct dxJointHinge_Fixture_B1_At_Zero_Axis_Along_X { + dxJointHinge_Fixture_B1_At_Zero_Axis_Along_X() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate (wId); + dBodySetPosition (bId1, 0, 0, 0); + + jId = dJointCreateHinge (wId, 0); + joint = (dxJointHinge*) jId; + + + dJointAttach (jId, bId1, NULL); + dJointSetHingeAnchor (jId, 0, 0, 0); + + axis[0] = 1; + axis[1] = 0; + axis[2] = 0; + } + + ~dxJointHinge_Fixture_B1_At_Zero_Axis_Along_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1; + + + dJointID jId; + dxJointHinge* joint; + + dVector3 axis; + }; + + // Rotate B1 by 90deg around X then back to original position + // + // ^ + // | => <--- + // | + // B1 B1 + // + // Start with a Delta of 90deg + // ^ + // <--- => | + // | + // B1 B1 + TEST_FIXTURE (dxJointHinge_Fixture_B1_At_Zero_Axis_Along_X, + test_dJointSetHingeAxisOffset_1Body_B1_90Deg) { + dMatrix3 R; + + dJointSetHingeAxis (jId, axis[0], axis[1], axis[2]); + + CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (M_PI/2.0, dJointGetHingeAngle (jId), 1e-4); + + dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], M_PI/2.0); + CHECK_CLOSE (M_PI/2.0, dJointGetHingeAngle (jId), 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, 0); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (0, dJointGetHingeAngle (jId), 1e-4); + } + + // Rotate B1 by -0.23rad around X then back to original position + // + // ^ ^ + // | => / + // | / + // B1 B1 + // + // Start with a Delta of -0.23rad + // ^ ^ + // / => | + // / | + // B1 B1 + TEST_FIXTURE (dxJointHinge_Fixture_B1_At_Zero_Axis_Along_X, + test_dJointSetHingeAxisOffset_1Body_B1_Minus0_23rad) { + dMatrix3 R; + + dJointSetHingeAxis (jId, axis[0], axis[1], axis[2]); + + CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, -REAL(0.23)); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (-REAL(0.23), dJointGetHingeAngle (jId), 1e-4); + + dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], -REAL(0.23)); + CHECK_CLOSE (-REAL(0.23), dJointGetHingeAngle (jId), 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, 0); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (0, dJointGetHingeAngle (jId), 1e-4); + } + + + + // Only one body body1 at (0,0,0) + // The joint is an Hinge Joint. + // Axis the inverse of the X axis + // Anchor at (0, 0, 0) + // + // ^Y + // | + // | + // | + // | + // | + // Z <-- X + struct dxJointHinge_Fixture_B1_At_Zero_Axis_Inverse_of_X { + dxJointHinge_Fixture_B1_At_Zero_Axis_Inverse_of_X() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate (wId); + dBodySetPosition (bId1, 0, 0, 0); + + jId = dJointCreateHinge (wId, 0); + joint = (dxJointHinge*) jId; + + + dJointAttach (jId, bId1, NULL); + dJointSetHingeAnchor (jId, 0, 0, 0); + + axis[0] = -1; + axis[1] = 0; + axis[2] = 0; + } + + ~dxJointHinge_Fixture_B1_At_Zero_Axis_Inverse_of_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1; + + + dJointID jId; + dxJointHinge* joint; + + dVector3 axis; + }; + + // Rotate B1 by 90deg around X then back to original position + // + // ^ + // | => <--- + // | + // B1 B1 + // + // Start with a Delta of 90deg + // ^ + // <--- => | + // | + // B1 B1 + TEST_FIXTURE (dxJointHinge_Fixture_B1_At_Zero_Axis_Inverse_of_X, + test_dJointSetHingeAxisOffset_1Body_B1_90Deg) { + dMatrix3 R; + + dJointSetHingeAxis (jId, axis[0], axis[1], axis[2]); + + CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (-M_PI/2.0, dJointGetHingeAngle (jId), 1e-4); + + dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], -M_PI/2.0); + CHECK_CLOSE (-M_PI/2.0, dJointGetHingeAngle (jId), 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, 0); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (0, dJointGetHingeAngle (jId), 1e-4); + } + + // Rotate B1 by -0.23rad around X then back to original position + // + // ^ ^ + // | => / + // | / + // B1 B1 + // + // Start with a Delta of -0.23rad + // ^ ^ + // / => | + // / | + // B1 B1 + TEST_FIXTURE (dxJointHinge_Fixture_B1_At_Zero_Axis_Inverse_of_X, + test_dJointSetHingeAxisOffset_1Body_B1_Minus0_23rad) { + dMatrix3 R; + + dJointSetHingeAxis (jId, axis[0], axis[1], axis[2]); + + CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, -REAL(0.23)); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (REAL(0.23), dJointGetHingeAngle (jId), 1e-4); + + dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], REAL(0.23)); + CHECK_CLOSE (REAL(0.23), dJointGetHingeAngle (jId), 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, 0); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (0, dJointGetHingeAngle (jId), 1e-4); + } + + + + + + // Only one body body2 at (0,0,0) + // The joint is an Hinge Joint. + // Axis is along the X axis + // Anchor at (0, 0, 0) + // + // ^Y + // | + // | + // | + // | + // | + // Z <-- X + struct dxJointHinge_Fixture_B2_At_Zero_Axis_Along_X { + dxJointHinge_Fixture_B2_At_Zero_Axis_Along_X() + { + wId = dWorldCreate(); + + bId2 = dBodyCreate (wId); + dBodySetPosition (bId2, 0, 0, 0); + + jId = dJointCreateHinge (wId, 0); + joint = (dxJointHinge*) jId; + + + dJointAttach (jId, NULL, bId2); + dJointSetHingeAnchor (jId, 0, 0, 0); + + axis[0] = 1; + axis[1] = 0; + axis[2] = 0; + } + + ~dxJointHinge_Fixture_B2_At_Zero_Axis_Along_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId2; + + + dJointID jId; + dxJointHinge* joint; + + dVector3 axis; + }; + + // Rotate B2 by 90deg around X then back to original position + // + // ^ + // | => <--- + // | + // B2 B2 + // + // Start with a Delta of 90deg + // ^ + // <--- => | + // | + // B2 B2 + TEST_FIXTURE (dxJointHinge_Fixture_B2_At_Zero_Axis_Along_X, + test_dJointSetHingeAxisOffset_1Body_B2_90Deg) { + dMatrix3 R; + + dJointSetHingeAxis (jId, axis[0], axis[1], axis[2]); + + CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0); + dBodySetRotation (bId2, R); + + CHECK_CLOSE (-M_PI/2.0, dJointGetHingeAngle (jId), 1e-4); + + dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], -M_PI/2.0); + CHECK_CLOSE (-M_PI/2.0, dJointGetHingeAngle (jId), 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, 0); + dBodySetRotation (bId2, R); + + CHECK_CLOSE (0, dJointGetHingeAngle (jId), 1e-4); + } + + // Rotate B2 by -0.23rad around X then back to original position + // + // ^ ^ + // | => / + // | / + // B2 B2 + // + // Start with a Delta of -0.23rad + // ^ ^ + // / => | + // / | + // B2 B2 + TEST_FIXTURE (dxJointHinge_Fixture_B2_At_Zero_Axis_Along_X, + test_dJointSetHingeAxisOffset_1Body_B2_Minus0_23rad) { + dMatrix3 R; + + dJointSetHingeAxis (jId, axis[0], axis[1], axis[2]); + + CHECK_CLOSE (dJointGetHingeAngle (jId), 0.0, 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, -REAL(0.23)); + dBodySetRotation (bId2, R); + + CHECK_CLOSE (REAL(0.23), dJointGetHingeAngle (jId), 1e-4); + + dJointSetHingeAxisOffset (jId, axis[0], axis[1], axis[2], REAL(0.23)); + CHECK_CLOSE (REAL(0.23), dJointGetHingeAngle (jId), 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, 0); + dBodySetRotation (bId2, R); + + CHECK_CLOSE (0, dJointGetHingeAngle (jId), 1e-4); + } + + + + // Create 2 bodies attached by a Hinge joint + // Axis is along the X axis (Default value + // Anchor at (0, 0, 0) (Default value) + // + // ^Y + // | + // * Body2 + // | + // | + // Body1 | + // * Z--------> + struct dxJointHinge_Test_Initialization { + dxJointHinge_Test_Initialization() + { + wId = dWorldCreate(); + + // Remove gravity to have the only force be the force of the joint + dWorldSetGravity(wId, 0,0,0); + + for (int j=0; j<2; ++j) { + bId[j][0] = dBodyCreate (wId); + dBodySetPosition (bId[j][0], -1, -2, -3); + + bId[j][1] = dBodyCreate (wId); + dBodySetPosition (bId[j][1], 11, 22, 33); + + + dMatrix3 R; + dVector3 axis; // Random axis + + axis[0] = REAL(0.53); + axis[1] = -REAL(0.71); + axis[2] = REAL(0.43); + dNormalize3(axis); + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], + REAL(0.47123)); // 27deg + dBodySetRotation (bId[j][0], R); + + + axis[0] = REAL(1.2); + axis[1] = REAL(0.87); + axis[2] = -REAL(0.33); + dNormalize3(axis); + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], + REAL(0.47123)); // 27deg + dBodySetRotation (bId[j][1], R); + + jId[j] = dJointCreateHinge (wId, 0); + dJointAttach (jId[j], bId[j][0], bId[j][1]); + // dJointSetHingeParam(jId[j], dParamLoStop, 1); + // dJointSetHingeParam(jId[j], dParamHiStop, 2); + // dJointSetHingeParam(jId[j], dParamFMax, 200); + } + } + + ~dxJointHinge_Test_Initialization() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId[2][2]; + + + dJointID jId[2]; + + }; + + + // Test if setting a Hinge with its default values + // will behave the same as a default Hinge joint + TEST_FIXTURE (dxJointHinge_Test_Initialization, + test_Hinge_Initialization) { + using namespace std; + + dVector3 axis; + dJointGetHingeAxis(jId[1], axis); + dJointSetHingeAxis(jId[1], axis[0], axis[1], axis[2]); + + + dVector3 anchor; + dJointGetHingeAnchor(jId[1], anchor); + dJointSetHingeAnchor(jId[1], anchor[0], anchor[1], anchor[2]); + + + for (int b=0; b<2; ++b) { + // Compare body b of the first joint with its equivalent on the + // second joint + const dReal *qA = dBodyGetQuaternion(bId[0][b]); + const dReal *qB = dBodyGetQuaternion(bId[1][b]); + CHECK_CLOSE (qA[0], qB[0], 1e-6); + CHECK_CLOSE (qA[1], qB[1], 1e-6); + CHECK_CLOSE (qA[2], qB[2], 1e-6); + CHECK_CLOSE (qA[3], qB[3], 1e-6); + } + + dWorldStep (wId,0.5); + dWorldStep (wId,0.5); + dWorldStep (wId,0.5); + dWorldStep (wId,0.5); + + for (int b=0; b<2; ++b) { + // Compare body b of the first joint with its equivalent on the + // second joint + const dReal *qA = dBodyGetQuaternion(bId[0][b]); + const dReal *qB = dBodyGetQuaternion(bId[1][b]); + CHECK_CLOSE (qA[0], qB[0], 1e-6); + CHECK_CLOSE (qA[1], qB[1], 1e-6); + CHECK_CLOSE (qA[2], qB[2], 1e-6); + CHECK_CLOSE (qA[3], qB[3], 1e-6); + + + const dReal *posA = dBodyGetPosition(bId[0][b]); + const dReal *posB = dBodyGetPosition(bId[1][b]); + CHECK_CLOSE (posA[0], posB[0], 1e-6); + CHECK_CLOSE (posA[1], posB[1], 1e-6); + CHECK_CLOSE (posA[2], posB[2], 1e-6); + CHECK_CLOSE (posA[3], posB[3], 1e-6); + } + } + + + TEST_FIXTURE(dxJointHinge_Fixture_B1_and_B2_At_Zero_Axis_Along_X, + test_Hinge_dParamVel) + { + const dReal targetvel = 100; + const dReal tolerance = targetvel * +#ifdef dSINGLE + 1e-2 +#else + 1e-6 +#endif + ; + + dJointSetHingeParam(jId, dParamFMax, dInfinity); + dJointSetHingeParam(jId, dParamVel, targetvel); + + dWorldStep(wId, 0.001); + + const dReal *v1 = dBodyGetAngularVel(bId1); + const dReal *v2 = dBodyGetAngularVel(bId2); + dVector3 rvel = { v1[0]-v2[0], v1[1]-v2[1], v1[2]-v2[2] }; + CHECK_CLOSE(rvel[0], targetvel, tolerance); + CHECK_CLOSE(rvel[1], 0, tolerance); + CHECK_CLOSE(rvel[2], 0, tolerance); + } + + + +} // End of SUITE TestdxJointHinge + + diff --git a/libs/ode-0.16.1/tests/joints/hinge2.cpp b/libs/ode-0.16.1/tests/joints/hinge2.cpp new file mode 100644 index 0000000..3f9007c --- /dev/null +++ b/libs/ode-0.16.1/tests/joints/hinge2.cpp @@ -0,0 +1,167 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ +//234567890123456789012345678901234567890123456789012345678901234567890123456789 +// 1 2 3 4 5 6 7 + +//////////////////////////////////////////////////////////////////////////////// +// This file create unit test for some of the functions found in: +// ode/src/joinst/hinge2.cpp +// +// +//////////////////////////////////////////////////////////////////////////////// + +#include <UnitTest++.h> +#include <ode/ode.h> + +#include "../../ode/src/config.h" +#include "../../ode/src/joints/hinge2.h" + + +using namespace std; + +SUITE (TestdxJointHinge2) +{ + // The 2 bodies are positionned at (-1, -2, -3), and (11, 22, 33) + // The bodis have rotation of 27deg around some axis. + // The joint is a Hinge2 Joint + // Axis is along the X axis + // Anchor at (0, 0, 0) + struct dxJointHinge2_Fixture_B1_and_B2_At_Zero_Axis_Along_X { + dxJointHinge2_Fixture_B1_and_B2_At_Zero_Axis_Along_X() + { + wId = dWorldCreate(); + + for (int j=0; j<2; ++j) { + bId[j][0] = dBodyCreate (wId); + dBodySetPosition (bId[j][0], -1, -2, -3); + + bId[j][1] = dBodyCreate (wId); + dBodySetPosition (bId[j][1], 11, 22, 33); + + + dMatrix3 R; + dVector3 axis; // Random axis + + axis[0] = REAL(0.53); + axis[1] = -REAL(0.71); + axis[2] = REAL(0.43); + dNormalize3(axis); + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], + REAL(0.47123)); // 27deg + dBodySetRotation (bId[j][0], R); + + + axis[0] = REAL(1.2); + axis[1] = REAL(0.87); + axis[2] = -REAL(0.33); + dNormalize3(axis); + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], + REAL(0.47123)); // 27deg + dBodySetRotation (bId[j][1], R); + + jId[j] = dJointCreateHinge2 (wId, 0); + dJointAttach (jId[j], bId[j][0], bId[j][1]); + } + } + + ~dxJointHinge2_Fixture_B1_and_B2_At_Zero_Axis_Along_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId[2][2]; + + + dJointID jId[2]; + }; + + // Rotate 2nd body 90deg around X then back to original position + // + // ^ ^ ^ + // | | => | <--- + // | | | + // B1 B2 B1 B2 + // + // Start with a Delta of 90deg + // ^ ^ ^ + // | <--- => | | + // | | | + // B1 B2 B1 B2 + TEST_FIXTURE (dxJointHinge2_Fixture_B1_and_B2_At_Zero_Axis_Along_X, + test_dJointSetHinge2AxisOffset_B2_90deg) { + + dVector3 anchor; + dJointGetHinge2Anchor(jId[1], anchor); + dJointSetHinge2Anchor(jId[1], anchor[0], anchor[1], anchor[2]); + + dVector3 axis1, axis2; + dJointGetHinge2Axis1(jId[1], axis1); + dJointGetHinge2Axis2(jId[1], axis2); + dJointSetHinge2Axes(jId[1], axis1, axis2); + dJointSetHinge2Axes(jId[1], axis1, NULL); + dJointSetHinge2Axes(jId[1], NULL, axis2); + + + for (int b=0; b<2; ++b) { + // Compare body b of the first joint with its equivalent on the + // second joint + const dReal *qA = dBodyGetQuaternion(bId[0][b]); + const dReal *qB = dBodyGetQuaternion(bId[1][b]); + CHECK_CLOSE (qA[0], qB[0], 1e-4); + CHECK_CLOSE (qA[1], qB[1], 1e-4); + CHECK_CLOSE (qA[2], qB[2], 1e-4); + CHECK_CLOSE (qA[3], qB[3], 1e-4); + } + + dWorldStep (wId,0.5); + dWorldStep (wId,0.5); + dWorldStep (wId,0.5); + dWorldStep (wId,0.5); + + for (int b=0; b<2; ++b) { + // Compare body b of the first joint with its equivalent on the + // second joint + const dReal *qA = dBodyGetQuaternion(bId[0][b]); + const dReal *qB = dBodyGetQuaternion(bId[1][b]); + CHECK_CLOSE (qA[0], qB[0], 1e-4); + CHECK_CLOSE (qA[1], qB[1], 1e-4); + CHECK_CLOSE (qA[2], qB[2], 1e-4); + CHECK_CLOSE (qA[3], qB[3], 1e-4); + + + const dReal *posA = dBodyGetPosition(bId[0][b]); + const dReal *posB = dBodyGetPosition(bId[1][b]); + CHECK_CLOSE (posA[0], posB[0], 1e-4); + CHECK_CLOSE (posA[1], posB[1], 1e-4); + CHECK_CLOSE (posA[2], posB[2], 1e-4); + CHECK_CLOSE (posA[3], posB[3], 1e-4); + } + } + + + + +} // End of SUITE TestdxJointHinge2 + + diff --git a/libs/ode-0.16.1/tests/joints/piston.cpp b/libs/ode-0.16.1/tests/joints/piston.cpp new file mode 100644 index 0000000..9422180 --- /dev/null +++ b/libs/ode-0.16.1/tests/joints/piston.cpp @@ -0,0 +1,1456 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ +//234567890123456789012345678901234567890123456789012345678901234567890123456789 +// 1 2 3 4 5 6 7 + +//////////////////////////////////////////////////////////////////////////////// +// This file create unit test for some of the functions found in: +// ode/src/joinst/piston.cpp +// +// +//////////////////////////////////////////////////////////////////////////////// + +#include <UnitTest++.h> +#include <ode/ode.h> + +#include "../../ode/src/config.h" +#include "../../ode/src/joints/piston.h" + +SUITE (TestdxJointPiston) +{ + // The 2 bodies are positionned at (0, 0, 0), with no rotation + // The joint is a Piston Joint + // Axis is along the X axis + // Anchor at (0, 0, 0) + struct Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X + { + Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate (wId); + dBodySetPosition (bId1, 0, 0, 0); + + bId2 = dBodyCreate (wId); + dBodySetPosition (bId2, 0, 0, 0); + + jId = dJointCreatePiston (wId, 0); + joint = (dxJointPiston*) jId; + + + dJointAttach (jId, bId1, bId2); + + dJointSetPistonAxis (jId, axis[0], axis[1], axis[2]); + } + + ~Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + + dJointID jId; + dxJointPiston* joint; + + static const dVector3 axis; + + static const dReal offset; + }; + const dVector3 Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X::axis = + { + 1, 0, 0 + }; + const dReal Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X::offset = REAL (3.1); + + // Move 1st body offset unit in the X direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + // + // Start with a Offset of offset unit + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X, + test_dJointSetPistonAxisOffset_B1_3Unit) + { + dJointSetPistonAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId1, offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4); + + dJointSetPistonAnchorOffset (jId, 0, 0, 0, + offset*axis[0],offset*axis[1],offset*axis[2]); + CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId1, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + + // Only here to test a deprecated warning + #if 0 // the deprecated warning is not a functional part of the API, no need to test it. + dJointSetPistonAxisDelta (jId, 1, 0, 0, 0, 0, 0); + #endif + } + + // Move 1st body offset unit in the opposite X direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + // + // Start with a Offset of -offset unit + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X, + test_dJointSetPistonAxisOffset_B1_Minus_3Unit) + { + dJointSetPistonAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId1, -offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4); + + dJointSetPistonAnchorOffset (jId, 0, 0, 0, + -offset*axis[0],-offset*axis[1],-offset*axis[2]); + CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId1, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + } + + // Move 2nd body offset unit in the X direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + // + // Start with a Offset of offset unit + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X, + test_dJointSetPistonAxisOffset_B2_3Unit) + { + dJointSetPistonAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId2, offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4); + + dJointSetPistonAnchorOffset (jId, 0, 0, 0, + -offset*axis[0],-offset*axis[1],-offset*axis[2]); + CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId2, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + } + + // Move 2nd body offset unit in the opposite X direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + // + // Start with a Offset of -offset unit + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X, + test_dJointSetPistonAxisOffset_B2_Minus_3Unit) + { + dJointSetPistonAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId2, -offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4); + + dJointSetPistonAnchorOffset (jId, 0, 0, 0, + offset*axis[0],offset*axis[1],offset*axis[2]); + CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId2, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + } + + + + // The 2 bodies are positionned at (0, 0, 0), with no rotation + // The joint is a Piston Joint + // Axis is the opposite of the X axis + // Anchor at (0, 0, 0) + struct Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X + { + Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate (wId); + dBodySetPosition (bId1, 0, 0, 0); + + bId2 = dBodyCreate (wId); + dBodySetPosition (bId2, 0, 0, 0); + + jId = dJointCreatePiston (wId, 0); + joint = (dxJointPiston*) jId; + + + dJointAttach (jId, bId1, bId2); + + + dJointSetPistonAxis (jId, axis[0], axis[1], axis[2]); + } + + ~Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + + dJointID jId; + dxJointPiston* joint; + + static const dVector3 axis; + static const dReal offset; + }; + const dVector3 Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X::axis = + { + -1, 0, 0 + }; + const dReal Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X::offset = REAL (3.1); + + // Move 1st body offset unit in the X direction + // + // X-------> X---------> <-- Axis + // B1 => B1 + // B2 B2 + // + // Start with a Offset of offset unit + // + // X-------> X---------> <-- Axis + // B1 => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetPistonAxisOffset_B1_3Unit) + { + dJointSetPistonAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId1, offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4); + + dJointSetPistonAnchorOffset (jId, 0, 0, 0, + -offset*axis[0],-offset*axis[1],-offset*axis[2]); + CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId1, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + } + + // Move 1st body offset unit in the opposite X direction + // + // X-------> X---------> <-- Axis + // B1 => B1 + // B2 B2 + // + // Start with a Offset of offset unit + // + // X-------> X---------> <-- Axis + // B1 => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetPistonAxisOffset_B1_Minus_3Unit) + { + dJointSetPistonAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId1, -offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4); + + dJointSetPistonAnchorOffset (jId, 0, 0, 0, + offset*axis[0],offset*axis[1],offset*axis[2]); + CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId1, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + } + + // Move 2nd body offset unit in the X direction + // + // X-------> X---------> <-- Axis + // B1 => B1 + // B2 B2 + // + // Start with a Offset of offset unit + // + // X-------> X---------> <-- Axis + // B1 => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetPistonAxisOffset_B2_3Unit) + { + dJointSetPistonAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId2, offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4); + + dJointSetPistonAnchorOffset (jId, 0, 0, 0, + offset*axis[0],offset*axis[1],offset*axis[2]); + CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId2, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + } + + // Move 2nd body offset unit in the opposite X direction + // + // X-------> X---------> <-- Axis + // B1 => B1 + // B2 B2 + // + // Start with a Offset of -offset unit + // + // X-------> X---------> <-- Axis + // B1 => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetPistonAxisOffset_B2_Minus_3Unit) + { + dJointSetPistonAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId2, -offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4); + + dJointSetPistonAnchorOffset (jId, 0, 0, 0, + -offset*axis[0],-offset*axis[1],-offset*axis[2]); + CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId2, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + } + + + // Only body 1 + // The body are positionned at (0, 0, 0), with no rotation + // The joint is a Piston Joint + // Axis is along the X axis + // Anchor at (0, 0, 0) + struct Fixture_dxJointPiston_B1_At_Zero_Axis_Along_X + { + Fixture_dxJointPiston_B1_At_Zero_Axis_Along_X() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate (wId); + dBodySetPosition (bId1, 0, 0, 0); + + jId = dJointCreatePiston (wId, 0); + joint = (dxJointPiston*) jId; + + + dJointAttach (jId, bId1, NULL); + + dJointSetPistonAxis (jId, axis[0], axis[1], axis[2]); + } + + ~Fixture_dxJointPiston_B1_At_Zero_Axis_Along_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1; + + dJointID jId; + dxJointPiston* joint; + + static const dVector3 axis; + + static const dReal offset; + }; + const dVector3 Fixture_dxJointPiston_B1_At_Zero_Axis_Along_X::axis = + { + 1, 0, 0 + }; + const dReal Fixture_dxJointPiston_B1_At_Zero_Axis_Along_X::offset = REAL (3.1); + + // Move 1st body offset unit in the X direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // + // Start with a Offset of offset unit + // + // X-------> X---------> Axis --> + // B1 => B1 + TEST_FIXTURE (Fixture_dxJointPiston_B1_At_Zero_Axis_Along_X, + test_dJointSetPistonAxisOffset_B1_OffsetUnit) + { + dJointSetPistonAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId1, offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4); + + dJointSetPistonAnchorOffset (jId, 0, 0, 0, + offset*axis[0],offset*axis[1],offset*axis[2]); + CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId1, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + } + + // Move 1st body offset unit in the opposite X direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // + // Start with a Offset of -offset unit + // + // X-------> X---------> Axis --> + // B1 => B1 + TEST_FIXTURE (Fixture_dxJointPiston_B1_At_Zero_Axis_Along_X, + test_dJointSetPistonAxisOffset_B1_Minus_OffsetUnit) + { + dJointSetPistonAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId1, -offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4); + + dJointSetPistonAnchorOffset (jId, 0, 0, 0, + -offset*axis[0],-offset*axis[1],-offset*axis[2]); + CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId1, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + } + + // Only body 1 + // The body are positionned at (0, 0, 0), with no rotation + // The joint is a Piston Joint + // Axis is in the oppsite X axis + // Anchor at (0, 0, 0) + struct Fixture_dxJointPiston_B1_At_Zero_Axis_Inverse_of_X + { + Fixture_dxJointPiston_B1_At_Zero_Axis_Inverse_of_X() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate (wId); + dBodySetPosition (bId1, 0, 0, 0); + + jId = dJointCreatePiston (wId, 0); + joint = (dxJointPiston*) jId; + + + dJointAttach (jId, bId1, NULL); + + dJointSetPistonAxis (jId, axis[0], axis[1], axis[2]); + } + + ~Fixture_dxJointPiston_B1_At_Zero_Axis_Inverse_of_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1; + + dJointID jId; + dxJointPiston* joint; + + static const dVector3 axis; + + static const dReal offset; + }; + const dVector3 Fixture_dxJointPiston_B1_At_Zero_Axis_Inverse_of_X::axis = + { + -1, 0, 0 + }; + const dReal Fixture_dxJointPiston_B1_At_Zero_Axis_Inverse_of_X::offset = REAL (3.1); + + // Move 1st body offset unit in the X direction + // + // X-------> X---------> <--- Axis + // B1 => B1 + // + // Start with a Offset of offset unit + // + // X-------> X---------> <--- Axis + // B1 => B1 + TEST_FIXTURE (Fixture_dxJointPiston_B1_At_Zero_Axis_Inverse_of_X, + test_dJointSetPistonAxisOffset_B1_OffsetUnit) + { + dJointSetPistonAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId1, offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4); + + dJointSetPistonAnchorOffset (jId, 0, 0, 0, + -offset*axis[0],-offset*axis[1],-offset*axis[2]); + CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId1, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + } + + // Move 1st body offset unit in the opposite X direction + // + // X-------> X---------> <--- Axis + // B1 => B1 + // + // Start with a Offset of -offset unit + // + // X-------> X---------> <--- Axis + // B1 => B1 + TEST_FIXTURE (Fixture_dxJointPiston_B1_At_Zero_Axis_Inverse_of_X, + test_dJointSetPistonAxisOffset_B1_Minus_OffsetUnit) + { + dJointSetPistonAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId1, -offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4); + + dJointSetPistonAnchorOffset (jId, 0, 0, 0, + offset*axis[0],offset*axis[1],offset*axis[2]); + CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId1, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + } + + + + + + + + + + // Only body 2 + // The body are positionned at (0, 0, 0), with no rotation + // The joint is a Piston Joint + // Axis is along the X axis + // Anchor at (0, 0, 0) + struct Fixture_dxJointPiston_B2_At_Zero_Axis_Along_X + { + Fixture_dxJointPiston_B2_At_Zero_Axis_Along_X() + { + wId = dWorldCreate(); + + bId2 = dBodyCreate (wId); + dBodySetPosition (bId2, 0, 0, 0); + + jId = dJointCreatePiston (wId, 0); + joint = (dxJointPiston*) jId; + + + dJointAttach (jId, NULL, bId2); + + dJointSetPistonAxis (jId, axis[0], axis[1], axis[2]); + } + + ~Fixture_dxJointPiston_B2_At_Zero_Axis_Along_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId2; + + dJointID jId; + dxJointPiston* joint; + + static const dVector3 axis; + + static const dReal offset; + }; + const dVector3 Fixture_dxJointPiston_B2_At_Zero_Axis_Along_X::axis = + { + 1, 0, 0 + }; + const dReal Fixture_dxJointPiston_B2_At_Zero_Axis_Along_X::offset = REAL (3.1); + + // Move 2nd body offset unit in the X direction + // + // X-------> X---------> Axis --> + // B2 => B2 + // + // Start with a Offset of offset unit + // + // X-------> X---------> Axis --> + // B2 => B2 + TEST_FIXTURE (Fixture_dxJointPiston_B2_At_Zero_Axis_Along_X, + test_dJointSetPistonAxisOffset_B2_OffsetUnit) + { + dJointSetPistonAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId2, offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4); + + dJointSetPistonAnchorOffset (jId, 0, 0, 0, + -offset*axis[0],-offset*axis[1],-offset*axis[2]); + CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId2, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + } + + // Move 2nd body offset unit in the opposite X direction + // + // X-------> X---------> Axis --> + // B2 => B2 + // + // Start with a Offset of -offset unit + // + // X-------> X---------> Axis --> + // B2 => B2 + TEST_FIXTURE (Fixture_dxJointPiston_B2_At_Zero_Axis_Along_X, + test_dJointSetPistonAxisOffset_B2_Minus_OffsetUnit) + { + dJointSetPistonAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId2, -offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4); + + dJointSetPistonAnchorOffset (jId, 0, 0, 0, + offset*axis[0],offset*axis[1],offset*axis[2]); + CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId2, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + } + + // Only body 2 + // The body are positionned at (0, 0, 0), with no rotation + // The joint is a Piston Joint + // Axis is in the opposite X axis + // Anchor at (0, 0, 0) + struct Fixture_dxJointPiston_B2_At_Zero_Axis_Inverse_of_X + { + Fixture_dxJointPiston_B2_At_Zero_Axis_Inverse_of_X() + { + wId = dWorldCreate(); + + bId2 = dBodyCreate (wId); + dBodySetPosition (bId2, 0, 0, 0); + + jId = dJointCreatePiston (wId, 0); + joint = (dxJointPiston*) jId; + + + dJointAttach (jId, NULL, bId2); + + dJointSetPistonAxis (jId, axis[0], axis[1], axis[2]); + } + + ~Fixture_dxJointPiston_B2_At_Zero_Axis_Inverse_of_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId2; + + dJointID jId; + dxJointPiston* joint; + + static const dVector3 axis; + + static const dReal offset; + }; + const dVector3 Fixture_dxJointPiston_B2_At_Zero_Axis_Inverse_of_X::axis = + { + -1, 0, 0 + }; + const dReal Fixture_dxJointPiston_B2_At_Zero_Axis_Inverse_of_X::offset = REAL (3.1); + + // Move 2nd body offset unit in the X direction + // + // X-------> X---------> <--- Axis + // B2 => B2 + // + // Start with a Offset of offset unit + // + // X-------> X---------> <--- Axis + // B2 => B2 + TEST_FIXTURE (Fixture_dxJointPiston_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetPistonAxisOffset_B2_OffsetUnit) + { + dJointSetPistonAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId2, offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4); + + dJointSetPistonAnchorOffset (jId, 0, 0, 0, + offset*axis[0],offset*axis[1],offset*axis[2]); + CHECK_CLOSE (offset, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId2, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + #if 0 // another deprecated warning test? + dJointSetPistonAxisDelta (jId, 1, 0, 0, 0, 0, 0); + #endif + } + + // Move 1st body offset unit in the opposite X direction + // + // X-------> X---------> <--- Axis + // B2 => B2 + // + // Start with a Offset of -offset unit + // + // X-------> X---------> <--- Axis + // B2 => B2 + TEST_FIXTURE (Fixture_dxJointPiston_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetPistonAxisOffset_B2_Minus_OffsetUnit) + { + dJointSetPistonAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId2, -offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4); + + dJointSetPistonAnchorOffset (jId, 0, 0, 0, + -offset*axis[0],-offset*axis[1],-offset*axis[2]); + CHECK_CLOSE (-offset, dJointGetPistonPosition (jId), 1e-4); + + dBodySetPosition (bId2, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + } + + // ========================================================================== + // Test Position Rate + // ========================================================================== + + // Apply force on 1st body in the X direction also the Axis direction + // + // X-------> X---------> Axis --> + // B1 F-> => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X, + test_dJointSetPistonPositionRate_Force_Along_Axis_on_B1) + { + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4); + + dBodyAddForce (bId1, 1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (1, dJointGetPistonPositionRate (jId), 1e-4); + } + + // Apply force on 1st body in the inverse X direction + // + // X-------> X---------> Axis --> + // B1 <-F => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X, + test_dJointSetPistonPositionRate_Force_Inverse_of_Axis_on_B1) + { + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4); + + dBodyAddForce (bId1, -1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (-1, dJointGetPistonPositionRate (jId), 1e-4); + } + + + // Apply force on 1st body in the X direction also the Axis direction + // + // X-------> X---------> <-- Axis + // B1 F-> => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetPistonPositionRate_Force_Inverse_Axis_on_B1) + { + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4); + + dBodyAddForce (bId1, 1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (-1, dJointGetPistonPositionRate (jId), 1e-4); + } + + // Apply force on 1st body in the inverse X direction + // + // X-------> X---------> <-- Axis + // B1 <-F => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetPistonPositionRate_Force_Along_of_Axis_on_B1) + { + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4); + + dBodyAddForce (bId1, -1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (1, dJointGetPistonPositionRate (jId), 1e-4); + } + + // Apply force on 1st body in the X direction also the Axis direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 F-> B2 + TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X, + test_dJointSetPistonPositionRate_Force_Along_Axis_on_B2) + { + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4); + + dBodyAddForce (bId2, 1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (-1, dJointGetPistonPositionRate (jId), 1e-4); + } + + // Apply force on 1st body in the inverse X direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 <-F B2 + TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Along_X, + test_dJointSetPistonPositionRate_Force_Inverse_of_Axis_on_B2) + { + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4); + + dBodyAddForce (bId2, -1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (1, dJointGetPistonPositionRate (jId), 1e-4); + } + + + // Apply force on 1st body in the X direction also the Axis direction + // + // X-------> X---------> <-- Axis + // B1 => B1 + // B2 F-> B2 + TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetPistonPositionRate_Force_Inverse_Axis_on_B2) + { + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4); + + dBodyAddForce (bId2, 1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (1, dJointGetPistonPositionRate (jId), 1e-4); + } + + // Apply force on 1st body in the inverse X direction + // + // X-------> X---------> <-- Axis + // B1 => B1 + // B2 <-F B2 + TEST_FIXTURE (Fixture_dxJointPiston_B1_and_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetPistonPositionRate_Force_Along_of_Axis_on_B2) + { + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4); + + dBodyAddForce (bId2, -1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (-1, dJointGetPistonPositionRate (jId), 1e-4); + } + + + + // Apply force on 1st body in the X direction also the Axis direction + // + // X-------> X---------> Axis --> + // B1 F-> => B1 + TEST_FIXTURE (Fixture_dxJointPiston_B1_At_Zero_Axis_Along_X, + test_dJointSetPistonPositionRate_Force_Along_Axis_on_B1) + { + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4); + + dBodyAddForce (bId1, 1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (1, dJointGetPistonPositionRate (jId), 1e-4); + } + + // Apply force on 1st body in the inverse X direction + // + // X-------> X---------> Axis --> + // B1 <-F => B1 + TEST_FIXTURE (Fixture_dxJointPiston_B1_At_Zero_Axis_Along_X, + test_dJointSetPistonPositionRate_Force_Inverse_of_Axis_on_B1) + { + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4); + + dBodyAddForce (bId1, -1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (-1, dJointGetPistonPositionRate (jId), 1e-4); + } + + + // Apply force on 1st body in the X direction also the Axis direction + // + // X-------> X---------> <-- Axis + // B1 F-> => B1 + TEST_FIXTURE (Fixture_dxJointPiston_B1_At_Zero_Axis_Inverse_of_X, + test_dJointSetPistonPositionRate_Force_Inverse_Axis_on_B1) + { + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4); + + dBodyAddForce (bId1, 1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (-1, dJointGetPistonPositionRate (jId), 1e-4); + } + + // Apply force on 1st body in the inverse X direction + // + // X-------> X---------> <-- Axis + // B1 <-F => B1 + TEST_FIXTURE (Fixture_dxJointPiston_B1_At_Zero_Axis_Inverse_of_X, + test_dJointSetPistonPositionRate_Force_Along_of_Axis_on_B1) + { + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4); + + dBodyAddForce (bId1, -1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (1, dJointGetPistonPositionRate (jId), 1e-4); + } + + + // Apply force on body 2 in the X direction also the Axis direction + // + // X-------> X---------> Axis --> + // B2 F-> B2 + TEST_FIXTURE (Fixture_dxJointPiston_B2_At_Zero_Axis_Along_X, + test_dJointSetPistonPositionRate_Force_Along_Axis_on_B2) + { + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4); + + dBodyAddForce (bId2, 1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (-1, dJointGetPistonPositionRate (jId), 1e-4); + } + + // Apply force on body 2 in the inverse X direction + // + // X-------> X---------> Axis --> + // B2 <-F B2 + TEST_FIXTURE (Fixture_dxJointPiston_B2_At_Zero_Axis_Along_X, + test_dJointSetPistonPositionRate_Force_Inverse_of_Axis_on_B2) + { + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4); + + dBodyAddForce (bId2, -1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (1, dJointGetPistonPositionRate (jId), 1e-4); + } + + + // Apply force on body 2 in the X direction also the Axis direction + // + // X-------> X---------> <-- Axis + // B2 F-> B2 + TEST_FIXTURE (Fixture_dxJointPiston_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetPistonPositionRate_Force_Inverse_Axis_on_B2) + { + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4); + + dBodyAddForce (bId2, 1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (1, dJointGetPistonPositionRate (jId), 1e-4); + } + + // Apply force on body 2 in the inverse X direction + // + // X-------> X---------> <-- Axis + // B2 <-F B2 + TEST_FIXTURE (Fixture_dxJointPiston_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetPistonPositionRate_Force_Along_of_Axis_on_B2) + { + CHECK_CLOSE (0.0, dJointGetPistonPosition (jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetPistonPositionRate (jId), 1e-4); + + dBodyAddForce (bId2, -1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (-1, dJointGetPistonPositionRate (jId), 1e-4); + } + + + + +// Create 2 bodies attached by a Piston joint + // Axis is along the X axis (Default value + // Anchor at (0, 0, 0) (Default value) + // + // ^Y + // | + // * Body2 + // | + // | + // Body1 | + // * Z--------> + struct dxJointPiston_Test_Initialization + { + dxJointPiston_Test_Initialization() + { + wId = dWorldCreate(); + + // Remove gravity to have the only force be the force of the joint + dWorldSetGravity(wId, 0,0,0); + + for (int j=0; j<2; ++j) + { + bId[j][0] = dBodyCreate (wId); + dBodySetPosition (bId[j][0], -1, -2, -3); + + bId[j][1] = dBodyCreate (wId); + dBodySetPosition (bId[j][1], 11, 22, 33); + + + dMatrix3 R; + dVector3 axis; // Random axis + + axis[0] = REAL(0.53); + axis[1] = -REAL(0.71); + axis[2] = REAL(0.43); + dNormalize3(axis); + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], + REAL(0.47123)); // 27deg + dBodySetRotation (bId[j][0], R); + + + axis[0] = REAL(1.2); + axis[1] = REAL(0.87); + axis[2] = -REAL(0.33); + dNormalize3(axis); + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], + REAL(0.47123)); // 27deg + dBodySetRotation (bId[j][1], R); + + jId[j] = dJointCreatePiston (wId, 0); + dJointAttach (jId[j], bId[j][0], bId[j][1]); + } + } + + ~dxJointPiston_Test_Initialization() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId[2][2]; + + + dJointID jId[2]; + + }; + + + // Test if setting a Piston with its default values + // will behave the same as a default Piston joint + TEST_FIXTURE (dxJointPiston_Test_Initialization, + test_Piston_Initialization) + { + using namespace std; + + dVector3 axis; + dJointGetPistonAxis(jId[1], axis); + dJointSetPistonAxis(jId[1], axis[0], axis[1], axis[2]); + + + dVector3 anchor; + dJointGetPistonAnchor(jId[1], anchor); + dJointSetPistonAnchor(jId[1], anchor[0], anchor[1], anchor[2]); + + + for (int b=0; b<2; ++b) + { + // Compare body b of the first joint with its equivalent on the + // second joint + const dReal *qA = dBodyGetQuaternion(bId[0][b]); + const dReal *qB = dBodyGetQuaternion(bId[1][b]); + CHECK_CLOSE (qA[0], qB[0], 1e-6); + CHECK_CLOSE (qA[1], qB[1], 1e-6); + CHECK_CLOSE (qA[2], qB[2], 1e-6); + CHECK_CLOSE (qA[3], qB[3], 1e-6); + } + + dWorldStep (wId,0.5); + dWorldStep (wId,0.5); + dWorldStep (wId,0.5); + dWorldStep (wId,0.5); + + for (int b=0; b<2; ++b) + { + // Compare body b of the first joint with its equivalent on the + // second joint + const dReal *qA = dBodyGetQuaternion(bId[0][b]); + const dReal *qB = dBodyGetQuaternion(bId[1][b]); + CHECK_CLOSE (qA[0], qB[0], 1e-6); + CHECK_CLOSE (qA[1], qB[1], 1e-6); + CHECK_CLOSE (qA[2], qB[2], 1e-6); + CHECK_CLOSE (qA[3], qB[3], 1e-6); + + + const dReal *posA = dBodyGetPosition(bId[0][b]); + const dReal *posB = dBodyGetPosition(bId[1][b]); + CHECK_CLOSE (posA[0], posB[0], 1e-6); + CHECK_CLOSE (posA[1], posB[1], 1e-6); + CHECK_CLOSE (posA[2], posB[2], 1e-6); + CHECK_CLOSE (posA[3], posB[3], 1e-6); + } + + + } + + + + + + // Compare only one body to 2 bodies with one fixed. + // + // The body are positionned at (0, 0, 0), with no rotation + // The joint is a Piston Joint + // Axis is along the X axis + // Anchor at (0, 0, 0) + struct Fixture_dxJointPiston_Compare_Body_At_Zero_Axis_Along_X + { + Fixture_dxJointPiston_Compare_Body_At_Zero_Axis_Along_X() + { + wId = dWorldCreate(); + + bId1_12 = dBodyCreate (wId); + dBodySetPosition (bId1_12, 0, 0, 0); + + bId2_12 = dBodyCreate (wId); + dBodySetPosition (bId2_12, 0, 0, 0); + // The force will be added in the function since it is not + // always on the same body + + jId_12 = dJointCreatePiston (wId, 0); + dJointAttach(jId_12, bId1_12, bId2_12); + + fixed = dJointCreateFixed (wId, 0); + + + + bId = dBodyCreate (wId); + dBodySetPosition (bId, 0, 0, 0); + + dBodyAddForce (bId, 4, 0, 0); + + jId = dJointCreatePiston (wId, 0); + } + + ~Fixture_dxJointPiston_Compare_Body_At_Zero_Axis_Along_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1_12; + dBodyID bId2_12; + + dJointID jId_12; // Joint with 2 bodies + + dJointID fixed; + + + + dBodyID bId; + dJointID jId; // Joint with one body + }; + + // This test compare the result of a slider with 2 bodies where body body 2 is + // fixed to the world to a slider with only one body at position 1. + // + // Test the limits [-1, 0.25] when only one body at is attached to the joint + // using dJointAttache(jId, bId, 0); + // + TEST_FIXTURE(Fixture_dxJointPiston_Compare_Body_At_Zero_Axis_Along_X, + test_Limit_minus1_025_One_Body_on_left) + { + dBodyAddForce (bId1_12, 4, 0, 0); + + dJointAttach(jId_12, bId1_12, bId2_12); + dJointSetPistonParam(jId_12, dParamLoStop, -1); + dJointSetPistonParam(jId_12, dParamHiStop, 0.25); + + dJointAttach(fixed, 0, bId2_12); + dJointSetFixed(fixed); + + dJointAttach(jId, bId, 0); + dJointSetPistonParam(jId, dParamLoStop, -1); + dJointSetPistonParam(jId, dParamHiStop, 0.25); + + + for (int i=0; i<50; ++i) + dWorldStep(wId, 1.0); + + + const dReal *pos1_12 = dBodyGetPosition(bId1_12); + const dReal *pos = dBodyGetPosition(bId); + + CHECK_CLOSE (pos1_12[0], pos[0], 1e-2); + CHECK_CLOSE (pos1_12[1], pos[1], 1e-2); + CHECK_CLOSE (pos1_12[2], pos[2], 1e-2); + + const dReal *q1_12 = dBodyGetQuaternion(bId1_12); + const dReal *q = dBodyGetQuaternion(bId); + + CHECK_CLOSE (q1_12[0], q[0], 1e-4); + CHECK_CLOSE (q1_12[1], q[1], 1e-4); + CHECK_CLOSE (q1_12[2], q[2], 1e-4); + CHECK_CLOSE (q1_12[3], q[3], 1e-4); + } + + + + // This test compare the result of a slider with 2 bodies where body body 1 is + // fixed to the world to a slider with only one body at position 2. + // + // Test the limits [-1, 0.25] when only one body at is attached to the joint + // using dJointAttache(jId, 0, bId); + // + TEST_FIXTURE(Fixture_dxJointPiston_Compare_Body_At_Zero_Axis_Along_X, + test_Limit_minus1_025_One_Body_on_right) + { + dBodyAddForce (bId2_12, 4, 0, 0); + + dJointAttach(jId_12, bId1_12, bId2_12); + dJointSetPistonParam(jId_12, dParamLoStop, -1); + dJointSetPistonParam(jId_12, dParamHiStop, 0.25); + + dJointAttach(fixed, bId1_12, 0); + dJointSetFixed(fixed); + + + dJointAttach(jId, 0, bId); + dJointSetPistonParam(jId, dParamLoStop, -1); + dJointSetPistonParam(jId, dParamHiStop, 0.25); + + for (int i=0; i<50; ++i) + dWorldStep(wId, 1.0); + + + const dReal *pos2_12 = dBodyGetPosition(bId2_12); + const dReal *pos = dBodyGetPosition(bId); + + CHECK_CLOSE (pos2_12[0], pos[0], 1e-2); + CHECK_CLOSE (pos2_12[1], pos[1], 1e-2); + CHECK_CLOSE (pos2_12[2], pos[2], 1e-2); + + + const dReal *q2_12 = dBodyGetQuaternion(bId2_12); + const dReal *q = dBodyGetQuaternion(bId); + + CHECK_CLOSE (q2_12[0], q[0], 1e-4); + CHECK_CLOSE (q2_12[1], q[1], 1e-4); + CHECK_CLOSE (q2_12[2], q[2], 1e-4); + CHECK_CLOSE (q2_12[3], q[3], 1e-4); + } + + + + // This test compare the result of a slider with 2 bodies where body body 2 is + // fixed to the world to a slider with only one body at position 1. + // + // Test the limits [0, 0] when only one body at is attached to the joint + // using dJointAttache(jId, bId, 0); + // + // The body should not move since their is no room between the two limits + // + TEST_FIXTURE(Fixture_dxJointPiston_Compare_Body_At_Zero_Axis_Along_X, + test_Limit_0_0_One_Body_on_left) + { + dBodyAddForce (bId1_12, 4, 0, 0); + + dJointAttach(jId_12, bId1_12, bId2_12); + dJointSetPistonParam(jId_12, dParamLoStop, 0); + dJointSetPistonParam(jId_12, dParamHiStop, 0); + + dJointAttach(fixed, 0, bId2_12); + dJointSetFixed(fixed); + + + dJointAttach(jId, bId, 0); + dJointSetPistonParam(jId, dParamLoStop, 0); + dJointSetPistonParam(jId, dParamHiStop, 0); + + for (int i=0; i<500; ++i) + dWorldStep(wId, 1.0); + + + const dReal *pos1_12 = dBodyGetPosition(bId1_12); + const dReal *pos = dBodyGetPosition(bId); + + CHECK_CLOSE (pos1_12[0], pos[0], 1e-4); + CHECK_CLOSE (pos1_12[1], pos[1], 1e-4); + CHECK_CLOSE (pos1_12[2], pos[2], 1e-4); + + CHECK_CLOSE (0, pos[0], 1e-4); + CHECK_CLOSE (0, pos[1], 1e-4); + CHECK_CLOSE (0, pos[2], 1e-4); + + + const dReal *q1_12 = dBodyGetQuaternion(bId1_12); + const dReal *q = dBodyGetQuaternion(bId); + + CHECK_CLOSE (q1_12[0], q[0], 1e-4); + CHECK_CLOSE (q1_12[1], q[1], 1e-4); + CHECK_CLOSE (q1_12[2], q[2], 1e-4); + CHECK_CLOSE (q1_12[3], q[3], 1e-4); + } + + + // This test compare the result of a slider with 2 bodies where body body 1 is + // fixed to the world to a slider with only one body at position 2. + // + // Test the limits [0, 0] when only one body at is attached to the joint + // using dJointAttache(jId, 0, bId); + // + // The body should not move since their is no room between the two limits + // + TEST_FIXTURE(Fixture_dxJointPiston_Compare_Body_At_Zero_Axis_Along_X, + test_Limit_0_0_One_Body_on_right) + { + dBodyAddForce (bId2_12, 4, 0, 0); + + dJointAttach(jId_12, bId1_12, bId2_12); + dJointSetPistonParam(jId_12, dParamLoStop, 0); + dJointSetPistonParam(jId_12, dParamHiStop, 0); + + dJointAttach(fixed, bId1_12, 0); + dJointSetFixed(fixed); + + + dJointAttach(jId, 0, bId); + dJointSetPistonParam(jId, dParamLoStop, 0); + dJointSetPistonParam(jId, dParamHiStop, 0); + + for (int i=0; i<500; ++i) + dWorldStep(wId, 1.0); + + const dReal *pos2_12 = dBodyGetPosition(bId2_12); + const dReal *pos = dBodyGetPosition(bId); + + CHECK_CLOSE (pos2_12[0], pos[0], 1e-4); + CHECK_CLOSE (pos2_12[1], pos[1], 1e-4); + CHECK_CLOSE (pos2_12[2], pos[2], 1e-4); + + CHECK_CLOSE (0, pos[0], 1e-4); + CHECK_CLOSE (0, pos[1], 1e-4); + CHECK_CLOSE (0, pos[2], 1e-4); + + + const dReal *q2_12 = dBodyGetQuaternion(bId2_12); + const dReal *q = dBodyGetQuaternion(bId); + + CHECK_CLOSE (q2_12[0], q[0], 1e-4); + CHECK_CLOSE (q2_12[1], q[1], 1e-4); + CHECK_CLOSE (q2_12[2], q[2], 1e-4); + CHECK_CLOSE (q2_12[3], q[3], 1e-4); + } + + +} // End of SUITE TestdxJointPiston diff --git a/libs/ode-0.16.1/tests/joints/pr.cpp b/libs/ode-0.16.1/tests/joints/pr.cpp new file mode 100644 index 0000000..30995c7 --- /dev/null +++ b/libs/ode-0.16.1/tests/joints/pr.cpp @@ -0,0 +1,1160 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ +//234567890123456789012345678901234567890123456789012345678901234567890123456789 +// 1 2 3 4 5 6 7 + +//////////////////////////////////////////////////////////////////////////////// +// This file create unit test for some of the functions found in: +// ode/src/joinst/pr.cpp +// +// +//////////////////////////////////////////////////////////////////////////////// + +#include <UnitTest++.h> +#include <ode/ode.h> + +#include "../../ode/src/config.h" +#include "../../ode/src/joints/pr.h" + +SUITE (TestdxJointPR) +{ + // The 2 bodies are positionned at (0, 0, 0), with no rotation + // The joint is a PR Joint + // Axis is along the X axis + // Anchor at (0, 0, 0) + struct Fixture_dxJointPR_B1_and_B2_At_Zero_Axis_Along_X + { + Fixture_dxJointPR_B1_and_B2_At_Zero_Axis_Along_X() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate (wId); + dBodySetPosition (bId1, 0, 0, 0); + + bId2 = dBodyCreate (wId); + dBodySetPosition (bId2, 0, 0, 0); + + jId = dJointCreatePR (wId, 0); + joint = (dxJointPR*) jId; + + + dJointAttach (jId, bId1, bId2); + + dJointSetPRAxis1 (jId, axis[0], axis[1], axis[2]); + } + + ~Fixture_dxJointPR_B1_and_B2_At_Zero_Axis_Along_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + + dJointID jId; + dxJointPR* joint; + + static const dVector3 axis; + + static const dReal offset; + }; + const dVector3 Fixture_dxJointPR_B1_and_B2_At_Zero_Axis_Along_X::axis = + { + 1, 0, 0 + }; + const dReal Fixture_dxJointPR_B1_and_B2_At_Zero_Axis_Along_X::offset = REAL (3.1); + + + + + + // Move 1st body offset unit in the X direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + // + // Start with a Offset of offset unit + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointPR_B1_and_B2_At_Zero_Axis_Along_X, + test_dJointSetPRAxisOffset_B1_3Unit) + { + dJointSetPRAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4); + + dBodySetPosition (bId1, offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4); + +// dJointSetPRAnchorOffset (jId, 0, 0, 0, +// offset*axis[0],offset*axis[1],offset*axis[2]); +// CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4); + +// dBodySetPosition (bId1, 0, 0, 0); +// CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4); + +// // Only here to test a deprecated warning +// dJointSetPRAxisDelta (jId, 1, 0, 0, 0, 0, 0); + } + + // Move 1st body offset unit in the opposite X direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + // + // Start with a Offset of -offset unit + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointPR_B1_and_B2_At_Zero_Axis_Along_X, + test_dJointSetPRAxisOffset_B1_Minus_3Unit) + { + dJointSetPRAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4); + + dBodySetPosition (bId1, -offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4); + +// dJointSetPRAnchorOffset (jId, 0, 0, 0, +// -offset*axis[0],-offset*axis[1],-offset*axis[2]); +// CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4); + +// dBodySetPosition (bId1, 0, 0, 0); +// CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4); + } + + // Move 2nd body offset unit in the X direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + // + // Start with a Offset of offset unit + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointPR_B1_and_B2_At_Zero_Axis_Along_X, + test_dJointSetPRAxisOffset_B2_3Unit) + { + dJointSetPRAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4); + + dBodySetPosition (bId2, offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4); + +// dJointSetPRAnchorOffset (jId, 0, 0, 0, +// -offset*axis[0],-offset*axis[1],-offset*axis[2]); +// CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4); + +// dBodySetPosition (bId2, 0, 0, 0); +// CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4); + } + + // Move 2nd body offset unit in the opposite X direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + // + // Start with a Offset of -offset unit + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointPR_B1_and_B2_At_Zero_Axis_Along_X, + test_dJointSetPRAxisOffset_B2_Minus_3Unit) + { + dJointSetPRAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4); + + dBodySetPosition (bId2, -offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4); + +// dJointSetPRAnchorOffset (jId, 0, 0, 0, +// offset*axis[0],offset*axis[1],offset*axis[2]); +// CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4); + +// dBodySetPosition (bId2, 0, 0, 0); +// CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4); + } + + + + + + + // Only body 1 + // The body are positionned at (0, 0, 0), with no rotation + // The joint is a PR Joint + // Axis is along the X axis + // Anchor at (0, 0, 0) + struct Fixture_dxJointPR_B1_At_Zero_Axis_Along_X + { + Fixture_dxJointPR_B1_At_Zero_Axis_Along_X() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate (wId); + dBodySetPosition (bId1, 0, 0, 0); + + jId = dJointCreatePR (wId, 0); + joint = (dxJointPR*) jId; + + + dJointAttach (jId, bId1, NULL); + + dJointSetPRAxis1 (jId, axis[0], axis[1], axis[2]); + } + + ~Fixture_dxJointPR_B1_At_Zero_Axis_Along_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1; + + dJointID jId; + dxJointPR* joint; + + static const dVector3 axis; + + static const dReal offset; + }; + const dVector3 Fixture_dxJointPR_B1_At_Zero_Axis_Along_X::axis = + { + 1, 0, 0 + }; + const dReal Fixture_dxJointPR_B1_At_Zero_Axis_Along_X::offset = REAL (3.1); + + // Move 1st body offset unit in the X direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // + // Start with a Offset of offset unit + // + // X-------> X---------> Axis --> + // B1 => B1 + TEST_FIXTURE (Fixture_dxJointPR_B1_At_Zero_Axis_Along_X, + test_dJointSetPRAxisOffset_B1_OffsetUnit) + { + dJointSetPRAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4); + + dBodySetPosition (bId1, offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4); + +// dJointSetPRAnchorOffset (jId, 0, 0, 0, +// offset*axis[0],offset*axis[1],offset*axis[2]); +// CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4); + +// dBodySetPosition (bId1, 0, 0, 0); +// CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4); + } + + // Move 1st body offset unit in the opposite X direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // + // Start with a Offset of -offset unit + // + // X-------> X---------> Axis --> + // B1 => B1 + TEST_FIXTURE (Fixture_dxJointPR_B1_At_Zero_Axis_Along_X, + test_dJointSetPRAxisOffset_B1_Minus_OffsetUnit) + { + dJointSetPRAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4); + + dBodySetPosition (bId1, -offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4); + +// dJointSetPRAnchorOffset (jId, 0, 0, 0, +// -offset*axis[0],-offset*axis[1],-offset*axis[2]); +// CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4); + +// dBodySetPosition (bId1, 0, 0, 0); +// CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4); + } + + // Only body 1 + // The body are positionned at (0, 0, 0), with no rotation + // The joint is a PR Joint + // Axis is in the oppsite X axis + // Anchor at (0, 0, 0) + struct Fixture_dxJointPR_B1_At_Zero_Axis_Inverse_of_X + { + Fixture_dxJointPR_B1_At_Zero_Axis_Inverse_of_X() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate (wId); + dBodySetPosition (bId1, 0, 0, 0); + + jId = dJointCreatePR (wId, 0); + joint = (dxJointPR*) jId; + + + dJointAttach (jId, bId1, NULL); + + dJointSetPRAxis1 (jId, axis[0], axis[1], axis[2]); + } + + ~Fixture_dxJointPR_B1_At_Zero_Axis_Inverse_of_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1; + + dJointID jId; + dxJointPR* joint; + + static const dVector3 axis; + + static const dReal offset; + }; + const dVector3 Fixture_dxJointPR_B1_At_Zero_Axis_Inverse_of_X::axis = + { + -1, 0, 0 + }; + const dReal Fixture_dxJointPR_B1_At_Zero_Axis_Inverse_of_X::offset = REAL (3.1); + + // Move 1st body offset unit in the X direction + // + // X-------> X---------> <--- Axis + // B1 => B1 + // + // Start with a Offset of offset unit + // + // X-------> X---------> <--- Axis + // B1 => B1 + TEST_FIXTURE (Fixture_dxJointPR_B1_At_Zero_Axis_Inverse_of_X, + test_dJointSetPRAxisOffset_B1_OffsetUnit) + { + dJointSetPRAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4); + + dBodySetPosition (bId1, offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4); + +// dJointSetPRAnchorOffset (jId, 0, 0, 0, +// -offset*axis[0],-offset*axis[1],-offset*axis[2]); +// CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4); + +// dBodySetPosition (bId1, 0, 0, 0); +// CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4); + } + + // Move 1st body offset unit in the opposite X direction + // + // X-------> X---------> <--- Axis + // B1 => B1 + // + // Start with a Offset of -offset unit + // + // X-------> X---------> <--- Axis + // B1 => B1 + TEST_FIXTURE (Fixture_dxJointPR_B1_At_Zero_Axis_Inverse_of_X, + test_dJointSetPRAxisOffset_B1_Minus_OffsetUnit) + { + dJointSetPRAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4); + + dBodySetPosition (bId1, -offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4); + +// dJointSetPRAnchorOffset (jId, 0, 0, 0, +// offset*axis[0],offset*axis[1],offset*axis[2]); +// CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4); + +// dBodySetPosition (bId1, 0, 0, 0); +// CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4); + } + + + + + // Compare only one body to 2 bodies with one fixed. + // + // The body are positionned at (0, 0, 0), with no rotation + // The joint is a PR Joint + // Axis is along the X axis + // Anchor at (0, 0, 0) + struct Fixture_dxJointPR_Compare_Body_At_Zero_AxisP_Along_Y + { + Fixture_dxJointPR_Compare_Body_At_Zero_AxisP_Along_Y() + { + wId = dWorldCreate(); + + bId1_12 = dBodyCreate (wId); + dBodySetPosition (bId1_12, 0, 0, 0); + + bId2_12 = dBodyCreate (wId); + dBodySetPosition (bId2_12, 0, 0, 0); + // The force will be added in the function since it is not + // always on the same body + + jId_12 = dJointCreatePR (wId, 0); + dJointAttach(jId_12, bId1_12, bId2_12); + + fixed = dJointCreateFixed (wId, 0); + + + + jId = dJointCreatePR (wId, 0); + + bId = dBodyCreate (wId); + dBodySetPosition (bId, 0, 0, 0); + + // Linear velocity along the prismatic axis; + dVector3 axis; + dJointGetPRAxis1(jId_12, axis); + dJointSetPRAxis1(jId, axis[0], axis[1], axis[2]); + dBodySetLinearVel (bId, 4*axis[0], 4*axis[1], 4*axis[2]); + } + + ~Fixture_dxJointPR_Compare_Body_At_Zero_AxisP_Along_Y() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1_12; + dBodyID bId2_12; + + dJointID jId_12; // Joint with 2 bodies + + dJointID fixed; + + + + dBodyID bId; + dJointID jId; // Joint with one body + }; + + + TEST_FIXTURE (Fixture_dxJointPR_Compare_Body_At_Zero_AxisP_Along_Y, + test_dJointSetPRPositionRate_Only_B1) + { + // Linear velocity along the prismatic axis; + dVector3 axis; + dJointGetPRAxis1(jId_12, axis); + dBodySetLinearVel (bId1_12, 4*axis[0], 4*axis[1], 4*axis[2]); + + dJointAttach(jId_12, bId1_12, bId2_12); + + dJointAttach(fixed, 0, bId2_12); + dJointSetFixed(fixed); + + dJointAttach(jId, bId, 0); + + CHECK_CLOSE(dJointGetPRPositionRate(jId_12), dJointGetPRPositionRate(jId), 1e-2); + + CHECK_CLOSE(dJointGetPRAngleRate(jId_12), dJointGetPRAngleRate(jId), 1e-2); + } + + + TEST_FIXTURE (Fixture_dxJointPR_Compare_Body_At_Zero_AxisP_Along_Y, + test_dJointSetPRPositionRate_Only_B2) + { + // Linear velocity along the prismatic axis; + dVector3 axis; + dJointGetPRAxis1(jId_12, axis); + dBodySetLinearVel (bId2_12, 4*axis[0], 4*axis[1], 4*axis[2]); + + dJointAttach(jId_12, bId1_12, bId2_12); + + dJointAttach(fixed, bId1_12, 0); + dJointSetFixed(fixed); + + dJointAttach(jId, 0, bId); + + CHECK_CLOSE(dJointGetPRPositionRate(jId_12), dJointGetPRPositionRate(jId), 1e-2); + CHECK_CLOSE(dJointGetPRAngleRate(jId_12), dJointGetPRAngleRate(jId), 1e-2); + } + + + + + + // Only body 2 + // The body are positionned at (0, 0, 0), with no rotation + // The joint is a PR Joint + // Axis is along the X axis + // Anchor at (0, 0, 0) + struct Fixture_dxJointPR_B2_At_Zero_Axis_Along_X + { + Fixture_dxJointPR_B2_At_Zero_Axis_Along_X() + { + wId = dWorldCreate(); + + bId2 = dBodyCreate (wId); + dBodySetPosition (bId2, 0, 0, 0); + + jId = dJointCreatePR (wId, 0); + joint = (dxJointPR*) jId; + + + dJointAttach (jId, NULL, bId2); + + dJointSetPRAxis1 (jId, axis[0], axis[1], axis[2]); + } + + ~Fixture_dxJointPR_B2_At_Zero_Axis_Along_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId2; + + dJointID jId; + dxJointPR* joint; + + static const dVector3 axis; + + static const dReal offset; + }; + const dVector3 Fixture_dxJointPR_B2_At_Zero_Axis_Along_X::axis = + { + 1, 0, 0 + }; + const dReal Fixture_dxJointPR_B2_At_Zero_Axis_Along_X::offset = REAL (3.1); + + // Move 2nd body offset unit in the X direction + // + // X-------> X---------> Axis --> + // B2 => B2 + // + // Start with a Offset of offset unit + // + // X-------> X---------> Axis --> + // B2 => B2 + TEST_FIXTURE (Fixture_dxJointPR_B2_At_Zero_Axis_Along_X, + test_dJointSetPRAxisOffset_B2_OffsetUnit) + { + dJointSetPRAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4); + + dBodySetPosition (bId2, offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4); + +// dJointSetPRAnchorOffset (jId, 0, 0, 0, +// -offset*axis[0],-offset*axis[1],-offset*axis[2]); +// CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4); + +// dBodySetPosition (bId2, 0, 0, 0); +// CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4); + } + + // Move 2nd body offset unit in the opposite X direction + // + // X-------> X---------> Axis --> + // B2 => B2 + // + // Start with a Offset of -offset unit + // + // X-------> X---------> Axis --> + // B2 => B2 + TEST_FIXTURE (Fixture_dxJointPR_B2_At_Zero_Axis_Along_X, + test_dJointSetPRAxisOffset_B2_Minus_OffsetUnit) + { + dJointSetPRAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4); + + dBodySetPosition (bId2, -offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4); + +// dJointSetPRAnchorOffset (jId, 0, 0, 0, +// offset*axis[0],offset*axis[1],offset*axis[2]); +// CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4); + +// dBodySetPosition (bId2, 0, 0, 0); +// CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4); + } + + // Only body 2 + // The body are positionned at (0, 0, 0), with no rotation + // The joint is a PR Joint + // Axis is in the opposite X axis + // Anchor at (0, 0, 0) + struct Fixture_dxJointPR_B2_At_Zero_Axis_Inverse_of_X + { + Fixture_dxJointPR_B2_At_Zero_Axis_Inverse_of_X() + { + wId = dWorldCreate(); + + bId2 = dBodyCreate (wId); + dBodySetPosition (bId2, 0, 0, 0); + + jId = dJointCreatePR (wId, 0); + joint = (dxJointPR*) jId; + + + dJointAttach (jId, NULL, bId2); + + dJointSetPRAxis1 (jId, axis[0], axis[1], axis[2]); + } + + ~Fixture_dxJointPR_B2_At_Zero_Axis_Inverse_of_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId2; + + dJointID jId; + dxJointPR* joint; + + static const dVector3 axis; + + static const dReal offset; + }; + const dVector3 Fixture_dxJointPR_B2_At_Zero_Axis_Inverse_of_X::axis = + { + -1, 0, 0 + }; + const dReal Fixture_dxJointPR_B2_At_Zero_Axis_Inverse_of_X::offset = REAL (3.1); + + // Move 2nd body offset unit in the X direction + // + // X-------> X---------> <--- Axis + // B2 => B2 + // + // Start with a Offset of offset unit + // + // X-------> X---------> <--- Axis + // B2 => B2 + TEST_FIXTURE (Fixture_dxJointPR_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetPRAxisOffset_B2_OffsetUnit) + { + dJointSetPRAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4); + + dBodySetPosition (bId2, offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4); + +// dJointSetPRAnchorOffset (jId, 0, 0, 0, +// offset*axis[0],offset*axis[1],offset*axis[2]); +// CHECK_CLOSE (offset, dJointGetPRPosition (jId), 1e-4); + +// dBodySetPosition (bId2, 0, 0, 0); +// CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4); +// dJointSetPRAxisDelta (jId, 1, 0, 0, 0, 0, 0); + } + + // Move 1st body offset unit in the opposite X direction + // + // X-------> X---------> <--- Axis + // B2 => B2 + // + // Start with a Offset of -offset unit + // + // X-------> X---------> <--- Axis + // B2 => B2 + TEST_FIXTURE (Fixture_dxJointPR_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetPRAxisOffset_B2_Minus_OffsetUnit) + { + dJointSetPRAnchor (jId, 0, 0, 0); + + CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4); + + dBodySetPosition (bId2, -offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4); + +// dJointSetPRAnchorOffset (jId, 0, 0, 0, +// -offset*axis[0],-offset*axis[1],-offset*axis[2]); +// CHECK_CLOSE (-offset, dJointGetPRPosition (jId), 1e-4); + +// dBodySetPosition (bId2, 0, 0, 0); +// CHECK_CLOSE (0.0, dJointGetPRPosition (jId), 1e-4); + } + + + // The 2 bodies are positionned at (0, 0, 0), and (0, 0, 0) + // The bodis have rotation of 27deg around some axis. + // The joint is a PR Joint + // Axis is along the X axis + // Anchor at (0, 0, 0) + struct Fixture_dxJointPR_B1_and_B2_Random_Orientation_At_Zero_Axis_Along_X + { + Fixture_dxJointPR_B1_and_B2_Random_Orientation_At_Zero_Axis_Along_X() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate (wId); + dBodySetPosition (bId1, 0, 0, 0); + + bId2 = dBodyCreate (wId); + dBodySetPosition (bId2, 0, 0, 0); + + dMatrix3 R; + + dVector3 axis; // Random axis + + axis[0] = REAL(0.53); + axis[1] = -REAL(0.71); + axis[2] = REAL(0.43); + dNormalize3(axis); + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], + REAL(0.47123)); // 27deg + dBodySetRotation (bId1, R); + + + axis[0] = REAL(1.2); + axis[1] = REAL(0.87); + axis[2] = -REAL(0.33); + dNormalize3(axis); + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], + REAL(0.47123)); // 27deg + dBodySetRotation (bId2, R); + + jId = dJointCreatePR (wId, 0); + joint = (dxJointPR*) jId; + + + dJointAttach (jId, bId1, bId2); + } + + ~Fixture_dxJointPR_B1_and_B2_Random_Orientation_At_Zero_Axis_Along_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + + dJointID jId; + dxJointPR* joint; + }; + + // Test is dJointSetPRAxis and dJointGetPRAxis return same value + TEST_FIXTURE (Fixture_dxJointPR_B1_and_B2_Random_Orientation_At_Zero_Axis_Along_X, + test_dJointSetGetPRAxis) + { + dVector3 axisOrig, axis; + + + dJointGetPRAxis1 (jId, axisOrig); + dJointGetPRAxis1 (jId, axis); + dJointSetPRAxis1 (jId, axis[0], axis[1], axis[2]); + dJointGetPRAxis1 (jId, axis); + CHECK_CLOSE (axis[0], axisOrig[0] , 1e-4); + CHECK_CLOSE (axis[1], axisOrig[1] , 1e-4); + CHECK_CLOSE (axis[2], axisOrig[2] , 1e-4); + + + dJointGetPRAxis2 (jId, axisOrig); + dJointGetPRAxis2(jId, axis); + dJointSetPRAxis2 (jId, axis[0], axis[1], axis[2]); + dJointGetPRAxis2 (jId, axis); + CHECK_CLOSE (axis[0], axisOrig[0] , 1e-4); + CHECK_CLOSE (axis[1], axisOrig[1] , 1e-4); + CHECK_CLOSE (axis[2], axisOrig[2] , 1e-4); + } + + + + // Create 2 bodies attached by a PR joint + // Axis is along the X axis (Default value + // Anchor at (0, 0, 0) (Default value) + // + // ^Y + // | + // * Body2 + // | + // | + // Body1 | + // * Z--------> + struct dxJointPR_Test_Initialization + { + dxJointPR_Test_Initialization() + { + wId = dWorldCreate(); + + // Remove gravity to have the only force be the force of the joint + dWorldSetGravity(wId, 0,0,0); + + for (int j=0; j<2; ++j) + { + bId[j][0] = dBodyCreate (wId); + dBodySetPosition (bId[j][0], -1, -2, -3); + + bId[j][1] = dBodyCreate (wId); + dBodySetPosition (bId[j][1], 11, 22, 33); + + + dMatrix3 R; + dVector3 axis; // Random axis + + axis[0] = REAL(0.53); + axis[1] = -REAL(0.71); + axis[2] = REAL(0.43); + dNormalize3(axis); + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], + REAL(0.47123)); // 27deg + dBodySetRotation (bId[j][0], R); + + + axis[0] = REAL(1.2); + axis[1] = REAL(0.87); + axis[2] = -REAL(0.33); + dNormalize3(axis); + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], + REAL(0.47123)); // 27deg + dBodySetRotation (bId[j][1], R); + + + jId[j] = dJointCreatePR (wId, 0); + dJointAttach (jId[j], bId[j][0], bId[j][1]); + } + } + + ~dxJointPR_Test_Initialization() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId[2][2]; + + + dJointID jId[2]; + + }; + + + // Test if setting a PR with its default values + // will behave the same as a default PR joint + TEST_FIXTURE (dxJointPR_Test_Initialization, + test_PR_Initialization) + { + using namespace std; + + dVector3 axis; + dJointGetPRAxis1(jId[1], axis); + dJointSetPRAxis1(jId[1], axis[0], axis[1], axis[2]); + + dJointGetPRAxis2(jId[1], axis); + dJointSetPRAxis2(jId[1], axis[0], axis[1], axis[2]); + + dVector3 anchor; + dJointGetPRAnchor(jId[1], anchor); + dJointSetPRAnchor(jId[1], anchor[0], anchor[1], anchor[2]); + + for (int b=0; b<2; ++b) + { + // Compare body b of the first joint with its equivalent on the + // second joint + const dReal *qA = dBodyGetQuaternion(bId[0][b]); + const dReal *qB = dBodyGetQuaternion(bId[1][b]); + CHECK_CLOSE (qA[0], qB[0], 1e-4); + CHECK_CLOSE (qA[1], qB[1], 1e-4); + CHECK_CLOSE (qA[2], qB[2], 1e-4); + CHECK_CLOSE (qA[3], qB[3], 1e-4); + } + + dWorldStep (wId,0.5); + dWorldStep (wId,0.5); + dWorldStep (wId,0.5); + dWorldStep (wId,0.5); + + for (int b=0; b<2; ++b) + { + // Compare body b of the first joint with its equivalent on the + // second joint + const dReal *qA = dBodyGetQuaternion(bId[0][b]); + const dReal *qB = dBodyGetQuaternion(bId[1][b]); + CHECK_CLOSE (qA[0], qB[0], 1e-4); + CHECK_CLOSE (qA[1], qB[1], 1e-4); + CHECK_CLOSE (qA[2], qB[2], 1e-4); + CHECK_CLOSE (qA[3], qB[3], 1e-4); + + + const dReal *posA = dBodyGetPosition(bId[0][b]); + const dReal *posB = dBodyGetPosition(bId[1][b]); + CHECK_CLOSE (posA[0], posB[0], 1e-4); + CHECK_CLOSE (posA[1], posB[1], 1e-4); + CHECK_CLOSE (posA[2], posB[2], 1e-4); + CHECK_CLOSE (posA[3], posB[3], 1e-4); + } + } + + + + + + + // This test compare the result of a slider with 2 bodies where body body 2 is + // fixed to the world to a slider with only one body at position 1. + // + // Test the limits [-1, 0.25] when only one body at is attached to the joint + // using dJointAttache(jId, bId, 0); + // + TEST_FIXTURE(Fixture_dxJointPR_Compare_Body_At_Zero_AxisP_Along_Y, + test_Limit_minus1_025_One_Body_on_left) + { + // Linear velocity along the prismatic axis; + dVector3 axis; + dJointGetPRAxis1(jId_12, axis); + dBodySetLinearVel (bId1_12, 4*axis[0], 4*axis[1], 4*axis[2]); + + dJointAttach(jId_12, bId1_12, bId2_12); + dJointSetPRParam(jId_12, dParamLoStop, -1); + dJointSetPRParam(jId_12, dParamHiStop, 0.25); + + dJointAttach(fixed, 0, bId2_12); + dJointSetFixed(fixed); + + dJointAttach(jId, bId, 0); + dJointSetPRParam(jId, dParamLoStop, -1); + dJointSetPRParam(jId, dParamHiStop, 0.25); + + + for (int i=0; i<50; ++i) + dWorldStep(wId, 1.0); + + + const dReal *pos1_12 = dBodyGetPosition(bId1_12); + const dReal *pos = dBodyGetPosition(bId); + + CHECK_CLOSE (pos1_12[0], pos[0], 1e-2); + CHECK_CLOSE (pos1_12[1], pos[1], 1e-2); + CHECK_CLOSE (pos1_12[2], pos[2], 1e-2); + + const dReal *q1_12 = dBodyGetQuaternion(bId1_12); + const dReal *q = dBodyGetQuaternion(bId); + + CHECK_CLOSE (q1_12[0], q[0], 1e-4); + CHECK_CLOSE (q1_12[1], q[1], 1e-4); + CHECK_CLOSE (q1_12[2], q[2], 1e-4); + CHECK_CLOSE (q1_12[3], q[3], 1e-4); + } + + + + // This test compare the result of a slider with 2 bodies where body body 1 is + // fixed to the world to a slider with only one body at position 2. + // + // Test the limits [-1, 0.25] when only one body at is attached to the joint + // using dJointAttache(jId, 0, bId); + // + TEST_FIXTURE(Fixture_dxJointPR_Compare_Body_At_Zero_AxisP_Along_Y, + test_Limit_minus1_025_One_Body_on_right) + { + // Linear velocity along the prismatic axis; + dVector3 axis; + dJointGetPRAxis1(jId_12, axis); + dBodySetLinearVel (bId2_12, 4*axis[0], 4*axis[1], 4*axis[2]); + + dJointAttach(jId_12, bId1_12, bId2_12); + dJointSetPRParam(jId_12, dParamLoStop, -1); + dJointSetPRParam(jId_12, dParamHiStop, 0.25); + + dJointAttach(fixed, bId1_12, 0); + dJointSetFixed(fixed); + + + dJointAttach(jId, 0, bId); + dJointSetPRParam(jId, dParamLoStop, -1); + dJointSetPRParam(jId, dParamHiStop, 0.25); + + for (int i=0; i<50; ++i) + dWorldStep(wId, 1.0); + + + const dReal *pos2_12 = dBodyGetPosition(bId2_12); + const dReal *pos = dBodyGetPosition(bId); + + CHECK_CLOSE (pos2_12[0], pos[0], 1e-2); + CHECK_CLOSE (pos2_12[1], pos[1], 1e-2); + CHECK_CLOSE (pos2_12[2], pos[2], 1e-2); + + + const dReal *q2_12 = dBodyGetQuaternion(bId2_12); + const dReal *q = dBodyGetQuaternion(bId); + + CHECK_CLOSE (q2_12[0], q[0], 1e-4); + CHECK_CLOSE (q2_12[1], q[1], 1e-4); + CHECK_CLOSE (q2_12[2], q[2], 1e-4); + CHECK_CLOSE (q2_12[3], q[3], 1e-4); + } + + + + // This test compare the result of a slider with 2 bodies where body body 2 is + // fixed to the world to a slider with only one body at position 1. + // + // Test the limits [0, 0] when only one body at is attached to the joint + // using dJointAttache(jId, bId, 0); + // + // The body should not move since their is no room between the two limits + // + TEST_FIXTURE(Fixture_dxJointPR_Compare_Body_At_Zero_AxisP_Along_Y, + test_Limit_0_0_One_Body_on_left) + { + // Linear velocity along the prismatic axis; + dVector3 axis; + dJointGetPRAxis1(jId_12, axis); + dBodySetLinearVel (bId1_12, 4*axis[0], 4*axis[1], 4*axis[2]); + + dJointAttach(jId_12, bId1_12, bId2_12); + dJointSetPRParam(jId_12, dParamLoStop, 0); + dJointSetPRParam(jId_12, dParamHiStop, 0); + + dJointAttach(fixed, 0, bId2_12); + dJointSetFixed(fixed); + + + dJointAttach(jId, bId, 0); + dJointSetPRParam(jId, dParamLoStop, 0); + dJointSetPRParam(jId, dParamHiStop, 0); + + for (int i=0; i<50; ++i) + dWorldStep(wId, 1.0); + + + + const dReal *pos1_12 = dBodyGetPosition(bId1_12); + const dReal *pos = dBodyGetPosition(bId); + + CHECK_CLOSE (pos1_12[0], pos[0], 1e-4); + CHECK_CLOSE (pos1_12[1], pos[1], 1e-4); + CHECK_CLOSE (pos1_12[2], pos[2], 1e-4); + + CHECK_CLOSE (0, pos[0], 1e-4); + CHECK_CLOSE (0, pos[1], 1e-4); + CHECK_CLOSE (0, pos[2], 1e-4); + + + const dReal *q1_12 = dBodyGetQuaternion(bId1_12); + const dReal *q = dBodyGetQuaternion(bId); + + CHECK_CLOSE (q1_12[0], q[0], 1e-4); + CHECK_CLOSE (q1_12[1], q[1], 1e-4); + CHECK_CLOSE (q1_12[2], q[2], 1e-4); + CHECK_CLOSE (q1_12[3], q[3], 1e-4); + } + + + // This test compare the result of a slider with 2 bodies where body body 1 is + // fixed to the world to a slider with only one body at position 2. + // + // Test the limits [0, 0] when only one body at is attached to the joint + // using dJointAttache(jId, 0, bId); + // + // The body should not move since their is no room between the two limits + // + TEST_FIXTURE(Fixture_dxJointPR_Compare_Body_At_Zero_AxisP_Along_Y, + test_Limit_0_0_One_Body_on_right) + { + // Linear velocity along the prismatic axis; + dVector3 axis; + dJointGetPRAxis1(jId_12, axis); + dBodySetLinearVel (bId2_12, 4*axis[0], 4*axis[1], 4*axis[2]); + + dJointAttach(jId_12, bId1_12, bId2_12); + dJointSetPRParam(jId_12, dParamLoStop, 0); + dJointSetPRParam(jId_12, dParamHiStop, 0); + + dJointAttach(fixed, bId1_12, 0); + dJointSetFixed(fixed); + + + dJointAttach(jId, 0, bId); + dJointSetPRParam(jId, dParamLoStop, 0); + dJointSetPRParam(jId, dParamHiStop, 0); + + for (int i=0; i<50; ++i) + { + dWorldStep(wId, 1.0); + } + + + const dReal *pos2_12 = dBodyGetPosition(bId2_12); + const dReal *pos = dBodyGetPosition(bId); + + CHECK_CLOSE (pos2_12[0], pos[0], 1e-4); + CHECK_CLOSE (pos2_12[1], pos[1], 1e-4); + CHECK_CLOSE (pos2_12[2], pos[2], 1e-4); + + CHECK_CLOSE (0, pos[0], 1e-4); + CHECK_CLOSE (0, pos[1], 1e-4); + CHECK_CLOSE (0, pos[2], 1e-4); + + + const dReal *q2_12 = dBodyGetQuaternion(bId2_12); + const dReal *q = dBodyGetQuaternion(bId); + + CHECK_CLOSE (q2_12[0], q[0], 1e-4); + CHECK_CLOSE (q2_12[1], q[1], 1e-4); + CHECK_CLOSE (q2_12[2], q[2], 1e-4); + CHECK_CLOSE (q2_12[3], q[3], 1e-4); + } + +} // End of SUITE TestdxJointPR + diff --git a/libs/ode-0.16.1/tests/joints/pu.cpp b/libs/ode-0.16.1/tests/joints/pu.cpp new file mode 100644 index 0000000..6d97a07 --- /dev/null +++ b/libs/ode-0.16.1/tests/joints/pu.cpp @@ -0,0 +1,920 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ +//234567890123456789012345678901234567890123456789012345678901234567890123456789 +// 1 2 3 4 5 6 7 + +//////////////////////////////////////////////////////////////////////////////// +// This file create unit test for some of the functions found in: +// ode/src/joinst/pu.cpp +// +// +//////////////////////////////////////////////////////////////////////////////// + +#include <UnitTest++.h> +#include <ode/ode.h> + +#include "../../ode/src/config.h" +#include "../../ode/src/joints/pu.h" + +SUITE (TestdxJointPU) +{ + // The 2 bodies are positionned at (0, 0, 0), and (0, 0, 0) + // The second body has a rotation of 27deg around X axis. + // The joint is a PU Joint + // Axis is along the X axis + // Anchor at (0, 0, 0) + struct Fixture_dxJointPU_B1_and_B2_At_Zero_Axis_Along_X + { + Fixture_dxJointPU_B1_and_B2_At_Zero_Axis_Along_X() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate (wId); + dBodySetPosition (bId1, 0, 0, 0); + + bId2 = dBodyCreate (wId); + dBodySetPosition (bId2, 0, 0, 0); + + dMatrix3 R; + + dRFromAxisAndAngle (R, 1, 0, 0, REAL(0.47123)); // 27deg + dBodySetRotation (bId2, R); + + jId = dJointCreatePU (wId, 0); + joint = (dxJointPU*) jId; + + + dJointAttach (jId, bId1, bId2); + } + + ~Fixture_dxJointPU_B1_and_B2_At_Zero_Axis_Along_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + + dJointID jId; + dxJointPU* joint; + }; + + // Test is dJointSetPUAxis and dJointGetPUAxis return same value + TEST_FIXTURE (Fixture_dxJointPU_B1_and_B2_At_Zero_Axis_Along_X, + test_dJointSetGetPUAxis) + { + dVector3 axisOrig, axis; + + + dJointGetPUAxis1 (jId, axisOrig); + dJointGetPUAxis1 (jId, axis); + dJointSetPUAxis1 (jId, axis[0], axis[1], axis[2]); + dJointGetPUAxis1 (jId, axis); + CHECK_CLOSE (axis[0], axisOrig[0] , 1e-4); + CHECK_CLOSE (axis[1], axisOrig[1] , 1e-4); + CHECK_CLOSE (axis[2], axisOrig[2] , 1e-4); + + + dJointGetPUAxis2 (jId, axisOrig); + dJointGetPUAxis2(jId, axis); + dJointSetPUAxis2 (jId, axis[0], axis[1], axis[2]); + dJointGetPUAxis2 (jId, axis); + CHECK_CLOSE (axis[0], axisOrig[0] , 1e-4); + CHECK_CLOSE (axis[1], axisOrig[1] , 1e-4); + CHECK_CLOSE (axis[2], axisOrig[2] , 1e-4); + + + dJointGetPUAxis3 (jId, axisOrig); + dJointGetPUAxis3(jId, axis); + dJointSetPUAxis3 (jId, axis[0], axis[1], axis[2]); + dJointGetPUAxis3 (jId, axis); + CHECK_CLOSE (axis[0], axisOrig[0] , 1e-4); + CHECK_CLOSE (axis[1], axisOrig[1] , 1e-4); + CHECK_CLOSE (axis[2], axisOrig[2] , 1e-4); + } + + + + + + + + + + + + + + + // The joint is a PU Joint + // Default joint value + // The two bodies at at (0, 0, 0) + struct Fixture_dxJointPU_B1_and_B2_At_Zero + { + Fixture_dxJointPU_B1_and_B2_At_Zero() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate (wId); + dBodySetPosition (bId1, 0, 0, 0); + + bId2 = dBodyCreate (wId); + dBodySetPosition (bId2, 0, 0, 0); + + jId = dJointCreatePU (wId, 0); + joint = (dxJointPU*) jId; + + + dJointAttach (jId, bId1, bId2); + } + + ~Fixture_dxJointPU_B1_and_B2_At_Zero() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + + dJointID jId; + dxJointPU* joint; + + static const dReal offset; + }; + const dReal Fixture_dxJointPU_B1_and_B2_At_Zero::offset = REAL (3.1); + + + + + + // Move 1st body offset unit in the X direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + // + // Start with a Offset of offset unit + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointPU_B1_and_B2_At_Zero, + test_dJointSetPUAxisOffset_B1_3Unit) + { + CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4); + + dBodySetPosition (bId1, offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetPUPosition (jId), 1e-4); + + dVector3 axis; + dJointGetPUAxisP (jId, axis); + + dJointSetPUAnchorOffset (jId, 0, 0, 0, + offset*axis[0],offset*axis[1],offset*axis[2]); + CHECK_CLOSE (offset, dJointGetPUPosition (jId), 1e-4); + + dBodySetPosition (bId1, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4); + } + + // Move 1st body offset unit in the opposite X direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + // + // Start with a Offset of -offset unit + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointPU_B1_and_B2_At_Zero, + test_dJointSetPUAxisOffset_B1_Minus_3Unit) + { + CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4); + + dBodySetPosition (bId1, -offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetPUPosition (jId), 1e-4); + + dVector3 axis; + dJointGetPUAxisP (jId, axis); + dJointSetPUAnchorOffset (jId, 0, 0, 0, + -offset*axis[0],-offset*axis[1],-offset*axis[2]); + CHECK_CLOSE (-offset, dJointGetPUPosition (jId), 1e-4); + + dBodySetPosition (bId1, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4); + } + + // Move 2nd body offset unit in the X direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + // + // Start with a Offset of offset unit + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointPU_B1_and_B2_At_Zero, + test_dJointSetPUAxisOffset_B2_3Unit) + { + CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4); + + dBodySetPosition (bId2, offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetPUPosition (jId), 1e-4); + + dVector3 axis; + dJointGetPUAxisP (jId, axis); + dJointSetPUAnchorOffset (jId, 0, 0, 0, + -offset*axis[0],-offset*axis[1],-offset*axis[2]); + CHECK_CLOSE (-offset, dJointGetPUPosition (jId), 1e-4); + + dBodySetPosition (bId2, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4); + } + + // Move 2nd body offset unit in the opposite X direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + // + // Start with a Offset of -offset unit + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointPU_B1_and_B2_At_Zero, + test_dJointSetPUAxisOffset_B2_Minus_3Unit) + { + CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4); + + dBodySetPosition (bId2, -offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetPUPosition (jId), 1e-4); + + dVector3 axis; + dJointGetPUAxisP (jId, axis); + dJointSetPUAnchorOffset (jId, 0, 0, 0, + offset*axis[0],offset*axis[1],offset*axis[2]); + CHECK_CLOSE (offset, dJointGetPUPosition (jId), 1e-4); + + dBodySetPosition (bId2, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4); + } + + + + // Attach only one body at position 1 to the joint dJointAttach (jId, bId, 0) + // Move 1st body offset unit in the X direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // + // Start with a Offset of offset unit + // + // X-------> X---------> Axis --> + // B1 => B1 + TEST_FIXTURE (Fixture_dxJointPU_B1_and_B2_At_Zero, + test_dJointSetPUAxisOffset_B1_OffsetUnit) + { + dJointAttach (jId, bId1, 0); + + CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4); + + dBodySetPosition (bId1, offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetPUPosition (jId), 1e-4); + + dVector3 axis; + dJointGetPUAxisP (jId, axis); + dJointSetPUAnchorOffset (jId, 0, 0, 0, + offset*axis[0],offset*axis[1],offset*axis[2]); + CHECK_CLOSE (offset, dJointGetPUPosition (jId), 1e-4); + + dBodySetPosition (bId1, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4); + } + + // Attache only one body at position 1 to the joint dJointAttach (jId, bId, 0) + // Move 1st body offset unit in the opposite X direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // + // Start with a Offset of -offset unit + // + // X-------> X---------> Axis --> + // B1 => B1 + TEST_FIXTURE (Fixture_dxJointPU_B1_and_B2_At_Zero, + test_dJointSetPUAxisOffset_B1_Minus_OffsetUnit) + { + dJointAttach (jId, bId1, 0); + + CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4); + + dBodySetPosition (bId1, -offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetPUPosition (jId), 1e-4); + + dVector3 axis; + dJointGetPUAxisP (jId, axis); + dJointSetPUAnchorOffset (jId, 0, 0, 0, + -offset*axis[0],-offset*axis[1],-offset*axis[2]); + CHECK_CLOSE (-offset, dJointGetPUPosition (jId), 1e-4); + + dBodySetPosition (bId1, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4); + } + + + + // Attache only one body at position 2 to the joint dJointAttach (jId, 0, bId) + // Move 1st body offset unit in the X direction + // + // X-------> X---------> Axis --> + // B2 => B2 + // + // Start with a Offset of offset unit + // + // X-------> X---------> Axis --> + // B2 => B2 + TEST_FIXTURE (Fixture_dxJointPU_B1_and_B2_At_Zero, + test_dJointSetPUAxisOffset_B2_OffsetUnit) + { + dJointAttach (jId, 0, bId2); + + CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4); + + dBodySetPosition (bId2, offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetPUPosition (jId), 1e-4); + + dVector3 axis; + dJointGetPUAxisP (jId, axis); + dJointSetPUAnchorOffset (jId, 0, 0, 0, + -offset*axis[0], -offset*axis[1], -offset*axis[2]); + CHECK_CLOSE (-offset, dJointGetPUPosition (jId), 1e-4); + + dBodySetPosition (bId2, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4); + } + + // Attache only one body at position 2 to the joint dJointAttach (jId, 0, bId) + // Move 1st body offset unit in the opposite X direction + // + // X-------> X---------> Axis --> + // B2 => B2 + // + // Start with a Offset of -offset unit + // + // X-------> X---------> Axis --> + // B2 => B2 + TEST_FIXTURE (Fixture_dxJointPU_B1_and_B2_At_Zero, + test_dJointSetPUAxisOffset_B2_Minus_OffsetUnit) + { + dJointAttach (jId, 0, bId2); + + CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4); + + dBodySetPosition (bId2, -offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetPUPosition (jId), 1e-4); + + dVector3 axis; + dJointGetPUAxisP (jId, axis); + dJointSetPUAnchorOffset (jId, 0, 0, 0, + offset*axis[0], offset*axis[1], offset*axis[2]); + CHECK_CLOSE (offset, dJointGetPUPosition (jId), 1e-4); + + dBodySetPosition (bId2, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4); + } + + + + + // Only one body + // The body are positionned at (0, 0, 0), with no rotation + // The joint is a PU Joint + // Axis is in the oppsite X axis + // Anchor at (0, 0, 0) + // N.B. By default the body is attached at position 1 on the joint + // dJointAttach (jId, bId, 0); + struct Fixture_dxJointPU_One_Body_At_Zero_Axis_Inverse_of_X + { + Fixture_dxJointPU_One_Body_At_Zero_Axis_Inverse_of_X() + { + wId = dWorldCreate(); + + bId = dBodyCreate (wId); + dBodySetPosition (bId, 0, 0, 0); + + jId = dJointCreatePU (wId, 0); + joint = (dxJointPU*) jId; + + + dJointAttach (jId, bId, NULL); + + dJointSetPUAxisP (jId, axis[0], axis[1], axis[2]); + } + + ~Fixture_dxJointPU_One_Body_At_Zero_Axis_Inverse_of_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId; + + dJointID jId; + dxJointPU* joint; + + static const dVector3 axis; + + static const dReal offset; + }; + const dVector3 Fixture_dxJointPU_One_Body_At_Zero_Axis_Inverse_of_X::axis = + { + -1, 0, 0 + }; + const dReal Fixture_dxJointPU_One_Body_At_Zero_Axis_Inverse_of_X::offset = REAL (3.1); + + + // Move 1st body offset unit in the X direction + // + // X-------> X---------> <--- Axis + // B1 => B1 + // + // Start with a Offset of offset unit + // + // X-------> X---------> <--- Axis + // B1 => B1 + TEST_FIXTURE (Fixture_dxJointPU_One_Body_At_Zero_Axis_Inverse_of_X, + test_dJointSetPUAxisOffset_B1_At_Position_1_OffsetUnit) + { + CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4); + + dBodySetPosition (bId, offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetPUPosition (jId), 1e-4); + + dJointSetPUAnchorOffset (jId, 0, 0, 0, + -offset*axis[0],-offset*axis[1],-offset*axis[2]); + CHECK_CLOSE (-offset, dJointGetPUPosition (jId), 1e-4); + + dBodySetPosition (bId, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4); + } + + // Move 1st body offset unit in the opposite X direction + // + // X-------> X---------> <--- Axis + // B1 => B1 + // + // Start with a Offset of -offset unit + // + // X-------> X---------> <--- Axis + // B1 => B1 + TEST_FIXTURE (Fixture_dxJointPU_One_Body_At_Zero_Axis_Inverse_of_X, + test_dJointSetPUAxisOffset_B1_Minus_OffsetUnit) + { + CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4); + + dBodySetPosition (bId, -offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetPUPosition (jId), 1e-4); + + dJointSetPUAnchorOffset (jId, 0, 0, 0, + offset*axis[0],offset*axis[1],offset*axis[2]); + CHECK_CLOSE (offset, dJointGetPUPosition (jId), 1e-4); + + dBodySetPosition (bId, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4); + } + + + // Move 1st body offset unit in the X direction + // + // X-------> X---------> <--- Axis + // B2 => B2 + // + // Start with a Offset of offset unit + // + // X-------> X---------> <--- Axis + // B2 => B2 + TEST_FIXTURE (Fixture_dxJointPU_One_Body_At_Zero_Axis_Inverse_of_X, + test_dJointSetPUAxisOffset_B2_OffsetUnit) + { + // By default it is attached to position 1 + // Now attach the body at positiojn 2 + dJointAttach(jId, 0, bId); + + CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4); + + dBodySetPosition (bId, offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetPUPosition (jId), 1e-4); + + dJointSetPUAnchorOffset (jId, 0, 0, 0, + offset*axis[0], offset*axis[1], offset*axis[2]); + CHECK_CLOSE (offset, dJointGetPUPosition (jId), 1e-4); + + dBodySetPosition (bId, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4); + } + + // Move 1st body offset unit in the opposite X direction + // + // X-------> X---------> <--- Axis + // B2 => B2 + // + // Start with a Offset of -offset unit + // + // X-------> X---------> <--- Axis + // B2 => B2 + TEST_FIXTURE (Fixture_dxJointPU_One_Body_At_Zero_Axis_Inverse_of_X, + test_dJointSetPUAxisOffset_B2_Minus_OffsetUnit) + { + // By default it is attached to position 1 + // Now attach the body at positiojn 2 + dJointAttach(jId, 0, bId); + + CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4); + + dBodySetPosition (bId, -offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetPUPosition (jId), 1e-4); + + dJointSetPUAnchorOffset (jId, 0, 0, 0, + -offset*axis[0], -offset*axis[1], -offset*axis[2]); + CHECK_CLOSE (-offset, dJointGetPUPosition (jId), 1e-4); + + dBodySetPosition (bId, 0, 0, 0); + CHECK_CLOSE (0.0, dJointGetPUPosition (jId), 1e-4); + } + + + + + + + + + + // Compare only one body to 2 bodies with one fixed. + // + // The body are positionned at (0, 0, 0), with no rotation + // The joint is a PU Joint with default values + struct Fixture_dxJointPU_Compare_One_Body_To_Two_Bodies_At_Zero + { + Fixture_dxJointPU_Compare_One_Body_To_Two_Bodies_At_Zero() + { + wId = dWorldCreate(); + + bId1_12 = dBodyCreate (wId); + dBodySetPosition (bId1_12, 0, 0, 0); + + bId2_12 = dBodyCreate (wId); + dBodySetPosition (bId2_12, 0, 0, 0); + // The force will be added in the function since it is not + // always on the same body + + jId_12 = dJointCreatePU (wId, 0); + dJointAttach(jId_12, bId1_12, bId2_12); + + fixed = dJointCreateFixed (wId, 0); + + + + jId = dJointCreatePU (wId, 0); + + bId = dBodyCreate (wId); + dBodySetPosition (bId, 0, 0, 0); + + // Linear velocity along the prismatic axis; + dVector3 axis; + dJointGetPUAxisP(jId_12, axis); + dJointSetPUAxisP(jId, axis[0], axis[1], axis[2]); + dBodySetLinearVel (bId, magnitude*axis[0], magnitude*axis[1], magnitude*axis[2]); + } + + ~Fixture_dxJointPU_Compare_One_Body_To_Two_Bodies_At_Zero() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1_12; + dBodyID bId2_12; + + dJointID jId_12; // Joint with 2 bodies + + dJointID fixed; + + + + dBodyID bId; + dJointID jId; // Joint with one body + + static const dReal magnitude; + }; + const dReal Fixture_dxJointPU_Compare_One_Body_To_Two_Bodies_At_Zero::magnitude = REAL (4.27); + + + TEST_FIXTURE (Fixture_dxJointPU_Compare_One_Body_To_Two_Bodies_At_Zero, + test_dJointSetPUPositionRate_Only_B1) + { + // Linear velocity along the prismatic axis; + dVector3 axis; + dJointGetPUAxisP(jId_12, axis); + dBodySetLinearVel (bId1_12, magnitude*axis[0], magnitude*axis[1], magnitude*axis[2]); + + dJointAttach(jId_12, bId1_12, bId2_12); + + dJointAttach(fixed, 0, bId2_12); + dJointSetFixed(fixed); + + dJointAttach(jId, bId, 0); + + CHECK_CLOSE(dJointGetPUPositionRate(jId_12), dJointGetPUPositionRate(jId), 1e-2); + } + + + TEST_FIXTURE (Fixture_dxJointPU_Compare_One_Body_To_Two_Bodies_At_Zero, + test_dJointSetPUPositionRate_Only_B2) + { + // Linear velocity along the prismatic axis; + dVector3 axis; + dJointGetPUAxisP(jId_12, axis); + dBodySetLinearVel (bId2_12, magnitude*axis[0], magnitude*axis[1], magnitude*axis[2]); + + dJointAttach(jId_12, bId1_12, bId2_12); + + dJointAttach(fixed, bId1_12, 0); + dJointSetFixed(fixed); + + dJointAttach(jId, 0, bId); + + CHECK_CLOSE(dJointGetPUPositionRate(jId_12), dJointGetPUPositionRate(jId), 1e-2); + } + + + + + + + + + // This test compare the result of a pu joint with 2 bodies where body body 2 is + // fixed to the world to a pu joint with only one body at position 1. + // + // Test the limits [-1, 0.25] when only one body at is attached to the joint + // using dJointAttache(jId, bId, 0); + // + TEST_FIXTURE(Fixture_dxJointPU_Compare_One_Body_To_Two_Bodies_At_Zero, + test_Limit_minus1_025_One_Body_on_left) + { + dVector3 axis; + dJointGetPUAxisP(jId_12, axis); + dJointSetPUAxisP(jId, axis[0], axis[1], axis[2]); + dBodySetLinearVel (bId1_12, magnitude*axis[0], magnitude*axis[1], magnitude*axis[2]); + + dJointAttach(jId_12, bId1_12, bId2_12); + dJointSetPUParam(jId_12, dParamLoStop3, -1); + dJointSetPUParam(jId_12, dParamHiStop3, 0.25); + + dJointAttach(fixed, 0, bId2_12); + dJointSetFixed(fixed); + + dJointAttach(jId, bId, 0); + dJointSetPUParam(jId, dParamLoStop3, -1); + dJointSetPUParam(jId, dParamHiStop3, 0.25); + + + for (int i=0; i<50; ++i) + dWorldStep(wId, 1.0); + + + const dReal *pos1_12 = dBodyGetPosition(bId1_12); + const dReal *pos = dBodyGetPosition(bId); + + CHECK_CLOSE (pos1_12[0], pos[0], 1e-2); + CHECK_CLOSE (pos1_12[1], pos[1], 1e-2); + CHECK_CLOSE (pos1_12[2], pos[2], 1e-2); + + const dReal *q1_12 = dBodyGetQuaternion(bId1_12); + const dReal *q = dBodyGetQuaternion(bId); + + CHECK_CLOSE (q1_12[0], q[0], 1e-4); + CHECK_CLOSE (q1_12[1], q[1], 1e-4); + CHECK_CLOSE (q1_12[2], q[2], 1e-4); + CHECK_CLOSE (q1_12[3], q[3], 1e-4); + + // Should be different than zero + CHECK( dJointGetPUPosition(jId_12) ); + CHECK( dJointGetPUPosition(jId) ); + + CHECK( dJointGetPUPositionRate(jId_12) ); + CHECK( dJointGetPUPositionRate(jId) ); + } + + + + // This test compare the result of a pu joint with 2 bodies where body body 1 is + // fixed to the world to a pu joint with only one body at position 2. + // + // Test the limits [-1, 0.25] when only one body at is attached to the joint + // using dJointAttache(jId, 0, bId); + // + TEST_FIXTURE(Fixture_dxJointPU_Compare_One_Body_To_Two_Bodies_At_Zero, + test_Limit_minus1_025_One_Body_on_right) + { + dVector3 axis; + dJointGetPUAxisP(jId_12, axis); + dJointSetPUAxisP(jId, axis[0], axis[1], axis[2]); + dBodySetLinearVel (bId2_12, magnitude*axis[0], magnitude*axis[1], magnitude*axis[2]); + + dJointAttach(jId_12, bId1_12, bId2_12); + dJointSetPUParam(jId_12, dParamLoStop3, -1); + dJointSetPUParam(jId_12, dParamHiStop3, 0.25); + + dJointAttach(fixed, bId1_12, 0); + dJointSetFixed(fixed); + + + dJointAttach(jId, 0, bId); + dJointSetPUParam(jId, dParamLoStop3, -1); + dJointSetPUParam(jId, dParamHiStop3, 0.25); + + for (int i=0; i<50; ++i) + dWorldStep(wId, 1.0); + + + const dReal *pos2_12 = dBodyGetPosition(bId2_12); + const dReal *pos = dBodyGetPosition(bId); + + CHECK_CLOSE (pos2_12[0], pos[0], 1e-2); + CHECK_CLOSE (pos2_12[1], pos[1], 1e-2); + CHECK_CLOSE (pos2_12[2], pos[2], 1e-2); + + + const dReal *q2_12 = dBodyGetQuaternion(bId2_12); + const dReal *q = dBodyGetQuaternion(bId); + + CHECK_CLOSE (q2_12[0], q[0], 1e-4); + CHECK_CLOSE (q2_12[1], q[1], 1e-4); + CHECK_CLOSE (q2_12[2], q[2], 1e-4); + CHECK_CLOSE (q2_12[3], q[3], 1e-4); + + // Should be different than zero + CHECK( dJointGetPUPosition(jId_12) ); + CHECK( dJointGetPUPosition(jId) ); + + CHECK( dJointGetPUPositionRate(jId_12) ); + CHECK( dJointGetPUPositionRate(jId) ); + } + + + + // This test compare the result of a pu joint with 2 bodies where body 2 is + // fixed to the world to a pu joint with only one body at position 1. + // + // Test the limits [0, 0] when only one body at is attached to the joint + // using dJointAttache(jId, bId, 0); + // + // The body should not move since their is no room between the two limits + // + TEST_FIXTURE(Fixture_dxJointPU_Compare_One_Body_To_Two_Bodies_At_Zero, + test_Limit_0_0_One_Body_on_left) + { + dVector3 axis; + dJointGetPUAxisP(jId_12, axis); + dJointSetPUAxisP(jId, axis[0], axis[1], axis[2]); + dBodySetLinearVel (bId1_12, magnitude*axis[0], magnitude*axis[1], magnitude*axis[2]); + + dJointAttach(jId_12, bId1_12, bId2_12); + dJointSetPUParam(jId_12, dParamLoStop3, 0); + dJointSetPUParam(jId_12, dParamHiStop3, 0); + + dJointAttach(fixed, 0, bId2_12); + dJointSetFixed(fixed); + + + dJointAttach(jId, bId, 0); + dJointSetPUParam(jId, dParamLoStop3, 0); + dJointSetPUParam(jId, dParamHiStop3, 0); + + for (int i=0; i<500; ++i) + dWorldStep(wId, 1.0); + + + const dReal *pos1_12 = dBodyGetPosition(bId1_12); + const dReal *pos = dBodyGetPosition(bId); + + CHECK_CLOSE (pos1_12[0], pos[0], 1e-4); + CHECK_CLOSE (pos1_12[1], pos[1], 1e-4); + CHECK_CLOSE (pos1_12[2], pos[2], 1e-4); + + CHECK_CLOSE (0, pos[0], 1e-4); + CHECK_CLOSE (0, pos[1], 1e-4); + CHECK_CLOSE (0, pos[2], 1e-4); + + + const dReal *q1_12 = dBodyGetQuaternion(bId1_12); + const dReal *q = dBodyGetQuaternion(bId); + + CHECK_CLOSE (q1_12[0], q[0], 1e-4); + CHECK_CLOSE (q1_12[1], q[1], 1e-4); + CHECK_CLOSE (q1_12[2], q[2], 1e-4); + CHECK_CLOSE (q1_12[3], q[3], 1e-4); + } + + + // This test compare the result of a pu joint with 2 bodies where body body 1 is + // fixed to the world to a pu joint with only one body at position 2. + // + // Test the limits [0, 0] when only one body at is attached to the joint + // using dJointAttache(jId, 0, bId); + // + // The body should not move since their is no room between the two limits + // + TEST_FIXTURE(Fixture_dxJointPU_Compare_One_Body_To_Two_Bodies_At_Zero, + test_Limit_0_0_One_Body_on_right) + { + dVector3 axis; + dJointGetPUAxisP(jId_12, axis); + dJointSetPUAxisP(jId, axis[0], axis[1], axis[2]); + dBodySetLinearVel (bId2_12, magnitude*axis[0], magnitude*axis[1], magnitude*axis[2]); + + dJointAttach(jId_12, bId1_12, bId2_12); + dJointSetPUParam(jId_12, dParamLoStop3, 0); + dJointSetPUParam(jId_12, dParamHiStop3, 0); + + dJointAttach(fixed, bId1_12, 0); + dJointSetFixed(fixed); + + + dJointAttach(jId, 0, bId); + dJointSetPUParam(jId, dParamLoStop3, 0); + dJointSetPUParam(jId, dParamHiStop3, 0); + + for (int i=0; i<500; ++i) + dWorldStep(wId, 1.0); + + const dReal *pos2_12 = dBodyGetPosition(bId2_12); + const dReal *pos = dBodyGetPosition(bId); + + CHECK_CLOSE (pos2_12[0], pos[0], 1e-4); + CHECK_CLOSE (pos2_12[1], pos[1], 1e-4); + CHECK_CLOSE (pos2_12[2], pos[2], 1e-4); + + CHECK_CLOSE (0, pos[0], 1e-4); + CHECK_CLOSE (0, pos[1], 1e-4); + CHECK_CLOSE (0, pos[2], 1e-4); + + + const dReal *q2_12 = dBodyGetQuaternion(bId2_12); + const dReal *q = dBodyGetQuaternion(bId); + + CHECK_CLOSE (q2_12[0], q[0], 1e-4); + CHECK_CLOSE (q2_12[1], q[1], 1e-4); + CHECK_CLOSE (q2_12[2], q[2], 1e-4); + CHECK_CLOSE (q2_12[3], q[3], 1e-4); + } + + +} // End of SUITE TestdxJointPU + diff --git a/libs/ode-0.16.1/tests/joints/slider.cpp b/libs/ode-0.16.1/tests/joints/slider.cpp new file mode 100644 index 0000000..fe57a55 --- /dev/null +++ b/libs/ode-0.16.1/tests/joints/slider.cpp @@ -0,0 +1,1332 @@ + +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ +//234567890123456789012345678901234567890123456789012345678901234567890123456789 +// 1 2 3 4 5 6 7 + +//////////////////////////////////////////////////////////////////////////////// +// This file create unit test for some of the functions found in: +// ode/src/joinst/slider.cpp +// +// +//////////////////////////////////////////////////////////////////////////////// + +#include <UnitTest++.h> +#include <ode/ode.h> + +#include "../../ode/src/config.h" +#include "../../ode/src/joints/slider.h" + +SUITE (TestdxJointSlider) +{ + struct dxJointSlider_Fixture_1 + { + dxJointSlider_Fixture_1() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate (wId); + dBodySetPosition (bId1, 0, -1, 0); + + bId2 = dBodyCreate (wId); + dBodySetPosition (bId2, 0, 1, 0); + + jId = dJointCreateSlider (wId, 0); + joint = (dxJointSlider*) jId; + + + dJointAttach (jId, bId1, bId2); + } + + ~dxJointSlider_Fixture_1() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + + dJointID jId; + dxJointSlider* joint; + }; + + TEST_FIXTURE (dxJointSlider_Fixture_1, test_dJointSetSlider) + { + // the 2 bodies are align + dJointSetSliderAxis (jId, 1, 0, 0); + CHECK_CLOSE (joint->qrel[0], 1.0, 1e-4); + CHECK_CLOSE (joint->qrel[1], 0.0, 1e-4); + CHECK_CLOSE (joint->qrel[2], 0.0, 1e-4); + CHECK_CLOSE (joint->qrel[3], 0.0, 1e-4); + + dMatrix3 R; + // Rotate 2nd body 90deg around X + dBodySetPosition (bId2, 0, 0, 1); + dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0); + dBodySetRotation (bId2, R); + + dJointSetSliderAxis (jId, 1, 0 ,0); + CHECK_CLOSE (joint->qrel[0], 0.70710678118654757, 1e-4); + CHECK_CLOSE (joint->qrel[1], 0.70710678118654757, 1e-4); + CHECK_CLOSE (joint->qrel[2], 0.0, 1e-4); + CHECK_CLOSE (joint->qrel[3], 0.0, 1e-4); + + + // Rotate 2nd body -90deg around X + dBodySetPosition (bId2, 0, 0, -1); + dRFromAxisAndAngle (R, 1, 0, 0, -M_PI/2.0); + dBodySetRotation (bId2, R); + + dJointSetSliderAxis (jId, 1, 0 ,0); + CHECK_CLOSE (joint->qrel[0], 0.70710678118654757, 1e-4); + CHECK_CLOSE (joint->qrel[1], -0.70710678118654757, 1e-4); + CHECK_CLOSE (joint->qrel[2], 0.0, 1e-4); + CHECK_CLOSE (joint->qrel[3], 0.0, 1e-4); + + + // Rotate 2nd body 90deg around Z + dBodySetPosition (bId2, 0, 1, 0); + dRFromAxisAndAngle (R, 0, 0, 1, M_PI/2.0); + dBodySetRotation (bId2, R); + + dJointSetSliderAxis (jId, 1, 0 ,0); + CHECK_CLOSE (joint->qrel[0], 0.70710678118654757, 1e-4); + CHECK_CLOSE (joint->qrel[1], 0.0, 1e-4); + CHECK_CLOSE (joint->qrel[2], 0.0, 1e-4); + CHECK_CLOSE (joint->qrel[3], 0.70710678118654757, 1e-4); + + + // Rotate 2nd body 45deg around Y + dBodySetPosition (bId2, 0, 1, 0); + dRFromAxisAndAngle (R, 0, 1, 0, M_PI/4.0); + dBodySetRotation (bId2, R); + + dJointSetSliderAxis (jId, 1, 0 ,0); + CHECK_CLOSE (joint->qrel[0], 0.92387953251128674, 1e-4); + CHECK_CLOSE (joint->qrel[1], 0.0, 1e-4); + CHECK_CLOSE (joint->qrel[2], 0.38268343236508984, 1e-4); + CHECK_CLOSE (joint->qrel[3], 0.0, 1e-4); + + // Rotate in a strange manner + // Both bodies at origin + dRFromEulerAngles (R, REAL(0.23), REAL(3.1), REAL(-0.73)); + dBodySetPosition (bId1, 0, 0, 0); + dBodySetRotation (bId1, R); + + dRFromEulerAngles (R, REAL(-0.57), REAL(1.49), REAL(0.81)); + dBodySetPosition (bId2, 0, 0, 0); + dBodySetRotation (bId2, R); + + dJointSetSliderAxis (jId, 1, 0 ,0); + CHECK_CLOSE (joint->qrel[0], -0.25526036263124319, 1e-4); + CHECK_CLOSE (joint->qrel[1], 0.28434861188441968, 1e-4); + CHECK_CLOSE (joint->qrel[2], -0.65308047160141625, 1e-4); + CHECK_CLOSE (joint->qrel[3], 0.65381489108282143, 1e-4); + } + + + + // The 2 bodies are positionned at (0, 0, 0), with no rotation + // The joint is a Slider Joint + // Axis is along the X axis + // Anchor at (0, 0, 0) + struct Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Along_X + { + Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Along_X() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate (wId); + dBodySetPosition (bId1, 0, 0, 0); + + bId2 = dBodyCreate (wId); + dBodySetPosition (bId2, 0, 0, 0); + + jId = dJointCreateSlider (wId, 0); + joint = (dxJointSlider*) jId; + + + dJointAttach (jId, bId1, bId2); + + dJointSetSliderAxis(jId, axis[0], axis[1], axis[2]); + } + + ~Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Along_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + + dJointID jId; + dxJointSlider* joint; + + static const dVector3 axis; + + static const dReal offset; + }; + const dVector3 Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Along_X::axis = {1, 0, 0}; + const dReal Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Along_X::offset = REAL(3.1); + + // Move 1st body offset unit in the X direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + // + // Start with a Offset of offset unit + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Along_X, + test_dJointSetSliderAxisOffset_B1_3Unit) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + + dBodySetPosition(bId1, offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetSliderPosition(jId), 1e-4); + } + + // Move 1st body offset unit in the opposite X direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + // + // Start with a Offset of -offset unit + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Along_X, + test_dJointSetSliderAxisOffset_B1_Minus_3Unit) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + + dBodySetPosition(bId1, -offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetSliderPosition(jId), 1e-4); + } + + // Move 2nd body offset unit in the X direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + // + // Start with a Offset of offset unit + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Along_X, + test_dJointSetSliderAxisOffset_B2_3Unit) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + + dBodySetPosition(bId2, offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetSliderPosition(jId), 1e-4); + } + + // Move 2nd body offset unit in the opposite X direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + // + // Start with a Offset of -offset unit + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Along_X, + test_dJointSetSliderAxisOffset_B2_Minus_3Unit) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + + dBodySetPosition(bId2, -offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetSliderPosition(jId), 1e-4); + } + + + + // The 2 bodies are positionned at (0, 0, 0), with no rotation + // The joint is a Slider Joint + // Axis is the opposite of the X axis + // Anchor at (0, 0, 0) + struct Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Inverse_of_X + { + Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Inverse_of_X() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate (wId); + dBodySetPosition (bId1, 0, 0, 0); + + bId2 = dBodyCreate (wId); + dBodySetPosition (bId2, 0, 0, 0); + + jId = dJointCreateSlider (wId, 0); + joint = (dxJointSlider*) jId; + + + dJointAttach (jId, bId1, bId2); + + + dJointSetSliderAxis(jId, axis[0], axis[1], axis[2]); + } + + ~Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Inverse_of_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + + dJointID jId; + dxJointSlider* joint; + + static const dVector3 axis; + static const dReal offset; + }; + const dVector3 Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Inverse_of_X::axis = {-1, 0, 0}; + const dReal Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Inverse_of_X::offset = REAL(3.1); + + // Move 1st body offset unit in the X direction + // + // X-------> X---------> <-- Axis + // B1 => B1 + // B2 B2 + // + // Start with a Offset of offset unit + // + // X-------> X---------> <-- Axis + // B1 => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetSliderAxisOffset_B1_3Unit) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + + dBodySetPosition(bId1, offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetSliderPosition(jId), 1e-4); + } + + // Move 1st body offset unit in the opposite X direction + // + // X-------> X---------> <-- Axis + // B1 => B1 + // B2 B2 + // + // Start with a Offset of offset unit + // + // X-------> X---------> <-- Axis + // B1 => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetSliderAxisOffset_B1_Minus_3Unit) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + + dBodySetPosition(bId1, -offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetSliderPosition(jId), 1e-4); + } + + // Move 2nd body offset unit in the X direction + // + // X-------> X---------> <-- Axis + // B1 => B1 + // B2 B2 + // + // Start with a Offset of offset unit + // + // X-------> X---------> <-- Axis + // B1 => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetSliderAxisOffset_B2_3Unit) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + + dBodySetPosition(bId2, offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetSliderPosition(jId), 1e-4); + } + + // Move 2nd body offset unit in the opposite X direction + // + // X-------> X---------> <-- Axis + // B1 => B1 + // B2 B2 + // + // Start with a Offset of -offset unit + // + // X-------> X---------> <-- Axis + // B1 => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetSliderAxisOffset_B2_Minus_3Unit) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + + dBodySetPosition(bId2, -offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetSliderPosition(jId), 1e-4); + } + + + // Only body 1 + // The body are positionned at (0, 0, 0), with no rotation + // The joint is a Slider Joint + // Axis is along the X axis + // Anchor at (0, 0, 0) + struct Fixture_dxJointSlider_B1_At_Zero_Axis_Along_X + { + Fixture_dxJointSlider_B1_At_Zero_Axis_Along_X() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate (wId); + dBodySetPosition (bId1, 0, 0, 0); + + jId = dJointCreateSlider (wId, 0); + joint = (dxJointSlider*) jId; + + + dJointAttach (jId, bId1, NULL); + + dJointSetSliderAxis(jId, axis[0], axis[1], axis[2]); + } + + ~Fixture_dxJointSlider_B1_At_Zero_Axis_Along_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1; + + dJointID jId; + dxJointSlider* joint; + + static const dVector3 axis; + + static const dReal offset; + }; + const dVector3 Fixture_dxJointSlider_B1_At_Zero_Axis_Along_X::axis = {1, 0, 0}; + const dReal Fixture_dxJointSlider_B1_At_Zero_Axis_Along_X::offset = REAL(3.1); + + // Move 1st body offset unit in the X direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // + TEST_FIXTURE (Fixture_dxJointSlider_B1_At_Zero_Axis_Along_X, + test_dJointSetSliderAxisOffset_B1_OffsetUnit) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + + dBodySetPosition(bId1, offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetSliderPosition(jId), 1e-4); + } + + // Move 1st body offset unit in the opposite X direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // + TEST_FIXTURE (Fixture_dxJointSlider_B1_At_Zero_Axis_Along_X, + test_dJointSetSliderAxisOffset_B1_Minus_OffsetUnit) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + + dBodySetPosition(bId1, -offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetSliderPosition(jId), 1e-4); + } + + + // Only body 1 + // The body are positionned at (0, 0, 0), with no rotation + // The joint is a Slider Joint + // Axis is in the oppsite X axis + // Anchor at (0, 0, 0) + struct Fixture_dxJointSlider_B1_At_Zero_Axis_Inverse_of_X + { + Fixture_dxJointSlider_B1_At_Zero_Axis_Inverse_of_X() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate (wId); + dBodySetPosition (bId1, 0, 0, 0); + + jId = dJointCreateSlider (wId, 0); + joint = (dxJointSlider*) jId; + + + dJointAttach (jId, bId1, NULL); + + dJointSetSliderAxis(jId, axis[0], axis[1], axis[2]); + } + + ~Fixture_dxJointSlider_B1_At_Zero_Axis_Inverse_of_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1; + + dJointID jId; + dxJointSlider* joint; + + static const dVector3 axis; + + static const dReal offset; + }; + const dVector3 Fixture_dxJointSlider_B1_At_Zero_Axis_Inverse_of_X::axis = {-1, 0, 0}; + const dReal Fixture_dxJointSlider_B1_At_Zero_Axis_Inverse_of_X::offset = REAL(3.1); + + // Move 1st body offset unit in the X direction + // + // X-------> X---------> <--- Axis + // B1 => B1 + // + TEST_FIXTURE (Fixture_dxJointSlider_B1_At_Zero_Axis_Inverse_of_X, + test_dJointSetSliderAxisOffset_B1_OffsetUnit) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + + dBodySetPosition(bId1, offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetSliderPosition(jId), 1e-4); + } + + // Move 1st body offset unit in the opposite X direction + // + // X-------> X---------> <--- Axis + // B1 => B1 + // + TEST_FIXTURE (Fixture_dxJointSlider_B1_At_Zero_Axis_Inverse_of_X, + test_dJointSetSliderAxisOffset_B1_Minus_OffsetUnit) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + + dBodySetPosition(bId1, -offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetSliderPosition(jId), 1e-4); + } + + + // Only body 2 + // The body are positionned at (0, 0, 0), with no rotation + // The joint is a Slider Joint + // Axis is along the X axis + // Anchor at (0, 0, 0) + struct Fixture_dxJointSlider_B2_At_Zero_Axis_Along_X + { + Fixture_dxJointSlider_B2_At_Zero_Axis_Along_X() + { + wId = dWorldCreate(); + + bId2 = dBodyCreate (wId); + dBodySetPosition (bId2, 0, 0, 0); + + jId = dJointCreateSlider (wId, 0); + joint = (dxJointSlider*) jId; + + + dJointAttach (jId, NULL, bId2); + + dJointSetSliderAxis(jId, axis[0], axis[1], axis[2]); + } + + ~Fixture_dxJointSlider_B2_At_Zero_Axis_Along_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId2; + + dJointID jId; + dxJointSlider* joint; + + static const dVector3 axis; + + static const dReal offset; + }; + const dVector3 Fixture_dxJointSlider_B2_At_Zero_Axis_Along_X::axis = {1, 0, 0}; + const dReal Fixture_dxJointSlider_B2_At_Zero_Axis_Along_X::offset = REAL(3.1); + + // Move 2nd body offset unit in the X direction + // + // X-------> X---------> Axis --> + // B2 => B2 + // + TEST_FIXTURE (Fixture_dxJointSlider_B2_At_Zero_Axis_Along_X, + test_dJointSetSliderAxisOffset_B2_OffsetUnit) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + + dBodySetPosition(bId2, offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetSliderPosition(jId), 1e-4); + } + + // Move 2nd body offset unit in the opposite X direction + // + // X-------> X---------> Axis --> + // B2 => B2 + // + TEST_FIXTURE (Fixture_dxJointSlider_B2_At_Zero_Axis_Along_X, + test_dJointSetSliderAxisOffset_B2_Minus_OffsetUnit) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + + dBodySetPosition(bId2, -offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetSliderPosition(jId), 1e-4); + } + + // Only body 2 + // The body are positionned at (0, 0, 0), with no rotation + // The joint is a Slider Joint + // Axis is in the oppsite X axis + // Anchor at (0, 0, 0) + struct Fixture_dxJointSlider_B2_At_Zero_Axis_Inverse_of_X + { + Fixture_dxJointSlider_B2_At_Zero_Axis_Inverse_of_X() + { + wId = dWorldCreate(); + + bId2 = dBodyCreate (wId); + dBodySetPosition (bId2, 0, 0, 0); + + jId = dJointCreateSlider (wId, 0); + joint = (dxJointSlider*) jId; + + + dJointAttach (jId, NULL, bId2); + + dJointSetSliderAxis(jId, axis[0], axis[1], axis[2]); + } + + ~Fixture_dxJointSlider_B2_At_Zero_Axis_Inverse_of_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId2; + + dJointID jId; + dxJointSlider* joint; + + static const dVector3 axis; + + static const dReal offset; + }; + const dVector3 Fixture_dxJointSlider_B2_At_Zero_Axis_Inverse_of_X::axis = {-1, 0, 0}; + const dReal Fixture_dxJointSlider_B2_At_Zero_Axis_Inverse_of_X::offset = REAL(3.1); + + // Move 2nd body offset unit in the X direction + // + // X-------> X---------> <--- Axis + // B2 => B2 + // + TEST_FIXTURE (Fixture_dxJointSlider_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetSliderAxisOffset_B2_OffsetUnit) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + + dBodySetPosition(bId2, offset, 0, 0); + + CHECK_CLOSE (offset, dJointGetSliderPosition(jId), 1e-4); + } + + // Move 2nd body offset unit in the opposite X direction + // + // X-------> X---------> <--- Axis + // B2 => B2 + // + TEST_FIXTURE (Fixture_dxJointSlider_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetSliderAxisOffset_B2_Minus_OffsetUnit) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + + dBodySetPosition(bId2, -offset, 0, 0); + + CHECK_CLOSE (-offset, dJointGetSliderPosition(jId), 1e-4); + } + + // ========================================================================== + // Test Position Rate + // ========================================================================== + + + // Apply force on 1st body in the X direction also the Axis direction + // + // X-------> X---------> Axis --> + // B1 F-> => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Along_X, + test_dJointSetSliderPositionRate_Force_Along_Axis_on_B1) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4); + + dBodyAddForce(bId1, 1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (1, dJointGetSliderPositionRate(jId), 1e-4); + } + + // Apply force on 1st body in the inverse X direction + // + // X-------> X---------> Axis --> + // B1 <-F => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Along_X, + test_dJointSetSliderPositionRate_Force_Inverse_of_Axis_on_B1) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4); + + dBodyAddForce(bId1, -1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (-1, dJointGetSliderPositionRate(jId), 1e-4); + } + + + // Apply force on 1st body in the X direction also the Axis direction + // + // X-------> X---------> <-- Axis + // B1 F-> => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetSliderPositionRate_Force_Inverse_Axis_on_B1) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4); + + dBodyAddForce(bId1, 1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (-1, dJointGetSliderPositionRate(jId), 1e-4); + } + + // Apply force on 1st body in the inverse X direction + // + // X-------> X---------> <-- Axis + // B1 <-F => B1 + // B2 B2 + TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetSliderPositionRate_Force_Along_of_Axis_on_B1) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4); + + dBodyAddForce(bId1, -1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (1, dJointGetSliderPositionRate(jId), 1e-4); + } + + // Apply force on 1st body in the X direction also the Axis direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 F-> B2 + TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Along_X, + test_dJointSetSliderPositionRate_Force_Along_Axis_on_B2) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4); + + dBodyAddForce(bId2, 1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (-1, dJointGetSliderPositionRate(jId), 1e-4); + } + + // Apply force on 1st body in the inverse X direction + // + // X-------> X---------> Axis --> + // B1 => B1 + // B2 <-F B2 + TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Along_X, + test_dJointSetSliderPositionRate_Force_Inverse_of_Axis_on_B2) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4); + + dBodyAddForce(bId2, -1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (1, dJointGetSliderPositionRate(jId), 1e-4); + } + + + // Apply force on 1st body in the X direction also the Axis direction + // + // X-------> X---------> <-- Axis + // B1 => B1 + // B2 F-> B2 + TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetSliderPositionRate_Force_Inverse_Axis_on_B2) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4); + + dBodyAddForce(bId2, 1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (1, dJointGetSliderPositionRate(jId), 1e-4); + } + + // Apply force on 1st body in the inverse X direction + // + // X-------> X---------> <-- Axis + // B1 => B1 + // B2 <-F B2 + TEST_FIXTURE (Fixture_dxJointSlider_B1_and_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetSliderPositionRate_Force_Along_of_Axis_on_B2) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4); + + dBodyAddForce(bId2, -1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (-1, dJointGetSliderPositionRate(jId), 1e-4); + } + + + + // Apply force on 1st body in the X direction also the Axis direction + // + // X-------> X---------> Axis --> + // B1 F-> => B1 + TEST_FIXTURE (Fixture_dxJointSlider_B1_At_Zero_Axis_Along_X, + test_dJointSetSliderPositionRate_Force_Along_Axis_on_B1) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4); + + dBodyAddForce(bId1, 1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (1, dJointGetSliderPositionRate(jId), 1e-4); + } + + // Apply force on 1st body in the inverse X direction + // + // X-------> X---------> Axis --> + // B1 <-F => B1 + TEST_FIXTURE (Fixture_dxJointSlider_B1_At_Zero_Axis_Along_X, + test_dJointSetSliderPositionRate_Force_Inverse_of_Axis_on_B1) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4); + + dBodyAddForce(bId1, -1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (-1, dJointGetSliderPositionRate(jId), 1e-4); + } + + + // Apply force on 1st body in the X direction also the Axis direction + // + // X-------> X---------> <-- Axis + // B1 F-> => B1 + TEST_FIXTURE (Fixture_dxJointSlider_B1_At_Zero_Axis_Inverse_of_X, + test_dJointSetSliderPositionRate_Force_Inverse_Axis_on_B1) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4); + + dBodyAddForce(bId1, 1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (-1, dJointGetSliderPositionRate(jId), 1e-4); + } + + // Apply force on 1st body in the inverse X direction + // + // X-------> X---------> <-- Axis + // B1 <-F => B1 + TEST_FIXTURE (Fixture_dxJointSlider_B1_At_Zero_Axis_Inverse_of_X, + test_dJointSetSliderPositionRate_Force_Along_of_Axis_on_B1) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4); + + dBodyAddForce(bId1, -1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (1, dJointGetSliderPositionRate(jId), 1e-4); + } + + + // Apply force on body 2 in the X direction also the Axis direction + // + // X-------> X---------> Axis --> + // B2 F-> B2 + TEST_FIXTURE (Fixture_dxJointSlider_B2_At_Zero_Axis_Along_X, + test_dJointSetSliderPositionRate_Force_Along_Axis_on_B2) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4); + + dBodyAddForce(bId2, 1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (-1, dJointGetSliderPositionRate(jId), 1e-4); + } + + // Apply force on body 2 in the inverse X direction + // + // X-------> X---------> Axis --> + // B2 <-F B2 + TEST_FIXTURE (Fixture_dxJointSlider_B2_At_Zero_Axis_Along_X, + test_dJointSetSliderPositionRate_Force_Inverse_of_Axis_on_B2) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4); + + dBodyAddForce(bId2, -1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (1, dJointGetSliderPositionRate(jId), 1e-4); + } + + + // Apply force on body 2 in the X direction also the Axis direction + // + // X-------> X---------> <-- Axis + // B2 F-> B2 + TEST_FIXTURE (Fixture_dxJointSlider_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetSliderPositionRate_Force_Inverse_Axis_on_B2) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4); + + dBodyAddForce(bId2, 1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (1, dJointGetSliderPositionRate(jId), 1e-4); + } + + // Apply force on body 2 in the inverse X direction + // + // X-------> X---------> <-- Axis + // B2 <-F B2 + TEST_FIXTURE (Fixture_dxJointSlider_B2_At_Zero_Axis_Inverse_of_X, + test_dJointSetSliderPositionRate_Force_Along_of_Axis_on_B2) + { + CHECK_CLOSE (0.0, dJointGetSliderPosition(jId), 1e-4); + CHECK_CLOSE (0.0, dJointGetSliderPositionRate(jId), 1e-4); + + dBodyAddForce(bId2, -1.0, 0, 0); + dWorldQuickStep (wId, 1.0); + + CHECK_CLOSE (-1, dJointGetSliderPositionRate(jId), 1e-4); + } + + + + + + + // Create 2 bodies attached by a Slider joint + // Axis is along the X axis (Default value + // Anchor at (0, 0, 0) (Default value) + // + // ^Y + // | + // | + // | + // | + // Body1 | Body2 + // * Z-----*->x + struct dxJointSlider_Test_Initialization + { + dxJointSlider_Test_Initialization() + { + wId = dWorldCreate(); + + // Remove gravity to have the only force be the force of the joint + dWorldSetGravity(wId, 0,0,0); + + for (int j=0; j<2; ++j) + { + bId[j][0] = dBodyCreate (wId); + dBodySetPosition (bId[j][0], -1, -2, -3); + + bId[j][1] = dBodyCreate (wId); + dBodySetPosition (bId[j][1], 11, 22, 33); + + + dMatrix3 R; + dVector3 axis; // Random axis + + axis[0] = REAL(0.53); + axis[1] = -REAL(0.71); + axis[2] = REAL(0.43); + dNormalize3(axis); + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], + REAL(0.47123)); // 27deg + dBodySetRotation (bId[j][0], R); + + + axis[0] = REAL(1.2); + axis[1] = REAL(0.87); + axis[2] = -REAL(0.33); + dNormalize3(axis); + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], + REAL(0.47123)); // 27deg + dBodySetRotation (bId[j][1], R); + + + jId[j] = dJointCreateSlider (wId, 0); + dJointAttach (jId[j], bId[j][0], bId[j][1]); + } + } + + ~dxJointSlider_Test_Initialization() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId[2][2]; + + + dJointID jId[2]; + + }; + + + // Test if setting a Slider joint with its default values + // will behave the same as a default Slider joint + TEST_FIXTURE (dxJointSlider_Test_Initialization, + test_Slider_Initialization) + { + using namespace std; + + dVector3 axis; + dJointGetSliderAxis(jId[1], axis); + dJointSetSliderAxis(jId[1], axis[0], axis[1], axis[2]); + + + CHECK_CLOSE (dJointGetSliderPosition(jId[0]), + dJointGetSliderPosition(jId[1]), 1e-6); + + + for (int b=0; b<2; ++b) + { + // Compare body b of the first joint with its equivalent on the + // second joint + const dReal *qA = dBodyGetQuaternion(bId[0][b]); + const dReal *qB = dBodyGetQuaternion(bId[1][b]); + CHECK_CLOSE (qA[0], qB[0], 1e-6); + CHECK_CLOSE (qA[1], qB[1], 1e-6); + CHECK_CLOSE (qA[2], qB[2], 1e-6); + CHECK_CLOSE (qA[3], qB[3], 1e-6); + } + + dWorldStep (wId,0.5); + dWorldStep (wId,0.5); + dWorldStep (wId,0.5); + dWorldStep (wId,0.5); + + for (int b=0; b<2; ++b) + { + // Compare body b of the first joint with its equivalent on the + // second joint + const dReal *qA = dBodyGetQuaternion(bId[0][b]); + const dReal *qB = dBodyGetQuaternion(bId[1][b]); + CHECK_CLOSE (qA[0], qB[0], 1e-6); + CHECK_CLOSE (qA[1], qB[1], 1e-6); + CHECK_CLOSE (qA[2], qB[2], 1e-6); + CHECK_CLOSE (qA[3], qB[3], 1e-6); + + + const dReal *posA = dBodyGetPosition(bId[0][b]); + const dReal *posB = dBodyGetPosition(bId[1][b]); + CHECK_CLOSE (posA[0], posB[0], 1e-6); + CHECK_CLOSE (posA[1], posB[1], 1e-6); + CHECK_CLOSE (posA[2], posB[2], 1e-6); + CHECK_CLOSE (posA[3], posB[3], 1e-6); + } + } + + + + // Compare Only body 1 to 2 bodies with one fixed. + // + // The body are positionned at (0, 0, 0), with no rotation + // The joint is a Slider Joint + // Axis is along the X axis + // Anchor at (0, 0, 0) + struct Fixture_dxJointSlider_Compare_Body_At_Zero_Axis_Along_X + { + Fixture_dxJointSlider_Compare_Body_At_Zero_Axis_Along_X() + { + wId = dWorldCreate(); + + bId1_12 = dBodyCreate (wId); + dBodySetPosition (bId1_12, 0, 0, 0); + + bId2_12 = dBodyCreate (wId); + dBodySetPosition (bId2_12, 0, 0, 0); + // The force will be added in the function since it is not + // always on the same body + + jId_12 = dJointCreateSlider (wId, 0); + dJointAttach(jId_12, bId1_12, bId2_12); + + fixed = dJointCreateFixed (wId, 0); + + + + bId = dBodyCreate (wId); + dBodySetPosition (bId, 0, 0, 0); + + dBodyAddForce (bId, 4, 0, 0); + + jId = dJointCreateSlider (wId, 0); + } + + ~Fixture_dxJointSlider_Compare_Body_At_Zero_Axis_Along_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1_12; + dBodyID bId2_12; + + dJointID jId_12; // Joint with 2 bodies + + dJointID fixed; + + + + dBodyID bId; + dJointID jId; // Joint with one body + }; + + // This test compare the result of a slider with 2 bodies where body body 2 is + // fixed to the world to a slider with only one body at position 1. + // + // Test the limits [-1, 0.25] when only one body at is attached to the joint + // using dJointAttache(jId, bId, 0); + // + TEST_FIXTURE(Fixture_dxJointSlider_Compare_Body_At_Zero_Axis_Along_X, + test_Limit_minus1_025_One_Body_on_left) + { + dBodyAddForce (bId1_12, 4, 0, 0); + + dJointAttach(jId_12, bId1_12, bId2_12); + dJointSetSliderParam(jId_12, dParamLoStop, -1); + dJointSetSliderParam(jId_12, dParamHiStop, 0.25); + + dJointAttach(fixed, 0, bId2_12); + dJointSetFixed(fixed); + + dJointAttach(jId, bId, 0); + dJointSetSliderParam(jId, dParamLoStop, -1); + dJointSetSliderParam(jId, dParamHiStop, 0.25); + + + for (int i=0; i<50; ++i) + dWorldStep(wId, 1.0); + + const dReal *pos1_12 = dBodyGetPosition(bId1_12); + + const dReal *pos = dBodyGetPosition(bId); + + + CHECK_CLOSE (pos[0], pos1_12[0], 1e-2); + CHECK_CLOSE (pos[1], pos1_12[1], 1e-2); + CHECK_CLOSE (pos[2], pos1_12[2], 1e-2); + } + + + + // This test compare the result of a slider with 2 bodies where body body 1 is + // fixed to the world to a slider with only one body at position 2. + // + // Test the limits [-1, 0.25] when only one body at is attached to the joint + // using dJointAttache(jId, 0, bId); + // + TEST_FIXTURE(Fixture_dxJointSlider_Compare_Body_At_Zero_Axis_Along_X, + test_Limit_minus1_025_One_Body_on_right) + { + dBodyAddForce (bId2_12, 4, 0, 0); + + dJointAttach(jId_12, bId1_12, bId2_12); + dJointSetSliderParam(jId_12, dParamLoStop, -1); + dJointSetSliderParam(jId_12, dParamHiStop, 0.25); + + dJointAttach(fixed, bId1_12, 0); + dJointSetFixed(fixed); + + + dJointAttach(jId, 0, bId); + dJointSetSliderParam(jId, dParamLoStop, -1); + dJointSetSliderParam(jId, dParamHiStop, 0.25); + + for (int i=0; i<50; ++i) + { + dWorldStep(wId, 1.0); + } + + const dReal *pos2_12 = dBodyGetPosition(bId2_12); + + const dReal *pos = dBodyGetPosition(bId); + + + CHECK_CLOSE (pos[0], pos2_12[0], 1e-2); + CHECK_CLOSE (pos[1], pos2_12[1], 1e-2); + CHECK_CLOSE (pos[2], pos2_12[2], 1e-2); + } + + + + // This test compare the result of a slider with 2 bodies where body body 2 is + // fixed to the world to a slider with only one body at position 1. + // + // Test the limits [0, 0] when only one body at is attached to the joint + // using dJointAttache(jId, bId, 0); + // + // The body should not move since their is no room between the two limits + // + TEST_FIXTURE(Fixture_dxJointSlider_Compare_Body_At_Zero_Axis_Along_X, + test_Limit_0_0_One_Body_on_left) + { + dBodyAddForce (bId1_12, 4, 0, 0); + + dJointAttach(jId_12, bId1_12, bId2_12); + dJointSetSliderParam(jId_12, dParamLoStop, 0); + dJointSetSliderParam(jId_12, dParamHiStop, 0); + + dJointAttach(fixed, 0, bId2_12); + dJointSetFixed(fixed); + + + dJointAttach(jId, bId, 0); + dJointSetSliderParam(jId, dParamLoStop, 0); + dJointSetSliderParam(jId, dParamHiStop, 0); + + for (int i=0; i<500; ++i) + dWorldStep(wId, 1.0); + + const dReal *pos1_12 = dBodyGetPosition(bId1_12); + + const dReal *pos = dBodyGetPosition(bId); + + + CHECK_CLOSE (pos[0], pos1_12[0], 1e-4); + CHECK_CLOSE (pos[1], pos1_12[1], 1e-4); + CHECK_CLOSE (pos[2], pos1_12[2], 1e-4); + + CHECK_CLOSE (pos[0], 0, 1e-4); + CHECK_CLOSE (pos[1], 0, 1e-4); + CHECK_CLOSE (pos[2], 0, 1e-4); + } + + + // This test compare the result of a slider with 2 bodies where body body 1 is + // fixed to the world to a slider with only one body at position 2. + // + // Test the limits [0, 0] when only one body at is attached to the joint + // using dJointAttache(jId, 0, bId); + // + // The body should not move since their is no room between the two limits + // + TEST_FIXTURE(Fixture_dxJointSlider_Compare_Body_At_Zero_Axis_Along_X, + test_Limit_0_0_One_Body_on_right) + { + dBodyAddForce (bId2_12, 4, 0, 0); + + dJointAttach(jId_12, bId1_12, bId2_12); + dJointSetSliderParam(jId_12, dParamLoStop, 0); + dJointSetSliderParam(jId_12, dParamHiStop, 0); + + dJointAttach(fixed, bId1_12, 0); + dJointSetFixed(fixed); + + + dJointAttach(jId, 0, bId); + dJointSetSliderParam(jId, dParamLoStop, 0); + dJointSetSliderParam(jId, dParamHiStop, 0); + + for (int i=0; i<500; ++i) + dWorldStep(wId, 1.0); + + const dReal *pos2_12 = dBodyGetPosition(bId2_12); + + const dReal *pos = dBodyGetPosition(bId); + + + CHECK_CLOSE (pos[0], pos2_12[0], 1e-4); + CHECK_CLOSE (pos[1], pos2_12[1], 1e-4); + CHECK_CLOSE (pos[2], pos2_12[2], 1e-4); + + CHECK_CLOSE (pos[0], 0, 1e-4); + CHECK_CLOSE (pos[1], 0, 1e-4); + CHECK_CLOSE (pos[2], 0, 1e-4); + } + + + + +} // End of SUITE TestdxJointSlider diff --git a/libs/ode-0.16.1/tests/joints/universal.cpp b/libs/ode-0.16.1/tests/joints/universal.cpp new file mode 100644 index 0000000..5a4c17b --- /dev/null +++ b/libs/ode-0.16.1/tests/joints/universal.cpp @@ -0,0 +1,2119 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +//////////////////////////////////////////////////////////////////////////////// +// This file create unit test for some of the functions found in: +// ode/src/joinst/universal.cpp +// +// +//////////////////////////////////////////////////////////////////////////////// + +#include <iostream> + +#include <UnitTest++.h> +#include <ode/ode.h> + +#include "../../ode/src/config.h" +#include "../../ode/src/joints/universal.h" + +dReal d2r(dReal degree) +{ + return degree * (dReal)(M_PI / 180.0); +} +dReal r2d(dReal degree) +{ + return degree * (dReal)(180.0/M_PI); +} + +SUITE (TestdxJointUniversal) +{ + // The 2 bodies are positionned at (0, 0, 0) + // The bodis have no rotation. + // The joint is a Universal Joint + // Axis1 is along the X axis + // Axis2 is along the Y axis + // Anchor at (0, 0, 0) + struct Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Along_X_Axis2_Along_Y + { + Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Along_X_Axis2_Along_Y() + { + + wId = dWorldCreate(); + + bId1 = dBodyCreate (wId); + dBodySetPosition (bId1, 0, 0, 0); + + bId2 = dBodyCreate (wId); + dBodySetPosition (bId2, 0, 0, 0); + + + jId = dJointCreateUniversal (wId, 0); + joint = (dxJointUniversal*) jId; + + + dJointAttach (jId, bId1, bId2); + } + + ~Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Along_X_Axis2_Along_Y() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + + dJointID jId; + dxJointUniversal* joint; + }; + + + // The 2 bodies are positionned at (-1, -2, -3), and (11, 22, 33) + // The bodis have rotation of 27deg around some axis. + // The joint is a Universal Joint + // Axis is along the X axis + // Anchor at (0, 0, 0) + struct Fixture_dxJointUniversal_B1_and_B2_At_Random_Axis_Along_X + { + Fixture_dxJointUniversal_B1_and_B2_At_Random_Axis_Along_X() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate (wId); + dBodySetPosition (bId1, -1, -2, -3); + + bId2 = dBodyCreate (wId); + dBodySetPosition (bId2, 11, 22, 33); + + dMatrix3 R; + + dVector3 axis; + + axis[0] = REAL(0.53); + axis[1] = -REAL(0.71); + axis[2] = REAL(0.43); + dNormalize3(axis); + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], + REAL(0.47123)); // 27deg + dBodySetRotation (bId1, R); + + + axis[0] = REAL(1.2); + axis[1] = REAL(0.87); + axis[2] = -REAL(0.33); + dNormalize3(axis); + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], + REAL(0.47123)); // 27deg + dBodySetRotation (bId2, R); + + jId = dJointCreateUniversal (wId, 0); + joint = (dxJointUniversal*) jId; + + + dJointAttach (jId, bId1, bId2); + } + + ~Fixture_dxJointUniversal_B1_and_B2_At_Random_Axis_Along_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + + dJointID jId; + dxJointUniversal* joint; + }; + + + // Only one body body1 at (0,0,0) + // The joint is an Universal Joint. + // Axis1 is along the X axis + // Axis2 is along the Y axis + // Anchor at (0, 0, 0) + // + // ^Y + // | + // | + // | + // | + // | + // Z <-- X + struct Fixture_dxJointUniversal_B1_At_Zero_Default_Axes + { + Fixture_dxJointUniversal_B1_At_Zero_Default_Axes() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate (wId); + dBodySetPosition (bId1, 0, 0, 0); + + jId = dJointCreateUniversal (wId, 0); + + + dJointAttach (jId, bId1, NULL); + dJointSetUniversalAnchor (jId, 0, 0, 0); + } + + ~Fixture_dxJointUniversal_B1_At_Zero_Default_Axes() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1; + + + dJointID jId; + }; + + + + // Only one body body2 at (0,0,0) + // The joint is an Universal Joint. + // Axis1 is along the X axis. + // Axis2 is along the Y axis. + // Anchor at (0, 0, 0) + // + // ^Y + // | + // | + // | + // | + // | + // Z <-- X + struct Fixture_dxJointUniversal_B2_At_Zero_Default_Axes + { + Fixture_dxJointUniversal_B2_At_Zero_Default_Axes() + { + wId = dWorldCreate(); + + bId2 = dBodyCreate (wId); + dBodySetPosition (bId2, 0, 0, 0); + + jId = dJointCreateUniversal (wId, 0); + + + dJointAttach (jId, NULL, bId2); + dJointSetUniversalAnchor (jId, 0, 0, 0); + } + + ~Fixture_dxJointUniversal_B2_At_Zero_Default_Axes() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId2; + + dJointID jId; + }; + + + // Test is dJointGetUniversalAngles versus + // dJointGetUniversalAngle1 and dJointGetUniversalAngle2 dJointGetUniversalAxis + TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Along_X_Axis2_Along_Y, + test_dJointSetGetUniversalAngles_Versus_Angle1_and_Angle2) + { + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dReal angle1, angle2; + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + + dMatrix3 R; + dReal ang1, ang2; + + + dVector3 axis1; + dJointGetUniversalAxis1 (jId, axis1); + + dVector3 axis2; + dJointGetUniversalAxis2 (jId, axis2); + + ang1 = d2r(REAL(23.0)); + dRFromAxisAndAngle (R, axis1[0], axis1[1], axis1[2], ang1); + dBodySetRotation (bId1, R); + + ang2 = d2r(REAL(17.0)); + dRFromAxisAndAngle (R, axis2[0], axis2[1], axis2[2], ang2); + dBodySetRotation (bId2, R); + + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (ang1, angle1, 1e-4); + CHECK_CLOSE (-ang2, angle2, 1e-4); + + + + + + + // ax1 and ax2 are pseudo-random axis. N.B. They are NOT the axis of the joints. + dVector3 ax1; + ax1[0] = REAL(0.2); + ax1[1] = -REAL(0.67); + ax1[2] = -REAL(0.81); + dNormalize3(ax1); + + dVector3 ax2; + ax2[0] = REAL(0.62); + ax2[1] = REAL(0.31); + ax2[2] = REAL(0.43); + dNormalize3(ax2); + + + ang1 = d2r(REAL(23.0)); + dRFromAxisAndAngle (R, ax1[0], ax1[1], ax1[2], ang1); + dBodySetRotation (bId1, R); + + ang2 = d2r(REAL(0.0)); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (angle1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (angle2, dJointGetUniversalAngle2 (jId), 1e-4); + + + + ang1 = d2r(REAL(0.0)); + + ang2 = d2r(REAL(23.0)); + dRFromAxisAndAngle (R, ax2[0], ax2[1], ax2[2], ang2); + dBodySetRotation (bId1, R); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (angle1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (angle2, dJointGetUniversalAngle2 (jId), 1e-4); + + + ang1 = d2r(REAL(38.0)); + dRFromAxisAndAngle (R, ax1[0], ax1[1], ax1[2], ang2); + dBodySetRotation (bId1, R); + + ang2 = d2r(REAL(-43.0)); + dRFromAxisAndAngle (R, ax2[0], ax2[1], ax2[2], ang2); + dBodySetRotation (bId1, R); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (angle1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (angle2, dJointGetUniversalAngle2 (jId), 1e-4); + + + // Try with random axis for the axis of the joints + dRSetIdentity(R); + dBodySetRotation (bId1, R); + dBodySetRotation (bId1, R); + + axis1[0] = REAL(0.32); + axis1[1] = -REAL(0.57); + axis1[2] = REAL(0.71); + dNormalize3(axis1); + + axis2[0] = -REAL(0.26); + axis2[1] = -REAL(0.31); + axis2[2] = REAL(0.69); + dNormalize3(axis2); + + dVector3 cross; + dCalcVectorCross3(cross, axis1, axis2); + dJointSetUniversalAxis1(jId, axis1[0], axis1[1], axis1[2]); + dJointSetUniversalAxis2(jId, cross[0], cross[1], cross[2]); + + + ang1 = d2r(REAL(23.0)); + dRFromAxisAndAngle (R, ax1[0], ax1[1], ax1[2], ang1); + dBodySetRotation (bId1, R); + + ang2 = d2r(REAL(0.0)); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (angle1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (angle2, dJointGetUniversalAngle2 (jId), 1e-4); + + + + ang1 = d2r(REAL(0.0)); + + ang2 = d2r(REAL(23.0)); + dRFromAxisAndAngle (R, ax2[0], ax2[1], ax2[2], ang2); + dBodySetRotation (bId1, R); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (angle1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (angle2, dJointGetUniversalAngle2 (jId), 1e-4); + + + ang1 = d2r(REAL(38.0)); + dRFromAxisAndAngle (R, ax1[0], ax1[1], ax1[2], ang2); + dBodySetRotation (bId1, R); + + ang2 = d2r(REAL(-43.0)); + dRFromAxisAndAngle (R, ax2[0], ax2[1], ax2[2], ang2); + dBodySetRotation (bId1, R); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (angle1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (angle2, dJointGetUniversalAngle2 (jId), 1e-4); + } + + + // ========================================================================= + // Test ONE BODY behavior + // ========================================================================= + + + // Test when there is only one body at position one on the joint + TEST_FIXTURE (Fixture_dxJointUniversal_B1_At_Zero_Default_Axes, + test_dJointGetUniversalAngle1_1Body_B1) + { + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dReal angle1, angle2; + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + + dVector3 axis1; + dJointGetUniversalAxis1 (jId, axis1); + dVector3 axis2; + dJointGetUniversalAxis2 (jId, axis2); + + dMatrix3 R; + + dReal ang1 = REAL(0.23); + dRFromAxisAndAngle (R, axis1[0], axis1[1], axis1[2], ang1); + dBodySetRotation (bId1, R); + + dReal ang2 = REAL(0.0); + + + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (ang1, angle1, 1e-4); + CHECK_CLOSE (-ang2, angle2, 1e-4); + + + + dMatrix3 I; + dRSetIdentity(I); // Set the rotation of the body to be the Identity (i.e. zero) + dBodySetRotation (bId1, I); + + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + + // Test the same rotation, when axis1 is inverted + dJointSetUniversalAxis1 (jId, -axis1[0], -axis1[1], -axis1[2]); + + dBodySetRotation (bId1, R); + + CHECK_CLOSE (-ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (-ang1, angle1, 1e-4); + CHECK_CLOSE (-ang2, angle2, 1e-4); + + + // Test the same rotation, when axis1 is default and axis2 is inverted + dBodySetRotation (bId1, I); + + dJointSetUniversalAxis1 (jId, axis1[0], axis1[1], axis1[2]); + dJointSetUniversalAxis2 (jId, -axis2[0], -axis2[1], -axis2[2]); + + + dBodySetRotation (bId1, R); + + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (ang1, angle1, 1e-4); + CHECK_CLOSE (ang2, angle2, 1e-4); + } + + + + + // Test when there is only one body at position two on the joint + TEST_FIXTURE (Fixture_dxJointUniversal_B2_At_Zero_Default_Axes, + test_dJointGetUniversalAngle1_1Body_B2) + { + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dReal angle1, angle2; + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + + dVector3 axis1; + dJointGetUniversalAxis1 (jId, axis1); + + dVector3 axis2; + dJointGetUniversalAxis2 (jId, axis2); + + dMatrix3 R; + + dReal ang1 = REAL(0.0); + + dReal ang2 = REAL(0.23); + dRFromAxisAndAngle (R, axis2[0], axis2[1], axis2[2], ang2); + dBodySetRotation (bId2, R); + + + + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (ang1, angle1, 1e-4); + CHECK_CLOSE (-ang2, angle2, 1e-4); + + + + dMatrix3 I; + dRSetIdentity(I); // Set the rotation of the body to be the Identity (i.e. zero) + dBodySetRotation (bId2, I); + + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + + dJointSetUniversalAxis2 (jId, -axis2[0], -axis2[1], -axis2[2]); + + dBodySetRotation (bId2, R); + + CHECK_CLOSE (-ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (-ang1, angle1, 1e-4); + CHECK_CLOSE (ang2, angle2, 1e-4); + + // Test the same rotation, when axis1 is inverted and axis2 is default + dBodySetRotation (bId2, I); + + dJointSetUniversalAxis1 (jId, -axis1[0], -axis1[1], -axis1[2]); + dJointSetUniversalAxis2 (jId, axis2[0], axis2[1], axis2[2]); + + + dBodySetRotation (bId2, R); + + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (ang1, angle1, 1e-4); + CHECK_CLOSE (-ang2, angle2, 1e-4); + } + + + + + + + // ========================================================================= + // + // ========================================================================= + + + // Test is dJointSetUniversalAxis and dJointGetUniversalAxis return same value + TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Random_Axis_Along_X, + test_dJointSetGetUniversalAxis) + { + dVector3 axisOrig, axis; + + + dJointGetUniversalAxis1 (jId, axisOrig); + dJointGetUniversalAxis1 (jId, axis); + dJointSetUniversalAxis1 (jId, axis[0], axis[1], axis[2]); + dJointGetUniversalAxis1 (jId, axis); + CHECK_CLOSE (axis[0], axisOrig[0] , 1e-4); + CHECK_CLOSE (axis[1], axisOrig[1] , 1e-4); + CHECK_CLOSE (axis[2], axisOrig[2] , 1e-4); + + + dJointGetUniversalAxis2 (jId, axisOrig); + dJointGetUniversalAxis2(jId, axis); + dJointSetUniversalAxis2 (jId, axis[0], axis[1], axis[2]); + dJointGetUniversalAxis2 (jId, axis); + CHECK_CLOSE (axis[0], axisOrig[0] , 1e-4); + CHECK_CLOSE (axis[1], axisOrig[1] , 1e-4); + CHECK_CLOSE (axis[2], axisOrig[2] , 1e-4); + + + dVector3 anchor1, anchor2, anchorOrig1, anchorOrig2; + dJointGetUniversalAnchor (jId, anchorOrig1); + dJointGetUniversalAnchor (jId, anchor1); + dJointGetUniversalAnchor2 (jId, anchorOrig2); + dJointGetUniversalAnchor2 (jId, anchor2); + + dJointSetUniversalAnchor (jId, anchor1[0], anchor1[1], anchor1[2]); + dJointGetUniversalAnchor (jId, anchor1); + dJointGetUniversalAnchor2 (jId, anchor2); + CHECK_CLOSE (anchor1[0], anchorOrig1[0] , 1e-4); + CHECK_CLOSE (anchor1[1], anchorOrig1[1] , 1e-4); + CHECK_CLOSE (anchor1[2], anchorOrig1[2] , 1e-4); + + CHECK_CLOSE (anchor2[0], anchorOrig2[0] , 1e-4); + CHECK_CLOSE (anchor2[1], anchorOrig2[1] , 1e-4); + CHECK_CLOSE (anchor2[2], anchorOrig2[2] , 1e-4); + } + + + + // Create 2 bodies attached by a Universal joint + // Axis is along the X axis (Default value + // Anchor at (0, 0, 0) (Default value) + // + // ^Y + // | + // * Body2 + // | + // | + // Body1 | + // * Z--------> + struct dxJointUniversal_Test_Initialization + { + dxJointUniversal_Test_Initialization() + { + wId = dWorldCreate(); + + // Remove gravity to have the only force be the force of the joint + dWorldSetGravity(wId, 0,0,0); + + for (int j=0; j<2; ++j) + { + bId[j][0] = dBodyCreate (wId); + dBodySetPosition (bId[j][0], -1, -2, -3); + + bId[j][1] = dBodyCreate (wId); + dBodySetPosition (bId[j][1], 11, 22, 33); + + + dMatrix3 R; + dVector3 axis; // Random axis + + axis[0] = REAL(0.53); + axis[1] = -REAL(0.71); + axis[2] = REAL(0.43); + dNormalize3(axis); + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], + REAL(0.47123)); // 27deg + dBodySetRotation (bId[j][0], R); + + + axis[0] = REAL(1.2); + axis[1] = REAL(0.87); + axis[2] = -REAL(0.33); + dNormalize3(axis); + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], + REAL(0.47123)); // 27deg + dBodySetRotation (bId[j][1], R); + + jId[j] = dJointCreateUniversal (wId, 0); + dJointAttach (jId[j], bId[j][0], bId[j][1]); + dJointSetUniversalParam(jId[j], dParamLoStop, 1); + dJointSetUniversalParam(jId[j], dParamHiStop, 2); + dJointSetUniversalParam(jId[j], dParamFMax, 200); + } + } + + ~dxJointUniversal_Test_Initialization() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId[2][2]; + + + dJointID jId[2]; + + }; + + + // Test if setting a Universal with its default values + // will behave the same as a default Universal joint + TEST_FIXTURE (dxJointUniversal_Test_Initialization, + test_Universal_Initialization) + { + using namespace std; + + dVector3 axis; + dJointGetUniversalAxis1(jId[1], axis); + dJointSetUniversalAxis1(jId[1], axis[0], axis[1], axis[2]); + + dJointGetUniversalAxis2(jId[1], axis); + dJointSetUniversalAxis2(jId[1], axis[0], axis[1], axis[2]); + + dVector3 anchor; + dJointGetUniversalAnchor(jId[1], anchor); + dJointSetUniversalAnchor(jId[1], anchor[0], anchor[1], anchor[2]); + + + for (int b=0; b<2; ++b) + { + // Compare body b of the first joint with its equivalent on the + // second joint + const dReal *qA = dBodyGetQuaternion(bId[0][b]); + const dReal *qB = dBodyGetQuaternion(bId[1][b]); + CHECK_CLOSE (qA[0], qB[0], 1e-4); + CHECK_CLOSE (qA[1], qB[1], 1e-4); + CHECK_CLOSE (qA[2], qB[2], 1e-4); + CHECK_CLOSE (qA[3], qB[3], 1e-4); + } + + dWorldStep (wId,0.5); + dWorldStep (wId,0.5); + dWorldStep (wId,0.5); + dWorldStep (wId,0.5); + + for (int b=0; b<2; ++b) + { + // Compare body b of the first joint with its equivalent on the + // second joint + const dReal *qA = dBodyGetQuaternion(bId[0][b]); + const dReal *qB = dBodyGetQuaternion(bId[1][b]); + CHECK_CLOSE (qA[0], qB[0], 1e-4); + CHECK_CLOSE (qA[1], qB[1], 1e-4); + CHECK_CLOSE (qA[2], qB[2], 1e-4); + CHECK_CLOSE (qA[3], qB[3], 1e-4); + + + const dReal *posA = dBodyGetPosition(bId[0][b]); + const dReal *posB = dBodyGetPosition(bId[1][b]); + CHECK_CLOSE (posA[0], posB[0], 1e-4); + CHECK_CLOSE (posA[1], posB[1], 1e-4); + CHECK_CLOSE (posA[2], posB[2], 1e-4); + CHECK_CLOSE (posA[3], posB[3], 1e-4); + } + } + + + + + + + + + + + + + + // ========================================================================== + // Testing the offset + // TODO: + // - Test Axis1Offset(...., 0, ang2); + // ========================================================================== + + + // Rotate first body 90deg around X (Axis1) then back to original position + // + // ^ ^ ^ Z ^ + // | | => <--- | | + // | | | | + // B1 B2 B1 B2 .----->Y + // / + // / + // v X (N.B. X is going out of the screen) + // + // Set Axis1 with an Offset of 90deg + // ^ ^ ^ + // <--- | => | | + // | | | + // B1 B2 B1 B2 + TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Along_X_Axis2_Along_Y, + test_dJointSetUniversalAxis1Offset_B1_90deg) + { + dMatrix3 R; + + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dReal angle1, angle2; + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + + + dVector3 axis; + dJointGetUniversalAxis1 (jId, axis); + + dReal ang1 = d2r(REAL(90.0)); + dReal ang2 = d2r(REAL(0.0)); + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], ang1); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (ang1, angle1, 1e-4); + CHECK_CLOSE (ang2, angle2, 1e-4); + + + + dJointSetUniversalAxis1Offset (jId, axis[0], axis[1], axis[2], + ang1, ang2); + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (ang1, angle1, 1e-4); + CHECK_CLOSE (ang2, angle2, 1e-4); + + + dRSetIdentity(R); // Set the rotation of the body to be zero + dBodySetRotation (bId1, R); + + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + } + + // Rotate 2nd body 90deg around (Axis2) then back to original position + // Offset when setting axis1 + // + // ^ ^ ^ Z ^ + // | | => <--- | | + // | | | | + // B1 B2 B1 B2 .----->Y + // / + // / + // v X (N.B. X is going out of the screen) + // + // Set Axis1 with an Offset of 90deg + // ^ ^ ^ + // <--- | => | | + // | | | + // B1 B2 B1 B2 + TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Along_X_Axis2_Along_Y, + test_dJointSetUniversalAxis1Offset_B2_90deg) + { + dMatrix3 R; + + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dReal angle1, angle2; + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + + + dVector3 ax1, ax2; + dJointGetUniversalAxis1 (jId, ax1); + dJointGetUniversalAxis2 (jId, ax2); + + dReal ang1 = d2r(REAL(0.0)); + dReal ang2 = d2r(REAL(90.0)); + dRFromAxisAndAngle (R, ax2[0], ax2[1], ax2[2], ang2); + dBodySetRotation (bId2, R); + + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (ang1, angle1, 1e-4); + CHECK_CLOSE (-ang2, angle2, 1e-4); + + + + dJointSetUniversalAxis1Offset (jId, ax1[0], ax1[1], ax1[2], + ang1, -ang2); + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (ang1, angle1, 1e-4); + CHECK_CLOSE (-ang2, angle2, 1e-4); + + + dRSetIdentity(R); // Set the rotation of the body to be zero + dBodySetRotation (bId1, R); + dBodySetRotation (bId2, R); + + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + } + + + + + + + + + // Rotate second body 90deg around Y (Axis2) then back to original position + // + // ^ ^ ^ Z ^ + // | | => | . | + // | | | | + // B1 B2 B1 B2 .----->Y + // / + // / + // v X (N.B. X is going out of the screen) + // + // Set Axis2 with an Offset of 90deg + // ^ ^ ^ + // | . => | | + // | | | + // B1 B2 B1 B2 + TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Along_X_Axis2_Along_Y, + test_dJointSetUniversalAxisOffset_B2_90deg) + { + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dReal angle1, angle2; + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + + dVector3 axis; + dJointGetUniversalAxis2 (jId, axis); + + dReal ang1 = d2r(REAL(0.0)); + dReal ang2 = d2r(REAL(90.0)); + + dMatrix3 R; + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], ang2); + dBodySetRotation (bId2, R); + + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (ang1, angle1, 1e-4); + CHECK_CLOSE (-ang2, angle2, 1e-4); + + + dJointSetUniversalAxis2Offset (jId, axis[0], axis[1], axis[2], + ang1, -ang2); + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (ang1, angle1, 1e-4); + CHECK_CLOSE (-ang2, angle2, 1e-4); + + + dRSetIdentity(R); // Set the rotation of the body to be zero + dBodySetRotation (bId2, R); + + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + } + + + + // Rotate 2nd body -90deg around Y (Axis2) then back to original position + // + // ^ ^ ^ Z ^ + // | | => | x | + // | | | | + // B1 B2 B1 B2 X .----> Y + // N.B. X is going out of the screen + // Start with a Delta of 90deg + // ^ ^ ^ + // | x => | | + // | | | + // B1 B2 B1 B2 + TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Along_X_Axis2_Along_Y, + test_dJointSetUniversalAxisOffset_B2_Minus90deg) + { + CHECK_CLOSE (dJointGetUniversalAngle1 (jId), 0, 1e-4); + CHECK_CLOSE (dJointGetUniversalAngle2 (jId), 0, 1e-4); + + dReal angle1, angle2; + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + + dVector3 axis; + dJointGetUniversalAxis2 (jId, axis); + + dReal ang1 = d2r(REAL(0.0)); + dReal ang2 = d2r(REAL(90.0)); + + dMatrix3 R; + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], -ang2); + dBodySetRotation (bId2, R); + + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (ang1, angle1, 1e-4); + CHECK_CLOSE (ang2, angle2, 1e-4); + + + + dJointSetUniversalAxis2Offset (jId, axis[0], axis[1], axis[2], + ang1, ang2); + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (ang1, angle1, 1e-4); + CHECK_CLOSE (ang2, angle2, 1e-4); + + + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], 0); + dBodySetRotation (bId2, R); + + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + } + + + // Rotate 1st body 0.23rad around X (Axis1) then back to original position + // + // ^ ^ ^ ^ Z ^ + // | | => \ | | + // | | \ | | + // B1 B2 B1 B2 .-------> Y + // / + // / + // v X (N.B. X is going out of the screen) + // + // Start with a Delta of 0.23rad + // ^ ^ ^ ^ + // \ | => | | + // \ | | | + // B1 B2 B1 B2 + TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Along_X_Axis2_Along_Y, + test_dJointSetUniversalAxis1Offset_B1_0_23rad) + { + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dReal angle1, angle2; + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + + dVector3 axis; + dJointGetUniversalAxis1 (jId, axis); + + dReal ang1 = REAL(0.23); + dReal ang2 = REAL(0.0); + + dMatrix3 R; + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], ang1); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + + dJointSetUniversalAxis1Offset (jId, axis[0], axis[1], axis[2], + ang1, ang2); + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (ang1, angle1, 1e-4); + CHECK_CLOSE (ang2, angle2, 1e-4); + + + dRSetIdentity(R); // Set the rotation of the body to be zero + dBodySetRotation (bId1, R); + + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + } + + // Rotate 2nd body 0.23rad around Y (Axis2) then back to original position + // + // ^ ^ ^ ^ Z ^ ^ Y (N.B. Y is going in the screen) + // | | => | / | / + // | | | / | / + // B1 B2 B1 B2 .-------> X + // + // Start with a Delta of 0.23rad + // ^ ^ ^ ^ + // | / => | | + // | / | | + // B1 B2 B1 B2 + TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Along_X_Axis2_Along_Y, + test_dJointSetUniversalAxisOffset_B2_0_23rad) + { + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dReal angle1, angle2; + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + + dVector3 axis; + dJointGetUniversalAxis2 (jId, axis); + + dReal ang1 = REAL(0.0); + dReal ang2 = REAL(0.23); + + dMatrix3 R; + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], ang2); + dBodySetRotation (bId2, R); + + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + + dJointSetUniversalAxis2Offset (jId, axis[0], axis[1], axis[2], + ang1, -ang2); + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (ang1, angle1, 1e-4); + CHECK_CLOSE (-ang2, angle2, 1e-4); + + + dRSetIdentity(R); // Set the rotation of the body to be zero + dBodySetRotation (bId2, R); + + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + } + + + // Rotate 1st body 0.23rad around X axis and 2nd body 0.37rad around Y (Axis2) + // then back to their original position. + // The Axis offset are set one at a time + // + // ^ ^ ^ ^ Z ^ ^ Y (N.B. Y is going in the screen) + // | | => \ / | / + // | | \ / | / + // B1 B2 B1 B2 .-------> X + // + // Start with a Delta of 0.23rad + // ^ ^ ^ ^ + // \ / => | | + // \ / | | + // B1 B2 B1 B2 + TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Along_X_Axis2_Along_Y, + test_dJointSetUniversalAxisOffset_B1_0_23rad_B2_0_37rad_One_by_One) + { + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dReal angle1, angle2; + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + + dVector3 axis1; + dJointGetUniversalAxis1 (jId, axis1); + dVector3 axis2; + dJointGetUniversalAxis2 (jId, axis2); + + dMatrix3 R; + + dReal ang1 = REAL(0.23); + dRFromAxisAndAngle (R, axis1[0], axis1[1], axis1[2], ang1); + dBodySetRotation (bId1, R); + + dReal ang2 = REAL(0.37); + dRFromAxisAndAngle (R, axis2[0], axis2[1], axis2[2], ang2); + dBodySetRotation (bId2, R); + + + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (ang1, angle1, 1e-4); + CHECK_CLOSE (-ang2, angle2, 1e-4); + + + dJointSetUniversalAxis1Offset (jId, axis1[0], axis1[1], axis1[2], + ang1, -ang2 ); + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (ang1, angle1, 1e-4); + CHECK_CLOSE (-ang2, angle2, 1e-4); + + dJointGetUniversalAxis1 (jId, axis1); + dJointGetUniversalAxis2 (jId, axis2); + + dRFromAxisAndAngle (R, axis2[0], axis2[1], axis2[2], ang2); + dBodySetRotation (bId2, R); + + dJointSetUniversalAxis2Offset (jId, axis2[0], axis2[1], axis2[2], + ang1, -ang2); + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (ang1, angle1, 1e-4); + CHECK_CLOSE (-ang2, angle2, 1e-4); + + + dRSetIdentity(R); // Set the rotation of the body to be zero + dBodySetRotation (bId1, R); + dBodySetRotation (bId2, R); + + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + } + + + +// The 2 bodies are positionned at (0, 0, 0), with no rotation +// The joint is an Universal Joint. +// Axis in the inverse direction of the X axis +// Anchor at (0, 0, 0) +// ^Y +// | +// | +// | +// | +// | +// Z <---- x (X going out of the page) + struct Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Inverse_of_X + { + Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Inverse_of_X() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate (wId); + dBodySetPosition (bId1, 0, 0, 0); + + bId2 = dBodyCreate (wId); + dBodySetPosition (bId2, 0, 0, 0); + + jId = dJointCreateUniversal (wId, 0); + joint = (dxJointUniversal*) jId; + + + dJointAttach (jId, bId1, bId2); + dJointSetUniversalAnchor (jId, 0, 0, 0); + + axis[0] = -1; + axis[1] = 0; + axis[2] = 0; + dJointSetUniversalAxis1(jId, axis[0], axis[1], axis[2]); + } + + ~Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Inverse_of_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + + dJointID jId; + dxJointUniversal* joint; + + dVector3 axis; + }; + + + // No offset when setting the Axis1 offset + // x is a Symbol for lines pointing into the screen + // . is a Symbol for lines pointing out of the screen + // + // In 2D In 3D + // ^ ^ ^ ^ Z ^ ^ Y + // | | => | | | / + // | | | | | / + // B1 B2 B1 B2 .-------> X <-- Axis1 + // + // Start with a Delta of 90deg + // ^ ^ ^ ^ + // | | => | | + // | | | | + // B1 B2 B1 B2 + TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Inverse_of_X, + test_dJointSetUniversalAxis1Offset_No_Offset_Axis1_Inverse_of_X) + { + CHECK_CLOSE (dJointGetUniversalAngle1 (jId), 0, 1e-4); + CHECK_CLOSE (dJointGetUniversalAngle2 (jId), 0, 1e-4); + + dReal angle1, angle2; + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + + dVector3 axis; + dJointGetUniversalAxis1 (jId, axis); + + dReal ang1 = REAL(0.0); + dReal ang2 = REAL(0.0); + + dMatrix3 R; + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], ang1); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + + dJointSetUniversalAxis1Offset (jId, axis[0], axis[1], axis[2], + ang1, ang2); + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (ang1, angle1, 1e-4); + CHECK_CLOSE (ang2, angle2, 1e-4); + + dRSetIdentity(R); // Set the rotation of the body to be zero + dBodySetRotation (bId1, R); + + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + } + + + + // Rotate 1st body 90deg around axis1 then back to original position + // x is a Symbol for lines pointing into the screen + // . is a Symbol for lines pointing out of the screen + // + // In 2D In 3D + // ^ ^ ^ Z ^ ^ Y + // | | => x | | / + // | | | | / + // B1 B2 B1 B2 .-------> X <-- Axis1 + // + // Start with a Delta of 90deg + // ^ ^ ^ + // x | => | | + // | | | + // B1 B2 B1 B2 + TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Inverse_of_X, + test_dJointSetUniversalAxis1Offset_B1_90Deg_Axis1_Inverse_of_X) + { + CHECK_CLOSE (dJointGetUniversalAngle1 (jId), 0, 1e-4); + CHECK_CLOSE (dJointGetUniversalAngle2 (jId), 0, 1e-4); + + dReal angle1, angle2; + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + + dVector3 axis; + dJointGetUniversalAxis1 (jId, axis); + + dReal ang1 = d2r(90); + dReal ang2 = REAL(0.0); + + dMatrix3 R; + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], ang1); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + + dJointSetUniversalAxis1Offset (jId, axis[0], axis[1], axis[2], + ang1, ang2); + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (ang1, angle1, 1e-4); + CHECK_CLOSE (ang2, angle2, 1e-4); + + dRSetIdentity(R); // Set the rotation of the body to be zero + dBodySetRotation (bId1, R); + + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + } + + + + // No offset when setting the Axis 2 offset + // x is a Symbol for lines pointing into the screen + // . is a Symbol for lines pointing out of the screen + // + // In 2D In 3D + // ^ ^ ^ ^ Z ^ ^ Y ^ Axis2 + // | | => | | | / / + // | | | | | / / + // B1 B2 B1 B2 . -------> <-- Axis1 + // + // Start with a Delta of 90deg + // ^ ^ ^ ^ + // | | => | | + // | | | | + // B1 B2 B1 B2 + TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Inverse_of_X, + test_dJointSetUniversalAxis2Offset_No_Offset_Axis2_Inverse_of_X) + { + CHECK_CLOSE (dJointGetUniversalAngle1 (jId), 0, 1e-4); + CHECK_CLOSE (dJointGetUniversalAngle2 (jId), 0, 1e-4); + + dReal angle1, angle2; + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + + dVector3 axis; + dJointGetUniversalAxis2 (jId, axis); + + dReal ang1 = d2r(REAL(0.0)); + dReal ang2 = d2r(REAL(0.0)); + + dMatrix3 R; + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], ang2); + dBodySetRotation (bId2, R); + + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + + dJointSetUniversalAxis2Offset (jId, axis[0], axis[1], axis[2], + ang1, -ang2); + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (ang1, angle1, 1e-4); + CHECK_CLOSE (-ang2, angle2, 1e-4); + + dRSetIdentity(R); // Set the rotation of the body to be zero + dBodySetRotation (bId2, R); + + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + } + + // Rotate 2nd body 90deg around axis2 then back to original position + // + // In 2D In 3D + // ^ ^ ^ Z ^ ^ Y ^ Axis2 + // | | => | --> | / / + // | | | | / / + // B1 B2 B1 B2 . -------> <-- Axis1 + // + // Start with a Delta of 90deg + // ^ ^ ^ + // | <--- => | | + // | | | + // B1 B2 B1 B2 + TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Inverse_of_X, + test_dJointSetUniversalAxisOffset_B2_90Deg) + { + CHECK_CLOSE (dJointGetUniversalAngle1 (jId), 0, 1e-4); + CHECK_CLOSE (dJointGetUniversalAngle2 (jId), 0, 1e-4); + + dReal angle1, angle2; + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + + dVector3 axis; + dJointGetUniversalAxis2 (jId, axis); + + dReal ang1 = d2r(REAL(0.0)); + dReal ang2 = d2r(REAL(90.0)); + + dMatrix3 R; + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], ang2); + dBodySetRotation (bId2, R); + + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + + dJointSetUniversalAxis2Offset (jId, axis[0], axis[1], axis[2], + ang1, -ang2); + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (ang1, angle1, 1e-4); + CHECK_CLOSE (-ang2, angle2, 1e-4); + + dRSetIdentity(R); // Set the rotation of the body to be zero + dBodySetRotation (bId2, R); + + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + } + + + // Rotate 2nd body -90deg around axis2 then back to original position + // + // ^ ^ ^ + // | | => | ---> + // | | | + // B1 B2 B1 B2 + // + // Start with a Delta of 90deg + // ^ ^ ^ + // | ---> => | | + // | | | + // B1 B2 B1 B2 + TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Inverse_of_X, + test_dJointSetUniversalAxis1Offset_B2_Minus90Deg) + { + CHECK_CLOSE (dJointGetUniversalAngle1 (jId), 0, 1e-4); + CHECK_CLOSE (dJointGetUniversalAngle2 (jId), 0, 1e-4); + + dReal angle1, angle2; + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + + dVector3 axis; + dJointGetUniversalAxis2 (jId, axis); + + dReal ang1 = d2r(0.0); + dReal ang2 = d2r(REAL(-90.0)); + + + dMatrix3 R; + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], ang2); + dBodySetRotation (bId2, R); + + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (ang1, angle1, 1e-4); + CHECK_CLOSE (-ang2, angle2, 1e-4); + + + dJointGetUniversalAxis1 (jId, axis); + dJointSetUniversalAxis1Offset (jId, axis[0], axis[1], axis[2], + ang1, -ang2); + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (ang1, angle1, 1e-4); + CHECK_CLOSE (-ang2, angle2, 1e-4); + + + dRSetIdentity(R); // Set the rotation of the body to be zero + dBodySetRotation (bId2, R); + + + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + } + + + // Rotate 1st body 0.23rad around X then back to original position + // + // ^ ^ ^ ^ + // | | => \ | + // | | \ | + // B1 B2 B1 B2 + // + // Start with a Delta of 0.23rad + // ^ ^ ^ ^ + // \ | => | | + // \ | | | + // B1 B2 B1 B2 + TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Inverse_of_X, + test_dJointSetUniversalAxis1Offset_B1_0_23rad) + { + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dReal angle1, angle2; + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + + dVector3 axis; + dJointGetUniversalAxis1 (jId, axis); + + dReal ang1 = REAL(0.23); + dReal ang2 = REAL(0.0); + + dMatrix3 R; + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], ang1); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + + dJointSetUniversalAxis1Offset (jId, axis[0], axis[1], axis[2], ang1, ang2); + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (ang1, angle1, 1e-4); + CHECK_CLOSE (-ang2, angle2, 1e-4); + + + dRSetIdentity(R); // Set the rotation of the body to be zero + dBodySetRotation (bId1, R); + + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + } + + + // Rotate 2nd body -0.23rad around Z then back to original position + // + // ^ ^ ^ ^ + // | | => / | + // | | / | + // B1 B2 B1 B2 + // + // Start with a Delta of 0.23rad + // ^ ^ ^ ^ + // / | => | | + // / | | | + // B1 B2 B1 B2 + TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_At_Zero_Axis1_Inverse_of_X, + test_dJointSetUniversalAxisOffset_B1_Minus0_23rad) + { + CHECK_CLOSE (dJointGetUniversalAngle1 (jId), 0, 1e-4); + + dMatrix3 R; + dRFromAxisAndAngle (R, 1, 0, 0, -REAL(0.23)); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (REAL(0.23), dJointGetUniversalAngle1 (jId), 1e-4); + + dVector3 axis; + dJointGetUniversalAxis1 (jId, axis); + dJointSetUniversalAxis1Offset (jId, axis[0], axis[1], axis[2], REAL(0.23), 0); + CHECK_CLOSE (REAL(0.23), dJointGetUniversalAngle1 (jId), 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, 0); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + } + + + + + // Rotate the body by 90deg around X then back to original position. + // The body is attached at the second position of the joint: + // dJointAttache(jId, 0, bId); + // + // ^ + // | => <--- + // | + // B1 B1 + // + // Start with a Delta of 90deg + // ^ + // <--- => | + // | + // B1 B1 + TEST_FIXTURE (Fixture_dxJointUniversal_B1_At_Zero_Default_Axes, + test_dJointSetUniversalAxisOffset_1Body_B1_90Deg) + { + CHECK_CLOSE (dJointGetUniversalAngle1 (jId), 0, 1e-4); + + dMatrix3 R; + dRFromAxisAndAngle (R, 1, 0, 0, M_PI/2.0); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (M_PI/2.0, dJointGetUniversalAngle1 (jId), 1e-4); + + dVector3 axis; + dJointGetUniversalAxis1 (jId, axis); + dJointSetUniversalAxis1Offset (jId, axis[0], axis[1], axis[2], M_PI/2.0, 0); + CHECK_CLOSE (M_PI/2.0, dJointGetUniversalAngle1 (jId), 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, 0); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + } + + // Rotate the body by -0.23rad around X then back to original position. + // The body is attached at the second position of the joint: + // dJointAttache(jId, 0, bId); + // + // ^ ^ + // | => / + // | / + // B1 B1 + // + // Start with a Delta of -0.23rad + // ^ ^ + // / => | + // / | + // B1 B1 + TEST_FIXTURE (Fixture_dxJointUniversal_B1_At_Zero_Default_Axes, + test_dJointSetUniversalAxisOffset_1Body_B1_Minus0_23rad) + { + CHECK_CLOSE (dJointGetUniversalAngle1 (jId), 0, 1e-4); + + dMatrix3 R; + dRFromAxisAndAngle (R, 1, 0, 0, -REAL(0.23)); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (-REAL(0.23), dJointGetUniversalAngle1 (jId), 1e-4); + + dVector3 axis; + dJointGetUniversalAxis1 (jId, axis); + dJointSetUniversalAxis1Offset (jId, axis[0], axis[1], axis[2], -REAL(0.23), 0); + CHECK_CLOSE (-REAL(0.23), dJointGetUniversalAngle1 (jId), 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, 0); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + } + + + + // Only one body body1 at (0,0,0) + // The joint is an Universal Joint. + // Axis the inverse of the X axis + // Anchor at (0, 0, 0) + // + // ^Y + // | + // | + // | + // | + // | + // Z <-- X + struct Fixture_dxJointUniversal_B1_At_Zero_Axis_Inverse_of_X + { + Fixture_dxJointUniversal_B1_At_Zero_Axis_Inverse_of_X() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate (wId); + dBodySetPosition (bId1, 0, 0, 0); + + jId = dJointCreateUniversal (wId, 0); + joint = (dxJointUniversal*) jId; + + + dJointAttach (jId, bId1, NULL); + dJointSetUniversalAnchor (jId, 0, 0, 0); + + axis[0] = -1; + axis[1] = 0; + axis[2] = 0; + dJointSetUniversalAxis1(jId, axis[0], axis[1], axis[2]); + } + + ~Fixture_dxJointUniversal_B1_At_Zero_Axis_Inverse_of_X() + { + dWorldDestroy (wId); + } + + dWorldID wId; + + dBodyID bId1; + + + dJointID jId; + dxJointUniversal* joint; + + dVector3 axis; + }; + + // Rotate B1 by 90deg around X then back to original position + // + // ^ + // | => <--- + // | + // B1 B1 + // + // Start with a Delta of 90deg + // ^ + // <--- => | + // | + // B1 B1 + TEST_FIXTURE (Fixture_dxJointUniversal_B1_At_Zero_Axis_Inverse_of_X, + test_dJointSetUniversalAxisOffset_1Body_B1_90Deg) + { + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + + dVector3 axis; + dJointGetUniversalAxis1(jId, axis); + + dReal ang1 = d2r(REAL(90.0)); + + dMatrix3 R; + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], ang1); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + + dJointSetUniversalAxis1Offset (jId, axis[0], axis[1], axis[2], ang1, 0); + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + + dRSetIdentity(R); // Set the rotation of the body to be zero + dBodySetRotation (bId1, R); + + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + } + + // Rotate B1 by -0.23rad around X then back to original position + // + // ^ ^ + // | => / + // | / + // B1 B1 + // + // Start with a Delta of -0.23rad + // ^ ^ + // / => | + // / | + // B1 B1 + TEST_FIXTURE (Fixture_dxJointUniversal_B1_At_Zero_Axis_Inverse_of_X, + test_dJointSetUniversalAxisOffset_1Body_B1_Minus0_23rad) + { + CHECK_CLOSE (dJointGetUniversalAngle1 (jId), 0, 1e-4); + + dMatrix3 R; + dRFromAxisAndAngle (R, 1, 0, 0, -REAL(0.23)); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (REAL(0.23), dJointGetUniversalAngle1 (jId), 1e-4); + + dVector3 axis; + dJointGetUniversalAxis1 (jId, axis); + dJointSetUniversalAxis1Offset (jId, axis[0], axis[1], axis[2], REAL(0.23), 0); + CHECK_CLOSE (REAL(0.23), dJointGetUniversalAngle1 (jId), 1e-4); + + dRFromAxisAndAngle (R, 1, 0, 0, 0); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + } + + + + + + + + // Rotate B2 by 90deg around X then back to original position + // + // ^ + // | => <--- + // | + // B2 B2 + // + // Start with a Delta of 90deg + // ^ + // <--- => | + // | + // B2 B2 + TEST_FIXTURE (Fixture_dxJointUniversal_B2_At_Zero_Default_Axes, + test_dJointSetUniversalAxisOffset_1Body_B2_90Deg) + { + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + + dVector3 axis; + dJointGetUniversalAxis2 (jId, axis); + + dReal ang2 = d2r(REAL(90.0)); + + dMatrix3 R; + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], ang2); + dBodySetRotation (bId2, R); + + CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointSetUniversalAxis2Offset (jId, axis[0], axis[1], axis[2], 0, -ang2); + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + + dRSetIdentity(R); // Set the rotation of the body to be zero + dBodySetRotation (bId2, R); + + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + } + + // Rotate B2 by -0.23rad around Y then back to original position + // + // ^ ^ + // | => / + // | / + // B2 B2 + // + // Start with an offset of -0.23rad + // ^ ^ + // / => | + // / | + // B2 B2 + TEST_FIXTURE (Fixture_dxJointUniversal_B2_At_Zero_Default_Axes, + test_dJointSetUniversalAxis2Offset_1Body_B2_Minus0_23rad) + { + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dReal angle1, angle2; + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + + dVector3 axis; + dJointGetUniversalAxis2 (jId, axis); + + dReal ang1 = 0; + dReal ang2 = REAL(-0.23); + + + dMatrix3 R; + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], ang2); + dBodySetRotation (bId2, R); + + + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (ang1, angle1, 1e-4); + CHECK_CLOSE (-ang2, angle2, 1e-4); + + + dJointSetUniversalAxis2Offset (jId, axis[0], axis[1], axis[2], + ang1, -ang2); + CHECK_CLOSE (ang1, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (-ang2, dJointGetUniversalAngle2 (jId), 1e-4); + + dRSetIdentity(R); // Set the rotation of the body to be zero + dBodySetRotation (bId2, R); + + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + } + + + + + + + + + + + + + // The 2 bodies are positionned at (0,0,0), and (0,0,0) + // The bodis have no rotation. + // The joint is a Universal Joint + // The axis of the joint are at random (Still at 90deg w.r.t each other) + // Anchor at (0, 0, 0) + struct Fixture_dxJointUniversal_B1_and_B2_Axis_Random + { + Fixture_dxJointUniversal_B1_and_B2_Axis_Random() + { + wId = dWorldCreate(); + + bId1 = dBodyCreate (wId); + dBodySetPosition (bId1, -1, -2, -3); + + bId2 = dBodyCreate (wId); + dBodySetPosition (bId2, 11, 22, 33); + + + jId = dJointCreateUniversal (wId, 0); + + + dJointAttach (jId, bId1, bId2); + + dVector3 axis1; + axis1[0] = REAL(0.53); + axis1[1] = -REAL(0.71); + axis1[2] = REAL(0.43); + dNormalize3(axis1); + + dVector3 axis; + axis[0] = REAL(1.2); + axis[1] = REAL(0.87); + axis[2] = -REAL(0.33); + + dVector3 axis2; + dCalcVectorCross3(axis2, axis1, axis); + + dJointSetUniversalAxis1(jId, axis1[0], axis1[1], axis1[2]); + dJointSetUniversalAxis2(jId, axis2[0], axis2[1], axis2[2]); + } + + ~Fixture_dxJointUniversal_B1_and_B2_Axis_Random() + { + dWorldDestroy (wId); + } + + + dWorldID wId; + + dBodyID bId1; + dBodyID bId2; + + + dJointID jId; + }; + + + // Rotate first body 90deg around Axis1 then back to original position + // + // ^ ^ ^ Z ^ + // | | => <--- | | + // | | | | + // B1 B2 B1 B2 X .----->Y + // N.B. X is going out of the screen + // Set Axis1 with an Offset of 90deg + // ^ ^ ^ + // <--- | => | | + // | | | + // B1 B2 B1 B2 + TEST_FIXTURE (Fixture_dxJointUniversal_B1_and_B2_Axis_Random, + test_dJointSetUniversalAxisOffset_B1_90deg_Axis_Random) + { + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + dReal angle1, angle2; + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + + + dVector3 axis; + dJointGetUniversalAxis1 (jId, axis); + + dReal angle = d2r(90); + dMatrix3 R; + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], angle); + dBodySetRotation (bId1, R); + + + CHECK_CLOSE (angle, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (angle, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + + + + dJointSetUniversalAxis1Offset (jId, axis[0], axis[1], axis[2], angle, 0); + CHECK_CLOSE (angle, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (angle, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + + + dRFromAxisAndAngle (R, axis[0], axis[1], axis[2], 0); + dBodySetRotation (bId1, R); + + CHECK_CLOSE (0, dJointGetUniversalAngle1 (jId), 1e-4); + CHECK_CLOSE (0, dJointGetUniversalAngle2 (jId), 1e-4); + + dJointGetUniversalAngles(jId, &angle1, &angle2); + CHECK_CLOSE (0, angle1, 1e-4); + CHECK_CLOSE (0, angle2, 1e-4); + } + +} // End of SUITE TestdxJointUniversal + diff --git a/libs/ode-0.16.1/tests/main.cpp b/libs/ode-0.16.1/tests/main.cpp new file mode 100644 index 0000000..d427825 --- /dev/null +++ b/libs/ode-0.16.1/tests/main.cpp @@ -0,0 +1,13 @@ +// openode_UnitTest++.cpp : Defines the entry point for the console application.
+//
+
+#include <UnitTest++.h>
+#include <ode/ode.h>
+
+int main()
+{
+ dInitODE();
+ int res = UnitTest::RunAllTests();
+ dCloseODE();
+ return res;
+}
diff --git a/libs/ode-0.16.1/tests/odemath.cpp b/libs/ode-0.16.1/tests/odemath.cpp new file mode 100644 index 0000000..4ddd818 --- /dev/null +++ b/libs/ode-0.16.1/tests/odemath.cpp @@ -0,0 +1,247 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library 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 files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ +//234567890123456789012345678901234567890123456789012345678901234567890123456789 +// 1 2 3 4 5 6 7 + +#include <UnitTest++.h> +#include <ode/ode.h> +#include <ode/odemath.h> + + + +TEST(test_dNormalization3) +{ + const dVector3 x = {1,0,0,0}; + const dVector3 y = {0,1,0,0}; + const dVector3 z = {0,0,1,0}; + dVector3 v; + + // Check when value in first component (i.e. [0]) + v[0] = REAL(1.0); + v[1] = REAL(0.0); + v[2] = REAL(0.0); + dSafeNormalize3(v); + CHECK_ARRAY_CLOSE(x, v, 3, 1e-6); + CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0)); + + v[0] = REAL(0.1); + v[1] = REAL(0.0); + v[2] = REAL(0.0); + dSafeNormalize3(v); + CHECK_ARRAY_CLOSE(x, v, 3, 1e-6); + CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0)); + + v[0] = REAL(1e-20); + v[1] = REAL(0.0); + v[2] = REAL(0.0); + dSafeNormalize3(v); + CHECK_ARRAY_CLOSE(x, v, 3, 1e-6); + CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0)); + + + // Check when value in first component (i.e. [0]) + v[0] = REAL(0.0); + v[1] = REAL(1.0); + v[2] = REAL(0.0); + dSafeNormalize3(v); + CHECK_ARRAY_CLOSE(y, v, 3, 1e-6); + CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0)); + + v[0] = REAL(0.0); + v[1] = REAL(0.1); + v[2] = REAL(0.0); + dSafeNormalize3(v); + CHECK_ARRAY_CLOSE(y, v, 3, 1e-6); + CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0)); + + v[0] = REAL(0.0); + v[1] = REAL(1e-20); + v[2] = REAL(0.0); + dSafeNormalize3(v); + CHECK_ARRAY_CLOSE(y, v, 3, 1e-6); + CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0)); + + + // Check when value in first component (i.e. [0]) + v[0] = REAL(0.0); + v[1] = REAL(0.0); + v[2] = REAL(1.0); + dSafeNormalize3(v); + CHECK_ARRAY_CLOSE(z, v, 3, 1e-6); + CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0)); + + v[0] = REAL(0.0); + v[1] = REAL(0.0); + v[2] = REAL(0.1); + dSafeNormalize3(v); + CHECK_ARRAY_CLOSE(z, v, 3, 1e-6); + CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0)); + + v[0] = REAL(0.0); + v[1] = REAL(0.0); + v[2] = REAL(1e-20); + dSafeNormalize3(v); + CHECK_ARRAY_CLOSE(z, v, 3, 1e-6); + CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0)); + + + // Check negative + // Check when value in first component (i.e. [0]) + v[0] = REAL(-1.0); + v[1] = REAL(0.0); + v[2] = REAL(0.0); + dSafeNormalize3(v); + CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0)); + + v[0] = REAL(-0.1); + v[1] = REAL(0.0); + v[2] = REAL(0.0); + dSafeNormalize3(v); + CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0)); + + v[0] = REAL(-1e-20); + v[1] = REAL(0.0); + v[2] = REAL(0.0); + dSafeNormalize3(v); + CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0)); + + + // Check when value in first component (i.e. [0]) + v[0] = REAL(0.0); + v[1] = REAL(-1.0); + v[2] = REAL(0.0); + dSafeNormalize3(v); + CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0)); + + v[0] = REAL(0.0); + v[1] = REAL(-0.1); + v[2] = REAL(0.0); + dSafeNormalize3(v); + CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0)); + + v[0] = REAL(0.0); + v[1] = REAL(-1e-20); + v[2] = REAL(0.0); + dSafeNormalize3(v); + CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0)); + + + // Check when value in first component (i.e. [0]) + v[0] = REAL(0.0); + v[1] = REAL(0.0); + v[2] = REAL(-1.0); + dSafeNormalize3(v); + CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0)); + + v[0] = REAL(0.0); + v[1] = REAL(0.0); + v[2] = REAL(-0.1); + dSafeNormalize3(v); + CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0)); + + v[0] = REAL(0.0); + v[1] = REAL(0.0); + v[2] = REAL(-1e-20); + dSafeNormalize3(v); + CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0)); + + + v[0] = REAL(9999999999.0); + v[1] = REAL(0.0); + v[2] = REAL(1e-20); + dSafeNormalize3(v); + CHECK_EQUAL(dCalcVectorLength3(v), REAL(1.0)); + + + v[0] = REAL(9999999999.0); + v[1] = REAL(9999.0); + v[2] = REAL(9.0); + dSafeNormalize3(v); + CHECK_CLOSE(dCalcVectorLength3(v), REAL(1.0),REAL(0.001)); + +} + + +TEST(test_dOrthogonalizeR) +{ + { + dMatrix3 r1 = { 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0 + }; + dMatrix3 r2; + memcpy(r2, r1, sizeof(dMatrix3)); + dOrthogonalizeR(r2); + CHECK_ARRAY_EQUAL(r1, r2, 12); + } + { + dMatrix3 r1 = { 0, 1, 0, 0, + 0, 0, 1, 0, + 1, 0, 0, 0 + }; + dMatrix3 r2; + memcpy(r2, r1, sizeof(dMatrix3)); + dOrthogonalizeR(r2); + CHECK_ARRAY_EQUAL(r1, r2, 12); + } + { + dMatrix3 r1 = { 0, 0, 1, 0, + 1, 0, 0, 0, + 0, 1, 0, 0 + }; + dMatrix3 r2; + memcpy(r2, r1, sizeof(dMatrix3)); + dOrthogonalizeR(r2); + CHECK_ARRAY_EQUAL(r1, r2, 12); + } + { + dMatrix3 r1 = { -1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, -1, 0 + }; + dMatrix3 r2; + memcpy(r2, r1, sizeof(dMatrix3)); + dOrthogonalizeR(r2); + CHECK_ARRAY_EQUAL(r1, r2, 12); + } + { + dMatrix3 r1 = { 0, -1, 0, 0, + 0, 0, 1, 0, + -1, 0, 0, 0 + }; + dMatrix3 r2; + memcpy(r2, r1, sizeof(dMatrix3)); + dOrthogonalizeR(r2); + CHECK_ARRAY_EQUAL(r1, r2, 12); + } + { + dMatrix3 r1 = { 0, 0, -1, 0, + 0, -1, 0, 0, + -1, 0, 0, 0 + }; + dMatrix3 r2; + memcpy(r2, r1, sizeof(dMatrix3)); + dOrthogonalizeR(r2); + CHECK_ARRAY_EQUAL(r1, r2, 12); + } + +} diff --git a/libs/ode-0.16.1/tools/README.txt b/libs/ode-0.16.1/tools/README.txt new file mode 100644 index 0000000..56019df --- /dev/null +++ b/libs/ode-0.16.1/tools/README.txt @@ -0,0 +1,94 @@ +HOW TO MAKE A RELEASE
+
+Originally by Jason Perkins (starkos@industriousone.com)
+
+
+PREREQUISITES
+
+In order to build an OpenDE release you'll need:
+
+* A Windows system
+* A Posix-like system (Linux, Mac OS X, Cygwin)
+* Visual Studio 2003 or later (for C++ release)
+* Visual Studio 2005 or later (for .NET release)
+* Subversion (command line version)
+* 7zip (command line version)
+* Doxygen
+
+All command line binaries (svn, 7z, doxygen) must be available on
+the system search path.
+
+
+
+INSTRUCTIONS
+
+* Update the version numbers in configure.in
+
+ AC_INIT(ODE,0.9.0-rc1,ode@ode.org)
+ ODE_CURRENT=0
+ ODE_REVISION=9
+ ODE_AGE=0-rc1
+
+
+* Create a release branch in Subversion. Using TortoiseSVN:
+
+ Update working copy
+ Right-click working copy folder and choose Branch/Tag
+ To https://opende.svn.sourceforge.net/svnroot/branches/0.9.0-rc1
+ Enter log message "Branching for 0.9.0-rc1 release"
+ OK
+
+ Using the command line:
+
+ $ cd ode
+ $ svn update
+ $ svn copy . -m "Branching for..." https://opende.... (see above)
+
+
+* Run msw-release.bat from a Visual Studio command prompt to create
+ the Windows binary package. I've used VS2003 for all releases since
+ 0.5, but am thinking about switching up to VS2005. The format of
+ this command is:
+
+ > msw-release.bat 0.9.0-rc1
+
+ The version argument supplied to the script must match the name of
+ the release branch in Subversion.
+
+
+* Run dotnet-release.bat to create the .NET bindings package. This
+ script must be run from a Visual Studio 2005 (or later) command
+ prompt. The format of the command is:
+
+ > dotnet-release.bat 0.9.0-rc1
+
+ The version argument supplied to the script must match the name of
+ the release branch in Subversion.
+
+
+* Run src-release.sh to create the source package. This script must be
+ run from a Posix-like environment in order to prepare the configure
+ script. I've tried it under Linux, Mac OS X, and Windows with Cygwin.
+
+ $ ./src-release.sh 0.9.0-rc1
+
+ The version argument supplied to the script must match the name of
+ the release branch in Subversion.
+
+
+* Visit the project site on SourceForge (http://sf.net/projects/opende)
+ and create a new file release including all of the files.
+
+
+SANITY CHECKING
+
+A few optional, but recommeded, checks to make sure that everything
+worked properly.
+
+ The binaries exist in lib/
+
+ include/ode/config.h exists
+
+ configure script exists (if not, make sure autotools is installed)
+
+ docs exist in docs/ (if not, make sure doxygen is on the path)
diff --git a/libs/ode-0.16.1/tools/msw-release.bat b/libs/ode-0.16.1/tools/msw-release.bat new file mode 100644 index 0000000..540ecce --- /dev/null +++ b/libs/ode-0.16.1/tools/msw-release.bat @@ -0,0 +1,138 @@ +@echo off
+rem ***********************************************************
+rem * ODE Windows Binary Release Script
+rem * Originally written by Jason Perkins (starkos@gmail.com)
+rem *
+rem * See README.txt in this directory for complete release
+rem * instructions before running this script.
+rem *
+rem * Prerequisites:
+rem * Command-line svn installed on path
+rem * Command-line 7z (7zip) installed on path
+rem * Command-line doxygen installed on path
+rem * Run from Visual Studio 2003 command prompt
+rem ***********************************************************
+
+rem * Check arguments
+if "%1"=="" goto show_usage
+
+
+rem ***********************************************************
+rem * Pre-build checklist
+rem ***********************************************************
+
+echo.
+echo STARTING PREBUILD CHECKLIST, PRESS ^^C TO ABORT.
+echo.
+echo Are you running at the VS2003 command prompt?
+pause
+echo.
+echo Is the version number "%1" correct?
+pause
+echo.
+echo Does the release branch "%1" exist in SVN?
+pause
+echo.
+echo Are 'svn', '7z', and 'doxygen' on the path?
+pause
+echo.
+echo Okay, ready to build the Windows binary packages for version %1!
+pause
+
+
+rem ***********************************************************
+rem * Retrieve source code
+rem ***********************************************************
+
+echo.
+echo RETRIEVING SOURCE CODE FROM REPOSITORY...
+echo.
+
+svn export https://opende.svn.sourceforge.net/svnroot/opende/branches/%1 ode-%1
+
+
+
+rem ***********************************************************
+rem * Prepare source code
+rem ***********************************************************
+
+echo.
+echo PREPARING SOURCE TREE...
+echo.
+
+cd ode-%1
+copy build\config-default.h include\ode\config.h
+
+cd ode\doc
+doxygen
+
+cd ..\..\..
+
+
+rem ***********************************************************
+rem * Build the binaries
+rem ***********************************************************
+
+echo.
+echo BUILDING RELEASE BINARIES (this will take a while)...
+echo.
+
+cd ode-%1\build\vs2003
+devenv.exe ode.sln /build DebugLib /project ode
+devenv.exe ode.sln /build DebugDLL /project ode
+devenv.exe ode.sln /build ReleaseLib /project ode
+devenv.exe ode.sln /build ReleaseDLL /project ode
+
+
+rem ***********************************************************
+rem * Package things up
+rem ***********************************************************
+
+cd ..\..
+move lib\ReleaseDLL\ode.lib lib\ReleaseDLL\ode-imports.lib
+
+cd ..
+7z a -tzip ode-win32-%1.zip ode-%1\*.txt ode-%1\include\ode\*.h ode-%1\lib\* ode-%1\docs\*
+
+
+rem ***********************************************************
+rem * Clean up
+rem ***********************************************************
+
+echo.
+echo CLEANING UP...
+echo.
+
+rmdir /s /q ode-%1
+
+
+rem ***********************************************************
+rem * Upload to SF.net
+rem ***********************************************************
+
+echo.
+echo Ready to upload package to SourceForce, press ^^C to abort.
+pause
+
+echo "anonymous" > ftp.txt
+echo "starkos" >> ftp.txt
+echo "cd incoming" >> ftp.txt
+echo "bin" >> ftp.txt
+echo "put ode-win32-%1.zip" >> ftp.txt
+echo "quit" >> ftp.txt
+
+ftp -s:ftp.txt upload.sourceforge.net
+erase ftp.txt
+
+goto done
+
+
+rem ***********************************************************
+rem * Error messages
+rem ***********************************************************
+
+:show_usage
+echo Usage: msw_release.bat version_number
+goto done
+
+:done
diff --git a/libs/ode-0.16.1/tools/ode_convex_export.py b/libs/ode-0.16.1/tools/ode_convex_export.py new file mode 100644 index 0000000..17375b5 --- /dev/null +++ b/libs/ode-0.16.1/tools/ode_convex_export.py @@ -0,0 +1,60 @@ +#!BPY
+"""
+Name: 'ODE Convex...'
+Blender: 244
+Group: 'Export'
+Tooltip: 'Export to Open Dynamics.'
+"""
+__author__ = "Rodrigo Hernandez"
+__url__ = ("http://www.ode.org")
+__version__ = "0.1"
+__bpydoc__ = """\
+ODE Convex Exporter
+This script Exports a Blender scene as a series of ODE Convex Geom data stored in a C header file.
+"""
+import Blender
+import bpy
+
+def WriteMesh(file,ob):
+ mesh = ob.getData(mesh=1)
+ # Write Point Count
+ file.write("unsigned int %s_pointcount = %d;\n" % (ob.getName(),len(mesh.verts)))
+ # Write Plane Count
+ file.write("unsigned int %s_planecount = %d;\n" % (ob.getName(),len(mesh.faces)))
+ # Write Points
+ file.write("dReal %s_points[%d]={\n" % (ob.getName(),(len(mesh.verts)*3)))
+ for vert in mesh.verts:
+ if vert.index==(len(mesh.verts)-1):
+ file.write("%f,%f,%f\n};\n" % (vert.co[0],vert.co[1],vert.co[2]))
+ else:
+ file.write("%f,%f,%f,\n" % (vert.co[0],vert.co[1],vert.co[2]))
+ # Write Polygons
+ file.write("unsigned int %s_polygons[]={\n" % ob.getName())
+ for face in mesh.faces:
+ file.write("%d," % len(face.verts))
+ for vert in face.verts:
+ file.write("%d," % vert.index)
+ if face.index==(len(mesh.faces)-1):
+ file.write("\n};\n");
+ else:
+ file.write("\n");
+ # Write Planes
+ file.write("dReal %s_planes[]={\n" % ob.getName())
+ for face in mesh.faces:
+ # d calculated separatelly for code readability
+ d = face.no[0]*face.verts[0].co[0]+face.no[1]*face.verts[0].co[1]+face.no[2]*face.verts[0].co[2]
+ file.write("%f,%f,%f,%f,\n" % (face.no[0],face.no[1],face.no[2],d))
+ file.write("};\n");
+
+# Entry Point
+sce = bpy.data.scenes.active
+in_editmode = Blender.Window.EditMode()
+if in_editmode: Blender.Window.EditMode(0)
+file = open("convex.h",mode='wt')
+for ob in sce.objects:
+ if ob.getType()=='Mesh':
+ WriteMesh(file,ob)
+file.close()
+if in_editmode:
+ Blender.Window.EditMode(1)
+print "ODE Export Done"
\ No newline at end of file diff --git a/libs/ode-0.16.1/tools/src-release.sh b/libs/ode-0.16.1/tools/src-release.sh new file mode 100644 index 0000000..c3c62d9 --- /dev/null +++ b/libs/ode-0.16.1/tools/src-release.sh @@ -0,0 +1,117 @@ +#!/bin/sh +################################################################### +# ODE Source Code Release Script +# Originally written by Jason Perkins (starkos@gmail.com) +#
+# See README.txt in this directory for complete release
+# instructions before running this script.
+#
+# Prerequisites:
+# Command-line svn installed on path
+# Command-line zip installed on path
+# Command-line doxygen installed on path
+# Autotools support installed
+# Run from a Posix-like shell (Linux, OS X, Cygwin)
+################################################################### + +# Check arguments +if [ $# -ne 1 ]; then + echo 1>&2 "Usage: $0 version_number" + exit 1 +fi + + +################################################################### +# Pre-build checklist +################################################################### + +echo "" +echo "STARTING PREBUILD CHECKLIST, PRESS ^C TO ABORT." +echo "" +echo "Is the version number '$1' correct?" +read line +echo "" +echo "Have you created a release branch named '$1' in SVN?" +read line +echo "" +echo Are 'svn', 'zip', and 'doxygen' on the path? +read line +echo "" +echo "Okay, ready to build the source code package for version $1!" +read line + + +################################################################### +# Retrieve source code +################################################################### + +echo "" +echo "RETRIEVING SOURCE CODE FROM REPOSITORY..." +echo "" + +svn export https://opende.svn.sourceforge.net/svnroot/opende/branches/$1 ode-$1 + + +################################################################### +# Prepare source code +################################################################### + +echo "" +echo "PREPARING SOURCE TREE..." +echo "" + +cd ode-$1 +chmod 755 autogen.sh +./autogen.sh +rm -rf autom4te.cache + +cp build/config-default.h include/ode/config.h + +cd ode/doc +doxygen + +cd ../../.. + + +################################################################### +# Package source code +################################################################### + +echo "" +echo "PACKAGING SOURCE CODE..." +echo "" + +zip -r9 ode-src-$1.zip ode-$1/* + + +################################################################### +# Clean up +################################################################### + +echo "" +echo "CLEANING UP..." +echo "" + +rm -rf ode-$1 + + +##################################################################### +# Send the files to SourceForge +##################################################################### + +echo "" +echo "Upload packages to SourceForge?" +read line +if [ $line = "y" ]; then + echo "Uploading to SourceForge..." + + echo "user anonymous starkos" > ftp.txt + echo "cd incoming" >> ftp.txt + echo "bin" >> ftp.txt + echo "put ode-src-$1.zip" >> ftp.txt + echo "quit" >> ftp.txt + + ftp -n upload.sourceforge.net < ftp.txt + + rm -f ftp.txt +fi |